phdMesh  Version of the Day
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Groups
NamedValue.hpp
1 /*------------------------------------------------------------------------*/
2 /* phdMesh : Parallel Heterogneous Dynamic unstructured Mesh */
3 /* Copyright (2007) Sandia Corporation */
4 /* */
5 /* Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive */
6 /* license for use of this work by or on behalf of the U.S. Government. */
7 /* */
8 /* This library is free software; you can redistribute it and/or modify */
9 /* it under the terms of the GNU Lesser General Public License as */
10 /* published by the Free Software Foundation; either version 2.1 of the */
11 /* License, or (at your option) any later version. */
12 /* */
13 /* This library is distributed in the hope that it will be useful, */
14 /* but WITHOUT ANY WARRANTY; without even the implied warranty of */
15 /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU */
16 /* Lesser General Public License for more details. */
17 /* */
18 /* You should have received a copy of the GNU Lesser General Public */
19 /* License along with this library; if not, write to the Free Software */
20 /* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 */
21 /* USA */
22 /*------------------------------------------------------------------------*/
28 #ifndef util_NamedValue_hpp
29 #define util_NamedValue_hpp
30 
31 #include <typeinfo>
32 #include <iostream>
33 #include <string>
34 #include <vector>
35 #include <limits>
36 #include <cstring>
37 #include <util/TypeName.hpp>
38 
39 using std::memcpy;
40 
41 namespace phdmesh {
42 
43 template< typename T = void > class NamedValue ;
44 
45 class NamedValueSet ;
46 
47 std::istream & operator >> ( std::istream & s , NamedValueSet & v );
48 std::ostream & operator << ( std::ostream & s , const NamedValueSet & v );
49 
50 }
51 
52 //----------------------------------------------------------------------
53 
54 namespace phdmesh {
55 
56 class NamedValueSet {
57 public:
58  const std::vector< NamedValue<void> * > get() const { return m_members ; }
59 
60  NamedValue<void> *
61  find( const std::string & s , const char sep = '.' ) const ;
62 
63  NamedValue<void> * insert( NamedValue<void> * );
64 
65  void remove( NamedValue<void> * );
66  void clear();
67 
68  ~NamedValueSet();
69  NamedValueSet();
70 private:
71  NamedValueSet( const NamedValueSet & );
72  NamedValueSet & operator = ( const NamedValueSet & );
73  std::vector< NamedValue<void> * > m_members ;
74 };
75 
76 //----------------------------------------------------------------------
80 template<>
81 class NamedValue<void> {
82 public:
83  const std::string name ;
84  const std::type_info & type ;
85 
86  //----------------------------------
87 
88  virtual unsigned get_max() const = 0 ;
89  virtual unsigned put_max() const = 0 ;
90 
91  virtual void * put_void( unsigned ) = 0 ;
92  virtual const void * get_void( unsigned ) const = 0 ;
93 
94  virtual void tell( std::ostream & ) const = 0 ;
95  virtual void write( std::ostream & ) const = 0 ;
96  virtual unsigned read( std::istream & ) = 0 ;
97 
98  virtual ~NamedValue();
99 
100  //----------------------------------
101 
102  template<typename T>
103  const T & get( unsigned i = 0 ) const
104  {
105  const std::type_info & t = typeid(T);
106  const void * const p = get_void(i);
107  if ( t != type || NULL == p ) { get_throw(t,i); }
108  return * ( (const T *) p );
109  }
110 
111  template<typename T>
112  T & put( unsigned i = 0 )
113  {
114  const std::type_info & t = typeid(T);
115  void * const p = put_void(i);
116  if ( t != type || NULL == p ) { put_throw(t,i); }
117  return * ( (T *) p );
118  }
119 
120  //----------------------------------
121 
123  virtual unsigned pack( void * ) const = 0 ;
124 
126  virtual unsigned unpack( void * ) = 0 ;
127 
128  //----------------------------------
129 
130  const std::vector< NamedValueSet * > references() const ;
131 
132 protected:
133 
134  NamedValue( const std::string & n , const std::type_info & t )
135  : name(n), type(t) {}
136 
137 private:
138 
139  friend class NamedValueSet ;
140 
141  std::vector< NamedValueSet * > m_holders ;
142 
143  void get_throw( const std::type_info & , unsigned ) const ;
144  void put_throw( const std::type_info & , unsigned ) const ;
145 
146  NamedValue();
147  NamedValue( const NamedValue & );
148  NamedValue & operator = ( const NamedValue & );
149 };
150 
151 //----------------------------------------------------------------------
152 
153 namespace {
154 
155 template< typename T >
156 unsigned read_array( std::istream & s , T * const v , const unsigned n )
157 {
158  unsigned i = 0 ;
159  while ( i < n && ( s >> v[i] ) ) { ++i ; }
160  s.clear( s.rdstate() & ~std::ios::failbit );
161  return i ;
162 }
163 
164 template< typename T >
165 unsigned read_vector( std::istream & s , std::vector<T> & v )
166 {
167  const unsigned n = v.size();
168  unsigned i = 0 ;
169  for ( T tmp ; s >> tmp ; ++i ) {
170  if ( i < n ) { v[i] = tmp ; }
171  else { v.push_back( tmp ); }
172  }
173  s.clear( s.rdstate() & ~std::ios::failbit );
174  return i ;
175 }
176 
177 template< typename T >
178 void write_array( std::ostream & s , const T * const v , const unsigned n )
179 {
180  for ( unsigned i = 0 ; i < n ; ++i ) {
181  if ( i ) { s << " " ; }
182  s << v[i] ;
183  }
184 }
185 
186 template< typename T >
187 unsigned pack_array( void * b , const T * const p , unsigned n )
188 {
189  n = ((const unsigned char *)(p+n)) - ((const unsigned char *)(p));
190  if ( b ) { memcpy( b , p , n ); }
191  return n ;
192 }
193 
194 template< typename T >
195 unsigned unpack_array( const void * b , T * const p , unsigned n )
196 {
197  if ( b ) {
198  n = ((unsigned char *)(p+n)) - ((unsigned char *)(p));
199  memcpy( p , b , n );
200  }
201  else {
202  n = 0 ;
203  }
204  return n ;
205 }
206 
207 template< typename T >
208 unsigned pack_vector( void * b , const std::vector<T> & v )
209 {
210  const unsigned n = v.size();
211  if ( b ) {
212  memcpy( b , & n , sizeof(unsigned) );
213  b = ((unsigned char *)b) + sizeof(unsigned);
214  }
215  return sizeof(unsigned) + pack_array<T>( b , & v[0] , n );
216 }
217 
218 template< typename T >
219 unsigned unpack_vector( void * b , std::vector<T> & v )
220 {
221  unsigned n = 0 ;
222  if ( b ) {
223  memcpy( & n , b , sizeof(unsigned) );
224  b = ((unsigned char *)b) + sizeof(unsigned);
225  if ( v.size() < n ) { v.resize(n); }
226  n = sizeof(unsigned) + unpack_array<T>( b , & v[0] , n );
227  }
228  return n ;
229 }
230 
231 unsigned pack_value( void * b , const std::string & s )
232 {
233  const unsigned n = s.size() + 1 ;
234  if ( b ) { memcpy( b , s.c_str() , n ); }
235  return n ;
236 }
237 
238 unsigned unpack_value( void * b , std::string & s )
239 {
240  unsigned n = 0 ;
241  if ( b ) { s.assign( (char *) b ); n = s.size() + 1 ; }
242  return n ;
243 }
244 
245 template< typename T >
246 unsigned pack_value( void * b , const T & v )
247 {
248  const unsigned n = sizeof(T);
249  if ( b ) { memcpy( b , & v , n ); }
250  return n ;
251 }
252 
253 template< typename T >
254 unsigned unpack_value( void * b , T & v )
255 {
256  unsigned n = 0 ;
257  if ( b ) { memcpy( & v , b , n = sizeof(T) ); }
258  return n ;
259 }
260 
261 }
262 
263 //----------------------------------------------------------------------
267 template< typename T >
268 class NamedValue : public NamedValue<void> {
269 public:
270 
271  T value ;
272 
273  ~NamedValue() {}
274 
276  NamedValue( const std::string & n ) : NamedValue<void>( n , typeid(T) ) {}
277  NamedValue( const std::string & n , const T & v )
278  : NamedValue<void>( n , typeid(T) ), value(v) {}
279 
281  void tell( std::ostream & s ) const
282  { s << name << " = " << TypeName<T>::value(); }
283 
285  void write( std::ostream & s ) const { s << value ; }
286 
288  unsigned read( std::istream & s ) { return s >> value ? 1 : 0 ; }
289 
290  unsigned pack( void * b ) const { return pack_value( b , value ); }
291  unsigned unpack( void * b ) { return unpack_value( b , value ); }
292 
293 private:
294 
295  unsigned get_max() const { return 1 ; }
296  unsigned put_max() const { return 1 ; }
297  void * put_void( unsigned i ) { return i ? NULL : & value ; }
298  const void * get_void( unsigned i ) const { return i ? NULL : & value ; }
299 
300  NamedValue();
301  NamedValue( const NamedValue & );
302  NamedValue & operator = ( const NamedValue & );
303 };
304 
305 //----------------------------------------------------------------------
309 template< typename T >
310 class NamedValue< T & > : public NamedValue<void> {
311 public:
312 
313  T & ref ;
314 
315  ~NamedValue() {}
316 
318  NamedValue( const std::string & n , T & v )
319  : NamedValue<void>( n , typeid(T) ), ref(v) {}
320 
322  void tell( std::ostream & s ) const
323  { s << name << " = " << TypeName<T &>::value(); }
324 
326  void write( std::ostream & s ) const { s << ref ; }
327 
329  unsigned read( std::istream & s ) { return s >> ref ? 1 : 0 ; }
330 
331  unsigned pack( void * b ) const { return pack_value( b , ref ); }
332  unsigned unpack( void * b ) { return unpack_value( b , ref ); }
333 
334 private:
335 
336  unsigned get_max() const { return 1 ; }
337  unsigned put_max() const { return 1 ; }
338  void * put_void( unsigned i ) { return i ? NULL : & ref ; }
339  const void * get_void( unsigned i ) const { return i ? NULL : & ref ; }
340 
341  NamedValue();
342  NamedValue( const NamedValue & );
343  NamedValue & operator = ( const NamedValue & );
344 };
345 
346 //----------------------------------------------------------------------
350 template< typename T >
351 class NamedValue< const T & > : public NamedValue<void> {
352 public:
353  const T & ref ;
354 
355  NamedValue( const std::string & n , const T & v )
356  : NamedValue<void>( n , typeid(T) ), ref(v) {}
357 
358  ~NamedValue() {}
359 
360  void write( std::ostream & s ) const { s << ref ; }
361 
362  unsigned read( std::istream & ) { return 0 ; }
363 
364  void tell( std::ostream & s ) const
365  { s << name << " = " << TypeName<const T &>::value(); }
366 
367  unsigned pack( void * b ) const { return pack_value( b , ref ); }
368 
369  unsigned unpack( void * b ) { return 0 ; }
370 
371 private:
372 
373  unsigned get_max() const { return 1 ; }
374  unsigned put_max() const { return 0 ; }
375  void * put_void( unsigned i ) { return NULL ; }
376  const void * get_void( unsigned i ) const { return i ? NULL : & ref ; }
377 
378  NamedValue();
379  NamedValue( const NamedValue & );
380  NamedValue & operator = ( const NamedValue & );
381 };
382 
383 //----------------------------------------------------------------------
384 
388 template< typename T , unsigned N >
389 class NamedValue< T[N] > : public NamedValue<void> {
390 public:
391  T value[N] ;
392 
393  NamedValue( const std::string & n ) : NamedValue<void>( n , typeid(T) ) {}
394 
395  ~NamedValue() {}
396 
397  void write( std::ostream & s ) const { write_array<T>(s,value,N); }
398 
399  unsigned read( std::istream & s ) { return read_array<T>(s,value,N); }
400 
401  void tell( std::ostream & s ) const
402  { s << name << " = " << TypeName<T[N]>::value(); }
403 
404  unsigned pack( void * b ) const { return pack_array<T>( b , value, N); }
405  unsigned unpack( void * b ) { return unpack_array<T>(b, value, N); }
406 
407 private:
408 
409  unsigned get_max() const { return N ; }
410  unsigned put_max() const { return N ; }
411  void * put_void( unsigned i ) { return i ? NULL : value + i ; }
412  const void * get_void( unsigned i ) const { return i ? NULL : value + i ; }
413 
414  NamedValue();
415  NamedValue( const NamedValue & );
416  NamedValue & operator = ( const NamedValue & );
417 };
418 
419 //----------------------------------------------------------------------
423 template< typename T >
424 class NamedValue< T * > : public NamedValue<void> {
425 public:
426  T * const ref ;
427  const unsigned size ;
428 
429  NamedValue( const std::string & n , T * v , unsigned s )
430  : NamedValue<void>( n , typeid(T) ), ref(v), size(s) {}
431 
432  ~NamedValue() {}
433 
434  void write( std::ostream & s ) const { write_array<T>(s,ref,size); }
435 
436  unsigned read( std::istream & s )
437  { return read_array<T>(s,ref,size); }
438 
439  void tell( std::ostream & s ) const
440  { s << name << " = " << type_name_array<T>(size) << " *" ; }
441 
442  unsigned pack( void * b ) const { return pack_array<T>( b,ref,size); }
443  unsigned unpack( void * b ) { return unpack_array<T>(b,ref,size); }
444 
445 private:
446 
447  unsigned get_max() const { return size ; }
448  unsigned put_max() const { return size ; }
449  void * put_void(unsigned i) {return i < size ? ref+i : NULL;}
450  const void * get_void(unsigned i) const {return i < size ? ref+i : NULL;}
451 
452  NamedValue();
453  NamedValue( const NamedValue & );
454  NamedValue & operator = ( const NamedValue & );
455 };
456 
457 
461 template< typename T >
462 class NamedValue< const T * > : public NamedValue<void> {
463 public:
464  const T * const ref ;
465  const unsigned size ;
466 
467  NamedValue( const std::string & n , const T * v , unsigned s )
468  : NamedValue<void>( n , typeid(T) ), ref(v), size(s) {}
469 
470  ~NamedValue() {}
471 
472  void write( std::ostream & s ) const { write_array<T>(s,ref,size); }
473  unsigned read( std::istream & ){ return 0 ; }
474 
475  void tell( std::ostream & s ) const
476  { s << name << " = " << type_name_array<const T>(size) << " *" ; }
477 
478  unsigned pack( void * b ) const { return pack_array<T>(b,ref,size); }
479  unsigned unpack( void * b ) { return 0 ; }
480 
481 private:
482 
483  unsigned get_max() const { return size ; }
484  unsigned put_max() const { return 0 ; }
485  void * put_void(unsigned ) {return NULL ; }
486  const void * get_void(unsigned i) const {return i < size ? ref+i : NULL;}
487 
488  NamedValue();
489  NamedValue( const NamedValue & );
490  NamedValue & operator = ( const NamedValue & );
491 };
492 
493 //----------------------------------------------------------------------
497 template< typename T >
498 class NamedValue< std::vector<T> > : public NamedValue<void> {
499 public:
500  std::vector<T> value ;
501 
502  NamedValue( const std::string & n ) : NamedValue<void>( n , typeid(T) ) {}
503 
504  NamedValue( const std::string & n , const std::vector<T> & v )
505  : NamedValue<void>( n , typeid(T) ), value(v) {}
506 
507  ~NamedValue() {}
508 
509  void tell( std::ostream & s ) const
510  { s << name << " = " << type_name_vector<T>( value.size() ); }
511 
512  void write( std::ostream & s ) const
513  { write_array<T>( s , & value[0] , value.size() ); }
514 
515  unsigned read( std::istream & s )
516  { return read_vector<T>( s , value ); }
517 
518  unsigned pack( void * b ) const { return pack_vector<T>( b , value ); }
519 
520  unsigned unpack( void * b ) { return unpack_vector<T>( b , value ); }
521 
522 private:
523 
524  unsigned get_max() const { return value.size(); }
525  unsigned put_max() const { return std::numeric_limits<unsigned>::max(); }
526 
527  void * put_void( unsigned i )
528  {
529  if ( value.size() <= i ) { value.resize(i+1); }
530  return & value[i] ;
531  }
532 
533  const void * get_void( unsigned i ) const
534  { return i < value.size() ? & value[i] : NULL ; }
535 
536  NamedValue();
537  NamedValue( const NamedValue & );
538  NamedValue & operator = ( const NamedValue & );
539 };
540 
541 template< typename T >
542 class NamedValue< std::vector<T> & > : public NamedValue<void> {
543 public:
544  std::vector<T> & ref ;
545 
546  NamedValue( const std::string & n , std::vector<T> & v )
547  : NamedValue<void>( n , typeid(T) ), ref(v) {}
548 
549  ~NamedValue() {}
550 
551  void tell( std::ostream & s ) const
552  { s << name << " = " << type_name_vector<T>( ref.size() ) << " &" ; }
553 
554  void write( std::ostream & s ) const
555  { write_array<T>( s , & ref[0] , ref.size() ); }
556 
557  unsigned read( std::istream & s )
558  { return read_vector<T>( s , ref ); }
559 
560  unsigned pack( void * b ) const { return pack_vector<T>( b , ref ); }
561 
562  unsigned unpack( void * b ) { return unpack_vector<T>( b , ref ); }
563 
564 private:
565 
566  unsigned get_max() const { return ref.size(); }
567  unsigned put_max() const { return std::numeric_limits<unsigned>::max(); }
568 
569  void * put_void( unsigned i )
570  {
571  if ( ref.size() <= i ) { ref.resize(i+1); }
572  return & ref[i] ;
573  }
574 
575  const void * get_void( unsigned i ) const
576  { return i < ref.size() ? & ref[i] : NULL ; }
577 
578  NamedValue();
579  NamedValue( const NamedValue & );
580  NamedValue & operator = ( const NamedValue & );
581 };
582 
583 //----------------------------------------------------------------------
587 template< typename T >
588 class NamedValue< const std::vector<T> & > : public NamedValue<void> {
589 public:
590  const std::vector<T> & ref ;
591 
592  explicit NamedValue( const std::string & n , const std::vector<T> & arg )
593  : NamedValue<void>( n , typeid(T) ), ref(arg) {}
594 
595  ~NamedValue() {}
596 
597  void tell( std::ostream & s ) const
598  { s << name << " = " << type_name_vector<const T>( ref.size() ) << " &" ; }
599 
600  void write( std::ostream & s ) const
601  { write_array<T>( s , & ref[0] , ref.size() ); }
602 
603  unsigned read( std::istream & ) { return 0 ; }
604 
605  unsigned pack( void * b ) const { return pack_vector<T>( b , ref ); }
606 
607  unsigned unpack( void * b ) { return 0 ; }
608 
609 private:
610 
611  unsigned get_max() const { return ref.size(); }
612  unsigned put_max() const { return 0 ; }
613 
614  void * put_void( unsigned ) { return NULL ; }
615 
616  const void * get_void( unsigned i ) const
617  { return i < ref.size() ? & ref[i] : NULL ; }
618 
619  NamedValue();
620  NamedValue( const NamedValue & );
621  NamedValue & operator = ( const NamedValue & );
622 };
623 
624 //----------------------------------------------------------------------
625 //----------------------------------------------------------------------
626 
627 template<>
628 class NamedValue< NamedValueSet > : public NamedValue<void> {
629 public:
630  NamedValueSet value ;
631 
632  ~NamedValue();
633 
634  NamedValue( const std::string & n )
635  : NamedValue<void>( n , typeid(NamedValueSet) ) {}
636 
637  void tell( std::ostream & ) const ;
638 
639  void write( std::ostream & s ) const { s << value ; }
640  unsigned read( std::istream & s ) { return s >> value ? 1 : 0 ; }
641 
642  //----------------------------------
643 
645  unsigned pack( void * ) const ;
646 
648  unsigned unpack( void * );
649 
650 private:
651 
652  unsigned get_max() const { return 1 ; }
653  unsigned put_max() const { return 1 ; }
654  void * put_void( unsigned i ) { return i ? NULL : & value ; }
655  const void * get_void( unsigned i ) const { return i ? NULL : & value ; }
656 
657 
658  NamedValue();
659  NamedValue( const NamedValue & );
660  NamedValue & operator = ( const NamedValue & );
661 };
662 
663 
664 } // namespace phdmesh
665 
666 //----------------------------------------------------------------------
667 
668 #endif
669 
unsigned pack(void *b) const
Definition: NamedValue.hpp:331
unsigned unpack(void *b)
Definition: NamedValue.hpp:405
void write(std::ostream &s) const
Write value to stream.
Definition: NamedValue.hpp:285
unsigned pack(void *b) const
Definition: NamedValue.hpp:367
void tell(std::ostream &s) const
Tell the type to a stream.
Definition: NamedValue.hpp:281
unsigned unpack(void *b)
Definition: NamedValue.hpp:332
unsigned read(std::istream &s)
Read value from stream.
Definition: NamedValue.hpp:288
unsigned unpack(void *b)
Definition: NamedValue.hpp:443
NamedValue(const std::string &n)
Constructor.
Definition: NamedValue.hpp:276
unsigned read(std::istream &s)
Read value from stream.
Definition: NamedValue.hpp:329
unsigned pack(void *b) const
Definition: NamedValue.hpp:404
NamedValue to an ordinary value.
Definition: NamedValue.hpp:43
void tell(std::ostream &s) const
Tell the type to a stream.
Definition: NamedValue.hpp:322
void write(std::ostream &s) const
Write value to stream.
Definition: NamedValue.hpp:326
unsigned pack(void *b) const
Definition: NamedValue.hpp:442
NamedValue(const std::string &n, T &v)
Constructor.
Definition: NamedValue.hpp:318
Base class for references provides access to anonymous type.
Definition: NamedValue.hpp:81
unsigned pack(void *b) const
Definition: NamedValue.hpp:478