00001
00006 #ifndef PARAMETERIOIMPL_h
00007 #define PARAMETERIOIMPL_h
00008
00009 #include <iostream>
00010 #include <string>
00011 #include <vector>
00012 #include <set>
00013 #include <map>
00014 #include <algorithm>
00015 #include "boost/type_traits.hpp"
00016 #include "boost/shared_ptr.hpp"
00017
00018 #include "VParameterNode.hh"
00022 namespace ParameterIOimpl{
00023 unsigned long ReadUnsignedInt(std::istream& in);
00024
00025 inline std::ostream& write(std::ostream& out, const VParameterNode& p,
00026 bool showhelp=false, int indent=0)
00027 {
00028 std::cerr<<"Writing VParameterNode\n";
00029 return p.WriteTo(out, showhelp, indent+1);
00030 }
00031
00032
00033 template<class T> inline std::istream& read(std::istream& in, T& t)
00034 { return in >> t; }
00035
00036 template<class T> inline std::ostream& write(std::ostream& out, const T& t,
00037 bool showhelp=false,
00038 int indent=0)
00039 { return writeleaf(out, t, showhelp, indent,
00040 boost::is_base_of<VParameterNode,T>()); }
00041
00042
00043
00044 template<class T> inline std::istream& read(std::istream& in, T* t)
00045 { return in >> *t; }
00046
00047 template<class T> inline std::ostream& write(std::ostream& out, const T* t,
00048 bool showhelp=false,
00049 int indent=0)
00050 { return writeleaf(out, *t, showhelp, indent,
00051 boost::is_base_of<VParameterNode,T>()); }
00052
00053 template<class T> inline std::istream& read(std::istream& in, boost::shared_ptr<T>& t)
00054 { return in >> *(t.get()); }
00055
00056 template<class T> inline std::ostream& write(std::ostream& out, const boost::shared_ptr<T>& t,
00057 bool showhelp=false,
00058 int indent=0)
00059 { return writeleaf(out, *(t.get()), showhelp, indent,
00060 boost::is_base_of<VParameterNode,T>()); }
00061
00062
00063
00064
00065
00066 template <class T> inline std::ostream& writeleaf(std::ostream& out,
00067 const T& t,
00068 bool showhelp, int indent,
00069 const boost::true_type&)
00070 { return t.WriteTo(out, showhelp, indent); }
00071
00072 template <class T> inline std::ostream& writeleaf(std::ostream& out,
00073 const T& t,
00074 bool showhelp, int indent,
00075 const boost::false_type&)
00076 { return out<<t; }
00077
00078
00079
00080 std::istream& read(std::istream& in, bool& b);
00081 inline std::ostream& write(std::ostream& out, const bool& b, bool, int)
00082 { return out<<std::boolalpha<< b <<std::noboolalpha; }
00083
00084 inline std::istream& read(std::istream& in, unsigned& u)
00085 { u = ReadUnsignedInt(in); return in; }
00086
00087 inline std::istream& read(std::istream& in, unsigned char& u)
00088 { u = ReadUnsignedInt(in); return in; }
00089 inline std::istream& read(std::istream& in, unsigned short& u)
00090 { u = ReadUnsignedInt(in); return in; }
00091 inline std::istream& read(std::istream& in, unsigned long& u)
00092 { u = ReadUnsignedInt(in); return in; }
00093 inline std::istream& read(std::istream& in, unsigned long long& u)
00094 { u = ReadUnsignedInt(in); return in; }
00095
00096
00097
00098 inline std::ostream& write(std::ostream& out, const unsigned& u, bool, int)
00099 { return out<<std::hex<<std::showbase<< u <<std::noshowbase<<std::dec; }
00100 inline std::ostream& write(std::ostream& out, const unsigned char& u, bool, int)
00101 { return out<<std::hex<<std::showbase<< u <<std::noshowbase<<std::dec; }
00102 inline std::ostream& write(std::ostream& out, const unsigned short& u, bool, int)
00103 { return out<<std::hex<<std::showbase<< u <<std::noshowbase<<std::dec; }
00104 inline std::ostream& write(std::ostream& out, const unsigned long& u, bool, int)
00105 { return out<<std::hex<<std::showbase<< u <<std::noshowbase<<std::dec; }
00106 inline std::ostream& write(std::ostream& out, const unsigned long long& u, bool, int)
00107 { return out<<std::hex<<std::showbase<< u <<std::noshowbase<<std::dec; }
00108
00109
00110
00111
00112
00113 template<class T> std::istream& read(std::istream& in, std::vector<T>& v);
00114 template<class T> std::ostream& write(std::ostream& out,
00115 const std::vector<T>& v,
00116 bool showhelp=false, int indent=0);
00117
00118 template<class T>
00119 std::istream& read(std::istream& in, std::set<T>& s);
00120 template<class T>
00121 std::ostream& write(std::ostream& out, const std::set<T>& s,
00122 bool showhelp=false, int indent=0);
00123
00124
00125 template<class A, class B>
00126 std::istream& read(std::istream& in, std::map<A,B>& m);
00127 template<class A, class B>
00128 std::ostream& write(std::ostream& out, const std::map<A,B>& m,
00129 bool showhelp=false, int indent=0);
00130
00131
00132
00133 std::istream& read(std::istream& in, std::string& s);
00134 std::ostream& write(std::ostream& out, const std::string& s, bool, int);
00135
00136 template<class A, class B> std::istream& read(std::istream& in,
00137 std::pair<A,B>& p);
00138 template<class B> std::istream& read(std::istream& in,
00139 std::pair<std::string,B>& p);
00140 template<class A, class B> std::ostream& write(std::ostream& out,
00141 const std::pair<A,B>& p,
00142 bool showhelp=false,
00143 int indent=0);
00144
00145
00146 template<class ConstIterator> std::ostream& writeit(std::ostream& out,
00147 ConstIterator a,
00148 ConstIterator b,
00149 unsigned container=0,
00150 bool showhelp=false,
00151 int indent=0);
00152 template<class T, class C> std::istream& readlist(std::istream& in,
00153 C& container);
00154
00155 template<class T> inline void insert(const T& t, std::vector<T>& v)
00156 { v.push_back(t); }
00157 template<class T> inline void insert(const T& t, std::set<T>& s)
00158 { s.insert(t); }
00159
00160 template<class A, class B>
00161 inline void insert(const std::pair<A,B>& p, std::map<A,B>& m)
00162 { m[p.first]=p.second; }
00163
00164 const char opener[]="[{(";
00165 const char closer[]="]})";
00166
00167
00168 template<class T> struct Constructor {
00169 static T make() { return T(); }
00170 };
00171 template<class T> struct Constructor<T*> {
00172 static T* make() { return new T(); }
00173 };
00174 template<class T> struct Constructor<boost::shared_ptr<T> >{
00175 static boost::shared_ptr<T> make() { return boost::shared_ptr<T>(new T());}
00176 };
00177
00178 };
00179
00180
00181
00182 template<class T>
00183 inline std::istream& ParameterIOimpl::read(std::istream& in, std::vector<T>& v)
00184 {
00185 return readlist<T>(in, v);
00186 }
00187
00188 template<class T>
00189 inline std::ostream& ParameterIOimpl::write(std::ostream& out,
00190 const std::vector<T>& v,
00191 bool showhelp, int indent)
00192 {
00193 return writeit(out, v.begin(), v.end(), 0, showhelp, indent);
00194 }
00195
00196
00197 template<class T> inline
00198 std::istream& ParameterIOimpl::read(std::istream& in, std::set<T>& s)
00199 {
00200 return readlist<T>(in, s);
00201 }
00202
00203 template<class T> inline
00204 std::ostream& ParameterIOimpl::write(std::ostream& out,
00205 const std::set<T>& s,
00206 bool showhelp, int indent)
00207 {
00208 return writeit(out, s.begin(), s.end(), 0, showhelp, indent);
00209 }
00210
00211
00212 template<class A, class B> inline
00213 std::istream& ParameterIOimpl::read(std::istream& in, std::map<A,B>& m)
00214 {
00215 return readlist<std::pair<A,B> >(in, m);
00216 }
00217
00218 template<class A, class B> inline
00219 std::ostream& ParameterIOimpl::write(std::ostream& out, const std::map<A,B>& m,
00220 bool showhelp, int indent)
00221 {
00222 return writeit(out, m.begin(), m.end() , 1, showhelp, indent);
00223 }
00224
00225
00226
00227
00228
00229 template<class A, class B> inline
00230 std::istream& ParameterIOimpl::read(std::istream& in, std::pair<A,B>& p)
00231 {
00232
00233 char start='0';
00234 in>>start;
00235 const char* startchar = std::find(opener, opener+sizeof(opener), start);
00236 size_t offset = startchar-opener;
00237 if(offset >= sizeof(opener))
00238 in.unget();
00239
00240
00241 read(in, p.first);
00242 char sep='0';
00243 in>>sep;
00244 if(sep != ':' && sep != ','){
00245 std::cerr<<"Error reading std::pair; expected : or , between values, got '"
00246 <<sep<<"'\n";
00247 in.setstate(std::ios::failbit);
00248 return in;
00249 }
00250 read(in, p.second);
00251 if(offset < sizeof(opener)){
00252 char end='0';
00253 in>>end;
00254
00255 }
00256 return in;
00257 }
00258
00259
00260 template<class B> inline
00261 std::istream& ParameterIOimpl::read(std::istream& in,
00262 std::pair<std::string,B>& p)
00263 {
00264
00265 read(in, p.first);
00266 if(p.first[p.first.size()-1] != ':'){
00267 char sep='0';
00268 in>>sep;
00269 if(sep != ':'){
00270 std::cerr<<"Error reading std::pair; expected ':' between values, got '"
00271 <<sep<<"'\n";
00272 in.setstate(std::ios::failbit);
00273 return in;
00274 }
00275 }
00276 else{
00277 p.first.resize(p.first.size()-1);
00278 }
00279 return read(in, p.second);
00280 }
00281
00282 template<class A, class B> inline
00283 std::ostream& ParameterIOimpl::write(std::ostream& out,const std::pair<A,B>& p,
00284 bool showhelp, int indent)
00285 {
00286 write(out, p.first, showhelp, indent)<<" : ";
00287 return write(out,p.second, showhelp, indent);
00288 }
00289
00290
00291
00292
00293 template<class ConstIterator>
00294 inline std::ostream& ParameterIOimpl::writeit(std::ostream& out,
00295 ConstIterator a,
00296 ConstIterator b,
00297 unsigned container,
00298 bool showhelp,
00299 int indent)
00300 {
00301 if(container >= sizeof(opener))
00302 container = 0;
00303
00304 out<<opener[container]<<' ';
00305 while(a != b){
00306 write(out, *a, showhelp, indent);
00307 out<<" ";
00308 if(++a != b)
00309 out<<", ";
00310 }
00311 return out<<closer[container];
00312 }
00313
00314
00315 template<class T, class C> inline
00316 std::istream& ParameterIOimpl::readlist(std::istream& in,C& container)
00317 {
00318
00319 bool emptyfirst = true;
00320 char start='0';
00321 in>>start;
00322 if(start == '+'){
00323 emptyfirst = false;
00324 in>>start;
00325 }
00326
00327 const char* startchar = std::find(opener, opener+sizeof(opener), start);
00328 size_t offset = startchar-opener;
00329
00330 if( offset >= sizeof(opener) ){
00331 std::cerr<<"Error reading dynamic list; expect one of "<<opener
00332 <<" at beginning of list, got '"<<start<<"'\n";
00333 in.setstate(std::ios::failbit);
00334 return in;
00335 }
00336
00337 if(emptyfirst)
00338 container.clear();
00339
00340 char next;
00341 while( in >> next && next != closer[offset] ){
00342 if(next == ',')
00343 continue;
00344 else if(next == '#'){
00345 std::string dummy;
00346 std::getline(in, dummy);
00347 continue;
00348 }
00349 in.unget();
00350 T t(Constructor<T>::make());
00351 if(!read(in,t))
00352 return in;
00353 insert(t, container);
00354 }
00355
00356 return in;
00357
00358 }
00359
00360 #endif