Sierra Toolkit Version of the Day
Array.hpp
Go to the documentation of this file.
00001 
00015 #ifndef STK_UTIL_UTIL_Array_h
00016 #define STK_UTIL_UTIL_Array_h
00017 
00018 #include <cstddef>
00019 #include <utility>
00020 #include <algorithm>
00021 #include <stdexcept>
00022 #include <stk_util/util/TypeList.hpp>
00023 #include <stk_util/diag/FArray.hpp>
00024 
00025 namespace sierra {
00026 
00031 
00073 template< class ElementType,
00074     class Tag0,
00075     class Tag1 = TypeListEnd,
00076     class Tag2 = TypeListEnd,
00077     class Tag3 = TypeListEnd,
00078     class Tag4 = TypeListEnd,
00079     class Tag5 = TypeListEnd,
00080     class Tag6 = TypeListEnd,
00081     class Tag7 = TypeListEnd>
00082 class Array;
00083 
00084 //----------------------------------------------------------------------
00091 template< class ElementType,
00092     class Tag0,
00093     class Tag1 = TypeListEnd,
00094     class Tag2 = TypeListEnd,
00095     class Tag3 = TypeListEnd,
00096     class Tag4 = TypeListEnd,
00097     class Tag5 = TypeListEnd,
00098     class Tag6 = TypeListEnd,
00099     class Tag7 = TypeListEnd,
00100           class A = std::allocator<ElementType> >
00101 class ArrayContainer;
00102 
00103 
00104 //----------------------------------------------------------------------
00105 // A typeless array is invalid...
00106 
00107 template< class Tag0,
00108     class Tag1,
00109     class Tag2,
00110     class Tag3,
00111     class Tag4,
00112     class Tag5,
00113     class Tag6,
00114     class Tag7>
00115 class Array<void, Tag0, Tag1, Tag2, Tag3, Tag4, Tag5, Tag6, Tag7> {};
00116 
00117 template <class ElementType>
00118 class Array<ElementType, TypeListEnd, TypeListEnd, TypeListEnd, TypeListEnd, TypeListEnd, TypeListEnd, TypeListEnd, TypeListEnd>
00119 {
00120 public:
00121   typedef ElementType element_type;
00122 
00123   typedef Array< element_type, TypeListEnd, TypeListEnd, TypeListEnd, TypeListEnd, TypeListEnd, TypeListEnd, TypeListEnd, TypeListEnd> SelfType;
00124 
00125 //  typedef Array< const element_type, TypeListEnd, TypeListEnd, TypeListEnd, TypeListEnd, TypeListEnd, TypeListEnd, TypeListEnd, TypeListEnd > Const;
00126 
00127   typedef typename MakeTypeList<TypeListEnd, TypeListEnd, TypeListEnd, TypeListEnd, TypeListEnd, TypeListEnd, TypeListEnd, TypeListEnd>::type TagList;
00128 
00131   enum { NumDim = 0 };
00132 };
00133 
00134 
00135 
00136 //----------------------------------------------------------------------
00137 //----------------------------------------------------------------------
00138 template< class ElementType,
00139     class Tag0,
00140     class Tag1,
00141     class Tag2,
00142     class Tag3,
00143     class Tag4,
00144     class Tag5,
00145     class Tag6,
00146     class Tag7>
00147 class Array : public FArray<ElementType, TypeListLength<typename MakeTypeList<Tag0, Tag1, Tag2, Tag3, Tag4, Tag5, Tag6, Tag7>::type>::value>
00148 {
00149 public:
00150   typedef ElementType element_type;
00151 
00152   typedef Array< element_type, Tag0, Tag1, Tag2, Tag3, Tag4, Tag5, Tag6, Tag7> SelfType;
00153 
00154   typedef Array< const element_type, Tag0, Tag1, Tag2, Tag3, Tag4, Tag5, Tag6, Tag7 > Const;
00155 
00156   typedef typename MakeTypeList<Tag0, Tag1, Tag2, Tag3, Tag4, Tag5, Tag6, Tag7>::type TagList;
00157 
00158   typedef FArray<ElementType, TypeListLength<typename MakeTypeList<Tag0, Tag1, Tag2, Tag3, Tag4, Tag5, Tag6, Tag7>::type>::value> BaseType;
00159 
00162   enum { NumDim = TypeListLength<TagList>::value };
00163 
00164   typedef Array< ElementType,
00165      typename TypeListAt<typename TypeListEraseAt<TagList, NumDim - 1>::list_type, 0>::type,
00166      typename TypeListAt<typename TypeListEraseAt<TagList, NumDim - 1>::list_type, 1>::type,
00167      typename TypeListAt<typename TypeListEraseAt<TagList, NumDim - 1>::list_type, 2>::type,
00168      typename TypeListAt<typename TypeListEraseAt<TagList, NumDim - 1>::list_type, 3>::type,
00169      typename TypeListAt<typename TypeListEraseAt<TagList, NumDim - 1>::list_type, 4>::type,
00170      typename TypeListAt<typename TypeListEraseAt<TagList, NumDim - 1>::list_type, 5>::type,
00171      typename TypeListAt<typename TypeListEraseAt<TagList, NumDim - 1>::list_type, 6>::type,
00172      TypeListEnd> Trunc;
00173 
00174   //----------------------------------------
00177   const unsigned * dimension() const {
00178     return BaseType::dimension();
00179   }
00180 
00181   const unsigned * stride() const {
00182     return BaseType::stride();
00183   }
00184 
00185   template<unsigned I>
00186   unsigned dimension() const {
00187     enum { ok = stk::StaticAssert< I < NumDim >::OK };
00188 
00189     return BaseType::m_dim[I];
00190   }
00191 
00192   unsigned dimension( const unsigned i ) const {
00193     this->array_dimension_verify(0, i, NumDim );
00194     return BaseType::m_dim[i];
00195   }
00196 
00197   unsigned stride( const unsigned i ) const {
00198     this->array_dimension_verify(0, i, NumDim );
00199     return BaseType::m_stride[i];
00200   }
00201 
00202   template<unsigned I>
00203   unsigned stride() const {
00204     enum { ok = stk::StaticAssert< I < NumDim >::OK };
00205     return BaseType::m_stride[I];
00206   }
00207 
00208   template<class Tag>
00209   unsigned dimension() const{
00210     enum { I  = TypeListIndex<TagList, Tag>::value };
00211     enum { ok = stk::StaticAssert< 0 <= I >::OK };
00212     return BaseType::m_dim[I];
00213   }
00214 
00215   template<class Tag, unsigned Ordinal>
00216   unsigned dimension() const {
00217     enum { I  = TypeListIndex<TagList, Tag, Ordinal>::value };
00218     enum { ok = stk::StaticAssert< 0 <= I >::OK };
00219     return BaseType::m_dim[I];
00220   }
00221 
00222   template<class Tag>
00223   unsigned stride() const {
00224     enum { I  = TypeListIndex<TagList, Tag>::value };
00225     enum { ok = stk::StaticAssert< 0 <= I >::OK };
00226     return BaseType::m_stride[I];
00227   }
00228 
00229   template<class Tag, unsigned Ordinal>
00230   unsigned stride() const {
00231     enum { I  = TypeListIndex<TagList, Tag, Ordinal>::value };
00232     enum { ok = stk::StaticAssert< 0 <= I >::OK };
00233     return BaseType::m_stride[I];
00234   }
00235 
00236   bool operator == ( const SelfType & a ) const {
00237     return ArrayHelper<NumDim>::equal( BaseType::m_dim, a.m_dim ) &&
00238       ArrayHelper<NumDim>::equal(BaseType::m_dim, BaseType::m_ptr, BaseType::m_stride, a.m_ptr, a.m_stride);
00239   }
00240 
00241   template<typename T>
00242   bool operator == (const Array<T, Tag0, Tag1, Tag2, Tag3, Tag4, Tag5, Tag6, Tag7> & a) const {
00243     return ArrayHelper<NumDim>::equal( BaseType::m_dim, a.dimension() ) &&
00244       ArrayHelper<NumDim>::equal(BaseType::m_dim, BaseType::m_ptr, BaseType::m_stride, a.ptr(), a.stride());
00245   }
00246 
00247   bool operator != ( const SelfType & a ) const {
00248     return ! operator == ( a );
00249   }
00250 
00251   template<typename T>
00252   bool operator != ( const Array<T, Tag0, Tag1, Tag2, Tag3, Tag4, Tag5, Tag6, Tag7> & a ) const {
00253     return ! operator == ( a );
00254   }
00255 
00256 public:
00257   ~Array()
00258   {}
00259 
00260   Array() : BaseType()
00261   {}
00262 
00263   Array( const SelfType & a )
00264     : BaseType( a )
00265   {}
00266 
00267   template<typename T>
00268   Array( const Array<T, Tag0, Tag1, Tag2, Tag3, Tag4, Tag5, Tag6, Tag7> & a )
00269     : BaseType( a )
00270   {}
00271 
00272   Array( element_type * const in_ptr,
00273    const unsigned n0, const unsigned n1,
00274    const unsigned n2, const unsigned n3,
00275    const unsigned n4, const unsigned n5,
00276    const unsigned n6, const unsigned n7 )
00277     : BaseType( in_ptr, n0, n1, n2, n3, n4, n5, n6, n7)
00278   {}
00279 
00280   Array( element_type * const in_ptr,
00281    const unsigned n0, const unsigned n1,
00282    const unsigned n2, const unsigned n3,
00283    const unsigned n4, const unsigned n5,
00284    const unsigned n6 )
00285     : BaseType( in_ptr, n0, n1, n2, n3, n4, n5, n6)
00286   {}
00287 
00288   Array( element_type * const in_ptr,
00289    const unsigned n0, const unsigned n1,
00290    const unsigned n2, const unsigned n3,
00291    const unsigned n4, const unsigned n5 )
00292     : BaseType( in_ptr, n0, n1, n2, n3, n4, n5)
00293   {}
00294 
00295   Array( element_type * const in_ptr,
00296    const unsigned n0, const unsigned n1,
00297    const unsigned n2, const unsigned n3,
00298    const unsigned n4 )
00299     : BaseType( in_ptr, n0, n1, n2, n3, n4)
00300   {}
00301 
00302   Array( element_type * const in_ptr,
00303    const unsigned n0, const unsigned n1,
00304    const unsigned n2, const unsigned n3 )
00305     : BaseType( in_ptr, n0, n1, n2, n3)
00306   {}
00307 
00308   Array( element_type * const in_ptr,
00309    const unsigned n0, const unsigned n1,
00310    const unsigned n2 )
00311     : BaseType( in_ptr, n0, n1, n2)
00312   {}
00313 
00314   Array( element_type * const in_ptr,
00315    const unsigned n0, const unsigned n1 )
00316     : BaseType( in_ptr, n0, n1)
00317   {}
00318 
00319   Array( element_type * const in_ptr,
00320    const unsigned n0 )
00321     : BaseType( in_ptr, n0)
00322   {}
00323 
00324   Array( element_type * const in_ptr,
00325    const unsigned n[NumDim] )
00326     : BaseType( in_ptr, n){}
00327 
00328   void set( const SelfType & a ) {
00329     BaseType::m_ptr = a.m_ptr;
00330 
00331     ArrayHelper<NumDim  >::copy( a.m_dim, BaseType::m_dim );
00332     ArrayHelper<NumDim+1>::copy( a.m_stride, BaseType::m_stride );
00333   }
00334 
00335   void set( element_type * const in_ptr,
00336       const unsigned n0, const unsigned n1,
00337       const unsigned n2, const unsigned n3,
00338       const unsigned n4, const unsigned n5,
00339       const unsigned n6, const unsigned n7 ) {
00340     BaseType::set(in_ptr, n0, n1, n2, n3, n4, n5, n6, n7);
00341   }
00342 
00343   void set( element_type * const in_ptr,
00344       const unsigned n0, const unsigned n1,
00345       const unsigned n2, const unsigned n3,
00346       const unsigned n4, const unsigned n5,
00347       const unsigned n6 ) {
00348     BaseType::set(in_ptr, n0, n1, n2, n3, n4, n5, n6);
00349   }
00350 
00351   void set( element_type * const in_ptr,
00352       const unsigned n0, const unsigned n1,
00353       const unsigned n2, const unsigned n3,
00354       const unsigned n4, const unsigned n5 ) {
00355     BaseType::set(in_ptr, n0, n1, n2, n3, n4, n5);
00356   }
00357 
00358   void set( element_type * const in_ptr,
00359       const unsigned n0, const unsigned n1,
00360       const unsigned n2, const unsigned n3,
00361       const unsigned n4 ) {
00362     BaseType::set(in_ptr, n0, n1, n2, n3, n4);
00363   }
00364 
00365   void set( element_type * const in_ptr,
00366       const unsigned n0, const unsigned n1,
00367       const unsigned n2, const unsigned n3 ) {
00368     BaseType::set(in_ptr, n0, n1, n2, n3);
00369   }
00370 
00371   void set( element_type * const in_ptr,
00372       const unsigned n0, const unsigned n1,
00373       const unsigned n2 ) {
00374     BaseType::set(in_ptr, n0, n1, n2);
00375   }
00376 
00377   void set( element_type * const in_ptr,
00378       const unsigned n0, const unsigned n1 ) {
00379     BaseType::set(in_ptr, n0, n1);
00380   }
00381 
00382   void set( element_type * const in_ptr,
00383       const unsigned n0 ) {
00384     BaseType::set(in_ptr, n0);
00385   }
00386 
00387   void set( element_type * const in_ptr,
00388       const unsigned n[NumDim] ) {
00389     BaseType::set(in_ptr, n);
00390   }
00391 
00392   Trunc dive(int i) {
00393     this->array_dimension_verify(0, i, BaseType::m_dim[NumDim - 1] );
00394 
00395     element_type *calc_ptr = BaseType::m_ptr + i*BaseType::m_stride[NumDim - 1];
00396 
00397     return Trunc(calc_ptr, BaseType::m_dim);
00398   }
00399 
00400   const Trunc dive(int i) const {
00401     this->array_dimension_verify(0, i, BaseType::m_dim[NumDim - 1] );
00402 
00403     element_type *calc_ptr = BaseType::m_ptr + i*BaseType::m_stride[NumDim - 1];
00404 
00405     return Trunc(calc_ptr, BaseType::m_dim);
00406   }
00407 
00408   template<typename T>
00409   void copy( const Array<T, Tag0, Tag1, Tag2, Tag3, Tag4, Tag5, Tag6, Tag7> & a ) {
00410     ArrayHelper<NumDim>::copy(BaseType::m_dim, BaseType::m_ptr, BaseType::m_stride, a.ptr(), a.stride() );
00411   }
00412 
00413   template<typename T>
00414   void fill( const T & value ) {
00415     ArrayHelper<NumDim>::fill(BaseType::m_dim, BaseType::m_ptr, BaseType::m_stride, value);
00416   }
00417 
00418 private:
00419   // Mutation (non-const methods) is not allowed so as to
00420   // provide derived classes with complete control over mutation.
00421 
00422   SelfType & operator = ( SelfType const & a );
00423 };
00424 
00425 template< class ElementType,
00426     class Tag0,
00427     class Tag1,
00428     class Tag2,
00429     class Tag3,
00430     class Tag4,
00431     class Tag5,
00432     class Tag6,
00433     class Tag7,
00434           class A>
00435 class ArrayContainer
00436   : public Array<ElementType, Tag0, Tag1, Tag2, Tag3, Tag4, Tag5, Tag6, Tag7>
00437 {
00438 public:
00439   typedef ArrayContainer<ElementType, Tag0, Tag1, Tag2, Tag3, Tag4, Tag5, Tag6, Tag7> SelfType;
00440 
00441   typedef Array<ElementType, Tag0, Tag1, Tag2, Tag3, Tag4, Tag5, Tag6, Tag7> BaseType;
00442 
00443   typedef typename BaseType::element_type element_type;
00444 
00445   typedef typename BaseType::TagList TagList;
00446 
00447   enum { NumDim = BaseType::NumDim };
00448 
00449 private:
00450   using BaseType::m_ptr;
00451   using BaseType::m_dim;
00452   using BaseType::m_stride;
00453 
00454   void resize_memory( const unsigned new_size ) {
00455     if ( m_capacity < new_size ) {
00456       if ( m_capacity )
00457         m_allocator.deallocate(m_ptr, m_capacity);
00458       m_capacity = new_size;
00459       m_ptr = m_allocator.allocate(m_capacity);
00460     }
00461   }
00462 
00463 public:
00464   ~ArrayContainer() {
00465     if ( m_capacity ) {
00466       m_allocator.deallocate(m_ptr, m_capacity);
00467       m_capacity = 0;
00468     }
00469   }
00470 
00471   //----------------------------------------
00472   // Constructors for initial view of contiguous memory.
00473 
00474   ArrayContainer( )
00475     : BaseType( ),
00476       m_capacity(0)
00477   {}
00478 
00479   ArrayContainer( const SelfType & a )
00480     : BaseType(),
00481       m_capacity(0)
00482   {
00483     resize_memory( BaseType::set_dim( a.m_dim ) );
00484     this->copy(a);
00485   }
00486 
00487   template<typename T>
00488   ArrayContainer( const Array<T, Tag0, Tag1, Tag2, Tag3, Tag4, Tag5, Tag6, Tag7> & a )
00489     : BaseType(), m_capacity(0)
00490   {
00491     resize_memory( BaseType::set_dim( a.dimension() ) );
00492     this->copy(a);
00493   }
00494 
00495   SelfType & operator = ( const SelfType & a ) {
00496     resize_memory( BaseType::set_dim( a.dimension() ) );
00497     this->copy(a);
00498     return *this;
00499   }
00500 
00501   template<typename T>
00502   SelfType & operator =( const Array<T, Tag0, Tag1, Tag2, Tag3, Tag4, Tag5, Tag6, Tag7> & a ) {
00503     resize_memory( BaseType::set_dim( a.dimension() ) );
00504     this->copy(a);
00505     return *this;
00506   }
00507 
00508   //----------------------------------------
00509 
00510   ArrayContainer( const unsigned n0, const unsigned n1,
00511       const unsigned n2, const unsigned n3,
00512       const unsigned n4, const unsigned n5,
00513       const unsigned n6, const unsigned n7 )
00514     : BaseType(NULL, n0, n1, n2, n3, n4, n5, n6, n7 ),
00515       m_capacity(0)
00516   {
00517     resize_memory( m_stride[NumDim] );
00518   }
00519 
00520   ArrayContainer( const unsigned n0, const unsigned n1,
00521       const unsigned n2, const unsigned n3,
00522       const unsigned n4, const unsigned n5,
00523       const unsigned n6 )
00524     : BaseType( NULL, n0, n1, n2, n3, n4, n5, n6 ),
00525       m_capacity(0)
00526   {
00527     resize_memory( m_stride[NumDim] );
00528   }
00529 
00530   ArrayContainer( const unsigned n0, const unsigned n1,
00531       const unsigned n2, const unsigned n3,
00532       const unsigned n4, const unsigned n5 )
00533     : BaseType( NULL, n0, n1, n2, n3, n4, n5 ),
00534       m_capacity(0)
00535   {
00536     resize_memory( m_stride[NumDim] );
00537   }
00538 
00539   ArrayContainer( const unsigned n0, const unsigned n1,
00540       const unsigned n2, const unsigned n3,
00541       const unsigned n4 )
00542     : BaseType( NULL, n0, n1, n2, n3, n4 ),
00543       m_capacity(0)
00544   {
00545     resize_memory( m_stride[NumDim] );
00546   }
00547 
00548   ArrayContainer( const unsigned n0, const unsigned n1,
00549       const unsigned n2, const unsigned n3 )
00550     : BaseType( NULL, n0, n1, n2, n3 ),
00551       m_capacity(0)
00552   {
00553     resize_memory( m_stride[NumDim] );
00554   }
00555 
00556   ArrayContainer( const unsigned n0, const unsigned n1,
00557       const unsigned n2 )
00558     : BaseType( NULL, n0, n1, n2 ),
00559       m_capacity(0)
00560   {
00561     resize_memory( m_stride[NumDim] );
00562   }
00563 
00564   ArrayContainer( const unsigned n0, const unsigned n1 )
00565     : BaseType( NULL, n0, n1 ),
00566       m_capacity(0)
00567   {
00568     resize_memory( m_stride[NumDim] );
00569   }
00570 
00571   ArrayContainer( const unsigned n0 )
00572     : BaseType( NULL, n0 ),
00573       m_capacity(0)
00574   {
00575     resize_memory( m_stride[NumDim] );
00576   }
00577 
00578   ArrayContainer( const unsigned n[] )
00579     : BaseType( NULL, n ),
00580       m_capacity(0)
00581   {
00582     resize_memory( m_stride[NumDim] );
00583   }
00584 
00585   //----------------------------------------
00586 
00587   template<typename T>
00588   SelfType & resize( const Array<T, Tag0, Tag1, Tag2, Tag3, Tag4, Tag5, Tag6, Tag7> & a ) {
00589     resize_memory( BaseType::set_dim( a.dimension() ) );
00590     return *this;
00591   }
00592 
00593   SelfType & resize( const unsigned n0, const unsigned n1,
00594          const unsigned n2, const unsigned n3,
00595          const unsigned n4, const unsigned n5,
00596          const unsigned n6, const unsigned n7 )
00597   {
00598     resize_memory(BaseType::set_dim(n0, n1, n2, n3, n4, n5, n6, n7));
00599     return *this;
00600   }
00601 
00602   SelfType & resize( const unsigned n0, const unsigned n1,
00603          const unsigned n2, const unsigned n3,
00604          const unsigned n4, const unsigned n5,
00605          const unsigned n6 )
00606   {
00607     resize_memory(BaseType::set_dim(n0, n1, n2, n3, n4, n5, n6));
00608     return *this;
00609   }
00610 
00611   SelfType & resize( const unsigned n0, const unsigned n1,
00612          const unsigned n2, const unsigned n3,
00613          const unsigned n4, const unsigned n5 )
00614   {
00615     resize_memory(BaseType::set_dim(n0, n1, n2, n3, n4, n5));
00616     return *this;
00617   }
00618 
00619   SelfType & resize( const unsigned n0, const unsigned n1,
00620          const unsigned n2, const unsigned n3,
00621          const unsigned n4 )
00622   {
00623     resize_memory(BaseType::set_dim(n0, n1, n2, n3, n4));
00624     return *this;
00625   }
00626 
00627   SelfType & resize( const unsigned n0, const unsigned n1,
00628          const unsigned n2, const unsigned n3 )
00629   {
00630     resize_memory(BaseType::set_dim(n0, n1, n2, n3));
00631     return *this;
00632   }
00633 
00634 
00635   SelfType & resize( const unsigned n0, const unsigned n1,
00636          const unsigned n2 )
00637   {
00638     resize_memory(BaseType::set_dim(n0, n1, n2));
00639     return *this;
00640   }
00641 
00642   SelfType & resize( const unsigned n0, const unsigned n1 )
00643   {
00644     resize_memory(BaseType::set_dim(n0, n1));
00645     return *this;
00646   }
00647 
00648   SelfType & resize( const unsigned n0 )
00649   {
00650     resize_memory(BaseType::set_dim(n0));
00651     return *this;
00652   }
00653 
00654   SelfType & resize( const unsigned n[] )
00655   {
00656     resize_memory( BaseType::set_dim(n) );
00657     return *this;
00658   }
00659 
00660   //----------------------------------------
00661 
00662 private:
00663   A             m_allocator;
00664   unsigned      m_capacity;
00665 };
00666 
00670 
00671 } // namespace sierra
00672 
00673 #endif // STK_UTIL_UTIL_Array_h
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines