00001
00002
00003
00004
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
00054
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
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
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
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
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
00195 t = (*(T*)fData);
00196 }
00197
00198
00199
00203 template <class T>
00204 void Param::Set(const T& t)
00205 {
00206
00207 if (fData) {
00208 this->fDataDelete(fData);
00209 fData = 0;
00210 }
00211
00212
00213 fDataType = gsDataType<T>;
00214 fDataDelete = gsDataDelete<T>;
00215 fDataCopyCons = gsDataCopyCons<T>;
00216 fDataCopy = gsDataCopy<T>;
00217 fDataPrint = gsDataPrint<T>;
00218
00219
00220 fDataCopyCons(&fData, &t);
00221 }
00222 }
00223 #endif // CFGPARAM_H
00224