Sierra Toolkit  Version of the Day
FArray.hpp
Go to the documentation of this file.
1 
15 #ifndef STK_UTIL_DIAG_FArray_h
16 #define STK_UTIL_DIAG_FArray_h
17 
18 #include <cstddef>
19 #include <utility>
20 #include <algorithm>
21 #include <stdexcept>
22 #include <typeinfo>
23 #include <iterator>
24 
25 #include <stk_util/util/StaticAssert.hpp>
26 
27 #ifndef NDEBUG
28 # define SIERRA_ARRAY_BOUNDS_CHECK
29 #endif
30 
31 namespace sierra {
32 
37 
38 
39 void
40 array_dimension_error(
41  const std::type_info & typeinfo,
42  unsigned dimension,
43  unsigned value,
44  unsigned upper);
45 
46 
77 template<class ElementType, int Dimension>
78 class FArray;
79 
85 template<class ElementType, int Dimension, class A = std::allocator<ElementType> >
87 
88 //----------------------------------------------------------------------
89 //----------------------------------------------------------------------
90 // Helpers
91 
92 template<unsigned N> struct ArrayHelper;
93 
94 //----------------------------------------------------------------------
95 //----------------------------------------------------------------------
96 
97 template<>
98 struct ArrayHelper<0>
99 {
100  template<typename T>
101  inline static void fill(const T, T *)
102  {}
103 
104  template<typename T>
105  inline static void copy(const T *, T *)
106  {}
107 
108  template<typename T>
109  inline static void prefix(const T *, T *)
110  {}
111 
112  inline static void get_index(const unsigned * const, unsigned *index, int offset) {
113  index[0] = offset;
114  }
115 
116  template<typename T>
117  inline static T *index(T * ptr, const unsigned * const, const unsigned * const, const unsigned * const index) {
118  return ptr + index[0];
119  }
120 };
121 
122 template<>
123 struct ArrayHelper<1>
124 {
125  template<typename T>
126  inline static bool equal(const T * x, const T * y) {
127  return *x == *y;
128  }
129 
130  template<typename T>
131  inline static void fill(const T x, T * y) {
132  *y = x;
133  }
134 
135  template<typename T>
136  inline static void copy(const T * x, T * y) {
137  *y = *x;
138  }
139 
140  template<typename T>
141  inline static void prefix(const T * x, T * p) {
142  *(p+1) = *p * *x;
143  }
144 
145  template<typename T>
146  static void copy(const unsigned * const dim,
147  T * a_ptr, const unsigned * const a_inc,
148  T const * b_ptr, const unsigned * const b_inc)
149  {
150  const unsigned ia = *a_inc;
151  const unsigned ib = *b_inc;
152  T * const a_end = a_ptr + *dim * ia;
153  while (a_end != a_ptr) {
154  *a_ptr = *b_ptr;
155  a_ptr += ia;
156  b_ptr += ib;
157  }
158  }
159 
160  template<typename T>
161  static void fill(const unsigned * const dim,
162  T * a_ptr, const unsigned * const a_inc,
163  const T & value)
164  {
165  const unsigned ia = *a_inc;
166  T * const a_end = a_ptr + *dim * ia;
167  while (a_end != a_ptr) {
168  *a_ptr = value;
169  a_ptr += ia;
170  }
171  }
172 
173  template<typename T>
174  static bool equal(const unsigned * const dim,
175  const T * a_ptr, const unsigned * const a_inc,
176  const T * b_ptr, const unsigned * const b_inc)
177  {
178  const unsigned ia = *a_inc;
179  const unsigned ib = *b_inc;
180  const T * const a_end = a_ptr + *dim * ia;
181  bool result = true;
182  while (a_end != a_ptr && (result = *a_ptr == *b_ptr)) {
183  a_ptr += ia;
184  b_ptr += ib;
185  }
186  return result;
187  }
188 
189  inline static void get_index(const unsigned * const inc, unsigned *index, int offset) {
190  index[1] = offset/inc[1];
191  index[0] = offset%inc[1];
192  }
193 
194  template<typename T>
195  inline static T *index(T * ptr, const unsigned * const inc, const unsigned * const, const unsigned * const index) {
196  return ptr + index[0] + index[1]*inc[1];
197  }
198 };
199 
200 
201 template<unsigned N>
202 struct ArrayHelper
203 {
204 private:
205  typedef ArrayHelper<N-1> M;
206 
207 public:
208  template<typename T>
209  inline static bool equal(const T * x, const T * y) {
210  return *x == *y && M::equal(x + 1, y + 1);
211  }
212 
213  template<typename T>
214  inline static void fill(const T x, T * y) {
215  *y = x;
216  M::fill(x, y+1);
217  }
218 
219  template<typename T>
220  inline static void copy(const T * x, T * y) {
221  *y = *x;
222  M::copy(x+1, y+1);
223  }
224 
225  template<typename T>
226  inline static void prefix(const T * x, T * p) {
227  *(p+1) = *p * *x;
228  M::prefix(x + 1, p + 1);
229  }
230 
231  template<typename T>
232  static void copy(const unsigned * const dim,
233  T * a_ptr, const unsigned * const a_inc,
234  T const * b_ptr, const unsigned * const b_inc)
235  {
236  const unsigned ia = *a_inc;
237  const unsigned ib = *b_inc;
238  T * const a_end = a_ptr + *dim * ia;
239  while (a_end != a_ptr) {
240  M::copy(dim + 1, a_ptr, a_inc + 1, b_ptr, b_inc + 1);
241  a_ptr += ia;
242  b_ptr += ib;
243  }
244  }
245 
246  template<typename T>
247  static void fill(const unsigned * const dim,
248  T * a_ptr, const unsigned * const a_inc,
249  const T & value)
250  {
251  const unsigned ia = *a_inc;
252  T * const a_end = a_ptr + *dim * ia;
253  while (a_end != a_ptr) {
254  M::fill(dim + 1, a_ptr, a_inc + 1, value);
255  a_ptr += ia;
256  }
257  }
258 
259  template<typename T>
260  static bool equal(const unsigned * const dim,
261  const T * a_ptr, const unsigned * const a_inc,
262  const T * b_ptr, const unsigned * const b_inc)
263  {
264  const unsigned ia = *a_inc;
265  const unsigned ib = *b_inc;
266  const T * const a_end = a_ptr + *dim * ia;
267  bool result = true;
268  while (a_end != a_ptr &&
269  (result = M::equal(dim+1, a_ptr, a_inc+1, b_ptr, b_inc+1))){
270  a_ptr += ia;
271  b_ptr += ib;
272  }
273  return result;
274  }
275 
276  inline static void get_index(const unsigned * const inc, unsigned *index, int offset) {
277  index[N] = offset/inc[N];
278  M::get_index(inc, index, offset%inc[N]);
279  }
280 
281  template<typename T>
282  inline static T *index(T * ptr, const unsigned * const inc, const unsigned * const dim, const unsigned * const index) {
283  return M::index(ptr, inc, dim, index) + index[N]*inc[N];
284  }
285 };
286 
287 //----------------------------------------------------------------------
288 // A typeless array is invalid...
289 
290 template<int Dimension>
291 class FArray<void, Dimension> {};
292 
293 template <class ElementType>
294 class FArray<ElementType, 0>
295 {
296 public:
297  typedef ElementType value_type;
298 
299  typedef FArray<value_type, 0> SelfType;
300 
301  typedef FArray<const value_type, 0> Const;
302 
303  enum { NumDim = 0};
304 };
305 
306 class FArrayBootstrap
307 {
308 public:
309  ~FArrayBootstrap();
310 };
311 
312 template<class ElementType, int Dimension>
313 class FArray : public FArrayBootstrap
314 {
315 public:
316  enum { NumDim = Dimension };
317 
318  typedef ElementType value_type;
319  typedef size_t size_type;
320  typedef ptrdiff_t difference_type;
321 
322  typedef value_type * pointer;
323  typedef const value_type * const_pointer;
324  typedef value_type & reference;
325  typedef const value_type & const_reference;
326 
327  typedef pointer iterator;
328  typedef const_pointer const_iterator;
329  typedef typename std::reverse_iterator<iterator> reverse_iterator;
330  typedef typename std::reverse_iterator<const_iterator> const_reverse_iterator;
331 
332  typedef FArray<ElementType, Dimension> SelfType;
333  typedef FArrayContainer<ElementType, Dimension> Container;
334  typedef FArray<ElementType, Dimension - 1> Trunc;
335 
336  class Index
337  {
338  public:
339  const unsigned &operator[](unsigned i) const {
340  return m_index[i];
341  }
342 
343  unsigned &operator[](unsigned i) {
344  return m_index[i];
345  }
346 
347  private:
348  unsigned m_index[NumDim];
349  };
350 
351  const unsigned * dimension() const {
352  return m_dim;
353  }
354 
355  const unsigned * stride() const {
356  return m_stride;
357  }
358 
359 #ifdef SIERRA_ARRAY_BOUNDS_CHECK
360  inline void array_dimension_verify(unsigned l_dimension, unsigned value, unsigned upper) const {
361  if (value >= upper)
362  {
363  array_dimension_error(typeid(*this), l_dimension, value, upper);
364  }
365  }
366 #else
367  inline void array_dimension_verify(unsigned, unsigned, unsigned) const {}
368 #endif
369 
370  template<unsigned I>
371  unsigned dimension() const {
373  return m_dim[I];
374  }
375 
376  template<unsigned I>
377  unsigned stride() const {
379  return m_stride[I];
380  }
381 
383  unsigned dimension(const unsigned i) const {
384  array_dimension_verify(0, i, NumDim);
385  return m_dim[i];
386  }
387 
388  unsigned stride(const unsigned i) const {
389  array_dimension_verify(0, i, NumDim);
390  return m_stride[i];
391  }
392 
393  unsigned size() const {
394  return m_stride[NumDim];
395  }
396 
397  //----------------------------------------
398 
399  bool operator==(const SelfType & a) const {
400  return ArrayHelper<NumDim>::equal(m_dim, a.m_dim) &&
401  ArrayHelper<NumDim>::equal(m_dim, m_ptr, m_stride, a.m_ptr, a.m_stride);
402  }
403 
404  template<typename T>
405  bool operator==(const FArray<T, Dimension> & a) const {
406  return ArrayHelper<NumDim>::equal(m_dim, a.dimension()) &&
407  ArrayHelper<NumDim>::equal(m_dim, m_ptr, m_stride, a.ptr(), a.stride());
408  }
409 
410  bool operator!=(const SelfType & a) const {
411  return ! operator==(a); }
412 
413  template<typename T>
414  bool operator!=(const FArray<T, Dimension> & a) const {
415  return ! operator==(a);
416  }
417 
418  value_type &operator()(const Index &index) {
419  for (unsigned i = 0; i < NumDim; ++i)
420  array_dimension_verify(i, index[i], m_dim[i]);
421 
422  value_type *l_ptr = ArrayHelper<NumDim - 1>::index(m_ptr, m_stride, m_dim, &index[0]);
423 
424  return *l_ptr;
425  }
426 
427  value_type & operator()(const unsigned i0, const unsigned i1,
428  const unsigned i2, const unsigned i3,
429  const unsigned i4, const unsigned i5,
430  const unsigned i6, const unsigned i7)
431  {
433 
434  array_dimension_verify(0, i0, m_dim[0]);
435  array_dimension_verify(1, i1, m_dim[1]);
436  array_dimension_verify(2, i2, m_dim[2]);
437  array_dimension_verify(3, i3, m_dim[3]);
438  array_dimension_verify(4, i4, m_dim[4]);
439  array_dimension_verify(5, i5, m_dim[5]);
440  array_dimension_verify(6, i6, m_dim[6]);
441  array_dimension_verify(7, i7, m_dim[7]);
442 
443  return *(m_ptr + i0 + m_stride[1] * i1 +
444  m_stride[2] * i2 + m_stride[3] * i3 +
445  m_stride[4] * i4 + m_stride[5] * i5 +
446  m_stride[6] * i6 + m_stride[7] * i7);
447  }
448 
449  value_type & operator()(const unsigned i0, const unsigned i1,
450  const unsigned i2, const unsigned i3,
451  const unsigned i4, const unsigned i5,
452  const unsigned i6)
453  {
455 
456  array_dimension_verify(0, i0, m_dim[0]);
457  array_dimension_verify(1, i1, m_dim[1]);
458  array_dimension_verify(2, i2, m_dim[2]);
459  array_dimension_verify(3, i3, m_dim[3]);
460  array_dimension_verify(4, i4, m_dim[4]);
461  array_dimension_verify(5, i5, m_dim[5]);
462  array_dimension_verify(6, i6, m_dim[6]);
463 
464  return *(m_ptr + i0 + m_stride[1] * i1 +
465  m_stride[2] * i2 + m_stride[3] * i3 +
466  m_stride[4] * i4 + m_stride[5] * i5 +
467  m_stride[6] * i6);
468  }
469 
470  value_type & operator()(const unsigned i0, const unsigned i1,
471  const unsigned i2, const unsigned i3,
472  const unsigned i4, const unsigned i5)
473  {
475 
476  array_dimension_verify(0, i0, m_dim[0]);
477  array_dimension_verify(1, i1, m_dim[1]);
478  array_dimension_verify(2, i2, m_dim[2]);
479  array_dimension_verify(3, i3, m_dim[3]);
480  array_dimension_verify(4, i4, m_dim[4]);
481  array_dimension_verify(5, i5, m_dim[5]);
482 
483  return *(m_ptr + i0 + m_stride[1] * i1 +
484  m_stride[2] * i2 + m_stride[3] * i3 +
485  m_stride[4] * i4 + m_stride[5] * i5);
486  }
487 
488  value_type & operator()(const unsigned i0, const unsigned i1,
489  const unsigned i2, const unsigned i3,
490  const unsigned i4)
491  {
493 
494  array_dimension_verify(0, i0, m_dim[0]);
495  array_dimension_verify(1, i1, m_dim[1]);
496  array_dimension_verify(2, i2, m_dim[2]);
497  array_dimension_verify(3, i3, m_dim[3]);
498  array_dimension_verify(4, i4, m_dim[4]);
499 
500  return *(m_ptr + i0 + m_stride[1] * i1 +
501  m_stride[2] * i2 + m_stride[3] * i3 +
502  m_stride[4] * i4);
503  }
504 
505  value_type & operator()(const unsigned i0, const unsigned i1,
506  const unsigned i2, const unsigned i3)
507  {
509 
510  array_dimension_verify(0, i0, m_dim[0]);
511  array_dimension_verify(1, i1, m_dim[1]);
512  array_dimension_verify(2, i2, m_dim[2]);
513  array_dimension_verify(3, i3, m_dim[3]);
514 
515  return *(m_ptr + i0 + m_stride[1] * i1 +
516  m_stride[2] * i2 + m_stride[3] * i3);
517  }
518 
519  value_type & operator()(const unsigned i0, const unsigned i1,
520  const unsigned i2)
521  {
523 
524  array_dimension_verify(0, i0, m_dim[0]);
525  array_dimension_verify(1, i1, m_dim[1]);
526  array_dimension_verify(2, i2, m_dim[2]);
527 
528  return *(m_ptr + i0 + m_stride[1] * i1 +
529  m_stride[2] * i2);
530  }
531 
532  value_type & operator()(const unsigned i0, const unsigned i1) {
534 
535  array_dimension_verify(0, i0, m_dim[0]);
536  array_dimension_verify(1, i1, m_dim[1]);
537 
538  return *(m_ptr + i0 + m_stride[1] * i1);
539  }
540 
541  value_type & operator()(const unsigned i0) {
543 
544  array_dimension_verify(0, i0, m_dim[0]);
545 
546  return *(m_ptr + i0);
547  }
548 
549  value_type * ptr() {
550  return m_ptr;
551  }
552 
553  value_type & operator[](unsigned i) {
554  array_dimension_verify(0, i, m_stride[NumDim]);
555  return m_ptr[i];
556  }
557 
558  const value_type &operator()(const Index &index) const {
559  for (unsigned i = 0; i < NumDim; ++i)
560  array_dimension_verify(i, index[i], m_dim[i]);
561 
562  const value_type *l_ptr = ArrayHelper<NumDim - 1>::index(m_ptr, m_stride, m_dim, &index[0]);
563 
564  return *l_ptr;
565  }
566 
567  const value_type & operator()(const unsigned i0, const unsigned i1,
568  const unsigned i2, const unsigned i3,
569  const unsigned i4, const unsigned i5,
570  const unsigned i6, const unsigned i7) const
571  {
573 
574  array_dimension_verify(0, i0, m_dim[0]);
575  array_dimension_verify(1, i1, m_dim[1]);
576  array_dimension_verify(2, i2, m_dim[2]);
577  array_dimension_verify(3, i3, m_dim[3]);
578  array_dimension_verify(4, i4, m_dim[4]);
579  array_dimension_verify(5, i5, m_dim[5]);
580  array_dimension_verify(6, i6, m_dim[6]);
581  array_dimension_verify(7, i7, m_dim[7]);
582 
583  return *(m_ptr + i0 + m_stride[1] * i1 +
584  m_stride[2] * i2 + m_stride[3] * i3 +
585  m_stride[4] * i4 + m_stride[5] * i5 +
586  m_stride[6] * i6 + m_stride[7] * i7);
587  }
588 
589  const value_type & operator()(const unsigned i0, const unsigned i1,
590  const unsigned i2, const unsigned i3,
591  const unsigned i4, const unsigned i5,
592  const unsigned i6) const
593  {
595 
596  array_dimension_verify(0, i0, m_dim[0]);
597  array_dimension_verify(1, i1, m_dim[1]);
598  array_dimension_verify(2, i2, m_dim[2]);
599  array_dimension_verify(3, i3, m_dim[3]);
600  array_dimension_verify(4, i4, m_dim[4]);
601  array_dimension_verify(5, i5, m_dim[5]);
602  array_dimension_verify(6, i6, m_dim[6]);
603 
604  return *(m_ptr + i0 + m_stride[1] * i1 +
605  m_stride[2] * i2 + m_stride[3] * i3 +
606  m_stride[4] * i4 + m_stride[5] * i5 +
607  m_stride[6] * i6);
608  }
609 
610  const value_type & operator()(const unsigned i0, const unsigned i1,
611  const unsigned i2, const unsigned i3,
612  const unsigned i4, const unsigned i5) const
613  {
615 
616  array_dimension_verify(0, i0, m_dim[0]);
617  array_dimension_verify(1, i1, m_dim[1]);
618  array_dimension_verify(2, i2, m_dim[2]);
619  array_dimension_verify(3, i3, m_dim[3]);
620  array_dimension_verify(4, i4, m_dim[4]);
621  array_dimension_verify(5, i5, m_dim[5]);
622 
623  return *(m_ptr + i0 + m_stride[1] * i1 +
624  m_stride[2] * i2 + m_stride[3] * i3 +
625  m_stride[4] * i4 + m_stride[5] * i5);
626  }
627 
628  const value_type & operator()(const unsigned i0, const unsigned i1,
629  const unsigned i2, const unsigned i3,
630  const unsigned i4) const
631  {
633 
634  array_dimension_verify(0, i0, m_dim[0]);
635  array_dimension_verify(1, i1, m_dim[1]);
636  array_dimension_verify(2, i2, m_dim[2]);
637  array_dimension_verify(3, i3, m_dim[3]);
638  array_dimension_verify(4, i4, m_dim[4]);
639 
640  return *(m_ptr + i0 + m_stride[1] * i1 +
641  m_stride[2] * i2 + m_stride[3] * i3 +
642  m_stride[4] * i4);
643  }
644 
645  const value_type & operator()(const unsigned i0, const unsigned i1,
646  const unsigned i2, const unsigned i3) const
647  {
649 
650  array_dimension_verify(0, i0, m_dim[0]);
651  array_dimension_verify(1, i1, m_dim[1]);
652  array_dimension_verify(2, i2, m_dim[2]);
653  array_dimension_verify(3, i3, m_dim[3]);
654 
655  return *(m_ptr + i0 + m_stride[1] * i1 +
656  m_stride[2] * i2 + m_stride[3] * i3);
657  }
658 
659  const value_type & operator()(const unsigned i0, const unsigned i1,
660  const unsigned i2) const
661  {
663 
664  array_dimension_verify(0, i0, m_dim[0]);
665  array_dimension_verify(1, i1, m_dim[1]);
666  array_dimension_verify(2, i2, m_dim[2]);
667 
668  return *(m_ptr + i0 + m_stride[1] * i1 +
669  m_stride[2] * i2);
670  }
671 
672  const value_type & operator()(const unsigned i0, const unsigned i1) const {
674 
675  array_dimension_verify(0, i0, m_dim[0]);
676  array_dimension_verify(1, i1, m_dim[1]);
677 
678  return *(m_ptr + i0 + m_stride[1] * i1);
679  }
680 
681  const value_type & operator()(const unsigned i0) const {
683 
684  array_dimension_verify(0, i0, m_dim[0]);
685 
686  return *(m_ptr + i0);
687  }
688 
689  value_type * ptr() const {
690  return m_ptr;
691  }
692 
693  const value_type & operator[](unsigned i) const {
694  array_dimension_verify(0, i, m_stride[NumDim]);
695  return m_ptr[i];
696  }
697 
698  //----------------------------------------
699 
700  bool verify_dimension(const unsigned n0, const unsigned n1,
701  const unsigned n2, const unsigned n3,
702  const unsigned n4, const unsigned n5,
703  const unsigned n6, const unsigned n7) const
704  {
706  return m_dim[0] == n0 && m_dim[1] == n1 &&
707  m_dim[2] == n2 && m_dim[3] == n3 &&
708  m_dim[4] == n4 && m_dim[5] == n5 &&
709  m_dim[6] == n6 && m_dim[7] == n7;
710  }
711 
712  bool verify_dimension(const unsigned n0, const unsigned n1,
713  const unsigned n2, const unsigned n3,
714  const unsigned n4, const unsigned n5,
715  const unsigned n6) const
716  {
718  return m_dim[0] == n0 && m_dim[1] == n1 &&
719  m_dim[2] == n2 && m_dim[3] == n3 &&
720  m_dim[4] == n4 && m_dim[5] == n5 &&
721  m_dim[6] == n6;
722  }
723 
724  bool verify_dimension(const unsigned n0, const unsigned n1,
725  const unsigned n2, const unsigned n3,
726  const unsigned n4, const unsigned n5) const
727  {
729  return m_dim[0] == n0 && m_dim[1] == n1 &&
730  m_dim[2] == n2 && m_dim[3] == n3 &&
731  m_dim[4] == n4 && m_dim[5] == n5;
732  }
733 
734  bool verify_dimension(const unsigned n0, const unsigned n1,
735  const unsigned n2, const unsigned n3,
736  const unsigned n4) const
737  {
739  return m_dim[0] == n0 && m_dim[1] == n1 &&
740  m_dim[2] == n2 && m_dim[3] == n3 &&
741  m_dim[4] == n4;
742  }
743 
744  bool verify_dimension(const unsigned n0, const unsigned n1,
745  const unsigned n2, const unsigned n3) const
746  {
748  return m_dim[0] == n0 && m_dim[1] == n1 &&
749  m_dim[2] == n2 && m_dim[3] == n3;
750  }
751 
752  bool verify_dimension(const unsigned n0, const unsigned n1,
753  const unsigned n2) const
754  {
756  return m_dim[0] == n0 && m_dim[1] == n1 &&
757  m_dim[2] == n2;
758  }
759 
760  bool verify_dimension(const unsigned n0, const unsigned n1) const {
762  return m_dim[0] == n0 && m_dim[1] == n1;
763  }
764 
765  bool verify_dimension(const unsigned n0) const {
767  return m_dim[0] == n0;
768  }
769 
770  unsigned set_dim(const unsigned d[]) {
771  m_stride[0] = 1;
772  ArrayHelper<NumDim>::copy(d, m_dim);
773  ArrayHelper<NumDim>::prefix(d, m_stride);
774  return m_stride[NumDim];
775  }
776 
777  unsigned set_dim(const unsigned n0, const unsigned n1,
778  const unsigned n2, const unsigned n3,
779  const unsigned n4, const unsigned n5,
780  const unsigned n6, const unsigned n7)
781  {
783 
784  m_stride[0] = 1;
785  m_stride[1] = m_stride[0] * (m_dim[0] = n0);
786  m_stride[2] = m_stride[1] * (m_dim[1] = n1);
787  m_stride[3] = m_stride[2] * (m_dim[2] = n2);
788  m_stride[4] = m_stride[3] * (m_dim[3] = n3);
789  m_stride[5] = m_stride[4] * (m_dim[4] = n4);
790  m_stride[6] = m_stride[5] * (m_dim[5] = n5);
791  m_stride[7] = m_stride[6] * (m_dim[6] = n6);
792  m_stride[8] = m_stride[7] * (m_dim[7] = n7);
793  return m_stride[NumDim];
794  }
795 
796  unsigned set_dim(const unsigned n0, const unsigned n1,
797  const unsigned n2, const unsigned n3,
798  const unsigned n4, const unsigned n5,
799  const unsigned n6)
800  {
802 
803  m_stride[0] = 1;
804  m_stride[1] = m_stride[0] * (m_dim[0] = n0);
805  m_stride[2] = m_stride[1] * (m_dim[1] = n1);
806  m_stride[3] = m_stride[2] * (m_dim[2] = n2);
807  m_stride[4] = m_stride[3] * (m_dim[3] = n3);
808  m_stride[5] = m_stride[4] * (m_dim[4] = n4);
809  m_stride[6] = m_stride[5] * (m_dim[5] = n5);
810  m_stride[7] = m_stride[6] * (m_dim[6] = n6);
811  return m_stride[NumDim];
812  }
813 
814  unsigned set_dim(const unsigned n0, const unsigned n1,
815  const unsigned n2, const unsigned n3,
816  const unsigned n4, const unsigned n5)
817  {
819 
820  m_stride[0] = 1;
821  m_stride[1] = m_stride[0] * (m_dim[0] = n0);
822  m_stride[2] = m_stride[1] * (m_dim[1] = n1);
823  m_stride[3] = m_stride[2] * (m_dim[2] = n2);
824  m_stride[4] = m_stride[3] * (m_dim[3] = n3);
825  m_stride[5] = m_stride[4] * (m_dim[4] = n4);
826  m_stride[6] = m_stride[5] * (m_dim[5] = n5);
827  return m_stride[NumDim];
828  }
829 
830  unsigned set_dim(const unsigned n0, const unsigned n1,
831  const unsigned n2, const unsigned n3,
832  const unsigned n4)
833  {
835 
836  m_stride[0] = 1;
837  m_stride[1] = m_stride[0] * (m_dim[0] = n0);
838  m_stride[2] = m_stride[1] * (m_dim[1] = n1);
839  m_stride[3] = m_stride[2] * (m_dim[2] = n2);
840  m_stride[4] = m_stride[3] * (m_dim[3] = n3);
841  m_stride[5] = m_stride[4] * (m_dim[4] = n4);
842  return m_stride[NumDim];
843  }
844 
845  unsigned set_dim(const unsigned n0, const unsigned n1,
846  const unsigned n2, const unsigned n3)
847  {
849 
850  m_stride[0] = 1;
851  m_stride[1] = m_stride[0] * (m_dim[0] = n0);
852  m_stride[2] = m_stride[1] * (m_dim[1] = n1);
853  m_stride[3] = m_stride[2] * (m_dim[2] = n2);
854  m_stride[4] = m_stride[3] * (m_dim[3] = n3);
855  return m_stride[NumDim];
856  }
857 
858  unsigned set_dim(const unsigned n0, const unsigned n1,
859  const unsigned n2)
860  {
862 
863  m_stride[0] = 1;
864  m_stride[1] = m_stride[0] * (m_dim[0] = n0);
865  m_stride[2] = m_stride[1] * (m_dim[1] = n1);
866  m_stride[3] = m_stride[2] * (m_dim[2] = n2);
867  return m_stride[NumDim];
868  }
869 
870  unsigned set_dim(const unsigned n0, const unsigned n1)
871  {
873 
874  m_stride[0] = 1;
875  m_stride[1] = m_stride[0] * (m_dim[0] = n0);
876  m_stride[2] = m_stride[1] * (m_dim[1] = n1);
877  return m_stride[NumDim];
878  }
879 
880  unsigned set_dim(const unsigned n0)
881  {
883 
884  m_stride[0] = 1;
885  m_stride[1] = m_stride[0] * (m_dim[0] = n0);
886  return m_stride[NumDim];
887  }
888 
889  unsigned set_dim(const SelfType & a)
890  {
891  ArrayHelper<NumDim>::copy(a.m_dim, m_dim);
892  ArrayHelper<NumDim+1>::copy(a.m_stride, m_stride);
893  return m_stride[NumDim];
894  }
895 
896 public:
897  ~FArray()
898  {
899  m_ptr = NULL;
900  ArrayHelper<NumDim>::fill((unsigned) 0, m_dim);
901  ArrayHelper<NumDim+1>::fill((unsigned) 0, m_stride);
902  }
903 
904  FArray()
905  : m_ptr(NULL)
906  {
907  ArrayHelper<NumDim>::fill((unsigned) 0, m_dim);
908  ArrayHelper<NumDim+1>::fill((unsigned) 0, m_stride);
909  }
910 
911  FArray(const SelfType & a)
912  : m_ptr(a.m_ptr)
913  {
914  ArrayHelper<NumDim>::copy(a.m_dim, m_dim);
915  ArrayHelper<NumDim+1>::copy(a.m_stride, m_stride);
916  }
917 
918  SelfType & operator=(SelfType const & a)
919  {
920  if (this != &a) {
921 
922  m_ptr = a.m_ptr;
923 
924  ArrayHelper<NumDim>::copy(a.m_dim, m_dim);
925  ArrayHelper<NumDim+1>::copy(a.m_stride, m_stride);
926  }
927  return *this;
928  }
929 
930  template<typename T>
931  FArray(const FArray<T, Dimension> & a)
932  : m_ptr(a.ptr())
933  {
934  ArrayHelper<NumDim>::copy(a.dimension(), m_dim);
935  ArrayHelper<NumDim+1>::copy(a.stride(), m_stride);
936  }
937 
938  FArray(value_type * const l_ptr,
939  const unsigned n0, const unsigned n1,
940  const unsigned n2, const unsigned n3,
941  const unsigned n4, const unsigned n5,
942  const unsigned n6, const unsigned n7)
943  : m_ptr(l_ptr)
944  {
945  set_dim(n0, n1, n2, n3, n4, n5, n6, n7);
946  }
947 
948  FArray(value_type * const l_ptr,
949  const unsigned n0, const unsigned n1,
950  const unsigned n2, const unsigned n3,
951  const unsigned n4, const unsigned n5,
952  const unsigned n6)
953  : m_ptr(l_ptr)
954  {
955  set_dim(n0, n1, n2, n3, n4, n5, n6);
956  }
957 
958  FArray(value_type * const l_ptr,
959  const unsigned n0, const unsigned n1,
960  const unsigned n2, const unsigned n3,
961  const unsigned n4, const unsigned n5)
962  : m_ptr(l_ptr)
963  {
964  set_dim(n0, n1, n2, n3, n4, n5);
965  }
966 
967  FArray(value_type * const l_ptr,
968  const unsigned n0, const unsigned n1,
969  const unsigned n2, const unsigned n3,
970  const unsigned n4)
971  : m_ptr(l_ptr)
972  {
973  set_dim(n0, n1, n2, n3, n4);
974  }
975 
976  FArray(value_type * const l_ptr,
977  const unsigned n0, const unsigned n1,
978  const unsigned n2, const unsigned n3)
979  : m_ptr(l_ptr)
980  {
981  set_dim(n0, n1, n2, n3);
982  }
983 
984  FArray(value_type * const l_ptr,
985  const unsigned n0, const unsigned n1,
986  const unsigned n2)
987  : m_ptr(l_ptr)
988  {
989  set_dim(n0, n1, n2);
990  }
991 
992  FArray(value_type * const l_ptr,
993  const unsigned n0, const unsigned n1)
994  : m_ptr(l_ptr)
995  {
996  set_dim(n0, n1);
997  }
998 
999  FArray(value_type * const l_ptr,
1000  const unsigned n0)
1001  : m_ptr(l_ptr)
1002  {
1003  set_dim(n0);
1004  }
1005 
1006  FArray(value_type * const l_ptr,
1007  const unsigned n[NumDim])
1008  : m_ptr(l_ptr)
1009  {
1010  set_dim(n);
1011  }
1012 
1013  void set(const SelfType & a) {
1014  m_ptr = a.m_ptr;
1015 
1016  ArrayHelper<NumDim>::copy(a.m_dim, m_dim);
1017  ArrayHelper<NumDim+1>::copy(a.m_stride, m_stride);
1018  }
1019 
1020  void set(value_type * const l_ptr,
1021  const unsigned n0, const unsigned n1,
1022  const unsigned n2, const unsigned n3,
1023  const unsigned n4, const unsigned n5,
1024  const unsigned n6, const unsigned n7)
1025  {
1026  m_ptr = l_ptr;
1027  set_dim(n0, n1, n2, n3, n4, n5, n6, n7);
1028  }
1029 
1030  void set(value_type * const l_ptr,
1031  const unsigned n0, const unsigned n1,
1032  const unsigned n2, const unsigned n3,
1033  const unsigned n4, const unsigned n5,
1034  const unsigned n6)
1035  {
1036  m_ptr = l_ptr;
1037  set_dim(n0, n1, n2, n3, n4, n5, n6);
1038  }
1039 
1040  void set(value_type * const l_ptr,
1041  const unsigned n0, const unsigned n1,
1042  const unsigned n2, const unsigned n3,
1043  const unsigned n4, const unsigned n5)
1044  {
1045  m_ptr = l_ptr;
1046  set_dim(n0, n1, n2, n3, n4, n5);
1047  }
1048 
1049  void set(value_type * const l_ptr,
1050  const unsigned n0, const unsigned n1,
1051  const unsigned n2, const unsigned n3,
1052  const unsigned n4) {
1053  m_ptr = l_ptr;
1054  set_dim(n0, n1, n2, n3, n4);
1055  }
1056 
1057  void set(value_type * const l_ptr,
1058  const unsigned n0, const unsigned n1,
1059  const unsigned n2, const unsigned n3)
1060  {
1061  m_ptr = l_ptr;
1062  set_dim(n0, n1, n2, n3);
1063  }
1064 
1065  void set(value_type * const l_ptr,
1066  const unsigned n0, const unsigned n1,
1067  const unsigned n2)
1068  {
1069  m_ptr = l_ptr;
1070  set_dim(n0, n1, n2);
1071  }
1072 
1073  void set(value_type * const l_ptr,
1074  const unsigned n0, const unsigned n1) {
1075  m_ptr = l_ptr;
1076  set_dim(n0, n1);
1077  }
1078 
1079  void set(value_type * const l_ptr,
1080  const unsigned n0) {
1081  m_ptr = l_ptr;
1082  set_dim(n0);
1083  }
1084 
1085  void set(value_type * const l_ptr,
1086  const unsigned n[NumDim]) {
1087  m_ptr = l_ptr;
1088  set_dim(n);
1089  }
1090 
1091  Trunc dive(int i) {
1092  array_dimension_verify(0, i, m_dim[NumDim - 1]);
1093 
1094  value_type *l_ptr = m_ptr + i*m_stride[NumDim - 1];
1095 
1096  return Trunc(l_ptr, m_dim);
1097  }
1098 
1099  const Trunc dive(int i) const {
1100  array_dimension_verify(0, i, m_dim[NumDim - 1]);
1101 
1102  value_type *l_ptr = m_ptr + i*m_stride[NumDim - 1];
1103 
1104  return Trunc(l_ptr, m_dim);
1105  }
1106 
1107  iterator begin() {
1108  return m_ptr;
1109  }
1110 
1111  iterator end() {
1112  return m_ptr + m_stride[NumDim];
1113  }
1114 
1115  const_iterator begin() const {
1116  return m_ptr;
1117  }
1118 
1119  const_iterator end() const {
1120  return m_ptr + m_stride[NumDim];
1121  }
1122 
1123  void dimensions(const_iterator it, Index &index) const {
1124  ArrayHelper<NumDim - 1>::get_index(m_stride, &index[0], it - m_ptr);
1125  }
1126 
1127  //----------------------------------------
1128  // Copy contents of a compatible array
1129 
1130  template<typename T>
1131  void copy(const FArray<T, Dimension> & a) {
1132  ArrayHelper<NumDim>::copy(m_dim, m_ptr, m_stride, a.ptr(), a.stride());
1133  }
1134 
1135  template<typename T>
1136  void fill(const T & value) {
1137  ArrayHelper<NumDim>::fill(m_dim, m_ptr, m_stride, value);
1138  }
1139 
1140 private:
1141  // Mutation (non-const methods) is not allowed so as to
1142  // provide derived classes with complete control over mutation.
1143 
1144 protected:
1145  value_type * m_ptr;
1146  unsigned m_dim[NumDim];
1147  unsigned m_stride[NumDim + 1];
1148 };
1149 
1150 
1151 template<class ElementType, int Dimension, class A>
1152 class FArrayContainer
1153  : public FArray<ElementType, Dimension>
1154 {
1155 public:
1156 // typedef typename FArray<ElementType, Dimension>::value_type value_type;
1157 
1158  typedef typename A::value_type value_type;
1159  typedef typename A::size_type size_type;
1160  typedef typename A::difference_type difference_type;
1161 
1162  typedef typename A::pointer pointer;
1163  typedef typename A::const_pointer const_pointer;
1164  typedef typename A::reference reference;
1165  typedef typename A::const_reference const_reference;
1166 
1167  typedef typename A::pointer iterator;
1168  typedef typename A::const_pointer const_iterator;
1169 
1170  typedef typename std::reverse_iterator<iterator> reverse_iterator;
1171  typedef typename std::reverse_iterator<const_iterator> const_reverse_iterator;
1172 
1173  typedef FArrayContainer<ElementType, Dimension> SelfType;
1174 
1175  typedef FArray<ElementType, Dimension> BaseType;
1176 
1177 // typedef typename BaseType::value_type value_type;
1178 
1179  enum { NumDim = BaseType::NumDim };
1180 
1181 private:
1182  using BaseType::m_ptr;
1183  using BaseType::m_dim;
1184  using BaseType::m_stride;
1185 
1186  void resize_memory(const unsigned new_size) {
1187  if (m_capacity < new_size) {
1188  if ( m_capacity )
1189  m_allocator.deallocate(m_ptr, m_capacity);
1190  m_capacity = new_size;
1191  m_ptr = m_allocator.allocate(m_capacity);
1192  }
1193  }
1194 
1195 public:
1196  ~FArrayContainer() {
1197  if (m_capacity) {
1198  m_allocator.deallocate(m_ptr, m_capacity);
1199  m_capacity = 0;
1200  }
1201  }
1202 
1203  //----------------------------------------
1204  // Constructors for initial view of contiguous memory.
1205 
1206  FArrayContainer()
1207  : BaseType(),
1208  m_capacity(0)
1209  {}
1210 
1211  FArrayContainer(const SelfType & a)
1212  : BaseType(),
1213  m_capacity(0)
1214  {
1215  resize_memory(BaseType::set_dim(a.m_dim));
1216  this->copy(a);
1217  }
1218 
1219  template<typename T>
1220  FArrayContainer(const FArray<T, Dimension> & a)
1221  : BaseType(),
1222  m_capacity(0)
1223  {
1224  resize_memory(BaseType::set_dim(a.dimension()));
1225  this->copy(a);
1226  }
1227 
1228  SelfType & operator=(const SelfType & a)
1229  {
1230  resize_memory(BaseType::set_dim(a.dimension()));
1231  this->copy(a);
1232  return *this;
1233  }
1234 
1235  template<typename T>
1236  SelfType & operator=(const FArray<T, Dimension> & a)
1237  {
1238  resize_memory(BaseType::set_dim(a.dimension()));
1239  this->copy(a);
1240  return *this;
1241  }
1242 
1243  //----------------------------------------
1244 
1245  FArrayContainer(const unsigned n0, const unsigned n1,
1246  const unsigned n2, const unsigned n3,
1247  const unsigned n4, const unsigned n5,
1248  const unsigned n6, const unsigned n7)
1249  : BaseType(NULL, n0, n1, n2, n3, n4, n5, n6, n7),
1250  m_capacity(0)
1251  {
1252  resize_memory(m_stride[NumDim]);
1253  std::fill(m_ptr, m_ptr + m_stride[NumDim], 0);
1254  }
1255 
1256  FArrayContainer(const unsigned n0, const unsigned n1,
1257  const unsigned n2, const unsigned n3,
1258  const unsigned n4, const unsigned n5,
1259  const unsigned n6)
1260  : BaseType(NULL, n0, n1, n2, n3, n4, n5, n6),
1261  m_capacity(0)
1262  {
1263  resize_memory(m_stride[NumDim]);
1264  std::fill(m_ptr, m_ptr + m_stride[NumDim], 0);
1265  }
1266 
1267 
1268  FArrayContainer(const unsigned n0, const unsigned n1,
1269  const unsigned n2, const unsigned n3,
1270  const unsigned n4, const unsigned n5)
1271  : BaseType(NULL, n0, n1, n2, n3, n4, n5),
1272  m_capacity(0)
1273  {
1274  resize_memory(m_stride[NumDim]);
1275  std::fill(m_ptr, m_ptr + m_stride[NumDim], 0);
1276  }
1277 
1278 
1279  FArrayContainer(const unsigned n0, const unsigned n1,
1280  const unsigned n2, const unsigned n3,
1281  const unsigned n4)
1282  : BaseType(NULL, n0, n1, n2, n3, n4),
1283  m_capacity(0)
1284  {
1285  resize_memory(m_stride[NumDim]);
1286  std::fill(m_ptr, m_ptr + m_stride[NumDim], 0);
1287  }
1288 
1289 
1290  FArrayContainer(const unsigned n0, const unsigned n1,
1291  const unsigned n2, const unsigned n3)
1292  : BaseType(NULL, n0, n1, n2, n3),
1293  m_capacity(0)
1294  {
1295  resize_memory(m_stride[NumDim]);
1296  std::fill(m_ptr, m_ptr + m_stride[NumDim], 0);
1297  }
1298 
1299 
1300  FArrayContainer(const unsigned n0, const unsigned n1,
1301  const unsigned n2)
1302  : BaseType(NULL, n0, n1, n2),
1303  m_capacity(0)
1304  {
1305  resize_memory(m_stride[NumDim]);
1306  std::fill(m_ptr, m_ptr + m_stride[NumDim], 0);
1307  }
1308 
1309 
1310  FArrayContainer(const unsigned n0, const unsigned n1)
1311  : BaseType(NULL, n0, n1),
1312  m_capacity(0)
1313  {
1314  resize_memory(m_stride[NumDim]);
1315  std::fill(m_ptr, m_ptr + m_stride[NumDim], 0);
1316  }
1317 
1318 
1319  FArrayContainer(const unsigned n0)
1320  : BaseType(NULL, n0),
1321  m_capacity(0)
1322  {
1323  resize_memory(m_stride[NumDim]);
1324  std::fill(m_ptr, m_ptr + m_stride[NumDim], 0);
1325  }
1326 
1327 
1328  FArrayContainer(const unsigned n[])
1329  : BaseType(NULL, n),
1330  m_capacity(0)
1331  {
1332  resize_memory(m_stride[NumDim]);
1333  std::fill(m_ptr, m_ptr + m_stride[NumDim], 0);
1334  }
1335 
1336 
1337  //----------------------------------------
1338 
1339  template<typename T>
1340  SelfType & resize(const FArray<T, Dimension> & a)
1341  {
1342  resize_memory(BaseType::set_dim(a.dimension()));
1343  return *this;
1344  }
1345 
1346  SelfType & resize(const unsigned n0, const unsigned n1,
1347  const unsigned n2, const unsigned n3,
1348  const unsigned n4, const unsigned n5,
1349  const unsigned n6, const unsigned n7)
1350  {
1351  resize_memory(BaseType::set_dim(n0, n1, n2, n3, n4, n5, n6, n7));
1352  return *this;
1353  }
1354 
1355  SelfType & resize(const unsigned n0, const unsigned n1,
1356  const unsigned n2, const unsigned n3,
1357  const unsigned n4, const unsigned n5,
1358  const unsigned n6)
1359  {
1360  resize_memory(BaseType::set_dim(n0, n1, n2, n3, n4, n5, n6));
1361  return *this;
1362  }
1363 
1364  SelfType & resize(const unsigned n0, const unsigned n1,
1365  const unsigned n2, const unsigned n3,
1366  const unsigned n4, const unsigned n5)
1367  {
1368  resize_memory(BaseType::set_dim(n0, n1, n2, n3, n4, n5));
1369  return *this;
1370  }
1371 
1372  SelfType & resize(const unsigned n0, const unsigned n1,
1373  const unsigned n2, const unsigned n3,
1374  const unsigned n4)
1375  {
1376  resize_memory(BaseType::set_dim(n0, n1, n2, n3, n4));
1377  return *this;
1378  }
1379 
1380  SelfType & resize(const unsigned n0, const unsigned n1,
1381  const unsigned n2, const unsigned n3)
1382  {
1383  resize_memory(BaseType::set_dim(n0, n1, n2, n3));
1384  return *this;
1385  }
1386 
1387 
1388  SelfType & resize(const unsigned n0, const unsigned n1,
1389  const unsigned n2)
1390  {
1391  resize_memory(BaseType::set_dim(n0, n1, n2));
1392  return *this;
1393  }
1394 
1395  SelfType & resize(const unsigned n0, const unsigned n1) {
1396  resize_memory(BaseType::set_dim(n0, n1));
1397  return *this;
1398  }
1399 
1400  SelfType & resize(const unsigned n0) {
1401  resize_memory(BaseType::set_dim(n0));
1402  return *this;
1403  }
1404 
1405  SelfType & resize(const unsigned n[]) {
1406  resize_memory(BaseType::set_dim(n));
1407  return *this;
1408  }
1409 
1410 private:
1411  A m_allocator;
1412  unsigned m_capacity;
1413 };
1414 
1418 
1419 } // namespace sierra
1420 
1421 #endif // STK_UTIL_DIAG_FArray_h
Definition: Env.cpp:53
OutputIterator copy(InputIterator first, InputIterator last, OutputIterator result)
Multidimensional array of contiguous memory. The memory is not owned by the array, but container access semantics are enforced, i.e. const Array<> elements cannot be assigned to.
Definition: FArray.hpp:78
Compile-time assertionIf the compile-time expression is true then defines.
Extend FArray with deep copy assignment and resize operations.
Definition: FArray.hpp:86
void fill(ForwardIterator first, ForwardIterator last, const T &value)
unsigned dimension(const unsigned i) const
Definition: FArray.hpp:383
bool equal(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2)