dump_base.h
Go to the documentation of this file.
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 
13 #ifndef DUMP_BASE_H
14 #define DUMP_BASE_H
15 
16 #include <iostream>
17 #include <sstream>
18 #include <iomanip>
19 
20 #include "classdesc.h"
21 #include <stdarg.h>
22 
23 namespace classdesc
24 {
29  class dump_t: public std::ostream
30  {
31  public:
32  dump_t(): std::ostream(std::cout.rdbuf()) {}
33  dump_t(std::ostream& o): std::ostream(o.rdbuf()) {}
34  };
35 
37  template <class T> void dump(dump_t& o, const string& d, const T& a);
38 
40  template <class T> void dump(std::ostream& o, const string& d, const T& a)
41  {dump_t t(o); classdesc::dump(t,d,a);}
42 
43  inline int format(std::ostream& o, const string& d)
44  {
45  const char* tail=d.c_str();
46  int ndots=0;
47  for (const char* c=tail; *c!='\0'; c++)
48  if (*c=='.')
49  {
50  ndots++;
51  o<<' ';
52  tail=c+1;
53  }
54  o<<tail<<":";
55  return ndots;
56  }
57 
58  //basic C types
59  template <class T>
60  void dump_basic(dump_t& o, const string& d, T& a)
61  {
62  format(o,d);
63  o<<a<<std::endl;
64  }
65 
66  template <class B>
67  typename enable_if< is_fundamental<B>, void >::T
68  dumpp(dump_t& o, const string& d, B& a) {dump_basic(o,d,a);}
69 
70  inline void dumpp(dump_t& o, const string& d, const char *& a) {dump_basic(o,d,a);}
71  template <class W>
72  void dumpp(dump_t& o, const string& d, std::basic_string<W>& a)
73  {dump_basic(o,d,a);}
74 
76  template <class A, class B>
77  typename enable_if< And<is_fundamental<A>,is_fundamental<B> >, void>::T
78  dump(dump_t& o, const string& d, std::pair<A,B>& a, dummy<0> dum=0)
79  {o << "["<< a.first<<"]="<<a.second;}
80 
81  template <class A, class B>
83  dump(dump_t& o, const string& d, std::pair<A,B>& a, dummy<1> dum=0)
84  {
85  o << "["<< a.first<<"]=";
86  dump(o,d,a.second);
87  }
88 
89  template <class A, class B>
90  typename enable_if< Not<is_fundamental<A> >, void>::T
91  dump(dump_t& o, const string& d, std::pair<A,B>& a, dummy<2> dum=0)
92  {
93  dump(o,string("[.")+d+"]=",a.first);
94  dump(o,d,a.second);
95  }
96 
97  template <class I>
98  typename enable_if< is_fundamental<
99  typename std::iterator_traits<I>::value_type>,
100  void>::T
101  dump_container(dump_t& o, const string& d, I begin,
102  const I& end, dummy<0> dum=0)
103  {
104  int tab = format(o,d);
105  for (; begin!=end; begin++)
106  o << std::setw(tab) << "" << *begin;
107  o<<std::endl;
108  }
109 
110  template <class I>
111  typename enable_if< Not<is_fundamental<
112  typename std::iterator_traits<I>::value_type> >,
113  void>::T
114  dump_container(dump_t& o, const string& d, I begin,
115  const I& end, dummy<1> dum=0)
116  {
117  int tab = format(o,d);
118  o<<std::endl;
119  for (size_t i=0; begin!=end; i++,begin++)
120  {
121  o<<std::setw(tab+2)<<"{"<<std::endl;
122  std::ostringstream idx;
123  idx<<i;
124  dump(o,d+"["+idx.str().c_str()+"]",*begin);
125  o<<std::setw(tab+2)<<"}"<<std::endl;
126  }
127  }
128 
129  template <class C>
130  typename enable_if<is_container<C>, void>::T
131  dump(dump_t& o, const string& d, C& a, dummy<0> dum=0)
132  {dump_container(o,d,a.begin(),a.end());}
133 
135  template <class C, class M>
136  void dump(dump_t& o, const string& d, C& a, M m) {}
137 
139  template <class T>
140  void dump(dump_t& o, const string& d, Enum_handle<T> arg)
141  {dump_basic(o,d,arg);}
142 
144  template <class T>
145  void dump(dump_t& o, const string& d, is_array ia, T& arg,
146  int dims, size_t ncopies, ...)
147  {
148  va_list ap;
149  va_start(ap,ncopies);
150  for (int i=1; i<dims; i++) ncopies*=va_arg(ap,int); //assume that 2 and higher D arrays dimensions are int
151  va_end(ap);
152  if (ncopies) dump_container(o,d,&arg, &arg+ncopies);
153  }
154 
156  template <class T>
157  void dump(dump_t& o, const string& d, is_const_static i, T arg)
158  {dump(o,d,arg);}
159 
160  template <class T, class U>
161  void dump(dump_t& o, const string& d, is_const_static i, const T&, U) {}
162 
163  template <class T>
164  void dump(dump_t& o, const string& d, Exclude<T>&) {}
165 
166  // shared_ptr support - polymorphism not supported
167  template <class T>
168  void dump(dump_t& o, const string& d, shared_ptr<T>& a)
169  {
170  if (a)
171  dump(o,d,*a);
172  else
173  dump(o,d,string("null"));
174  }
175 
176 }
177 
178 namespace classdesc_access
179 {
180  template <class T> struct access_dump;
181 }
182 
183 using classdesc::dump;
184 using classdesc::dumpp;
185 
186 namespace classdesc
187 {
188  //TODO maybe we could indicate inheritance more smartly than this?
189  template <class T>
190  void dump_onbase(dump_t& x,const string& d,T& a)
191  {::dump(x,d,a);}
192 }
193 using classdesc::dump_onbase;
194 
195 #endif
Definition: classdesc.h:326
Definition: classdesc.h:623
Definition: dump_base.h:180
Definition: classdesc.h:626
void dump(dump_t &o, const string &d, const T &a)
forward declare generic dump operation
Definition: dump_epilogue.h:55
Definition: classdesc.h:588
Definition: dump_base.h:29
std::string idx(const std::string &prefix, size_t i)
utility for generating index keys (for use with arrays)
Definition: xml_common.h:14
Contains definitions related to classdesc functionality.
Definition: arrays.h:2514
controlled template specialisation: stolen from boost::enable_if.
Definition: classdesc.h:249
Definition: classdesc.h:266
Contains access_* structs, and nothing else. These structs are used to gain access to private members...
Definition: accessor.h:55
Definition: classdesc.h:704