26#if ! defined (octave_Array_h)
27#define octave_Array_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>
156 :
Alloc (), m_data (allocate (
len)), m_len (
len), m_count (1)
158 std::copy_n (
d,
len, m_data);
165 :
Alloc (), m_data (allocate (0)), m_len (0), m_count (1) { }
168 :
Alloc (), m_data (allocate (
len)), m_len (
len), m_count (1) { }
171 :
Alloc (), m_data (allocate (
len)), m_len (
len), m_count (1)
173 std::fill_n (m_data,
len, val);
178 :
Alloc (xallocator), m_data (ptr), m_len (dv.safe_numel ()), m_count (1)
183 :
Alloc (), m_data (allocate (a.m_len)), m_len (a.m_len),
202 pointer data = Alloc_traits::allocate (*
this,
len);
203 for (
size_t i = 0; i <
len; i++)
204 T_Alloc_traits::construct (*
this, data+i);
210 for (
size_t i = 0; i <
len; i++)
211 T_Alloc_traits::destroy (*
this, data+i);
212 Alloc_traits::deallocate (*
this, data,
len);
222 if (m_rep->m_count > 1)
226 if (--m_rep->m_count == 0)
230 m_slice_data = m_rep->
m_data;
266 : m_dimensions (dv), m_rep(a.m_rep), m_slice_data (a.m_slice_data+l), m_slice_len (u-l)
280 : m_dimensions (), m_rep (nil_rep ()), m_slice_data (m_rep->m_data),
281 m_slice_len (m_rep->m_len)
290 m_slice_data (m_rep->m_data), m_slice_len (m_rep->m_len)
299 m_slice_data (m_rep->m_data), m_slice_len (m_rep->m_len)
311 OCTARRAY_OVERRIDABLE_FUNC_API
316 m_slice_data (m_rep->m_data), m_slice_len (m_rep->m_len)
325 template<
template <
typename...>
class Container>
329 template <
typename U,
typename A = Alloc>
331 : m_dimensions (a.dims ()),
333 m_slice_data (m_rep->m_data), m_slice_len (m_rep->m_len)
338 : m_dimensions (a.m_dimensions), m_rep (a.m_rep), m_slice_data (a.m_slice_data),
339 m_slice_len (a.m_slice_len)
345 : m_dimensions (std::move (a.m_dimensions)), m_rep (a.m_rep),
346 m_slice_data (a.m_slice_data), m_slice_len (a.m_slice_len)
349 a.m_slice_data =
nullptr;
361 if (m_rep && --m_rep->
m_count == 0)
387 m_dimensions = std::move (a.m_dimensions);
393 if (m_rep && --m_rep->
m_count == 0)
397 m_slice_data = a.m_slice_data;
398 m_slice_len = a.m_slice_len;
401 a.m_slice_data =
nullptr;
408 OCTARRAY_API
void fill (
const T& val);
410 OCTARRAY_API
void clear ();
411 OCTARRAY_API
void clear (
const dim_vector& dv);
419 {
return m_slice_len; }
427 if (m_dimensions.
ndims () != 2 || m_dimensions(1) != 1)
438 if (m_dimensions.
ndims () != 2 || m_dimensions(0) != 1)
449 if (m_dimensions.
ndims () != 2)
461 {
return m_dimensions(0); }
472 {
return m_dimensions(1); }
484 {
return m_dimensions.
ndims () >= 3 ? m_dimensions(2) : 1; }
500 return d >= ndims () ? 1 : m_dimensions(
d);
503 OCTARRAY_OVERRIDABLE_FUNC_API std::size_t
byte_size ()
const
504 {
return static_cast<std::size_t
> (
numel ()) *
sizeof (T); }
508 {
return m_dimensions; }
526 {
return m_slice_data[n]; }
528 {
return m_slice_data[n]; }
530 OCTARRAY_OVERRIDABLE_FUNC_API T&
532 {
return xelem (dim1 ()*j+i); }
533 OCTARRAY_OVERRIDABLE_FUNC_API crefT
535 {
return xelem (dim1 ()*j+i); }
537 OCTARRAY_OVERRIDABLE_FUNC_API T&
539 {
return xelem (i, dim2 ()*k+j); }
540 OCTARRAY_OVERRIDABLE_FUNC_API crefT
542 {
return xelem (i, dim2 ()*k+j); }
544 OCTARRAY_OVERRIDABLE_FUNC_API T&
546 {
return xelem (compute_index_unchecked (
ra_idx)); }
548 OCTARRAY_OVERRIDABLE_FUNC_API crefT
550 {
return xelem (compute_index_unchecked (
ra_idx)); }
570 {
return elem (dim1 ()*j+i); }
573 {
return elem (i, dim2 ()*k+j); }
581 {
return elem (i, j); }
583 {
return elem (i, j, k); }
597 {
return xelem (n); }
599 OCTARRAY_OVERRIDABLE_FUNC_API crefT
601 {
return xelem (i, j); }
603 OCTARRAY_OVERRIDABLE_FUNC_API crefT
605 {
return xelem (i, j, k); }
607 OCTARRAY_OVERRIDABLE_FUNC_API crefT
611 OCTARRAY_OVERRIDABLE_FUNC_API crefT
613 OCTARRAY_OVERRIDABLE_FUNC_API crefT
615 {
return elem (i, j); }
616 OCTARRAY_OVERRIDABLE_FUNC_API crefT
618 {
return elem (i, j, k); }
619 OCTARRAY_OVERRIDABLE_FUNC_API crefT
647 {
return permute (vec,
true); }
649 OCTARRAY_OVERRIDABLE_FUNC_API
bool issquare ()
const
650 {
return (dim1 () == dim2 ()); }
652 OCTARRAY_OVERRIDABLE_FUNC_API
bool isempty ()
const
653 {
return numel () == 0; }
655 OCTARRAY_OVERRIDABLE_FUNC_API
bool isvector ()
const
656 {
return m_dimensions.
isvector (); }
662 OCTARRAY_API
Array<T, Alloc> hermitian (T (*fcn) (
const T&) =
nullptr)
const;
665 OCTARRAY_OVERRIDABLE_FUNC_API
const T *
data ()
const
666 {
return m_slice_data; }
669 OCTARRAY_API T * rwdata ();
674 {
return rwdata (); }
679 OCTARRAY_OVERRIDABLE_FUNC_API
int ndims ()
const
680 {
return m_dimensions.
ndims (); }
684 OCTARRAY_API
Array<T, Alloc> index (
const octave::idx_vector& i)
const;
686 OCTARRAY_API
Array<T, Alloc> index (
const octave::idx_vector& i,
const octave::idx_vector& j)
const;
691 virtual OCTARRAY_API T resize_fill_value ()
const;
698 resize2 (nr, nc, resize_fill_value ());
703 { resize1 (n, resize_fill_value ()); }
705 OCTARRAY_API
void resize (
const dim_vector& dv,
const T& rfv);
707 { resize (dv, resize_fill_value ()); }
717 index (
const octave::idx_vector& i,
bool resize_ok,
const T& rfv)
const;
719 index (
const octave::idx_vector& i,
bool resize_ok)
const
721 return index (i, resize_ok, resize_fill_value ());
725 index (
const octave::idx_vector& i,
const octave::idx_vector& j,
726 bool resize_ok,
const T& rfv)
const;
728 index (
const octave::idx_vector& i,
const octave::idx_vector& j,
729 bool resize_ok)
const
731 return index (i, j, resize_ok, resize_fill_value ());
744 assign (
const octave::idx_vector& i,
const Array<T, Alloc>& rhs,
const T& rfv);
745 OCTARRAY_OVERRIDABLE_FUNC_API
void
748 assign (i, rhs, resize_fill_value ());
752 assign (
const octave::idx_vector& i,
const octave::idx_vector& j,
754 OCTARRAY_OVERRIDABLE_FUNC_API
void
755 assign (
const octave::idx_vector& i,
const octave::idx_vector& j,
758 assign (i, j, rhs, resize_fill_value ());
771 OCTARRAY_API
void delete_elements (
const octave::idx_vector& i);
774 OCTARRAY_API
void delete_elements (
int dim,
const octave::idx_vector& i);
798 m_slice_data = m_rep->
m_data;
802 OCTARRAY_API
void print_info (std::ostream& os,
const std::string& prefix)
const;
832 bool backward =
false)
const;
837 OCTARRAY_API
Array<T, Alloc> nth_element (
const octave::idx_vector& n,
int dim = 0)
const;
854#if defined (OCTAVE_HAVE_STD_PMR_POLYMORPHIC_ALLOCATOR)
855 template <
typename U,
typename F,
856 typename A = std::pmr::polymorphic_allocator<U>>
858 template <
typename U,
typename F,
typename A = std::allocator<U>>
865 const T *m = data ();
871 for (i = 0; i <
len - 3; i += 4)
876 p[i+1] = fcn (m[i+1]);
877 p[i+2] = fcn (m[i+2]);
878 p[i+3] = fcn (m[i+3]);
891#if defined (OCTAVE_HAVE_STD_PMR_POLYMORPHIC_ALLOCATOR)
892 template <
typename U,
typename A = std::pmr::polymorphic_allocator<U>>
894 template <
typename U,
typename A = std::allocator<U>>
898 {
return map<U, U (&) (T), A> (fcn); }
900#if defined (OCTAVE_HAVE_STD_PMR_POLYMORPHIC_ALLOCATOR)
901 template <
typename U,
typename A = std::pmr::polymorphic_allocator<U>>
903 template <
typename U,
typename A = std::allocator<U>>
906 map (U (&fcn) (
const T&))
const
907 {
return map<U, U (&) (const T&), A> (fcn); }
911 template <
typename F,
bool zero>
914 return octave::any_all_test<F, T, zero> (fcn, data (),
numel ());
919 template <
typename F>
921 {
return test<F, false> (fcn); }
923 template <
typename F>
925 {
return test<F, true> (fcn); }
931 {
return test<bool (&) (T), false> (fcn); }
934 {
return test<bool (&) (const T&), false> (fcn); }
937 {
return test<bool (&) (T), true> (fcn); }
940 {
return test<bool (&) (const T&), true> (fcn); }
943 template <
typename U,
typename A>
friend class Array;
948 OCTARRAY_API
bool optimize_dimensions (
const dim_vector& dv);
951 OCTARRAY_API
static void instantiation_guard ();
957template<
typename T,
typename Alloc>
958template<
template <
typename...>
class Container>
967 (*current_liboctave_error_handler)
968 (
"reshape: can't reshape %zi elements into %s array",
969 a.size (), new_dims_str.c_str ());
979template <
typename T,
typename Alloc>
980OCTARRAY_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.
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
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