shards  Version of the Day
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 
3248  size_type dimension( size_type ord ) const
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 
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 
The preferred multi-dimensional Array interface with compile-time user-defined dimension 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.
size_type dimension() const
Dimension of the given ordinate.
bool contiguous() const
If the member data storage is contiguous.
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)
Construct a Rank 7..8 array; use Tag#::Size for defaults. The input dimensions are the 7 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 iType &i4, const iType &i5, const iType &i6) const
Access member of a Rank 6 array.
value_type & operator()(const iType &i1) const
Access member of a Rank 1 array.
value_type & operator()(const iType &i1, const iType &i2, const iType &i3) const
Access member of a Rank 3 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 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 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.
Array & assign(value_type *arg_ptr)
Construct a Rank 1..8 array; use Tag#::Size for defaults.
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.
Array(const ReverseType &rhs)
Copy constructor for reverse type.
value_type * contiguous_data() const
Pointer to contiguous block of member data.
bool natural() const
If the multidimension follows the natural ordering.
helper::reverse ReverseType
The compatible multidimensional array with reversed multi-index ordering and dimension tags...
value_type & operator()(const iType &i1, const iType &i2, const iType &i3, const iType &i4) const
Access member of a Rank 4 array.
size_type dimension(size_type ord) const
Dimension of the given ordinate.
bool contiguous() const
If the member data storage is contiguous.
Abstract base class for array dimension tags supplied to the Array template class.
Array(const Array< Scalar, array_order > &rhs)
Construct compile-time array from run-time array.
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...
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...
bool natural() const
If the multidimension follows the natural ordering.
An anonymous array dimension tag, which is NOT the recommended usage.
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 dimension(const size_type ordinate) const
Dimension of the given ordinate.
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 iType &i7, const iType &i8) const
Access member via Rank 8 multi-index.
value_type * contiguous_data() const
Pointer to contiguous block of member data.
bool reverse() const
If the multidimension follows the reverse (Fortran) ordering.
const ArrayDimTag * tag_type
Type of runtime dimension tags.
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.
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...
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)
Construct a Rank 5..8 array; use Tag#::Size for defaults. The input dimensions are the 5 slowest stri...
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...
helper::truncate TruncateType
Subarray type that removes the slowest striding dimension (first natural or last fortran ordinate)...
void dimensions(std::vector< iType > &n)
Dimension of all ordinate.
value_type * contiguous_data() const
Pointer to contiguous block of member data.
Array(value_type *arg_ptr, const size_type *const dims)
Construct with array of dimensions.
Array(const Array &rhs)
Copy constructor.
value_type & operator()(const iType &i1, const iType &i2) const
Access member of a Rank 2 array.
value_type & operator[](const iType &i) const
Access member via offset into contiguous block.
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...
void dimensions(std::vector< iType > &n)
Dimensions of all ordinates.
Scalar value_type
Type of member data.
TruncateType truncate(const iType &i) const
Generate a subarray view of the array with the slowest striding ordinate offset by i and removed...
void assign_stride(value_type *arg_ptr, const size_type *arg_stride, size_type arg_final_dim)
Assign stride and pointer.
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.
void assign_stride(value_type *arg_ptr, const size_type *arg_stride)
Assign stride and pointer.
Array truncate(const iType &i) const
Generate a subarray view of the array with the slowest striding ordinate offset by i and removed...
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...
Use the Natural or C-language ordering for multi-dimensions where the right-most dimension is stride-...
Array()
Default constructor.
Use the Reverse or Fortran-language ordering for multi-dimensions where the left-most dimension is st...
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...
tag_type tag(size_type ord) const
Access the dimension tag-singleton for a given ordinate.
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...
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.
array_traits::int_t size_type
Type for sizes.
Array(const ReverseType &rhs)
Copy constructor for compatible reverse type.
Array(value_type *arg_ptr)
Construct a Rank 1..8 array; use Tag#::Size for defaults.
size_type size() const
Total number of member data items.
bool reverse() const
If the multidimension follows the reverse (Fortran) ordering.
value_type & operator()() const
Access member via Rank 0 multi-index.
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.
size_type rank() const
Rank of the array is the number of non-void dimension tags.
size_type rank() const
Rank of the array is the number of non-void dimension tags.
Copy into an array.