26#if ! defined (octave_Array_base_h)
27#define octave_Array_base_h 1
29#include "octave-config.h"
126template <
typename T,
typename Alloc>
class OCTARRAY_API
Array;
128template <
typename T,
typename Alloc>
141 typedef typename T_Alloc_traits::pointer
pointer;
147 OCTARRAY_OVERRIDABLE_FUNC_API
149 :
Alloc (), m_data (allocate (
len)), m_len (
len), m_count (1)
151 std::copy_n (
d,
len, m_data);
154 template <
typename U>
155 OCTARRAY_OVERRIDABLE_FUNC_API
157 :
Alloc (), m_data (allocate (
len)), m_len (
len), m_count (1)
159 if constexpr (std::is_same_v<T, bool>)
164 m_data[i] =
static_cast<bool> (
d[i]);
167 std::copy_n (
d,
len, m_data);
174 :
Alloc (), m_data (allocate (0)), m_len (0), m_count (1) { }
177 :
Alloc (), m_data (allocate (
len)), m_len (
len), m_count (1) { }
179 explicit OCTARRAY_OVERRIDABLE_FUNC_API
181 :
Alloc (), m_data (allocate (
len)), m_len (
len), m_count (1)
183 std::fill_n (m_data,
len, val);
186 explicit OCTARRAY_OVERRIDABLE_FUNC_API
189 :
Alloc (xallocator), m_data (ptr), m_len (dv.safe_numel ()), m_count (1)
194 :
Alloc (), m_data (allocate (a.m_len)), m_len (a.m_len),
200 OCTARRAY_OVERRIDABLE_FUNC_API
~ArrayRep () { deallocate (m_data, m_len); }
209 OCTARRAY_OVERRIDABLE_FUNC_API
ArrayRep&
214 pointer data = Alloc_traits::allocate (*
this,
len);
215 for (
size_t i = 0; i <
len; i++)
216 T_Alloc_traits::construct (*
this, data+i);
222 for (
size_t i = 0; i <
len; i++)
223 T_Alloc_traits::destroy (*
this, data+i);
224 Alloc_traits::deallocate (*
this, data,
len);
234 if (m_rep->m_count > 1)
238 if (--m_rep->m_count == 0)
242 m_slice_data = m_rep->
m_data;
276 OCTARRAY_OVERRIDABLE_FUNC_API
279 : m_dimensions (dv), m_rep(a.m_rep), m_slice_data (a.m_slice_data+l), m_slice_len (u-l)
292 OCTARRAY_OVERRIDABLE_FUNC_API
Array ()
293 : m_dimensions (), m_rep (nil_rep ()), m_slice_data (m_rep->m_data),
294 m_slice_len (m_rep->m_len)
300 OCTARRAY_OVERRIDABLE_FUNC_API
304 m_slice_data (m_rep->m_data), m_slice_len (m_rep->m_len)
310 OCTARRAY_OVERRIDABLE_FUNC_API
314 m_slice_data (m_rep->m_data), m_slice_len (m_rep->m_len)
326 OCTARRAY_OVERRIDABLE_FUNC_API
331 m_slice_data (m_rep->m_data), m_slice_len (m_rep->m_len)
340 template<
template <
typename...>
class Container>
341 OCTARRAY_OVERRIDABLE_FUNC_API
345 template <
typename U,
typename A = Alloc>
346 OCTARRAY_OVERRIDABLE_FUNC_API
348 : m_dimensions (a.dims ()),
350 m_slice_data (m_rep->m_data), m_slice_len (m_rep->m_len)
354 OCTARRAY_OVERRIDABLE_FUNC_API
356 : m_dimensions (a.m_dimensions), m_rep (a.m_rep), m_slice_data (a.m_slice_data),
357 m_slice_len (a.m_slice_len)
362 OCTARRAY_OVERRIDABLE_FUNC_API
364 : m_dimensions (std::move (a.m_dimensions)), m_rep (a.m_rep),
365 m_slice_data (a.m_slice_data), m_slice_len (a.m_slice_len)
368 a.m_slice_data =
nullptr;
374 virtual OCTARRAY_OVERRIDABLE_FUNC_API
~Array ()
380 if (m_rep && --m_rep->
m_count == 0)
408 m_dimensions = std::move (a.m_dimensions);
414 if (m_rep && --m_rep->
m_count == 0)
418 m_slice_data = a.m_slice_data;
419 m_slice_len = a.m_slice_len;
422 a.m_slice_data =
nullptr;
429 OCTARRAY_API
void fill (
const T& val);
431 OCTARRAY_API
void clear ();
432 OCTARRAY_API
void clear (
const dim_vector& dv);
434 OCTARRAY_OVERRIDABLE_FUNC_API
void
441 {
return m_slice_len; }
449 if (m_dimensions.
ndims () != 2 || m_dimensions(1) != 1)
460 if (m_dimensions.
ndims () != 2 || m_dimensions(0) != 1)
471 if (m_dimensions.
ndims () != 2)
483 {
return m_dimensions(0); }
494 {
return m_dimensions(1); }
506 {
return m_dimensions.
ndims () >= 3 ? m_dimensions(2) : 1; }
522 return d >= ndims () ? 1 : m_dimensions(
d);
525 OCTARRAY_OVERRIDABLE_FUNC_API std::size_t
byte_size ()
const
526 {
return static_cast<std::size_t
> (
numel ()) *
sizeof (T); }
530 {
return m_dimensions; }
548 {
return m_slice_data[n]; }
550 {
return m_slice_data[n]; }
552 OCTARRAY_OVERRIDABLE_FUNC_API T&
554 {
return xelem (dim1 ()*j+i); }
555 OCTARRAY_OVERRIDABLE_FUNC_API crefT
557 {
return xelem (dim1 ()*j+i); }
559 OCTARRAY_OVERRIDABLE_FUNC_API T&
561 {
return xelem (i, dim2 ()*k+j); }
562 OCTARRAY_OVERRIDABLE_FUNC_API crefT
564 {
return xelem (i, dim2 ()*k+j); }
566 OCTARRAY_OVERRIDABLE_FUNC_API T&
568 {
return xelem (compute_index_unchecked (
ra_idx)); }
570 OCTARRAY_OVERRIDABLE_FUNC_API crefT
572 {
return xelem (compute_index_unchecked (
ra_idx)); }
592 {
return elem (dim1 ()*j+i); }
595 {
return elem (i, dim2 ()*k+j); }
603 {
return elem (i, j); }
605 {
return elem (i, j, k); }
619 {
return xelem (n); }
621 OCTARRAY_OVERRIDABLE_FUNC_API crefT
623 {
return xelem (i, j); }
625 OCTARRAY_OVERRIDABLE_FUNC_API crefT
627 {
return xelem (i, j, k); }
629 OCTARRAY_OVERRIDABLE_FUNC_API crefT
633 OCTARRAY_OVERRIDABLE_FUNC_API crefT
635 OCTARRAY_OVERRIDABLE_FUNC_API crefT
637 {
return elem (i, j); }
638 OCTARRAY_OVERRIDABLE_FUNC_API crefT
640 {
return elem (i, j, k); }
641 OCTARRAY_OVERRIDABLE_FUNC_API crefT
669 {
return permute (vec,
true); }
671 OCTARRAY_OVERRIDABLE_FUNC_API
bool issquare ()
const
672 {
return (dim1 () == dim2 ()); }
674 OCTARRAY_OVERRIDABLE_FUNC_API
bool isempty ()
const
675 {
return numel () == 0; }
677 OCTARRAY_OVERRIDABLE_FUNC_API
bool isvector ()
const
678 {
return m_dimensions.
isvector (); }
684 OCTARRAY_API
Array<T, Alloc> hermitian (T (*fcn) (
const T&) =
nullptr)
const;
687 OCTARRAY_OVERRIDABLE_FUNC_API
const T *
data ()
const
688 {
return m_slice_data; }
691 OCTARRAY_API T * rwdata ();
696 {
return rwdata (); }
701 OCTARRAY_OVERRIDABLE_FUNC_API
int ndims ()
const
702 {
return m_dimensions.
ndims (); }
706 OCTARRAY_API
Array<T, Alloc> index (
const octave::idx_vector& i)
const;
708 OCTARRAY_API
Array<T, Alloc> index (
const octave::idx_vector& i,
const octave::idx_vector& j)
const;
713 virtual OCTARRAY_API T resize_fill_value ()
const;
720 resize2 (nr, nc, resize_fill_value ());
725 { resize1 (n, resize_fill_value ()); }
727 OCTARRAY_API
void resize (
const dim_vector& dv,
const T& rfv);
729 { resize (dv, resize_fill_value ()); }
739 index (
const octave::idx_vector& i,
bool resize_ok,
const T& rfv)
const;
741 index (
const octave::idx_vector& i,
bool resize_ok)
const
743 return index (i, resize_ok, resize_fill_value ());
747 index (
const octave::idx_vector& i,
const octave::idx_vector& j,
748 bool resize_ok,
const T& rfv)
const;
750 index (
const octave::idx_vector& i,
const octave::idx_vector& j,
751 bool resize_ok)
const
753 return index (i, j, resize_ok, resize_fill_value ());
766 assign (
const octave::idx_vector& i,
const Array<T, Alloc>& rhs,
const T& rfv);
767 OCTARRAY_OVERRIDABLE_FUNC_API
void
770 assign (i, rhs, resize_fill_value ());
774 assign (
const octave::idx_vector& i,
const octave::idx_vector& j,
776 OCTARRAY_OVERRIDABLE_FUNC_API
void
777 assign (
const octave::idx_vector& i,
const octave::idx_vector& j,
780 assign (i, j, rhs, resize_fill_value ());
793 OCTARRAY_API
void delete_elements (
const octave::idx_vector& i);
796 OCTARRAY_API
void delete_elements (
int dim,
const octave::idx_vector& i);
820 m_slice_data = m_rep->
m_data;
824 OCTARRAY_API
void print_info (std::ostream& os,
const std::string& prefix)
const;
854 bool backward =
false)
const;
859 OCTARRAY_API
Array<T, Alloc> nth_element (
const octave::idx_vector& n,
int dim = 0)
const;
876#if defined (OCTAVE_HAVE_STD_PMR_POLYMORPHIC_ALLOCATOR)
877 template <
typename U,
typename F,
878 typename A = std::pmr::polymorphic_allocator<U>>
880 template <
typename U,
typename F,
typename A = std::allocator<U>>
882 OCTARRAY_OVERRIDABLE_FUNC_API
888 const T *m = data ();
894 for (i = 0; i <
len - 3; i += 4)
899 p[i+1] = fcn (m[i+1]);
900 p[i+2] = fcn (m[i+2]);
901 p[i+3] = fcn (m[i+3]);
914#if defined (OCTAVE_HAVE_STD_PMR_POLYMORPHIC_ALLOCATOR)
915 template <
typename U,
typename A = std::pmr::polymorphic_allocator<U>>
917 template <
typename U,
typename A = std::allocator<U>>
919 OCTARRAY_OVERRIDABLE_FUNC_API
922 {
return map<U, U (&) (T), A> (fcn); }
924#if defined (OCTAVE_HAVE_STD_PMR_POLYMORPHIC_ALLOCATOR)
925 template <
typename U,
typename A = std::pmr::polymorphic_allocator<U>>
927 template <
typename U,
typename A = std::allocator<U>>
929 OCTARRAY_OVERRIDABLE_FUNC_API
931 map (U (&fcn) (
const T&))
const
932 {
return map<U, U (&) (const T&), A> (fcn); }
936 template <
typename F,
bool zero>
937 OCTARRAY_OVERRIDABLE_FUNC_API
940 return octave::any_all_test<F, T, zero> (fcn, data (),
numel ());
945 template <
typename F>
946 OCTARRAY_OVERRIDABLE_FUNC_API
948 {
return test<F, false> (fcn); }
950 template <
typename F>
951 OCTARRAY_OVERRIDABLE_FUNC_API
953 {
return test<F, true> (fcn); }
958 OCTARRAY_OVERRIDABLE_FUNC_API
bool test_any (
bool (&fcn) (T))
const
959 {
return test<bool (&) (T), false> (fcn); }
961 OCTARRAY_OVERRIDABLE_FUNC_API
bool test_any (
bool (&fcn) (
const T&))
const
962 {
return test<bool (&) (const T&), false> (fcn); }
964 OCTARRAY_OVERRIDABLE_FUNC_API
bool test_all (
bool (&fcn) (T))
const
965 {
return test<bool (&) (T), true> (fcn); }
967 OCTARRAY_OVERRIDABLE_FUNC_API
bool test_all (
bool (&fcn) (
const T&))
const
968 {
return test<bool (&) (const T&), true> (fcn); }
971 template <
typename U,
typename A>
friend class Array;
976 OCTARRAY_API
bool optimize_dimensions (
const dim_vector& dv);
979 OCTARRAY_API
static void instantiation_guard ();
985template<
typename T,
typename Alloc>
986template<
template <
typename...>
class Container>
987OCTARRAY_OVERRIDABLE_FUNC_API
996 (*current_liboctave_error_handler)
997 (
"reshape: can't reshape %zi elements into %s array",
998 a.size (), new_dims_str.c_str ());
1002 for (
const T&
x : a)
1008template <
typename T,
typename Alloc>
1009OCTARRAY_API std::ostream&
std::ostream & operator<<(std::ostream &os, const Array< T, Alloc > &a)
octave_idx_type compute_index(octave_idx_type n, const dim_vector &dims)
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.
const dim_vector & dims() const
Return a const-reference so that dims ()(i) works efficiently.
Array< T, Alloc >::ArrayRep * m_rep
bool test_all(bool(&fcn)(const T &)) const
Size of the specified dimension.
T & xelem(octave_idx_type n)
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.
T & xelem(octave_idx_type i, octave_idx_type j)
Size of the specified dimension.
friend class Array
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)
Array< T, Alloc > ipermute(const Array< octave_idx_type > &vec) const
Size of the specified dimension.
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.
T & elem(octave_idx_type i, octave_idx_type j)
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.
void resize1(octave_idx_type n)
Size of the specified dimension.
T & elem(octave_idx_type n)
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< U, A > map(U(&fcn)(const T &)) const
Size of the specified dimension.
Array< U, A > map(F fcn) const
Apply function fcn to each element of the Array<T, Alloc>.
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.
Array< T, Alloc > as_row() const
Return the array as a row vector.
Array< T, Alloc > index(const octave::idx_vector &i, bool resize_ok) const
Size of the specified dimension.
Array< U, A > map(U(&fcn)(T)) const
Overloads for function references.
void assign(const octave::idx_vector &i, const Array< T, Alloc > &rhs)
Size of the specified dimension.
Array< T, Alloc > reshape(const dim_vector &new_dims) const
Size of the specified dimension.
octave_idx_type dim2() const
Array< T, Alloc > as_column() const
Return the array as a column vector.
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
Array< T, Alloc > as_matrix() const
Return the array as a matrix.
Array< T, Alloc > reshape(octave_idx_type nr, octave_idx_type nc) const
Size of the specified dimension.
bool test_any(bool(&fcn)(const T &)) const
Size of the specified dimension.
bool isempty() const
Size of the specified dimension.
const T * data() const
Size of the specified dimension.
bool is_shared() const
Size of the specified dimension.
T * rwdata()
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.
T & xelem(octave_idx_type i, octave_idx_type j, octave_idx_type k)
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.
crefT elem(const Array< octave_idx_type > &ra_idx) const
Size of the specified dimension.
T & elem(octave_idx_type i, octave_idx_type j, octave_idx_type k)
Size of the specified dimension.
T & elem(const Array< octave_idx_type > &ra_idx)
Size of the specified dimension.
bool test_any(bool(&fcn)(T)) const
Overloads for function references.
Array< T, Alloc > index(const octave::idx_vector &i, const octave::idx_vector &j, bool resize_ok) const
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 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 ().
if_then_else< is_class_type< T >::no, T, Tconst & >::result type
F77_RET_T const F77_INT F77_CMPLX * A
T::size_type numel(const T &str)
const octave_base_value const Array< octave_idx_type > & ra_idx
F77_RET_T const F77_DBLE const F77_DBLE F77_DBLE * d
F77_RET_T const F77_DBLE * x