00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
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 }
00665
00666
00667
00668 #endif
00669