NamedValue.hpp

00001 /*------------------------------------------------------------------------*/
00002 /*      phdMesh : Parallel Heterogneous Dynamic unstructured Mesh         */
00003 /*                Copyright (2007) 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 /*------------------------------------------------------------------------*/
00028 #ifndef util_NamedValue_hpp
00029 #define util_NamedValue_hpp
00030 
00031 #include <typeinfo>
00032 #include <iostream>
00033 #include <string>
00034 #include <vector>
00035 #include <limits>
00036 #include <cstring>
00037 #include <util/TypeName.hpp>
00038 
00039 using std::memcpy;
00040 
00041 namespace phdmesh {
00042 
00043 template< typename T = void > class NamedValue ;
00044 
00045 class NamedValueSet ;
00046 
00047 std::istream & operator >> ( std::istream & s , NamedValueSet & v );
00048 std::ostream & operator << ( std::ostream & s , const NamedValueSet & v );
00049 
00050 }
00051 
00052 //----------------------------------------------------------------------
00053 
00054 namespace phdmesh {
00055 
00056 class NamedValueSet {
00057 public:
00058   const std::vector< NamedValue<void> * > get() const { return m_members ; }
00059 
00060   NamedValue<void> *
00061     find( const std::string & s , const char sep = '.' ) const ;
00062 
00063   NamedValue<void> * insert( NamedValue<void> * );
00064 
00065   void remove( NamedValue<void> * );
00066   void clear();
00067 
00068   ~NamedValueSet();
00069   NamedValueSet();
00070 private:
00071   NamedValueSet( const NamedValueSet & );
00072   NamedValueSet & operator = ( const NamedValueSet & );
00073   std::vector< NamedValue<void> * > m_members ;
00074 };
00075 
00076 //----------------------------------------------------------------------
00080 template<>
00081 class NamedValue<void> {
00082 public:
00083   const std::string      name ;
00084   const std::type_info & type ;
00085 
00086   //----------------------------------
00087 
00088   virtual     unsigned get_max() const = 0 ;
00089   virtual     unsigned put_max() const = 0 ;
00090 
00091   virtual       void * put_void( unsigned ) = 0 ;
00092   virtual const void * get_void( unsigned ) const = 0 ;
00093 
00094   virtual void     tell(  std::ostream & ) const = 0 ;
00095   virtual void     write( std::ostream & ) const = 0 ;
00096   virtual unsigned read(  std::istream & ) = 0 ;
00097 
00098   virtual ~NamedValue();
00099 
00100   //----------------------------------
00101 
00102   template<typename T>
00103   const T & get( unsigned i = 0 ) const
00104     {
00105       const std::type_info & t = typeid(T);
00106       const void * const p = get_void(i);
00107       if ( t != type || NULL == p ) { get_throw(t,i); }
00108       return * ( (const T *) p );
00109     }
00110 
00111   template<typename T>
00112   T & put( unsigned i = 0 )
00113     {
00114       const std::type_info & t = typeid(T);
00115       void * const p = put_void(i);
00116       if ( t != type || NULL == p ) { put_throw(t,i); }
00117       return * ( (T *) p );
00118     }
00119 
00120   //----------------------------------
00121 
00123   virtual unsigned pack( void * ) const = 0 ;
00124 
00126   virtual unsigned unpack( void * ) = 0 ;
00127 
00128   //----------------------------------
00129 
00130   const std::vector< NamedValueSet * > references() const ;
00131 
00132 protected:
00133 
00134   NamedValue( const std::string & n , const std::type_info & t )
00135     : name(n), type(t) {}
00136 
00137 private:
00138 
00139   friend class NamedValueSet ;
00140 
00141   std::vector< NamedValueSet * > m_holders ;
00142 
00143   void get_throw( const std::type_info & , unsigned ) const ;
00144   void put_throw( const std::type_info & , unsigned ) const ;
00145 
00146   NamedValue();
00147   NamedValue( const NamedValue & );
00148   NamedValue & operator = ( const NamedValue & );
00149 };
00150 
00151 //----------------------------------------------------------------------
00152 
00153 namespace {
00154 
00155 template< typename T >
00156 unsigned read_array( std::istream & s , T * const v , const unsigned n )
00157 {
00158   unsigned i = 0 ;
00159   while ( i < n && ( s >> v[i] ) ) { ++i ; }
00160   s.clear( s.rdstate() & ~std::ios::failbit );
00161   return i ;
00162 }
00163 
00164 template< typename T >
00165 unsigned read_vector( std::istream & s , std::vector<T> & v )
00166 {
00167   const unsigned n = v.size();
00168   unsigned i = 0 ;
00169   for ( T tmp ; s >> tmp ; ++i ) {
00170     if ( i < n ) { v[i] = tmp ; } 
00171     else { v.push_back( tmp ); }
00172   }
00173   s.clear( s.rdstate() & ~std::ios::failbit );
00174   return i ;
00175 }
00176 
00177 template< typename T >
00178 void write_array( std::ostream & s , const T * const v , const unsigned n )
00179 {
00180   for ( unsigned i = 0 ; i < n ; ++i ) {
00181     if ( i ) { s << " " ; }
00182     s << v[i] ;
00183   }
00184 }
00185 
00186 template< typename T >
00187 unsigned pack_array( void * b , const T * const p , unsigned n )
00188 {
00189   n = ((const unsigned char *)(p+n)) - ((const unsigned char *)(p));
00190   if ( b ) { memcpy( b , p , n ); }
00191   return n ;
00192 }
00193 
00194 template< typename T >
00195 unsigned unpack_array( const void * b , T * const p , unsigned n )
00196 {
00197   if ( b ) {
00198     n = ((unsigned char *)(p+n)) - ((unsigned char *)(p));
00199     memcpy( p , b , n );
00200   }
00201   else {
00202     n = 0 ;
00203   }
00204   return n ;
00205 }
00206 
00207 template< typename T >
00208 unsigned pack_vector( void * b , const std::vector<T> & v )
00209 {
00210   const unsigned n = v.size();
00211   if ( b ) {
00212     memcpy( b , & n , sizeof(unsigned) );
00213     b = ((unsigned char *)b) + sizeof(unsigned);
00214   }
00215   return sizeof(unsigned) + pack_array<T>( b , & v[0] , n );
00216 }
00217 
00218 template< typename T >
00219 unsigned unpack_vector( void * b , std::vector<T> & v )
00220 {
00221   unsigned n = 0 ;
00222   if ( b ) {
00223     memcpy( & n , b , sizeof(unsigned) );
00224     b = ((unsigned char *)b) + sizeof(unsigned);
00225     if ( v.size() < n ) { v.resize(n); }
00226     n = sizeof(unsigned) + unpack_array<T>( b , & v[0] , n );
00227   }
00228   return n ;
00229 }
00230 
00231 unsigned pack_value( void * b , const std::string & s )
00232 {
00233   const unsigned n = s.size() + 1 ;
00234   if ( b ) { memcpy( b , s.c_str() , n ); }
00235   return n ;
00236 }
00237 
00238 unsigned unpack_value( void * b , std::string & s )
00239 {
00240   unsigned n = 0 ;
00241   if ( b ) { s.assign( (char *) b ); n = s.size() + 1 ; }
00242   return n ;
00243 }
00244 
00245 template< typename T >
00246 unsigned pack_value( void * b , const T & v )
00247 {
00248   const unsigned n = sizeof(T);
00249   if ( b ) { memcpy( b , & v , n ); }
00250   return n ;
00251 }
00252 
00253 template< typename T >
00254 unsigned unpack_value( void * b , T & v )
00255 {
00256   unsigned n = 0 ;
00257   if ( b ) { memcpy( & v , b , n = sizeof(T) ); }
00258   return n ;
00259 }
00260 
00261 }
00262 
00263 //----------------------------------------------------------------------
00267 template< typename T >
00268 class NamedValue : public NamedValue<void> {
00269 public:
00270 
00271   T value ;
00272 
00273   ~NamedValue() {}
00274 
00276   NamedValue( const std::string & n ) : NamedValue<void>( n , typeid(T) ) {}
00277   NamedValue( const std::string & n , const T & v )
00278     : NamedValue<void>( n , typeid(T) ), value(v) {}
00279 
00281   void tell( std::ostream & s ) const
00282     { s << name << " = " << TypeName<T>::value(); }
00283 
00285   void write( std::ostream & s ) const { s << value ; }
00286 
00288   unsigned read( std::istream & s ) { return s >> value ? 1 : 0 ; }
00289 
00290   unsigned pack(   void * b ) const { return pack_value( b , value ); }
00291   unsigned unpack( void * b )       { return unpack_value( b , value ); }
00292 
00293 private:
00294 
00295         unsigned get_max() const { return 1 ; }
00296         unsigned put_max() const { return 1 ; }
00297         void * put_void( unsigned i )       { return i ? NULL : & value ; }
00298   const void * get_void( unsigned i ) const { return i ? NULL : & value ; }
00299 
00300   NamedValue();
00301   NamedValue( const NamedValue & );
00302   NamedValue & operator = ( const NamedValue & );
00303 };
00304 
00305 //----------------------------------------------------------------------
00309 template< typename T >
00310 class NamedValue< T & > : public NamedValue<void> {
00311 public:
00312 
00313   T & ref ;
00314 
00315   ~NamedValue() {}
00316 
00318   NamedValue( const std::string & n , T & v )
00319     : NamedValue<void>( n , typeid(T) ), ref(v) {}
00320 
00322   void tell( std::ostream & s ) const
00323     { s << name << " = " << TypeName<T &>::value(); }
00324 
00326   void write( std::ostream & s ) const { s << ref ; }
00327 
00329   unsigned read( std::istream & s ) { return s >> ref ? 1 : 0 ; }
00330 
00331   unsigned pack(   void * b ) const { return pack_value( b , ref ); }
00332   unsigned unpack( void * b )       { return unpack_value( b , ref ); }
00333 
00334 private:
00335 
00336         unsigned get_max() const { return 1 ; }
00337         unsigned put_max() const { return 1 ; }
00338         void * put_void( unsigned i )       { return i ? NULL : & ref ; }
00339   const void * get_void( unsigned i ) const { return i ? NULL : & ref ; }
00340 
00341   NamedValue();
00342   NamedValue( const NamedValue & );
00343   NamedValue & operator = ( const NamedValue & );
00344 };
00345 
00346 //----------------------------------------------------------------------
00350 template< typename T >
00351 class NamedValue< const T & > : public NamedValue<void> {
00352 public:
00353   const T & ref ;
00354 
00355   NamedValue( const std::string & n , const T & v )
00356     : NamedValue<void>( n , typeid(T) ), ref(v) {}
00357 
00358   ~NamedValue() {}
00359 
00360   void write( std::ostream & s ) const { s << ref ; }
00361 
00362   unsigned read( std::istream & ) { return 0 ; }
00363 
00364   void tell( std::ostream & s ) const
00365     { s << name << " = " << TypeName<const T &>::value(); }
00366 
00367   unsigned pack( void * b ) const { return pack_value( b , ref ); }
00368 
00369   unsigned unpack( void * b ) { return 0 ; }
00370 
00371 private:
00372 
00373         unsigned get_max() const { return 1 ; }
00374         unsigned put_max() const { return 0 ; }
00375         void * put_void( unsigned i ) { return NULL ; }
00376   const void * get_void( unsigned i ) const { return i ? NULL : & ref ; }
00377 
00378   NamedValue();
00379   NamedValue( const NamedValue & );
00380   NamedValue & operator = ( const NamedValue & );
00381 };
00382 
00383 //----------------------------------------------------------------------
00384 
00388 template< typename T , unsigned N >
00389 class NamedValue< T[N] > : public NamedValue<void> {
00390 public:
00391   T value[N] ;
00392 
00393   NamedValue( const std::string & n ) : NamedValue<void>( n , typeid(T) ) {}
00394 
00395   ~NamedValue() {}
00396 
00397   void write( std::ostream & s ) const { write_array<T>(s,value,N); }
00398 
00399   unsigned read( std::istream & s ) { return read_array<T>(s,value,N); }
00400 
00401   void tell( std::ostream & s ) const
00402     { s << name << " = " << TypeName<T[N]>::value(); }
00403 
00404   unsigned pack(   void * b ) const { return pack_array<T>( b , value, N); }
00405   unsigned unpack( void * b )       { return unpack_array<T>(b, value, N); }
00406 
00407 private:
00408 
00409         unsigned get_max() const { return N ; }
00410         unsigned put_max() const { return N ; }
00411         void * put_void( unsigned i )       { return i ? NULL : value + i ; }
00412   const void * get_void( unsigned i ) const { return i ? NULL : value + i ; }
00413 
00414   NamedValue();
00415   NamedValue( const NamedValue & );
00416   NamedValue & operator = ( const NamedValue & );
00417 };
00418 
00419 //----------------------------------------------------------------------
00423 template< typename T >
00424 class NamedValue< T * > : public NamedValue<void> {
00425 public:
00426   T * const      ref ;
00427   const unsigned size ;
00428 
00429   NamedValue( const std::string & n , T * v , unsigned s )
00430     : NamedValue<void>( n , typeid(T) ), ref(v), size(s) {}
00431 
00432   ~NamedValue() {}
00433 
00434   void write( std::ostream & s ) const { write_array<T>(s,ref,size); }
00435 
00436   unsigned read( std::istream & s )
00437     { return read_array<T>(s,ref,size); }
00438 
00439   void tell( std::ostream & s ) const
00440     { s << name << " = " << type_name_array<T>(size) << " *" ; }
00441 
00442   unsigned pack(   void * b ) const { return pack_array<T>(  b,ref,size); }
00443   unsigned unpack( void * b )       { return unpack_array<T>(b,ref,size); }
00444 
00445 private:
00446 
00447         unsigned get_max() const { return size ; }
00448         unsigned put_max() const { return size ; }
00449         void * put_void(unsigned i)       {return i < size ? ref+i : NULL;}
00450   const void * get_void(unsigned i) const {return i < size ? ref+i : NULL;}
00451 
00452   NamedValue();
00453   NamedValue( const NamedValue & );
00454   NamedValue & operator = ( const NamedValue & );
00455 };
00456 
00457 
00461 template< typename T >
00462 class NamedValue< const T * > : public NamedValue<void> {
00463 public:
00464   const T * const ref ;
00465   const unsigned  size ;
00466 
00467   NamedValue( const std::string & n , const T * v , unsigned s )
00468     : NamedValue<void>( n , typeid(T) ), ref(v), size(s) {}
00469 
00470   ~NamedValue() {}
00471 
00472   void write( std::ostream & s ) const { write_array<T>(s,ref,size); }
00473   unsigned read( std::istream & ){ return 0 ; }
00474 
00475   void tell( std::ostream & s ) const
00476     { s << name << " = " << type_name_array<const T>(size) << " *" ; }
00477 
00478   unsigned pack( void * b ) const { return pack_array<T>(b,ref,size); }
00479   unsigned unpack( void * b ) { return 0 ; }
00480 
00481 private:
00482 
00483         unsigned get_max() const { return size ; }
00484         unsigned put_max() const { return 0 ; }
00485         void * put_void(unsigned ) {return NULL ; }
00486   const void * get_void(unsigned i) const {return i < size ? ref+i : NULL;}
00487 
00488   NamedValue();
00489   NamedValue( const NamedValue & );
00490   NamedValue & operator = ( const NamedValue & );
00491 };
00492 
00493 //----------------------------------------------------------------------
00497 template< typename T >
00498 class NamedValue< std::vector<T> > : public NamedValue<void> {
00499 public:
00500   std::vector<T> value ;
00501 
00502   NamedValue( const std::string & n ) : NamedValue<void>( n , typeid(T) ) {}
00503 
00504   NamedValue( const std::string & n , const std::vector<T> & v )
00505     : NamedValue<void>( n , typeid(T) ), value(v) {}
00506 
00507   ~NamedValue() {}
00508 
00509   void tell( std::ostream & s ) const
00510     { s << name << " = " << type_name_vector<T>( value.size() ); }
00511 
00512   void write( std::ostream & s ) const
00513     { write_array<T>( s , & value[0] , value.size() ); }
00514 
00515   unsigned read( std::istream & s )
00516     { return read_vector<T>( s , value ); }
00517 
00518   unsigned pack( void * b ) const { return pack_vector<T>( b , value ); }
00519 
00520   unsigned unpack( void * b ) { return unpack_vector<T>( b , value ); }
00521 
00522 private:
00523 
00524   unsigned get_max() const { return value.size(); }
00525   unsigned put_max() const { return std::numeric_limits<unsigned>::max(); }
00526 
00527   void * put_void( unsigned i )
00528     {
00529       if ( value.size() <= i ) { value.resize(i+1); }
00530       return & value[i] ;
00531     }
00532 
00533   const void * get_void( unsigned i ) const
00534     { return i < value.size() ? & value[i] : NULL ; }
00535 
00536   NamedValue();
00537   NamedValue( const NamedValue & );
00538   NamedValue & operator = ( const NamedValue & );
00539 };
00540 
00541 template< typename T >
00542 class NamedValue< std::vector<T> & > : public NamedValue<void> {
00543 public:
00544   std::vector<T> & ref ;
00545 
00546   NamedValue( const std::string & n , std::vector<T> & v )
00547     : NamedValue<void>( n , typeid(T) ), ref(v) {}
00548 
00549   ~NamedValue() {}
00550 
00551   void tell( std::ostream & s ) const
00552     { s << name << " = " << type_name_vector<T>( ref.size() ) << " &" ; }
00553 
00554   void write( std::ostream & s ) const
00555     { write_array<T>( s , & ref[0] , ref.size() ); }
00556 
00557   unsigned read( std::istream & s )
00558     { return read_vector<T>( s , ref ); }
00559 
00560   unsigned pack( void * b ) const { return pack_vector<T>( b , ref ); }
00561 
00562   unsigned unpack( void * b ) { return unpack_vector<T>( b , ref ); }
00563 
00564 private:
00565 
00566   unsigned get_max() const { return ref.size(); }
00567   unsigned put_max() const { return std::numeric_limits<unsigned>::max(); }
00568 
00569   void * put_void( unsigned i )
00570     {
00571       if ( ref.size() <= i ) { ref.resize(i+1); }
00572       return & ref[i] ;
00573     }
00574 
00575   const void * get_void( unsigned i ) const
00576     { return i < ref.size() ? & ref[i] : NULL ; }
00577 
00578   NamedValue();
00579   NamedValue( const NamedValue & );
00580   NamedValue & operator = ( const NamedValue & );
00581 };
00582 
00583 //----------------------------------------------------------------------
00587 template< typename T >
00588 class NamedValue< const std::vector<T> & > : public NamedValue<void> {
00589 public:
00590   const std::vector<T> & ref ;
00591 
00592   explicit NamedValue( const std::string & n , const std::vector<T> & arg )
00593     : NamedValue<void>( n , typeid(T) ), ref(arg) {}
00594 
00595   ~NamedValue() {}
00596 
00597   void tell( std::ostream & s ) const
00598     { s << name << " = " << type_name_vector<const T>( ref.size() ) << " &" ; }
00599 
00600   void write( std::ostream & s ) const
00601     { write_array<T>( s , & ref[0] , ref.size() ); }
00602 
00603   unsigned read( std::istream & ) { return 0 ; }
00604 
00605   unsigned pack( void * b ) const { return pack_vector<T>( b , ref ); }
00606 
00607   unsigned unpack( void * b ) { return 0 ; }
00608 
00609 private:
00610 
00611   unsigned get_max() const { return ref.size(); }
00612   unsigned put_max() const { return 0 ; }
00613 
00614   void * put_void( unsigned ) { return NULL ; }
00615 
00616   const void * get_void( unsigned i ) const
00617     { return i < ref.size() ? & ref[i] : NULL ; }
00618 
00619   NamedValue();
00620   NamedValue( const NamedValue & );
00621   NamedValue & operator = ( const NamedValue & );
00622 };
00623 
00624 //----------------------------------------------------------------------
00625 //----------------------------------------------------------------------
00626 
00627 template<>
00628 class NamedValue< NamedValueSet > : public NamedValue<void> {
00629 public:
00630   NamedValueSet value ;
00631 
00632   ~NamedValue();
00633 
00634   NamedValue( const std::string & n )
00635     : NamedValue<void>( n , typeid(NamedValueSet) ) {}
00636 
00637   void tell( std::ostream & ) const ;
00638 
00639   void     write( std::ostream & s ) const { s << value ; }
00640   unsigned read(  std::istream & s ) { return s >> value ? 1 : 0 ; }
00641 
00642   //----------------------------------
00643 
00645   unsigned pack( void * ) const ;
00646 
00648   unsigned unpack( void * );
00649 
00650 private:
00651 
00652         unsigned get_max() const { return 1 ; }
00653         unsigned put_max() const { return 1 ; }
00654         void * put_void( unsigned i )       { return i ? NULL : & value ; }
00655   const void * get_void( unsigned i ) const { return i ? NULL : & value ; }
00656 
00657 
00658   NamedValue();
00659   NamedValue( const NamedValue & );
00660   NamedValue & operator = ( const NamedValue & );
00661 };
00662 
00663 
00664 } // namespace phdmesh
00665 
00666 //----------------------------------------------------------------------
00667 
00668 #endif
00669 

Generated on Tue Jul 13 09:22:43 2010 for phdMesh by  doxygen 1.4.7