phdMesh Version of the Day
Array.hpp
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 
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator