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