classdesc.h
1 /*
2  @copyright Russell Standish 2000-2013
3  @author Russell Standish
4  This file is part of Classdesc
5 
6  Open source licensed under the MIT license. See LICENSE for details.
7 */
8 
9 #ifndef CLASSDESC_H
10 #define CLASSDESC_H
11 
12 // ensure link time failure if classdesc_epilogue.h not included
13 namespace
14 {
15  int classdesc_epilogue_not_included();
16  int _dummy=classdesc_epilogue_not_included();
17 }
18 
19 #include <string>
20 #include <sstream>
21 #include <map>
22 #include <cmath>
23 #include <cstddef>
24 #include <stdexcept>
25 #include <memory>
26 #include <climits>
27 
28 #ifdef __CYGWIN__
29 namespace std
30 {
31  //missing in Cygwin?
32  typedef basic_string<wchar_t> wstring;
33 }
34 #endif
35 
36 #include <vector>
37 #include <deque>
38 #include <list>
39 #include <set>
40 #include <map>
41 #if defined(__cplusplus) && __cplusplus>=201103L
42 #include <unordered_map>
43 #include <unordered_set>
44 #endif
45 
46 
47  /*
48  Classdesc is now dependent on TR1. These can either
49  be obtained from the compiler's standard library, or from Boost.
50  TODO: check that this works with Boost!
51  */
52 #ifdef TR1
53 #include <tr1/type_traits>
54 #if !defined(__ICC) || __ICC > 1100 //tr1 shared_ptr impl not functional with icc 10.1
55 #include <tr1/memory>
56 #endif
57 #elif BOOST_TR1
58 #include <boost/tr1/type_traits.hpp>
59 #include <boost/tr1/memory.hpp>
60 #endif
61 
66 #if defined(__cplusplus) && __cplusplus>=201103L || defined(_MSC_VER)
67 
68 #include <unordered_map>
69 #include <unordered_set>
70 
71 #include <type_traits>
72 namespace classdesc
73 {
74  using std::true_type;
75  using std::false_type;
76 
77  using std::is_void;
78  using std::is_integral;
79  using std::is_floating_point;
80  // is_arry conflicts with an already established classdesc concept
81  // using std::is_array;
82  using std::is_pointer;
83  using std::is_reference;
84  using std::is_member_object_pointer;
85  using std::is_member_function_pointer;
86  using std::is_enum;
87  using std::is_union;
88  using std::is_class;
89  using std::is_function;
90 
91  using std::is_arithmetic;
92  using std::is_fundamental;
93  using std::is_object;
94  using std::is_scalar;
95  using std::is_compound;
96  using std::is_member_pointer;
97 
98  using std::is_const;
99  using std::is_volatile;
100  using std::is_pod;
101  using std::is_empty;
102  using std::is_polymorphic;
103  using std::is_abstract;
104  using std::is_signed;
105  using std::is_unsigned;
106  using std::alignment_of;
107  // conflicts with ecolab definition
108  // using std::rank;
109  using std::extent;
110 
111  using std::is_same;
112  using std::is_base_of;
113  using std::is_convertible;
114 
115  using std::remove_const;
116  using std::remove_volatile;
117  using std::remove_cv;
118  using std::add_const;
119  using std::add_volatile;
120  using std::add_cv;
121 
122  using std::remove_reference;
123 
124  using std::remove_extent;
125  using std::remove_all_extents;
126 
127  using std::remove_pointer;
128  using std::add_pointer;
129 
130 
131  using std::shared_ptr;
132  using std::weak_ptr;
133 
134  using std::is_default_constructible;
135  using std::is_copy_constructible;
136  using std::is_assignable;
137 }
138 
139 // long long is now part of the standard language
140 #ifndef HAVE_LONGLONG
141 #define HAVE_LONGLONG
142 #endif
143 
144 #elif defined(BOOST_TR1) || defined(TR1)
145 namespace classdesc
146 {
147  using std::tr1::true_type;
148  using std::tr1::false_type;
149 
150  using std::tr1::is_void;
151  using std::tr1::is_integral;
152  using std::tr1::is_floating_point;
153  // conflicts with an already established classdesc concept
154  //using std::tr1::is_array;
155  using std::tr1::is_pointer;
156  using std::tr1::is_reference;
157  using std::tr1::is_member_object_pointer;
158  using std::tr1::is_member_function_pointer;
159  using std::tr1::is_enum;
160  using std::tr1::is_union;
161  using std::tr1::is_class;
162  using std::tr1::is_function;
163 
164  using std::tr1::is_arithmetic;
165  using std::tr1::is_fundamental;
166  using std::tr1::is_object;
167  using std::tr1::is_scalar;
168  using std::tr1::is_compound;
169  using std::tr1::is_member_pointer;
170 
171  using std::tr1::is_const;
172  using std::tr1::is_volatile;
173  using std::tr1::is_pod;
174  using std::tr1::is_empty;
175  using std::tr1::is_polymorphic;
176  using std::tr1::is_abstract;
177  using std::tr1::is_signed;
178  using std::tr1::is_unsigned;
179  using std::tr1::alignment_of;
180  // conflicts with ecolab definition
181  // using std::tr1::rank;
182  using std::tr1::extent;
183 
184  using std::tr1::is_same;
185  using std::tr1::is_base_of;
186  using std::tr1::is_convertible;
187 
188  using std::tr1::remove_const;
189  using std::tr1::remove_volatile;
190  using std::tr1::remove_cv;
191  using std::tr1::add_const;
192  using std::tr1::add_volatile;
193  using std::tr1::add_cv;
194 
195  using std::tr1::remove_reference;
196 
197  using std::tr1::remove_extent;
198  using std::tr1::remove_all_extents;
199 
200  using std::tr1::remove_pointer;
201  using std::tr1::add_pointer;
202 
203  // nb ultimately, all compilers will support std::shared_ptr, but
204  // until then, this bit of ugly hackery is required.
205 #if (!defined(__ICC) || __ICC > 1100)
206  using std::tr1::shared_ptr;
207 #endif
208 
209  // fake these using TR1 counterparts (which are conservative)
210  template <class T> struct is_default_constructible:
211 
212  public std::tr1::has_nothrow_constructor<T> {};
213  template <class T> struct is_copy_constructible:
214  public std::tr1::has_nothrow_copy<T> {};
215  template <class T, class U> struct is_assignable
216  {
217  static const bool value=std::tr1::has_nothrow_assign<T>::value &&
218  std::tr1::is_convertible<U,T>::value;
219  };
220 
221  // ensure at least strings work!
222  template <class C, class A>
223  struct is_default_constructible<std::basic_string<C,A> >:
224  public std::tr1::true_type {};
225  template <class C, class A>
226  struct is_copy_constructible<std::basic_string<C,A> >:
227  public std::tr1::true_type {};
228  template <class C, class A, class U>
229  struct is_assignable<std::basic_string<C,A>, U>
230  {
231  static const bool value=
232  std::tr1::is_convertible<U,std::basic_string<C,A> >::value;
233  };
234 }
235 
236 #endif
237 
238 
239 namespace classdesc
240 {
241  using std::string;
242  template <bool, class type=void> struct enable_if_c {typedef type T;};
243  template <class T> struct enable_if_c<false,T> {};
245 
249  template <class Cond, class T=void> struct enable_if:
250  public enable_if_c<Cond::value,T> {};
251 
252  // NB - implementation of C++11 std::conditional
253  template <bool C, class True, class F>
254  struct conditional
255  {
256  typedef True T;
257  };
258 
259  template <class True, class F>
260  struct conditional<false, True, F>
261  {
262  typedef F T;
263  };
264 
265  // to help distinguish functions templates on old compilers (eg gcc 3.2)
266  template <int> struct dummy {dummy(int) {} };
267 
269  template <class T> struct is_sequence {static const bool value=false;};
270  template <class T, class A> struct is_sequence<std::vector<T,A> > {
271  static const bool value=true;};
272  template <class T, class A> struct is_sequence<std::deque<T,A> > {
273  static const bool value=true;};
274  template <class T, class A> struct is_sequence<std::list<T,A> > {
275  static const bool value=true;};
276  template <class T> struct is_sequence<const T>: public is_sequence<T> {};
278 
280  template <class T> struct is_string {static const bool value=false;};
281  template <class T> struct is_string<std::basic_string<T> >
282  {static const bool value=true;};
283  template <class T> struct is_string<const T>: public is_string<T> {};
285 
287  template <class T>
288  struct is_associative_container {static const bool value=false;};
289  template <class T, class C, class A>
290  struct is_associative_container<std::set<T,C,A> > {
291  static const bool value=true;};
292  template <class K, class V, class C, class A>
293  struct is_associative_container<std::map<K,V,C,A> > {
294  static const bool value=true;};
295  template <class T, class C, class A>
296  struct is_associative_container<std::multiset<T,C,A> > {
297  static const bool value=true;};
298  template <class K, class V, class C, class A>
299  struct is_associative_container<std::multimap<K,V,C,A> > {
300  static const bool value=true;};
301 
302 #if defined(__cplusplus) && __cplusplus>=201103L
303  template <class K, class V, class H, class P, class A>
304  struct is_associative_container<std::unordered_map<K,V,H,P,A> > {
305  static const bool value=true;};
306  template <class K, class H, class P, class A>
307  struct is_associative_container<std::unordered_set<K,H,P,A> > {
308  static const bool value=true;};
309  template <class K, class V, class H, class P, class A>
310  struct is_associative_container<std::unordered_multimap<K,V,H,P,A> > {
311  static const bool value=true;};
312  template <class K, class H, class P, class A>
313  struct is_associative_container<std::unordered_multiset<K,H,P,A> > {
314  static const bool value=true;};
315 #endif
316  template <class T> struct is_associative_container<const T>: public is_associative_container<T> {};
317 
319  template <class T> struct is_container {
320  static const bool value=
322  };
323 
326  template <class T> struct Not
327  {static const bool value=!T::value;};
328 
329  template <class A, class B> struct And
330  {static const bool value=A::value && B::value;};
331 
332  template <class A, class B> struct Or
333  {static const bool value=A::value || B::value;};
334 
335  template <int X, int Y> struct Eq
336  {static const bool value=X==Y;};
337 
339 
341 
342  // is_assignable doesn't seem to be working correctly yet
343 // template <class T> struct is_dca:
344 // public And<And<is_default_constructible<T>, is_copy_constructible<T> >,
345 // is_assignable<T,T> > {};
346  template <class T> struct is_dca:
347  public And<is_default_constructible<T>, is_copy_constructible<T> > {};
348 
349 
351  template <class T> struct is_rvalue
352  {
353  static const bool value=is_dca<T>::value && !is_abstract<T>::value;
354  };
355 
356  template <class T> struct is_rvalue<T&>
357  {
358  static const bool value=false;
359  };
360 
361  template <class T> struct is_rvalue<const T&>: public is_rvalue<T> {};
362 
364 
366  struct exception: std::runtime_error
367  {
368  exception(const string& s="classdesc exception"): std::runtime_error(s) {}
369  };
370 
371 
372  /*
373  Support for typeName functionality
374  */
375  template <class T> struct tn; //for partial specialisation support
376  template <class T> std::string typeName();
377 
378 #if defined(__cplusplus) && __cplusplus>=201103L
379  // handle variadic arguments
380  template <class T, class... A> std::string varTn() {return typeName<T>()+","+varTn<A...>();}
381  template <class T> std::string varTn() {return typeName<T>();}
382 #endif
383 
385  template <> inline std::string typeName<bool>() {return "bool";}
386  template <> inline std::string typeName<char>() {return "char";}
387  template <> inline std::string typeName<short>() {return "short";}
388  template <> inline std::string typeName<int>() {return "int";}
389  template <> inline std::string typeName<long>() {return "long";}
390 
391  template <> inline std::string typeName<signed char>() {return "signed char";}
392  template <> inline std::string typeName<unsigned char>() {return "unsigned char";}
393  template <> inline std::string typeName<unsigned short>(){return "unsigned short";}
394  template <> inline std::string typeName<unsigned int>() {return "unsigned int";}
395  template <> inline std::string typeName<unsigned long>() {return "unsigned long";}
396 
397 #ifdef HAVE_LONGLONG
398  template <> inline std::string typeName<long long>() {return "long long";}
399  template <> inline std::string typeName<unsigned long long>() {return "unsigned long long";}
400 #endif
401 
402  template <> inline std::string typeName<float>() {return "float";}
403  template <> inline std::string typeName<double>() {return "double";}
404  template <> inline std::string typeName<long double>() {return "long double";}
405 
406 
407  template <> inline std::string typeName<std::string>() {return "std::string";}
408  template <> inline std::string typeName<std::wstring>() {return "std::wstring";}
410 
411  // handle C++ new fixed width types
412 #if __cplusplus>=201103L
413  template <> inline std::string typeName<char16_t>() {return "char16_t";}
414  template <> inline std::string typeName<char32_t>() {return "char32_t";}
415 #endif
416 
417  template <class T> struct tn<T*>
418  {
419  static std::string name()
420  {return typeName<T>()+"*";}
421  };
422 
423  template <class T> struct tn<shared_ptr<T> >
424  {
425  static std::string name()
426  {return "classdesc::shared_ptr<"+typeName<T>()+">";}
427  };
428 
429 #if defined(__cplusplus) && __cplusplus <= 201402
430 #if defined(__GNUC__) && !defined(__ICC) && !defined(__clang__)
431 #pragma GCC diagnostic push
432 #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
433 #endif
434  template <class T> struct tn<std::auto_ptr<T> >
435  {
436  static std::string name()
437  {return "auto_ptr<"+typeName<T>()+">";}
438  };
439 #if defined(__GNUC__) && !defined(__ICC) && !defined(__clang__)
440 #pragma GCC diagnostic pop
441 #endif
442 #endif
443 
444 #if defined(__cplusplus) && __cplusplus>=201103L
445  template <class T> struct tn<std::unique_ptr<T> >
446  {
447  static std::string name()
448  {return "std::unique_ptr<"+typeName<T>()+">";}
449  };
450 #endif
451 
452  template <class T,class A> struct tn<std::vector<T,A> >
453  {
454  static std::string name()
455  {return "std::vector<"+typeName<T>()+">";}
456  };
457 
458  template <class T, class A> struct tn<std::list<T,A> >
459  {
460  static std::string name()
461  {return "std::list<"+typeName<T>()+">";}
462  };
463 
464  template <class T,class A> struct tn<std::deque<T,A> >
465  {
466  static std::string name()
467  {return "std::deque<"+typeName<T>()+">";}
468  };
469 
470  template <class T, class C, class A> struct tn<std::set<T,C,A> >
471  {
472  static std::string name()
473  {return "std::set<"+typeName<T>()+">";}
474  };
475 
476  template <class K, class V, class C, class A> struct tn<std::map<K,V,C,A> >
477  {
478  static std::string name()
479  {return "std::map<"+typeName<K>()+","+typeName<V>()+">";}
480  };
481 
482  template <class K, class V> struct tn<std::pair<K,V> >
483  {
484  static std::string name()
485  {return "std::pair<"+typeName<K>()+","+typeName<V>()+">";}
486  };
487 
488 
489 
491  struct EnumKey
492  {
493  const char* name;
494  int value;
495  };
496 
497  typedef std::map<std::string,int> SVMap;
498  typedef std::map<int,std::string> VSMap;
499 
500  template <class T>
501  class EnumKeys
502  {
503  SVMap s2v;
504  VSMap v2s;
505  public:
506  EnumKeys(const EnumKey* data, int size)
507  {
508  for (const EnumKey *i=data; i<data+size; i++)
509  {
510  s2v[i->name]=i->value;
511  v2s[i->value]=i->name;
512  }
513  }
514  T operator()(std::string key) const {
515  SVMap::const_iterator i=s2v.find(key);
516  if (i!=s2v.end()) return T(i->second);
517  else return T(0);
518  }
519  std::string operator()(int val) const
520  {
521  VSMap::const_iterator i=v2s.find(val);
522  if (i!=v2s.end()) return i->second;
523  else return "";
524  }
525  std::string operator()(T val) const {return operator()(int(val));}
526  // use these to iterate of the enum's keys
527  size_t size() const {return v2s.size();}
528  typedef VSMap::const_iterator iterator;
529  iterator begin() const {return v2s.begin();}
530  iterator end() const {return v2s.end();}
531 
532  typedef iterator It; // resolves a type ambiguity below
533  class Siterator: public It
534  {
535  public:
536  typedef string value_type;
537  typedef string* pointer;
538  typedef const string& reference;
539  Siterator() {}
540  Siterator(const It& i): It(i) {}
541  const string& operator*() const {return It::operator*().second;}
542  const string* operator->() const {return &It::operator*().second;}
543  };
544 
545  Siterator sbegin() const {return begin();}
546  Siterator send() const {return end();}
547 
548  class Viterator: public It
549  {
550  public:
551  typedef T value_type;
552  typedef T* pointer;
553  typedef const T& reference;
554  Viterator() {}
555  Viterator(const It& i): It(i) {}
556  T operator*() const {return T(It::operator*().first);}
557  };
558 
559  Viterator vbegin() const {return begin();}
560  Viterator vend() const {return end();}
561  };
562 
563  namespace {
564  template <class T>
565  struct enum_keysData
566  {
567  static EnumKey keysData[];
568  static EnumKeys<T> keys;
569  };
570 
571  template <class T> int enumKey(const std::string&);
572  template <class T> std::string enumKey(int);
573  }
574 
575  template <class T> const EnumKeys<T>&
576  enum_keys() {return enum_keysData<T>::keys;}
577 
578  template <class T>
579  typename enable_if<is_enum<T>, std::ostream&>::T
580  operator<<(std::ostream& o, T x)
581  {return o<<enum_keys<T>()(x);}
582 
587  template <class T> //T is an enum
589  {
590  T& ref;
591  public:
592  Enum_handle(T& arg): ref(arg) {}
593  operator std::string() const {
594  return enumKey<typename remove_const<T>::type>(static_cast<int>(ref));
595  }
596  operator int() const {return static_cast<int>(ref);}
597  const Enum_handle& operator=(T x) {ref=x; return *this;}
598  const Enum_handle& operator=(int x) {ref=T(x); return *this;}
599  const Enum_handle& operator=(const std::string& x)
600  {ref=T(enumKey<T>(x)); return *this;}
601  };
602 
603  template <class T>
604  std::istream& operator>>(std::istream& i, Enum_handle<T>& x)
605  {
606  std::string temp;
607  i>>temp;
608  x=temp;
609  return i;
610  }
611 
612  template <class T>
613  std::ostream& operator<<(std::ostream& o, Enum_handle<T> x)
614  {
615  o << static_cast<std::string>(x);
616  return o;
617  }
618 
619  template <class T>
620  Enum_handle<T> enum_handle(T& x) {return Enum_handle<T>(x);}
621 
623  class is_array {};
624 
626  class is_const_static {};
627 
629  class is_node {};
630  class is_treenode: public is_node {};
631  class is_graphnode: public is_node {};
632 
633  // derive from this to create a null descriptor
634  template <class T>
636  {
637  void operator()(void *targ, const string& desc, T& arg) {}
638  };
639 
640  // get last component of name
641  inline std::string tail(const string& x) {
642  std::string r(x);
643  std::string::size_type i=r.rfind('.');
644  return r.substr( i==std::string::npos? 0: i+1);
645  }
646 
647  // get all but last component of name
648  inline std::string head(const string& x) {
649  std::string r(x);
650  std::string::size_type i=r.rfind('.');
651  return r.substr( 0, i==std::string::npos? std::string::npos: i);
652  }
653 
655  template <class TT> struct NonConstKeyValueType
656  {typedef TT T;};
657 
658  template <class K, class V> struct NonConstKeyValueType<std::pair<const K,V> >
659  {typedef std::pair<K,V> T;};
660 
661 
666  template <class T>
667  struct ExcludeClass: public T
668  {
669  ExcludeClass() {}
670  template <class U> explicit ExcludeClass(const U& x): T(x) {}
671  template <class U> const T& operator=(const U& x) {return T::operator=(x);}
672  template <class U> operator const U&() const {return *static_cast<U*>(this);}
673  template <class U> operator U&() {return *static_cast<U*>(this);}
674  // other operators?
675  };
676 
677  template <class T>
679  {
680  typedef T& RefType;
681  typedef const T& ConstRefType;
682  T val;
683  ExcludeFundamental() {}
684  template <class U> explicit ExcludeFundamental(const U& x): val(x) {}
685  template <class U> const T& operator=(const U& x) {return val=x;}
686  template <class U> operator U() const {return val;}
687  operator RefType () {return val;}
688  operator ConstRefType () const {return val;}
689  T operator+(const T& x) const {return val+x;}
690  T operator-(const T& x) const {return val-x;}
691  T operator*(const T& x) const {return val*x;}
692  T operator/(const T& x) const {return val/x;}
693  T operator%(const T& x) const {return mod(val,x);}
694  T operator+=(const T& x) {return val+=x;}
695  T operator-=(const T& x) {return val-=x;}
696  T operator*=(const T& x) {return val*=x;}
697  T operator/=(const T& x) {return val/=x;}
698  T operator%=(const T& x) {val=mod(val,x); return val;}
699  bool operator==(const T& x) const {return val==x;}
700  bool operator==(const ExcludeFundamental<T>& x) const {return val==x.val;}
701  template <class U> bool operator!=(U x) const {return !operator==(x);}
702  };
703 
704  template <class T> struct Exclude: public
705  conditional<is_class<T>::value, ExcludeClass<T>, ExcludeFundamental<T> >::T
706  {
707  typedef typename conditional
708  <is_class<T>::value, ExcludeClass<T>, ExcludeFundamental<T> >::T Super;
709  Exclude() {}
710  template <class U> explicit Exclude(const U& x): Super(x) {}
711  template <class U> const T& operator=(const U& x) {return Super::operator=(x);}
712  };
713 
714  template <class T>
715  struct Exclude<T*>
716  {
717  T* val;
718  Exclude(): val(NULL) {}
719 #if __cplusplus>=201103L
720  Exclude(std::nullptr_t): val(nullptr) {}
721  bool operator==(std::nullptr_t) const {return val==nullptr;}
722 #endif
723  bool operator==(const T* x) const {return val==x;}
724  bool operator==(const Exclude<T*>& x) const {return val==x.val;}
725  template <class U> bool operator!=(U x) const {return !operator==(x);}
726  template <class U> explicit Exclude(const U& x): val(x) {}
727  template <class U> const T& operator=(U x) {return *(val=x);}
728  template <class U> operator U() const {return val;}
729  T& operator*() {return *val;}
730  const T& operator*() const {return *val;}
731  T* operator->() {return val;}
732  const T* operator->() const {return val;}
733  template <class U>
734  typename enable_if<is_integral<U>,T*>::T
735  operator+(U x) {return val+x;}
736  template <class U>
737  typename enable_if<is_integral<U>,const T*>::T
738  operator+(U x) const {return val+x;}
739  std::ptrdiff_t operator-(const T* x) const {return val-x;}
740  };
741 
742  template <class T, class U>
743  typename enable_if<is_integral<U>,T*>::T
744  operator+(U x, Exclude<T*> y)
745  {return y+x;}
746 
747  template <class T>
748  std::ptrdiff_t operator-(const T* x, const Exclude<T*> y)
749  {return -(y-x);}
750 
751  template <class T>
752  std::ptrdiff_t operator-(T* x, const Exclude<T*> y)
753  {return -(y-x);}
754 
755  template <class T, class U> T mod(T x, U y) {return x%y;}
756  template <class U> float mod(float x, U y) {return std::fmod(x,y);}
757  template <class U> double mod(double x, U y) {return std::fmod(x,y);}
758 
759 
760  // handle fundamental types
761  template <>
762  struct Exclude<bool>
763  {
764  typedef bool& RefType;
765  typedef const bool& ConstRefType;
766  bool val;
767  Exclude() {}
768  template <class U> explicit Exclude(const U& x): val(x) {}
769  template <class U> bool operator=(const U& x) {return val=x;}
770  template <class U> operator U() const {return val;}
771  operator RefType () {return val;}
772  operator ConstRefType () const {return val;}
773  bool operator&&(const bool& x) const {return val&&x;}
774  bool operator||(const bool& x) const {return val||x;}
775  bool operator&=(const bool& x) {return val=val&&x;}
776  bool operator|=(const bool& x) {return val=val||x;}
777  bool operator!() const {return !val;}
778  };
779 
781 
783  template <class action_t>
785  {
786  template <class U>
787  void operator()(action_t&,const string&,U&) {}
788  };
789 
792 
793  template <class B>
794  struct base_cast
795  {
796  template <class C>
797  static B& cast(C& x) {return static_cast<B&>(x);}
798  template <class C>
799  static const B& cast(const C& x) {return static_cast<const B&>(x);}
800  };
802 
804  template <class T> string basename()
805  {
806  string r(".base_"+typeName<T>());
807  for (size_t i=1; i<r.size(); ++i)
808  if (!isalnum(r[i])) r[i]='_';
809  return r;
810  }
811 }
812 #endif
can a temporary of type T be constructed and passed to an argument
Definition: classdesc.h:351
Definition: classdesc.h:326
Definition: classdesc.h:794
Definition: ref.h:27
determines if T is a standard sequence container
Definition: classdesc.h:269
MPIbuf manipulator to send the MPIbuf&#39;s contents to a remote process.
Definition: classdescMP.h:37
Definition: classdesc.h:335
Definition: graph.h:537
Definition: classdesc.h:329
Definition: classdesc.h:375
Definition: classdesc.h:667
Definition: classdesc.h:631
Definition: classdesc.h:623
Definition: classdesc.h:254
Definition: classdesc.h:629
Definition: classdesc.h:635
determines if this is a string
Definition: classdesc.h:280
Definition: classdesc.h:626
helper for constructing null descriptors
Definition: classdesc.h:784
helper for unpacking into map value_types
Definition: classdesc.h:655
Definition: classdesc.h:715
determines if T is a container
Definition: classdesc.h:319
Definition: classdesc.h:588
Definition: classdesc.h:332
Definition: classdesc.h:630
std::ostream & operator<<(std::ostream &s, const ecolab::Graph &x)
for use with TCL_obj. Graphviz format is used with the netgraph command.
Contains definitions related to classdesc functionality.
Definition: arrays.h:2514
controlled template specialisation: stolen from boost::enable_if.
Definition: classdesc.h:249
has default constructor, and is copiable
Definition: classdesc.h:346
Definition: classdesc.h:501
Definition: classdesc.h:266
Definition: classdesc.h:548
Definition: classdesc.h:533
string basename()
returns a valid identifier to append to the descriptor of a base class
Definition: classdesc.h:804
base class for exceptions thrown by classdesc
Definition: classdesc.h:366
determines if T is a standard associative container
Definition: classdesc.h:288
Definition: classdesc.h:678
enum symbol handling
Definition: classdesc.h:491
Definition: classdesc.h:704
Definition: classdesc.h:242