24 #ifndef util_Array_hpp
25 #define util_Array_hpp
27 #ifdef ARRAY_BOUNDS_CHECKING
28 #define ARRAY_CHECK( X ) X
30 #define ARRAY_CHECK( X )
35 #include <util/SimpleArrayOps.hpp>
124 template<
typename Scalar ,
ArrayOrder Order ,
125 class Tag1 = void ,
class Tag2 = void ,
126 class Tag3 = void ,
class Tag4 = void ,
127 class Tag5 = void ,
class Tag6 = void ,
128 class Tag7 = void ,
class Tag8 =
void >
133 template<
class ArrayType ,
class Tag >
struct ArrayAppend ;
163 virtual const char *
name()
const = 0 ;
168 virtual std::string
to_string(
unsigned dimension ,
169 unsigned index )
const ;
174 virtual unsigned to_index(
unsigned dimension ,
175 const std::string & label )
const ;
192 const char *
name()
const ;
208 #include <util/ArrayPrivate.hpp>
232 template<
typename Scalar ,
ArrayOrder array_order ,
233 class Tag1 ,
class Tag2 ,
class Tag3 ,
class Tag4 ,
234 class Tag5 ,
class Tag6 ,
class Tag7 ,
class Tag8 >
239 Array<void,array_order,Tag1,Tag2,Tag3,Tag4,Tag5,Tag6,Tag7,Tag8>
258 enum { Rank = md_type::Rank };
267 enum { Contiguous =
true };
270 unsigned rank()
const {
return Rank ; }
283 #ifndef DOXYGEN_COMPILE
285 template <
unsigned ordinate >
286 struct Tag {
typedef typename ArrayTagAt<Array,ordinate>::type type ; };
292 array_check_ordinal( Rank , ordinate );
294 array_dim_tags<Tag1,Tag2,Tag3,Tag4,Tag5,Tag6,Tag7,Tag8>()[ordinate];
299 template <
unsigned ordinate >
unsigned dimension()
const
301 array_check_ordinal_is_less<ordinate,Rank>();
302 return ArrayStrideDim<array_order,Rank,ordinate>::dimension(
m_stride);
308 array_check_ordinal( Rank , ordinate );
309 return ArrayStrideDim<array_order,Rank>::dimension(
m_stride,ordinate);
316 for (
unsigned i = 0 ; i < Rank ; ++i ) { n[i] =
dimension(i); }
340 tmp.m_ptr =
m_ptr + i * ( 1 < Rank ?
m_stride[ Rank - 2 ] : 1 );
352 ARRAY_CHECK( array_check_offset(
size(),i) );
358 const unsigned i3 ,
const unsigned i4 ,
359 const unsigned i5 ,
const unsigned i6 ,
360 const unsigned i7 ,
const unsigned i8 )
const
362 array_offset<array_order,Rank>(
m_stride,i1,i2,i3,i4,i5,i6,i7,i8) ];
367 const unsigned i3 ,
const unsigned i4 ,
368 const unsigned i5 ,
const unsigned i6 ,
369 const unsigned i7 )
const
371 array_offset<array_order,Rank>(
m_stride,i1,i2,i3,i4,i5,i6,i7) ];
376 const unsigned i3 ,
const unsigned i4 ,
377 const unsigned i5 ,
const unsigned i6 )
const
379 array_offset<array_order,Rank>(
m_stride,i1,i2,i3,i4,i5,i6) ];
384 const unsigned i3 ,
const unsigned i4 ,
385 const unsigned i5 )
const
386 {
return m_ptr[ array_offset<array_order,Rank>(
m_stride,i1,i2,i3,i4,i5) ]; }
390 const unsigned i3 ,
const unsigned i4 )
const
391 {
return m_ptr[ array_offset<array_order,Rank>(
m_stride,i1,i2,i3,i4) ]; }
395 const unsigned i3 )
const
396 {
return m_ptr[ array_offset<array_order,Rank>(
m_stride,i1,i2,i3) ]; }
400 {
return m_ptr[ array_offset<array_order,Rank>(
m_stride,i1,i2) ]; }
404 {
return m_ptr[ array_offset<array_order,Rank>(
m_stride,i1) ]; }
428 Copy<Rank>(
m_stride , rhs.m_stride );
440 Copy<Rank>(
m_stride , rhs.m_stride );
450 const unsigned n1 ,
const unsigned n2 ,
451 const unsigned n3 ,
const unsigned n4 ,
452 const unsigned n5 ,
const unsigned n6 ,
453 const unsigned n7 ,
const unsigned n8 )
455 { md_type::assign(
m_stride , n1 , n2 , n3 , n4 , n5 , n6 , n7 , n8 ); }
461 const unsigned n1 ,
const unsigned n2 ,
462 const unsigned n3 ,
const unsigned n4 ,
463 const unsigned n5 ,
const unsigned n6 ,
466 { md_type::assign(
m_stride , n1 , n2 , n3 , n4 , n5 , n6 , n7 ); }
472 const unsigned n1 ,
const unsigned n2 ,
473 const unsigned n3 ,
const unsigned n4 ,
474 const unsigned n5 ,
const unsigned n6 )
476 { md_type::assign(
m_stride , n1 , n2 , n3 , n4 , n5 , n6 ); }
482 const unsigned n1 ,
const unsigned n2 ,
483 const unsigned n3 ,
const unsigned n4 ,
486 { md_type::assign(
m_stride , n1 , n2 , n3 , n4 , n5 ); }
492 const unsigned n1 ,
const unsigned n2 ,
493 const unsigned n3 ,
const unsigned n4 )
495 { md_type::assign(
m_stride , n1 , n2 , n3 , n4 ); }
501 const unsigned n1 ,
const unsigned n2 ,
504 { md_type::assign(
m_stride , n1 , n2 , n3 ); }
510 :
m_ptr( arg_ptr ) { md_type::assign(
m_stride , n1 , n2 ); }
532 class , class , class , class ,
533 class , class , class ,
class >
539 #ifndef DOXYGEN_COMPILE
544 template<
typename Scalar >
545 class Array<Scalar,
RankZero,void,void,void,void,void,void,void,void>
556 enum { Natural =
false };
557 enum { Reverse =
false };
558 enum { Contiguous =
true };
560 unsigned rank()
const {
return Rank ; }
561 bool natural()
const {
return Natural ; }
562 bool reverse()
const {
return Reverse ; }
563 bool contiguous()
const {
return Contiguous ; }
585 {
m_ptr = rhs.m_ptr ;
return *this ; }
597 class , class , class , class ,
598 class , class , class ,
class >
618 template<
typename Scalar , ArrayOrder array_order >
619 class Array<Scalar,array_order,void,void,void,void,void,void,void,void>
644 enum { Contiguous =
true };
647 unsigned rank()
const {
return m_rank ; }
663 array_check_ordinal( m_rank , ordinal );
664 const int i = Natural ? ( m_rank - 1 ) - ordinal : ordinal ;
673 array_check_ordinal( m_rank , ordinal );
674 const int i = Natural ? ( m_rank - 1 ) - ordinal : ordinal ;
682 for (
unsigned i = 0 ; i < m_rank ; ++i ) { n[i] =
dimension(i); }
702 tmp.m_rank = m_rank - 1 ;
704 for ( k = 0 ; k < m_rank - 1 ; ++k ) { tmp.m_stride[i] =
m_stride[i] ; }
705 for ( ; k < 8 ; ++k ) { tmp.m_stride[i] = 0 ; }
706 for ( k = 0 ; k < m_rank - 1 ; ++k ) { tmp.m_tag[i] = m_tag[i] ; }
707 for ( ; k < 8 ; ++k ) { tmp.m_tag[i] = NULL ; }
718 ARRAY_CHECK( array_check_offset(
size(),i) );
725 const unsigned i3 ,
const unsigned i4 ,
726 const unsigned i5 ,
const unsigned i6 ,
727 const unsigned i7 ,
const unsigned i8 )
const
729 ARRAY_CHECK( array_check_rank( m_rank , 8 ) );
731 array_offset<array_order,8>(
m_stride,i1,i2,i3,i4,i5,i6,i7,i8) ];
735 const unsigned i3 ,
const unsigned i4 ,
736 const unsigned i5 ,
const unsigned i6 ,
737 const unsigned i7 )
const
739 ARRAY_CHECK( array_check_rank( m_rank , 7 ) );
741 array_offset<array_order,7>(
m_stride,i1,i2,i3,i4,i5,i6,i7) ];
745 const unsigned i3 ,
const unsigned i4 ,
746 const unsigned i5 ,
const unsigned i6 )
const
748 ARRAY_CHECK( array_check_rank( m_rank , 6 ) );
749 return m_ptr[ array_offset<array_order,6>(
m_stride,i1,i2,i3,i4,i5,i6) ];
753 const unsigned i3 ,
const unsigned i4 ,
754 const unsigned i5 )
const
756 ARRAY_CHECK( array_check_rank( m_rank , 5 ) );
757 return m_ptr[ array_offset<array_order,5>(
m_stride,i1,i2,i3,i4,i5) ];
761 const unsigned i3 ,
const unsigned i4 )
const
763 ARRAY_CHECK( array_check_rank( m_rank , 4 ) );
764 return m_ptr[ array_offset<array_order,4>(
m_stride,i1,i2,i3,i4) ];
768 const unsigned i3 )
const
770 ARRAY_CHECK( array_check_rank( m_rank , 3 ) );
771 return m_ptr[ array_offset<array_order,3>(
m_stride,i1,i2,i3) ];
776 ARRAY_CHECK( array_check_rank( m_rank , 2 ) );
782 ARRAY_CHECK( array_check_rank( m_rank , 1 ) );
792 typedef typename ArrayReverse< Array >::type
ReverseType ;
797 :
m_ptr(NULL), m_rank(0)
807 Copy<8>( m_tag , rhs.m_tag );
813 m_rank = rhs.m_rank ;
815 Copy<8>( m_tag , rhs.m_tag );
824 Copy<8>( m_tag , rhs.m_tag );
831 m_rank = rhs.m_rank ;
833 Copy<8>( m_tag , rhs.m_tag );
843 class Tag1 ,
class Tag2 ,
class Tag3 ,
class Tag4 ,
844 class Tag5 ,
class Tag6 ,
class Tag7 ,
class Tag8 >
850 enum { inRank = a_t::Rank };
851 enum { inNatural = a_t::Natural };
853 Copy< inRank >(
m_stride , rhs.m_stride );
857 for ( ; i < inRank ; ++i ) { m_tag[i] = rhs.tag((inRank-1)-i); }
860 for ( ; i < inRank ; ++i ) { m_tag[i] = rhs.tag(i); }
862 for ( ; i < 8 ; ++i ) { m_tag[i] = NULL ; }
869 const unsigned rank ,
870 const unsigned *
const dims ,
872 :
m_ptr( ptr ), m_rank( rank )
877 for ( i = 0 ; i <
rank ; ++i ) {
m_stride[i] = n *= dims[(rank-1)-i]; }
878 for ( ; i < 8 ; ++i ) {
m_stride[i] = 0 ; }
879 for ( i = 0 ; i <
rank ; ++i ) { m_tag[i] = tags[(rank-1)-i]; }
880 for ( ; i < 8 ; ++i ) { m_tag[i] = NULL ; }
885 for ( i = 0 ; i <
rank ; ++i ) {
m_stride[i] = n *= dims[i] ; }
886 for ( ; i < 8 ; ++i ) {
m_stride[i] = 0 ; }
887 for ( i = 0 ; i <
rank ; ++i ) { m_tag[i] = tags[i]; }
888 for ( ; i < 8 ; ++i ) { m_tag[i] = NULL ; }
908 class , class , class , class ,
909 class , class , class ,
class >
value_type * contiguous_data() const
Pointer to contiguous block of member data.
Array(const ReverseType &rhs)
Copy constructor for reverse type.
value_type & operator()(const unsigned i1, const unsigned i2, const unsigned i3, const unsigned i4, const unsigned i5) const
Access member of a Rank 5 array.
value_type & operator()(const unsigned i1, const unsigned i2, const unsigned i3, const unsigned i4, const unsigned i5, const unsigned i6) const
Access member of a Rank 6 array.
Array(value_type *arg_ptr, const unsigned n1, const unsigned n2)
Construct a Rank 2..8 array; use Tag#::Size for defaults. The input dimensions are the 2 slowest stri...
void dimensions(std::vector< unsigned > &n)
Dimension of all ordinate.
Array(value_type *arg_ptr, const unsigned n1, const unsigned n2, const unsigned n3)
Construct a Rank 3..8 array; use Tag#::Size for defaults. The input dimensions are the 3 slowest stri...
void Copy(T *, const T &)
dst[k] = src , k = 0..N-1
Array(const Array< value_type, order, Tag1, Tag2, Tag3, Tag4, Tag5, Tag6, Tag7, Tag8 > &rhs)
Copy constructor from an Array with compile-time defined rank and dimension tags. ...
bool contiguous() const
If the member data storage is contiguous.
Scalar value_type
Type of member data.
unsigned rank() const
Rank of the array is the number of non-void dimension tags.
value_type & operator()(const unsigned i1, const unsigned i2, const unsigned i3, const unsigned i4) const
Access member of a Rank 4 array.
unsigned size_type
Type for sizes.
Use the Natural or C-language ordering for multi-dimensions where the right-most dimension is stride-...
Array()
Default constructor.
value_type * m_ptr
Pointer to contiguous block of members.
Array(value_type *arg_ptr, const unsigned n1, const unsigned n2, const unsigned n3, const unsigned n4, const unsigned n5, const unsigned n6, const unsigned n7)
Construct a Rank 7..8 array; use Tag#::Size for defaults. The input dimensions are the 7 slowest stri...
unsigned dimension(const unsigned ordinate) const
Dimension of the given ordinate.
value_type & operator()(const unsigned i1, const unsigned i2, const unsigned i3, const unsigned i4, const unsigned i5, const unsigned i6, const unsigned i7, const unsigned i8) const
Access member via Rank 8 multi-index.
unsigned rank() const
Rank of the array is the number of non-void dimension tags.
Array(value_type *arg_ptr, const unsigned n1, const unsigned n2, const unsigned n3, const unsigned n4, const unsigned n5, const unsigned n6)
Construct a Rank 6..8 array; use Tag#::Size for defaults. The input dimensions are the 6 slowest stri...
size_type size() const
Total number of member data items.
virtual const char * name() const =0
Name of the tag, typically the name of the derived class.
Scalar value_type
Type of member data.
value_type * contiguous_data() const
Pointer to contiguous block of member data.
Array(value_type *arg_ptr, const unsigned *const dims)
Construct with array of dimensions.
bool natural() const
If the multidimension follows the natural ordering.
tag_type tag(const unsigned ordinate) const
Access the dimension tag-singleton for a given ordinate.
Use the Reverse or Fortran-language ordering for multi-dimensions where the left-most dimension is st...
Array(value_type *arg_ptr)
Construct a Rank 1..8 array; use Tag#::Size for defaults.
Array truncate(const unsigned i) const
Generate a subarray view of the array with the slowest striding ordinate offset by i and removed...
bool reverse() const
If the multidimension follows the reverse (Fortran) ordering.
value_type & operator()(const unsigned i1) const
Access member of a Rank 1 array.
value_type & operator()(const unsigned i1, const unsigned i2, const unsigned i3) const
Access member of a Rank 3 array.
Abstract base class for array dimension tags supplied to the Array template class.
ArrayTruncate< Array >::type TruncateType
Subarray type that removes the slowest striding dimension (first natural or last fortran ordinate)...
Array & operator=(const Array &rhs)
Assignment operator.
Array(const ReverseType &rhs)
Copy constructor for compatible reverse type.
ArrayOrder
Define Natural (C-language) or Fortran ordering of array dimensions. A RankZero array does not ha...
static const ArrayDimension & tag()
Singleton.
unsigned size_type
Type for sizes.
size_type size() const
Total number of data items.
const char * name() const
Name of the tag, typically the name of the derived class.
bool contiguous() const
If the member data storage is contiguous.
const ArrayDimTag * tag_type
Type of runtime dimension tags.
Array(value_type *arg_ptr, const unsigned n1, const unsigned n2, const unsigned n3, const unsigned n4)
Construct a Rank 4..8 array; use Tag#::Size for defaults. The input dimensions are the 4 slowest stri...
virtual unsigned to_index(unsigned dimension, const std::string &label) const
Given a dimension and input strige produce an index. Default to converting label to an integer...
void dimensions(std::vector< unsigned > &n)
Dimensions of all ordinates.
bool reverse() const
If the multidimension follows the reverse (Fortran) ordering.
value_type * m_ptr
Pointer to contiguous block of members.
An anonymous array dimension tag, which is NOT the recommended usage.
value_type & operator()(const unsigned i1, const unsigned i2, const unsigned i3, const unsigned i4, const unsigned i5, const unsigned i6, const unsigned i7) const
Access member of a Rank 7 array.
Special tag to indicate that an array specification has degenerated to rank-zero, i...
value_type & operator[](size_type i) const
Access member via full ordering of members.
unsigned dimension(const unsigned ordinal) const
Dimension of the given ordinate.
const ArrayDimTag * tag_type
Type of runtime dimension tags.
unsigned dimension() const
Dimension of the given ordinate.
Array(value_type *arg_ptr, const unsigned n1)
Construct a Rank 1..8 array; use Tag#::Size for defaults. The input dimension is the slowest stride...
Array(value_type *arg_ptr, const unsigned n1, const unsigned n2, const unsigned n3, const unsigned n4, const unsigned n5)
Construct a Rank 5..8 array; use Tag#::Size for defaults. The input dimensions are the 5 slowest stri...
tag_type tag(const unsigned ordinal) const
Access the dimension tag-singleton for a given ordinate.
value_type & operator()(const unsigned i1, const unsigned i2, const unsigned i3, const unsigned i4, const unsigned i5, const unsigned i6, const unsigned i7, const unsigned i8) const
Access member of a Rank 8 array.
ArrayReverse< Array >::type ReverseType
The compatible multidimensional array with reversed multi-index ordering and dimension tags...
Array(value_type *arg_ptr, const unsigned n1, const unsigned n2, const unsigned n3, const unsigned n4, const unsigned n5, const unsigned n6, const unsigned n7, const unsigned n8)
Construct a Rank 8 array.
bool natural() const
If the multidimension follows the natural ordering.
unsigned m_rank
Rank of the array.
TruncateType truncate(const unsigned i) const
Generate a subarray view of the array with the slowest striding ordinate offset by i and removed...
size_type m_stride[Rank]
Array of strides, smallest to largest.
virtual std::string to_string(unsigned dimension, unsigned index) const
Given a dimension and index produce a string for output. Default to converting index to a string...
value_type & operator()(const unsigned i1, const unsigned i2) const
Access member of a Rank 2 array.
The preferred multi-dimensional Array interface with compile-time user-defined dimension ordinate...
Array(const Array &rhs)
Copy constructor.
value_type & operator[](size_type i) const
Access member via offset into contiguous block.