Shards_Array.hpp

00001 /*------------------------------------------------------------------------*/
00002 /*                  shards : Shared Discretization Tools                  */
00003 /*                Copyright (2008) Sandia Corporation                     */
00004 /*                                                                        */
00005 /*  Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive   */
00006 /*  license for use of this work by or on behalf of the U.S. Government.  */
00007 /*                                                                        */
00008 /*  This library is free software; you can redistribute it and/or modify  */
00009 /*  it under the terms of the GNU Lesser General Public License as        */
00010 /*  published by the Free Software Foundation; either version 2.1 of the  */
00011 /*  License, or (at your option) any later version.                       */
00012 /*                                                                        */
00013 /*  This library is distributed in the hope that it will be useful,       */
00014 /*  but WITHOUT ANY WARRANTY; without even the implied warranty of        */
00015 /*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU     */
00016 /*  Lesser General Public License for more details.                       */
00017 /*                                                                        */
00018 /*  You should have received a copy of the GNU Lesser General Public      */
00019 /*  License along with this library; if not, write to the Free Software   */
00020 /*  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307   */
00021 /*  USA                                                                   */
00022 /*------------------------------------------------------------------------*/
00023 
00024 #ifndef Shards_Array_hpp
00025 #define Shards_Array_hpp
00026 
00027 //----------------------------------------------------------------------
00028 
00029 #include <vector>
00030 #include <string>
00031 #include <Shards_SimpleArrayOps.hpp>
00032 
00033 //----------------------------------------------------------------------
00034 // Macro to compile in array bounds checking:
00035 
00036 #ifdef SHARDS_ARRAY_BOUNDS_CHECKING
00037 #define SHARDS_ARRAY_CHECK( X ) X
00038 #else
00039 #define SHARDS_ARRAY_CHECK( X )
00040 #endif
00041 
00042 //----------------------------------------------------------------------
00043 
00044 namespace shards {
00045 
00050 namespace array_traits {
00051 typedef int int_t ;
00052 } // namespace array_traits
00053 
00054 //----------------------------------------------------------------------
00060 enum ArrayOrder {
00064   NaturalOrder ,
00065 
00069   FortranOrder ,
00070 
00074   RankZero
00075 };
00076 
00077 //----------------------------------------------------------------------
00078 
00079 template< typename Scalar , ArrayOrder Order , 
00080           class Tag1 = void , class Tag2 = void ,
00081           class Tag3 = void , class Tag4 = void ,
00082           class Tag5 = void , class Tag6 = void ,
00083           class Tag7 = void , class Tag8 = void >
00084 class Array ;
00085 
00086 //----------------------------------------------------------------------
00087 
00111 class ArrayDimTag {
00112 public:
00113 
00114   typedef array_traits::int_t size_type ;
00115 
00117   virtual const char * name() const = 0 ;
00118 
00123   virtual std::string to_string( size_type dimension ,
00124                                  size_type index ) const ;
00125 
00130   virtual size_type to_index( size_type dimension ,
00131                               const std::string & label ) const ; 
00132  
00133 protected:
00134   virtual ~ArrayDimTag();
00135   ArrayDimTag() {}
00136   
00137 private:
00138   ArrayDimTag( const ArrayDimTag & );
00139   ArrayDimTag & operator = ( const ArrayDimTag & );
00140 };
00141 
00146 class ArrayDimension : public ArrayDimTag {
00147 public:
00148 
00149   const char * name() const ;
00150 
00152   static const ArrayDimension & tag();
00153 
00154 private:
00155   ~ArrayDimension();
00156   ArrayDimension();
00157   ArrayDimension( const ArrayDimension & );
00158   ArrayDimension & operator = ( const ArrayDimension & );
00159 };
00160 
00164 #define SHARDS_ARRAY_DIM_TAG_SIMPLE_DECLARATION( ADT ) \
00165   class ADT : public shards::ArrayDimTag { \
00166   public: \
00167     const char * name() const ; \
00168     static const ADT & tag(); \
00169   private: \
00170     ~ADT(); \
00171     ADT(); \
00172     ADT( const ADT & ); \
00173     ADT & operator = ( const ADT & ); \
00174   };
00175 
00179 #define SHARDS_ARRAY_DIM_TAG_SIMPLE_IMPLEMENTATION( ADT ) \
00180   ADT::ADT() {} \
00181   ADT::~ADT() {} \
00182   const char * ADT::name() const { static const char n[] = # ADT; return n; } \
00183   const ADT & ADT::tag() { static const ADT self ; return self ; }
00184 
00185 //----------------------------------------------------------------------
00186 //----------------------------------------------------------------------
00187 
00190 } // namespace shards
00191 
00192 //----------------------------------------------------------------------
00193 //----------------------------------------------------------------------
00194 // Private implementation details for the array
00195 
00196 #ifndef DOXYGEN_COMPILE
00197 
00198 namespace shards {
00199 namespace array_traits {
00200 
00201 //----------------------------------------------------------------------
00203 template< typename iType >
00204 inline
00205 iType stride_size(
00206   const iType & rank ,
00207   const iType * const stride )
00208 { return 0 < rank ? stride[ rank - 1 ] : 0 ; }
00209 
00211 template< typename iType >
00212 inline
00213 void stride_to_natural_dimensions(
00214   const iType   rank ,
00215   const iType * const stride ,
00216         iType * const dim )
00217 {
00218   iType n = 1 ;
00219   for ( iType i = 0 ; i < rank ; ++i )
00220     { dim[(rank-1)-i] = stride[i] / n ; n = stride[i] ; }
00221 }
00222 
00224 template< typename iType >
00225 inline
00226 void stride_to_natural_indices(
00227   const iType   rank ,
00228   const iType * const stride ,
00229         iType   offset ,
00230         iType * const indices )
00231 {
00232   iType * i = indices ;
00233   for ( const iType * s = stride + rank - 1 ; stride < s-- ; ++i ) {
00234     *i = offset / *s ;
00235     offset %= *s ;
00236   }
00237   *i = offset ;
00238 }
00239 
00241 template< typename iType >
00242 inline
00243 void stride_from_natural_dimensions( 
00244   const iType rank ,
00245         iType * const stride ,
00246   const iType * const dim )
00247 {
00248   iType n = 1 ;
00249   for ( iType i = 0 ; i < rank ; ++i ) { stride[i] = n *= dim[(rank-1)-i]; }
00250 }
00251 
00252 //----------------------------------------------------------------------
00253 
00254 void throw_bad_conversion( const int_t lhs_rank ,
00255                            const ArrayDimTag * const lhs_tags[] ,
00256                            const int_t rhs_rank ,
00257                            const ArrayDimTag * const rhs_tags[] );
00258 
00259 void check_rank( const int_t rank ,
00260                  const int_t test_rank );
00261 
00262 void check_range( const int_t index , const int_t bound );
00263 
00264 void check_indices( const bool ,
00265                     const int_t rank ,
00266                     const int_t * const stride ,
00267                     const int_t = 0 ,
00268                     const int_t = 0 ,
00269                     const int_t = 0 ,
00270                     const int_t = 0 ,
00271                     const int_t = 0 ,
00272                     const int_t = 0 ,
00273                     const int_t = 0 ,
00274                     const int_t = 0 );
00275 
00276 void init_dim(
00277          int_t dst_stride[] ,     
00278    const int_t src_dimension[] ,  
00279    const int_t rank , const bool natural );
00280  
00281 void init_tags(
00282    const ArrayDimTag *       dst_tag[] , 
00283    const ArrayDimTag * const src_tag[] , 
00284    const int_t rank , const bool natural );
00285 
00286 //----------------------------------------------------------------------
00287 
00288 template< int_t , int_t > struct CheckRank ;
00289 
00290 template<> struct CheckRank<0,0> { static void ok(){} };
00291 template<> struct CheckRank<1,1> { static void ok(){} };
00292 template<> struct CheckRank<2,2> { static void ok(){} };
00293 template<> struct CheckRank<3,3> { static void ok(){} };
00294 template<> struct CheckRank<4,4> { static void ok(){} };
00295 template<> struct CheckRank<5,5> { static void ok(){} };
00296 template<> struct CheckRank<6,6> { static void ok(){} };
00297 template<> struct CheckRank<7,7> { static void ok(){} };
00298 template<> struct CheckRank<8,8> { static void ok(){} };
00299 
00300 //----------------------------------------------------------------------
00301 
00302 template< int_t Index , int_t Bound > struct CheckRange ;
00303 
00304 template<> struct CheckRange<0,8> { static void ok(){} };
00305 template<> struct CheckRange<1,8> { static void ok(){} };
00306 template<> struct CheckRange<2,8> { static void ok(){} };
00307 template<> struct CheckRange<3,8> { static void ok(){} };
00308 template<> struct CheckRange<4,8> { static void ok(){} };
00309 template<> struct CheckRange<5,8> { static void ok(){} };
00310 template<> struct CheckRange<6,8> { static void ok(){} };
00311 template<> struct CheckRange<7,8> { static void ok(){} };
00312 
00313 template<> struct CheckRange<0,7> { static void ok(){} };
00314 template<> struct CheckRange<1,7> { static void ok(){} };
00315 template<> struct CheckRange<2,7> { static void ok(){} };
00316 template<> struct CheckRange<3,7> { static void ok(){} };
00317 template<> struct CheckRange<4,7> { static void ok(){} };
00318 template<> struct CheckRange<5,7> { static void ok(){} };
00319 template<> struct CheckRange<6,7> { static void ok(){} };
00320 
00321 template<> struct CheckRange<0,6> { static void ok(){} };
00322 template<> struct CheckRange<1,6> { static void ok(){} };
00323 template<> struct CheckRange<2,6> { static void ok(){} };
00324 template<> struct CheckRange<3,6> { static void ok(){} };
00325 template<> struct CheckRange<4,6> { static void ok(){} };
00326 template<> struct CheckRange<5,6> { static void ok(){} };
00327 
00328 template<> struct CheckRange<0,5> { static void ok(){} };
00329 template<> struct CheckRange<1,5> { static void ok(){} };
00330 template<> struct CheckRange<2,5> { static void ok(){} };
00331 template<> struct CheckRange<3,5> { static void ok(){} };
00332 template<> struct CheckRange<4,5> { static void ok(){} };
00333 
00334 template<> struct CheckRange<0,4> { static void ok(){} };
00335 template<> struct CheckRange<1,4> { static void ok(){} };
00336 template<> struct CheckRange<2,4> { static void ok(){} };
00337 template<> struct CheckRange<3,4> { static void ok(){} };
00338 
00339 template<> struct CheckRange<0,3> { static void ok(){} };
00340 template<> struct CheckRange<1,3> { static void ok(){} };
00341 template<> struct CheckRange<2,3> { static void ok(){} };
00342 
00343 template<> struct CheckRange<0,2> { static void ok(){} };
00344 template<> struct CheckRange<1,2> { static void ok(){} };
00345 
00346 template<> struct CheckRange<0,1> { static void ok(){} };
00347 
00348 //----------------------------------------------------------------------
00349 
00350 template< class , int_t > struct TagAt ;
00351 
00352 template< typename Scalar , ArrayOrder order ,
00353           class Tag1 , class Tag2 , class Tag3 , class Tag4 ,
00354           class Tag5 , class Tag6 , class Tag7 , class Tag8 >
00355 struct TagAt<Array<Scalar,order,Tag1,Tag2,Tag3,Tag4,Tag5,Tag6,Tag7,Tag8>,0>
00356 { typedef Tag1 type ; };
00357 
00358 template< typename Scalar , ArrayOrder order ,
00359           class Tag1 , class Tag2 , class Tag3 , class Tag4 ,
00360           class Tag5 , class Tag6 , class Tag7 , class Tag8 >
00361 struct TagAt<Array<Scalar,order,Tag1,Tag2,Tag3,Tag4,Tag5,Tag6,Tag7,Tag8>,1>
00362 { typedef Tag2 type ; };
00363 
00364 template< typename Scalar , ArrayOrder order ,
00365           class Tag1 , class Tag2 , class Tag3 , class Tag4 ,
00366           class Tag5 , class Tag6 , class Tag7 , class Tag8 >
00367 struct TagAt<Array<Scalar,order,Tag1,Tag2,Tag3,Tag4,Tag5,Tag6,Tag7,Tag8>,2>
00368 { typedef Tag3 type ; };
00369 
00370 template< typename Scalar , ArrayOrder order ,
00371           class Tag1 , class Tag2 , class Tag3 , class Tag4 ,
00372           class Tag5 , class Tag6 , class Tag7 , class Tag8 >
00373 struct TagAt<Array<Scalar,order,Tag1,Tag2,Tag3,Tag4,Tag5,Tag6,Tag7,Tag8>,3>
00374 { typedef Tag4 type ; };
00375 
00376 template< typename Scalar , ArrayOrder order ,
00377           class Tag1 , class Tag2 , class Tag3 , class Tag4 ,
00378           class Tag5 , class Tag6 , class Tag7 , class Tag8 >
00379 struct TagAt<Array<Scalar,order,Tag1,Tag2,Tag3,Tag4,Tag5,Tag6,Tag7,Tag8>,4>
00380 { typedef Tag5 type ; };
00381 
00382 template< typename Scalar , ArrayOrder order ,
00383           class Tag1 , class Tag2 , class Tag3 , class Tag4 ,
00384           class Tag5 , class Tag6 , class Tag7 , class Tag8 >
00385 struct TagAt<Array<Scalar,order,Tag1,Tag2,Tag3,Tag4,Tag5,Tag6,Tag7,Tag8>,5>
00386 { typedef Tag6 type ; };
00387 
00388 template< typename Scalar , ArrayOrder order ,
00389           class Tag1 , class Tag2 , class Tag3 , class Tag4 ,
00390           class Tag5 , class Tag6 , class Tag7 , class Tag8 >
00391 struct TagAt<Array<Scalar,order,Tag1,Tag2,Tag3,Tag4,Tag5,Tag6,Tag7,Tag8>,6>
00392 { typedef Tag7 type ; };
00393 
00394 template< typename Scalar , ArrayOrder order ,
00395           class Tag1 , class Tag2 , class Tag3 , class Tag4 ,
00396           class Tag5 , class Tag6 , class Tag7 , class Tag8 >
00397 struct TagAt<Array<Scalar,order,Tag1,Tag2,Tag3,Tag4,Tag5,Tag6,Tag7,Tag8>,7>
00398 { typedef Tag8 type ; };
00399 
00400 //----------------------------------------------------------------------
00401 //----------------------------------------------------------------------
00402 
00403 template< ArrayOrder , int_t Rank , int_t Ordinal = 0 > struct StrideDim ;
00404 
00405 template< int_t Rank , int_t Ordinal >
00406 struct StrideDim<RankZero,Rank,Ordinal> {
00407 
00408   template< typename iType >
00409   static iType dimension( const iType * )
00410     { return 0 ; }
00411 
00412   template< typename iType >
00413   static iType dimension( const iType * , iType )
00414     { return 0 ; }
00415 };
00416 
00417 template< int_t Rank >
00418 struct StrideDim<FortranOrder,Rank,0> {
00419 
00420   template< typename iType >
00421   static iType dimension( const iType * stride )
00422     {
00423       array_traits::CheckRange<0,Rank>::ok();
00424       return stride[0];
00425     }
00426 
00427   template< typename iType >
00428   static iType dimension( const iType * stride , iType ordinal )
00429     {
00430       array_traits::check_range(ordinal,Rank);
00431       return ordinal ? stride[ordinal] / stride[ordinal-1] : stride[0] ;
00432     }
00433 };
00434 
00435 template< int_t Rank >
00436 struct StrideDim<NaturalOrder,Rank,0> {
00437 
00438   template< typename iType >
00439   static iType dimension( const iType * stride )
00440     {
00441       array_traits::CheckRange<0,Rank>::ok();
00442       return stride[0];
00443     }
00444 
00445   template< typename iType >
00446   static iType dimension( const iType * stride , iType ordinal )
00447     {
00448       array_traits::check_range(ordinal,Rank);
00449       ordinal = ( Rank - 1 ) - ordinal ;
00450       return ordinal ? stride[ordinal] / stride[ordinal-1] : stride[0] ;
00451     }
00452 };
00453 
00454 template< int_t Rank , int_t Ordinal >
00455 struct StrideDim<FortranOrder,Rank,Ordinal> {
00456 
00457   template< typename iType >
00458   static iType dimension( const iType * stride )
00459     {
00460       array_traits::CheckRange<Ordinal,Rank>::ok();
00461       return stride[Ordinal] / stride[Ordinal-1];
00462     }
00463 };
00464 
00465 template< int_t Rank , int_t Ordinal >
00466 struct StrideDim<NaturalOrder,Rank,Ordinal> {
00467 
00468   template< typename iType >
00469   static iType dimension( const iType * stride )
00470     {
00471       enum { I = ( Rank - 1 ) - Ordinal };
00472       array_traits::CheckRange<Ordinal,Rank>::ok();
00473       return stride[I] / stride[I-1];
00474     }
00475 };
00476 
00477 //----------------------------------------------------------------------
00478 
00479 template< ArrayOrder > struct Offset ;
00480 
00481 template<>
00482 struct Offset<FortranOrder> {
00483 
00484   template< typename isType , typename iType >
00485   static iType op( const isType * const stride ,
00486                    const iType & i1 , const iType & i2 ,
00487                    const iType & i3 , const iType & i4 ,
00488                    const iType & i5 , const iType & i6 ,
00489                    const iType & i7 , const iType & i8 )
00490   {
00491     SHARDS_ARRAY_CHECK(check_indices(false,8,stride,i1,i2,i3,i4,i5,i6,i7,i8));
00492     return i1             + i2 * stride[0] +
00493            i3 * stride[1] + i4 * stride[2] +
00494            i5 * stride[3] + i6 * stride[4] +
00495            i7 * stride[5] + i8 * stride[6] ;
00496   }
00497 
00498   template< typename isType , typename iType >
00499   static iType op( const isType * const stride ,
00500                    const iType & i1 , const iType & i2 ,
00501                    const iType & i3 , const iType & i4 ,
00502                    const iType & i5 , const iType & i6 ,
00503                    const iType & i7 )
00504   {
00505     SHARDS_ARRAY_CHECK(check_indices(false,7,stride,i1,i2,i3,i4,i5,i6,i7));
00506     return i1             + i2 * stride[0] +
00507            i3 * stride[1] + i4 * stride[2] +
00508            i5 * stride[3] + i6 * stride[4] +
00509            i7 * stride[5] ;
00510   }
00511 
00512   template< typename isType , typename iType >
00513   static iType op( const isType * const stride ,
00514                    const iType & i1 , const iType & i2 ,
00515                    const iType & i3 , const iType & i4 ,
00516                    const iType & i5 , const iType & i6 )
00517   {
00518     SHARDS_ARRAY_CHECK(check_indices(false,6,stride,i1,i2,i3,i4,i5,i6));
00519     return i1             + i2 * stride[0] +
00520            i3 * stride[1] + i4 * stride[2] +
00521            i5 * stride[3] + i6 * stride[4] ;
00522   }
00523 
00524   template< typename isType , typename iType >
00525   static iType op( const isType * const stride ,
00526                    const iType & i1 , const iType & i2 ,
00527                    const iType & i3 , const iType & i4 ,
00528                    const iType & i5 )
00529   {
00530     SHARDS_ARRAY_CHECK(check_indices(false,5,stride,i1,i2,i3,i4,i5));
00531     return i1             + i2 * stride[0] +
00532            i3 * stride[1] + i4 * stride[2] +
00533            i5 * stride[3] ;
00534   }
00535 
00536   template< typename isType , typename iType >
00537   static iType op( const isType * const stride ,
00538                    const iType & i1 , const iType & i2 ,
00539                    const iType & i3 , const iType & i4 )
00540   {
00541     SHARDS_ARRAY_CHECK(check_indices(false,4,stride,i1,i2,i3,i4));
00542     return i1             + i2 * stride[0] +
00543            i3 * stride[1] + i4 * stride[2] ;
00544   }
00545 
00546   template< typename isType , typename iType >
00547   static iType op( const isType * const stride ,
00548                    const iType & i1 , const iType & i2 ,
00549                    const iType & i3 )
00550   {
00551     SHARDS_ARRAY_CHECK(check_indices(false,3,stride,i1,i2,i3));
00552     return i1 + i2 * stride[0] + i3 * stride[1] ;
00553   }
00554 
00555   template< typename isType , typename iType >
00556   static iType op( const isType * const stride ,
00557                    const iType & i1 , const iType & i2 )
00558   {
00559     SHARDS_ARRAY_CHECK(check_indices(false,2,stride,i1,i2));
00560     return i1 + i2 * stride[0] ;
00561   }
00562 
00563   template< typename isType , typename iType >
00564   static iType op( const isType * const SHARDS_ARRAY_CHECK( stride ) ,
00565                    const iType & i1 )
00566   {
00567     SHARDS_ARRAY_CHECK(check_indices(false,1,stride,i1));
00568     return i1 ;
00569   }
00570 };
00571 
00572 //----------------------------------------------------------------------
00573 
00574 template<>
00575 struct Offset<NaturalOrder> {
00576 
00577   template< typename isType , typename iType >
00578   static iType op( const isType * const stride ,
00579                    const iType & i1 , const iType & i2 ,
00580                    const iType & i3 , const iType & i4 ,
00581                    const iType & i5 , const iType & i6 ,
00582                    const iType & i7 , const iType & i8 )
00583   {
00584     SHARDS_ARRAY_CHECK(check_indices(true,8,stride,i1,i2,i3,i4,i5,i6,i7,i8));
00585     return i8             + i7 * stride[0] +
00586            i6 * stride[1] + i5 * stride[2] +
00587            i4 * stride[3] + i3 * stride[4] +
00588            i2 * stride[5] + i1 * stride[6] ;
00589   }
00590 
00591   template< typename isType , typename iType >
00592   static iType op( const isType * const stride ,
00593                    const iType & i1 , const iType & i2 ,
00594                    const iType & i3 , const iType & i4 ,
00595                    const iType & i5 , const iType & i6 ,
00596                    const iType & i7 )
00597   {
00598     SHARDS_ARRAY_CHECK(check_indices(true,7,stride,i1,i2,i3,i4,i5,i6,i7));
00599     return i7             + i6 * stride[0] +
00600            i5 * stride[1] + i4 * stride[2] +
00601            i3 * stride[3] + i2 * stride[4] +
00602            i1 * stride[5] ;
00603   }
00604 
00605   template< typename isType , typename iType >
00606   static iType op( const isType * const stride ,
00607                    const iType & i1 , const iType & i2 ,
00608                    const iType & i3 , const iType & i4 ,
00609                    const iType & i5 , const iType & i6 )
00610   {
00611     SHARDS_ARRAY_CHECK(check_indices(true,6,stride,i1,i2,i3,i4,i5,i6));
00612     return i6             + i5 * stride[0] +
00613            i4 * stride[1] + i3 * stride[2] +
00614            i2 * stride[3] + i1 * stride[4] ;
00615   }
00616 
00617   template< typename isType , typename iType >
00618   static iType op( const isType * const stride ,
00619                    const iType & i1 , const iType & i2 ,
00620                    const iType & i3 , const iType & i4 ,
00621                    const iType & i5 )
00622   {
00623     SHARDS_ARRAY_CHECK(check_indices(true,5,stride,i1,i2,i3,i4,i5));
00624     return i5             + i4 * stride[0] +
00625            i3 * stride[1] + i2 * stride[2] +
00626            i1 * stride[3] ;
00627   }
00628 
00629   template< typename isType , typename iType >
00630   static iType op( const isType * const stride ,
00631                    const iType & i1 , const iType & i2 ,
00632                    const iType & i3 , const iType & i4 )
00633   {
00634     SHARDS_ARRAY_CHECK(check_indices(true,4,stride,i1,i2,i3,i4));
00635     return i4             + i3 * stride[0] +
00636            i2 * stride[1] + i1 * stride[2] ;
00637   }
00638 
00639   template< typename isType , typename iType >
00640   static iType op( const isType * const stride ,
00641                    const iType & i1 , const iType & i2 ,
00642                    const iType & i3 )
00643   {
00644     SHARDS_ARRAY_CHECK(check_indices(true,3,stride,i1,i2,i3));
00645     return i3 + i2 * stride[0] + i1 * stride[1] ;
00646   }
00647 
00648   template< typename isType , typename iType >
00649   static iType op( const isType * const stride ,
00650                    const iType & i1 , const iType & i2 )
00651   {
00652     SHARDS_ARRAY_CHECK(check_indices(true,2,stride,i1,i2));
00653     return i2 + i1 * stride[0] ;
00654   }
00655 
00656   template< typename isType , typename iType >
00657   static iType op( const isType * const SHARDS_ARRAY_CHECK( stride ) ,
00658                    const iType & i1 )
00659   {
00660     SHARDS_ARRAY_CHECK(check_indices(true,1,stride,i1));
00661     return i1 ;
00662   }
00663 };
00664 
00665 //----------------------------------------------------------------------
00666 //----------------------------------------------------------------------
00667 
00668 template< typename Scalar , ArrayOrder Order ,
00669           class Tag1 , class Tag2 , class Tag3 , class Tag4 ,
00670           class Tag5 , class Tag6 , class Tag7 , class Tag8 >
00671 struct Helper ;
00672 
00673 //----------------------------------------------------------------------
00676 template< typename Scalar ,
00677           class Tag1 , class Tag2 , class Tag3 , class Tag4 ,
00678           class Tag5 , class Tag6 , class Tag7 , class Tag8 >
00679 struct Helper<Scalar,NaturalOrder,Tag1,Tag2,Tag3,Tag4,Tag5,Tag6,Tag7,Tag8>
00680 {
00681   typedef
00682     Array<Scalar,FortranOrder,Tag8,Tag7,Tag6,Tag5,Tag4,Tag3,Tag2,Tag1>
00683       reverse ;
00684 
00685   typedef
00686     Array<Scalar,NaturalOrder,Tag2,Tag3,Tag4,Tag5,Tag6,Tag7,Tag8,void>
00687       truncate ;
00688 
00689   enum { Rank = 8 };
00690 
00691   static bool verify( const int_t rank , const ArrayDimTag * const tags[] )
00692     {
00693       return rank    == Rank &&
00694              tags[0] == & Tag8::tag() &&
00695              tags[1] == & Tag7::tag() &&
00696              tags[2] == & Tag6::tag() &&
00697              tags[3] == & Tag5::tag() &&
00698              tags[4] == & Tag4::tag() &&
00699              tags[5] == & Tag3::tag() &&
00700              tags[6] == & Tag2::tag() &&
00701              tags[7] == & Tag1::tag() ;
00702     }
00703 
00704   static void assign_tags( const ArrayDimTag * tags[] )
00705     {
00706       tags[0] = & Tag8::tag();
00707       tags[1] = & Tag7::tag();
00708       tags[2] = & Tag6::tag();
00709       tags[3] = & Tag5::tag();
00710       tags[4] = & Tag4::tag();
00711       tags[5] = & Tag3::tag();
00712       tags[6] = & Tag2::tag();
00713       tags[7] = & Tag1::tag();
00714     }
00715 
00716   template< typename iType >
00717   static void assign( iType * stride )
00718     {
00719         stride[7] = Tag1::Size * (
00720         stride[6] = Tag2::Size * (
00721         stride[5] = Tag3::Size * (
00722         stride[4] = Tag4::Size * (
00723         stride[3] = Tag5::Size * (
00724         stride[2] = Tag6::Size * (
00725         stride[1] = Tag7::Size * (
00726         stride[0] = Tag8::Size )))))));
00727     }
00728 
00729   template< typename iType >
00730   static void assign( iType * stride ,
00731                       const iType & n1 )
00732     {
00733         stride[7] = n1 * (
00734         stride[6] = Tag2::Size * (
00735         stride[5] = Tag3::Size * (
00736         stride[4] = Tag4::Size * (
00737         stride[3] = Tag5::Size * (
00738         stride[2] = Tag6::Size * (
00739         stride[1] = Tag7::Size * (
00740         stride[0] = Tag8::Size )))))));
00741     }
00742 
00743   template< typename iType >
00744   static void assign( iType * stride ,
00745                       const iType & n1 ,
00746                       const iType & n2 )
00747     {
00748         stride[7] = n1 * (
00749         stride[6] = n2 * (
00750         stride[5] = Tag3::Size * (
00751         stride[4] = Tag4::Size * (
00752         stride[3] = Tag5::Size * (
00753         stride[2] = Tag6::Size * (
00754         stride[1] = Tag7::Size * (
00755         stride[0] = Tag8::Size )))))));
00756     }
00757 
00758   template< typename iType >
00759   static void assign( iType * stride ,
00760                       const iType & n1 ,
00761                       const iType & n2 ,
00762                       const iType & n3 )
00763     {
00764         stride[7] = n1 * (
00765         stride[6] = n2 * (
00766         stride[5] = n3 * (
00767         stride[4] = Tag4::Size * (
00768         stride[3] = Tag5::Size * (
00769         stride[2] = Tag6::Size * (
00770         stride[1] = Tag7::Size * (
00771         stride[0] = Tag8::Size )))))));
00772     }
00773 
00774   template< typename iType >
00775   static void assign( iType * stride ,
00776                       const iType & n1 ,
00777                       const iType & n2 ,
00778                       const iType & n3 ,
00779                       const iType & n4 )
00780     {
00781         stride[7] = n1 * (
00782         stride[6] = n2 * (
00783         stride[5] = n3 * (
00784         stride[4] = n4 * (
00785         stride[3] = Tag5::Size * (
00786         stride[2] = Tag6::Size * (
00787         stride[1] = Tag7::Size * (
00788         stride[0] = Tag8::Size )))))));
00789     }
00790 
00791   template< typename iType >
00792   static void assign( iType * stride ,
00793                       const iType & n1 ,
00794                       const iType & n2 ,
00795                       const iType & n3 ,
00796                       const iType & n4 ,
00797                       const iType & n5 )
00798     {
00799         stride[7] = n1 * (
00800         stride[6] = n2 * (
00801         stride[5] = n3 * (
00802         stride[4] = n4 * (
00803         stride[3] = n5 * (
00804         stride[2] = Tag6::Size  * (
00805         stride[1] = Tag7::Size  * (
00806         stride[0] = Tag8::Size  )))))));
00807     }
00808 
00809   template< typename iType >
00810   static void assign( iType * stride ,
00811                       const iType & n1 ,
00812                       const iType & n2 ,
00813                       const iType & n3 ,
00814                       const iType & n4 ,
00815                       const iType & n5 ,
00816                       const iType & n6 )
00817     {
00818         stride[7] = n1 * (
00819         stride[6] = n2 * (
00820         stride[5] = n3 * (
00821         stride[4] = n4 * (
00822         stride[3] = n5 * (
00823         stride[2] = n6 * (
00824         stride[1] = Tag7::Size * (
00825         stride[0] = Tag8::Size )))))));
00826     }
00827 
00828   template< typename iType >
00829   static void assign( iType * stride ,
00830                       const iType & n1 ,
00831                       const iType & n2 ,
00832                       const iType & n3 ,
00833                       const iType & n4 ,
00834                       const iType & n5 ,
00835                       const iType & n6 ,
00836                       const iType & n7 )
00837     {
00838         stride[7] = n1 * (
00839         stride[6] = n2 * (
00840         stride[5] = n3 * (
00841         stride[4] = n4 * (
00842         stride[3] = n5 * (
00843         stride[2] = n6 * (
00844         stride[1] = n7 * (
00845         stride[0] = Tag8::Size )))))));
00846     }
00847 
00848   template< typename iType >
00849   static void assign( iType * stride ,
00850                       const iType & n1 ,
00851                       const iType & n2 ,
00852                       const iType & n3 ,
00853                       const iType & n4 ,
00854                       const iType & n5 ,
00855                       const iType & n6 ,
00856                       const iType & n7 ,
00857                       const iType & n8 )
00858     {
00859         stride[7] = n1 * (
00860         stride[6] = n2 * (
00861         stride[5] = n3 * (
00862         stride[4] = n4 * (
00863         stride[3] = n5 * (
00864         stride[2] = n6 * (
00865         stride[1] = n7 * (
00866         stride[0] = n8 )))))));
00867     }
00868 
00869   template< typename iType >
00870   static void assign( iType * stride ,
00871                       const iType * const dims )
00872     {
00873         stride[7] = dims[0] * (
00874         stride[6] = dims[1] * (
00875         stride[5] = dims[2] * (
00876         stride[4] = dims[3] * (
00877         stride[3] = dims[4] * (
00878         stride[2] = dims[5] * (
00879         stride[1] = dims[6] * (
00880         stride[0] = dims[7] )))))));
00881     }
00882 };
00883 
00884 template< typename Scalar ,
00885           class Tag1 , class Tag2 , class Tag3 , class Tag4 ,
00886           class Tag5 , class Tag6 , class Tag7 , class Tag8 >
00887 struct Helper<Scalar,FortranOrder,Tag1,Tag2,Tag3,Tag4,Tag5,Tag6,Tag7,Tag8>
00888 {
00889   typedef
00890     Array<Scalar,NaturalOrder,Tag8,Tag7,Tag6,Tag5,Tag4,Tag3,Tag2,Tag1>
00891       reverse ;
00892 
00893   typedef
00894     Array<Scalar,FortranOrder,Tag1,Tag2,Tag3,Tag4,Tag5,Tag6,Tag7,void>
00895       truncate ;
00896 
00897   enum { Rank = 8 };
00898 
00899   static bool verify( int_t rank , const ArrayDimTag * tags[] )
00900     {
00901       return rank == Rank &&
00902              tags[0] == & Tag1::tag() &&
00903              tags[1] == & Tag2::tag() &&
00904              tags[2] == & Tag3::tag() &&
00905              tags[3] == & Tag4::tag() &&
00906              tags[4] == & Tag5::tag() &&
00907              tags[5] == & Tag6::tag() &&
00908              tags[6] == & Tag7::tag() &&
00909              tags[7] == & Tag8::tag();
00910     }
00911 
00912   static void assign_tags( const ArrayDimTag * tags[] )
00913     {
00914       tags[0] = & Tag1::tag();
00915       tags[1] = & Tag2::tag();
00916       tags[2] = & Tag3::tag();
00917       tags[3] = & Tag4::tag();
00918       tags[4] = & Tag5::tag();
00919       tags[5] = & Tag6::tag();
00920       tags[6] = & Tag7::tag();
00921       tags[7] = & Tag8::tag();
00922     }
00923 
00924   template< typename iType >
00925   static void assign( iType * stride )
00926     {
00927         stride[7] = Tag8::Size * (
00928         stride[6] = Tag7::Size * (
00929         stride[5] = Tag6::Size * (
00930         stride[4] = Tag5::Size * (
00931         stride[3] = Tag4::Size * (
00932         stride[2] = Tag3::Size * (
00933         stride[1] = Tag2::Size * (
00934         stride[0] = Tag1::Size )))))));
00935     }
00936 
00937   template< typename iType >
00938   static void assign( iType * stride ,
00939                       const iType & n8 )
00940     {
00941         stride[7] = n8 * (
00942         stride[6] = Tag7::Size * (
00943         stride[5] = Tag6::Size * (
00944         stride[4] = Tag5::Size * (
00945         stride[3] = Tag4::Size * (
00946         stride[2] = Tag3::Size * (
00947         stride[1] = Tag2::Size * (
00948         stride[0] = Tag1::Size )))))));
00949     }
00950 
00951   template< typename iType >
00952   static void assign( iType * stride ,
00953                       const iType & n7 ,
00954                       const iType & n8 )
00955     {
00956         stride[7] = n8 * (
00957         stride[6] = n7 * (
00958         stride[5] = Tag6::Size * (
00959         stride[4] = Tag5::Size * (
00960         stride[3] = Tag4::Size * (
00961         stride[2] = Tag3::Size * (
00962         stride[1] = Tag2::Size * (
00963         stride[0] = Tag1::Size )))))));
00964     }
00965 
00966   template< typename iType >
00967   static void assign( iType * stride ,
00968                       const iType & n6 ,
00969                       const iType & n7 ,
00970                       const iType & n8 )
00971     {
00972         stride[7] = n8 * (
00973         stride[6] = n7 * (
00974         stride[5] = n6 * (
00975         stride[4] = Tag5::Size * (
00976         stride[3] = Tag4::Size * (
00977         stride[2] = Tag3::Size * (
00978         stride[1] = Tag2::Size * (
00979         stride[0] = Tag1::Size )))))));
00980     }
00981 
00982   template< typename iType >
00983   static void assign( iType * stride ,
00984                       const iType & n5 ,
00985                       const iType & n6 ,
00986                       const iType & n7 ,
00987                       const iType & n8 )
00988     {
00989         stride[7] = n8 * (
00990         stride[6] = n7 * (
00991         stride[5] = n6 * (
00992         stride[4] = n5 * (
00993         stride[3] = Tag4::Size * (
00994         stride[2] = Tag3::Size * (
00995         stride[1] = Tag2::Size * (
00996         stride[0] = Tag1::Size )))))));
00997     }
00998 
00999   template< typename iType >
01000   static void assign( iType * stride ,
01001                       const iType & n4 ,
01002                       const iType & n5 ,
01003                       const iType & n6 ,
01004                       const iType & n7 ,
01005                       const iType & n8 )
01006     {
01007         stride[7] = n8 * (
01008         stride[6] = n7 * (
01009         stride[5] = n6 * (
01010         stride[4] = n5 * (
01011         stride[3] = n4 * (
01012         stride[2] = Tag3::Size  * (
01013         stride[1] = Tag2::Size  * (
01014         stride[0] = Tag1::Size  )))))));
01015     }
01016 
01017   template< typename iType >
01018   static void assign( iType * stride ,
01019                       const iType & n3 ,
01020                       const iType & n4 ,
01021                       const iType & n5 ,
01022                       const iType & n6 ,
01023                       const iType & n7 ,
01024                       const iType & n8 )
01025     {
01026         stride[7] = n8 * (
01027         stride[6] = n7 * (
01028         stride[5] = n6 * (
01029         stride[4] = n5 * (
01030         stride[3] = n4 * (
01031         stride[2] = n3 * (
01032         stride[1] = Tag2::Size * (
01033         stride[0] = Tag1::Size )))))));
01034     }
01035 
01036   template< typename iType >
01037   static void assign( iType * stride ,
01038                       const iType & n2 ,
01039                       const iType & n3 ,
01040                       const iType & n4 ,
01041                       const iType & n5 ,
01042                       const iType & n6 ,
01043                       const iType & n7 ,
01044                       const iType & n8 )
01045     {
01046         stride[7] = n8 * (
01047         stride[6] = n7 * (
01048         stride[5] = n6 * (
01049         stride[4] = n5 * (
01050         stride[3] = n4 * (
01051         stride[2] = n3 * (
01052         stride[1] = n2 * (
01053         stride[0] = Tag1::Size )))))));
01054     }
01055 
01056   template< typename iType >
01057   static void assign( iType * stride ,
01058                       const iType & n1 ,
01059                       const iType & n2 ,
01060                       const iType & n3 ,
01061                       const iType & n4 ,
01062                       const iType & n5 ,
01063                       const iType & n6 ,
01064                       const iType & n7 ,
01065                       const iType & n8 )
01066     {
01067         stride[7] = n8 * (
01068         stride[6] = n7 * (
01069         stride[5] = n6 * (
01070         stride[4] = n5 * (
01071         stride[3] = n4 * (
01072         stride[2] = n3 * (
01073         stride[1] = n2 * (
01074         stride[0] = n1 )))))));
01075     }
01076 
01077   template< typename iType >
01078   static void assign( iType * stride ,
01079                       const iType * const dims )
01080     {
01081         stride[7] = dims[7] * (
01082         stride[6] = dims[6] * (
01083         stride[5] = dims[5] * (
01084         stride[4] = dims[4] * (
01085         stride[3] = dims[3] * (
01086         stride[2] = dims[2] * (
01087         stride[1] = dims[1] * (
01088         stride[0] = dims[0] )))))));
01089     }
01090 };
01091 
01092 //----------------------------------------------------------------------
01095 template< typename Scalar ,
01096           class Tag1 , class Tag2 , class Tag3 , class Tag4 ,
01097           class Tag5 , class Tag6 , class Tag7 >
01098 struct Helper<Scalar,NaturalOrder,Tag1,Tag2,Tag3,Tag4,Tag5,Tag6,Tag7,void>
01099 {
01100   typedef
01101     Array<Scalar,FortranOrder,Tag7,Tag6,Tag5,Tag4,Tag3,Tag2,Tag1,void>
01102       reverse ;
01103 
01104   typedef
01105     Array<Scalar,NaturalOrder,Tag2,Tag3,Tag4,Tag5,Tag6,Tag7,void,void>
01106       truncate ;
01107 
01108   template< class TagA >
01109   struct append {
01110     typedef
01111       Array<Scalar,NaturalOrder,TagA,Tag1,Tag2,Tag3,Tag4,Tag5,Tag6,Tag7>
01112         natural ;
01113 
01114     typedef
01115       Array<Scalar,FortranOrder,Tag7,Tag6,Tag5,Tag4,Tag3,Tag2,Tag1,TagA>
01116         fortran ;
01117 
01118     typedef  natural  type ;
01119     typedef  fortran  reverse ;
01120   };
01121 
01122   enum { Rank = 7 };
01123 
01124   static bool verify( int_t rank , const ArrayDimTag * tags[] )
01125     {
01126       return rank == Rank &&
01127              tags[0] == & Tag7::tag() &&
01128              tags[1] == & Tag6::tag() &&
01129              tags[2] == & Tag5::tag() &&
01130              tags[3] == & Tag4::tag() &&
01131              tags[4] == & Tag3::tag() &&
01132              tags[5] == & Tag2::tag() &&
01133              tags[6] == & Tag1::tag() ;
01134     }
01135 
01136   static void assign_tags( const ArrayDimTag * tags[] )
01137     {
01138       tags[0] = & Tag7::tag();
01139       tags[1] = & Tag6::tag();
01140       tags[2] = & Tag5::tag();
01141       tags[3] = & Tag4::tag();
01142       tags[4] = & Tag3::tag();
01143       tags[5] = & Tag2::tag();
01144       tags[6] = & Tag1::tag();
01145       tags[7] = NULL ;
01146     }
01147 
01148   template< typename iType >
01149   static void assign( iType * stride )
01150     {
01151       stride[7] = 0 ;
01152       stride[6] = Tag1::Size * (
01153       stride[5] = Tag2::Size * (
01154       stride[4] = Tag3::Size * (
01155       stride[3] = Tag4::Size * (
01156       stride[2] = Tag5::Size * (
01157       stride[1] = Tag6::Size * (
01158       stride[0] = Tag7::Size ))))));
01159     }
01160 
01161   template< typename iType >
01162   static void assign( iType * stride ,
01163                       const iType & n1 )
01164     {
01165       stride[7] = 0 ;
01166       stride[6] = n1 * (
01167       stride[5] = Tag2::Size * (
01168       stride[4] = Tag3::Size * (
01169       stride[3] = Tag4::Size * (
01170       stride[2] = Tag5::Size * (
01171       stride[1] = Tag6::Size * (
01172       stride[0] = Tag7::Size ))))));
01173     }
01174 
01175   template< typename iType >
01176   static void assign( iType * stride ,
01177                       const iType & n1 ,
01178                       const iType & n2 )
01179     {
01180       stride[7] = 0 ;
01181       stride[6] = n1 * (
01182       stride[5] = n2 * (
01183       stride[4] = Tag3::Size * (
01184       stride[3] = Tag4::Size * (
01185       stride[2] = Tag5::Size * (
01186       stride[1] = Tag6::Size * (
01187       stride[0] = Tag7::Size ))))));
01188     }
01189 
01190   template< typename iType >
01191   static void assign( iType * stride ,
01192                       const iType & n1 ,
01193                       const iType & n2 ,
01194                       const iType & n3 )
01195     {
01196       stride[7] = 0 ;
01197       stride[6] = n1 * (
01198       stride[5] = n2 * (
01199       stride[4] = n3 * (
01200       stride[3] = Tag4::Size * (
01201       stride[2] = Tag5::Size * (
01202       stride[1] = Tag6::Size * (
01203       stride[0] = Tag7::Size ))))));
01204     }
01205 
01206   template< typename iType >
01207   static void assign( iType * stride ,
01208                       const iType & n1 ,
01209                       const iType & n2 ,
01210                       const iType & n3 ,
01211                       const iType & n4 )
01212     {
01213       stride[7] = 0 ;
01214       stride[6] = n1 * (
01215       stride[5] = n2 * (
01216       stride[4] = n3 * (
01217       stride[3] = n4 * (
01218       stride[2] = Tag5::Size * (
01219       stride[1] = Tag6::Size * (
01220       stride[0] = Tag7::Size ))))));
01221     }
01222 
01223   template< typename iType >
01224   static void assign( iType * stride ,
01225                       const iType & n1 ,
01226                       const iType & n2 ,
01227                       const iType & n3 ,
01228                       const iType & n4 ,
01229                       const iType & n5 )
01230     {
01231       stride[7] = 0 ;
01232       stride[6] = n1 * (
01233       stride[5] = n2 * (
01234       stride[4] = n3 * (
01235       stride[3] = n4 * (
01236       stride[2] = n5 * (
01237       stride[1] = Tag6::Size * (
01238       stride[0] = Tag7::Size ))))));
01239     }
01240 
01241   template< typename iType >
01242   static void assign( iType * stride ,
01243                       const iType & n1 ,
01244                       const iType & n2 ,
01245                       const iType & n3 ,
01246                       const iType & n4 ,
01247                       const iType & n5 ,
01248                       const iType & n6 )
01249     {
01250       stride[7] = 0 ;
01251       stride[6] = n1 * (
01252       stride[5] = n2 * (
01253       stride[4] = n3 * (
01254       stride[3] = n4 * (
01255       stride[2] = n5 * (
01256       stride[1] = n6 * (
01257       stride[0] = Tag7::Size ))))));
01258     }
01259 
01260   template< typename iType >
01261   static void assign( iType * stride ,
01262                       const iType & n1 ,
01263                       const iType & n2 ,
01264                       const iType & n3 ,
01265                       const iType & n4 ,
01266                       const iType & n5 ,
01267                       const iType & n6 ,
01268                       const iType & n7 )
01269     {
01270       stride[7] = 0 ;
01271       stride[6] = n1 * (
01272       stride[5] = n2 * (
01273       stride[4] = n3 * (
01274       stride[3] = n4 * (
01275       stride[2] = n5 * (
01276       stride[1] = n6 * (
01277       stride[0] = n7 ))))));
01278     }
01279 
01280   template< typename iType >
01281   static void assign( iType * stride ,
01282                       const iType * const dims )
01283     {
01284       stride[7] = 0 ;
01285       stride[6] = dims[0] * (
01286       stride[5] = dims[1] * (
01287       stride[4] = dims[2] * (
01288       stride[3] = dims[3] * (
01289       stride[2] = dims[4] * (
01290       stride[1] = dims[5] * (
01291       stride[0] = dims[6] ))))));
01292     }
01293 };
01294 
01295 template< typename Scalar ,
01296           class Tag1 , class Tag2 , class Tag3 , class Tag4 ,
01297           class Tag5 , class Tag6 , class Tag7 >
01298 struct Helper<Scalar,FortranOrder,Tag1,Tag2,Tag3,Tag4,Tag5,Tag6,Tag7,void>
01299 {
01300   typedef
01301     Array<Scalar,NaturalOrder,Tag7,Tag6,Tag5,Tag4,Tag3,Tag2,Tag1,void>
01302       reverse ;
01303 
01304   typedef
01305     Array<Scalar,FortranOrder,Tag1,Tag2,Tag3,Tag4,Tag5,Tag6,void,void>
01306       truncate ;
01307 
01308   template< class TagA >
01309   struct append {
01310     typedef
01311       Array<Scalar,FortranOrder,Tag1,Tag2,Tag3,Tag4,Tag5,Tag6,Tag7,TagA>
01312         fortran ;
01313 
01314     typedef
01315       Array<Scalar,NaturalOrder,TagA,Tag7,Tag6,Tag5,Tag4,Tag3,Tag2,Tag1>
01316         natural ;
01317 
01318     typedef  fortran  type ;
01319     typedef  natural  reverse ;
01320   };
01321 
01322   enum { Rank = 7 };
01323 
01324   static bool verify( int_t rank , const ArrayDimTag * tags[] )
01325     {
01326       return rank == Rank &&
01327              tags[0] == & Tag1::tag() &&
01328              tags[1] == & Tag2::tag() &&
01329              tags[2] == & Tag3::tag() &&
01330              tags[3] == & Tag4::tag() &&
01331              tags[4] == & Tag5::tag() &&
01332              tags[5] == & Tag6::tag() &&
01333              tags[6] == & Tag7::tag();
01334     }
01335 
01336   static void assign_tags( const ArrayDimTag * tags[] )
01337     {
01338       tags[0] = & Tag1::tag();
01339       tags[1] = & Tag2::tag();
01340       tags[2] = & Tag3::tag();
01341       tags[3] = & Tag4::tag();
01342       tags[4] = & Tag5::tag();
01343       tags[5] = & Tag6::tag();
01344       tags[6] = & Tag7::tag();
01345       tags[7] = NULL ;
01346     }
01347 
01348   template< typename iType >
01349   static void assign( iType * stride )
01350     {
01351       stride[7] = 0 ;
01352       stride[6] = Tag7::Size * (
01353       stride[5] = Tag6::Size * (
01354       stride[4] = Tag5::Size * (
01355       stride[3] = Tag4::Size * (
01356       stride[2] = Tag3::Size * (
01357       stride[1] = Tag2::Size * (
01358       stride[0] = Tag1::Size ))))));
01359     }
01360 
01361   template< typename iType >
01362   static void assign( iType * stride ,
01363                       const iType & n7 )
01364     {
01365       stride[7] = 0 ;
01366       stride[6] = n7 * (
01367       stride[5] = Tag6::Size * (
01368       stride[4] = Tag5::Size * (
01369       stride[3] = Tag4::Size * (
01370       stride[2] = Tag3::Size * (
01371       stride[1] = Tag2::Size * (
01372       stride[0] = Tag1::Size ))))));
01373     }
01374 
01375   template< typename iType >
01376   static void assign( iType * stride ,
01377                       const iType & n6 ,
01378                       const iType & n7 )
01379     {
01380       stride[7] = 0 ;
01381       stride[6] = n7 * (
01382       stride[5] = n6 * (
01383       stride[4] = Tag5::Size * (
01384       stride[3] = Tag4::Size * (
01385       stride[2] = Tag3::Size * (
01386       stride[1] = Tag2::Size * (
01387       stride[0] = Tag1::Size ))))));
01388     }
01389 
01390   template< typename iType >
01391   static void assign( iType * stride ,
01392                       const iType & n5 ,
01393                       const iType & n6 ,
01394                       const iType & n7 )
01395     {
01396       stride[7] = 0 ;
01397       stride[6] = n7 * (
01398       stride[5] = n6 * (
01399       stride[4] = n5 * (
01400       stride[3] = Tag4::Size * (
01401       stride[2] = Tag3::Size * (
01402       stride[1] = Tag2::Size * (
01403       stride[0] = Tag1::Size ))))));
01404     }
01405 
01406   template< typename iType >
01407   static void assign( iType * stride ,
01408                       const iType & n4 ,
01409                       const iType & n5 ,
01410                       const iType & n6 ,
01411                       const iType & n7 )
01412     {
01413       stride[7] = 0 ;
01414       stride[6] = n7 * (
01415       stride[5] = n6 * (
01416       stride[4] = n5 * (
01417       stride[3] = n4 * (
01418       stride[2] = Tag3::Size * (
01419       stride[1] = Tag2::Size * (
01420       stride[0] = Tag1::Size ))))));
01421     }
01422 
01423   template< typename iType >
01424   static void assign( iType * stride ,
01425                       const iType & n3 ,
01426                       const iType & n4 ,
01427                       const iType & n5 ,
01428                       const iType & n6 ,
01429                       const iType & n7 )
01430     {
01431       stride[7] = 0 ;
01432       stride[6] = n7 * (
01433       stride[5] = n6 * (
01434       stride[4] = n5 * (
01435       stride[3] = n4 * (
01436       stride[2] = n3 * (
01437       stride[1] = Tag2::Size * (
01438       stride[0] = Tag1::Size ))))));
01439     }
01440 
01441   template< typename iType >
01442   static void assign( iType * stride ,
01443                       const iType & n2 ,
01444                       const iType & n3 ,
01445                       const iType & n4 ,
01446                       const iType & n5 ,
01447                       const iType & n6 ,
01448                       const iType & n7 )
01449     {
01450       stride[7] = 0 ;
01451       stride[6] = n7 * (
01452       stride[5] = n6 * (
01453       stride[4] = n5 * (
01454       stride[3] = n4 * (
01455       stride[2] = n3 * (
01456       stride[1] = n2 * (
01457       stride[0] = Tag1::Size ))))));
01458     }
01459 
01460   template< typename iType >
01461   static void assign( iType * stride ,
01462                       const iType & n1 ,
01463                       const iType & n2 ,
01464                       const iType & n3 ,
01465                       const iType & n4 ,
01466                       const iType & n5 ,
01467                       const iType & n6 ,
01468                       const iType & n7 )
01469     {
01470       stride[7] = 0 ;
01471       stride[6] = n7 * (
01472       stride[5] = n6 * (
01473       stride[4] = n5 * (
01474       stride[3] = n4 * (
01475       stride[2] = n3 * (
01476       stride[1] = n2 * (
01477       stride[0] = n1 ))))));
01478     }
01479 
01480   template< typename iType >
01481   static void assign( iType * stride ,
01482                       const iType * const dims )
01483     {
01484       stride[7] = 0 ;
01485       stride[6] = dims[6] * (
01486       stride[5] = dims[5] * (
01487       stride[4] = dims[4] * (
01488       stride[3] = dims[3] * (
01489       stride[2] = dims[2] * (
01490       stride[1] = dims[1] * (
01491       stride[0] = dims[0] ))))));
01492    }
01493 };
01494 
01495 //----------------------------------------------------------------------
01498 template< typename Scalar ,
01499           class Tag1 , class Tag2 , class Tag3 , class Tag4 ,
01500           class Tag5 , class Tag6 >
01501 struct Helper<Scalar,NaturalOrder,Tag1,Tag2,Tag3,Tag4,Tag5,Tag6,void,void>
01502 {
01503   typedef
01504     Array<Scalar,FortranOrder,Tag6,Tag5,Tag4,Tag3,Tag2,Tag1,void,void>
01505       reverse ;
01506 
01507   typedef
01508     Array<Scalar,NaturalOrder,Tag2,Tag3,Tag4,Tag5,Tag6,void,void,void>
01509       truncate ;
01510 
01511   template< class TagA >
01512   struct append {
01513     typedef
01514       Array<Scalar,NaturalOrder,TagA,Tag1,Tag2,Tag3,Tag4,Tag5,Tag6,void>
01515         natural ;
01516 
01517     typedef
01518       Array<Scalar,FortranOrder,Tag6,Tag5,Tag4,Tag3,Tag2,Tag1,TagA,void>
01519         fortran ;
01520 
01521     typedef  natural  type ;
01522     typedef  fortran  reverse ;
01523   };
01524 
01525   enum { Rank = 6 };
01526 
01527   static bool verify( int_t rank , const ArrayDimTag * tags[] )
01528     {
01529       return rank == Rank &&
01530              tags[0] == & Tag6::tag() &&
01531              tags[1] == & Tag5::tag() &&
01532              tags[2] == & Tag4::tag() &&
01533              tags[3] == & Tag3::tag() &&
01534              tags[4] == & Tag2::tag() &&
01535              tags[5] == & Tag1::tag();
01536     }
01537 
01538   static void assign_tags( const ArrayDimTag * tags[] )
01539     {
01540       tags[0] = & Tag6::tag();
01541       tags[1] = & Tag5::tag();
01542       tags[2] = & Tag4::tag();
01543       tags[3] = & Tag3::tag();
01544       tags[4] = & Tag2::tag();
01545       tags[5] = & Tag1::tag();
01546       tags[6] = NULL ;
01547       tags[7] = NULL ;
01548     }
01549 
01550   template< typename iType >
01551   static void assign( iType * stride )
01552     {
01553       stride[7] = 0 ;
01554       stride[6] = 0 ;
01555       stride[5] = Tag1::Size * (
01556       stride[4] = Tag2::Size * (
01557       stride[3] = Tag3::Size * (
01558       stride[2] = Tag4::Size * (
01559       stride[1] = Tag5::Size * (
01560       stride[0] = Tag6::Size )))));
01561     }
01562 
01563   template< typename iType >
01564   static void assign( iType * stride ,
01565                       const iType & n1 )
01566     {
01567       stride[7] = 0 ;
01568       stride[6] = 0 ;
01569       stride[5] = n1 * (
01570       stride[4] = Tag2::Size * (
01571       stride[3] = Tag3::Size * (
01572       stride[2] = Tag4::Size * (
01573       stride[1] = Tag5::Size * (
01574       stride[0] = Tag6::Size )))));
01575     }
01576 
01577   template< typename iType >
01578   static void assign( iType * stride ,
01579                       const iType & n1 ,
01580                       const iType & n2 )
01581     {
01582       stride[7] = 0 ;
01583       stride[6] = 0 ;
01584       stride[5] = n1 * (
01585       stride[4] = n2 * (
01586       stride[3] = Tag3::Size * (
01587       stride[2] = Tag4::Size * (
01588       stride[1] = Tag5::Size * (
01589       stride[0] = Tag6::Size )))));
01590     }
01591 
01592   template< typename iType >
01593   static void assign( iType * stride ,
01594                       const iType & n1 ,
01595                       const iType & n2 ,
01596                       const iType & n3 )
01597     {
01598       stride[7] = 0 ;
01599       stride[6] = 0 ;
01600       stride[5] = n1 * (
01601       stride[4] = n2 * (
01602       stride[3] = n3 * (
01603       stride[2] = Tag4::Size * (
01604       stride[1] = Tag5::Size * (
01605       stride[0] = Tag6::Size )))));
01606     }
01607 
01608   template< typename iType >
01609   static void assign( iType * stride ,
01610                       const iType & n1 ,
01611                       const iType & n2 ,
01612                       const iType & n3 ,
01613                       const iType & n4 )
01614     {
01615       stride[7] = 0 ;
01616       stride[6] = 0 ;
01617       stride[5] = n1 * (
01618       stride[4] = n2 * (
01619       stride[3] = n3 * (
01620       stride[2] = n4 * (
01621       stride[1] = Tag5::Size * (
01622       stride[0] = Tag6::Size )))));
01623     }
01624 
01625   template< typename iType >
01626   static void assign( iType * stride ,
01627                       const iType & n1 ,
01628                       const iType & n2 ,
01629                       const iType & n3 ,
01630                       const iType & n4 ,
01631                       const iType & n5 )
01632     {
01633       stride[7] = 0 ;
01634       stride[6] = 0 ;
01635       stride[5] = n1 * (
01636       stride[4] = n2 * (
01637       stride[3] = n3 * (
01638       stride[2] = n4 * (
01639       stride[1] = n5 * (
01640       stride[0] = Tag6::Size )))));
01641     }
01642 
01643   template< typename iType >
01644   static void assign( iType * stride ,
01645                       const iType & n1 ,
01646                       const iType & n2 ,
01647                       const iType & n3 ,
01648                       const iType & n4 ,
01649                       const iType & n5 ,
01650                       const iType & n6 )
01651     {
01652       stride[7] = 0 ;
01653       stride[6] = 0 ;
01654       stride[5] = n1 * (
01655       stride[4] = n2 * (
01656       stride[3] = n3 * (
01657       stride[2] = n4 * (
01658       stride[1] = n5 * (
01659       stride[0] = n6 )))));
01660     }
01661 
01662   template< typename iType >
01663   static void assign( iType * stride ,
01664                       const iType * const dims )
01665     {
01666       stride[7] = 0 ;
01667       stride[6] = 0 ;
01668       stride[5] = dims[0] * (
01669       stride[4] = dims[1] * (
01670       stride[3] = dims[2] * (
01671       stride[2] = dims[3] * (
01672       stride[1] = dims[4] * (
01673       stride[0] = dims[5] )))));
01674     }
01675 };
01676 
01677 template< typename Scalar ,
01678           class Tag1 , class Tag2 , class Tag3 , class Tag4 ,
01679           class Tag5 , class Tag6 >
01680 struct Helper<Scalar,FortranOrder,Tag1,Tag2,Tag3,Tag4,Tag5,Tag6,void,void>
01681 {
01682   typedef
01683     Array<Scalar,NaturalOrder,Tag6,Tag5,Tag4,Tag3,Tag2,Tag1,void,void>
01684       reverse ;
01685 
01686   typedef
01687     Array<Scalar,FortranOrder,Tag1,Tag2,Tag3,Tag4,Tag5,void,void,void>
01688       truncate ;
01689 
01690   template< class TagA >
01691   struct append {
01692     typedef
01693       Array<Scalar,FortranOrder,Tag1,Tag2,Tag3,Tag4,Tag5,Tag6,TagA,void>
01694         fortran ;
01695 
01696     typedef
01697       Array<Scalar,NaturalOrder,TagA,Tag6,Tag5,Tag4,Tag3,Tag2,Tag1,void>
01698         natural ;
01699 
01700     typedef  fortran  type ;
01701     typedef  natural  reverse ;
01702   };
01703 
01704   enum { Rank = 6 };
01705 
01706   static bool verify( int_t rank , const ArrayDimTag * tags[] )
01707     {
01708       return rank == Rank &&
01709              tags[0] == & Tag1::tag() &&
01710              tags[1] == & Tag2::tag() &&
01711              tags[2] == & Tag3::tag() &&
01712              tags[3] == & Tag4::tag() &&
01713              tags[4] == & Tag5::tag() &&
01714              tags[5] == & Tag6::tag();
01715     }
01716 
01717   static void assign_tags( const ArrayDimTag * tags[] )
01718     {
01719       tags[0] = & Tag1::tag();
01720       tags[1] = & Tag2::tag();
01721       tags[2] = & Tag3::tag();
01722       tags[3] = & Tag4::tag();
01723       tags[4] = & Tag5::tag();
01724       tags[5] = & Tag6::tag();
01725       tags[6] = NULL ;
01726       tags[7] = NULL ;
01727     }
01728 
01729   template< typename iType >
01730   static void assign( iType * stride )
01731     {
01732       stride[7] = 0 ;
01733       stride[6] = 0 ;
01734       stride[5] = Tag6::Size * (
01735       stride[4] = Tag5::Size * (
01736       stride[3] = Tag4::Size * (
01737       stride[2] = Tag3::Size * (
01738       stride[1] = Tag2::Size * (
01739       stride[0] = Tag1::Size )))));
01740     }
01741 
01742   template< typename iType >
01743   static void assign( iType * stride ,
01744                       const iType & n6 )
01745     {
01746       stride[7] = 0 ;
01747       stride[6] = 0 ;
01748       stride[5] = n6 * (
01749       stride[4] = Tag5::Size * (
01750       stride[3] = Tag4::Size * (
01751       stride[2] = Tag3::Size * (
01752       stride[1] = Tag2::Size * (
01753       stride[0] = Tag1::Size )))));
01754     }
01755 
01756   template< typename iType >
01757   static void assign( iType * stride ,
01758                       const iType & n5 ,
01759                       const iType & n6 )
01760     {
01761       stride[7] = 0 ;
01762       stride[6] = 0 ;
01763       stride[5] = n6 * (
01764       stride[4] = n5 * (
01765       stride[3] = Tag4::Size * (
01766       stride[2] = Tag3::Size * (
01767       stride[1] = Tag2::Size * (
01768       stride[0] = Tag1::Size )))));
01769     }
01770 
01771   template< typename iType >
01772   static void assign( iType * stride ,
01773                       const iType & n4 ,
01774                       const iType & n5 ,
01775                       const iType & n6 )
01776     {
01777       stride[7] = 0 ;
01778       stride[6] = 0 ;
01779       stride[5] = n6 * (
01780       stride[4] = n5 * (
01781       stride[3] = n4 * (
01782       stride[2] = Tag3::Size * (
01783       stride[1] = Tag2::Size * (
01784       stride[0] = Tag1::Size )))));
01785     }
01786 
01787   template< typename iType >
01788   static void assign( iType * stride ,
01789                       const iType & n3 ,
01790                       const iType & n4 ,
01791                       const iType & n5 ,
01792                       const iType & n6 )
01793     {
01794       stride[7] = 0 ;
01795       stride[6] = 0 ;
01796       stride[5] = n6 * (
01797       stride[4] = n5 * (
01798       stride[3] = n4 * (
01799       stride[2] = n3 * (
01800       stride[1] = Tag2::Size * (
01801       stride[0] = Tag1::Size )))));
01802     }
01803 
01804   template< typename iType >
01805   static void assign( iType * stride ,
01806                       const iType & n2 ,
01807                       const iType & n3 ,
01808                       const iType & n4 ,
01809                       const iType & n5 ,
01810                       const iType & n6 )
01811     {
01812       stride[7] = 0 ;
01813       stride[6] = 0 ;
01814       stride[5] = n6 * (
01815       stride[4] = n5 * (
01816       stride[3] = n4 * (
01817       stride[2] = n3 * (
01818       stride[1] = n2 * (
01819       stride[0] = Tag1::Size )))));
01820     }
01821 
01822   template< typename iType >
01823   static void assign( iType * stride ,
01824                       const iType & n1 ,
01825                       const iType & n2 ,
01826                       const iType & n3 ,
01827                       const iType & n4 ,
01828                       const iType & n5 ,
01829                       const iType & n6 )
01830     {
01831       stride[7] = 0 ;
01832       stride[6] = 0 ;
01833       stride[5] = n6 * (
01834       stride[4] = n5 * (
01835       stride[3] = n4 * (
01836       stride[2] = n3 * (
01837       stride[1] = n2 * (
01838       stride[0] = n1 )))));
01839     }
01840 
01841   template< typename iType >
01842   static void assign( iType * stride ,
01843                       const iType * const dims )
01844     {
01845       stride[7] = 0 ;
01846       stride[6] = 0 ;
01847       stride[5] = dims[5] * (
01848       stride[4] = dims[4] * (
01849       stride[3] = dims[3] * (
01850       stride[2] = dims[2] * (
01851       stride[1] = dims[1] * (
01852       stride[0] = dims[0] )))));
01853    }
01854 };
01855 
01856 //----------------------------------------------------------------------
01859 template< typename Scalar ,
01860           class Tag1 , class Tag2 , class Tag3 , class Tag4 , class Tag5 >
01861 struct Helper<Scalar,NaturalOrder,Tag1,Tag2,Tag3,Tag4,Tag5,void,void,void>
01862 {
01863   typedef
01864     Array<Scalar,FortranOrder,Tag5,Tag4,Tag3,Tag2,Tag1,void,void,void>
01865       reverse ;
01866 
01867   typedef
01868     Array<Scalar,NaturalOrder,Tag2,Tag3,Tag4,Tag5,void,void,void,void>
01869       truncate ;
01870 
01871   template< class TagA >
01872   struct append {
01873     typedef
01874       Array<Scalar,NaturalOrder,TagA,Tag1,Tag2,Tag3,Tag4,Tag5,void,void>
01875         natural ;
01876 
01877     typedef
01878       Array<Scalar,FortranOrder,Tag5,Tag4,Tag3,Tag2,Tag1,TagA,void,void>
01879         fortran ;
01880 
01881     typedef  natural  type ;
01882     typedef  fortran  reverse ;
01883   };
01884 
01885   enum { Rank = 5 };
01886 
01887   static bool verify( int_t rank , const ArrayDimTag * tags[] )
01888     {
01889       return rank == Rank &&
01890              tags[0] == & Tag5::tag() &&
01891              tags[1] == & Tag4::tag() &&
01892              tags[2] == & Tag3::tag() &&
01893              tags[3] == & Tag2::tag() &&
01894              tags[4] == & Tag1::tag();
01895     }
01896 
01897   static void assign_tags( const ArrayDimTag * tags[] )
01898     {
01899       tags[0] = & Tag5::tag();
01900       tags[1] = & Tag4::tag();
01901       tags[2] = & Tag3::tag();
01902       tags[3] = & Tag2::tag();
01903       tags[4] = & Tag1::tag();
01904       tags[5] = NULL ;
01905       tags[6] = NULL ;
01906       tags[7] = NULL ;
01907     }
01908 
01909   template< typename iType >
01910   static void assign( iType * stride )
01911     {
01912       stride[7] = 0 ;
01913       stride[6] = 0 ;
01914       stride[5] = 0 ;
01915       stride[4] = Tag1::Size * (
01916       stride[3] = Tag2::Size * (
01917       stride[2] = Tag3::Size * (
01918       stride[1] = Tag4::Size * (
01919       stride[0] = Tag5::Size ))));
01920     }
01921 
01922   template< typename iType >
01923   static void assign( iType * stride ,
01924                       const iType & n1 )
01925     {
01926       stride[7] = 0 ;
01927       stride[6] = 0 ;
01928       stride[5] = 0 ;
01929       stride[4] = n1 * (
01930       stride[3] = Tag2::Size * (
01931       stride[2] = Tag3::Size * (
01932       stride[1] = Tag4::Size * (
01933       stride[0] = Tag5::Size ))));
01934     }
01935 
01936   template< typename iType >
01937   static void assign( iType * stride ,
01938                       const iType & n1 ,
01939                       const iType & n2 )
01940     {
01941       stride[7] = 0 ;
01942       stride[6] = 0 ;
01943       stride[5] = 0 ;
01944       stride[4] = n1 * (
01945       stride[3] = n2 * (
01946       stride[2] = Tag3::Size * (
01947       stride[1] = Tag4::Size * (
01948       stride[0] = Tag5::Size ))));
01949     }
01950 
01951   template< typename iType >
01952   static void assign( iType * stride ,
01953                       const iType & n1 ,
01954                       const iType & n2 ,
01955                       const iType & n3 )
01956     {
01957       stride[7] = 0 ;
01958       stride[6] = 0 ;
01959       stride[5] = 0 ;
01960       stride[4] = n1 * (
01961       stride[3] = n2 * (
01962       stride[2] = n3 * (
01963       stride[1] = Tag4::Size * (
01964       stride[0] = Tag5::Size ))));
01965     }
01966 
01967   template< typename iType >
01968   static void assign( iType * stride ,
01969                       const iType & n1 ,
01970                       const iType & n2 ,
01971                       const iType & n3 ,
01972                       const iType & n4 )
01973     {
01974       stride[7] = 0 ;
01975       stride[6] = 0 ;
01976       stride[5] = 0 ;
01977       stride[4] = n1 * (
01978       stride[3] = n2 * (
01979       stride[2] = n3 * (
01980       stride[1] = n4 * (
01981       stride[0] = Tag5::Size ))));
01982     }
01983 
01984   template< typename iType >
01985   static void assign( iType * stride ,
01986                       const iType & n1 ,
01987                       const iType & n2 ,
01988                       const iType & n3 ,
01989                       const iType & n4 ,
01990                       const iType & n5 )
01991     {
01992       stride[7] = 0 ;
01993       stride[6] = 0 ;
01994       stride[5] = 0 ;
01995       stride[4] = n1 * (
01996       stride[3] = n2 * (
01997       stride[2] = n3 * (
01998       stride[1] = n4 * (
01999       stride[0] = n5 ))));
02000     }
02001 
02002   template< typename iType >
02003   static void assign( iType * stride ,
02004                       const iType * const dims )
02005     {
02006       stride[7] = 0 ;
02007       stride[6] = 0 ;
02008       stride[5] = 0 ;
02009       stride[4] = dims[0] * (
02010       stride[3] = dims[1] * (
02011       stride[2] = dims[2] * (
02012       stride[1] = dims[3] * (
02013       stride[0] = dims[4] ))));
02014     }
02015 };
02016 
02017 template< typename Scalar ,
02018           class Tag1 , class Tag2 , class Tag3 , class Tag4 , class Tag5 >
02019 struct Helper<Scalar,FortranOrder,Tag1,Tag2,Tag3,Tag4,Tag5,void,void,void>
02020 {
02021   typedef
02022     Array<Scalar,NaturalOrder,Tag5,Tag4,Tag3,Tag2,Tag1,void,void,void>
02023       reverse ;
02024 
02025   typedef
02026     Array<Scalar,FortranOrder,Tag1,Tag2,Tag3,Tag4,void,void,void,void>
02027       truncate ;
02028 
02029   template< class TagA >
02030   struct append {
02031     typedef
02032       Array<Scalar,FortranOrder,Tag1,Tag2,Tag3,Tag4,Tag5,TagA,void,void>
02033         fortran ;
02034 
02035     typedef
02036       Array<Scalar,NaturalOrder,TagA,Tag5,Tag4,Tag3,Tag2,Tag1,void,void>
02037         natural ;
02038 
02039     typedef  fortran  type ;
02040     typedef  natural  reverse ;
02041   };
02042 
02043   enum { Rank = 5 };
02044 
02045   static bool verify( int_t rank , const ArrayDimTag * tags[] )
02046     {
02047       return rank == Rank &&
02048              tags[0] == & Tag1::tag() &&
02049              tags[1] == & Tag2::tag() &&
02050              tags[2] == & Tag3::tag() &&
02051              tags[3] == & Tag4::tag() &&
02052              tags[4] == & Tag5::tag();
02053     }
02054 
02055   static void assign_tags( const ArrayDimTag * tags[] )
02056     {
02057       tags[0] = & Tag1::tag();
02058       tags[1] = & Tag2::tag();
02059       tags[2] = & Tag3::tag();
02060       tags[3] = & Tag4::tag();
02061       tags[4] = & Tag5::tag();
02062       tags[5] = NULL ;
02063       tags[6] = NULL ;
02064       tags[7] = NULL ;
02065     }
02066 
02067   template< typename iType >
02068   static void assign( iType * stride )
02069     {
02070       stride[7] = 0 ;
02071       stride[6] = 0 ;
02072       stride[5] = 0 ;
02073       stride[4] = Tag5::Size * (
02074       stride[3] = Tag4::Size * (
02075       stride[2] = Tag3::Size * (
02076       stride[1] = Tag2::Size * (
02077       stride[0] = Tag1::Size ))));
02078     }
02079 
02080   template< typename iType >
02081   static void assign( iType * stride ,
02082                       const iType & n5 )
02083     {
02084       stride[7] = 0 ;
02085       stride[6] = 0 ;
02086       stride[5] = 0 ;
02087       stride[4] = n5 * (
02088       stride[3] = Tag4::Size * (
02089       stride[2] = Tag3::Size * (
02090       stride[1] = Tag2::Size * (
02091       stride[0] = Tag1::Size ))));
02092     }
02093 
02094   template< typename iType >
02095   static void assign( iType * stride ,
02096                       const iType & n4 ,
02097                       const iType & n5 )
02098     {
02099       stride[7] = 0 ;
02100       stride[6] = 0 ;
02101       stride[5] = 0 ;
02102       stride[4] = n5 * (
02103       stride[3] = n4 * (
02104       stride[2] = Tag3::Size * (
02105       stride[1] = Tag2::Size * (
02106       stride[0] = Tag1::Size ))));
02107     }
02108 
02109   template< typename iType >
02110   static void assign( iType * stride ,
02111                       const iType & n3 ,
02112                       const iType & n4 ,
02113                       const iType & n5 )
02114     {
02115       stride[7] = 0 ;
02116       stride[6] = 0 ;
02117       stride[5] = 0 ;
02118       stride[4] = n5 * (
02119       stride[3] = n4 * (
02120       stride[2] = n3 * (
02121       stride[1] = Tag2::Size * (
02122       stride[0] = Tag1::Size ))));
02123     }
02124 
02125   template< typename iType >
02126   static void assign( iType * stride ,
02127                       const iType & n2 ,
02128                       const iType & n3 ,
02129                       const iType & n4 ,
02130                       const iType & n5 )
02131     {
02132       stride[7] = 0 ;
02133       stride[6] = 0 ;
02134       stride[5] = 0 ;
02135       stride[4] = n5 * (
02136       stride[3] = n4 * (
02137       stride[2] = n3 * (
02138       stride[1] = n2 * (
02139       stride[0] = Tag1::Size ))));
02140     }
02141 
02142   template< typename iType >
02143   static void assign( iType * stride ,
02144                       const iType & n1 ,
02145                       const iType & n2 ,
02146                       const iType & n3 ,
02147                       const iType & n4 ,
02148                       const iType & n5 )
02149     {
02150       stride[7] = 0 ;
02151       stride[6] = 0 ;
02152       stride[5] = 0 ;
02153       stride[4] = n5 * (
02154       stride[3] = n4 * (
02155       stride[2] = n3 * (
02156       stride[1] = n2 * (
02157       stride[0] = n1 ))));
02158     }
02159 
02160   template< typename iType >
02161   static void assign( iType * stride ,
02162                       const iType * const dims )
02163     {
02164       stride[7] = 0 ;
02165       stride[6] = 0 ;
02166       stride[5] = 0 ;
02167       stride[4] = dims[4] * (
02168       stride[3] = dims[3] * (
02169       stride[2] = dims[2] * (
02170       stride[1] = dims[1] * (
02171       stride[0] = dims[0] ))));
02172    }
02173 };
02174 
02175 //----------------------------------------------------------------------
02178 template< typename Scalar , class Tag1 , class Tag2 , class Tag3 , class Tag4 >
02179 struct Helper<Scalar,NaturalOrder,Tag1,Tag2,Tag3,Tag4,void,void,void,void>
02180 {
02181   typedef
02182     Array<Scalar,FortranOrder,Tag4,Tag3,Tag2,Tag1,void,void,void,void>
02183       reverse ;
02184 
02185   typedef
02186     Array<Scalar,NaturalOrder,Tag2,Tag3,Tag4,void,void,void,void,void>
02187       truncate ;
02188 
02189   template< class TagA >
02190   struct append {
02191     typedef
02192       Array<Scalar,NaturalOrder,TagA,Tag1,Tag2,Tag3,Tag4,void,void,void>
02193         natural ;
02194 
02195     typedef
02196       Array<Scalar,FortranOrder,Tag4,Tag3,Tag2,Tag1,TagA,void,void,void>
02197         fortran ;
02198 
02199     typedef  natural  type ;
02200     typedef  fortran  reverse ;
02201   };
02202 
02203   enum { Rank = 4 };
02204 
02205   static bool verify( int_t rank , const ArrayDimTag * tags[] )
02206     {
02207       return rank == Rank &&
02208              tags[0] == & Tag4::tag() &&
02209              tags[1] == & Tag3::tag() &&
02210              tags[2] == & Tag2::tag() &&
02211              tags[3] == & Tag1::tag();
02212     }
02213 
02214   static void assign_tags( const ArrayDimTag * tags[] )
02215     {
02216       tags[0] = & Tag4::tag();
02217       tags[1] = & Tag3::tag();
02218       tags[2] = & Tag2::tag();
02219       tags[3] = & Tag1::tag();
02220       tags[4] = NULL ;
02221       tags[5] = NULL ;
02222       tags[6] = NULL ;
02223       tags[7] = NULL ;
02224     }
02225 
02226   template< typename iType >
02227   static void assign( iType * stride )
02228     {
02229       stride[7] = 0 ;
02230       stride[6] = 0 ;
02231       stride[5] = 0 ;
02232       stride[4] = 0 ;
02233       stride[3] = Tag1::Size * (
02234       stride[2] = Tag2::Size * (
02235       stride[1] = Tag3::Size * (
02236       stride[0] = Tag4::Size )));
02237     }
02238 
02239   template< typename iType >
02240   static void assign( iType * stride ,
02241                       const iType & n1 )
02242     {
02243       stride[7] = 0 ;
02244       stride[6] = 0 ;
02245       stride[5] = 0 ;
02246       stride[4] = 0 ;
02247       stride[3] = n1 * (
02248       stride[2] = Tag2::Size * (
02249       stride[1] = Tag3::Size * (
02250       stride[0] = Tag4::Size )));
02251     }
02252 
02253   template< typename iType >
02254   static void assign( iType * stride ,
02255                       const iType & n1 ,
02256                       const iType & n2 )
02257     {
02258       stride[7] = 0 ;
02259       stride[6] = 0 ;
02260       stride[5] = 0 ;
02261       stride[4] = 0 ;
02262       stride[3] = n1 * (
02263       stride[2] = n2 * (
02264       stride[1] = Tag3::Size * (
02265       stride[0] = Tag4::Size )));
02266     }
02267 
02268   template< typename iType >
02269   static void assign( iType * stride ,
02270                       const iType & n1 ,
02271                       const iType & n2 ,
02272                       const iType & n3 )
02273     {
02274       stride[7] = 0 ;
02275       stride[6] = 0 ;
02276       stride[5] = 0 ;
02277       stride[4] = 0 ;
02278       stride[3] = n1 * (
02279       stride[2] = n2 * (
02280       stride[1] = n3 * (
02281       stride[0] = Tag4::Size )));
02282     }
02283 
02284   template< typename iType >
02285   static void assign( iType * stride ,
02286                       const iType & n1 ,
02287                       const iType & n2 ,
02288                       const iType & n3 ,
02289                       const iType & n4 )
02290     {
02291       stride[7] = 0 ;
02292       stride[6] = 0 ;
02293       stride[5] = 0 ;
02294       stride[4] = 0 ;
02295       stride[3] = n1 * (
02296       stride[2] = n2 * (
02297       stride[1] = n3 * (
02298       stride[0] = n4 )));
02299     }
02300 
02301   template< typename iType >
02302   static void assign( iType * stride ,
02303                       const iType * const dims )
02304     {
02305       stride[7] = 0 ;
02306       stride[6] = 0 ;
02307       stride[5] = 0 ;
02308       stride[4] = 0 ;
02309       stride[3] = dims[0] * (
02310       stride[2] = dims[1] * (
02311       stride[1] = dims[2] * (
02312       stride[0] = dims[3] )));
02313     }
02314 };
02315 
02316 template< typename Scalar , class Tag1 , class Tag2 , class Tag3 , class Tag4 >
02317 struct Helper<Scalar,FortranOrder,Tag1,Tag2,Tag3,Tag4,void,void,void,void>
02318 {
02319   typedef
02320     Array<Scalar,NaturalOrder,Tag4,Tag3,Tag2,Tag1,void,void,void,void>
02321       reverse ;
02322 
02323   typedef
02324     Array<Scalar,FortranOrder,Tag1,Tag2,Tag3,void,void,void,void,void>
02325       truncate ;
02326 
02327   template< class TagA >
02328   struct append {
02329     typedef
02330       Array<Scalar,FortranOrder,Tag1,Tag2,Tag3,Tag4,TagA,void,void,void>
02331         fortran ;
02332 
02333     typedef
02334       Array<Scalar,NaturalOrder,TagA,Tag4,Tag3,Tag2,Tag1,void,void,void>
02335         natural ;
02336 
02337     typedef  fortran  type ;
02338     typedef  natural  reverse ;
02339   };
02340 
02341   enum { Rank = 4 };
02342 
02343   static bool verify( int_t rank , const ArrayDimTag * tags[] )
02344     {
02345       return rank == Rank &&
02346              tags[0] == & Tag1::tag() &&
02347              tags[1] == & Tag2::tag() &&
02348              tags[2] == & Tag3::tag() &&
02349              tags[3] == & Tag4::tag();
02350     }
02351 
02352   static void assign_tags( const ArrayDimTag * tags[] )
02353     {
02354       tags[0] = & Tag1::tag();
02355       tags[1] = & Tag2::tag();
02356       tags[2] = & Tag3::tag();
02357       tags[3] = & Tag4::tag();
02358       tags[4] = NULL ;
02359       tags[5] = NULL ;
02360       tags[6] = NULL ;
02361       tags[7] = NULL ;
02362     }
02363 
02364   template< typename iType >
02365   static void assign( iType * stride )
02366     {
02367       stride[7] = 0 ;
02368       stride[6] = 0 ;
02369       stride[5] = 0 ;
02370       stride[4] = 0 ;
02371       stride[3] = Tag4::Size * (
02372       stride[2] = Tag3::Size * (
02373       stride[1] = Tag2::Size * (
02374       stride[0] = Tag1::Size )));
02375     }
02376 
02377   template< typename iType >
02378   static void assign( iType * stride ,
02379                       const iType & n4 )
02380     {
02381       stride[7] = 0 ;
02382       stride[6] = 0 ;
02383       stride[5] = 0 ;
02384       stride[4] = 0 ;
02385       stride[3] = n4 * (
02386       stride[2] = Tag3::Size * (
02387       stride[1] = Tag2::Size * (
02388       stride[0] = Tag1::Size )));
02389     }
02390 
02391   template< typename iType >
02392   static void assign( iType * stride ,
02393                       const iType & n3 ,
02394                       const iType & n4 )
02395     {
02396       stride[7] = 0 ;
02397       stride[6] = 0 ;
02398       stride[5] = 0 ;
02399       stride[4] = 0 ;
02400       stride[3] = n4 * (
02401       stride[2] = n3 * (
02402       stride[1] = Tag2::Size * (
02403       stride[0] = Tag1::Size )));
02404     }
02405 
02406   template< typename iType >
02407   static void assign( iType * stride ,
02408                       const iType & n2 ,
02409                       const iType & n3 ,
02410                       const iType & n4 )
02411     {
02412       stride[7] = 0 ;
02413       stride[6] = 0 ;
02414       stride[5] = 0 ;
02415       stride[4] = 0 ;
02416       stride[3] = n4 * (
02417       stride[2] = n3 * (
02418       stride[1] = n2 * (
02419       stride[0] = Tag1::Size )));
02420     }
02421 
02422   template< typename iType >
02423   static void assign( iType * stride ,
02424                       const iType & n1 ,
02425                       const iType & n2 ,
02426                       const iType & n3 ,
02427                       const iType & n4 )
02428     {
02429       stride[7] = 0 ;
02430       stride[6] = 0 ;
02431       stride[5] = 0 ;
02432       stride[4] = 0 ;
02433       stride[3] = n4 * (
02434       stride[2] = n3 * (
02435       stride[1] = n2 * (
02436       stride[0] = n1 )));
02437     }
02438 
02439   template< typename iType >
02440   static void assign( iType * stride ,
02441                       const iType * const dims )
02442     {
02443       stride[7] = 0 ;
02444       stride[6] = 0 ;
02445       stride[5] = 0 ;
02446       stride[4] = 0 ;
02447       stride[3] = dims[3] * (
02448       stride[2] = dims[2] * (
02449       stride[1] = dims[1] * (
02450       stride[0] = dims[0] )));
02451    }
02452 };
02453 
02454 //----------------------------------------------------------------------
02457 template< typename Scalar , class Tag1 , class Tag2 , class Tag3 >
02458 struct Helper<Scalar,NaturalOrder,Tag1,Tag2,Tag3,void,void,void,void,void>
02459 {
02460   typedef
02461     Array<Scalar,FortranOrder,Tag3,Tag2,Tag1,void,void,void,void,void>
02462       reverse ;
02463 
02464   typedef
02465     Array<Scalar,NaturalOrder,Tag2,Tag3,void,void,void,void,void,void>
02466       truncate ;
02467 
02468   template< class TagA >
02469   struct append {
02470     typedef
02471       Array<Scalar,NaturalOrder,TagA,Tag1,Tag2,Tag3,void,void,void,void>
02472         natural ;
02473 
02474     typedef
02475       Array<Scalar,FortranOrder,Tag3,Tag2,Tag1,TagA,void,void,void,void>
02476         fortran ;
02477 
02478     typedef  natural  type ;
02479     typedef  fortran  reverse ;
02480   };
02481 
02482   enum { Rank = 3 };
02483 
02484   static bool verify( int_t rank , const ArrayDimTag * tags[] )
02485     {
02486       return rank == Rank &&
02487              tags[0] == & Tag3::tag() &&
02488              tags[1] == & Tag2::tag() &&
02489              tags[2] == & Tag1::tag();
02490     }
02491 
02492   static void assign_tags( const ArrayDimTag * tags[] )
02493     {
02494       tags[0] = & Tag3::tag();
02495       tags[1] = & Tag2::tag();
02496       tags[2] = & Tag1::tag();
02497       tags[3] = NULL ;
02498       tags[4] = NULL ;
02499       tags[5] = NULL ;
02500       tags[6] = NULL ;
02501       tags[7] = NULL ;
02502     }
02503 
02504   template< typename iType >
02505   static void assign( iType * stride )
02506     {
02507       stride[7] = 0 ;
02508       stride[6] = 0 ;
02509       stride[5] = 0 ;
02510       stride[4] = 0 ;
02511       stride[3] = 0 ;
02512       stride[2] = Tag1::Size * (
02513       stride[1] = Tag2::Size * (
02514       stride[0] = Tag3::Size ));
02515     }
02516 
02517   template< typename iType >
02518   static void assign( iType * stride ,
02519                       const iType & n1 )
02520     {
02521       stride[7] = 0 ;
02522       stride[6] = 0 ;
02523       stride[5] = 0 ;
02524       stride[4] = 0 ;
02525       stride[3] = 0 ;
02526       stride[2] = n1 * (
02527       stride[1] = Tag2::Size * (
02528       stride[0] = Tag3::Size ));
02529     }
02530 
02531   template< typename iType >
02532   static void assign( iType * stride ,
02533                       const iType & n1 ,
02534                       const iType & n2 )
02535     {
02536       stride[7] = 0 ;
02537       stride[6] = 0 ;
02538       stride[5] = 0 ;
02539       stride[4] = 0 ;
02540       stride[3] = 0 ;
02541       stride[2] = n1 * (
02542       stride[1] = n2 * (
02543       stride[0] = Tag3::Size ));
02544     }
02545 
02546   template< typename iType >
02547   static void assign( iType * stride ,
02548                       const iType & n1 ,
02549                       const iType & n2 ,
02550                       const iType & n3 )
02551     {
02552       stride[7] = 0 ;
02553       stride[6] = 0 ;
02554       stride[5] = 0 ;
02555       stride[4] = 0 ;
02556       stride[3] = 0 ;
02557       stride[2] = n1 * (
02558       stride[1] = n2 * (
02559       stride[0] = n3 ));
02560     }
02561 
02562   template< typename iType >
02563   static void assign( iType * stride ,
02564                       const iType * const dims )
02565     {
02566       stride[7] = 0 ;
02567       stride[6] = 0 ;
02568       stride[5] = 0 ;
02569       stride[4] = 0 ;
02570       stride[3] = 0 ;
02571       stride[2] = dims[0] * (
02572       stride[1] = dims[1] * (
02573       stride[0] = dims[2] ));
02574     }
02575 };
02576 
02577 template< typename Scalar , class Tag1 , class Tag2 , class Tag3 >
02578 struct Helper<Scalar,FortranOrder,Tag1,Tag2,Tag3,void,void,void,void,void>
02579 {
02580   typedef
02581     Array<Scalar,NaturalOrder,Tag3,Tag2,Tag1,void,void,void,void,void>
02582       reverse ;
02583 
02584   typedef
02585     Array<Scalar,FortranOrder,Tag1,Tag2,void,void,void,void,void,void>
02586       truncate ;
02587 
02588   template< class TagA >
02589   struct append {
02590     typedef
02591       Array<Scalar,FortranOrder,Tag1,Tag2,Tag3,TagA,void,void,void,void>
02592         fortran ;
02593 
02594     typedef
02595       Array<Scalar,NaturalOrder,TagA,Tag3,Tag2,Tag1,void,void,void,void>
02596         natural ;
02597 
02598     typedef  fortran  type ;
02599     typedef  natural  reverse ;
02600   };
02601 
02602   enum { Rank = 3 };
02603 
02604   static bool verify( int_t rank , const ArrayDimTag * tags[] )
02605     {
02606       return rank == Rank &&
02607              tags[0] == & Tag1::tag() &&
02608              tags[1] == & Tag2::tag() &&
02609              tags[2] == & Tag3::tag();
02610     }
02611 
02612   static void assign_tags( const ArrayDimTag * tags[] )
02613     {
02614       tags[0] = & Tag1::tag();
02615       tags[1] = & Tag2::tag();
02616       tags[2] = & Tag3::tag();
02617       tags[3] = NULL ;
02618       tags[4] = NULL ;
02619       tags[5] = NULL ;
02620       tags[6] = NULL ;
02621       tags[7] = NULL ;
02622     }
02623 
02624   template< typename iType >
02625   static void assign( iType * stride )
02626     {
02627       stride[7] = 0 ;
02628       stride[6] = 0 ;
02629       stride[5] = 0 ;
02630       stride[4] = 0 ;
02631       stride[3] = 0 ;
02632       stride[2] = Tag3::Size * (
02633       stride[1] = Tag2::Size * (
02634       stride[0] = Tag1::Size ));
02635     }
02636 
02637   template< typename iType >
02638   static void assign( iType * stride ,
02639                       const iType & n3 )
02640     {
02641       stride[7] = 0 ;
02642       stride[6] = 0 ;
02643       stride[5] = 0 ;
02644       stride[4] = 0 ;
02645       stride[3] = 0 ;
02646       stride[2] = n3 * (
02647       stride[1] = Tag2::Size * (
02648       stride[0] = Tag1::Size ));
02649     }
02650 
02651   template< typename iType >
02652   static void assign( iType * stride ,
02653                       const iType & n2 ,
02654                       const iType & n3 )
02655     {
02656       stride[7] = 0 ;
02657       stride[6] = 0 ;
02658       stride[5] = 0 ;
02659       stride[4] = 0 ;
02660       stride[3] = 0 ;
02661       stride[2] = n3 * (
02662       stride[1] = n2 * (
02663       stride[0] = Tag1::Size ));
02664     }
02665 
02666   template< typename iType >
02667   static void assign( iType * stride ,
02668                       const iType & n1 ,
02669                       const iType & n2 ,
02670                       const iType & n3 )
02671     {
02672       stride[7] = 0 ;
02673       stride[6] = 0 ;
02674       stride[5] = 0 ;
02675       stride[4] = 0 ;
02676       stride[3] = 0 ;
02677       stride[2] = n3 * (
02678       stride[1] = n2 * (
02679       stride[0] = n1 ));
02680     }
02681 
02682   template< typename iType >
02683   static void assign( iType * stride ,
02684                       const iType * const dims )
02685     {
02686       stride[7] = 0 ;
02687       stride[6] = 0 ;
02688       stride[5] = 0 ;
02689       stride[4] = 0 ;
02690       stride[3] = 0 ;
02691       stride[2] = dims[2] * (
02692       stride[1] = dims[1] * (
02693       stride[0] = dims[0] ));
02694    }
02695 };
02696 
02697 //----------------------------------------------------------------------
02700 template< typename Scalar , class Tag1 , class Tag2 >
02701 struct Helper<Scalar,NaturalOrder,Tag1,Tag2,void,void,void,void,void,void>
02702 {
02703   typedef
02704     Array<Scalar,FortranOrder,Tag2,Tag1,void,void,void,void,void,void>
02705       reverse ;
02706 
02707   typedef
02708     Array<Scalar,NaturalOrder,Tag2,void,void,void,void,void,void,void>
02709       truncate ;
02710 
02711   template< class TagA >
02712   struct append {
02713     typedef
02714       Array<Scalar,NaturalOrder,TagA,Tag1,Tag2,void,void,void,void,void>
02715         natural ;
02716 
02717     typedef
02718       Array<Scalar,FortranOrder,Tag2,Tag1,TagA,void,void,void,void,void>
02719         fortran ;
02720 
02721     typedef  natural  type ;
02722     typedef  fortran  reverse ;
02723   };
02724 
02725   enum { Rank = 2 };
02726 
02727   static bool verify( int_t rank , const ArrayDimTag * tags[] )
02728     {
02729       return rank == Rank &&
02730              tags[0] == & Tag2::tag() &&
02731              tags[1] == & Tag1::tag();
02732     }
02733 
02734   static void assign_tags( const ArrayDimTag * tags[] )
02735     {
02736       tags[0] = & Tag2::tag();
02737       tags[1] = & Tag1::tag();
02738       tags[2] = NULL ;
02739       tags[3] = NULL ;
02740       tags[4] = NULL ;
02741       tags[5] = NULL ;
02742       tags[6] = NULL ;
02743       tags[7] = NULL ;
02744     }
02745 
02746   template< typename iType >
02747   static void assign( iType * stride )
02748     {
02749       stride[7] = 0 ;
02750       stride[6] = 0 ;
02751       stride[5] = 0 ;
02752       stride[4] = 0 ;
02753       stride[3] = 0 ;
02754       stride[2] = 0 ;
02755       stride[1] = Tag1::Size * (
02756       stride[0] = Tag2::Size );
02757     }
02758 
02759   template< typename iType >
02760   static void assign( iType * stride ,
02761                       const iType & n1 )
02762     {
02763       stride[7] = 0 ;
02764       stride[6] = 0 ;
02765       stride[5] = 0 ;
02766       stride[4] = 0 ;
02767       stride[3] = 0 ;
02768       stride[2] = 0 ;
02769       stride[1] = n1 * (
02770       stride[0] = Tag2::Size );
02771     }
02772 
02773   template< typename iType >
02774   static void assign( iType * stride ,
02775                       const iType & n1 ,
02776                       const iType & n2 )
02777     {
02778       stride[7] = 0 ;
02779       stride[6] = 0 ;
02780       stride[5] = 0 ;
02781       stride[4] = 0 ;
02782       stride[3] = 0 ;
02783       stride[2] = 0 ;
02784       stride[1] = n1 * (
02785       stride[0] = n2 );
02786     }
02787 
02788   template< typename iType >
02789   static void assign( iType * stride ,
02790                       const iType * const dims )
02791     {
02792       stride[7] = 0 ;
02793       stride[6] = 0 ;
02794       stride[5] = 0 ;
02795       stride[4] = 0 ;
02796       stride[3] = 0 ;
02797       stride[2] = 0 ;
02798       stride[1] = dims[0] * (
02799       stride[0] = dims[1] );
02800     }
02801 };
02802 
02803 template< typename Scalar , class Tag1 , class Tag2 >
02804 struct Helper<Scalar,FortranOrder,Tag1,Tag2,void,void,void,void,void,void>
02805 {
02806   typedef
02807     Array<Scalar,NaturalOrder,Tag2,Tag1,void,void,void,void,void,void>
02808       reverse ;
02809 
02810   typedef
02811     Array<Scalar,FortranOrder,Tag1,void,void,void,void,void,void,void>
02812       truncate ;
02813 
02814   template< class TagA >
02815   struct append {
02816     typedef
02817       Array<Scalar,FortranOrder,Tag1,Tag2,TagA,void,void,void,void,void>
02818         fortran ;
02819 
02820     typedef
02821       Array<Scalar,NaturalOrder,TagA,Tag2,Tag1,void,void,void,void,void>
02822         natural ;
02823 
02824     typedef  fortran  type ;
02825     typedef  natural  reverse ;
02826   };
02827 
02828   enum { Rank = 2 };
02829 
02830   static bool verify( int_t rank , const ArrayDimTag * tags[] )
02831     {
02832       return rank == Rank &&
02833              tags[0] = & Tag1::tag() &&
02834              tags[1] = & Tag2::tag();
02835     }
02836 
02837   static void assign_tags( const ArrayDimTag * tags[] )
02838     {
02839       tags[0] = & Tag1::tag();
02840       tags[1] = & Tag2::tag();
02841       tags[2] = NULL ;
02842       tags[3] = NULL ;
02843       tags[4] = NULL ;
02844       tags[5] = NULL ;
02845       tags[6] = NULL ;
02846       tags[7] = NULL ;
02847     }
02848 
02849   template< typename iType >
02850   static void assign( iType * stride )
02851     {
02852       stride[7] = 0 ;
02853       stride[6] = 0 ;
02854       stride[5] = 0 ;
02855       stride[4] = 0 ;
02856       stride[3] = 0 ;
02857       stride[2] = 0 ;
02858       stride[1] = Tag2::Size * (
02859       stride[0] = Tag1::Size );
02860     }
02861 
02862   template< typename iType >
02863   static void assign( iType * stride ,
02864                       const iType & n2 )
02865     {
02866       stride[7] = 0 ;
02867       stride[6] = 0 ;
02868       stride[5] = 0 ;
02869       stride[4] = 0 ;
02870       stride[3] = 0 ;
02871       stride[2] = 0 ;
02872       stride[1] = n2 * (
02873       stride[0] = Tag1::Size );
02874     }
02875 
02876   template< typename iType >
02877   static void assign( iType * stride ,
02878                       const iType & n1 ,
02879                       const iType & n2 )
02880     {
02881       stride[7] = 0 ;
02882       stride[6] = 0 ;
02883       stride[5] = 0 ;
02884       stride[4] = 0 ;
02885       stride[3] = 0 ;
02886       stride[2] = 0 ;
02887       stride[1] = n2 * (
02888       stride[0] = n1 );
02889     }
02890 
02891   template< typename iType >
02892   static void assign( iType * stride ,
02893                       const iType * const dims )
02894     {
02895       stride[7] = 0 ;
02896       stride[6] = 0 ;
02897       stride[5] = 0 ;
02898       stride[4] = 0 ;
02899       stride[3] = 0 ;
02900       stride[2] = 0 ;
02901       stride[1] = dims[1] * (
02902       stride[0] = dims[0] );
02903     }
02904 };
02905 
02906 //----------------------------------------------------------------------
02909 template< typename Scalar , class Tag1 >
02910 struct Helper<Scalar,NaturalOrder,Tag1,void,void,void,void,void,void,void>
02911 {
02912   typedef
02913     Array<Scalar,FortranOrder,Tag1,void,void,void,void,void,void,void>
02914       reverse ;
02915 
02916   typedef
02917     Array<Scalar,RankZero,void,void,void,void,void,void,void,void>
02918       truncate ;
02919 
02920   template< class TagA >
02921   struct append {
02922     typedef
02923       Array<Scalar,NaturalOrder,TagA,Tag1,void,void,void,void,void,void>
02924         natural ;
02925 
02926     typedef
02927       Array<Scalar,FortranOrder,Tag1,TagA,void,void,void,void,void,void>
02928         fortran ;
02929 
02930     typedef  natural  type ;
02931     typedef  fortran  reverse ;
02932   };
02933 
02934   enum { Rank = 1 };
02935 
02936   static bool verify( int_t rank , const ArrayDimTag * tags[] )
02937     { return rank == Rank && tags[0] == & Tag1::tag(); }
02938 
02939   static void assign_tags( const ArrayDimTag * tags[] )
02940     {
02941       tags[0] = & Tag1::tag();
02942       tags[1] = NULL ;
02943       tags[2] = NULL ;
02944       tags[3] = NULL ;
02945       tags[4] = NULL ;
02946       tags[5] = NULL ;
02947       tags[6] = NULL ;
02948       tags[7] = NULL ;
02949     }
02950 
02951   template< typename iType >
02952   static void assign( iType * stride )
02953     {
02954       stride[7] = 0 ;
02955       stride[6] = 0 ;
02956       stride[5] = 0 ;
02957       stride[4] = 0 ;
02958       stride[3] = 0 ;
02959       stride[2] = 0 ;
02960       stride[1] = 0 ;
02961       stride[0] = Tag1::Size ;
02962     }
02963 
02964   template< typename iType >
02965   static void assign( iType * stride ,
02966                       const iType & n1 )
02967     {
02968       stride[7] = 0 ;
02969       stride[6] = 0 ;
02970       stride[5] = 0 ;
02971       stride[4] = 0 ;
02972       stride[3] = 0 ;
02973       stride[2] = 0 ;
02974       stride[1] = 0 ;
02975       stride[0] = n1 ;
02976     }
02977 
02978   template< typename iType >
02979   static void assign( iType * stride ,
02980                       const iType * const dims )
02981     {
02982       stride[7] = 0 ;
02983       stride[6] = 0 ;
02984       stride[5] = 0 ;
02985       stride[4] = 0 ;
02986       stride[3] = 0 ;
02987       stride[2] = 0 ;
02988       stride[1] = 0 ;
02989       stride[0] = dims[0] ;
02990     }
02991 };
02992 
02993 template< typename Scalar , class Tag1 >
02994 struct Helper<Scalar,FortranOrder,Tag1,void,void,void,void,void,void,void>
02995 {
02996   typedef
02997     Array<Scalar,NaturalOrder,Tag1,void,void,void,void,void,void,void>
02998       reverse ;
02999 
03000   typedef
03001     Array<Scalar,RankZero,void,void,void,void,void,void,void,void>
03002       truncate ;
03003 
03004   template< class TagA >
03005   struct append {
03006     typedef
03007       Array<Scalar,FortranOrder,Tag1,TagA,void,void,void,void,void,void>
03008         fortran ;
03009 
03010     typedef
03011       Array<Scalar,NaturalOrder,TagA,Tag1,void,void,void,void,void,void>
03012         natural ;
03013 
03014     typedef  fortran  type ;
03015     typedef  natural  reverse ;
03016   };
03017 
03018   enum { Rank = 1 };
03019 
03020   static bool verify( int_t rank , const ArrayDimTag * tags[] )
03021     { return rank == Rank && tags[0] == & Tag1::tag(); }
03022 
03023   static void assign_tags( const ArrayDimTag * tags[] )
03024     {
03025       tags[0] = & Tag1::tag();
03026       tags[1] = NULL ;
03027       tags[2] = NULL ;
03028       tags[3] = NULL ;
03029       tags[4] = NULL ;
03030       tags[5] = NULL ;
03031       tags[6] = NULL ;
03032       tags[7] = NULL ;
03033     }
03034 
03035   template< typename iType >
03036   static void assign( iType * stride )
03037     {
03038       stride[7] = 0 ;
03039       stride[6] = 0 ;
03040       stride[5] = 0 ;
03041       stride[4] = 0 ;
03042       stride[3] = 0 ;
03043       stride[2] = 0 ;
03044       stride[1] = 0 ;
03045       stride[0] = Tag1::Size ;
03046     }
03047 
03048   template< typename iType >
03049   static void assign( iType * stride , const iType & n1 )
03050     {
03051       stride[7] = 0 ;
03052       stride[6] = 0 ;
03053       stride[5] = 0 ;
03054       stride[4] = 0 ;
03055       stride[3] = 0 ;
03056       stride[2] = 0 ;
03057       stride[1] = 0 ;
03058       stride[0] = n1 ;
03059     }
03060 
03061   template< typename iType >
03062   static void assign( iType * stride , const iType * const dims )
03063     {
03064       stride[7] = 0 ;
03065       stride[6] = 0 ;
03066       stride[5] = 0 ;
03067       stride[4] = 0 ;
03068       stride[3] = 0 ;
03069       stride[2] = 0 ;
03070       stride[0] = dims[0] ;
03071     }
03072 };
03073 
03074 //----------------------------------------------------------------------
03077 template< typename Scalar >
03078 struct Helper<Scalar,RankZero,void,void,void,void,void,void,void,void>
03079 {
03080   typedef
03081     Array<Scalar,RankZero,void,void,void,void,void,void,void,void>
03082       reverse ;
03083 
03084   template< class TagA >
03085   struct append {
03086     typedef
03087       Array<Scalar,NaturalOrder,TagA,void,void,void,void,void,void,void>
03088         natural ;
03089 
03090     typedef
03091       Array<Scalar,FortranOrder,TagA,void,void,void,void,void,void,void>
03092         fortran ;
03093 
03094     typedef natural type ;
03095     typedef fortran reverse ;
03096   };
03097 
03098   enum { Rank = 0 };
03099 
03100   template< typename iType >
03101   static void assign( iType * ) {}
03102 };
03103 
03104 //----------------------------------------------------------------------
03107 template< typename Scalar >
03108 struct Helper<Scalar,NaturalOrder,void,void,void,void,void,void,void,void>
03109 {
03110   typedef
03111     Array<Scalar,FortranOrder,void,void,void,void,void,void,void,void>
03112       reverse ;
03113 };
03114 
03115 template< typename Scalar >
03116 struct Helper<Scalar,FortranOrder,void,void,void,void,void,void,void,void>
03117 {
03118   typedef
03119     Array<Scalar,NaturalOrder,void,void,void,void,void,void,void,void>
03120       reverse ;
03121 };
03122 
03123 //----------------------------------------------------------------------
03124 
03125 } // namespace array_traits
03126 
03127 template< class ArrayType , class TagA > struct ArrayAppend {};
03128 
03129 template< typename Scalar , ArrayOrder Order ,
03130           class Tag1 , class Tag2 , class Tag3 , class Tag4 ,
03131           class Tag5 , class Tag6 , class Tag7 , class TagA >
03132 struct ArrayAppend<
03133        Array<Scalar,Order,Tag1,Tag2,Tag3,Tag4,Tag5,Tag6,Tag7,void> , TagA >
03134 {
03135 private:
03136   typedef typename
03137     array_traits::Helper<Scalar,Order,Tag1,Tag2,Tag3,Tag4,Tag5,Tag6,Tag7,void>
03138       ::template append<TagA> helper ;
03139 public:
03140   typedef typename helper::type    type ;
03141   typedef typename helper::natural natural ;
03142   typedef typename helper::fortran fortran ;
03143 };
03144 
03145 } // namespace shards
03146 
03147 #endif /* DOXYGEN_COMPILE */
03148 
03149 //----------------------------------------------------------------------
03150 //----------------------------------------------------------------------
03151 
03152 namespace shards {
03153 
03158 //----------------------------------------------------------------------
03171 template< typename Scalar , ArrayOrder array_order >
03172 class Array<Scalar,array_order,void,void,void,void,void,void,void,void>
03173 {
03174 private:
03175   typedef typename array_traits::Offset<array_order> Offset ;
03176 public:
03182   typedef Scalar  value_type ;
03183 
03185   typedef array_traits::int_t size_type ;
03186 
03188   typedef const ArrayDimTag * tag_type ;
03189 
03190   //----------------------------------
03191 
03193   enum { Natural = NaturalOrder == array_order };
03194 
03196   enum { Reverse = FortranOrder == array_order };
03197 
03199   enum { Contiguous = true };
03200 
03202   size_type rank()   const { return m_rank ; }
03203 
03205   bool natural()    const { return Natural ; }
03206 
03208   bool reverse()    const { return Reverse ; }
03209 
03211   bool contiguous() const { return Contiguous ; }
03212 
03213   //----------------------------------
03214 
03216   tag_type tag( size_type ord ) const
03217     {
03218       array_traits::check_range( ord , m_rank );
03219       if ( Natural ) { ord = ( m_rank - 1 ) - ord ; }
03220       return m_tag[ord];
03221     }
03222 
03223   //----------------------------------
03224 
03226   size_type dimension( size_type ord ) const
03227     {
03228       array_traits::check_range( ord , m_rank );
03229       if ( Natural ) { ord = ( m_rank - 1 ) - ord ; }
03230       return ord ? m_stride[ord] / m_stride[ord-1] : m_stride[ord] ;
03231     }
03232 
03234   template< typename iType >
03235   void dimensions( std::vector<iType> & n )
03236     {
03237       n.resize( m_rank );
03238       for ( size_type i = 0 ; i < m_rank ; ++i ) { n[i] = dimension(i); }
03239     }
03240 
03242   size_type size() const { return m_stride[ m_rank - 1 ]; }
03243 
03245   //----------------------------------
03253   template< typename iType >
03254   Array truncate( const iType & i ) const
03255     { return Array( *this , i ); }
03256 
03258   value_type * contiguous_data() const { return m_ptr ; }
03259 
03261   template< typename iType >
03262   value_type & operator[]( const iType & i ) const
03263     {
03264       SHARDS_ARRAY_CHECK( array_traits::check_range(i,size()) );
03265       return m_ptr[ i ];
03266     }
03267 
03268   //----------------------------------
03270   template< typename iType >
03271   value_type & operator()( const iType & i1 , const iType & i2 ,
03272                            const iType & i3 , const iType & i4 ,
03273                            const iType & i5 , const iType & i6 ,
03274                            const iType & i7 , const iType & i8 ) const
03275     {
03276       SHARDS_ARRAY_CHECK( array_traits::check_rank( m_rank , 8 ) );
03277       return m_ptr[ Offset::op(m_stride,i1,i2,i3,i4,i5,i6,i7,i8) ];
03278     }
03279 
03280   template< typename iType >
03281   value_type & operator()( const iType & i1 , const iType & i2 ,
03282                            const iType & i3 , const iType & i4 ,
03283                            const iType & i5 , const iType & i6 ,
03284                            const iType & i7 ) const
03285     {
03286       SHARDS_ARRAY_CHECK( array_traits::check_rank( m_rank , 7 ) );
03287       return m_ptr[ Offset::op(m_stride,i1,i2,i3,i4,i5,i6,i7) ];
03288     }
03289 
03290   template< typename iType >
03291   value_type & operator()( const iType & i1 , const iType & i2 ,
03292                            const iType & i3 , const iType & i4 ,
03293                            const iType & i5 , const iType & i6 ) const
03294     {
03295       SHARDS_ARRAY_CHECK( array_traits::check_rank( m_rank , 6 ) );
03296       return m_ptr[ Offset::op(m_stride,i1,i2,i3,i4,i5,i6) ];
03297     }
03298 
03299   template< typename iType >
03300   value_type & operator()( const iType & i1 , const iType & i2 ,
03301                            const iType & i3 , const iType & i4 ,
03302                            const iType & i5 ) const
03303     {
03304       SHARDS_ARRAY_CHECK( array_traits::check_rank( m_rank , 5 ) );
03305       return m_ptr[ Offset::op(m_stride,i1,i2,i3,i4,i5) ];
03306     }
03307 
03308   template< typename iType >
03309   value_type & operator()( const iType & i1 , const iType & i2 ,
03310                            const iType & i3 , const iType & i4 ) const
03311     {
03312       SHARDS_ARRAY_CHECK( array_traits::check_rank( m_rank , 4 ) );
03313       return m_ptr[ Offset::op(m_stride,i1,i2,i3,i4) ];
03314     }
03315 
03316   template< typename iType >
03317   value_type & operator()( const iType & i1 , const iType & i2 ,
03318                            const iType & i3 ) const
03319     {
03320       SHARDS_ARRAY_CHECK( array_traits::check_rank( m_rank , 3 ) );
03321       return m_ptr[ Offset::op(m_stride,i1,i2,i3) ];
03322     }
03323 
03324   template< typename iType >
03325   value_type & operator()( const iType & i1 , const iType & i2 ) const
03326     {
03327       SHARDS_ARRAY_CHECK( array_traits::check_rank( m_rank , 2 ) );
03328       return m_ptr[ Offset::op(m_stride,i1,i2) ];
03329     }
03330 
03331   template< typename iType >
03332   value_type & operator()( const iType & i1 ) const
03333     {
03334       SHARDS_ARRAY_CHECK( array_traits::check_rank( m_rank , 1 ) );
03335       return m_ptr[ Offset::op(m_stride,i1) ];
03336     }
03337 
03339   //----------------------------------
03344   typedef typename
03345     array_traits::Helper<Scalar,array_order,void,void,void,void,void,void,void,void>
03346       ::reverse  ReverseType ;
03347 
03348   //----------------------------------
03349 
03350   Array()
03351     : m_ptr(NULL), m_rank(0)
03352     {
03353       Copy<8>( m_stride , (size_type) 0 );
03354       Copy<8>( m_tag , (tag_type) NULL );
03355     }
03356 
03357   Array( const Array & rhs )
03358     : m_ptr( rhs.m_ptr ), m_rank( rhs.m_rank )
03359     {
03360       Copy<8>( m_stride , rhs.m_stride );
03361       Copy<8>( m_tag , rhs.m_tag );
03362     }
03363 
03364   Array & operator = ( const Array & rhs )
03365     {
03366       m_ptr = rhs.m_ptr ;
03367       m_rank = rhs.m_rank ;
03368       Copy<8>( m_stride , rhs.m_stride );
03369       Copy<8>( m_tag , rhs.m_tag );
03370       return *this ;
03371     }
03372 
03374   Array( const ReverseType & rhs )
03375     : m_ptr( rhs.m_ptr ), m_rank( rhs.m_rank )
03376     {
03377       Copy<8>( m_stride , rhs.m_stride );
03378       Copy<8>( m_tag , rhs.m_tag );
03379     }
03380 
03382   Array & operator = ( const ReverseType & rhs )
03383     {
03384       m_ptr = rhs.m_ptr ;
03385       m_rank = rhs.m_rank ;
03386       Copy<8>( m_stride , rhs.m_stride );
03387       Copy<8>( m_tag , rhs.m_tag );
03388       return *this ;
03389     }
03390 
03391   //----------------------------------
03392   // Class specific constructors:
03393 
03394   Array( value_type * ptr ,
03395          const size_type rank ,
03396          const size_type * const dims ,
03397          const tag_type  * const tags )
03398     : m_ptr( ptr ), m_rank( rank )
03399     {
03400       array_traits::init_dim( m_stride, dims, rank, Natural);
03401       array_traits::init_tags( m_tag,   tags, rank, Natural);
03402     }
03403 
03405 private:
03406 
03408   Array( const Array & rhs , const size_type i )
03409     : m_ptr( NULL ), m_rank( 0 )
03410     {
03411       if ( 1 < rhs.m_rank ) {
03412         Copy<8>( m_stride , rhs.m_stride );
03413         Copy<8>( m_tag , rhs.m_tag );
03414         m_rank = rhs.m_rank - 1 ;
03415         m_ptr  = rhs.m_ptr + ( m_rank ? m_stride[ m_rank - 1 ] * i : i );
03416         m_stride[ m_rank ] = 0 ;
03417         m_tag[ m_rank ] = 0 ;
03418       }
03419       else {
03420         Copy<8>( m_stride , (size_type) 0 );
03421         Copy<8>( m_tag , (tag_type) NULL );
03422       }
03423     }
03424 
03426   value_type * m_ptr ;
03427 
03429   size_type  m_rank ;
03430 
03432   size_type  m_stride[8];
03433 
03435   tag_type   m_tag[8] ;
03436 
03437   template< typename , ArrayOrder ,
03438             class , class , class , class ,
03439             class , class , class , class >
03440   friend class shards::Array ;
03441 };
03442 
03443 //----------------------------------------------------------------------
03462 template< typename Scalar , ArrayOrder array_order ,
03463           class Tag1 , class Tag2 , class Tag3 , class Tag4 ,
03464           class Tag5 , class Tag6 , class Tag7 , class Tag8 >
03465 class Array
03466 {
03467 private:
03468 
03469 #ifndef DOXYGEN_COMPILE
03470   typedef
03471     array_traits::Helper<Scalar,array_order,
03472                          Tag1,Tag2,Tag3,Tag4,Tag5,Tag6,Tag7,Tag8>
03473       helper ;
03474 #endif /* DOXYGEN_COMPILE */
03475 
03476 public:
03482   typedef Scalar  value_type ;
03483 
03485   typedef array_traits::int_t size_type ;
03486 
03488   typedef const ArrayDimTag * tag_type ;
03489 
03490   //----------------------------------
03491 
03493   enum { Rank = helper::Rank };
03494 
03496   enum { Natural = NaturalOrder == array_order };
03497 
03499   enum { Reverse = FortranOrder == array_order };
03500 
03502   enum { Contiguous = true };
03503 
03505   size_type rank()   const { return Rank ; }
03506 
03508   bool natural()    const { return Natural ; }
03509 
03511   bool reverse()    const { return Reverse ; }
03512 
03514   bool contiguous() const { return Contiguous ; }
03515 
03516   //----------------------------------
03517 
03518 #ifndef DOXYGEN_COMPILE
03519 
03520   template < size_type ordinate >
03521   struct Tag {
03522     typedef typename array_traits::TagAt<Array,ordinate>::type type ;
03523   };
03524 #endif
03525 
03527   tag_type tag( const size_type ordinate ) const
03528     { return m_array.tag( ordinate ); }
03529 
03530   //----------------------------------
03532   template < size_type ordinate > size_type dimension() const
03533     {
03534       typedef array_traits::StrideDim<array_order,Rank,ordinate> StrideDim ;
03535       return StrideDim::dimension(m_array.m_stride);
03536     }
03537 
03539   size_type dimension( const size_type ordinate ) const
03540     {
03541       typedef array_traits::StrideDim<array_order,Rank> StrideDim ;
03542       return StrideDim::dimension(m_array.m_stride,ordinate);
03543     }
03544 
03546   template< typename iType >
03547   void dimensions( std::vector<iType> & n )
03548     { m_array.dimensions<iType>( n ); }
03549 
03551   size_type size() const { return m_array.m_stride[ Rank - 1 ]; }
03552 
03554   //----------------------------------
03562   typedef typename helper::truncate TruncateType ;
03563 
03568   template< typename iType >
03569   TruncateType truncate( const iType & i ) const
03570     { return TruncateType( m_array , i ); }
03571 
03572   //----------------------------------
03574   value_type * contiguous_data() const { return m_array.contiguous_data(); }
03575 
03577   template< typename iType >
03578   value_type & operator[]( const iType & i ) const
03579     { return m_array[i]; }
03580 
03582   template< typename iType >
03583   value_type & operator()( const iType & i1 , const iType & i2 ,
03584                            const iType & i3 , const iType & i4 ,
03585                            const iType & i5 , const iType & i6 ,
03586                            const iType & i7 , const iType & i8 ) const
03587     {
03588       array_traits::CheckRank<8,Rank>::ok();
03589       return m_array(i1,i2,i3,i4,i5,i6,i7,i8);
03590     }
03591 
03593   template< typename iType >
03594   value_type & operator()( const iType & i1 , const iType & i2 ,
03595                            const iType & i3 , const iType & i4 ,
03596                            const iType & i5 , const iType & i6 ,
03597                            const iType & i7 ) const
03598     {
03599       array_traits::CheckRank<7,Rank>::ok();
03600       return m_array(i1,i2,i3,i4,i5,i6,i7);
03601     }
03602 
03604   template< typename iType >
03605   value_type & operator()( const iType & i1 , const iType & i2 ,
03606                            const iType & i3 , const iType & i4 ,
03607                            const iType & i5 , const iType & i6 ) const
03608     {
03609       array_traits::CheckRank<6,Rank>::ok();
03610       return m_array(i1,i2,i3,i4,i5,i6);
03611     }
03612 
03614   template< typename iType >
03615   value_type & operator()( const iType & i1 , const iType & i2 ,
03616                            const iType & i3 , const iType & i4 ,
03617                            const iType & i5 ) const
03618     {
03619       array_traits::CheckRank<5,Rank>::ok();
03620       return m_array(i1,i2,i3,i4,i5);
03621     }
03622 
03624   template< typename iType >
03625   value_type & operator()( const iType & i1 , const iType & i2 ,
03626                            const iType & i3 , const iType & i4 ) const
03627     {
03628       array_traits::CheckRank<4,Rank>::ok();
03629       return m_array(i1,i2,i3,i4);
03630     }
03631 
03633   template< typename iType >
03634   value_type & operator()( const iType & i1 , const iType & i2 ,
03635                            const iType & i3 ) const
03636     {
03637       array_traits::CheckRank<3,Rank>::ok();
03638       return m_array(i1,i2,i3);
03639     }
03640 
03642   template< typename iType >
03643   value_type & operator()( const iType & i1 , const iType & i2 ) const
03644     {
03645       array_traits::CheckRank<2,Rank>::ok();
03646       return m_array(i1,i2);
03647     }
03648 
03650   template< typename iType >
03651   value_type & operator()( const iType & i1 ) const
03652     {
03653       array_traits::CheckRank<1,Rank>::ok();
03654       return m_array(i1);
03655     }
03656 
03658   //----------------------------------
03666   typedef typename helper::reverse  ReverseType ;
03667 
03669   Array() : m_array()
03670     { m_array.m_rank = Rank ; helper::assign_tags( m_array.m_tag ); }
03671 
03673   Array( const Array & rhs ) : m_array( rhs.m_array ) {}
03674 
03676   Array & operator = ( const Array & rhs )
03677     { m_array.operator=(rhs.m_array); return *this ; }
03678 
03680   Array( const ReverseType & rhs ) : m_array( rhs.m_array ) {}
03681 
03683   Array & operator = ( const ReverseType & rhs )
03684     { m_array.operator=(rhs.m_array); return *this ; }
03685 
03687   Array & assign( value_type * arg_ptr , const size_type * const dims )
03688     {
03689       m_array.m_ptr = arg_ptr ;
03690       array_traits::init_dim( m_array.m_stride , dims , Rank , Natural );
03691       return *this ;
03692     }
03693 
03695   Array( value_type * arg_ptr , const size_type * const dims )
03696     : m_array()
03697     {
03698       m_array.m_rank = Rank ;
03699       helper::assign_tags( m_array.m_tag );
03700       assign( arg_ptr , dims );
03701     }
03702 
03704   Array & assign( value_type * arg_ptr ,
03705                   const size_type n1 , const size_type n2 ,
03706                   const size_type n3 , const size_type n4 ,
03707                   const size_type n5 , const size_type n6 ,
03708                   const size_type n7 , const size_type n8 )
03709     {
03710       array_traits::CheckRange<7,Rank>::ok();
03711       m_array.m_ptr  = arg_ptr ;
03712       helper::assign( m_array.m_stride, n1, n2, n3, n4, n5, n6, n7, n8 );
03713       return *this ;
03714     }
03715 
03717   Array( value_type * arg_ptr ,
03718          const size_type n1 , const size_type n2 ,
03719          const size_type n3 , const size_type n4 ,
03720          const size_type n5 , const size_type n6 ,
03721          const size_type n7 , const size_type n8 )
03722     : m_array()
03723     {
03724       m_array.m_rank = Rank ;
03725       helper::assign_tags( m_array.m_tag );
03726       assign( arg_ptr, n1, n2, n3, n4, n5, n6, n7, n8 );
03727     }
03728 
03732   Array& assign( value_type * arg_ptr ,
03733                  const size_type n1 , const size_type n2 ,
03734                  const size_type n3 , const size_type n4 ,
03735                  const size_type n5 , const size_type n6 ,
03736                  const size_type n7 )
03737     {
03738       array_traits::CheckRange<6,Rank>::ok();
03739       m_array.m_ptr = arg_ptr ;
03740       helper::assign( m_array.m_stride, n1, n2, n3, n4, n5, n6, n7 );
03741       return *this ;
03742     }
03743 
03747   Array( value_type * arg_ptr ,
03748          const size_type n1 , const size_type n2 ,
03749          const size_type n3 , const size_type n4 ,
03750          const size_type n5 , const size_type n6 ,
03751          const size_type n7 )
03752     : m_array()
03753     {
03754       m_array.m_rank = Rank ;
03755       helper::assign_tags( m_array.m_tag );
03756       assign( arg_ptr, n1, n2, n3, n4, n5, n6, n7 );
03757     }
03758 
03762   Array & assign( value_type * arg_ptr ,
03763                   const size_type n1 , const size_type n2 ,
03764                   const size_type n3 , const size_type n4 ,
03765                   const size_type n5 , const size_type n6 )
03766     {
03767       array_traits::CheckRange<5,Rank>::ok();
03768       m_array.m_ptr = arg_ptr ;
03769       helper::assign( m_array.m_stride, n1, n2, n3, n4, n5, n6 );
03770       return *this ;
03771     }
03772 
03776   Array( value_type * arg_ptr ,
03777          const size_type n1 , const size_type n2 ,
03778          const size_type n3 , const size_type n4 ,
03779          const size_type n5 , const size_type n6 )
03780     : m_array()
03781     {
03782       m_array.m_rank = Rank ;
03783       helper::assign_tags( m_array.m_tag );
03784       assign( arg_ptr, n1, n2, n3, n4, n5, n6 );
03785     }
03786 
03790   Array & assign( value_type * arg_ptr ,
03791                   const size_type n1 , const size_type n2 ,
03792                   const size_type n3 , const size_type n4 ,
03793                   const size_type n5 )
03794     {
03795       array_traits::CheckRange<4,Rank>::ok();
03796       m_array.m_ptr  = arg_ptr ;
03797       helper::assign( m_array.m_stride, n1, n2, n3, n4, n5 );
03798       return *this ;
03799     }
03800 
03804   Array( value_type * arg_ptr ,
03805          const size_type n1 , const size_type n2 ,
03806          const size_type n3 , const size_type n4 ,
03807          const size_type n5 )
03808     : m_array()
03809     {
03810       m_array.m_rank = Rank ;
03811       helper::assign_tags( m_array.m_tag );
03812       assign( arg_ptr, n1, n2, n3, n4, n5 );
03813     }
03814 
03818   Array & assign( value_type * arg_ptr ,
03819                   const size_type n1 , const size_type n2 ,
03820                   const size_type n3 , const size_type n4 )
03821     {
03822       array_traits::CheckRange<3,Rank>::ok();
03823       m_array.m_ptr  = arg_ptr ;
03824       helper::assign( m_array.m_stride, n1, n2, n3, n4 );
03825       return *this ;
03826     }
03827 
03831   Array( value_type * arg_ptr ,
03832          const size_type n1 , const size_type n2 ,
03833          const size_type n3 , const size_type n4 )
03834     : m_array()
03835     {
03836       m_array.m_rank = Rank ;
03837       helper::assign_tags( m_array.m_tag );
03838       assign( arg_ptr, n1, n2, n3, n4 );
03839     }
03840 
03844   Array & assign( value_type * arg_ptr ,
03845                   const size_type n1 , const size_type n2 ,
03846                   const size_type n3 )
03847     {
03848       array_traits::CheckRange<2,Rank>::ok();
03849       m_array.m_ptr  = arg_ptr ;
03850       helper::assign( m_array.m_stride, n1, n2, n3 );
03851       return *this ;
03852     }
03853 
03857   Array( value_type * arg_ptr ,
03858          const size_type n1 , const size_type n2 ,
03859          const size_type n3 )
03860     : m_array()
03861     {
03862       m_array.m_rank = Rank ;
03863       helper::assign_tags( m_array.m_tag );
03864       assign( arg_ptr , n1, n2, n3 );
03865     }
03866 
03870   Array & assign( value_type * arg_ptr ,
03871                   const size_type n1 , const size_type n2 )
03872     {
03873       array_traits::CheckRange<1,Rank>::ok();
03874       m_array.m_ptr  = arg_ptr ;
03875       helper::assign( m_array.m_stride, n1, n2 );
03876       return *this ;
03877     }
03878 
03882   Array( value_type * arg_ptr , const size_type n1 , const size_type n2 )
03883     : m_array()
03884     {
03885       m_array.m_rank = Rank ;
03886       helper::assign_tags( m_array.m_tag );
03887       assign( arg_ptr, n1, n2 );
03888     }
03889 
03893   Array & assign( value_type * arg_ptr , const size_type n1 )
03894     {
03895       array_traits::CheckRange<0,Rank>::ok();
03896       m_array.m_ptr  = arg_ptr ;
03897       helper::assign( m_array.m_stride, n1 );
03898       return *this ;
03899     }
03900 
03904   Array( value_type * arg_ptr , const size_type n1 )
03905     : m_array()
03906     {
03907       m_array.m_rank = Rank ;
03908       helper::assign_tags( m_array.m_tag );
03909       assign( arg_ptr, n1 );
03910     }
03911 
03913   Array & assign( value_type * arg_ptr )
03914     {
03915       m_array.m_ptr = arg_ptr ;
03916       helper::assign( m_array.m_stride );
03917       return *this ;
03918     }
03919 
03921   Array( value_type * arg_ptr )
03922     : m_array()
03923     {
03924       m_array.m_rank = Rank ;
03925       helper::assign_tags( m_array.m_tag );
03926       assign( arg_ptr );
03927     }
03928 
03930   Array( const Array<Scalar,array_order> & rhs )
03931     : m_array( rhs )
03932     {
03933       if ( ! helper::verify( m_array.m_rank , m_array.m_tag ) ) {
03934         m_array.m_rank = Rank ;
03935         helper::assign_tags( m_array.m_tag );
03936         array_traits::throw_bad_conversion( m_array.m_rank , m_array.m_tag ,
03937                                             rhs.m_rank , rhs.m_tag );
03938       }
03939     }
03940 
03942   operator const Array<Scalar,array_order> & () const { return m_array ; }
03943 
03945   operator typename Array<Scalar,array_order>::ReverseType () const
03946     { return typename Array<Scalar,array_order>::ReverseType( m_array ); }
03947 
03949   void assign_stride( value_type      * arg_ptr ,
03950                       const size_type * arg_stride )
03951     {
03952       m_array.m_ptr = arg_ptr ;
03953       Copy<Rank>(   m_array.m_stride , arg_stride );
03954       Copy<8-Rank>( m_array.m_stride + Rank , size_type(0) );
03955     }
03956 
03958   void assign_stride( value_type      * arg_ptr ,
03959                       const size_type * arg_stride ,
03960                             size_type   arg_final_dim )
03961     {
03962       m_array.m_ptr = arg_ptr ;
03963       Copy<Rank-1>( m_array.m_stride , arg_stride );
03964       m_array.m_stride[Rank-1] = m_array.m_stride[Rank-2] * arg_final_dim ;
03965       Copy<8-Rank>( m_array.m_stride + Rank , size_type(0) );
03966     }
03967 
03969 protected:
03970 
03971   Array( const Array<Scalar,array_order> & rhs , size_type i )
03972     : m_array( rhs , i )
03973     {
03974       if ( ! helper::verify( m_array.m_rank , m_array.m_tag ) ) {
03975         m_array.m_rank = Rank ;
03976         helper::assign_tags( m_array.m_tag );
03977         array_traits::throw_bad_conversion( m_array.m_rank , m_array.m_tag ,
03978                                             rhs.m_rank - 1 , rhs.m_tag );
03979       }
03980     }
03981 
03982   Array<value_type,array_order> m_array ;
03983 
03984   template< typename , ArrayOrder ,
03985             class , class , class , class ,
03986             class , class , class , class >
03987   friend class shards::Array ;
03988 };
03989 
03990 //----------------------------------------------------------------------
03991 
03995 template< typename Scalar >
03996 class Array<Scalar,RankZero,void,void,void,void,void,void,void,void>
03997 {
03998 public:
04004   typedef Scalar  value_type ;
04005 
04007   typedef array_traits::int_t size_type ;
04008 
04010   typedef const ArrayDimTag * tag_type ;
04011 
04012   //----------------------------------
04013 
04015   enum { Rank = 0 };
04016 
04018   enum { Natural = false };
04019 
04021   enum { Reverse = false };
04022 
04024   enum { Contiguous = true };
04025 
04027   size_type rank()   const { return Rank ; }
04028 
04030   bool natural()    const { return Natural ; }
04031 
04033   bool reverse()    const { return Reverse ; }
04034 
04036   bool contiguous() const { return Contiguous ; }
04037 
04038   //----------------------------------
04039 
04041   size_type size() const { return 1 ; }
04042 
04044   //----------------------------------
04050   value_type * contiguous_data() const { return m_ptr ; }
04051 
04053   value_type & operator()() const { return *m_ptr ; }
04054 
04056   //----------------------------------
04061   Array() : m_ptr(NULL) {}
04062 
04063   Array( const Array & rhs ) : m_ptr( rhs.m_ptr ) {}
04064 
04065   Array & operator = ( const Array & rhs )
04066     { m_ptr = rhs.m_ptr ; return *this ; }
04067 
04068   //----------------------------------
04069   // Class specific constructors:
04070 
04071   Array( value_type * arg_ptr ) : m_ptr( arg_ptr ) {}
04072 
04074 protected:
04075 
04076 #ifndef DOXYGEN_COMPILE
04077   value_type * m_ptr ;
04078 
04079   template< typename , ArrayOrder ,
04080             class , class , class , class ,
04081             class , class , class , class >
04082   friend class shards::Array ;
04083 
04084 #endif /* DOXYGEN_COMPILE */
04085 };
04086 
04087 
04088 //----------------------------------------------------------------------
04089 //----------------------------------------------------------------------
04090 
04093 } // namespace shards
04094 
04095 #undef SHARDS_ARRAY_CHECK
04096 
04097 #endif /* Shards_Array_hpp */
04098 
Generated on Wed Mar 31 15:02:54 2010 for shards by  doxygen 1.6.3