26 #if ! defined (octave_Array_h)
27 #define octave_Array_h 1
29 #include "octave-config.h"
126 template <
typename T,
typename Alloc>
128 OCTARRAY_TEMPLATE_API
141 typedef typename T_Alloc_traits::pointer
pointer;
148 :
Alloc (), m_data (allocate (
len)), m_len (
len), m_count (1)
150 std::copy_n (
d,
len, m_data);
153 template <
typename U>
155 :
Alloc (), m_data (allocate (
len)), m_len (
len), m_count (1)
157 std::copy_n (
d,
len, m_data);
164 :
Alloc (), m_data (allocate (0)), m_len (0), m_count (1) { }
167 :
Alloc (), m_data (allocate (
len)), m_len (
len), m_count (1) { }
170 :
Alloc (), m_data (allocate (
len)), m_len (
len), m_count (1)
172 std::fill_n (m_data,
len, val);
177 :
Alloc (xallocator), m_data (ptr), m_len (dv.safe_numel ()), m_count (1)
182 :
Alloc (), m_data (allocate (a.m_len)), m_len (a.m_len),
198 pointer data = Alloc_traits::allocate (*
this,
len);
199 for (
size_t i = 0; i <
len; i++)
200 T_Alloc_traits::construct (*
this, data+i);
206 for (
size_t i = 0; i <
len; i++)
207 T_Alloc_traits::destroy (*
this, data+i);
208 Alloc_traits::deallocate (*
this, data,
len);
218 if (m_rep->m_count > 1)
222 if (--m_rep->m_count == 0)
226 m_slice_data = m_rep->m_data;
262 : m_dimensions (dv), m_rep(a.m_rep), m_slice_data (a.m_slice_data+l), m_slice_len (u-l)
276 : m_dimensions (), m_rep (nil_rep ()), m_slice_data (m_rep->m_data),
277 m_slice_len (m_rep->m_len)
286 m_slice_data (m_rep->m_data), m_slice_len (m_rep->m_len)
295 m_slice_data (m_rep->m_data), m_slice_len (m_rep->m_len)
307 OCTARRAY_OVERRIDABLE_FUNC_API
312 m_slice_data (m_rep->m_data), m_slice_len (m_rep->m_len)
321 template<
template <
typename...>
class Container>
325 template <
typename U,
typename A = Alloc>
327 : m_dimensions (a.dims ()),
329 m_slice_data (m_rep->m_data), m_slice_len (m_rep->m_len)
334 : m_dimensions (a.m_dimensions), m_rep (a.m_rep), m_slice_data (a.m_slice_data),
335 m_slice_len (a.m_slice_len)
341 : m_dimensions (std::move (a.m_dimensions)), m_rep (a.m_rep),
342 m_slice_data (a.m_slice_data), m_slice_len (a.m_slice_len)
345 a.m_slice_data =
nullptr;
357 if (m_rep && --m_rep->
m_count == 0)
383 m_dimensions = std::move (a.m_dimensions);
389 if (m_rep && --m_rep->
m_count == 0)
393 m_slice_data = a.m_slice_data;
394 m_slice_len = a.m_slice_len;
397 a.m_slice_data =
nullptr;
404 OCTARRAY_API
void fill (
const T& val);
406 OCTARRAY_API
void clear ();
407 OCTARRAY_API
void clear (
const dim_vector& dv);
415 {
return m_slice_len; }
423 if (m_dimensions.
ndims () != 2 || m_dimensions(1) != 1)
434 if (m_dimensions.
ndims () != 2 || m_dimensions(0) != 1)
445 if (m_dimensions.
ndims () != 2)
457 {
return m_dimensions(0); }
468 {
return m_dimensions(1); }
480 {
return m_dimensions.
ndims () >= 3 ? m_dimensions(2) : 1; }
496 return d >= ndims () ? 1 : m_dimensions(
d);
499 OCTARRAY_OVERRIDABLE_FUNC_API std::size_t
byte_size ()
const
500 {
return static_cast<std::size_t
> (
numel ()) *
sizeof (T); }
504 {
return m_dimensions; }
525 {
return m_slice_data[
n]; }
527 {
return m_slice_data[
n]; }
529 OCTARRAY_OVERRIDABLE_FUNC_API T&
531 {
return xelem (dim1 ()*j+i); }
532 OCTARRAY_OVERRIDABLE_FUNC_API crefT
534 {
return xelem (dim1 ()*j+i); }
536 OCTARRAY_OVERRIDABLE_FUNC_API T&
538 {
return xelem (i, dim2 ()*k+j); }
539 OCTARRAY_OVERRIDABLE_FUNC_API crefT
541 {
return xelem (i, dim2 ()*k+j); }
543 OCTARRAY_OVERRIDABLE_FUNC_API T&
545 {
return xelem (compute_index_unchecked (
ra_idx)); }
547 OCTARRAY_OVERRIDABLE_FUNC_API crefT
549 {
return xelem (compute_index_unchecked (
ra_idx)); }
569 {
return elem (dim1 ()*j+i); }
572 {
return elem (i, dim2 ()*k+j); }
580 {
return elem (i, j); }
582 {
return elem (i, j, k); }
596 {
return xelem (
n); }
598 OCTARRAY_OVERRIDABLE_FUNC_API crefT
600 {
return xelem (i, j); }
602 OCTARRAY_OVERRIDABLE_FUNC_API crefT
604 {
return xelem (i, j, k); }
606 OCTARRAY_OVERRIDABLE_FUNC_API crefT
610 OCTARRAY_OVERRIDABLE_FUNC_API crefT
612 OCTARRAY_OVERRIDABLE_FUNC_API crefT
614 {
return elem (i, j); }
615 OCTARRAY_OVERRIDABLE_FUNC_API crefT
617 {
return elem (i, j, k); }
618 OCTARRAY_OVERRIDABLE_FUNC_API crefT
646 {
return permute (vec,
true); }
648 OCTARRAY_OVERRIDABLE_FUNC_API
bool issquare ()
const
649 {
return (dim1 () == dim2 ()); }
651 OCTARRAY_OVERRIDABLE_FUNC_API
bool isempty ()
const
652 {
return numel () == 0; }
654 OCTARRAY_OVERRIDABLE_FUNC_API
bool isvector ()
const
655 {
return m_dimensions.
isvector (); }
661 OCTARRAY_API
Array<T, Alloc> hermitian (T (*fcn) (
const T&) =
nullptr)
const;
663 OCTARRAY_OVERRIDABLE_FUNC_API
const T *
data ()
const
664 {
return m_slice_data; }
666 OCTARRAY_API T * fortran_vec ();
671 OCTARRAY_OVERRIDABLE_FUNC_API
int ndims ()
const
672 {
return m_dimensions.
ndims (); }
683 virtual OCTARRAY_API T resize_fill_value ()
const;
690 resize2 (nr, nc, resize_fill_value ());
695 { resize1 (
n, resize_fill_value ()); }
697 OCTARRAY_API
void resize (
const dim_vector& dv,
const T& rfv);
699 { resize (dv, resize_fill_value ()); }
713 return index (i, resize_ok, resize_fill_value ());
718 bool resize_ok,
const T& rfv)
const;
721 bool resize_ok)
const
723 return index (i, j, resize_ok, resize_fill_value ());
732 return index (ia, resize_ok, resize_fill_value ());
740 OCTARRAY_OVERRIDABLE_FUNC_API
void
743 assign (i, rhs, resize_fill_value ());
749 OCTARRAY_OVERRIDABLE_FUNC_API
void
753 assign (i, j, rhs, resize_fill_value ());
758 OCTARRAY_OVERRIDABLE_FUNC_API
void
761 assign (ia, rhs, resize_fill_value ());
796 m_slice_data = m_rep->
m_data;
800 OCTARRAY_API
void print_info (std::ostream& os,
const std::string& prefix)
const;
830 bool backward =
false)
const;
852 #if defined (OCTAVE_HAVE_STD_PMR_POLYMORPHIC_ALLOCATOR)
853 template <
typename U,
typename F,
854 typename A = std::pmr::polymorphic_allocator<U>>
856 template <
typename U,
typename F,
typename A = std::allocator<U>>
863 const T *
m = data ();
869 for (i = 0; i <
len - 3; i += 4)
874 p[i+1] = fcn (
m[i+1]);
875 p[i+2] = fcn (
m[i+2]);
876 p[i+3] = fcn (
m[i+3]);
889 #if defined (OCTAVE_HAVE_STD_PMR_POLYMORPHIC_ALLOCATOR)
890 template <
typename U,
typename A = std::pmr::polymorphic_allocator<U>>
892 template <
typename U,
typename A = std::allocator<U>>
896 {
return map<U, U (&) (T), A> (fcn); }
898 #if defined (OCTAVE_HAVE_STD_PMR_POLYMORPHIC_ALLOCATOR)
899 template <
typename U,
typename A = std::pmr::polymorphic_allocator<U>>
901 template <
typename U,
typename A = std::allocator<U>>
904 map (U (&fcn) (
const T&))
const
905 {
return map<U, U (&) (const T&), A> (fcn); }
909 template <
typename F,
bool zero>
912 return octave::any_all_test<F, T, zero> (fcn, data (),
numel ());
917 template <
typename F>
919 {
return test<F, false> (fcn); }
921 template <
typename F>
923 {
return test<F, true> (fcn); }
929 {
return test<bool (&) (T), false> (fcn); }
932 {
return test<bool (&) (const T&), false> (fcn); }
935 {
return test<bool (&) (T), true> (fcn); }
938 {
return test<bool (&) (const T&), true> (fcn); }
941 template <
typename U,
typename A>
friend class Array;
949 OCTARRAY_API
static void instantiation_guard ();
955 template<
typename T,
typename Alloc>
956 template<
template <
typename...>
class Container>
965 (*current_liboctave_error_handler)
966 (
"reshape: can't reshape %zi elements into %s array",
967 a.size (), new_dims_str.c_str ());
977 template <
typename T,
typename Alloc>
978 OCTARRAY_API std::ostream&
octave_idx_type compute_index(octave_idx_type n, const dim_vector &dims)
std::ostream & operator<<(std::ostream &os, const Array< T, Alloc > &a)
octave_idx_type lookup(const T *x, octave_idx_type n, T y)
The real representation of all arrays.
T_Alloc_traits::pointer pointer
pointer allocate(size_t len)
ArrayRep(U *d, octave_idx_type len)
ArrayRep(pointer d, octave_idx_type len)
octave::refcount< octave_idx_type > m_count
ArrayRep(octave_idx_type len)
octave_idx_type numel() const
ArrayRep(octave_idx_type len, const T &val)
ArrayRep(pointer ptr, const dim_vector &dv, const Alloc &xallocator=Alloc())
std::allocator_traits< Alloc > Alloc_traits
ArrayRep(const ArrayRep &a)
void deallocate(pointer data, size_t len)
Alloc_traits::template rebind_traits< T > T_Alloc_traits
N Dimensional Array with copy-on-write semantics.
T & elem(octave_idx_type n)
Size of the specified dimension.
bool test_all(bool(&fcn)(const T &)) const
Size of the specified dimension.
T * fortran_vec()
Size of the specified dimension.
void resize2(octave_idx_type nr, octave_idx_type nc)
Size of the specified dimension.
crefT xelem(octave_idx_type n) const
Size of the specified dimension.
size_type size(const size_type d) const
Size of the specified dimension.
friend class Array
Size of the specified dimension.
Array< T, Alloc > reshape(const dim_vector &new_dims) const
Size of the specified dimension.
crefT xelem(octave_idx_type i, octave_idx_type j) const
Size of the specified dimension.
octave_idx_type size_type
Used for operator(), and returned by numel() and size() (beware: signed integer)
std::size_t byte_size() const
Size of the specified dimension.
void resize(const dim_vector &dv)
Size of the specified dimension.
crefT elem(octave_idx_type n) const
Size of the specified dimension.
bool test_all(bool(&fcn)(T)) const
Size of the specified dimension.
void maybe_economize()
Size of the specified dimension.
Array(T *ptr, const dim_vector &dv, const Alloc &xallocator=Alloc())
octave_idx_type pages() const
Size of the specified dimension.
bool test_all(F fcn) const
Size of the specified dimension.
octave_idx_type dim3() const
Size of the specified dimension.
bool issquare() const
Size of the specified dimension.
Array(const Array< U, A > &a)
Type conversion case.
octave_idx_type compute_index_unchecked(const Array< octave_idx_type > &ra_idx) const
Size of the specified dimension.
Array< T, Alloc > as_column() const
Return the array as a column vector.
Array< T, Alloc > as_matrix() const
Return the array as a matrix.
void resize1(octave_idx_type n)
Size of the specified dimension.
Array< T, Alloc > as_row() const
Return the array as a row vector.
T & xelem(octave_idx_type i, octave_idx_type j, octave_idx_type k)
Size of the specified dimension.
Array< T, Alloc > index(const octave::idx_vector &i, bool resize_ok) const
Size of the specified dimension.
bool isvector() const
Size of the specified dimension.
int ndims() const
Size of the specified dimension.
octave_idx_type m_slice_len
ref_param< T >::type crefT
crefT elem(octave_idx_type i, octave_idx_type j) const
Size of the specified dimension.
T & xelem(const Array< octave_idx_type > &ra_idx)
Size of the specified dimension.
crefT xelem(octave_idx_type i, octave_idx_type j, octave_idx_type k) const
Size of the specified dimension.
Array< T, Alloc > ipermute(const Array< octave_idx_type > &vec) const
Size of the specified dimension.
Array< U, A > map(U(&fcn)(T)) const
Overloads for function references.
bool optimize_dimensions(const dim_vector &dv)
Returns true if this->dims () == dv, and if so, replaces this->m_dimensions by a shallow copy of dv.
void clear(octave_idx_type r, octave_idx_type c)
Array(const dim_vector &dv, const T &val)
nD initialized ctor.
octave_idx_type rows() const
Array(const dim_vector &dv)
nD uninitialized ctor.
bool test_any(F fcn) const
Simpler calls.
const T * data() const
Size of the specified dimension.
void assign(const octave::idx_vector &i, const Array< T, Alloc > &rhs)
Size of the specified dimension.
void assign(const Array< octave::idx_vector > &ia, const Array< T, Alloc > &rhs)
Size of the specified dimension.
octave_idx_type dim2() const
void assign(const octave::idx_vector &i, const octave::idx_vector &j, const Array< T, Alloc > &rhs)
Size of the specified dimension.
bool is_nd_vector() const
Size of the specified dimension.
octave_idx_type columns() const
Array(Array< T, Alloc > &&a)
octave_idx_type dim1() const
octave_idx_type cols() const
Array(const Array< T, Alloc > &a, const dim_vector &dv, octave_idx_type l, octave_idx_type u)
slice constructor
bool test_any(bool(&fcn)(const T &)) const
Size of the specified dimension.
Array< T, Alloc > index(const octave::idx_vector &i, const octave::idx_vector &j, bool resize_ok) const
Size of the specified dimension.
bool isempty() const
Size of the specified dimension.
T & xelem(octave_idx_type i, octave_idx_type j)
Size of the specified dimension.
bool is_shared() const
Size of the specified dimension.
bool test(F fcn) const
Generic any/all test functionality with arbitrary predicate.
Array(const Container< T > &a, const dim_vector &dv)
Constructor from standard library sequence containers.
const dim_vector & dims() const
Return a const-reference so that dims ()(i) works efficiently.
T & xelem(octave_idx_type n)
Size of the specified dimension.
Array< U, A > map(F fcn) const
Apply function fcn to each element of the Array<T, Alloc>.
Array< T, Alloc > reshape(octave_idx_type nr, octave_idx_type nc) const
Size of the specified dimension.
crefT elem(octave_idx_type i, octave_idx_type j, octave_idx_type k) const
Size of the specified dimension.
Array< U, A > map(U(&fcn)(const T &)) const
Size of the specified dimension.
Array< T, Alloc > index(const Array< octave::idx_vector > &ia, bool resize_ok) const
Size of the specified dimension.
crefT elem(const Array< octave_idx_type > &ra_idx) const
Size of the specified dimension.
Array< T, Alloc >::ArrayRep * m_rep
T & elem(octave_idx_type i, octave_idx_type j, octave_idx_type k)
Size of the specified dimension.
T & elem(octave_idx_type i, octave_idx_type j)
Size of the specified dimension.
bool test_any(bool(&fcn)(T)) const
Overloads for function references.
T & elem(const Array< octave_idx_type > &ra_idx)
Size of the specified dimension.
crefT xelem(const Array< octave_idx_type > &ra_idx) const
Size of the specified dimension.
Array(const Array< T, Alloc > &a)
No type conversion case.
octave_idx_type numel() const
Number of elements in the array.
Array()
Empty ctor (0 by 0).
Vector representing the dimensions (size) of an Array.
octave_idx_type compute_index(const octave_idx_type *idx) const
Linear index from an index tuple.
octave_idx_type safe_numel() const
The following function will throw a std::bad_alloc () exception if the requested size is larger than ...
std::string str(char sep='x') const
void chop_trailing_singletons()
bool is_nd_vector() const
octave_idx_type ndims() const
Number of dimensions.
dim_vector redim(int n) const
Force certain dimensionality, preserving numel ().
virtual octave_idx_type numel() const
if_then_else< is_class_type< T >::no, T, T const & >::result type
octave::idx_vector idx_vector
F77_RET_T const F77_INT F77_CMPLX * A
F77_RET_T const F77_DBLE const F77_DBLE F77_DBLE * d
F77_RET_T const F77_DBLE * x
T::size_type numel(const T &str)
const octave_base_value const Array< octave_idx_type > & ra_idx