Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

Param.h

Go to the documentation of this file.
00001 
00002 // $Id: Param.h,v 1.2 2008/09/22 18:28:41 fmwk Exp $
00003 //
00004 // messier@indiana.edu
00006 #ifndef CFG_PARAM_H
00007 #define CFG_PARAM_H
00008 #include <iostream>
00009 #include <sstream>
00010 #include <string>
00011 #include <vector>
00012 #include <typeinfo>
00013 #include <ctime>
00014 #include "Config/Exception.h"
00015 
00016 namespace cfg {
00018   //
00022   class Param {
00023   public:
00024     friend std::ostream& operator<<(std::ostream& os, const Param& p);
00025     
00026   public:
00027     Param();
00028     Param(const Param& p);
00029     Param(const char* name, const char* comment);
00030     template <class T>
00031       Param(const char* name, const T& d, const char* comment);
00032     ~Param();
00033     
00034   public:
00035     const char* GetName()               const;
00036     const char* GetComment()            const;
00037     const char* XMLTag()                const;
00038     void        Print(std::ostream& os) const;
00039     
00040     template <class T> void Get(T& t) const;
00041     
00042   public:
00043     template <class T> void Set(const T& t);
00044     Param& operator=(const Param& rhs);
00045     
00046     
00047   private:
00048     std::string fName;    
00049     std::string fComment; 
00050     void*       fData;    
00051     
00052   private:
00053     // The following methods allow one to correctly treat the void*
00054     // fData as a class of correct type
00055     const std::type_info& (*fDataType)(void);
00056     void                  (*fDataDelete)(void*);
00057     void                  (*fDataCopyCons)(void** dest, const void* src);
00058     void                  (*fDataCopy)(void* dest, const void* src);
00059     void                  (*fDataPrint)(std::ostream& os, const void* d);
00060   };
00062   
00064   // Inlined templated functions
00066   
00070   template <class T>
00071     static const std::type_info& gsDataType(void) 
00072     {
00073       return typeid(T);
00074     }
00075   
00076   //......................................................................
00077   
00081   template <class T>
00082     static void gsDataDelete(void* p) 
00083     {
00084       T* pc = (T*)p; delete pc; 
00085     }
00086   
00087   //......................................................................
00088 
00093   template <class T>
00094     static void gsDataCopyCons(void** dest, const void* src) 
00095     {
00096       T* srcc = (T*)src;
00097       T* newt = new T(*srcc);
00098       *dest   = (void*)newt;
00099     }
00100   
00101   //......................................................................
00102 
00107   template <class T>
00108     static void gsDataCopy(void* dest, const void* src) 
00109     {
00110       T* destc = (T*)dest;
00111       T* srcc  = (T*)src;
00112       (*destc) = (*srcc);
00113     }
00114   
00115   //......................................................................
00116 
00120   template <class T>
00121     static void gsDataPrint(std::ostream& os, const void* p)
00122     {
00123       T* pc = (T*)p;
00124       os << (*pc);
00125     }
00126   
00127   //......................................................................
00128   
00132   template <class T>
00133     static std::ostream& operator<<(std::ostream& os, const std::vector<T>& v) 
00134     {
00135       int sz   = v.size();
00136       int szm1 = sz-1;
00137       if ( (typeid(T) == typeid(std::string)) || 
00138            (typeid(T) == typeid(const char*)) ) {
00139         // Add quotes if data is of string type
00140         for (int i=0; i<sz; ++i) {
00141           if (i==szm1) os << "\"" << v[i] << "\"";
00142           else         os << "\"" << v[i] << "\" ";
00143         }
00144       }
00145       else {
00146         // Non-string data gets streamed normally
00147         for (int i=0; i<sz; ++i) {
00148           if (i==szm1) os << v[i];
00149           else         os << v[i] << " ";
00150         }
00151       }
00152       return os;
00153     }
00154   
00155   //......................................................................
00156 
00160   template <class T>
00161     Param::Param(const char* name, const T& d, const char* comment) :
00162     fName        ( name    ),
00163     fComment     ( comment ),
00164     fData        ( 0 ),
00165     fDataType    ( 0 ),
00166     fDataDelete  ( 0 ),
00167     fDataCopyCons( 0 ),
00168     fDataCopy    ( 0 ),
00169     fDataPrint   ( 0 )
00170     {
00171       this->Set(d);
00172     }
00173   
00174   //......................................................................
00175   
00179   template <class T>
00180     void Param::Get(T& t) const
00181     {
00182       // Check that types match
00183       const std::type_info& ti = typeid(T);
00184       if (ti != this->fDataType()) {
00185         std::ostringstream os;
00186         os << "Attempt to get data of type " << ti.name()
00187            << " from parameter " << this->GetName() << " which is of type "
00188            << this->fDataType().name();
00189         throw cfg::Exception(Exception::kTypeMismatch,
00190                              os.str().c_str(),
00191                              __FILE__,
00192                              __LINE__);
00193       }
00194       // Normal case: types match so just make a copy to t
00195       t = (*(T*)fData);
00196     }
00197   
00198   //......................................................................
00199   
00203   template <class T>
00204     void Param::Set(const T& t)
00205     {
00206       // Delete the data currently held
00207       if (fData) {
00208         this->fDataDelete(fData);
00209         fData = 0;
00210       }
00211       
00212       // Setup the methods for handling this datum
00213       fDataType     = gsDataType<T>;
00214       fDataDelete   = gsDataDelete<T>;
00215       fDataCopyCons = gsDataCopyCons<T>;
00216       fDataCopy     = gsDataCopy<T>;
00217       fDataPrint    = gsDataPrint<T>;
00218       
00219       // Create the data from the data passed in
00220       fDataCopyCons(&fData, &t);
00221     }
00222 }
00223 #endif // CFGPARAM_H
00224 

Generated on Mon Feb 16 04:45:30 2009 for NOvA Offline by  doxygen 1.3.9.1