shards  Version of the Day
 All Classes Functions Variables Typedefs Enumerations Enumerator Groups
Shards_Array.hpp
1 // @HEADER
2 // *****************************************************************************
3 // Shards : Shared Discretization Tools
4 //
5 // Copyright 2008-2011 NTESS and the Shards contributors.
6 // SPDX-License-Identifier: BSD-3-Clause
7 // *****************************************************************************
8 // @HEADER
9 
10 #ifndef Shards_Array_hpp
11 #define Shards_Array_hpp
12 
13 //----------------------------------------------------------------------
14 
15 #include <vector>
16 #include <string>
17 #include <Shards_SimpleArrayOps.hpp>
18 
19 //----------------------------------------------------------------------
20 // Macro to compile in array bounds checking:
21 
22 #ifdef SHARDS_ARRAY_BOUNDS_CHECKING
23 #define SHARDS_ARRAY_CHECK( X ) X
24 #else
25 #define SHARDS_ARRAY_CHECK( X )
26 #endif
27 
28 //----------------------------------------------------------------------
29 
30 namespace shards {
31 
36 namespace array_traits {
37 typedef int int_t ;
38 } // namespace array_traits
39 
40 //----------------------------------------------------------------------
46 enum ArrayOrder {
51 
56 
61 };
62 
63 //----------------------------------------------------------------------
64 
65 template< typename Scalar , ArrayOrder Order ,
66  class Tag1 = void , class Tag2 = void ,
67  class Tag3 = void , class Tag4 = void ,
68  class Tag5 = void , class Tag6 = void ,
69  class Tag7 = void , class Tag8 = void >
70 class Array ;
71 
72 //----------------------------------------------------------------------
73 
97 class ArrayDimTag {
98 public:
99 
100  typedef array_traits::int_t size_type ;
101 
103  virtual const char * name() const = 0 ;
104 
109  virtual std::string to_string( size_type dimension ,
110  size_type index ) const ;
111 
116  virtual size_type to_index( size_type dimension ,
117  const std::string & label ) const ;
118 
119 protected:
120  virtual ~ArrayDimTag();
121  ArrayDimTag() {}
122 
123 private:
124  ArrayDimTag( const ArrayDimTag & );
125  ArrayDimTag & operator = ( const ArrayDimTag & );
126 };
127 
132 class ArrayDimension : public ArrayDimTag {
133 public:
134 
135  const char * name() const ;
136 
138  static const ArrayDimension & tag();
139 
140 private:
141  ~ArrayDimension();
142  ArrayDimension();
143  ArrayDimension( const ArrayDimension & );
144  ArrayDimension & operator = ( const ArrayDimension & );
145 };
146 
150 #define SHARDS_ARRAY_DIM_TAG_SIMPLE_DECLARATION( ADT ) \
151  class ADT : public shards::ArrayDimTag { \
152  public: \
153  const char * name() const ; \
154  static const ADT & tag(); \
155  private: \
156  ~ADT(); \
157  ADT(); \
158  ADT( const ADT & ); \
159  ADT & operator = ( const ADT & ); \
160  };
161 
165 #define SHARDS_ARRAY_DIM_TAG_SIMPLE_IMPLEMENTATION( ADT ) \
166  ADT::ADT() {} \
167  ADT::~ADT() {} \
168  const char * ADT::name() const { static const char n[] = # ADT; return n; } \
169  const ADT & ADT::tag() { static const ADT self ; return self ; }
170 
171 //----------------------------------------------------------------------
172 //----------------------------------------------------------------------
173 
176 } // namespace shards
177 
178 //----------------------------------------------------------------------
179 //----------------------------------------------------------------------
180 // Private implementation details for the array
181 
182 #ifndef DOXYGEN_COMPILE
183 
184 namespace shards {
185 namespace array_traits {
186 
187 //----------------------------------------------------------------------
189 template< typename iType >
190 inline
191 iType stride_size(
192  const iType & rank ,
193  const iType * const stride )
194 { return 0 < rank ? stride[ rank - 1 ] : 0 ; }
195 
197 template< typename iType >
198 inline
199 void stride_to_natural_dimensions(
200  const iType rank ,
201  const iType * const stride ,
202  iType * const dim )
203 {
204  iType n = 1 ;
205  for ( iType i = 0 ; i < rank ; ++i )
206  { dim[(rank-1)-i] = stride[i] / n ; n = stride[i] ; }
207 }
208 
210 template< typename iType >
211 inline
212 void stride_to_natural_indices(
213  const iType rank ,
214  const iType * const stride ,
215  iType offset ,
216  iType * const indices )
217 {
218  iType * i = indices ;
219  for ( const iType * s = stride + rank - 1 ; stride < s-- ; ++i ) {
220  *i = offset / *s ;
221  offset %= *s ;
222  }
223  *i = offset ;
224 }
225 
227 template< typename iType >
228 inline
229 void stride_from_natural_dimensions(
230  const iType rank ,
231  iType * const stride ,
232  const iType * const dim )
233 {
234  iType n = 1 ;
235  for ( iType i = 0 ; i < rank ; ++i ) { stride[i] = n *= dim[(rank-1)-i]; }
236 }
237 
238 //----------------------------------------------------------------------
239 
240 void throw_bad_conversion( const int_t lhs_rank ,
241  const ArrayDimTag * const lhs_tags[] ,
242  const int_t rhs_rank ,
243  const ArrayDimTag * const rhs_tags[] );
244 
245 void check_rank( const int_t rank ,
246  const int_t test_rank );
247 
248 void check_range( const int_t index , const int_t bound );
249 
250 void check_indices( const bool ,
251  const int_t rank ,
252  const int_t * const stride ,
253  const int_t = 0 ,
254  const int_t = 0 ,
255  const int_t = 0 ,
256  const int_t = 0 ,
257  const int_t = 0 ,
258  const int_t = 0 ,
259  const int_t = 0 ,
260  const int_t = 0 );
261 
262 void init_dim(
263  int_t dst_stride[] ,
264  const int_t src_dimension[] ,
265  const int_t rank , const bool natural );
266 
267 void init_tags(
268  const ArrayDimTag * dst_tag[] ,
269  const ArrayDimTag * const src_tag[] ,
270  const int_t rank , const bool natural );
271 
272 //----------------------------------------------------------------------
273 
274 template< int_t , int_t > struct CheckRank ;
275 
276 template<> struct CheckRank<0,0> { static void ok(){} };
277 template<> struct CheckRank<1,1> { static void ok(){} };
278 template<> struct CheckRank<2,2> { static void ok(){} };
279 template<> struct CheckRank<3,3> { static void ok(){} };
280 template<> struct CheckRank<4,4> { static void ok(){} };
281 template<> struct CheckRank<5,5> { static void ok(){} };
282 template<> struct CheckRank<6,6> { static void ok(){} };
283 template<> struct CheckRank<7,7> { static void ok(){} };
284 template<> struct CheckRank<8,8> { static void ok(){} };
285 
286 //----------------------------------------------------------------------
287 
288 template< int_t Index , int_t Bound > struct CheckRange ;
289 
290 template<> struct CheckRange<0,8> { static void ok(){} };
291 template<> struct CheckRange<1,8> { static void ok(){} };
292 template<> struct CheckRange<2,8> { static void ok(){} };
293 template<> struct CheckRange<3,8> { static void ok(){} };
294 template<> struct CheckRange<4,8> { static void ok(){} };
295 template<> struct CheckRange<5,8> { static void ok(){} };
296 template<> struct CheckRange<6,8> { static void ok(){} };
297 template<> struct CheckRange<7,8> { static void ok(){} };
298 
299 template<> struct CheckRange<0,7> { static void ok(){} };
300 template<> struct CheckRange<1,7> { static void ok(){} };
301 template<> struct CheckRange<2,7> { static void ok(){} };
302 template<> struct CheckRange<3,7> { static void ok(){} };
303 template<> struct CheckRange<4,7> { static void ok(){} };
304 template<> struct CheckRange<5,7> { static void ok(){} };
305 template<> struct CheckRange<6,7> { static void ok(){} };
306 
307 template<> struct CheckRange<0,6> { static void ok(){} };
308 template<> struct CheckRange<1,6> { static void ok(){} };
309 template<> struct CheckRange<2,6> { static void ok(){} };
310 template<> struct CheckRange<3,6> { static void ok(){} };
311 template<> struct CheckRange<4,6> { static void ok(){} };
312 template<> struct CheckRange<5,6> { static void ok(){} };
313 
314 template<> struct CheckRange<0,5> { static void ok(){} };
315 template<> struct CheckRange<1,5> { static void ok(){} };
316 template<> struct CheckRange<2,5> { static void ok(){} };
317 template<> struct CheckRange<3,5> { static void ok(){} };
318 template<> struct CheckRange<4,5> { static void ok(){} };
319 
320 template<> struct CheckRange<0,4> { static void ok(){} };
321 template<> struct CheckRange<1,4> { static void ok(){} };
322 template<> struct CheckRange<2,4> { static void ok(){} };
323 template<> struct CheckRange<3,4> { static void ok(){} };
324 
325 template<> struct CheckRange<0,3> { static void ok(){} };
326 template<> struct CheckRange<1,3> { static void ok(){} };
327 template<> struct CheckRange<2,3> { static void ok(){} };
328 
329 template<> struct CheckRange<0,2> { static void ok(){} };
330 template<> struct CheckRange<1,2> { static void ok(){} };
331 
332 template<> struct CheckRange<0,1> { static void ok(){} };
333 
334 //----------------------------------------------------------------------
335 
336 template< class , int_t > struct TagAt ;
337 
338 template< typename Scalar , ArrayOrder order ,
339  class Tag1 , class Tag2 , class Tag3 , class Tag4 ,
340  class Tag5 , class Tag6 , class Tag7 , class Tag8 >
341 struct TagAt<Array<Scalar,order,Tag1,Tag2,Tag3,Tag4,Tag5,Tag6,Tag7,Tag8>,0>
342 { typedef Tag1 type ; };
343 
344 template< typename Scalar , ArrayOrder order ,
345  class Tag1 , class Tag2 , class Tag3 , class Tag4 ,
346  class Tag5 , class Tag6 , class Tag7 , class Tag8 >
347 struct TagAt<Array<Scalar,order,Tag1,Tag2,Tag3,Tag4,Tag5,Tag6,Tag7,Tag8>,1>
348 { typedef Tag2 type ; };
349 
350 template< typename Scalar , ArrayOrder order ,
351  class Tag1 , class Tag2 , class Tag3 , class Tag4 ,
352  class Tag5 , class Tag6 , class Tag7 , class Tag8 >
353 struct TagAt<Array<Scalar,order,Tag1,Tag2,Tag3,Tag4,Tag5,Tag6,Tag7,Tag8>,2>
354 { typedef Tag3 type ; };
355 
356 template< typename Scalar , ArrayOrder order ,
357  class Tag1 , class Tag2 , class Tag3 , class Tag4 ,
358  class Tag5 , class Tag6 , class Tag7 , class Tag8 >
359 struct TagAt<Array<Scalar,order,Tag1,Tag2,Tag3,Tag4,Tag5,Tag6,Tag7,Tag8>,3>
360 { typedef Tag4 type ; };
361 
362 template< typename Scalar , ArrayOrder order ,
363  class Tag1 , class Tag2 , class Tag3 , class Tag4 ,
364  class Tag5 , class Tag6 , class Tag7 , class Tag8 >
365 struct TagAt<Array<Scalar,order,Tag1,Tag2,Tag3,Tag4,Tag5,Tag6,Tag7,Tag8>,4>
366 { typedef Tag5 type ; };
367 
368 template< typename Scalar , ArrayOrder order ,
369  class Tag1 , class Tag2 , class Tag3 , class Tag4 ,
370  class Tag5 , class Tag6 , class Tag7 , class Tag8 >
371 struct TagAt<Array<Scalar,order,Tag1,Tag2,Tag3,Tag4,Tag5,Tag6,Tag7,Tag8>,5>
372 { typedef Tag6 type ; };
373 
374 template< typename Scalar , ArrayOrder order ,
375  class Tag1 , class Tag2 , class Tag3 , class Tag4 ,
376  class Tag5 , class Tag6 , class Tag7 , class Tag8 >
377 struct TagAt<Array<Scalar,order,Tag1,Tag2,Tag3,Tag4,Tag5,Tag6,Tag7,Tag8>,6>
378 { typedef Tag7 type ; };
379 
380 template< typename Scalar , ArrayOrder order ,
381  class Tag1 , class Tag2 , class Tag3 , class Tag4 ,
382  class Tag5 , class Tag6 , class Tag7 , class Tag8 >
383 struct TagAt<Array<Scalar,order,Tag1,Tag2,Tag3,Tag4,Tag5,Tag6,Tag7,Tag8>,7>
384 { typedef Tag8 type ; };
385 
386 //----------------------------------------------------------------------
387 //----------------------------------------------------------------------
388 
389 template< ArrayOrder , int_t Rank , int_t Ordinal = 0 > struct StrideDim ;
390 
391 template< int_t Rank , int_t Ordinal >
392 struct StrideDim<RankZero,Rank,Ordinal> {
393 
394  template< typename iType >
395  static iType dimension( const iType * )
396  { return 0 ; }
397 
398  template< typename iType >
399  static iType dimension( const iType * , iType )
400  { return 0 ; }
401 };
402 
403 template< int_t Rank >
404 struct StrideDim<FortranOrder,Rank,0> {
405 
406  template< typename iType >
407  static iType dimension( const iType * stride )
408  {
409  array_traits::CheckRange<0,Rank>::ok();
410  return stride[0];
411  }
412 
413  template< typename iType >
414  static iType dimension( const iType * stride , iType ordinal )
415  {
416  array_traits::check_range(ordinal,Rank);
417  return ordinal ? stride[ordinal] / stride[ordinal-1] : stride[0] ;
418  }
419 };
420 
421 template< int_t Rank >
422 struct StrideDim<NaturalOrder,Rank,0> {
423 
424  template< typename iType >
425  static iType dimension( const iType * stride )
426  {
427  array_traits::CheckRange<0,Rank>::ok();
428  return stride[0];
429  }
430 
431  template< typename iType >
432  static iType dimension( const iType * stride , iType ordinal )
433  {
434  array_traits::check_range(ordinal,Rank);
435  ordinal = ( Rank - 1 ) - ordinal ;
436  return ordinal ? stride[ordinal] / stride[ordinal-1] : stride[0] ;
437  }
438 };
439 
440 template< int_t Rank , int_t Ordinal >
441 struct StrideDim<FortranOrder,Rank,Ordinal> {
442 
443  template< typename iType >
444  static iType dimension( const iType * stride )
445  {
446  array_traits::CheckRange<Ordinal,Rank>::ok();
447  return stride[Ordinal] / stride[Ordinal-1];
448  }
449 };
450 
451 template< int_t Rank , int_t Ordinal >
452 struct StrideDim<NaturalOrder,Rank,Ordinal> {
453 
454  template< typename iType >
455  static iType dimension( const iType * stride )
456  {
457  enum { I = ( Rank - 1 ) - Ordinal };
458  array_traits::CheckRange<Ordinal,Rank>::ok();
459  return stride[I] / stride[I-1];
460  }
461 };
462 
463 //----------------------------------------------------------------------
464 
465 template< ArrayOrder > struct Offset ;
466 
467 template<>
468 struct Offset<FortranOrder> {
469 
470  template< typename isType , typename iType >
471  static iType op( const isType * const stride ,
472  const iType & i1 , const iType & i2 ,
473  const iType & i3 , const iType & i4 ,
474  const iType & i5 , const iType & i6 ,
475  const iType & i7 , const iType & i8 )
476  {
477  SHARDS_ARRAY_CHECK(check_indices(false,8,stride,i1,i2,i3,i4,i5,i6,i7,i8));
478  return i1 + i2 * stride[0] +
479  i3 * stride[1] + i4 * stride[2] +
480  i5 * stride[3] + i6 * stride[4] +
481  i7 * stride[5] + i8 * stride[6] ;
482  }
483 
484  template< typename isType , typename iType >
485  static iType op( const isType * const stride ,
486  const iType & i1 , const iType & i2 ,
487  const iType & i3 , const iType & i4 ,
488  const iType & i5 , const iType & i6 ,
489  const iType & i7 )
490  {
491  SHARDS_ARRAY_CHECK(check_indices(false,7,stride,i1,i2,i3,i4,i5,i6,i7));
492  return i1 + i2 * stride[0] +
493  i3 * stride[1] + i4 * stride[2] +
494  i5 * stride[3] + i6 * stride[4] +
495  i7 * stride[5] ;
496  }
497 
498  template< typename isType , typename iType >
499  static iType op( const isType * const stride ,
500  const iType & i1 , const iType & i2 ,
501  const iType & i3 , const iType & i4 ,
502  const iType & i5 , const iType & i6 )
503  {
504  SHARDS_ARRAY_CHECK(check_indices(false,6,stride,i1,i2,i3,i4,i5,i6));
505  return i1 + i2 * stride[0] +
506  i3 * stride[1] + i4 * stride[2] +
507  i5 * stride[3] + i6 * stride[4] ;
508  }
509 
510  template< typename isType , typename iType >
511  static iType op( const isType * const stride ,
512  const iType & i1 , const iType & i2 ,
513  const iType & i3 , const iType & i4 ,
514  const iType & i5 )
515  {
516  SHARDS_ARRAY_CHECK(check_indices(false,5,stride,i1,i2,i3,i4,i5));
517  return i1 + i2 * stride[0] +
518  i3 * stride[1] + i4 * stride[2] +
519  i5 * stride[3] ;
520  }
521 
522  template< typename isType , typename iType >
523  static iType op( const isType * const stride ,
524  const iType & i1 , const iType & i2 ,
525  const iType & i3 , const iType & i4 )
526  {
527  SHARDS_ARRAY_CHECK(check_indices(false,4,stride,i1,i2,i3,i4));
528  return i1 + i2 * stride[0] +
529  i3 * stride[1] + i4 * stride[2] ;
530  }
531 
532  template< typename isType , typename iType >
533  static iType op( const isType * const stride ,
534  const iType & i1 , const iType & i2 ,
535  const iType & i3 )
536  {
537  SHARDS_ARRAY_CHECK(check_indices(false,3,stride,i1,i2,i3));
538  return i1 + i2 * stride[0] + i3 * stride[1] ;
539  }
540 
541  template< typename isType , typename iType >
542  static iType op( const isType * const stride ,
543  const iType & i1 , const iType & i2 )
544  {
545  SHARDS_ARRAY_CHECK(check_indices(false,2,stride,i1,i2));
546  return i1 + i2 * stride[0] ;
547  }
548 
549  template< typename isType , typename iType >
550  static iType op( const isType * const SHARDS_ARRAY_CHECK( stride ) ,
551  const iType & i1 )
552  {
553  SHARDS_ARRAY_CHECK(check_indices(false,1,stride,i1));
554  return i1 ;
555  }
556 };
557 
558 //----------------------------------------------------------------------
559 
560 template<>
561 struct Offset<NaturalOrder> {
562 
563  template< typename isType , typename iType >
564  static iType op( const isType * const stride ,
565  const iType & i1 , const iType & i2 ,
566  const iType & i3 , const iType & i4 ,
567  const iType & i5 , const iType & i6 ,
568  const iType & i7 , const iType & i8 )
569  {
570  SHARDS_ARRAY_CHECK(check_indices(true,8,stride,i1,i2,i3,i4,i5,i6,i7,i8));
571  return i8 + i7 * stride[0] +
572  i6 * stride[1] + i5 * stride[2] +
573  i4 * stride[3] + i3 * stride[4] +
574  i2 * stride[5] + i1 * stride[6] ;
575  }
576 
577  template< typename isType , typename iType >
578  static iType op( const isType * const stride ,
579  const iType & i1 , const iType & i2 ,
580  const iType & i3 , const iType & i4 ,
581  const iType & i5 , const iType & i6 ,
582  const iType & i7 )
583  {
584  SHARDS_ARRAY_CHECK(check_indices(true,7,stride,i1,i2,i3,i4,i5,i6,i7));
585  return i7 + i6 * stride[0] +
586  i5 * stride[1] + i4 * stride[2] +
587  i3 * stride[3] + i2 * stride[4] +
588  i1 * stride[5] ;
589  }
590 
591  template< typename isType , typename iType >
592  static iType op( const isType * const stride ,
593  const iType & i1 , const iType & i2 ,
594  const iType & i3 , const iType & i4 ,
595  const iType & i5 , const iType & i6 )
596  {
597  SHARDS_ARRAY_CHECK(check_indices(true,6,stride,i1,i2,i3,i4,i5,i6));
598  return i6 + i5 * stride[0] +
599  i4 * stride[1] + i3 * stride[2] +
600  i2 * stride[3] + i1 * stride[4] ;
601  }
602 
603  template< typename isType , typename iType >
604  static iType op( const isType * const stride ,
605  const iType & i1 , const iType & i2 ,
606  const iType & i3 , const iType & i4 ,
607  const iType & i5 )
608  {
609  SHARDS_ARRAY_CHECK(check_indices(true,5,stride,i1,i2,i3,i4,i5));
610  return i5 + i4 * stride[0] +
611  i3 * stride[1] + i2 * stride[2] +
612  i1 * stride[3] ;
613  }
614 
615  template< typename isType , typename iType >
616  static iType op( const isType * const stride ,
617  const iType & i1 , const iType & i2 ,
618  const iType & i3 , const iType & i4 )
619  {
620  SHARDS_ARRAY_CHECK(check_indices(true,4,stride,i1,i2,i3,i4));
621  return i4 + i3 * stride[0] +
622  i2 * stride[1] + i1 * stride[2] ;
623  }
624 
625  template< typename isType , typename iType >
626  static iType op( const isType * const stride ,
627  const iType & i1 , const iType & i2 ,
628  const iType & i3 )
629  {
630  SHARDS_ARRAY_CHECK(check_indices(true,3,stride,i1,i2,i3));
631  return i3 + i2 * stride[0] + i1 * stride[1] ;
632  }
633 
634  template< typename isType , typename iType >
635  static iType op( const isType * const stride ,
636  const iType & i1 , const iType & i2 )
637  {
638  SHARDS_ARRAY_CHECK(check_indices(true,2,stride,i1,i2));
639  return i2 + i1 * stride[0] ;
640  }
641 
642  template< typename isType , typename iType >
643  static iType op( const isType * const SHARDS_ARRAY_CHECK( stride ) ,
644  const iType & i1 )
645  {
646  SHARDS_ARRAY_CHECK(check_indices(true,1,stride,i1));
647  return i1 ;
648  }
649 };
650 
651 //----------------------------------------------------------------------
652 //----------------------------------------------------------------------
653 
654 template< typename Scalar , ArrayOrder Order ,
655  class Tag1 , class Tag2 , class Tag3 , class Tag4 ,
656  class Tag5 , class Tag6 , class Tag7 , class Tag8 >
657 struct Helper ;
658 
659 //----------------------------------------------------------------------
662 template< typename Scalar ,
663  class Tag1 , class Tag2 , class Tag3 , class Tag4 ,
664  class Tag5 , class Tag6 , class Tag7 , class Tag8 >
665 struct Helper<Scalar,NaturalOrder,Tag1,Tag2,Tag3,Tag4,Tag5,Tag6,Tag7,Tag8>
666 {
667  typedef
668  Array<Scalar,FortranOrder,Tag8,Tag7,Tag6,Tag5,Tag4,Tag3,Tag2,Tag1>
669  reverse ;
670 
671  typedef
672  Array<Scalar,NaturalOrder,Tag2,Tag3,Tag4,Tag5,Tag6,Tag7,Tag8,void>
673  truncate ;
674 
675  enum { Rank = 8 };
676 
677  static bool verify( const int_t rank , const ArrayDimTag * const tags[] )
678  {
679  return rank == Rank &&
680  tags[0] == & Tag8::tag() &&
681  tags[1] == & Tag7::tag() &&
682  tags[2] == & Tag6::tag() &&
683  tags[3] == & Tag5::tag() &&
684  tags[4] == & Tag4::tag() &&
685  tags[5] == & Tag3::tag() &&
686  tags[6] == & Tag2::tag() &&
687  tags[7] == & Tag1::tag() ;
688  }
689 
690  static void assign_tags( const ArrayDimTag * tags[] )
691  {
692  tags[0] = & Tag8::tag();
693  tags[1] = & Tag7::tag();
694  tags[2] = & Tag6::tag();
695  tags[3] = & Tag5::tag();
696  tags[4] = & Tag4::tag();
697  tags[5] = & Tag3::tag();
698  tags[6] = & Tag2::tag();
699  tags[7] = & Tag1::tag();
700  }
701 
702  template< typename iType >
703  static void assign( iType * stride )
704  {
705  stride[7] = Tag1::Size * (
706  stride[6] = Tag2::Size * (
707  stride[5] = Tag3::Size * (
708  stride[4] = Tag4::Size * (
709  stride[3] = Tag5::Size * (
710  stride[2] = Tag6::Size * (
711  stride[1] = Tag7::Size * (
712  stride[0] = Tag8::Size )))))));
713  }
714 
715  template< typename iType >
716  static void assign( iType * stride ,
717  const iType & n1 )
718  {
719  stride[7] = n1 * (
720  stride[6] = Tag2::Size * (
721  stride[5] = Tag3::Size * (
722  stride[4] = Tag4::Size * (
723  stride[3] = Tag5::Size * (
724  stride[2] = Tag6::Size * (
725  stride[1] = Tag7::Size * (
726  stride[0] = Tag8::Size )))))));
727  }
728 
729  template< typename iType >
730  static void assign( iType * stride ,
731  const iType & n1 ,
732  const iType & n2 )
733  {
734  stride[7] = n1 * (
735  stride[6] = n2 * (
736  stride[5] = Tag3::Size * (
737  stride[4] = Tag4::Size * (
738  stride[3] = Tag5::Size * (
739  stride[2] = Tag6::Size * (
740  stride[1] = Tag7::Size * (
741  stride[0] = Tag8::Size )))))));
742  }
743 
744  template< typename iType >
745  static void assign( iType * stride ,
746  const iType & n1 ,
747  const iType & n2 ,
748  const iType & n3 )
749  {
750  stride[7] = n1 * (
751  stride[6] = n2 * (
752  stride[5] = n3 * (
753  stride[4] = Tag4::Size * (
754  stride[3] = Tag5::Size * (
755  stride[2] = Tag6::Size * (
756  stride[1] = Tag7::Size * (
757  stride[0] = Tag8::Size )))))));
758  }
759 
760  template< typename iType >
761  static void assign( iType * stride ,
762  const iType & n1 ,
763  const iType & n2 ,
764  const iType & n3 ,
765  const iType & n4 )
766  {
767  stride[7] = n1 * (
768  stride[6] = n2 * (
769  stride[5] = n3 * (
770  stride[4] = n4 * (
771  stride[3] = Tag5::Size * (
772  stride[2] = Tag6::Size * (
773  stride[1] = Tag7::Size * (
774  stride[0] = Tag8::Size )))))));
775  }
776 
777  template< typename iType >
778  static void assign( iType * stride ,
779  const iType & n1 ,
780  const iType & n2 ,
781  const iType & n3 ,
782  const iType & n4 ,
783  const iType & n5 )
784  {
785  stride[7] = n1 * (
786  stride[6] = n2 * (
787  stride[5] = n3 * (
788  stride[4] = n4 * (
789  stride[3] = n5 * (
790  stride[2] = Tag6::Size * (
791  stride[1] = Tag7::Size * (
792  stride[0] = Tag8::Size )))))));
793  }
794 
795  template< typename iType >
796  static void assign( iType * stride ,
797  const iType & n1 ,
798  const iType & n2 ,
799  const iType & n3 ,
800  const iType & n4 ,
801  const iType & n5 ,
802  const iType & n6 )
803  {
804  stride[7] = n1 * (
805  stride[6] = n2 * (
806  stride[5] = n3 * (
807  stride[4] = n4 * (
808  stride[3] = n5 * (
809  stride[2] = n6 * (
810  stride[1] = Tag7::Size * (
811  stride[0] = Tag8::Size )))))));
812  }
813 
814  template< typename iType >
815  static void assign( iType * stride ,
816  const iType & n1 ,
817  const iType & n2 ,
818  const iType & n3 ,
819  const iType & n4 ,
820  const iType & n5 ,
821  const iType & n6 ,
822  const iType & n7 )
823  {
824  stride[7] = n1 * (
825  stride[6] = n2 * (
826  stride[5] = n3 * (
827  stride[4] = n4 * (
828  stride[3] = n5 * (
829  stride[2] = n6 * (
830  stride[1] = n7 * (
831  stride[0] = Tag8::Size )))))));
832  }
833 
834  template< typename iType >
835  static void assign( iType * stride ,
836  const iType & n1 ,
837  const iType & n2 ,
838  const iType & n3 ,
839  const iType & n4 ,
840  const iType & n5 ,
841  const iType & n6 ,
842  const iType & n7 ,
843  const iType & n8 )
844  {
845  stride[7] = n1 * (
846  stride[6] = n2 * (
847  stride[5] = n3 * (
848  stride[4] = n4 * (
849  stride[3] = n5 * (
850  stride[2] = n6 * (
851  stride[1] = n7 * (
852  stride[0] = n8 )))))));
853  }
854 
855  template< typename iType >
856  static void assign( iType * stride ,
857  const iType * const dims )
858  {
859  stride[7] = dims[0] * (
860  stride[6] = dims[1] * (
861  stride[5] = dims[2] * (
862  stride[4] = dims[3] * (
863  stride[3] = dims[4] * (
864  stride[2] = dims[5] * (
865  stride[1] = dims[6] * (
866  stride[0] = dims[7] )))))));
867  }
868 };
869 
870 template< typename Scalar ,
871  class Tag1 , class Tag2 , class Tag3 , class Tag4 ,
872  class Tag5 , class Tag6 , class Tag7 , class Tag8 >
873 struct Helper<Scalar,FortranOrder,Tag1,Tag2,Tag3,Tag4,Tag5,Tag6,Tag7,Tag8>
874 {
875  typedef
876  Array<Scalar,NaturalOrder,Tag8,Tag7,Tag6,Tag5,Tag4,Tag3,Tag2,Tag1>
877  reverse ;
878 
879  typedef
880  Array<Scalar,FortranOrder,Tag1,Tag2,Tag3,Tag4,Tag5,Tag6,Tag7,void>
881  truncate ;
882 
883  enum { Rank = 8 };
884 
885  static bool verify( int_t rank , const ArrayDimTag * tags[] )
886  {
887  return rank == Rank &&
888  tags[0] == & Tag1::tag() &&
889  tags[1] == & Tag2::tag() &&
890  tags[2] == & Tag3::tag() &&
891  tags[3] == & Tag4::tag() &&
892  tags[4] == & Tag5::tag() &&
893  tags[5] == & Tag6::tag() &&
894  tags[6] == & Tag7::tag() &&
895  tags[7] == & Tag8::tag();
896  }
897 
898  static void assign_tags( const ArrayDimTag * tags[] )
899  {
900  tags[0] = & Tag1::tag();
901  tags[1] = & Tag2::tag();
902  tags[2] = & Tag3::tag();
903  tags[3] = & Tag4::tag();
904  tags[4] = & Tag5::tag();
905  tags[5] = & Tag6::tag();
906  tags[6] = & Tag7::tag();
907  tags[7] = & Tag8::tag();
908  }
909 
910  template< typename iType >
911  static void assign( iType * stride )
912  {
913  stride[7] = Tag8::Size * (
914  stride[6] = Tag7::Size * (
915  stride[5] = Tag6::Size * (
916  stride[4] = Tag5::Size * (
917  stride[3] = Tag4::Size * (
918  stride[2] = Tag3::Size * (
919  stride[1] = Tag2::Size * (
920  stride[0] = Tag1::Size )))))));
921  }
922 
923  template< typename iType >
924  static void assign( iType * stride ,
925  const iType & n8 )
926  {
927  stride[7] = n8 * (
928  stride[6] = Tag7::Size * (
929  stride[5] = Tag6::Size * (
930  stride[4] = Tag5::Size * (
931  stride[3] = Tag4::Size * (
932  stride[2] = Tag3::Size * (
933  stride[1] = Tag2::Size * (
934  stride[0] = Tag1::Size )))))));
935  }
936 
937  template< typename iType >
938  static void assign( iType * stride ,
939  const iType & n7 ,
940  const iType & n8 )
941  {
942  stride[7] = n8 * (
943  stride[6] = n7 * (
944  stride[5] = Tag6::Size * (
945  stride[4] = Tag5::Size * (
946  stride[3] = Tag4::Size * (
947  stride[2] = Tag3::Size * (
948  stride[1] = Tag2::Size * (
949  stride[0] = Tag1::Size )))))));
950  }
951 
952  template< typename iType >
953  static void assign( iType * stride ,
954  const iType & n6 ,
955  const iType & n7 ,
956  const iType & n8 )
957  {
958  stride[7] = n8 * (
959  stride[6] = n7 * (
960  stride[5] = n6 * (
961  stride[4] = Tag5::Size * (
962  stride[3] = Tag4::Size * (
963  stride[2] = Tag3::Size * (
964  stride[1] = Tag2::Size * (
965  stride[0] = Tag1::Size )))))));
966  }
967 
968  template< typename iType >
969  static void assign( iType * stride ,
970  const iType & n5 ,
971  const iType & n6 ,
972  const iType & n7 ,
973  const iType & n8 )
974  {
975  stride[7] = n8 * (
976  stride[6] = n7 * (
977  stride[5] = n6 * (
978  stride[4] = n5 * (
979  stride[3] = Tag4::Size * (
980  stride[2] = Tag3::Size * (
981  stride[1] = Tag2::Size * (
982  stride[0] = Tag1::Size )))))));
983  }
984 
985  template< typename iType >
986  static void assign( iType * stride ,
987  const iType & n4 ,
988  const iType & n5 ,
989  const iType & n6 ,
990  const iType & n7 ,
991  const iType & n8 )
992  {
993  stride[7] = n8 * (
994  stride[6] = n7 * (
995  stride[5] = n6 * (
996  stride[4] = n5 * (
997  stride[3] = n4 * (
998  stride[2] = Tag3::Size * (
999  stride[1] = Tag2::Size * (
1000  stride[0] = Tag1::Size )))))));
1001  }
1002 
1003  template< typename iType >
1004  static void assign( iType * stride ,
1005  const iType & n3 ,
1006  const iType & n4 ,
1007  const iType & n5 ,
1008  const iType & n6 ,
1009  const iType & n7 ,
1010  const iType & n8 )
1011  {
1012  stride[7] = n8 * (
1013  stride[6] = n7 * (
1014  stride[5] = n6 * (
1015  stride[4] = n5 * (
1016  stride[3] = n4 * (
1017  stride[2] = n3 * (
1018  stride[1] = Tag2::Size * (
1019  stride[0] = Tag1::Size )))))));
1020  }
1021 
1022  template< typename iType >
1023  static void assign( iType * stride ,
1024  const iType & n2 ,
1025  const iType & n3 ,
1026  const iType & n4 ,
1027  const iType & n5 ,
1028  const iType & n6 ,
1029  const iType & n7 ,
1030  const iType & n8 )
1031  {
1032  stride[7] = n8 * (
1033  stride[6] = n7 * (
1034  stride[5] = n6 * (
1035  stride[4] = n5 * (
1036  stride[3] = n4 * (
1037  stride[2] = n3 * (
1038  stride[1] = n2 * (
1039  stride[0] = Tag1::Size )))))));
1040  }
1041 
1042  template< typename iType >
1043  static void assign( iType * stride ,
1044  const iType & n1 ,
1045  const iType & n2 ,
1046  const iType & n3 ,
1047  const iType & n4 ,
1048  const iType & n5 ,
1049  const iType & n6 ,
1050  const iType & n7 ,
1051  const iType & n8 )
1052  {
1053  stride[7] = n8 * (
1054  stride[6] = n7 * (
1055  stride[5] = n6 * (
1056  stride[4] = n5 * (
1057  stride[3] = n4 * (
1058  stride[2] = n3 * (
1059  stride[1] = n2 * (
1060  stride[0] = n1 )))))));
1061  }
1062 
1063  template< typename iType >
1064  static void assign( iType * stride ,
1065  const iType * const dims )
1066  {
1067  stride[7] = dims[7] * (
1068  stride[6] = dims[6] * (
1069  stride[5] = dims[5] * (
1070  stride[4] = dims[4] * (
1071  stride[3] = dims[3] * (
1072  stride[2] = dims[2] * (
1073  stride[1] = dims[1] * (
1074  stride[0] = dims[0] )))))));
1075  }
1076 };
1077 
1078 //----------------------------------------------------------------------
1081 template< typename Scalar ,
1082  class Tag1 , class Tag2 , class Tag3 , class Tag4 ,
1083  class Tag5 , class Tag6 , class Tag7 >
1084 struct Helper<Scalar,NaturalOrder,Tag1,Tag2,Tag3,Tag4,Tag5,Tag6,Tag7,void>
1085 {
1086  typedef
1087  Array<Scalar,FortranOrder,Tag7,Tag6,Tag5,Tag4,Tag3,Tag2,Tag1,void>
1088  reverse ;
1089 
1090  typedef
1091  Array<Scalar,NaturalOrder,Tag2,Tag3,Tag4,Tag5,Tag6,Tag7,void,void>
1092  truncate ;
1093 
1094  template< class TagA >
1095  struct append {
1096  typedef
1097  Array<Scalar,NaturalOrder,TagA,Tag1,Tag2,Tag3,Tag4,Tag5,Tag6,Tag7>
1098  natural ;
1099 
1100  typedef
1101  Array<Scalar,FortranOrder,Tag7,Tag6,Tag5,Tag4,Tag3,Tag2,Tag1,TagA>
1102  fortran ;
1103 
1104  typedef natural type ;
1105  typedef fortran reverse ;
1106  };
1107 
1108  enum { Rank = 7 };
1109 
1110  static bool verify( int_t rank , const ArrayDimTag * tags[] )
1111  {
1112  return rank == Rank &&
1113  tags[0] == & Tag7::tag() &&
1114  tags[1] == & Tag6::tag() &&
1115  tags[2] == & Tag5::tag() &&
1116  tags[3] == & Tag4::tag() &&
1117  tags[4] == & Tag3::tag() &&
1118  tags[5] == & Tag2::tag() &&
1119  tags[6] == & Tag1::tag() ;
1120  }
1121 
1122  static void assign_tags( const ArrayDimTag * tags[] )
1123  {
1124  tags[0] = & Tag7::tag();
1125  tags[1] = & Tag6::tag();
1126  tags[2] = & Tag5::tag();
1127  tags[3] = & Tag4::tag();
1128  tags[4] = & Tag3::tag();
1129  tags[5] = & Tag2::tag();
1130  tags[6] = & Tag1::tag();
1131  tags[7] = NULL ;
1132  }
1133 
1134  template< typename iType >
1135  static void assign( iType * stride )
1136  {
1137  stride[7] = 0 ;
1138  stride[6] = Tag1::Size * (
1139  stride[5] = Tag2::Size * (
1140  stride[4] = Tag3::Size * (
1141  stride[3] = Tag4::Size * (
1142  stride[2] = Tag5::Size * (
1143  stride[1] = Tag6::Size * (
1144  stride[0] = Tag7::Size ))))));
1145  }
1146 
1147  template< typename iType >
1148  static void assign( iType * stride ,
1149  const iType & n1 )
1150  {
1151  stride[7] = 0 ;
1152  stride[6] = n1 * (
1153  stride[5] = Tag2::Size * (
1154  stride[4] = Tag3::Size * (
1155  stride[3] = Tag4::Size * (
1156  stride[2] = Tag5::Size * (
1157  stride[1] = Tag6::Size * (
1158  stride[0] = Tag7::Size ))))));
1159  }
1160 
1161  template< typename iType >
1162  static void assign( iType * stride ,
1163  const iType & n1 ,
1164  const iType & n2 )
1165  {
1166  stride[7] = 0 ;
1167  stride[6] = n1 * (
1168  stride[5] = n2 * (
1169  stride[4] = Tag3::Size * (
1170  stride[3] = Tag4::Size * (
1171  stride[2] = Tag5::Size * (
1172  stride[1] = Tag6::Size * (
1173  stride[0] = Tag7::Size ))))));
1174  }
1175 
1176  template< typename iType >
1177  static void assign( iType * stride ,
1178  const iType & n1 ,
1179  const iType & n2 ,
1180  const iType & n3 )
1181  {
1182  stride[7] = 0 ;
1183  stride[6] = n1 * (
1184  stride[5] = n2 * (
1185  stride[4] = n3 * (
1186  stride[3] = Tag4::Size * (
1187  stride[2] = Tag5::Size * (
1188  stride[1] = Tag6::Size * (
1189  stride[0] = Tag7::Size ))))));
1190  }
1191 
1192  template< typename iType >
1193  static void assign( iType * stride ,
1194  const iType & n1 ,
1195  const iType & n2 ,
1196  const iType & n3 ,
1197  const iType & n4 )
1198  {
1199  stride[7] = 0 ;
1200  stride[6] = n1 * (
1201  stride[5] = n2 * (
1202  stride[4] = n3 * (
1203  stride[3] = n4 * (
1204  stride[2] = Tag5::Size * (
1205  stride[1] = Tag6::Size * (
1206  stride[0] = Tag7::Size ))))));
1207  }
1208 
1209  template< typename iType >
1210  static void assign( iType * stride ,
1211  const iType & n1 ,
1212  const iType & n2 ,
1213  const iType & n3 ,
1214  const iType & n4 ,
1215  const iType & n5 )
1216  {
1217  stride[7] = 0 ;
1218  stride[6] = n1 * (
1219  stride[5] = n2 * (
1220  stride[4] = n3 * (
1221  stride[3] = n4 * (
1222  stride[2] = n5 * (
1223  stride[1] = Tag6::Size * (
1224  stride[0] = Tag7::Size ))))));
1225  }
1226 
1227  template< typename iType >
1228  static void assign( iType * stride ,
1229  const iType & n1 ,
1230  const iType & n2 ,
1231  const iType & n3 ,
1232  const iType & n4 ,
1233  const iType & n5 ,
1234  const iType & n6 )
1235  {
1236  stride[7] = 0 ;
1237  stride[6] = n1 * (
1238  stride[5] = n2 * (
1239  stride[4] = n3 * (
1240  stride[3] = n4 * (
1241  stride[2] = n5 * (
1242  stride[1] = n6 * (
1243  stride[0] = Tag7::Size ))))));
1244  }
1245 
1246  template< typename iType >
1247  static void assign( iType * stride ,
1248  const iType & n1 ,
1249  const iType & n2 ,
1250  const iType & n3 ,
1251  const iType & n4 ,
1252  const iType & n5 ,
1253  const iType & n6 ,
1254  const iType & n7 )
1255  {
1256  stride[7] = 0 ;
1257  stride[6] = n1 * (
1258  stride[5] = n2 * (
1259  stride[4] = n3 * (
1260  stride[3] = n4 * (
1261  stride[2] = n5 * (
1262  stride[1] = n6 * (
1263  stride[0] = n7 ))))));
1264  }
1265 
1266  template< typename iType >
1267  static void assign( iType * stride ,
1268  const iType * const dims )
1269  {
1270  stride[7] = 0 ;
1271  stride[6] = dims[0] * (
1272  stride[5] = dims[1] * (
1273  stride[4] = dims[2] * (
1274  stride[3] = dims[3] * (
1275  stride[2] = dims[4] * (
1276  stride[1] = dims[5] * (
1277  stride[0] = dims[6] ))))));
1278  }
1279 };
1280 
1281 template< typename Scalar ,
1282  class Tag1 , class Tag2 , class Tag3 , class Tag4 ,
1283  class Tag5 , class Tag6 , class Tag7 >
1284 struct Helper<Scalar,FortranOrder,Tag1,Tag2,Tag3,Tag4,Tag5,Tag6,Tag7,void>
1285 {
1286  typedef
1287  Array<Scalar,NaturalOrder,Tag7,Tag6,Tag5,Tag4,Tag3,Tag2,Tag1,void>
1288  reverse ;
1289 
1290  typedef
1291  Array<Scalar,FortranOrder,Tag1,Tag2,Tag3,Tag4,Tag5,Tag6,void,void>
1292  truncate ;
1293 
1294  template< class TagA >
1295  struct append {
1296  typedef
1297  Array<Scalar,FortranOrder,Tag1,Tag2,Tag3,Tag4,Tag5,Tag6,Tag7,TagA>
1298  fortran ;
1299 
1300  typedef
1301  Array<Scalar,NaturalOrder,TagA,Tag7,Tag6,Tag5,Tag4,Tag3,Tag2,Tag1>
1302  natural ;
1303 
1304  typedef fortran type ;
1305  typedef natural reverse ;
1306  };
1307 
1308  enum { Rank = 7 };
1309 
1310  static bool verify( int_t rank , const ArrayDimTag * tags[] )
1311  {
1312  return rank == Rank &&
1313  tags[0] == & Tag1::tag() &&
1314  tags[1] == & Tag2::tag() &&
1315  tags[2] == & Tag3::tag() &&
1316  tags[3] == & Tag4::tag() &&
1317  tags[4] == & Tag5::tag() &&
1318  tags[5] == & Tag6::tag() &&
1319  tags[6] == & Tag7::tag();
1320  }
1321 
1322  static void assign_tags( const ArrayDimTag * tags[] )
1323  {
1324  tags[0] = & Tag1::tag();
1325  tags[1] = & Tag2::tag();
1326  tags[2] = & Tag3::tag();
1327  tags[3] = & Tag4::tag();
1328  tags[4] = & Tag5::tag();
1329  tags[5] = & Tag6::tag();
1330  tags[6] = & Tag7::tag();
1331  tags[7] = NULL ;
1332  }
1333 
1334  template< typename iType >
1335  static void assign( iType * stride )
1336  {
1337  stride[7] = 0 ;
1338  stride[6] = Tag7::Size * (
1339  stride[5] = Tag6::Size * (
1340  stride[4] = Tag5::Size * (
1341  stride[3] = Tag4::Size * (
1342  stride[2] = Tag3::Size * (
1343  stride[1] = Tag2::Size * (
1344  stride[0] = Tag1::Size ))))));
1345  }
1346 
1347  template< typename iType >
1348  static void assign( iType * stride ,
1349  const iType & n7 )
1350  {
1351  stride[7] = 0 ;
1352  stride[6] = n7 * (
1353  stride[5] = Tag6::Size * (
1354  stride[4] = Tag5::Size * (
1355  stride[3] = Tag4::Size * (
1356  stride[2] = Tag3::Size * (
1357  stride[1] = Tag2::Size * (
1358  stride[0] = Tag1::Size ))))));
1359  }
1360 
1361  template< typename iType >
1362  static void assign( iType * stride ,
1363  const iType & n6 ,
1364  const iType & n7 )
1365  {
1366  stride[7] = 0 ;
1367  stride[6] = n7 * (
1368  stride[5] = n6 * (
1369  stride[4] = Tag5::Size * (
1370  stride[3] = Tag4::Size * (
1371  stride[2] = Tag3::Size * (
1372  stride[1] = Tag2::Size * (
1373  stride[0] = Tag1::Size ))))));
1374  }
1375 
1376  template< typename iType >
1377  static void assign( iType * stride ,
1378  const iType & n5 ,
1379  const iType & n6 ,
1380  const iType & n7 )
1381  {
1382  stride[7] = 0 ;
1383  stride[6] = n7 * (
1384  stride[5] = n6 * (
1385  stride[4] = n5 * (
1386  stride[3] = Tag4::Size * (
1387  stride[2] = Tag3::Size * (
1388  stride[1] = Tag2::Size * (
1389  stride[0] = Tag1::Size ))))));
1390  }
1391 
1392  template< typename iType >
1393  static void assign( iType * stride ,
1394  const iType & n4 ,
1395  const iType & n5 ,
1396  const iType & n6 ,
1397  const iType & n7 )
1398  {
1399  stride[7] = 0 ;
1400  stride[6] = n7 * (
1401  stride[5] = n6 * (
1402  stride[4] = n5 * (
1403  stride[3] = n4 * (
1404  stride[2] = Tag3::Size * (
1405  stride[1] = Tag2::Size * (
1406  stride[0] = Tag1::Size ))))));
1407  }
1408 
1409  template< typename iType >
1410  static void assign( iType * stride ,
1411  const iType & n3 ,
1412  const iType & n4 ,
1413  const iType & n5 ,
1414  const iType & n6 ,
1415  const iType & n7 )
1416  {
1417  stride[7] = 0 ;
1418  stride[6] = n7 * (
1419  stride[5] = n6 * (
1420  stride[4] = n5 * (
1421  stride[3] = n4 * (
1422  stride[2] = n3 * (
1423  stride[1] = Tag2::Size * (
1424  stride[0] = Tag1::Size ))))));
1425  }
1426 
1427  template< typename iType >
1428  static void assign( iType * stride ,
1429  const iType & n2 ,
1430  const iType & n3 ,
1431  const iType & n4 ,
1432  const iType & n5 ,
1433  const iType & n6 ,
1434  const iType & n7 )
1435  {
1436  stride[7] = 0 ;
1437  stride[6] = n7 * (
1438  stride[5] = n6 * (
1439  stride[4] = n5 * (
1440  stride[3] = n4 * (
1441  stride[2] = n3 * (
1442  stride[1] = n2 * (
1443  stride[0] = Tag1::Size ))))));
1444  }
1445 
1446  template< typename iType >
1447  static void assign( iType * stride ,
1448  const iType & n1 ,
1449  const iType & n2 ,
1450  const iType & n3 ,
1451  const iType & n4 ,
1452  const iType & n5 ,
1453  const iType & n6 ,
1454  const iType & n7 )
1455  {
1456  stride[7] = 0 ;
1457  stride[6] = n7 * (
1458  stride[5] = n6 * (
1459  stride[4] = n5 * (
1460  stride[3] = n4 * (
1461  stride[2] = n3 * (
1462  stride[1] = n2 * (
1463  stride[0] = n1 ))))));
1464  }
1465 
1466  template< typename iType >
1467  static void assign( iType * stride ,
1468  const iType * const dims )
1469  {
1470  stride[7] = 0 ;
1471  stride[6] = dims[6] * (
1472  stride[5] = dims[5] * (
1473  stride[4] = dims[4] * (
1474  stride[3] = dims[3] * (
1475  stride[2] = dims[2] * (
1476  stride[1] = dims[1] * (
1477  stride[0] = dims[0] ))))));
1478  }
1479 };
1480 
1481 //----------------------------------------------------------------------
1484 template< typename Scalar ,
1485  class Tag1 , class Tag2 , class Tag3 , class Tag4 ,
1486  class Tag5 , class Tag6 >
1487 struct Helper<Scalar,NaturalOrder,Tag1,Tag2,Tag3,Tag4,Tag5,Tag6,void,void>
1488 {
1489  typedef
1490  Array<Scalar,FortranOrder,Tag6,Tag5,Tag4,Tag3,Tag2,Tag1,void,void>
1491  reverse ;
1492 
1493  typedef
1494  Array<Scalar,NaturalOrder,Tag2,Tag3,Tag4,Tag5,Tag6,void,void,void>
1495  truncate ;
1496 
1497  template< class TagA >
1498  struct append {
1499  typedef
1500  Array<Scalar,NaturalOrder,TagA,Tag1,Tag2,Tag3,Tag4,Tag5,Tag6,void>
1501  natural ;
1502 
1503  typedef
1504  Array<Scalar,FortranOrder,Tag6,Tag5,Tag4,Tag3,Tag2,Tag1,TagA,void>
1505  fortran ;
1506 
1507  typedef natural type ;
1508  typedef fortran reverse ;
1509  };
1510 
1511  enum { Rank = 6 };
1512 
1513  static bool verify( int_t rank , const ArrayDimTag * tags[] )
1514  {
1515  return rank == Rank &&
1516  tags[0] == & Tag6::tag() &&
1517  tags[1] == & Tag5::tag() &&
1518  tags[2] == & Tag4::tag() &&
1519  tags[3] == & Tag3::tag() &&
1520  tags[4] == & Tag2::tag() &&
1521  tags[5] == & Tag1::tag();
1522  }
1523 
1524  static void assign_tags( const ArrayDimTag * tags[] )
1525  {
1526  tags[0] = & Tag6::tag();
1527  tags[1] = & Tag5::tag();
1528  tags[2] = & Tag4::tag();
1529  tags[3] = & Tag3::tag();
1530  tags[4] = & Tag2::tag();
1531  tags[5] = & Tag1::tag();
1532  tags[6] = NULL ;
1533  tags[7] = NULL ;
1534  }
1535 
1536  template< typename iType >
1537  static void assign( iType * stride )
1538  {
1539  stride[7] = 0 ;
1540  stride[6] = 0 ;
1541  stride[5] = Tag1::Size * (
1542  stride[4] = Tag2::Size * (
1543  stride[3] = Tag3::Size * (
1544  stride[2] = Tag4::Size * (
1545  stride[1] = Tag5::Size * (
1546  stride[0] = Tag6::Size )))));
1547  }
1548 
1549  template< typename iType >
1550  static void assign( iType * stride ,
1551  const iType & n1 )
1552  {
1553  stride[7] = 0 ;
1554  stride[6] = 0 ;
1555  stride[5] = n1 * (
1556  stride[4] = Tag2::Size * (
1557  stride[3] = Tag3::Size * (
1558  stride[2] = Tag4::Size * (
1559  stride[1] = Tag5::Size * (
1560  stride[0] = Tag6::Size )))));
1561  }
1562 
1563  template< typename iType >
1564  static void assign( iType * stride ,
1565  const iType & n1 ,
1566  const iType & n2 )
1567  {
1568  stride[7] = 0 ;
1569  stride[6] = 0 ;
1570  stride[5] = n1 * (
1571  stride[4] = n2 * (
1572  stride[3] = Tag3::Size * (
1573  stride[2] = Tag4::Size * (
1574  stride[1] = Tag5::Size * (
1575  stride[0] = Tag6::Size )))));
1576  }
1577 
1578  template< typename iType >
1579  static void assign( iType * stride ,
1580  const iType & n1 ,
1581  const iType & n2 ,
1582  const iType & n3 )
1583  {
1584  stride[7] = 0 ;
1585  stride[6] = 0 ;
1586  stride[5] = n1 * (
1587  stride[4] = n2 * (
1588  stride[3] = n3 * (
1589  stride[2] = Tag4::Size * (
1590  stride[1] = Tag5::Size * (
1591  stride[0] = Tag6::Size )))));
1592  }
1593 
1594  template< typename iType >
1595  static void assign( iType * stride ,
1596  const iType & n1 ,
1597  const iType & n2 ,
1598  const iType & n3 ,
1599  const iType & n4 )
1600  {
1601  stride[7] = 0 ;
1602  stride[6] = 0 ;
1603  stride[5] = n1 * (
1604  stride[4] = n2 * (
1605  stride[3] = n3 * (
1606  stride[2] = n4 * (
1607  stride[1] = Tag5::Size * (
1608  stride[0] = Tag6::Size )))));
1609  }
1610 
1611  template< typename iType >
1612  static void assign( iType * stride ,
1613  const iType & n1 ,
1614  const iType & n2 ,
1615  const iType & n3 ,
1616  const iType & n4 ,
1617  const iType & n5 )
1618  {
1619  stride[7] = 0 ;
1620  stride[6] = 0 ;
1621  stride[5] = n1 * (
1622  stride[4] = n2 * (
1623  stride[3] = n3 * (
1624  stride[2] = n4 * (
1625  stride[1] = n5 * (
1626  stride[0] = Tag6::Size )))));
1627  }
1628 
1629  template< typename iType >
1630  static void assign( iType * stride ,
1631  const iType & n1 ,
1632  const iType & n2 ,
1633  const iType & n3 ,
1634  const iType & n4 ,
1635  const iType & n5 ,
1636  const iType & n6 )
1637  {
1638  stride[7] = 0 ;
1639  stride[6] = 0 ;
1640  stride[5] = n1 * (
1641  stride[4] = n2 * (
1642  stride[3] = n3 * (
1643  stride[2] = n4 * (
1644  stride[1] = n5 * (
1645  stride[0] = n6 )))));
1646  }
1647 
1648  template< typename iType >
1649  static void assign( iType * stride ,
1650  const iType * const dims )
1651  {
1652  stride[7] = 0 ;
1653  stride[6] = 0 ;
1654  stride[5] = dims[0] * (
1655  stride[4] = dims[1] * (
1656  stride[3] = dims[2] * (
1657  stride[2] = dims[3] * (
1658  stride[1] = dims[4] * (
1659  stride[0] = dims[5] )))));
1660  }
1661 };
1662 
1663 template< typename Scalar ,
1664  class Tag1 , class Tag2 , class Tag3 , class Tag4 ,
1665  class Tag5 , class Tag6 >
1666 struct Helper<Scalar,FortranOrder,Tag1,Tag2,Tag3,Tag4,Tag5,Tag6,void,void>
1667 {
1668  typedef
1669  Array<Scalar,NaturalOrder,Tag6,Tag5,Tag4,Tag3,Tag2,Tag1,void,void>
1670  reverse ;
1671 
1672  typedef
1673  Array<Scalar,FortranOrder,Tag1,Tag2,Tag3,Tag4,Tag5,void,void,void>
1674  truncate ;
1675 
1676  template< class TagA >
1677  struct append {
1678  typedef
1679  Array<Scalar,FortranOrder,Tag1,Tag2,Tag3,Tag4,Tag5,Tag6,TagA,void>
1680  fortran ;
1681 
1682  typedef
1683  Array<Scalar,NaturalOrder,TagA,Tag6,Tag5,Tag4,Tag3,Tag2,Tag1,void>
1684  natural ;
1685 
1686  typedef fortran type ;
1687  typedef natural reverse ;
1688  };
1689 
1690  enum { Rank = 6 };
1691 
1692  static bool verify( int_t rank , const ArrayDimTag * tags[] )
1693  {
1694  return rank == Rank &&
1695  tags[0] == & Tag1::tag() &&
1696  tags[1] == & Tag2::tag() &&
1697  tags[2] == & Tag3::tag() &&
1698  tags[3] == & Tag4::tag() &&
1699  tags[4] == & Tag5::tag() &&
1700  tags[5] == & Tag6::tag();
1701  }
1702 
1703  static void assign_tags( const ArrayDimTag * tags[] )
1704  {
1705  tags[0] = & Tag1::tag();
1706  tags[1] = & Tag2::tag();
1707  tags[2] = & Tag3::tag();
1708  tags[3] = & Tag4::tag();
1709  tags[4] = & Tag5::tag();
1710  tags[5] = & Tag6::tag();
1711  tags[6] = NULL ;
1712  tags[7] = NULL ;
1713  }
1714 
1715  template< typename iType >
1716  static void assign( iType * stride )
1717  {
1718  stride[7] = 0 ;
1719  stride[6] = 0 ;
1720  stride[5] = Tag6::Size * (
1721  stride[4] = Tag5::Size * (
1722  stride[3] = Tag4::Size * (
1723  stride[2] = Tag3::Size * (
1724  stride[1] = Tag2::Size * (
1725  stride[0] = Tag1::Size )))));
1726  }
1727 
1728  template< typename iType >
1729  static void assign( iType * stride ,
1730  const iType & n6 )
1731  {
1732  stride[7] = 0 ;
1733  stride[6] = 0 ;
1734  stride[5] = n6 * (
1735  stride[4] = Tag5::Size * (
1736  stride[3] = Tag4::Size * (
1737  stride[2] = Tag3::Size * (
1738  stride[1] = Tag2::Size * (
1739  stride[0] = Tag1::Size )))));
1740  }
1741 
1742  template< typename iType >
1743  static void assign( iType * stride ,
1744  const iType & n5 ,
1745  const iType & n6 )
1746  {
1747  stride[7] = 0 ;
1748  stride[6] = 0 ;
1749  stride[5] = n6 * (
1750  stride[4] = n5 * (
1751  stride[3] = Tag4::Size * (
1752  stride[2] = Tag3::Size * (
1753  stride[1] = Tag2::Size * (
1754  stride[0] = Tag1::Size )))));
1755  }
1756 
1757  template< typename iType >
1758  static void assign( iType * stride ,
1759  const iType & n4 ,
1760  const iType & n5 ,
1761  const iType & n6 )
1762  {
1763  stride[7] = 0 ;
1764  stride[6] = 0 ;
1765  stride[5] = n6 * (
1766  stride[4] = n5 * (
1767  stride[3] = n4 * (
1768  stride[2] = Tag3::Size * (
1769  stride[1] = Tag2::Size * (
1770  stride[0] = Tag1::Size )))));
1771  }
1772 
1773  template< typename iType >
1774  static void assign( iType * stride ,
1775  const iType & n3 ,
1776  const iType & n4 ,
1777  const iType & n5 ,
1778  const iType & n6 )
1779  {
1780  stride[7] = 0 ;
1781  stride[6] = 0 ;
1782  stride[5] = n6 * (
1783  stride[4] = n5 * (
1784  stride[3] = n4 * (
1785  stride[2] = n3 * (
1786  stride[1] = Tag2::Size * (
1787  stride[0] = Tag1::Size )))));
1788  }
1789 
1790  template< typename iType >
1791  static void assign( iType * stride ,
1792  const iType & n2 ,
1793  const iType & n3 ,
1794  const iType & n4 ,
1795  const iType & n5 ,
1796  const iType & n6 )
1797  {
1798  stride[7] = 0 ;
1799  stride[6] = 0 ;
1800  stride[5] = n6 * (
1801  stride[4] = n5 * (
1802  stride[3] = n4 * (
1803  stride[2] = n3 * (
1804  stride[1] = n2 * (
1805  stride[0] = Tag1::Size )))));
1806  }
1807 
1808  template< typename iType >
1809  static void assign( iType * stride ,
1810  const iType & n1 ,
1811  const iType & n2 ,
1812  const iType & n3 ,
1813  const iType & n4 ,
1814  const iType & n5 ,
1815  const iType & n6 )
1816  {
1817  stride[7] = 0 ;
1818  stride[6] = 0 ;
1819  stride[5] = n6 * (
1820  stride[4] = n5 * (
1821  stride[3] = n4 * (
1822  stride[2] = n3 * (
1823  stride[1] = n2 * (
1824  stride[0] = n1 )))));
1825  }
1826 
1827  template< typename iType >
1828  static void assign( iType * stride ,
1829  const iType * const dims )
1830  {
1831  stride[7] = 0 ;
1832  stride[6] = 0 ;
1833  stride[5] = dims[5] * (
1834  stride[4] = dims[4] * (
1835  stride[3] = dims[3] * (
1836  stride[2] = dims[2] * (
1837  stride[1] = dims[1] * (
1838  stride[0] = dims[0] )))));
1839  }
1840 };
1841 
1842 //----------------------------------------------------------------------
1845 template< typename Scalar ,
1846  class Tag1 , class Tag2 , class Tag3 , class Tag4 , class Tag5 >
1847 struct Helper<Scalar,NaturalOrder,Tag1,Tag2,Tag3,Tag4,Tag5,void,void,void>
1848 {
1849  typedef
1850  Array<Scalar,FortranOrder,Tag5,Tag4,Tag3,Tag2,Tag1,void,void,void>
1851  reverse ;
1852 
1853  typedef
1854  Array<Scalar,NaturalOrder,Tag2,Tag3,Tag4,Tag5,void,void,void,void>
1855  truncate ;
1856 
1857  template< class TagA >
1858  struct append {
1859  typedef
1860  Array<Scalar,NaturalOrder,TagA,Tag1,Tag2,Tag3,Tag4,Tag5,void,void>
1861  natural ;
1862 
1863  typedef
1864  Array<Scalar,FortranOrder,Tag5,Tag4,Tag3,Tag2,Tag1,TagA,void,void>
1865  fortran ;
1866 
1867  typedef natural type ;
1868  typedef fortran reverse ;
1869  };
1870 
1871  enum { Rank = 5 };
1872 
1873  static bool verify( int_t rank , const ArrayDimTag * tags[] )
1874  {
1875  return rank == Rank &&
1876  tags[0] == & Tag5::tag() &&
1877  tags[1] == & Tag4::tag() &&
1878  tags[2] == & Tag3::tag() &&
1879  tags[3] == & Tag2::tag() &&
1880  tags[4] == & Tag1::tag();
1881  }
1882 
1883  static void assign_tags( const ArrayDimTag * tags[] )
1884  {
1885  tags[0] = & Tag5::tag();
1886  tags[1] = & Tag4::tag();
1887  tags[2] = & Tag3::tag();
1888  tags[3] = & Tag2::tag();
1889  tags[4] = & Tag1::tag();
1890  tags[5] = NULL ;
1891  tags[6] = NULL ;
1892  tags[7] = NULL ;
1893  }
1894 
1895  template< typename iType >
1896  static void assign( iType * stride )
1897  {
1898  stride[7] = 0 ;
1899  stride[6] = 0 ;
1900  stride[5] = 0 ;
1901  stride[4] = Tag1::Size * (
1902  stride[3] = Tag2::Size * (
1903  stride[2] = Tag3::Size * (
1904  stride[1] = Tag4::Size * (
1905  stride[0] = Tag5::Size ))));
1906  }
1907 
1908  template< typename iType >
1909  static void assign( iType * stride ,
1910  const iType & n1 )
1911  {
1912  stride[7] = 0 ;
1913  stride[6] = 0 ;
1914  stride[5] = 0 ;
1915  stride[4] = n1 * (
1916  stride[3] = Tag2::Size * (
1917  stride[2] = Tag3::Size * (
1918  stride[1] = Tag4::Size * (
1919  stride[0] = Tag5::Size ))));
1920  }
1921 
1922  template< typename iType >
1923  static void assign( iType * stride ,
1924  const iType & n1 ,
1925  const iType & n2 )
1926  {
1927  stride[7] = 0 ;
1928  stride[6] = 0 ;
1929  stride[5] = 0 ;
1930  stride[4] = n1 * (
1931  stride[3] = n2 * (
1932  stride[2] = Tag3::Size * (
1933  stride[1] = Tag4::Size * (
1934  stride[0] = Tag5::Size ))));
1935  }
1936 
1937  template< typename iType >
1938  static void assign( iType * stride ,
1939  const iType & n1 ,
1940  const iType & n2 ,
1941  const iType & n3 )
1942  {
1943  stride[7] = 0 ;
1944  stride[6] = 0 ;
1945  stride[5] = 0 ;
1946  stride[4] = n1 * (
1947  stride[3] = n2 * (
1948  stride[2] = n3 * (
1949  stride[1] = Tag4::Size * (
1950  stride[0] = Tag5::Size ))));
1951  }
1952 
1953  template< typename iType >
1954  static void assign( iType * stride ,
1955  const iType & n1 ,
1956  const iType & n2 ,
1957  const iType & n3 ,
1958  const iType & n4 )
1959  {
1960  stride[7] = 0 ;
1961  stride[6] = 0 ;
1962  stride[5] = 0 ;
1963  stride[4] = n1 * (
1964  stride[3] = n2 * (
1965  stride[2] = n3 * (
1966  stride[1] = n4 * (
1967  stride[0] = Tag5::Size ))));
1968  }
1969 
1970  template< typename iType >
1971  static void assign( iType * stride ,
1972  const iType & n1 ,
1973  const iType & n2 ,
1974  const iType & n3 ,
1975  const iType & n4 ,
1976  const iType & n5 )
1977  {
1978  stride[7] = 0 ;
1979  stride[6] = 0 ;
1980  stride[5] = 0 ;
1981  stride[4] = n1 * (
1982  stride[3] = n2 * (
1983  stride[2] = n3 * (
1984  stride[1] = n4 * (
1985  stride[0] = n5 ))));
1986  }
1987 
1988  template< typename iType >
1989  static void assign( iType * stride ,
1990  const iType * const dims )
1991  {
1992  stride[7] = 0 ;
1993  stride[6] = 0 ;
1994  stride[5] = 0 ;
1995  stride[4] = dims[0] * (
1996  stride[3] = dims[1] * (
1997  stride[2] = dims[2] * (
1998  stride[1] = dims[3] * (
1999  stride[0] = dims[4] ))));
2000  }
2001 };
2002 
2003 template< typename Scalar ,
2004  class Tag1 , class Tag2 , class Tag3 , class Tag4 , class Tag5 >
2005 struct Helper<Scalar,FortranOrder,Tag1,Tag2,Tag3,Tag4,Tag5,void,void,void>
2006 {
2007  typedef
2008  Array<Scalar,NaturalOrder,Tag5,Tag4,Tag3,Tag2,Tag1,void,void,void>
2009  reverse ;
2010 
2011  typedef
2012  Array<Scalar,FortranOrder,Tag1,Tag2,Tag3,Tag4,void,void,void,void>
2013  truncate ;
2014 
2015  template< class TagA >
2016  struct append {
2017  typedef
2018  Array<Scalar,FortranOrder,Tag1,Tag2,Tag3,Tag4,Tag5,TagA,void,void>
2019  fortran ;
2020 
2021  typedef
2022  Array<Scalar,NaturalOrder,TagA,Tag5,Tag4,Tag3,Tag2,Tag1,void,void>
2023  natural ;
2024 
2025  typedef fortran type ;
2026  typedef natural reverse ;
2027  };
2028 
2029  enum { Rank = 5 };
2030 
2031  static bool verify( int_t rank , const ArrayDimTag * tags[] )
2032  {
2033  return rank == Rank &&
2034  tags[0] == & Tag1::tag() &&
2035  tags[1] == & Tag2::tag() &&
2036  tags[2] == & Tag3::tag() &&
2037  tags[3] == & Tag4::tag() &&
2038  tags[4] == & Tag5::tag();
2039  }
2040 
2041  static void assign_tags( const ArrayDimTag * tags[] )
2042  {
2043  tags[0] = & Tag1::tag();
2044  tags[1] = & Tag2::tag();
2045  tags[2] = & Tag3::tag();
2046  tags[3] = & Tag4::tag();
2047  tags[4] = & Tag5::tag();
2048  tags[5] = NULL ;
2049  tags[6] = NULL ;
2050  tags[7] = NULL ;
2051  }
2052 
2053  template< typename iType >
2054  static void assign( iType * stride )
2055  {
2056  stride[7] = 0 ;
2057  stride[6] = 0 ;
2058  stride[5] = 0 ;
2059  stride[4] = Tag5::Size * (
2060  stride[3] = Tag4::Size * (
2061  stride[2] = Tag3::Size * (
2062  stride[1] = Tag2::Size * (
2063  stride[0] = Tag1::Size ))));
2064  }
2065 
2066  template< typename iType >
2067  static void assign( iType * stride ,
2068  const iType & n5 )
2069  {
2070  stride[7] = 0 ;
2071  stride[6] = 0 ;
2072  stride[5] = 0 ;
2073  stride[4] = n5 * (
2074  stride[3] = Tag4::Size * (
2075  stride[2] = Tag3::Size * (
2076  stride[1] = Tag2::Size * (
2077  stride[0] = Tag1::Size ))));
2078  }
2079 
2080  template< typename iType >
2081  static void assign( iType * stride ,
2082  const iType & n4 ,
2083  const iType & n5 )
2084  {
2085  stride[7] = 0 ;
2086  stride[6] = 0 ;
2087  stride[5] = 0 ;
2088  stride[4] = n5 * (
2089  stride[3] = n4 * (
2090  stride[2] = Tag3::Size * (
2091  stride[1] = Tag2::Size * (
2092  stride[0] = Tag1::Size ))));
2093  }
2094 
2095  template< typename iType >
2096  static void assign( iType * stride ,
2097  const iType & n3 ,
2098  const iType & n4 ,
2099  const iType & n5 )
2100  {
2101  stride[7] = 0 ;
2102  stride[6] = 0 ;
2103  stride[5] = 0 ;
2104  stride[4] = n5 * (
2105  stride[3] = n4 * (
2106  stride[2] = n3 * (
2107  stride[1] = Tag2::Size * (
2108  stride[0] = Tag1::Size ))));
2109  }
2110 
2111  template< typename iType >
2112  static void assign( iType * stride ,
2113  const iType & n2 ,
2114  const iType & n3 ,
2115  const iType & n4 ,
2116  const iType & n5 )
2117  {
2118  stride[7] = 0 ;
2119  stride[6] = 0 ;
2120  stride[5] = 0 ;
2121  stride[4] = n5 * (
2122  stride[3] = n4 * (
2123  stride[2] = n3 * (
2124  stride[1] = n2 * (
2125  stride[0] = Tag1::Size ))));
2126  }
2127 
2128  template< typename iType >
2129  static void assign( iType * stride ,
2130  const iType & n1 ,
2131  const iType & n2 ,
2132  const iType & n3 ,
2133  const iType & n4 ,
2134  const iType & n5 )
2135  {
2136  stride[7] = 0 ;
2137  stride[6] = 0 ;
2138  stride[5] = 0 ;
2139  stride[4] = n5 * (
2140  stride[3] = n4 * (
2141  stride[2] = n3 * (
2142  stride[1] = n2 * (
2143  stride[0] = n1 ))));
2144  }
2145 
2146  template< typename iType >
2147  static void assign( iType * stride ,
2148  const iType * const dims )
2149  {
2150  stride[7] = 0 ;
2151  stride[6] = 0 ;
2152  stride[5] = 0 ;
2153  stride[4] = dims[4] * (
2154  stride[3] = dims[3] * (
2155  stride[2] = dims[2] * (
2156  stride[1] = dims[1] * (
2157  stride[0] = dims[0] ))));
2158  }
2159 };
2160 
2161 //----------------------------------------------------------------------
2164 template< typename Scalar , class Tag1 , class Tag2 , class Tag3 , class Tag4 >
2165 struct Helper<Scalar,NaturalOrder,Tag1,Tag2,Tag3,Tag4,void,void,void,void>
2166 {
2167  typedef
2168  Array<Scalar,FortranOrder,Tag4,Tag3,Tag2,Tag1,void,void,void,void>
2169  reverse ;
2170 
2171  typedef
2172  Array<Scalar,NaturalOrder,Tag2,Tag3,Tag4,void,void,void,void,void>
2173  truncate ;
2174 
2175  template< class TagA >
2176  struct append {
2177  typedef
2178  Array<Scalar,NaturalOrder,TagA,Tag1,Tag2,Tag3,Tag4,void,void,void>
2179  natural ;
2180 
2181  typedef
2182  Array<Scalar,FortranOrder,Tag4,Tag3,Tag2,Tag1,TagA,void,void,void>
2183  fortran ;
2184 
2185  typedef natural type ;
2186  typedef fortran reverse ;
2187  };
2188 
2189  enum { Rank = 4 };
2190 
2191  static bool verify( int_t rank , const ArrayDimTag * tags[] )
2192  {
2193  return rank == Rank &&
2194  tags[0] == & Tag4::tag() &&
2195  tags[1] == & Tag3::tag() &&
2196  tags[2] == & Tag2::tag() &&
2197  tags[3] == & Tag1::tag();
2198  }
2199 
2200  static void assign_tags( const ArrayDimTag * tags[] )
2201  {
2202  tags[0] = & Tag4::tag();
2203  tags[1] = & Tag3::tag();
2204  tags[2] = & Tag2::tag();
2205  tags[3] = & Tag1::tag();
2206  tags[4] = NULL ;
2207  tags[5] = NULL ;
2208  tags[6] = NULL ;
2209  tags[7] = NULL ;
2210  }
2211 
2212  template< typename iType >
2213  static void assign( iType * stride )
2214  {
2215  stride[7] = 0 ;
2216  stride[6] = 0 ;
2217  stride[5] = 0 ;
2218  stride[4] = 0 ;
2219  stride[3] = Tag1::Size * (
2220  stride[2] = Tag2::Size * (
2221  stride[1] = Tag3::Size * (
2222  stride[0] = Tag4::Size )));
2223  }
2224 
2225  template< typename iType >
2226  static void assign( iType * stride ,
2227  const iType & n1 )
2228  {
2229  stride[7] = 0 ;
2230  stride[6] = 0 ;
2231  stride[5] = 0 ;
2232  stride[4] = 0 ;
2233  stride[3] = n1 * (
2234  stride[2] = Tag2::Size * (
2235  stride[1] = Tag3::Size * (
2236  stride[0] = Tag4::Size )));
2237  }
2238 
2239  template< typename iType >
2240  static void assign( iType * stride ,
2241  const iType & n1 ,
2242  const iType & n2 )
2243  {
2244  stride[7] = 0 ;
2245  stride[6] = 0 ;
2246  stride[5] = 0 ;
2247  stride[4] = 0 ;
2248  stride[3] = n1 * (
2249  stride[2] = n2 * (
2250  stride[1] = Tag3::Size * (
2251  stride[0] = Tag4::Size )));
2252  }
2253 
2254  template< typename iType >
2255  static void assign( iType * stride ,
2256  const iType & n1 ,
2257  const iType & n2 ,
2258  const iType & n3 )
2259  {
2260  stride[7] = 0 ;
2261  stride[6] = 0 ;
2262  stride[5] = 0 ;
2263  stride[4] = 0 ;
2264  stride[3] = n1 * (
2265  stride[2] = n2 * (
2266  stride[1] = n3 * (
2267  stride[0] = Tag4::Size )));
2268  }
2269 
2270  template< typename iType >
2271  static void assign( iType * stride ,
2272  const iType & n1 ,
2273  const iType & n2 ,
2274  const iType & n3 ,
2275  const iType & n4 )
2276  {
2277  stride[7] = 0 ;
2278  stride[6] = 0 ;
2279  stride[5] = 0 ;
2280  stride[4] = 0 ;
2281  stride[3] = n1 * (
2282  stride[2] = n2 * (
2283  stride[1] = n3 * (
2284  stride[0] = n4 )));
2285  }
2286 
2287  template< typename iType >
2288  static void assign( iType * stride ,
2289  const iType * const dims )
2290  {
2291  stride[7] = 0 ;
2292  stride[6] = 0 ;
2293  stride[5] = 0 ;
2294  stride[4] = 0 ;
2295  stride[3] = dims[0] * (
2296  stride[2] = dims[1] * (
2297  stride[1] = dims[2] * (
2298  stride[0] = dims[3] )));
2299  }
2300 };
2301 
2302 template< typename Scalar , class Tag1 , class Tag2 , class Tag3 , class Tag4 >
2303 struct Helper<Scalar,FortranOrder,Tag1,Tag2,Tag3,Tag4,void,void,void,void>
2304 {
2305  typedef
2306  Array<Scalar,NaturalOrder,Tag4,Tag3,Tag2,Tag1,void,void,void,void>
2307  reverse ;
2308 
2309  typedef
2310  Array<Scalar,FortranOrder,Tag1,Tag2,Tag3,void,void,void,void,void>
2311  truncate ;
2312 
2313  template< class TagA >
2314  struct append {
2315  typedef
2316  Array<Scalar,FortranOrder,Tag1,Tag2,Tag3,Tag4,TagA,void,void,void>
2317  fortran ;
2318 
2319  typedef
2320  Array<Scalar,NaturalOrder,TagA,Tag4,Tag3,Tag2,Tag1,void,void,void>
2321  natural ;
2322 
2323  typedef fortran type ;
2324  typedef natural reverse ;
2325  };
2326 
2327  enum { Rank = 4 };
2328 
2329  static bool verify( int_t rank , const ArrayDimTag * tags[] )
2330  {
2331  return rank == Rank &&
2332  tags[0] == & Tag1::tag() &&
2333  tags[1] == & Tag2::tag() &&
2334  tags[2] == & Tag3::tag() &&
2335  tags[3] == & Tag4::tag();
2336  }
2337 
2338  static void assign_tags( const ArrayDimTag * tags[] )
2339  {
2340  tags[0] = & Tag1::tag();
2341  tags[1] = & Tag2::tag();
2342  tags[2] = & Tag3::tag();
2343  tags[3] = & Tag4::tag();
2344  tags[4] = NULL ;
2345  tags[5] = NULL ;
2346  tags[6] = NULL ;
2347  tags[7] = NULL ;
2348  }
2349 
2350  template< typename iType >
2351  static void assign( iType * stride )
2352  {
2353  stride[7] = 0 ;
2354  stride[6] = 0 ;
2355  stride[5] = 0 ;
2356  stride[4] = 0 ;
2357  stride[3] = Tag4::Size * (
2358  stride[2] = Tag3::Size * (
2359  stride[1] = Tag2::Size * (
2360  stride[0] = Tag1::Size )));
2361  }
2362 
2363  template< typename iType >
2364  static void assign( iType * stride ,
2365  const iType & n4 )
2366  {
2367  stride[7] = 0 ;
2368  stride[6] = 0 ;
2369  stride[5] = 0 ;
2370  stride[4] = 0 ;
2371  stride[3] = n4 * (
2372  stride[2] = Tag3::Size * (
2373  stride[1] = Tag2::Size * (
2374  stride[0] = Tag1::Size )));
2375  }
2376 
2377  template< typename iType >
2378  static void assign( iType * stride ,
2379  const iType & n3 ,
2380  const iType & n4 )
2381  {
2382  stride[7] = 0 ;
2383  stride[6] = 0 ;
2384  stride[5] = 0 ;
2385  stride[4] = 0 ;
2386  stride[3] = n4 * (
2387  stride[2] = n3 * (
2388  stride[1] = Tag2::Size * (
2389  stride[0] = Tag1::Size )));
2390  }
2391 
2392  template< typename iType >
2393  static void assign( iType * stride ,
2394  const iType & n2 ,
2395  const iType & n3 ,
2396  const iType & n4 )
2397  {
2398  stride[7] = 0 ;
2399  stride[6] = 0 ;
2400  stride[5] = 0 ;
2401  stride[4] = 0 ;
2402  stride[3] = n4 * (
2403  stride[2] = n3 * (
2404  stride[1] = n2 * (
2405  stride[0] = Tag1::Size )));
2406  }
2407 
2408  template< typename iType >
2409  static void assign( iType * stride ,
2410  const iType & n1 ,
2411  const iType & n2 ,
2412  const iType & n3 ,
2413  const iType & n4 )
2414  {
2415  stride[7] = 0 ;
2416  stride[6] = 0 ;
2417  stride[5] = 0 ;
2418  stride[4] = 0 ;
2419  stride[3] = n4 * (
2420  stride[2] = n3 * (
2421  stride[1] = n2 * (
2422  stride[0] = n1 )));
2423  }
2424 
2425  template< typename iType >
2426  static void assign( iType * stride ,
2427  const iType * const dims )
2428  {
2429  stride[7] = 0 ;
2430  stride[6] = 0 ;
2431  stride[5] = 0 ;
2432  stride[4] = 0 ;
2433  stride[3] = dims[3] * (
2434  stride[2] = dims[2] * (
2435  stride[1] = dims[1] * (
2436  stride[0] = dims[0] )));
2437  }
2438 };
2439 
2440 //----------------------------------------------------------------------
2443 template< typename Scalar , class Tag1 , class Tag2 , class Tag3 >
2444 struct Helper<Scalar,NaturalOrder,Tag1,Tag2,Tag3,void,void,void,void,void>
2445 {
2446  typedef
2447  Array<Scalar,FortranOrder,Tag3,Tag2,Tag1,void,void,void,void,void>
2448  reverse ;
2449 
2450  typedef
2451  Array<Scalar,NaturalOrder,Tag2,Tag3,void,void,void,void,void,void>
2452  truncate ;
2453 
2454  template< class TagA >
2455  struct append {
2456  typedef
2457  Array<Scalar,NaturalOrder,TagA,Tag1,Tag2,Tag3,void,void,void,void>
2458  natural ;
2459 
2460  typedef
2461  Array<Scalar,FortranOrder,Tag3,Tag2,Tag1,TagA,void,void,void,void>
2462  fortran ;
2463 
2464  typedef natural type ;
2465  typedef fortran reverse ;
2466  };
2467 
2468  enum { Rank = 3 };
2469 
2470  static bool verify( int_t rank , const ArrayDimTag * tags[] )
2471  {
2472  return rank == Rank &&
2473  tags[0] == & Tag3::tag() &&
2474  tags[1] == & Tag2::tag() &&
2475  tags[2] == & Tag1::tag();
2476  }
2477 
2478  static void assign_tags( const ArrayDimTag * tags[] )
2479  {
2480  tags[0] = & Tag3::tag();
2481  tags[1] = & Tag2::tag();
2482  tags[2] = & Tag1::tag();
2483  tags[3] = NULL ;
2484  tags[4] = NULL ;
2485  tags[5] = NULL ;
2486  tags[6] = NULL ;
2487  tags[7] = NULL ;
2488  }
2489 
2490  template< typename iType >
2491  static void assign( iType * stride )
2492  {
2493  stride[7] = 0 ;
2494  stride[6] = 0 ;
2495  stride[5] = 0 ;
2496  stride[4] = 0 ;
2497  stride[3] = 0 ;
2498  stride[2] = Tag1::Size * (
2499  stride[1] = Tag2::Size * (
2500  stride[0] = Tag3::Size ));
2501  }
2502 
2503  template< typename iType >
2504  static void assign( iType * stride ,
2505  const iType & n1 )
2506  {
2507  stride[7] = 0 ;
2508  stride[6] = 0 ;
2509  stride[5] = 0 ;
2510  stride[4] = 0 ;
2511  stride[3] = 0 ;
2512  stride[2] = n1 * (
2513  stride[1] = Tag2::Size * (
2514  stride[0] = Tag3::Size ));
2515  }
2516 
2517  template< typename iType >
2518  static void assign( iType * stride ,
2519  const iType & n1 ,
2520  const iType & n2 )
2521  {
2522  stride[7] = 0 ;
2523  stride[6] = 0 ;
2524  stride[5] = 0 ;
2525  stride[4] = 0 ;
2526  stride[3] = 0 ;
2527  stride[2] = n1 * (
2528  stride[1] = n2 * (
2529  stride[0] = Tag3::Size ));
2530  }
2531 
2532  template< typename iType >
2533  static void assign( iType * stride ,
2534  const iType & n1 ,
2535  const iType & n2 ,
2536  const iType & n3 )
2537  {
2538  stride[7] = 0 ;
2539  stride[6] = 0 ;
2540  stride[5] = 0 ;
2541  stride[4] = 0 ;
2542  stride[3] = 0 ;
2543  stride[2] = n1 * (
2544  stride[1] = n2 * (
2545  stride[0] = n3 ));
2546  }
2547 
2548  template< typename iType >
2549  static void assign( iType * stride ,
2550  const iType * const dims )
2551  {
2552  stride[7] = 0 ;
2553  stride[6] = 0 ;
2554  stride[5] = 0 ;
2555  stride[4] = 0 ;
2556  stride[3] = 0 ;
2557  stride[2] = dims[0] * (
2558  stride[1] = dims[1] * (
2559  stride[0] = dims[2] ));
2560  }
2561 };
2562 
2563 template< typename Scalar , class Tag1 , class Tag2 , class Tag3 >
2564 struct Helper<Scalar,FortranOrder,Tag1,Tag2,Tag3,void,void,void,void,void>
2565 {
2566  typedef
2567  Array<Scalar,NaturalOrder,Tag3,Tag2,Tag1,void,void,void,void,void>
2568  reverse ;
2569 
2570  typedef
2571  Array<Scalar,FortranOrder,Tag1,Tag2,void,void,void,void,void,void>
2572  truncate ;
2573 
2574  template< class TagA >
2575  struct append {
2576  typedef
2577  Array<Scalar,FortranOrder,Tag1,Tag2,Tag3,TagA,void,void,void,void>
2578  fortran ;
2579 
2580  typedef
2581  Array<Scalar,NaturalOrder,TagA,Tag3,Tag2,Tag1,void,void,void,void>
2582  natural ;
2583 
2584  typedef fortran type ;
2585  typedef natural reverse ;
2586  };
2587 
2588  enum { Rank = 3 };
2589 
2590  static bool verify( int_t rank , const ArrayDimTag * tags[] )
2591  {
2592  return rank == Rank &&
2593  tags[0] == & Tag1::tag() &&
2594  tags[1] == & Tag2::tag() &&
2595  tags[2] == & Tag3::tag();
2596  }
2597 
2598  static void assign_tags( const ArrayDimTag * tags[] )
2599  {
2600  tags[0] = & Tag1::tag();
2601  tags[1] = & Tag2::tag();
2602  tags[2] = & Tag3::tag();
2603  tags[3] = NULL ;
2604  tags[4] = NULL ;
2605  tags[5] = NULL ;
2606  tags[6] = NULL ;
2607  tags[7] = NULL ;
2608  }
2609 
2610  template< typename iType >
2611  static void assign( iType * stride )
2612  {
2613  stride[7] = 0 ;
2614  stride[6] = 0 ;
2615  stride[5] = 0 ;
2616  stride[4] = 0 ;
2617  stride[3] = 0 ;
2618  stride[2] = Tag3::Size * (
2619  stride[1] = Tag2::Size * (
2620  stride[0] = Tag1::Size ));
2621  }
2622 
2623  template< typename iType >
2624  static void assign( iType * stride ,
2625  const iType & n3 )
2626  {
2627  stride[7] = 0 ;
2628  stride[6] = 0 ;
2629  stride[5] = 0 ;
2630  stride[4] = 0 ;
2631  stride[3] = 0 ;
2632  stride[2] = n3 * (
2633  stride[1] = Tag2::Size * (
2634  stride[0] = Tag1::Size ));
2635  }
2636 
2637  template< typename iType >
2638  static void assign( iType * stride ,
2639  const iType & n2 ,
2640  const iType & n3 )
2641  {
2642  stride[7] = 0 ;
2643  stride[6] = 0 ;
2644  stride[5] = 0 ;
2645  stride[4] = 0 ;
2646  stride[3] = 0 ;
2647  stride[2] = n3 * (
2648  stride[1] = n2 * (
2649  stride[0] = Tag1::Size ));
2650  }
2651 
2652  template< typename iType >
2653  static void assign( iType * stride ,
2654  const iType & n1 ,
2655  const iType & n2 ,
2656  const iType & n3 )
2657  {
2658  stride[7] = 0 ;
2659  stride[6] = 0 ;
2660  stride[5] = 0 ;
2661  stride[4] = 0 ;
2662  stride[3] = 0 ;
2663  stride[2] = n3 * (
2664  stride[1] = n2 * (
2665  stride[0] = n1 ));
2666  }
2667 
2668  template< typename iType >
2669  static void assign( iType * stride ,
2670  const iType * const dims )
2671  {
2672  stride[7] = 0 ;
2673  stride[6] = 0 ;
2674  stride[5] = 0 ;
2675  stride[4] = 0 ;
2676  stride[3] = 0 ;
2677  stride[2] = dims[2] * (
2678  stride[1] = dims[1] * (
2679  stride[0] = dims[0] ));
2680  }
2681 };
2682 
2683 //----------------------------------------------------------------------
2686 template< typename Scalar , class Tag1 , class Tag2 >
2687 struct Helper<Scalar,NaturalOrder,Tag1,Tag2,void,void,void,void,void,void>
2688 {
2689  typedef
2690  Array<Scalar,FortranOrder,Tag2,Tag1,void,void,void,void,void,void>
2691  reverse ;
2692 
2693  typedef
2694  Array<Scalar,NaturalOrder,Tag2,void,void,void,void,void,void,void>
2695  truncate ;
2696 
2697  template< class TagA >
2698  struct append {
2699  typedef
2700  Array<Scalar,NaturalOrder,TagA,Tag1,Tag2,void,void,void,void,void>
2701  natural ;
2702 
2703  typedef
2704  Array<Scalar,FortranOrder,Tag2,Tag1,TagA,void,void,void,void,void>
2705  fortran ;
2706 
2707  typedef natural type ;
2708  typedef fortran reverse ;
2709  };
2710 
2711  enum { Rank = 2 };
2712 
2713  static bool verify( int_t rank , const ArrayDimTag * tags[] )
2714  {
2715  return rank == Rank &&
2716  tags[0] == & Tag2::tag() &&
2717  tags[1] == & Tag1::tag();
2718  }
2719 
2720  static void assign_tags( const ArrayDimTag * tags[] )
2721  {
2722  tags[0] = & Tag2::tag();
2723  tags[1] = & Tag1::tag();
2724  tags[2] = NULL ;
2725  tags[3] = NULL ;
2726  tags[4] = NULL ;
2727  tags[5] = NULL ;
2728  tags[6] = NULL ;
2729  tags[7] = NULL ;
2730  }
2731 
2732  template< typename iType >
2733  static void assign( iType * stride )
2734  {
2735  stride[7] = 0 ;
2736  stride[6] = 0 ;
2737  stride[5] = 0 ;
2738  stride[4] = 0 ;
2739  stride[3] = 0 ;
2740  stride[2] = 0 ;
2741  stride[1] = Tag1::Size * (
2742  stride[0] = Tag2::Size );
2743  }
2744 
2745  template< typename iType >
2746  static void assign( iType * stride ,
2747  const iType & n1 )
2748  {
2749  stride[7] = 0 ;
2750  stride[6] = 0 ;
2751  stride[5] = 0 ;
2752  stride[4] = 0 ;
2753  stride[3] = 0 ;
2754  stride[2] = 0 ;
2755  stride[1] = n1 * (
2756  stride[0] = Tag2::Size );
2757  }
2758 
2759  template< typename iType >
2760  static void assign( iType * stride ,
2761  const iType & n1 ,
2762  const iType & n2 )
2763  {
2764  stride[7] = 0 ;
2765  stride[6] = 0 ;
2766  stride[5] = 0 ;
2767  stride[4] = 0 ;
2768  stride[3] = 0 ;
2769  stride[2] = 0 ;
2770  stride[1] = n1 * (
2771  stride[0] = n2 );
2772  }
2773 
2774  template< typename iType >
2775  static void assign( iType * stride ,
2776  const iType * const dims )
2777  {
2778  stride[7] = 0 ;
2779  stride[6] = 0 ;
2780  stride[5] = 0 ;
2781  stride[4] = 0 ;
2782  stride[3] = 0 ;
2783  stride[2] = 0 ;
2784  stride[1] = dims[0] * (
2785  stride[0] = dims[1] );
2786  }
2787 };
2788 
2789 template< typename Scalar , class Tag1 , class Tag2 >
2790 struct Helper<Scalar,FortranOrder,Tag1,Tag2,void,void,void,void,void,void>
2791 {
2792  typedef
2793  Array<Scalar,NaturalOrder,Tag2,Tag1,void,void,void,void,void,void>
2794  reverse ;
2795 
2796  typedef
2797  Array<Scalar,FortranOrder,Tag1,void,void,void,void,void,void,void>
2798  truncate ;
2799 
2800  template< class TagA >
2801  struct append {
2802  typedef
2803  Array<Scalar,FortranOrder,Tag1,Tag2,TagA,void,void,void,void,void>
2804  fortran ;
2805 
2806  typedef
2807  Array<Scalar,NaturalOrder,TagA,Tag2,Tag1,void,void,void,void,void>
2808  natural ;
2809 
2810  typedef fortran type ;
2811  typedef natural reverse ;
2812  };
2813 
2814  enum { Rank = 2 };
2815 
2816  static bool verify( int_t rank , const ArrayDimTag * tags[] )
2817  {
2818  return rank == Rank &&
2819  tags[0] = & Tag1::tag() &&
2820  tags[1] = & Tag2::tag();
2821  }
2822 
2823  static void assign_tags( const ArrayDimTag * tags[] )
2824  {
2825  tags[0] = & Tag1::tag();
2826  tags[1] = & Tag2::tag();
2827  tags[2] = NULL ;
2828  tags[3] = NULL ;
2829  tags[4] = NULL ;
2830  tags[5] = NULL ;
2831  tags[6] = NULL ;
2832  tags[7] = NULL ;
2833  }
2834 
2835  template< typename iType >
2836  static void assign( iType * stride )
2837  {
2838  stride[7] = 0 ;
2839  stride[6] = 0 ;
2840  stride[5] = 0 ;
2841  stride[4] = 0 ;
2842  stride[3] = 0 ;
2843  stride[2] = 0 ;
2844  stride[1] = Tag2::Size * (
2845  stride[0] = Tag1::Size );
2846  }
2847 
2848  template< typename iType >
2849  static void assign( iType * stride ,
2850  const iType & n2 )
2851  {
2852  stride[7] = 0 ;
2853  stride[6] = 0 ;
2854  stride[5] = 0 ;
2855  stride[4] = 0 ;
2856  stride[3] = 0 ;
2857  stride[2] = 0 ;
2858  stride[1] = n2 * (
2859  stride[0] = Tag1::Size );
2860  }
2861 
2862  template< typename iType >
2863  static void assign( iType * stride ,
2864  const iType & n1 ,
2865  const iType & n2 )
2866  {
2867  stride[7] = 0 ;
2868  stride[6] = 0 ;
2869  stride[5] = 0 ;
2870  stride[4] = 0 ;
2871  stride[3] = 0 ;
2872  stride[2] = 0 ;
2873  stride[1] = n2 * (
2874  stride[0] = n1 );
2875  }
2876 
2877  template< typename iType >
2878  static void assign( iType * stride ,
2879  const iType * const dims )
2880  {
2881  stride[7] = 0 ;
2882  stride[6] = 0 ;
2883  stride[5] = 0 ;
2884  stride[4] = 0 ;
2885  stride[3] = 0 ;
2886  stride[2] = 0 ;
2887  stride[1] = dims[1] * (
2888  stride[0] = dims[0] );
2889  }
2890 };
2891 
2892 //----------------------------------------------------------------------
2895 template< typename Scalar , class Tag1 >
2896 struct Helper<Scalar,NaturalOrder,Tag1,void,void,void,void,void,void,void>
2897 {
2898  typedef
2899  Array<Scalar,FortranOrder,Tag1,void,void,void,void,void,void,void>
2900  reverse ;
2901 
2902  typedef
2903  Array<Scalar,RankZero,void,void,void,void,void,void,void,void>
2904  truncate ;
2905 
2906  template< class TagA >
2907  struct append {
2908  typedef
2909  Array<Scalar,NaturalOrder,TagA,Tag1,void,void,void,void,void,void>
2910  natural ;
2911 
2912  typedef
2913  Array<Scalar,FortranOrder,Tag1,TagA,void,void,void,void,void,void>
2914  fortran ;
2915 
2916  typedef natural type ;
2917  typedef fortran reverse ;
2918  };
2919 
2920  enum { Rank = 1 };
2921 
2922  static bool verify( int_t rank , const ArrayDimTag * tags[] )
2923  { return rank == Rank && tags[0] == & Tag1::tag(); }
2924 
2925  static void assign_tags( const ArrayDimTag * tags[] )
2926  {
2927  tags[0] = & Tag1::tag();
2928  tags[1] = NULL ;
2929  tags[2] = NULL ;
2930  tags[3] = NULL ;
2931  tags[4] = NULL ;
2932  tags[5] = NULL ;
2933  tags[6] = NULL ;
2934  tags[7] = NULL ;
2935  }
2936 
2937  template< typename iType >
2938  static void assign( iType * stride )
2939  {
2940  stride[7] = 0 ;
2941  stride[6] = 0 ;
2942  stride[5] = 0 ;
2943  stride[4] = 0 ;
2944  stride[3] = 0 ;
2945  stride[2] = 0 ;
2946  stride[1] = 0 ;
2947  stride[0] = Tag1::Size ;
2948  }
2949 
2950  template< typename iType >
2951  static void assign( iType * stride ,
2952  const iType & n1 )
2953  {
2954  stride[7] = 0 ;
2955  stride[6] = 0 ;
2956  stride[5] = 0 ;
2957  stride[4] = 0 ;
2958  stride[3] = 0 ;
2959  stride[2] = 0 ;
2960  stride[1] = 0 ;
2961  stride[0] = n1 ;
2962  }
2963 
2964  template< typename iType >
2965  static void assign( iType * stride ,
2966  const iType * const dims )
2967  {
2968  stride[7] = 0 ;
2969  stride[6] = 0 ;
2970  stride[5] = 0 ;
2971  stride[4] = 0 ;
2972  stride[3] = 0 ;
2973  stride[2] = 0 ;
2974  stride[1] = 0 ;
2975  stride[0] = dims[0] ;
2976  }
2977 };
2978 
2979 template< typename Scalar , class Tag1 >
2980 struct Helper<Scalar,FortranOrder,Tag1,void,void,void,void,void,void,void>
2981 {
2982  typedef
2983  Array<Scalar,NaturalOrder,Tag1,void,void,void,void,void,void,void>
2984  reverse ;
2985 
2986  typedef
2987  Array<Scalar,RankZero,void,void,void,void,void,void,void,void>
2988  truncate ;
2989 
2990  template< class TagA >
2991  struct append {
2992  typedef
2993  Array<Scalar,FortranOrder,Tag1,TagA,void,void,void,void,void,void>
2994  fortran ;
2995 
2996  typedef
2997  Array<Scalar,NaturalOrder,TagA,Tag1,void,void,void,void,void,void>
2998  natural ;
2999 
3000  typedef fortran type ;
3001  typedef natural reverse ;
3002  };
3003 
3004  enum { Rank = 1 };
3005 
3006  static bool verify( int_t rank , const ArrayDimTag * tags[] )
3007  { return rank == Rank && tags[0] == & Tag1::tag(); }
3008 
3009  static void assign_tags( const ArrayDimTag * tags[] )
3010  {
3011  tags[0] = & Tag1::tag();
3012  tags[1] = NULL ;
3013  tags[2] = NULL ;
3014  tags[3] = NULL ;
3015  tags[4] = NULL ;
3016  tags[5] = NULL ;
3017  tags[6] = NULL ;
3018  tags[7] = NULL ;
3019  }
3020 
3021  template< typename iType >
3022  static void assign( iType * stride )
3023  {
3024  stride[7] = 0 ;
3025  stride[6] = 0 ;
3026  stride[5] = 0 ;
3027  stride[4] = 0 ;
3028  stride[3] = 0 ;
3029  stride[2] = 0 ;
3030  stride[1] = 0 ;
3031  stride[0] = Tag1::Size ;
3032  }
3033 
3034  template< typename iType >
3035  static void assign( iType * stride , const iType & n1 )
3036  {
3037  stride[7] = 0 ;
3038  stride[6] = 0 ;
3039  stride[5] = 0 ;
3040  stride[4] = 0 ;
3041  stride[3] = 0 ;
3042  stride[2] = 0 ;
3043  stride[1] = 0 ;
3044  stride[0] = n1 ;
3045  }
3046 
3047  template< typename iType >
3048  static void assign( iType * stride , const iType * const dims )
3049  {
3050  stride[7] = 0 ;
3051  stride[6] = 0 ;
3052  stride[5] = 0 ;
3053  stride[4] = 0 ;
3054  stride[3] = 0 ;
3055  stride[2] = 0 ;
3056  stride[0] = dims[0] ;
3057  }
3058 };
3059 
3060 //----------------------------------------------------------------------
3063 template< typename Scalar >
3064 struct Helper<Scalar,RankZero,void,void,void,void,void,void,void,void>
3065 {
3066  typedef
3067  Array<Scalar,RankZero,void,void,void,void,void,void,void,void>
3068  reverse ;
3069 
3070  template< class TagA >
3071  struct append {
3072  typedef
3073  Array<Scalar,NaturalOrder,TagA,void,void,void,void,void,void,void>
3074  natural ;
3075 
3076  typedef
3077  Array<Scalar,FortranOrder,TagA,void,void,void,void,void,void,void>
3078  fortran ;
3079 
3080  typedef natural type ;
3081  typedef fortran reverse ;
3082  };
3083 
3084  enum { Rank = 0 };
3085 
3086  template< typename iType >
3087  static void assign( iType * ) {}
3088 };
3089 
3090 //----------------------------------------------------------------------
3093 template< typename Scalar >
3094 struct Helper<Scalar,NaturalOrder,void,void,void,void,void,void,void,void>
3095 {
3096  typedef
3097  Array<Scalar,FortranOrder,void,void,void,void,void,void,void,void>
3098  reverse ;
3099 };
3100 
3101 template< typename Scalar >
3102 struct Helper<Scalar,FortranOrder,void,void,void,void,void,void,void,void>
3103 {
3104  typedef
3105  Array<Scalar,NaturalOrder,void,void,void,void,void,void,void,void>
3106  reverse ;
3107 };
3108 
3109 //----------------------------------------------------------------------
3110 
3111 } // namespace array_traits
3112 
3113 template< class ArrayType , class TagA > struct ArrayAppend {};
3114 
3115 template< typename Scalar , ArrayOrder Order ,
3116  class Tag1 , class Tag2 , class Tag3 , class Tag4 ,
3117  class Tag5 , class Tag6 , class Tag7 , class TagA >
3118 struct ArrayAppend<
3119  Array<Scalar,Order,Tag1,Tag2,Tag3,Tag4,Tag5,Tag6,Tag7,void> , TagA >
3120 {
3121 private:
3122  typedef typename
3123  array_traits::Helper<Scalar,Order,Tag1,Tag2,Tag3,Tag4,Tag5,Tag6,Tag7,void>
3124  ::template append<TagA> helper ;
3125 public:
3126  typedef typename helper::type type ;
3127  typedef typename helper::natural natural ;
3128  typedef typename helper::fortran fortran ;
3129 };
3130 
3131 } // namespace shards
3132 
3133 #endif /* DOXYGEN_COMPILE */
3134 
3135 //----------------------------------------------------------------------
3136 //----------------------------------------------------------------------
3137 
3138 namespace shards {
3139 
3144 //----------------------------------------------------------------------
3157 template< typename Scalar , ArrayOrder array_order >
3158 class Array<Scalar,array_order,void,void,void,void,void,void,void,void>
3159 {
3160 private:
3161  typedef typename array_traits::Offset<array_order> Offset ;
3162 public:
3168  typedef Scalar value_type ;
3169 
3171  typedef array_traits::int_t size_type ;
3172 
3174  typedef const ArrayDimTag * tag_type ;
3175 
3176  //----------------------------------
3177 
3179  enum { Natural = NaturalOrder == array_order };
3180 
3182  enum { Reverse = FortranOrder == array_order };
3183 
3185  enum { Contiguous = true };
3186 
3188  size_type rank() const { return m_rank ; }
3189 
3191  bool natural() const { return Natural ; }
3192 
3194  bool reverse() const { return Reverse ; }
3195 
3197  bool contiguous() const { return Contiguous ; }
3198 
3199  //----------------------------------
3200 
3202  tag_type tag( size_type ord ) const
3203  {
3204  array_traits::check_range( ord , m_rank );
3205  if ( Natural ) { ord = ( m_rank - 1 ) - ord ; }
3206  return m_tag[ord];
3207  }
3208 
3209  //----------------------------------
3210 
3213  {
3214  array_traits::check_range( ord , m_rank );
3215  if ( Natural ) { ord = ( m_rank - 1 ) - ord ; }
3216  return ord ? m_stride[ord] / m_stride[ord-1] : m_stride[ord] ;
3217  }
3218 
3220  template< typename iType >
3221  void dimensions( std::vector<iType> & n )
3222  {
3223  n.resize( m_rank );
3224  for ( size_type i = 0 ; i < m_rank ; ++i ) { n[i] = dimension(i); }
3225  }
3226 
3228  size_type size() const { return m_stride[ m_rank - 1 ]; }
3229 
3231  //----------------------------------
3239  template< typename iType >
3240  Array truncate( const iType & i ) const
3241  { return Array( *this , i ); }
3242 
3244  value_type * contiguous_data() const { return m_ptr ; }
3245 
3247  template< typename iType >
3248  value_type & operator[]( const iType & i ) const
3249  {
3250  SHARDS_ARRAY_CHECK( array_traits::check_range(i,size()) );
3251  return m_ptr[ i ];
3252  }
3253 
3254  //----------------------------------
3256  template< typename iType >
3257  value_type & operator()( const iType & i1 , const iType & i2 ,
3258  const iType & i3 , const iType & i4 ,
3259  const iType & i5 , const iType & i6 ,
3260  const iType & i7 , const iType & i8 ) const
3261  {
3262  SHARDS_ARRAY_CHECK( array_traits::check_rank( m_rank , 8 ) );
3263  return m_ptr[ Offset::op(m_stride,i1,i2,i3,i4,i5,i6,i7,i8) ];
3264  }
3265 
3266  template< typename iType >
3267  value_type & operator()( const iType & i1 , const iType & i2 ,
3268  const iType & i3 , const iType & i4 ,
3269  const iType & i5 , const iType & i6 ,
3270  const iType & i7 ) const
3271  {
3272  SHARDS_ARRAY_CHECK( array_traits::check_rank( m_rank , 7 ) );
3273  return m_ptr[ Offset::op(m_stride,i1,i2,i3,i4,i5,i6,i7) ];
3274  }
3275 
3276  template< typename iType >
3277  value_type & operator()( const iType & i1 , const iType & i2 ,
3278  const iType & i3 , const iType & i4 ,
3279  const iType & i5 , const iType & i6 ) const
3280  {
3281  SHARDS_ARRAY_CHECK( array_traits::check_rank( m_rank , 6 ) );
3282  return m_ptr[ Offset::op(m_stride,i1,i2,i3,i4,i5,i6) ];
3283  }
3284 
3285  template< typename iType >
3286  value_type & operator()( const iType & i1 , const iType & i2 ,
3287  const iType & i3 , const iType & i4 ,
3288  const iType & i5 ) const
3289  {
3290  SHARDS_ARRAY_CHECK( array_traits::check_rank( m_rank , 5 ) );
3291  return m_ptr[ Offset::op(m_stride,i1,i2,i3,i4,i5) ];
3292  }
3293 
3294  template< typename iType >
3295  value_type & operator()( const iType & i1 , const iType & i2 ,
3296  const iType & i3 , const iType & i4 ) const
3297  {
3298  SHARDS_ARRAY_CHECK( array_traits::check_rank( m_rank , 4 ) );
3299  return m_ptr[ Offset::op(m_stride,i1,i2,i3,i4) ];
3300  }
3301 
3302  template< typename iType >
3303  value_type & operator()( const iType & i1 , const iType & i2 ,
3304  const iType & i3 ) const
3305  {
3306  SHARDS_ARRAY_CHECK( array_traits::check_rank( m_rank , 3 ) );
3307  return m_ptr[ Offset::op(m_stride,i1,i2,i3) ];
3308  }
3309 
3310  template< typename iType >
3311  value_type & operator()( const iType & i1 , const iType & i2 ) const
3312  {
3313  SHARDS_ARRAY_CHECK( array_traits::check_rank( m_rank , 2 ) );
3314  return m_ptr[ Offset::op(m_stride,i1,i2) ];
3315  }
3316 
3317  template< typename iType >
3318  value_type & operator()( const iType & i1 ) const
3319  {
3320  SHARDS_ARRAY_CHECK( array_traits::check_rank( m_rank , 1 ) );
3321  return m_ptr[ Offset::op(m_stride,i1) ];
3322  }
3323 
3325  //----------------------------------
3330  typedef typename
3331  array_traits::Helper<Scalar,array_order,void,void,void,void,void,void,void,void>
3332  ::reverse ReverseType ;
3333 
3334  //----------------------------------
3335 
3336  Array()
3337  : m_ptr(NULL), m_rank(0)
3338  {
3339  Copy<8>( m_stride , (size_type) 0 );
3340  Copy<8>( m_tag , (tag_type) NULL );
3341  }
3342 
3343  Array( const Array & rhs )
3344  : m_ptr( rhs.m_ptr ), m_rank( rhs.m_rank )
3345  {
3346  Copy<8>( m_stride , rhs.m_stride );
3347  Copy<8>( m_tag , rhs.m_tag );
3348  }
3349 
3350  Array & operator = ( const Array & rhs )
3351  {
3352  m_ptr = rhs.m_ptr ;
3353  m_rank = rhs.m_rank ;
3354  Copy<8>( m_stride , rhs.m_stride );
3355  Copy<8>( m_tag , rhs.m_tag );
3356  return *this ;
3357  }
3358 
3360  Array( const ReverseType & rhs )
3361  : m_ptr( rhs.m_ptr ), m_rank( rhs.m_rank )
3362  {
3363  Copy<8>( m_stride , rhs.m_stride );
3364  Copy<8>( m_tag , rhs.m_tag );
3365  }
3366 
3368  Array & operator = ( const ReverseType & rhs )
3369  {
3370  m_ptr = rhs.m_ptr ;
3371  m_rank = rhs.m_rank ;
3372  Copy<8>( m_stride , rhs.m_stride );
3373  Copy<8>( m_tag , rhs.m_tag );
3374  return *this ;
3375  }
3376 
3377  //----------------------------------
3378  // Class specific constructors:
3379 
3380  Array( value_type * ptr ,
3381  const size_type input_rank ,
3382  const size_type * const dims ,
3383  const tag_type * const tags )
3384  : m_ptr( ptr ), m_rank( input_rank )
3385  {
3386  array_traits::init_dim( m_stride, dims, input_rank, Natural);
3387  array_traits::init_tags( m_tag, tags, input_rank, Natural);
3388  }
3389 
3392  template< class Tag1 , class Tag2 , class Tag3 , class Tag4 ,
3393  class Tag5 , class Tag6 , class Tag7 , class Tag8 >
3394  Array & assign( value_type * ptr ,
3395  size_type n1 , size_type n2 , size_type n3 , size_type n4 ,
3396  size_type n5 , size_type n6 , size_type n7 , size_type n8 )
3397  {
3398  typedef
3399  array_traits::Helper<Scalar,array_order,
3400  Tag1,Tag2,Tag3,Tag4,Tag5,Tag6,Tag7,Tag8>
3401  helper ;
3402  m_ptr = ptr ;
3403  m_rank = helper::Rank ;
3404  helper::assign_tags( m_tag );
3405  helper::assign( m_stride, n1, n2, n3, n4, n5, n6, n7, n8 );
3406  return *this ;
3407  }
3408 
3409  template< class Tag1 , class Tag2 , class Tag3 , class Tag4 ,
3410  class Tag5 , class Tag6 , class Tag7 >
3411  Array & assign( value_type * ptr ,
3412  size_type n1 , size_type n2 , size_type n3 , size_type n4 ,
3413  size_type n5 , size_type n6 , size_type n7 )
3414  {
3415  typedef
3416  array_traits::Helper<Scalar,array_order,
3417  Tag1,Tag2,Tag3,Tag4,Tag5,Tag6,Tag7,void>
3418  helper ;
3419  m_ptr = ptr ;
3420  m_rank = helper::Rank ;
3421  helper::assign_tags( m_tag );
3422  helper::assign( m_stride, n1, n2, n3, n4, n5, n6, n7 ); return *this ;
3423  }
3424 
3425  template< class Tag1 , class Tag2 , class Tag3 , class Tag4 ,
3426  class Tag5 , class Tag6 >
3427  Array & assign( value_type * ptr ,
3428  size_type n1 , size_type n2 , size_type n3 , size_type n4 ,
3429  size_type n5 , size_type n6 )
3430  {
3431  typedef
3432  array_traits::Helper<Scalar,array_order,
3433  Tag1,Tag2,Tag3,Tag4,Tag5,Tag6,void,void>
3434  helper ;
3435  m_ptr = ptr ;
3436  m_rank = helper::Rank ;
3437  helper::assign_tags( m_tag );
3438  helper::assign( m_stride, n1, n2, n3, n4, n5, n6 );
3439  return *this ;
3440  }
3441 
3442  template< class Tag1 , class Tag2 , class Tag3 , class Tag4 ,
3443  class Tag5 >
3444  Array & assign( value_type * ptr ,
3445  size_type n1 , size_type n2 , size_type n3 , size_type n4 ,
3446  size_type n5 )
3447  {
3448  typedef
3449  array_traits::Helper<Scalar,array_order,
3450  Tag1,Tag2,Tag3,Tag4,Tag5,void,void,void>
3451  helper ;
3452  m_ptr = ptr ;
3453  m_rank = helper::Rank ;
3454  helper::assign_tags( m_tag );
3455  helper::assign( m_stride, n1, n2, n3, n4, n5 );
3456  return *this ;
3457  }
3458 
3459  template< class Tag1 , class Tag2 , class Tag3 , class Tag4 >
3460  Array & assign( value_type * ptr ,
3461  size_type n1 , size_type n2 , size_type n3 , size_type n4 )
3462  {
3463  typedef
3464  array_traits::Helper<Scalar,array_order,
3465  Tag1,Tag2,Tag3,Tag4,void,void,void,void>
3466  helper ;
3467  m_ptr = ptr ;
3468  m_rank = helper::Rank ;
3469  helper::assign_tags( m_tag );
3470  helper::assign( m_stride, n1, n2, n3, n4 );
3471  return *this ;
3472  }
3473 
3474  template< class Tag1 , class Tag2 , class Tag3 >
3475  Array & assign( value_type * ptr ,
3476  size_type n1 , size_type n2 , size_type n3 )
3477  {
3478  typedef
3479  array_traits::Helper<Scalar,array_order,
3480  Tag1,Tag2,Tag3,void,void,void,void,void>
3481  helper ;
3482  m_ptr = ptr ;
3483  m_rank = helper::Rank ;
3484  helper::assign_tags( m_tag );
3485  helper::assign( m_stride, n1, n2, n3 );
3486  return *this ;
3487  }
3488 
3489  template< class Tag1 , class Tag2 >
3490  Array & assign( value_type * ptr ,
3491  size_type n1 , size_type n2 )
3492  {
3493  typedef
3494  array_traits::Helper<Scalar,array_order,
3495  Tag1,Tag2,void,void,void,void,void,void>
3496  helper ;
3497  m_ptr = ptr ;
3498  m_rank = helper::Rank ;
3499  helper::assign_tags( m_tag );
3500  helper::assign( m_stride, n1, n2 );
3501  return *this ;
3502  }
3503 
3504  template< class Tag1 >
3505  Array & assign( value_type * ptr ,
3506  size_type n1 )
3507  {
3508  typedef
3509  array_traits::Helper<Scalar,array_order,
3510  Tag1,void,void,void,void,void,void,void>
3511  helper ;
3512  m_ptr = ptr ;
3513  m_rank = helper::Rank ;
3514  helper::assign_tags( m_tag );
3515  helper::assign( m_stride, n1 );
3516  return *this ;
3517  }
3518 
3519 private:
3520 
3522  Array( const Array & rhs , const size_type i )
3523  : m_ptr( NULL ), m_rank( 0 )
3524  {
3525  if ( 1 < rhs.m_rank ) {
3526  Copy<8>( m_stride , rhs.m_stride );
3527  Copy<8>( m_tag , rhs.m_tag );
3528  m_rank = rhs.m_rank - 1 ;
3529  m_ptr = rhs.m_ptr + ( m_rank ? m_stride[ m_rank - 1 ] * i : i );
3530  m_stride[ m_rank ] = 0 ;
3531  m_tag[ m_rank ] = 0 ;
3532  }
3533  else {
3534  Copy<8>( m_stride , (size_type) 0 );
3535  Copy<8>( m_tag , (tag_type) NULL );
3536  }
3537  }
3538 
3540  value_type * m_ptr ;
3541 
3543  size_type m_rank ;
3544 
3546  size_type m_stride[8];
3547 
3549  tag_type m_tag[8] ;
3550 
3551  template< typename , ArrayOrder ,
3552  class , class , class , class ,
3553  class , class , class , class >
3554  friend class shards::Array ;
3555 };
3556 
3557 //----------------------------------------------------------------------
3576 template< typename Scalar , ArrayOrder array_order ,
3577  class Tag1 , class Tag2 , class Tag3 , class Tag4 ,
3578  class Tag5 , class Tag6 , class Tag7 , class Tag8 >
3579 class Array
3580 {
3581 private:
3582 
3583 #ifndef DOXYGEN_COMPILE
3584  typedef
3585  array_traits::Helper<Scalar,array_order,
3586  Tag1,Tag2,Tag3,Tag4,Tag5,Tag6,Tag7,Tag8>
3587  helper ;
3588 #endif /* DOXYGEN_COMPILE */
3589 
3590 public:
3596  typedef Scalar value_type ;
3597 
3599  typedef array_traits::int_t size_type ;
3600 
3602  typedef const ArrayDimTag * tag_type ;
3603 
3604  //----------------------------------
3605 
3607  enum { Rank = helper::Rank };
3608 
3610  enum { Natural = NaturalOrder == array_order };
3611 
3613  enum { Reverse = FortranOrder == array_order };
3614 
3616  enum { Contiguous = true };
3617 
3619  size_type rank() const { return Rank ; }
3620 
3622  bool natural() const { return Natural ; }
3623 
3625  bool reverse() const { return Reverse ; }
3626 
3628  bool contiguous() const { return Contiguous ; }
3629 
3630  //----------------------------------
3631 
3632 #ifndef DOXYGEN_COMPILE
3633 
3634  template < size_type ordinate >
3635  struct Tag {
3636  typedef typename array_traits::TagAt<Array,ordinate>::type type ;
3637  };
3638 #endif
3639 
3641  tag_type tag( const size_type ordinate ) const
3642  { return m_array.tag( ordinate ); }
3643 
3644  //----------------------------------
3646  template < size_type ordinate > size_type dimension() const
3647  {
3648  typedef array_traits::StrideDim<array_order,Rank,ordinate> StrideDim ;
3649  return StrideDim::dimension(m_array.m_stride);
3650  }
3651 
3653  size_type dimension( const size_type ordinate ) const
3654  {
3655  typedef array_traits::StrideDim<array_order,Rank> StrideDim ;
3656  return StrideDim::dimension(m_array.m_stride,ordinate);
3657  }
3658 
3660  template< typename iType >
3661  void dimensions( std::vector<iType> & n )
3662  { m_array.template dimensions<iType>( n ); }
3663 
3665  size_type size() const { return m_array.m_stride[ Rank - 1 ]; }
3666 
3668  //----------------------------------
3676  typedef typename helper::truncate TruncateType ;
3677 
3682  template< typename iType >
3683  TruncateType truncate( const iType & i ) const
3684  { return TruncateType( m_array , i ); }
3685 
3686  //----------------------------------
3688  value_type * contiguous_data() const { return m_array.contiguous_data(); }
3689 
3691  template< typename iType >
3692  value_type & operator[]( const iType & i ) const
3693  { return m_array[i]; }
3694 
3696  template< typename iType >
3697  value_type & operator()( const iType & i1 , const iType & i2 ,
3698  const iType & i3 , const iType & i4 ,
3699  const iType & i5 , const iType & i6 ,
3700  const iType & i7 , const iType & i8 ) const
3701  {
3702  array_traits::CheckRank<8,Rank>::ok();
3703  return m_array(i1,i2,i3,i4,i5,i6,i7,i8);
3704  }
3705 
3707  template< typename iType >
3708  value_type & operator()( const iType & i1 , const iType & i2 ,
3709  const iType & i3 , const iType & i4 ,
3710  const iType & i5 , const iType & i6 ,
3711  const iType & i7 ) const
3712  {
3713  array_traits::CheckRank<7,Rank>::ok();
3714  return m_array(i1,i2,i3,i4,i5,i6,i7);
3715  }
3716 
3718  template< typename iType >
3719  value_type & operator()( const iType & i1 , const iType & i2 ,
3720  const iType & i3 , const iType & i4 ,
3721  const iType & i5 , const iType & i6 ) const
3722  {
3723  array_traits::CheckRank<6,Rank>::ok();
3724  return m_array(i1,i2,i3,i4,i5,i6);
3725  }
3726 
3728  template< typename iType >
3729  value_type & operator()( const iType & i1 , const iType & i2 ,
3730  const iType & i3 , const iType & i4 ,
3731  const iType & i5 ) const
3732  {
3733  array_traits::CheckRank<5,Rank>::ok();
3734  return m_array(i1,i2,i3,i4,i5);
3735  }
3736 
3738  template< typename iType >
3739  value_type & operator()( const iType & i1 , const iType & i2 ,
3740  const iType & i3 , const iType & i4 ) const
3741  {
3742  array_traits::CheckRank<4,Rank>::ok();
3743  return m_array(i1,i2,i3,i4);
3744  }
3745 
3747  template< typename iType >
3748  value_type & operator()( const iType & i1 , const iType & i2 ,
3749  const iType & i3 ) const
3750  {
3751  array_traits::CheckRank<3,Rank>::ok();
3752  return m_array(i1,i2,i3);
3753  }
3754 
3756  template< typename iType >
3757  value_type & operator()( const iType & i1 , const iType & i2 ) const
3758  {
3759  array_traits::CheckRank<2,Rank>::ok();
3760  return m_array(i1,i2);
3761  }
3762 
3764  template< typename iType >
3765  value_type & operator()( const iType & i1 ) const
3766  {
3767  array_traits::CheckRank<1,Rank>::ok();
3768  return m_array(i1);
3769  }
3770 
3772  //----------------------------------
3780  typedef typename helper::reverse ReverseType ;
3781 
3783  Array() : m_array()
3784  { m_array.m_rank = Rank ; helper::assign_tags( m_array.m_tag ); }
3785 
3787  Array( const Array & rhs ) : m_array( rhs.m_array ) {}
3788 
3790  Array & operator = ( const Array & rhs )
3791  { m_array.operator=(rhs.m_array); return *this ; }
3792 
3794  Array( const ReverseType & rhs ) : m_array( rhs.m_array ) {}
3795 
3797  Array & operator = ( const ReverseType & rhs )
3798  { m_array.operator=(rhs.m_array); return *this ; }
3799 
3801  Array & assign( value_type * arg_ptr , const size_type * const dims )
3802  {
3803  m_array.m_ptr = arg_ptr ;
3804  array_traits::init_dim( m_array.m_stride , dims , Rank , Natural );
3805  return *this ;
3806  }
3807 
3809  Array( value_type * arg_ptr , const size_type * const dims )
3810  : m_array()
3811  {
3812  m_array.m_rank = Rank ;
3813  helper::assign_tags( m_array.m_tag );
3814  assign( arg_ptr , dims );
3815  }
3816 
3818  Array & assign( value_type * arg_ptr ,
3819  const size_type n1 , const size_type n2 ,
3820  const size_type n3 , const size_type n4 ,
3821  const size_type n5 , const size_type n6 ,
3822  const size_type n7 , const size_type n8 )
3823  {
3824  array_traits::CheckRange<7,Rank>::ok();
3825  m_array.m_ptr = arg_ptr ;
3826  helper::assign( m_array.m_stride, n1, n2, n3, n4, n5, n6, n7, n8 );
3827  return *this ;
3828  }
3829 
3831  Array( value_type * arg_ptr ,
3832  const size_type n1 , const size_type n2 ,
3833  const size_type n3 , const size_type n4 ,
3834  const size_type n5 , const size_type n6 ,
3835  const size_type n7 , const size_type n8 )
3836  : m_array()
3837  {
3838  m_array.m_rank = Rank ;
3839  helper::assign_tags( m_array.m_tag );
3840  assign( arg_ptr, n1, n2, n3, n4, n5, n6, n7, n8 );
3841  }
3842 
3846  Array& assign( value_type * arg_ptr ,
3847  const size_type n1 , const size_type n2 ,
3848  const size_type n3 , const size_type n4 ,
3849  const size_type n5 , const size_type n6 ,
3850  const size_type n7 )
3851  {
3852  array_traits::CheckRange<6,Rank>::ok();
3853  m_array.m_ptr = arg_ptr ;
3854  helper::assign( m_array.m_stride, n1, n2, n3, n4, n5, n6, n7 );
3855  return *this ;
3856  }
3857 
3861  Array( value_type * arg_ptr ,
3862  const size_type n1 , const size_type n2 ,
3863  const size_type n3 , const size_type n4 ,
3864  const size_type n5 , const size_type n6 ,
3865  const size_type n7 )
3866  : m_array()
3867  {
3868  m_array.m_rank = Rank ;
3869  helper::assign_tags( m_array.m_tag );
3870  assign( arg_ptr, n1, n2, n3, n4, n5, n6, n7 );
3871  }
3872 
3876  Array & assign( value_type * arg_ptr ,
3877  const size_type n1 , const size_type n2 ,
3878  const size_type n3 , const size_type n4 ,
3879  const size_type n5 , const size_type n6 )
3880  {
3881  array_traits::CheckRange<5,Rank>::ok();
3882  m_array.m_ptr = arg_ptr ;
3883  helper::assign( m_array.m_stride, n1, n2, n3, n4, n5, n6 );
3884  return *this ;
3885  }
3886 
3890  Array( value_type * arg_ptr ,
3891  const size_type n1 , const size_type n2 ,
3892  const size_type n3 , const size_type n4 ,
3893  const size_type n5 , const size_type n6 )
3894  : m_array()
3895  {
3896  m_array.m_rank = Rank ;
3897  helper::assign_tags( m_array.m_tag );
3898  assign( arg_ptr, n1, n2, n3, n4, n5, n6 );
3899  }
3900 
3904  Array & assign( value_type * arg_ptr ,
3905  const size_type n1 , const size_type n2 ,
3906  const size_type n3 , const size_type n4 ,
3907  const size_type n5 )
3908  {
3909  array_traits::CheckRange<4,Rank>::ok();
3910  m_array.m_ptr = arg_ptr ;
3911  helper::assign( m_array.m_stride, n1, n2, n3, n4, n5 );
3912  return *this ;
3913  }
3914 
3918  Array( value_type * arg_ptr ,
3919  const size_type n1 , const size_type n2 ,
3920  const size_type n3 , const size_type n4 ,
3921  const size_type n5 )
3922  : m_array()
3923  {
3924  m_array.m_rank = Rank ;
3925  helper::assign_tags( m_array.m_tag );
3926  assign( arg_ptr, n1, n2, n3, n4, n5 );
3927  }
3928 
3932  Array & assign( value_type * arg_ptr ,
3933  const size_type n1 , const size_type n2 ,
3934  const size_type n3 , const size_type n4 )
3935  {
3936  array_traits::CheckRange<3,Rank>::ok();
3937  m_array.m_ptr = arg_ptr ;
3938  helper::assign( m_array.m_stride, n1, n2, n3, n4 );
3939  return *this ;
3940  }
3941 
3945  Array( value_type * arg_ptr ,
3946  const size_type n1 , const size_type n2 ,
3947  const size_type n3 , const size_type n4 )
3948  : m_array()
3949  {
3950  m_array.m_rank = Rank ;
3951  helper::assign_tags( m_array.m_tag );
3952  assign( arg_ptr, n1, n2, n3, n4 );
3953  }
3954 
3958  Array & assign( value_type * arg_ptr ,
3959  const size_type n1 , const size_type n2 ,
3960  const size_type n3 )
3961  {
3962  array_traits::CheckRange<2,Rank>::ok();
3963  m_array.m_ptr = arg_ptr ;
3964  helper::assign( m_array.m_stride, n1, n2, n3 );
3965  return *this ;
3966  }
3967 
3971  Array( value_type * arg_ptr ,
3972  const size_type n1 , const size_type n2 ,
3973  const size_type n3 )
3974  : m_array()
3975  {
3976  m_array.m_rank = Rank ;
3977  helper::assign_tags( m_array.m_tag );
3978  assign( arg_ptr , n1, n2, n3 );
3979  }
3980 
3984  Array & assign( value_type * arg_ptr ,
3985  const size_type n1 , const size_type n2 )
3986  {
3987  array_traits::CheckRange<1,Rank>::ok();
3988  m_array.m_ptr = arg_ptr ;
3989  helper::assign( m_array.m_stride, n1, n2 );
3990  return *this ;
3991  }
3992 
3996  Array( value_type * arg_ptr , const size_type n1 , const size_type n2 )
3997  : m_array()
3998  {
3999  m_array.m_rank = Rank ;
4000  helper::assign_tags( m_array.m_tag );
4001  assign( arg_ptr, n1, n2 );
4002  }
4003 
4007  Array & assign( value_type * arg_ptr , const size_type n1 )
4008  {
4009  array_traits::CheckRange<0,Rank>::ok();
4010  m_array.m_ptr = arg_ptr ;
4011  helper::assign( m_array.m_stride, n1 );
4012  return *this ;
4013  }
4014 
4018  Array( value_type * arg_ptr , const size_type n1 )
4019  : m_array()
4020  {
4021  m_array.m_rank = Rank ;
4022  helper::assign_tags( m_array.m_tag );
4023  assign( arg_ptr, n1 );
4024  }
4025 
4027  Array & assign( value_type * arg_ptr )
4028  {
4029  m_array.m_ptr = arg_ptr ;
4030  helper::assign( m_array.m_stride );
4031  return *this ;
4032  }
4033 
4035  Array( value_type * arg_ptr )
4036  : m_array()
4037  {
4038  m_array.m_rank = Rank ;
4039  helper::assign_tags( m_array.m_tag );
4040  assign( arg_ptr );
4041  }
4042 
4045  : m_array( rhs )
4046  {
4047  if ( ! helper::verify( m_array.m_rank , m_array.m_tag ) ) {
4048  m_array.m_rank = Rank ;
4049  helper::assign_tags( m_array.m_tag );
4050  array_traits::throw_bad_conversion( m_array.m_rank , m_array.m_tag ,
4051  rhs.m_rank , rhs.m_tag );
4052  }
4053  }
4054 
4056  operator const Array<Scalar,array_order> & () const { return m_array ; }
4057 
4059  operator typename Array<Scalar,array_order>::ReverseType () const
4060  { return typename Array<Scalar,array_order>::ReverseType( m_array ); }
4061 
4063  void assign_stride( value_type * arg_ptr ,
4064  const size_type * arg_stride )
4065  {
4066  m_array.m_ptr = arg_ptr ;
4067  Copy<Rank>( m_array.m_stride , arg_stride );
4068  Copy<8-Rank>( m_array.m_stride + Rank , size_type(0) );
4069  }
4070 
4072  void assign_stride( value_type * arg_ptr ,
4073  const size_type * arg_stride ,
4074  size_type arg_final_dim )
4075  {
4076  m_array.m_ptr = arg_ptr ;
4077  Copy<Rank-1>( m_array.m_stride , arg_stride );
4078  m_array.m_stride[Rank-1] = m_array.m_stride[Rank-2] * arg_final_dim ;
4079  Copy<8-Rank>( m_array.m_stride + Rank , size_type(0) );
4080  }
4081 
4083 protected:
4084 
4085  Array( const Array<Scalar,array_order> & rhs , size_type i )
4086  : m_array( rhs , i )
4087  {
4088  if ( ! helper::verify( m_array.m_rank , m_array.m_tag ) ) {
4089  m_array.m_rank = Rank ;
4090  helper::assign_tags( m_array.m_tag );
4091  array_traits::throw_bad_conversion( m_array.m_rank , m_array.m_tag ,
4092  rhs.m_rank - 1 , rhs.m_tag );
4093  }
4094  }
4095 
4096  Array<value_type,array_order> m_array ;
4097 
4098  template< typename , ArrayOrder ,
4099  class , class , class , class ,
4100  class , class , class , class >
4101  friend class shards::Array ;
4102 };
4103 
4104 //----------------------------------------------------------------------
4105 
4109 template< typename Scalar >
4110 class Array<Scalar,RankZero,void,void,void,void,void,void,void,void>
4111 {
4112 public:
4118  typedef Scalar value_type ;
4119 
4121  typedef array_traits::int_t size_type ;
4122 
4124  typedef const ArrayDimTag * tag_type ;
4125 
4126  //----------------------------------
4127 
4129  enum { Rank = 0 };
4130 
4132  enum { Natural = false };
4133 
4135  enum { Reverse = false };
4136 
4138  enum { Contiguous = true };
4139 
4141  size_type rank() const { return Rank ; }
4142 
4144  bool natural() const { return Natural ; }
4145 
4147  bool reverse() const { return Reverse ; }
4148 
4150  bool contiguous() const { return Contiguous ; }
4151 
4152  //----------------------------------
4153 
4155  size_type size() const { return 1 ; }
4156 
4158  //----------------------------------
4164  value_type * contiguous_data() const { return m_ptr ; }
4165 
4167  value_type & operator()() const { return *m_ptr ; }
4168 
4170  //----------------------------------
4175  Array() : m_ptr(NULL) {}
4176 
4177  Array( const Array & rhs ) : m_ptr( rhs.m_ptr ) {}
4178 
4179  Array & operator = ( const Array & rhs )
4180  { m_ptr = rhs.m_ptr ; return *this ; }
4181 
4182  //----------------------------------
4183  // Class specific constructors:
4184 
4185  Array( value_type * arg_ptr ) : m_ptr( arg_ptr ) {}
4186 
4188 protected:
4189 
4190 #ifndef DOXYGEN_COMPILE
4191  value_type * m_ptr ;
4192 
4193  template< typename , ArrayOrder ,
4194  class , class , class , class ,
4195  class , class , class , class >
4196  friend class shards::Array ;
4197 
4198 #endif /* DOXYGEN_COMPILE */
4199 };
4200 
4201 
4202 //----------------------------------------------------------------------
4203 //----------------------------------------------------------------------
4204 
4207 } // namespace shards
4208 
4209 #undef SHARDS_ARRAY_CHECK
4210 
4211 #endif /* Shards_Array_hpp */
4212 
value_type * contiguous_data() const
Pointer to contiguous block of member data.
The preferred multi-dimensional Array interface with compile-time user-defined dimension ordinate...
helper::reverse ReverseType
The compatible multidimensional array with reversed multi-index ordering and dimension tags...
Array(value_type *arg_ptr, const size_type n1, const size_type n2, const size_type n3, const size_type n4, const size_type n5, const size_type n6, const size_type n7)
Construct a Rank 7..8 array; use Tag#::Size for defaults. The input dimensions are the 7 slowest stri...
static const ArrayDimension & tag()
Singleton tag for ArrayDimension.
value_type & operator[](const iType &i) const
Access member via offset into contiguous block.
bool contiguous() const
If the member data storage is contiguous.
virtual size_type to_index(size_type dimension, const std::string &label) const
Given a dimension and input strige produce an index.
bool contiguous() const
If the member data storage is contiguous.
Array(value_type *arg_ptr, const size_type n1)
Construct a Rank 1..8 array; use Tag#::Size for defaults. The input dimension is the slowest stride...
value_type & operator()(const iType &i1) const
Access member of a Rank 1 array.
ArrayOrder
Define Natural (C-language) or Fortran ordering of array dimensions. A RankZero array does not ha...
Array(value_type *arg_ptr, const size_type *const dims)
Construct with array of dimensions.
Array & assign(value_type *arg_ptr, const size_type n1, const size_type n2, const size_type n3, const size_type n4, const size_type n5)
Construct a Rank 5..8 array; use Tag#::Size for defaults. The input dimensions are the 5 slowest stri...
Array(const ReverseType &rhs)
Copy constructor for reverse type.
const char * name() const
Name of the tag, typically the name of the derived class.
Array & assign(value_type *arg_ptr, const size_type n1, const size_type n2, const size_type n3, const size_type n4, const size_type n5, const size_type n6)
Construct a Rank 6..8 array; use Tag#::Size for defaults. The input dimensions are the 6 slowest stri...
value_type * contiguous_data() const
Pointer to contiguous block of member data.
Array & assign(value_type *arg_ptr)
Construct a Rank 1..8 array; use Tag#::Size for defaults.
value_type & operator()(const iType &i1, const iType &i2, const iType &i3, const iType &i4, const iType &i5, const iType &i6, const iType &i7) const
Access member of a Rank 7 array.
size_type dimension(size_type ord) const
Dimension of the given ordinate.
size_type size() const
Total number of member data items.
size_type rank() const
Rank of the array is the number of non-void dimension tags.
Abstract base class for array dimension tags supplied to the Array template class.
bool reverse() const
If the multidimension follows the reverse (Fortran) ordering.
helper::truncate TruncateType
Subarray type that removes the slowest striding dimension (first natural or last fortran ordinate)...
void assign_stride(value_type *arg_ptr, const size_type *arg_stride)
Assign stride and pointer.
bool natural() const
If the multidimension follows the natural ordering.
tag_type tag(const size_type ordinate) const
Access the dimension tag-singleton for a given ordinate.
Array & assign(value_type *arg_ptr, const size_type n1, const size_type n2, const size_type n3, const size_type n4, const size_type n5, const size_type n6, const size_type n7, const size_type n8)
Construct a Rank 8 array.
An anonymous array dimension tag, which is NOT the recommended usage.
Array & assign(value_type *arg_ptr, const size_type n1, const size_type n2, const size_type n3, const size_type n4, const size_type n5, const size_type n6, const size_type n7)
Construct a Rank 7..8 array; use Tag#::Size for defaults. The input dimensions are the 7 slowest stri...
Array(const Array< Scalar, array_order > &rhs)
Construct compile-time array from run-time array.
value_type & operator[](const iType &i) const
Access member via full ordering of members.
value_type & operator()(const iType &i1, const iType &i2, const iType &i3, const iType &i4, const iType &i5, const iType &i6) const
Access member of a Rank 6 array.
value_type & operator()(const iType &i1, const iType &i2, const iType &i3, const iType &i4, const iType &i5, const iType &i6, const iType &i7, const iType &i8) const
Access member via Rank 8 multi-index.
const ArrayDimTag * tag_type
Type of runtime dimension tags.
value_type & operator()(const iType &i1, const iType &i2) const
Access member of a Rank 2 array.
bool reverse() const
If the multidimension follows the reverse (Fortran) ordering.
Array(value_type *arg_ptr, const size_type n1, const size_type n2, const size_type n3, const size_type n4, const size_type n5)
Construct a Rank 5..8 array; use Tag#::Size for defaults. The input dimensions are the 5 slowest stri...
size_type dimension(const size_type ordinate) const
Dimension of the given ordinate.
Array & assign(value_type *arg_ptr, const size_type *const dims)
Assign pointer and dimensions.
Array(value_type *arg_ptr, const size_type n1, const size_type n2, const size_type n3, const size_type n4, const size_type n5, const size_type n6, const size_type n7, const size_type n8)
Construct a Rank 8 array.
value_type & operator()(const iType &i1, const iType &i2, const iType &i3, const iType &i4, const iType &i5, const iType &i6, const iType &i7, const iType &i8) const
Access member of a Rank 8 array.
void dimensions(std::vector< iType > &n)
Dimensions of all ordinates.
void dimensions(std::vector< iType > &n)
Dimension of all ordinate.
value_type * contiguous_data() const
Pointer to contiguous block of member data.
value_type & operator()(const iType &i1, const iType &i2, const iType &i3, const iType &i4) const
Access member of a Rank 4 array.
value_type & operator()(const iType &i1, const iType &i2, const iType &i3, const iType &i4, const iType &i5) const
Access member of a Rank 5 array.
virtual const char * name() const =0
Name of the tag, typically the name of the derived class.
Array(const ReverseType &rhs)
Copy constructor for compatible reverse type.
Array(value_type *arg_ptr, const size_type n1, const size_type n2, const size_type n3, const size_type n4, const size_type n5, const size_type n6)
Construct a Rank 6..8 array; use Tag#::Size for defaults. The input dimensions are the 6 slowest stri...
Array & assign(value_type *arg_ptr, const size_type n1, const size_type n2)
Construct a Rank 2..8 array; use Tag#::Size for defaults. The input dimensions are the 2 slowest stri...
TruncateType truncate(const iType &i) const
Generate a subarray view of the array with the slowest striding ordinate offset by i and removed...
Array & assign(value_type *arg_ptr, const size_type n1, const size_type n2, const size_type n3, const size_type n4)
Construct a Rank 4..8 array; use Tag#::Size for defaults. The input dimensions are the 4 slowest stri...
Special tag to indicate that an array specification has degenerated to rank-zero, i...
bool contiguous() const
If the member data storage is contiguous.
bool reverse() const
If the multidimension follows the reverse (Fortran) ordering.
Array(value_type *arg_ptr, const size_type n1, const size_type n2)
Construct a Rank 2..8 array; use Tag#::Size for defaults. The input dimensions are the 2 slowest stri...
Array truncate(const iType &i) const
Generate a subarray view of the array with the slowest striding ordinate offset by i and removed...
Array & assign(value_type *arg_ptr, const size_type n1)
Construct a Rank 1..8 array; use Tag#::Size for defaults. The input dimension is the slowest stride...
Use the Natural or C-language ordering for multi-dimensions where the right-most dimension is stride-...
Array & assign(value_type *arg_ptr, const size_type n1, const size_type n2, const size_type n3)
Construct a Rank 3..8 array; use Tag#::Size for defaults. The input dimensions are the 3 slowest stri...
Use the Reverse or Fortran-language ordering for multi-dimensions where the left-most dimension is st...
tag_type tag(size_type ord) const
Access the dimension tag-singleton for a given ordinate.
Array()
Default constructor.
Array(value_type *arg_ptr, const size_type n1, const size_type n2, const size_type n3, const size_type n4)
Construct a Rank 4..8 array; use Tag#::Size for defaults. The input dimensions are the 4 slowest stri...
bool natural() const
If the multidimension follows the natural ordering.
void assign_stride(value_type *arg_ptr, const size_type *arg_stride, size_type arg_final_dim)
Assign stride and pointer.
size_type dimension() const
Dimension of the given ordinate.
Array(const Array &rhs)
Copy constructor.
array_traits::int_t size_type
Type for sizes.
bool natural() const
If the multidimension follows the natural ordering.
virtual std::string to_string(size_type dimension, size_type index) const
Given a dimension and index produce a string for output.
value_type & operator()() const
Access member via Rank 0 multi-index.
Array(value_type *arg_ptr, const size_type n1, const size_type n2, const size_type n3)
Construct a Rank 3..8 array; use Tag#::Size for defaults. The input dimensions are the 3 slowest stri...
size_type rank() const
Rank of the array is the number of non-void dimension tags.
value_type & operator()(const iType &i1, const iType &i2, const iType &i3) const
Access member of a Rank 3 array.
size_type rank() const
Rank of the array is the number of non-void dimension tags.
Scalar value_type
Type of member data.
Array(value_type *arg_ptr)
Construct a Rank 1..8 array; use Tag#::Size for defaults.
Copy into an array.