|
phdMesh Version of the Day
|
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
1.7.4