ParameterIOimpl.hh

Go to the documentation of this file.
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   //basic template
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   //overload for pointers and shared pointers
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   //lowest level needs meta template to give indent to parameters
00065   //T inherits from VParameterNode:
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   //T is not a VParameterNode: 
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   //overload for bools and unsigned ints
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   //container overloads
00112   //overload for vector
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   //overload set
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   //overload map
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   //overload for std::string
00133   std::istream& read(std::istream& in, std::string& s);
00134   std::ostream& write(std::ostream& out, const std::string& s, bool, int);
00135   //overload for std::pair
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   //combine IO for all containers using generic definitions
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   //default construction for all classes
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 //overload for std::vector
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 //overload for std::set
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 //overload for std::map
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 //overload for std::pair
00229 template<class A, class B> inline
00230 std::istream& ParameterIOimpl::read(std::istream& in, std::pair<A,B>& p)
00231 {
00232   //allow an opening parenth
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   //require a separating colon or comma. specialized for std::strings
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     //check for end = correct closer? 
00255   }
00256   return in;
00257 }
00258 
00259 //specialize std::pair read for case where first par is a string
00260 template<class B> inline
00261 std::istream& ParameterIOimpl::read(std::istream& in, 
00262                                     std::pair<std::string,B>& p)
00263 {
00264   //require a separating colon (:). specialized for std::strings
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   //read one character at a time until we reach an opener 
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 == '#'){ //comment, so kill the rest of the line
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
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines

Generated on 20 Jun 2014 for daqman by  doxygen 1.6.1