Sierra Toolkit  Version of the Day
Array.hpp
Go to the documentation of this file.
1 
15 #ifndef STK_UTIL_UTIL_Array_h
16 #define STK_UTIL_UTIL_Array_h
17 
18 #include <cstddef>
19 #include <utility>
20 #include <algorithm>
21 #include <stdexcept>
22 #include <stk_util/util/TypeList.hpp>
23 #include <stk_util/diag/FArray.hpp>
24 
25 namespace sierra {
26 
31 
73 template< class ElementType,
74  class Tag0,
75  class Tag1 = TypeListEnd,
76  class Tag2 = TypeListEnd,
77  class Tag3 = TypeListEnd,
78  class Tag4 = TypeListEnd,
79  class Tag5 = TypeListEnd,
80  class Tag6 = TypeListEnd,
81  class Tag7 = TypeListEnd>
82 class Array;
83 
84 //----------------------------------------------------------------------
91 template< class ElementType,
92  class Tag0,
93  class Tag1 = TypeListEnd,
94  class Tag2 = TypeListEnd,
95  class Tag3 = TypeListEnd,
96  class Tag4 = TypeListEnd,
97  class Tag5 = TypeListEnd,
98  class Tag6 = TypeListEnd,
99  class Tag7 = TypeListEnd,
100  class A = std::allocator<ElementType> >
102 
103 
104 //----------------------------------------------------------------------
105 // A typeless array is invalid...
106 
107 template< class Tag0,
108  class Tag1,
109  class Tag2,
110  class Tag3,
111  class Tag4,
112  class Tag5,
113  class Tag6,
114  class Tag7>
115 class Array<void, Tag0, Tag1, Tag2, Tag3, Tag4, Tag5, Tag6, Tag7> {};
116 
117 template <class ElementType>
119 {
120 public:
121  typedef ElementType element_type;
122 
124 
125 // typedef Array< const element_type, TypeListEnd, TypeListEnd, TypeListEnd, TypeListEnd, TypeListEnd, TypeListEnd, TypeListEnd, TypeListEnd > Const;
126 
128 
131  enum { NumDim = 0 };
132 };
133 
134 
135 
136 //----------------------------------------------------------------------
137 //----------------------------------------------------------------------
138 template< class ElementType,
139  class Tag0,
140  class Tag1,
141  class Tag2,
142  class Tag3,
143  class Tag4,
144  class Tag5,
145  class Tag6,
146  class Tag7>
147 class Array : public FArray<ElementType, TypeListLength<typename MakeTypeList<Tag0, Tag1, Tag2, Tag3, Tag4, Tag5, Tag6, Tag7>::type>::value>
148 {
149 public:
150  typedef ElementType element_type;
151 
152  typedef Array< element_type, Tag0, Tag1, Tag2, Tag3, Tag4, Tag5, Tag6, Tag7> SelfType;
153 
154  typedef Array< const element_type, Tag0, Tag1, Tag2, Tag3, Tag4, Tag5, Tag6, Tag7 > Const;
155 
156  typedef typename MakeTypeList<Tag0, Tag1, Tag2, Tag3, Tag4, Tag5, Tag6, Tag7>::type TagList;
157 
158  typedef FArray<ElementType, TypeListLength<typename MakeTypeList<Tag0, Tag1, Tag2, Tag3, Tag4, Tag5, Tag6, Tag7>::type>::value> BaseType;
159 
162  enum { NumDim = TypeListLength<TagList>::value };
163 
164  typedef Array< ElementType,
165  typename TypeListAt<typename TypeListEraseAt<TagList, NumDim - 1>::list_type, 0>::type,
166  typename TypeListAt<typename TypeListEraseAt<TagList, NumDim - 1>::list_type, 1>::type,
167  typename TypeListAt<typename TypeListEraseAt<TagList, NumDim - 1>::list_type, 2>::type,
168  typename TypeListAt<typename TypeListEraseAt<TagList, NumDim - 1>::list_type, 3>::type,
169  typename TypeListAt<typename TypeListEraseAt<TagList, NumDim - 1>::list_type, 4>::type,
170  typename TypeListAt<typename TypeListEraseAt<TagList, NumDim - 1>::list_type, 5>::type,
171  typename TypeListAt<typename TypeListEraseAt<TagList, NumDim - 1>::list_type, 6>::type,
172  TypeListEnd> Trunc;
173 
174  //----------------------------------------
177  const unsigned * dimension() const {
178  return BaseType::dimension();
179  }
180 
181  const unsigned * stride() const {
182  return BaseType::stride();
183  }
184 
185  template<unsigned I>
186  unsigned dimension() const {
188 
189  return BaseType::m_dim[I];
190  }
191 
192  unsigned dimension( const unsigned i ) const {
193  this->array_dimension_verify(0, i, NumDim );
194  return BaseType::m_dim[i];
195  }
196 
197  unsigned stride( const unsigned i ) const {
198  this->array_dimension_verify(0, i, NumDim );
199  return BaseType::m_stride[i];
200  }
201 
202  template<unsigned I>
203  unsigned stride() const {
205  return BaseType::m_stride[I];
206  }
207 
208  template<class Tag>
209  unsigned dimension() const{
210  enum { I = TypeListIndex<TagList, Tag>::value };
212  return BaseType::m_dim[I];
213  }
214 
215  template<class Tag, unsigned Ordinal>
216  unsigned dimension() const {
217  enum { I = TypeListIndex<TagList, Tag, Ordinal>::value };
219  return BaseType::m_dim[I];
220  }
221 
222  template<class Tag>
223  unsigned stride() const {
224  enum { I = TypeListIndex<TagList, Tag>::value };
226  return BaseType::m_stride[I];
227  }
228 
229  template<class Tag, unsigned Ordinal>
230  unsigned stride() const {
231  enum { I = TypeListIndex<TagList, Tag, Ordinal>::value };
233  return BaseType::m_stride[I];
234  }
235 
236  bool operator == ( const SelfType & a ) const {
237  return ArrayHelper<NumDim>::equal( BaseType::m_dim, a.m_dim ) &&
238  ArrayHelper<NumDim>::equal(BaseType::m_dim, BaseType::m_ptr, BaseType::m_stride, a.m_ptr, a.m_stride);
239  }
240 
241  template<typename T>
242  bool operator == (const Array<T, Tag0, Tag1, Tag2, Tag3, Tag4, Tag5, Tag6, Tag7> & a) const {
243  return ArrayHelper<NumDim>::equal( BaseType::m_dim, a.dimension() ) &&
244  ArrayHelper<NumDim>::equal(BaseType::m_dim, BaseType::m_ptr, BaseType::m_stride, a.ptr(), a.stride());
245  }
246 
247  bool operator != ( const SelfType & a ) const {
248  return ! operator == ( a );
249  }
250 
251  template<typename T>
252  bool operator != ( const Array<T, Tag0, Tag1, Tag2, Tag3, Tag4, Tag5, Tag6, Tag7> & a ) const {
253  return ! operator == ( a );
254  }
255 
256 public:
257  ~Array()
258  {}
259 
260  Array() : BaseType()
261  {}
262 
263  Array( const SelfType & a )
264  : BaseType( a )
265  {}
266 
267  template<typename T>
268  Array( const Array<T, Tag0, Tag1, Tag2, Tag3, Tag4, Tag5, Tag6, Tag7> & a )
269  : BaseType( a )
270  {}
271 
272  Array( element_type * const in_ptr,
273  const unsigned n0, const unsigned n1,
274  const unsigned n2, const unsigned n3,
275  const unsigned n4, const unsigned n5,
276  const unsigned n6, const unsigned n7 )
277  : BaseType( in_ptr, n0, n1, n2, n3, n4, n5, n6, n7)
278  {}
279 
280  Array( element_type * const in_ptr,
281  const unsigned n0, const unsigned n1,
282  const unsigned n2, const unsigned n3,
283  const unsigned n4, const unsigned n5,
284  const unsigned n6 )
285  : BaseType( in_ptr, n0, n1, n2, n3, n4, n5, n6)
286  {}
287 
288  Array( element_type * const in_ptr,
289  const unsigned n0, const unsigned n1,
290  const unsigned n2, const unsigned n3,
291  const unsigned n4, const unsigned n5 )
292  : BaseType( in_ptr, n0, n1, n2, n3, n4, n5)
293  {}
294 
295  Array( element_type * const in_ptr,
296  const unsigned n0, const unsigned n1,
297  const unsigned n2, const unsigned n3,
298  const unsigned n4 )
299  : BaseType( in_ptr, n0, n1, n2, n3, n4)
300  {}
301 
302  Array( element_type * const in_ptr,
303  const unsigned n0, const unsigned n1,
304  const unsigned n2, const unsigned n3 )
305  : BaseType( in_ptr, n0, n1, n2, n3)
306  {}
307 
308  Array( element_type * const in_ptr,
309  const unsigned n0, const unsigned n1,
310  const unsigned n2 )
311  : BaseType( in_ptr, n0, n1, n2)
312  {}
313 
314  Array( element_type * const in_ptr,
315  const unsigned n0, const unsigned n1 )
316  : BaseType( in_ptr, n0, n1)
317  {}
318 
319  Array( element_type * const in_ptr,
320  const unsigned n0 )
321  : BaseType( in_ptr, n0)
322  {}
323 
324  Array( element_type * const in_ptr,
325  const unsigned n[NumDim] )
326  : BaseType( in_ptr, n){}
327 
328  void set( const SelfType & a ) {
329  BaseType::m_ptr = a.m_ptr;
330 
331  ArrayHelper<NumDim >::copy( a.m_dim, BaseType::m_dim );
332  ArrayHelper<NumDim+1>::copy( a.m_stride, BaseType::m_stride );
333  }
334 
335  void set( element_type * const in_ptr,
336  const unsigned n0, const unsigned n1,
337  const unsigned n2, const unsigned n3,
338  const unsigned n4, const unsigned n5,
339  const unsigned n6, const unsigned n7 ) {
340  BaseType::set(in_ptr, n0, n1, n2, n3, n4, n5, n6, n7);
341  }
342 
343  void set( element_type * const in_ptr,
344  const unsigned n0, const unsigned n1,
345  const unsigned n2, const unsigned n3,
346  const unsigned n4, const unsigned n5,
347  const unsigned n6 ) {
348  BaseType::set(in_ptr, n0, n1, n2, n3, n4, n5, n6);
349  }
350 
351  void set( element_type * const in_ptr,
352  const unsigned n0, const unsigned n1,
353  const unsigned n2, const unsigned n3,
354  const unsigned n4, const unsigned n5 ) {
355  BaseType::set(in_ptr, n0, n1, n2, n3, n4, n5);
356  }
357 
358  void set( element_type * const in_ptr,
359  const unsigned n0, const unsigned n1,
360  const unsigned n2, const unsigned n3,
361  const unsigned n4 ) {
362  BaseType::set(in_ptr, n0, n1, n2, n3, n4);
363  }
364 
365  void set( element_type * const in_ptr,
366  const unsigned n0, const unsigned n1,
367  const unsigned n2, const unsigned n3 ) {
368  BaseType::set(in_ptr, n0, n1, n2, n3);
369  }
370 
371  void set( element_type * const in_ptr,
372  const unsigned n0, const unsigned n1,
373  const unsigned n2 ) {
374  BaseType::set(in_ptr, n0, n1, n2);
375  }
376 
377  void set( element_type * const in_ptr,
378  const unsigned n0, const unsigned n1 ) {
379  BaseType::set(in_ptr, n0, n1);
380  }
381 
382  void set( element_type * const in_ptr,
383  const unsigned n0 ) {
384  BaseType::set(in_ptr, n0);
385  }
386 
387  void set( element_type * const in_ptr,
388  const unsigned n[NumDim] ) {
389  BaseType::set(in_ptr, n);
390  }
391 
392  Trunc dive(int i) {
393  this->array_dimension_verify(0, i, BaseType::m_dim[NumDim - 1] );
394 
395  element_type *calc_ptr = BaseType::m_ptr + i*BaseType::m_stride[NumDim - 1];
396 
397  return Trunc(calc_ptr, BaseType::m_dim);
398  }
399 
400  const Trunc dive(int i) const {
401  this->array_dimension_verify(0, i, BaseType::m_dim[NumDim - 1] );
402 
403  element_type *calc_ptr = BaseType::m_ptr + i*BaseType::m_stride[NumDim - 1];
404 
405  return Trunc(calc_ptr, BaseType::m_dim);
406  }
407 
408  template<typename T>
409  void copy( const Array<T, Tag0, Tag1, Tag2, Tag3, Tag4, Tag5, Tag6, Tag7> & a ) {
410  ArrayHelper<NumDim>::copy(BaseType::m_dim, BaseType::m_ptr, BaseType::m_stride, a.ptr(), a.stride() );
411  }
412 
413  template<typename T>
414  void fill( const T & value ) {
415  ArrayHelper<NumDim>::fill(BaseType::m_dim, BaseType::m_ptr, BaseType::m_stride, value);
416  }
417 
418 private:
419  // Mutation (non-const methods) is not allowed so as to
420  // provide derived classes with complete control over mutation.
421 
422  SelfType & operator = ( SelfType const & a );
423 };
424 
425 template< class ElementType,
426  class Tag0,
427  class Tag1,
428  class Tag2,
429  class Tag3,
430  class Tag4,
431  class Tag5,
432  class Tag6,
433  class Tag7,
434  class A>
435 class ArrayContainer
436  : public Array<ElementType, Tag0, Tag1, Tag2, Tag3, Tag4, Tag5, Tag6, Tag7>
437 {
438 public:
439  typedef ArrayContainer<ElementType, Tag0, Tag1, Tag2, Tag3, Tag4, Tag5, Tag6, Tag7> SelfType;
440 
441  typedef Array<ElementType, Tag0, Tag1, Tag2, Tag3, Tag4, Tag5, Tag6, Tag7> BaseType;
442 
443  typedef typename BaseType::element_type element_type;
444 
445  typedef typename BaseType::TagList TagList;
446 
447  enum { NumDim = BaseType::NumDim };
448 
449 private:
450  using BaseType::m_ptr;
451  using BaseType::m_dim;
452  using BaseType::m_stride;
453 
454  void resize_memory( const unsigned new_size ) {
455  if ( m_capacity < new_size ) {
456  if ( m_capacity )
457  m_allocator.deallocate(m_ptr, m_capacity);
458  m_capacity = new_size;
459  m_ptr = m_allocator.allocate(m_capacity);
460  }
461  }
462 
463 public:
464  ~ArrayContainer() {
465  if ( m_capacity ) {
466  m_allocator.deallocate(m_ptr, m_capacity);
467  m_capacity = 0;
468  }
469  }
470 
471  //----------------------------------------
472  // Constructors for initial view of contiguous memory.
473 
474  ArrayContainer( )
475  : BaseType( ),
476  m_capacity(0)
477  {}
478 
479  ArrayContainer( const SelfType & a )
480  : BaseType(),
481  m_capacity(0)
482  {
483  resize_memory( BaseType::set_dim( a.m_dim ) );
484  this->copy(a);
485  }
486 
487  template<typename T>
488  ArrayContainer( const Array<T, Tag0, Tag1, Tag2, Tag3, Tag4, Tag5, Tag6, Tag7> & a )
489  : BaseType(), m_capacity(0)
490  {
491  resize_memory( BaseType::set_dim( a.dimension() ) );
492  this->copy(a);
493  }
494 
495  SelfType & operator = ( const SelfType & a ) {
496  resize_memory( BaseType::set_dim( a.dimension() ) );
497  this->copy(a);
498  return *this;
499  }
500 
501  template<typename T>
502  SelfType & operator =( const Array<T, Tag0, Tag1, Tag2, Tag3, Tag4, Tag5, Tag6, Tag7> & a ) {
503  resize_memory( BaseType::set_dim( a.dimension() ) );
504  this->copy(a);
505  return *this;
506  }
507 
508  //----------------------------------------
509 
510  ArrayContainer( const unsigned n0, const unsigned n1,
511  const unsigned n2, const unsigned n3,
512  const unsigned n4, const unsigned n5,
513  const unsigned n6, const unsigned n7 )
514  : BaseType(NULL, n0, n1, n2, n3, n4, n5, n6, n7 ),
515  m_capacity(0)
516  {
517  resize_memory( m_stride[NumDim] );
518  }
519 
520  ArrayContainer( const unsigned n0, const unsigned n1,
521  const unsigned n2, const unsigned n3,
522  const unsigned n4, const unsigned n5,
523  const unsigned n6 )
524  : BaseType( NULL, n0, n1, n2, n3, n4, n5, n6 ),
525  m_capacity(0)
526  {
527  resize_memory( m_stride[NumDim] );
528  }
529 
530  ArrayContainer( const unsigned n0, const unsigned n1,
531  const unsigned n2, const unsigned n3,
532  const unsigned n4, const unsigned n5 )
533  : BaseType( NULL, n0, n1, n2, n3, n4, n5 ),
534  m_capacity(0)
535  {
536  resize_memory( m_stride[NumDim] );
537  }
538 
539  ArrayContainer( const unsigned n0, const unsigned n1,
540  const unsigned n2, const unsigned n3,
541  const unsigned n4 )
542  : BaseType( NULL, n0, n1, n2, n3, n4 ),
543  m_capacity(0)
544  {
545  resize_memory( m_stride[NumDim] );
546  }
547 
548  ArrayContainer( const unsigned n0, const unsigned n1,
549  const unsigned n2, const unsigned n3 )
550  : BaseType( NULL, n0, n1, n2, n3 ),
551  m_capacity(0)
552  {
553  resize_memory( m_stride[NumDim] );
554  }
555 
556  ArrayContainer( const unsigned n0, const unsigned n1,
557  const unsigned n2 )
558  : BaseType( NULL, n0, n1, n2 ),
559  m_capacity(0)
560  {
561  resize_memory( m_stride[NumDim] );
562  }
563 
564  ArrayContainer( const unsigned n0, const unsigned n1 )
565  : BaseType( NULL, n0, n1 ),
566  m_capacity(0)
567  {
568  resize_memory( m_stride[NumDim] );
569  }
570 
571  ArrayContainer( const unsigned n0 )
572  : BaseType( NULL, n0 ),
573  m_capacity(0)
574  {
575  resize_memory( m_stride[NumDim] );
576  }
577 
578  ArrayContainer( const unsigned n[] )
579  : BaseType( NULL, n ),
580  m_capacity(0)
581  {
582  resize_memory( m_stride[NumDim] );
583  }
584 
585  //----------------------------------------
586 
587  template<typename T>
588  SelfType & resize( const Array<T, Tag0, Tag1, Tag2, Tag3, Tag4, Tag5, Tag6, Tag7> & a ) {
589  resize_memory( BaseType::set_dim( a.dimension() ) );
590  return *this;
591  }
592 
593  SelfType & resize( const unsigned n0, const unsigned n1,
594  const unsigned n2, const unsigned n3,
595  const unsigned n4, const unsigned n5,
596  const unsigned n6, const unsigned n7 )
597  {
598  resize_memory(BaseType::set_dim(n0, n1, n2, n3, n4, n5, n6, n7));
599  return *this;
600  }
601 
602  SelfType & resize( const unsigned n0, const unsigned n1,
603  const unsigned n2, const unsigned n3,
604  const unsigned n4, const unsigned n5,
605  const unsigned n6 )
606  {
607  resize_memory(BaseType::set_dim(n0, n1, n2, n3, n4, n5, n6));
608  return *this;
609  }
610 
611  SelfType & resize( const unsigned n0, const unsigned n1,
612  const unsigned n2, const unsigned n3,
613  const unsigned n4, const unsigned n5 )
614  {
615  resize_memory(BaseType::set_dim(n0, n1, n2, n3, n4, n5));
616  return *this;
617  }
618 
619  SelfType & resize( const unsigned n0, const unsigned n1,
620  const unsigned n2, const unsigned n3,
621  const unsigned n4 )
622  {
623  resize_memory(BaseType::set_dim(n0, n1, n2, n3, n4));
624  return *this;
625  }
626 
627  SelfType & resize( const unsigned n0, const unsigned n1,
628  const unsigned n2, const unsigned n3 )
629  {
630  resize_memory(BaseType::set_dim(n0, n1, n2, n3));
631  return *this;
632  }
633 
634 
635  SelfType & resize( const unsigned n0, const unsigned n1,
636  const unsigned n2 )
637  {
638  resize_memory(BaseType::set_dim(n0, n1, n2));
639  return *this;
640  }
641 
642  SelfType & resize( const unsigned n0, const unsigned n1 )
643  {
644  resize_memory(BaseType::set_dim(n0, n1));
645  return *this;
646  }
647 
648  SelfType & resize( const unsigned n0 )
649  {
650  resize_memory(BaseType::set_dim(n0));
651  return *this;
652  }
653 
654  SelfType & resize( const unsigned n[] )
655  {
656  resize_memory( BaseType::set_dim(n) );
657  return *this;
658  }
659 
660  //----------------------------------------
661 
662 private:
663  A m_allocator;
664  unsigned m_capacity;
665 };
666 
670 
671 } // namespace sierra
672 
673 #endif // STK_UTIL_UTIL_Array_h
Definition: Env.cpp:53
Extend Array with deep copy assignment and resize operations.
Definition: Array.hpp:101
Linked list of types.
Definition: TypeList.hpp:479
Compile-time assertionIf the compile-time expression is true then defines.
const unsigned * dimension() const
Definition: Array.hpp:177
Multidimensional array view of contiguous memory.
Definition: Array.hpp:82