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