|
phdMesh Version of the Day
|
00001 /*------------------------------------------------------------------------*/ 00002 /* phdMesh : Parallel Heterogneous Dynamic unstructured Mesh */ 00003 /* Copyright (2008) Sandia Corporation */ 00004 /* */ 00005 /* Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive */ 00006 /* license for use of this work by or on behalf of the U.S. Government. */ 00007 /* */ 00008 /* This library is free software; you can redistribute it and/or modify */ 00009 /* it under the terms of the GNU Lesser General Public License as */ 00010 /* published by the Free Software Foundation; either version 2.1 of the */ 00011 /* License, or (at your option) any later version. */ 00012 /* */ 00013 /* This library is distributed in the hope that it will be useful, */ 00014 /* but WITHOUT ANY WARRANTY; without even the implied warranty of */ 00015 /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU */ 00016 /* Lesser General Public License for more details. */ 00017 /* */ 00018 /* You should have received a copy of the GNU Lesser General Public */ 00019 /* License along with this library; if not, write to the Free Software */ 00020 /* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 */ 00021 /* USA */ 00022 /*------------------------------------------------------------------------*/ 00023 00024 #ifndef util_Array_hpp 00025 #define util_Array_hpp 00026 00027 #ifdef ARRAY_BOUNDS_CHECKING 00028 #define ARRAY_CHECK( X ) X 00029 #else 00030 #define ARRAY_CHECK( X ) 00031 #endif 00032 00033 #include <vector> 00034 #include <string> 00035 #include <util/SimpleArrayOps.hpp> 00036 00037 namespace phdmesh { 00038 00101 //---------------------------------------------------------------------- 00107 enum ArrayOrder { 00111 NaturalOrder , 00112 00116 FortranOrder , 00117 00121 RankZero 00122 }; 00123 00124 template< typename Scalar , ArrayOrder Order , 00125 class Tag1 = void , class Tag2 = void , 00126 class Tag3 = void , class Tag4 = void , 00127 class Tag5 = void , class Tag6 = void , 00128 class Tag7 = void , class Tag8 = void > 00129 class Array ; 00130 00131 //---------------------------------------------------------------------- 00132 00133 template< class ArrayType , class Tag > struct ArrayAppend ; 00134 00135 //---------------------------------------------------------------------- 00160 struct ArrayDimTag { 00161 00163 virtual const char * name() const = 0 ; 00164 00168 virtual std::string to_string( unsigned dimension , 00169 unsigned index ) const ; 00170 00174 virtual unsigned to_index( unsigned dimension , 00175 const std::string & label ) const ; 00176 00177 protected: 00178 virtual ~ArrayDimTag(); 00179 ArrayDimTag() {} 00180 private: 00181 ArrayDimTag( const ArrayDimTag & ); 00182 ArrayDimTag & operator = ( const ArrayDimTag & ); 00183 }; 00184 00190 struct ArrayDimension : public ArrayDimTag { 00191 00192 const char * name() const ; 00193 00194 static const ArrayDimension & tag(); 00195 00196 private: 00197 ~ArrayDimension(); 00198 ArrayDimension() {} 00199 ArrayDimension( const ArrayDimension & ); 00200 ArrayDimension & operator = ( const ArrayDimension & ); 00201 }; 00202 00203 } // namespace phdmesh 00204 00205 //---------------------------------------------------------------------- 00206 //---------------------------------------------------------------------- 00207 00208 #include <util/ArrayPrivate.hpp> 00209 00210 namespace phdmesh { 00211 00212 //---------------------------------------------------------------------- 00232 template< typename Scalar , ArrayOrder array_order , 00233 class Tag1 , class Tag2 , class Tag3 , class Tag4 , 00234 class Tag5 , class Tag6 , class Tag7 , class Tag8 > 00235 class Array 00236 { 00237 private: 00238 typedef 00239 Array<void,array_order,Tag1,Tag2,Tag3,Tag4,Tag5,Tag6,Tag7,Tag8> 00240 md_type ; 00241 public: 00247 typedef Scalar value_type ; 00248 00250 typedef unsigned size_type ; 00251 00253 typedef const ArrayDimTag * tag_type ; 00254 00255 //---------------------------------- 00256 00258 enum { Rank = md_type::Rank }; 00259 00261 enum { Natural = NaturalOrder == array_order }; 00262 00264 enum { Reverse = FortranOrder == array_order }; 00265 00267 enum { Contiguous = true }; 00268 00270 unsigned rank() const { return Rank ; } 00271 00273 bool natural() const { return Natural ; } 00274 00276 bool reverse() const { return Reverse ; } 00277 00279 bool contiguous() const { return Contiguous ; } 00280 00281 //---------------------------------- 00282 00283 #ifndef DOXYGEN_COMPILE 00284 00285 template < unsigned ordinate > 00286 struct Tag { typedef typename ArrayTagAt<Array,ordinate>::type type ; }; 00287 #endif 00288 00290 tag_type tag( const unsigned ordinate ) const 00291 { 00292 array_check_ordinal( Rank , ordinate ); 00293 return 00294 array_dim_tags<Tag1,Tag2,Tag3,Tag4,Tag5,Tag6,Tag7,Tag8>()[ordinate]; 00295 } 00296 00297 //---------------------------------- 00299 template < unsigned ordinate > unsigned dimension() const 00300 { 00301 array_check_ordinal_is_less<ordinate,Rank>(); 00302 return ArrayStrideDim<array_order,Rank,ordinate>::dimension(m_stride); 00303 } 00304 00306 unsigned dimension( const unsigned ordinate ) const 00307 { 00308 array_check_ordinal( Rank , ordinate ); 00309 return ArrayStrideDim<array_order,Rank>::dimension(m_stride,ordinate); 00310 } 00311 00313 void dimensions( std::vector<unsigned> & n ) 00314 { 00315 n.resize( Rank ); 00316 for ( unsigned i = 0 ; i < Rank ; ++i ) { n[i] = dimension(i); } 00317 } 00318 00320 size_type size() const { return m_stride[ Rank - 1 ]; } 00321 00323 //---------------------------------- 00331 typedef typename ArrayTruncate<Array>::type TruncateType ; 00332 00337 TruncateType truncate( const unsigned i ) const 00338 { 00339 TruncateType tmp ; 00340 tmp.m_ptr = m_ptr + i * ( 1 < Rank ? m_stride[ Rank - 2 ] : 1 ); 00341 Copy<Rank-1>( tmp.m_stride , m_stride ); 00342 return tmp ; 00343 } 00344 00345 //---------------------------------- 00347 value_type * contiguous_data() const { return m_ptr ; } 00348 00350 value_type & operator[]( size_type i ) const 00351 { 00352 ARRAY_CHECK( array_check_offset(size(),i) ); 00353 return m_ptr[ i ]; 00354 } 00355 00357 value_type & operator()( const unsigned i1 , const unsigned i2 , 00358 const unsigned i3 , const unsigned i4 , 00359 const unsigned i5 , const unsigned i6 , 00360 const unsigned i7 , const unsigned i8 ) const 00361 { return m_ptr[ 00362 array_offset<array_order,Rank>(m_stride,i1,i2,i3,i4,i5,i6,i7,i8) ]; 00363 } 00364 00366 value_type & operator()( const unsigned i1 , const unsigned i2 , 00367 const unsigned i3 , const unsigned i4 , 00368 const unsigned i5 , const unsigned i6 , 00369 const unsigned i7 ) const 00370 { return m_ptr[ 00371 array_offset<array_order,Rank>(m_stride,i1,i2,i3,i4,i5,i6,i7) ]; 00372 } 00373 00375 value_type & operator()( const unsigned i1 , const unsigned i2 , 00376 const unsigned i3 , const unsigned i4 , 00377 const unsigned i5 , const unsigned i6 ) const 00378 { return m_ptr[ 00379 array_offset<array_order,Rank>(m_stride,i1,i2,i3,i4,i5,i6) ]; 00380 } 00381 00383 value_type & operator()( const unsigned i1 , const unsigned i2 , 00384 const unsigned i3 , const unsigned i4 , 00385 const unsigned i5 ) const 00386 { return m_ptr[ array_offset<array_order,Rank>(m_stride,i1,i2,i3,i4,i5) ]; } 00387 00389 value_type & operator()( const unsigned i1 , const unsigned i2 , 00390 const unsigned i3 , const unsigned i4 ) const 00391 { return m_ptr[ array_offset<array_order,Rank>(m_stride,i1,i2,i3,i4) ]; } 00392 00394 value_type & operator()( const unsigned i1 , const unsigned i2 , 00395 const unsigned i3 ) const 00396 { return m_ptr[ array_offset<array_order,Rank>(m_stride,i1,i2,i3) ]; } 00397 00399 value_type & operator()( const unsigned i1 , const unsigned i2 ) const 00400 { return m_ptr[ array_offset<array_order,Rank>(m_stride,i1,i2) ]; } 00401 00403 value_type & operator()( const unsigned i1 ) const 00404 { return m_ptr[ array_offset<array_order,Rank>(m_stride,i1) ]; } 00405 00407 //---------------------------------- 00415 typedef typename ArrayReverse< Array >::type ReverseType ; 00416 00418 Array() : m_ptr(NULL) { Copy<Rank>( m_stride , (size_type) 0 ); } 00419 00421 Array( const Array & rhs ) 00422 : m_ptr( rhs.m_ptr ) { Copy<Rank>( m_stride , rhs.m_stride ); } 00423 00425 Array & operator = ( const Array & rhs ) 00426 { 00427 m_ptr = rhs.m_ptr ; 00428 Copy<Rank>( m_stride , rhs.m_stride ); 00429 return *this ; 00430 } 00431 00433 Array( const ReverseType & rhs ) 00434 : m_ptr( rhs.m_ptr ) { Copy<Rank>( m_stride , rhs.m_stride ); } 00435 00437 Array & operator = ( const ReverseType & rhs ) 00438 { 00439 m_ptr = rhs.m_ptr ; 00440 Copy<Rank>( m_stride , rhs.m_stride ); 00441 return *this ; 00442 } 00443 00445 Array( value_type * arg_ptr , const unsigned * const dims ) 00446 : m_ptr( arg_ptr ) { md_type::assign( m_stride , dims ); } 00447 00449 Array( value_type * arg_ptr , 00450 const unsigned n1 , const unsigned n2 , 00451 const unsigned n3 , const unsigned n4 , 00452 const unsigned n5 , const unsigned n6 , 00453 const unsigned n7 , const unsigned n8 ) 00454 : m_ptr( arg_ptr ) 00455 { md_type::assign( m_stride , n1 , n2 , n3 , n4 , n5 , n6 , n7 , n8 ); } 00456 00460 Array( value_type * arg_ptr , 00461 const unsigned n1 , const unsigned n2 , 00462 const unsigned n3 , const unsigned n4 , 00463 const unsigned n5 , const unsigned n6 , 00464 const unsigned n7 ) 00465 : m_ptr( arg_ptr ) 00466 { md_type::assign( m_stride , n1 , n2 , n3 , n4 , n5 , n6 , n7 ); } 00467 00471 Array( value_type * arg_ptr , 00472 const unsigned n1 , const unsigned n2 , 00473 const unsigned n3 , const unsigned n4 , 00474 const unsigned n5 , const unsigned n6 ) 00475 : m_ptr( arg_ptr ) 00476 { md_type::assign( m_stride , n1 , n2 , n3 , n4 , n5 , n6 ); } 00477 00481 Array( value_type * arg_ptr , 00482 const unsigned n1 , const unsigned n2 , 00483 const unsigned n3 , const unsigned n4 , 00484 const unsigned n5 ) 00485 : m_ptr( arg_ptr ) 00486 { md_type::assign( m_stride , n1 , n2 , n3 , n4 , n5 ); } 00487 00491 Array( value_type * arg_ptr , 00492 const unsigned n1 , const unsigned n2 , 00493 const unsigned n3 , const unsigned n4 ) 00494 : m_ptr( arg_ptr ) 00495 { md_type::assign( m_stride , n1 , n2 , n3 , n4 ); } 00496 00500 Array( value_type * arg_ptr , 00501 const unsigned n1 , const unsigned n2 , 00502 const unsigned n3 ) 00503 : m_ptr( arg_ptr ) 00504 { md_type::assign( m_stride , n1 , n2 , n3 ); } 00505 00509 Array( value_type * arg_ptr , const unsigned n1 , const unsigned n2 ) 00510 : m_ptr( arg_ptr ) { md_type::assign( m_stride , n1 , n2 ); } 00511 00515 Array( value_type * arg_ptr , const unsigned n1 ) 00516 : m_ptr( arg_ptr ) { md_type::assign( m_stride , n1 ); } 00517 00519 Array( value_type * arg_ptr ) 00520 : m_ptr( arg_ptr ) { md_type::assign( m_stride ); } 00521 00523 protected: 00524 00526 value_type * m_ptr ; 00527 00529 size_type m_stride[ Rank ]; 00530 00531 template< typename , ArrayOrder , 00532 class , class , class , class , 00533 class , class , class , class > 00534 friend class phdmesh::Array ; 00535 }; 00536 00537 //---------------------------------------------------------------------- 00538 00539 #ifndef DOXYGEN_COMPILE 00540 00544 template< typename Scalar > 00545 class Array<Scalar,RankZero,void,void,void,void,void,void,void,void> 00546 { 00547 public: 00548 00549 typedef Scalar value_type ; 00550 typedef unsigned size_type ; 00551 typedef const ArrayDimTag * tag_type ; 00552 00553 //---------------------------------- 00554 00555 enum { Rank = 0 }; 00556 enum { Natural = false }; 00557 enum { Reverse = false }; 00558 enum { Contiguous = true }; 00559 00560 unsigned rank() const { return Rank ; } 00561 bool natural() const { return Natural ; } 00562 bool reverse() const { return Reverse ; } 00563 bool contiguous() const { return Contiguous ; } 00564 00565 //---------------------------------- 00566 00568 size_type size() const { return m_ptr ? 1 : 0 ; } 00569 00570 //---------------------------------- 00572 value_type * contiguous_data() const { return m_ptr ; } 00573 00575 value_type & operator()() const { return *m_ptr ; } 00576 00577 //---------------------------------- 00578 // Required constructors and assignment operators: 00579 00580 Array() : m_ptr(NULL) {} 00581 00582 Array( const Array & rhs ) : m_ptr( rhs.m_ptr ) {} 00583 00584 Array & operator = ( const Array & rhs ) 00585 { m_ptr = rhs.m_ptr ; return *this ; } 00586 00587 //---------------------------------- 00588 // Class specific constructors: 00589 00590 Array( value_type * arg_ptr ) : m_ptr( arg_ptr ) {} 00591 00592 protected: 00593 00594 value_type * m_ptr ; 00595 00596 template< typename , ArrayOrder , 00597 class , class , class , class , 00598 class , class , class , class > 00599 friend class phdmesh::Array ; 00600 }; 00601 00602 #endif /* DOXYGEN_COMPILE */ 00603 //---------------------------------------------------------------------- 00604 //---------------------------------------------------------------------- 00618 template< typename Scalar , ArrayOrder array_order > 00619 class Array<Scalar,array_order,void,void,void,void,void,void,void,void> 00620 { 00621 public: 00627 typedef Scalar value_type ; 00628 00630 typedef unsigned size_type ; 00631 00633 typedef const ArrayDimTag * tag_type ; 00634 00635 //---------------------------------- 00636 00638 enum { Natural = NaturalOrder == array_order }; 00639 00641 enum { Reverse = FortranOrder == array_order }; 00642 00644 enum { Contiguous = true }; 00645 00647 unsigned rank() const { return m_rank ; } 00648 00650 bool natural() const { return Natural ; } 00651 00653 bool reverse() const { return Reverse ; } 00654 00656 bool contiguous() const { return Contiguous ; } 00657 00658 //---------------------------------- 00659 00661 tag_type tag( const unsigned ordinal ) const 00662 { 00663 array_check_ordinal( m_rank , ordinal ); 00664 const int i = Natural ? ( m_rank - 1 ) - ordinal : ordinal ; 00665 return m_tag[i]; 00666 } 00667 00668 //---------------------------------- 00669 00671 unsigned dimension( const unsigned ordinal ) const 00672 { 00673 array_check_ordinal( m_rank , ordinal ); 00674 const int i = Natural ? ( m_rank - 1 ) - ordinal : ordinal ; 00675 return i ? m_stride[i] / m_stride[i-1] : m_stride[i] ; 00676 } 00677 00679 void dimensions( std::vector<unsigned> & n ) 00680 { 00681 n.resize( m_rank ); 00682 for ( unsigned i = 0 ; i < m_rank ; ++i ) { n[i] = dimension(i); } 00683 } 00684 00686 size_type size() const { return m_stride[ m_rank - 1 ]; } 00687 00689 //---------------------------------- 00697 Array truncate( const unsigned i ) const 00698 { 00699 Array tmp ; 00700 if ( 1 < m_rank ) { 00701 tmp.m_ptr = m_ptr + m_stride[ m_rank - 2 ] * i ; 00702 tmp.m_rank = m_rank - 1 ; 00703 unsigned k ; 00704 for ( k = 0 ; k < m_rank - 1 ; ++k ) { tmp.m_stride[i] = m_stride[i] ; } 00705 for ( ; k < 8 ; ++k ) { tmp.m_stride[i] = 0 ; } 00706 for ( k = 0 ; k < m_rank - 1 ; ++k ) { tmp.m_tag[i] = m_tag[i] ; } 00707 for ( ; k < 8 ; ++k ) { tmp.m_tag[i] = NULL ; } 00708 } 00709 return tmp ; 00710 } 00711 00713 value_type * contiguous_data() const { return m_ptr ; } 00714 00716 value_type & operator[]( size_type i ) const 00717 { 00718 ARRAY_CHECK( array_check_offset(size(),i) ); 00719 return m_ptr[ i ]; 00720 } 00721 00722 //---------------------------------- 00724 value_type & operator()( const unsigned i1 , const unsigned i2 , 00725 const unsigned i3 , const unsigned i4 , 00726 const unsigned i5 , const unsigned i6 , 00727 const unsigned i7 , const unsigned i8 ) const 00728 { 00729 ARRAY_CHECK( array_check_rank( m_rank , 8 ) ); 00730 return m_ptr[ 00731 array_offset<array_order,8>(m_stride,i1,i2,i3,i4,i5,i6,i7,i8) ]; 00732 } 00733 00734 value_type & operator()( const unsigned i1 , const unsigned i2 , 00735 const unsigned i3 , const unsigned i4 , 00736 const unsigned i5 , const unsigned i6 , 00737 const unsigned i7 ) const 00738 { 00739 ARRAY_CHECK( array_check_rank( m_rank , 7 ) ); 00740 return m_ptr[ 00741 array_offset<array_order,7>(m_stride,i1,i2,i3,i4,i5,i6,i7) ]; 00742 } 00743 00744 value_type & operator()( const unsigned i1 , const unsigned i2 , 00745 const unsigned i3 , const unsigned i4 , 00746 const unsigned i5 , const unsigned i6 ) const 00747 { 00748 ARRAY_CHECK( array_check_rank( m_rank , 6 ) ); 00749 return m_ptr[ array_offset<array_order,6>(m_stride,i1,i2,i3,i4,i5,i6) ]; 00750 } 00751 00752 value_type & operator()( const unsigned i1 , const unsigned i2 , 00753 const unsigned i3 , const unsigned i4 , 00754 const unsigned i5 ) const 00755 { 00756 ARRAY_CHECK( array_check_rank( m_rank , 5 ) ); 00757 return m_ptr[ array_offset<array_order,5>(m_stride,i1,i2,i3,i4,i5) ]; 00758 } 00759 00760 value_type & operator()( const unsigned i1 , const unsigned i2 , 00761 const unsigned i3 , const unsigned i4 ) const 00762 { 00763 ARRAY_CHECK( array_check_rank( m_rank , 4 ) ); 00764 return m_ptr[ array_offset<array_order,4>(m_stride,i1,i2,i3,i4) ]; 00765 } 00766 00767 value_type & operator()( const unsigned i1 , const unsigned i2 , 00768 const unsigned i3 ) const 00769 { 00770 ARRAY_CHECK( array_check_rank( m_rank , 3 ) ); 00771 return m_ptr[ array_offset<array_order,3>(m_stride,i1,i2,i3) ]; 00772 } 00773 00774 value_type & operator()( const unsigned i1 , const unsigned i2 ) const 00775 { 00776 ARRAY_CHECK( array_check_rank( m_rank , 2 ) ); 00777 return m_ptr[ array_offset<array_order,2>(m_stride,i1,i2) ]; 00778 } 00779 00780 value_type & operator()( const unsigned i1 ) const 00781 { 00782 ARRAY_CHECK( array_check_rank( m_rank , 1 ) ); 00783 return m_ptr[ array_offset<array_order,1>(m_stride,i1) ]; 00784 } 00785 00787 //---------------------------------- 00792 typedef typename ArrayReverse< Array >::type ReverseType ; 00793 00794 //---------------------------------- 00795 00796 Array() 00797 : m_ptr(NULL), m_rank(0) 00798 { 00799 Copy<8>( m_stride , (size_type) 0 ); 00800 Copy<8>( m_tag , (tag_type) NULL ); 00801 } 00802 00803 Array( const Array & rhs ) 00804 : m_ptr( rhs.m_ptr ), m_rank( rhs.m_rank ) 00805 { 00806 Copy<8>( m_stride , rhs.m_stride ); 00807 Copy<8>( m_tag , rhs.m_tag ); 00808 } 00809 00810 Array & operator = ( const Array & rhs ) 00811 { 00812 m_ptr = rhs.m_ptr ; 00813 m_rank = rhs.m_rank ; 00814 Copy<8>( m_stride , rhs.m_stride ); 00815 Copy<8>( m_tag , rhs.m_tag ); 00816 return *this ; 00817 } 00818 00820 Array( const ReverseType & rhs ) 00821 : m_ptr( rhs.m_ptr ), m_rank( rhs.m_rank ) 00822 { 00823 Copy<8>( m_stride , rhs.m_stride ); 00824 Copy<8>( m_tag , rhs.m_tag ); 00825 } 00826 00828 Array & operator = ( const ReverseType & rhs ) 00829 { 00830 m_ptr = rhs.m_ptr ; 00831 m_rank = rhs.m_rank ; 00832 Copy<8>( m_stride , rhs.m_stride ); 00833 Copy<8>( m_tag , rhs.m_tag ); 00834 return *this ; 00835 } 00836 00837 //---------------------------------- 00838 00842 template< ArrayOrder order , 00843 class Tag1 , class Tag2 , class Tag3 , class Tag4 , 00844 class Tag5 , class Tag6 , class Tag7 , class Tag8 > 00845 Array( 00846 const Array<value_type,order,Tag1,Tag2,Tag3,Tag4,Tag5,Tag6,Tag7,Tag8> & rhs ) 00847 : m_ptr( rhs.m_ptr ), m_rank( 0 ) 00848 { 00849 typedef Array<value_type,order,Tag1,Tag2,Tag3,Tag4,Tag5,Tag6,Tag7,Tag8> a_t ; 00850 enum { inRank = a_t::Rank }; 00851 enum { inNatural = a_t::Natural }; 00852 m_rank = inRank ; 00853 Copy< inRank >( m_stride , rhs.m_stride ); 00854 Copy< 8 - inRank >( m_stride + inRank , (size_type) 0 ); 00855 unsigned i = 0 ; 00856 if ( inNatural ) { 00857 for ( ; i < inRank ; ++i ) { m_tag[i] = rhs.tag((inRank-1)-i); } 00858 } 00859 else { 00860 for ( ; i < inRank ; ++i ) { m_tag[i] = rhs.tag(i); } 00861 } 00862 for ( ; i < 8 ; ++i ) { m_tag[i] = NULL ; } 00863 } 00864 00865 //---------------------------------- 00866 // Class specific constructors: 00867 00868 Array( value_type * ptr , 00869 const unsigned rank , 00870 const unsigned * const dims , 00871 const tag_type * const tags ) 00872 : m_ptr( ptr ), m_rank( rank ) 00873 { 00874 if ( Natural ) { 00875 size_type n = 1 ; 00876 unsigned i ; 00877 for ( i = 0 ; i < rank ; ++i ) { m_stride[i] = n *= dims[(rank-1)-i]; } 00878 for ( ; i < 8 ; ++i ) { m_stride[i] = 0 ; } 00879 for ( i = 0 ; i < rank ; ++i ) { m_tag[i] = tags[(rank-1)-i]; } 00880 for ( ; i < 8 ; ++i ) { m_tag[i] = NULL ; } 00881 } 00882 else { 00883 size_type n = 1 ; 00884 unsigned i ; 00885 for ( i = 0 ; i < rank ; ++i ) { m_stride[i] = n *= dims[i] ; } 00886 for ( ; i < 8 ; ++i ) { m_stride[i] = 0 ; } 00887 for ( i = 0 ; i < rank ; ++i ) { m_tag[i] = tags[i]; } 00888 for ( ; i < 8 ; ++i ) { m_tag[i] = NULL ; } 00889 } 00890 } 00891 00893 protected: 00894 00896 value_type * m_ptr ; 00897 00899 unsigned m_rank ; 00900 00902 size_type m_stride[8]; 00903 00905 tag_type m_tag[8] ; 00906 00907 template< typename , ArrayOrder , 00908 class , class , class , class , 00909 class , class , class , class > 00910 friend class phdmesh::Array ; 00911 }; 00912 00913 //---------------------------------------------------------------------- 00914 //---------------------------------------------------------------------- 00915 00916 } // namespace phdmesh 00917 00918 #undef ARRAY_CHECK 00919 00920 #endif 00921
1.7.4