00001
00002 #ifndef INCLUDED_plistPrimitives_h_
00003 #define INCLUDED_plistPrimitives_h_
00004
00005 #include "plistBase.h"
00006 #include <map>
00007
00008 extern "C" {
00009
00010
00011 xmlNode* xmlAddPrevSibling(xmlNode* node, xmlNode* sibling);
00012 xmlNode* xmlNewText(const xmlChar* s);
00013 xmlNode* xmlNewComment(const xmlChar* s);
00014 xmlNode* xmlAddChild(xmlNode * parent, xmlNode* child);
00015 xmlNode* xmlNewChild(xmlNode* parent, xmlNs* ns, const xmlChar * name, const xmlChar * content);
00016 int xmlStrEqual(const xmlChar* a, const xmlChar* b);
00017 xmlChar* xmlNodeGetContent(xmlNode* node);
00018 void xmlNodeSetContent(xmlNode* node, const xmlChar* content);
00019 xmlAttr* xmlHasProperty(xmlNode* node, const xmlChar* name);
00020 xmlChar* xmlGetProperty(xmlNode* node, const xmlChar* name);
00021 long xmlGetLineNo(xmlNode* node);
00022 extern void (*xmlFree)(void* ptr);
00023 void xmlNodeSetName(xmlNode* node, const xmlChar* name);
00024 void xmlFreeNode(xmlNode* node);
00025 void xmlUnlinkNode(xmlNode* node);
00026
00027 }
00028
00029 namespace plist {
00030
00031
00032
00033
00034
00035 template<typename T> const char* getTypeName();
00036
00037 template<> inline const char* getTypeName<short>() { return "integer"; }
00038 template<> inline const char* getTypeName<unsigned short>() { return "integer"; }
00039 template<> inline const char* getTypeName<int>() { return "integer"; }
00040 template<> inline const char* getTypeName<unsigned int>() { return "integer"; }
00041 template<> inline const char* getTypeName<long>() { return "integer"; }
00042 template<> inline const char* getTypeName<unsigned long>() { return "integer"; }
00043 template<> inline const char* getTypeName<long long>() { return "integer"; }
00044 template<> inline const char* getTypeName<unsigned long long>() { return "integer"; }
00045 template<> inline const char* getTypeName<float>() { return "real"; }
00046 template<> inline const char* getTypeName<double>() { return "real"; }
00047
00048
00049
00050
00051
00052
00053
00054 template<typename T>
00055 class Primitive : public PrimitiveBase {
00056 public:
00057 template<typename U, typename V> struct conversion_policy { typedef typename U::template ConversionTo<V> value_conversion; };
00058
00059
00060 Primitive() : PrimitiveBase(), val(), prevVal() {}
00061
00062 Primitive(const T& v) : PrimitiveBase(), val(v), prevVal() {}
00063
00064 Primitive& operator=(const T& v) { if(&v==&prevVal) std::swap(val,prevVal); else { prevVal=val; val=v; } fireValueChanged(prevVal==val); return *this; }
00065 virtual Primitive& operator=(const PrimitiveBase& pb) { if(dynamic_cast<const Primitive*>(&pb)!=this) operator=(pb.to<T>()); return *this; }
00066
00067 Primitive& operator=(const Primitive& p) { operator=(p.val); return *this; }
00068
00069 Primitive& operator+=(const T& v) { prevVal=val; val+=v; fireValueChanged(prevVal==val); return *this; }
00070 Primitive& operator-=(const T& v) { prevVal=val; val-=v; fireValueChanged(prevVal==val); return *this; }
00071 Primitive& operator*=(const T& v) { prevVal=val; val*=v; fireValueChanged(prevVal==val); return *this; }
00072 Primitive& operator/=(const T& v) { prevVal=val; val/=v; fireValueChanged(prevVal==val); return *this; }
00073
00074
00075 const T& operator*() const { return val; }
00076
00077 const T* operator->() const { return &val; }
00078
00079
00080 operator T() const { return val; }
00081
00082
00083 void loadXML(xmlNode* node);
00084
00085 void saveXML(xmlNode* node) const;
00086 void set(const std::string& str);
00087 using PrimitiveBase::set;
00088 std::string get() const {
00089 std::stringstream sstr;
00090 sstr <<std::setprecision(std::numeric_limits<T>::digits10)<< val;
00091 return sstr.str();
00092 }
00093
00094 virtual long toLong() const { return static_cast<long>(val); }
00095 virtual double toDouble() const { return static_cast<double>(val); }
00096
00097
00098 PLIST_CLONE_DEF(Primitive<T>,new Primitive<T>(val));
00099
00100 const T& getPreviousValue() const { return prevVal; }
00101
00102 protected:
00103 T val;
00104 T prevVal;
00105 };
00106
00107 template<typename T>
00108 void Primitive<T>::loadXML(xmlNode* node) {
00109 if(node==NULL)
00110 return;
00111 prevVal=val;
00112 bool bt=xNodeHasName(node,"true");
00113 bool bf=xNodeHasName(node,"false");
00114 if(!bt && !bf && !xNodeHasName(node,"integer") && !xNodeHasName(node,"real") && !xNodeHasName(node,"string")) {
00115 std::stringstream errstr;
00116 errstr << "Error: plist::Primitive<" << typeid(T).name() << "> expects " << getTypeName<T>() << ", got unknown type " << (const char*)xNodeGetName(node);
00117 throw bad_format(node,errstr.str());
00118 }
00119 if(!xNodeHasName(node,getTypeName<T>()))
00120 std::cerr << "Warning: plist expected " << getTypeName<T>() << " got " << (const char*)xNodeGetName(node) << ", trying to convert. (line " << xmlGetLineNo(node) << ")" << std::endl;
00121 if(bt)
00122 val = true;
00123 else if(bf)
00124 val = false;
00125 else {
00126 xmlChar * cont=xmlNodeGetContent(node);
00127 std::stringstream str((const char*)cont);
00128 str >> val;
00129 xmlFree(cont);
00130 }
00131 fireValueChanged(prevVal==val);
00132 }
00133 template<typename T>
00134 void Primitive<T>::saveXML(xmlNode* node) const {
00135 if(node==NULL)
00136 return;
00137 xmlNodeSetName(node,(const xmlChar*)getTypeName<T>());
00138 std::stringstream str;
00139 str <<std::setprecision(std::numeric_limits<T>::digits10)<< val;
00140 xmlNodeSetContent(node,(const xmlChar*)str.str().c_str());
00141 }
00142 template<typename T>
00143 void Primitive<T>::set(const std::string& str) {
00144 prevVal=val;
00145 std::stringstream sstr(str);
00146 sstr >> val;
00147 while(sstr.good() && isspace(sstr.peek()))
00148 sstr.get();
00149 if(sstr.fail()) {
00150 if(matchTrue(str))
00151 val=true;
00152 else if(matchFalse(str))
00153 val=false;
00154 else {
00155 std::string err="Expected "; err+=getTypeName<T>(); err+=" value, got '"+str+"'";
00156 throw bad_format(NULL,err);
00157 }
00158 std::cerr << "Warning: expected " << getTypeName<T>() << " value, interpreting '" << str << "' as boolean (value of " << val << ")" << std::endl;
00159 }
00160 if(sstr.good()) {
00161 std::cerr << "Warning: expected " << getTypeName<T>() << " value, truncating remainder '";
00162 char c=sstr.get();
00163 while(sstr) { std::cerr << c; c=sstr.get(); }
00164 std::cerr << "'" << std::endl;
00165 }
00166 fireValueChanged(prevVal==val);
00167 }
00168
00169
00170 PLIST_CLONE_IMPT(T,Primitive,new Primitive<T>(val));
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180 template<>
00181 class Primitive<bool> : public PrimitiveBase {
00182 public:
00183 template<typename U, typename V> struct conversion_policy { typedef typename U::template ConversionTo<V> value_conversion; };
00184 Primitive() : PrimitiveBase(), val(), prevVal() {}
00185 Primitive(const bool& v) : PrimitiveBase(), val(v), prevVal() {}
00186 Primitive& operator=(const bool& v) { if(&v==&prevVal) std::swap(val,prevVal); else { prevVal=val; val=v; } fireValueChanged(prevVal==val); return *this; }
00187 virtual Primitive& operator=(const PrimitiveBase& pb) { if(dynamic_cast<const Primitive*>(&pb)!=this) operator=(pb.to<bool>()); return *this; }
00188 Primitive& operator=(const Primitive& p) { operator=(p.val); return *this; }
00189
00190 const bool& operator*() const { return val; }
00191
00192 const bool* operator->() const { return &val; }
00193 operator bool() const { return val; }
00194
00195 void loadXML(xmlNode* node);
00196 void saveXML(xmlNode* node) const;
00197 void set(const std::string& str);
00198 using PrimitiveBase::set;
00199 std::string get() const {
00200 return val?"true":"false";
00201 }
00202 virtual long toLong() const { return static_cast<long>(val); }
00203 virtual double toDouble() const { return static_cast<double>(val); }
00204
00205
00206 PLIST_CLONE_DEF(Primitive<bool>,new Primitive<bool>(val));
00207
00208 const bool& getPreviousValue() const { return prevVal; }
00209
00210 protected:
00211 bool val;
00212 bool prevVal;
00213 };
00214
00215
00216
00217
00218
00219
00220 template<>
00221 class Primitive<char> : public PrimitiveBase {
00222 public:
00223 template<typename U, typename V> struct conversion_policy { typedef typename U::template ConversionTo<V> value_conversion; };
00224 Primitive() : PrimitiveBase(), val(), prevVal(), numeric(false) {}
00225 Primitive(const char& v, bool isNum=false) : PrimitiveBase(), val(v), prevVal(), numeric(isNum) {}
00226 Primitive& operator=(char v) { if(&v==&prevVal) std::swap(val,prevVal); else { prevVal=val; val=v; } fireValueChanged(prevVal==val); return *this; }
00227 virtual Primitive& operator=(const PrimitiveBase& pb) { if(dynamic_cast<const Primitive*>(&pb)!=this) operator=(pb.to<char>()); return *this; }
00228
00229 Primitive& operator=(const Primitive& p) { operator=(p.val); return *this; }
00230 Primitive& operator+=(char v) { prevVal=val; val+=v; fireValueChanged(prevVal==val); return *this; }
00231 Primitive& operator-=(char v) { prevVal=val; val-=v; fireValueChanged(prevVal==val); return *this; }
00232 Primitive& operator*=(char v) { prevVal=val; val*=v; fireValueChanged(prevVal==val); return *this; }
00233 Primitive& operator/=(char v) { prevVal=val; val/=v; fireValueChanged(prevVal==val); return *this; }
00234
00235 const char& operator*() const { return val; }
00236
00237 const char* operator->() const { return &val; }
00238 operator char() const { return val; }
00239
00240 void setNumeric(bool isNum) { numeric=isNum; }
00241 bool getNumeric() const { return numeric; }
00242
00243 void loadXML(xmlNode* node);
00244 void saveXML(xmlNode* node) const;
00245 void set(const std::string& str);
00246 using PrimitiveBase::set;
00247 std::string get() const {
00248 if(numeric) {
00249 std::stringstream sstr;
00250 sstr << (int)val;
00251 return sstr.str();
00252 } else
00253 return std::string(1,val);
00254 }
00255 virtual long toLong() const { return static_cast<long>(val); }
00256 virtual double toDouble() const { return static_cast<double>(val); }
00257
00258
00259 PLIST_CLONE_DEF(Primitive<char>,new Primitive<char>(val));
00260
00261 const char& getPreviousValue() const { return prevVal; }
00262
00263 protected:
00264 char val;
00265 char prevVal;
00266 bool numeric;
00267 };
00268
00269
00270
00271
00272 template<>
00273 class Primitive<unsigned char> : public PrimitiveBase {
00274 public:
00275 template<typename U, typename V> struct conversion_policy { typedef typename U::template ConversionTo<V> value_conversion; };
00276 Primitive() : PrimitiveBase(), val(), prevVal(), numeric(false) {}
00277 Primitive(const unsigned char& v, bool isNum=false) : PrimitiveBase(), val(v), prevVal(), numeric(isNum) {}
00278 Primitive& operator=(unsigned char v) { prevVal=val; val=v; fireValueChanged(prevVal==val); return *this; }
00279 virtual Primitive& operator=(const PrimitiveBase& pb) { if(dynamic_cast<const Primitive*>(&pb)!=this) operator=(pb.to<unsigned char>()); return *this; }
00280
00281 Primitive& operator=(const Primitive& p) { operator=(p.val); return *this; }
00282 Primitive& operator+=(unsigned char v) { prevVal=val; val+=v; fireValueChanged(prevVal==val); return *this; }
00283 Primitive& operator-=(unsigned char v) { prevVal=val; val-=v; fireValueChanged(prevVal==val); return *this; }
00284 Primitive& operator*=(unsigned char v) { prevVal=val; val*=v; fireValueChanged(prevVal==val); return *this; }
00285 Primitive& operator/=(unsigned char v) { prevVal=val; val/=v; fireValueChanged(prevVal==val); return *this; }
00286
00287 const unsigned char& operator*() const { return val; }
00288
00289 const unsigned char* operator->() const { return &val; }
00290 operator unsigned char() const { return val; }
00291
00292 void setNumeric(bool isNum) { numeric=isNum; }
00293 bool getNumeric() const { return numeric; }
00294
00295 void loadXML(xmlNode* node);
00296 void saveXML(xmlNode* node) const;
00297 void set(const std::string& str);
00298 using PrimitiveBase::set;
00299 std::string get() const {
00300 if(numeric) {
00301 std::stringstream sstr;
00302 sstr << (int)val;
00303 return sstr.str();
00304 } else
00305 return std::string(1,val);
00306 }
00307 virtual long toLong() const { return static_cast<long>(val); }
00308 virtual double toDouble() const { return static_cast<double>(val); }
00309
00310
00311 PLIST_CLONE_DEF(Primitive<unsigned char>,new Primitive<unsigned char>(val));
00312
00313 const unsigned char& getPreviousValue() const { return prevVal; }
00314
00315 protected:
00316 unsigned char val;
00317 unsigned char prevVal;
00318 bool numeric;
00319 };
00320
00321
00322
00323
00324 template<>
00325 class Primitive<std::string> : public PrimitiveBase, public std::string {
00326 public:
00327 template<typename U, typename V> struct conversion_policy { typedef typename U::template ConversionTo<V> value_conversion; };
00328 Primitive() : PrimitiveBase(), std::string(), prevVal() {}
00329 Primitive(const std::string& v) : PrimitiveBase(), std::string(v), prevVal() {}
00330 Primitive(const std::string& v, size_type off, size_type count=npos) : PrimitiveBase(), std::string(v,off,count), prevVal() {}
00331 Primitive(const char* v, size_type count) : PrimitiveBase(), std::string(v,count), prevVal() {}
00332 Primitive(const char* v) : PrimitiveBase(), std::string(v), prevVal() {}
00333 Primitive(size_type count, char v) : PrimitiveBase(), std::string(count,v), prevVal() {}
00334 Primitive& operator=(const std::string& v) { if(&v==&prevVal) std::string::swap(prevVal); else { prevVal=*this; std::string::operator=(v); } fireValueChanged(prevVal==*this); return *this; }
00335 Primitive& operator=(const char* v) { prevVal=*this; std::string::operator=(v); fireValueChanged(prevVal==*this); return *this; }
00336 Primitive& operator=(char v) { prevVal=*this; std::string::operator=(v); fireValueChanged(prevVal==*this); return *this; }
00337 virtual Primitive& operator=(const PrimitiveBase& pb) { if(dynamic_cast<const Primitive*>(&pb)!=this) operator=(pb.toString()); return *this; }
00338
00339 Primitive& operator=(const Primitive& p) { operator=(static_cast<const std::string&>(p)); return *this; }
00340
00341 const std::string& operator*() const { return *this; }
00342
00343 const std::string* operator->() const { return this; }
00344
00345
00346 void loadXML(xmlNode* node);
00347 void saveXML(xmlNode* node) const;
00348 void set(const std::string& str) { operator=(str); }
00349 using PrimitiveBase::set;
00350 std::string get() const { return *this; }
00351 virtual long toLong() const;
00352 virtual double toDouble() const;
00353
00354
00355 PLIST_CLONE_DEF(Primitive<std::string>,new Primitive<std::string>(get()));
00356
00357 const std::string& getPreviousValue() const { return prevVal; }
00358
00359 protected:
00360 std::string prevVal;
00361 };
00362
00363
00364 class NamedEnumerationBase : public PrimitiveBase {
00365 public:
00366 NamedEnumerationBase() : PrimitiveBase(), strictValue(true) {}
00367 NamedEnumerationBase(const NamedEnumerationBase& ne) : PrimitiveBase(ne), strictValue(ne.strictValue) {}
00368 NamedEnumerationBase& operator=(const std::string& v) { set(v); return *this; }
00369 NamedEnumerationBase& operator=(const NamedEnumerationBase& ne) { PrimitiveBase::operator=(ne); return *this; }
00370 virtual NamedEnumerationBase& operator=(const PrimitiveBase& pb)=0;
00371
00372
00373 virtual void getPreferredNames(std::map<int,std::string>& names) const=0;
00374
00375 virtual void getAllNames(std::map<std::string,int>& names) const=0;
00376
00377 std::string getDescription(bool preferredOnly=true);
00378 void setStrict(bool strict) { strictValue=strict; }
00379 bool getStrict() const { return strictValue; }
00380
00381 protected:
00382 bool strictValue;
00383 };
00384
00385
00386
00387
00388
00389
00390
00391
00392
00393
00394
00395
00396
00397
00398
00399
00400
00401
00402
00403
00404
00405
00406
00407
00408
00409
00410
00411
00412
00413
00414
00415
00416
00417
00418
00419
00420
00421
00422 template<typename T>
00423 class NamedEnumeration : public NamedEnumerationBase {
00424 public:
00425 template<typename U, typename V> struct conversion_policy { typedef typename U::template ConversionTo<V> value_conversion; };
00426 NamedEnumeration() : NamedEnumerationBase(), val(), prevVal() {}
00427 NamedEnumeration(const NamedEnumeration& ne) : NamedEnumerationBase(ne), val(ne.val), prevVal() {}
00428 NamedEnumeration(const T& v, const char * const* enumnames) : NamedEnumerationBase(), val(v), prevVal() { setNames(enumnames); }
00429 NamedEnumeration(const T& v) : NamedEnumerationBase(), val(v), prevVal() {}
00430 NamedEnumeration& operator=(const T& v) { if(&v==&prevVal) std::swap(val,prevVal); else { prevVal=val; val=v; } fireValueChanged(prevVal==val); return *this; }
00431 NamedEnumeration& operator=(const std::string& v) { set(v); return *this; }
00432 NamedEnumeration& operator=(const NamedEnumeration& ne) { operator=(ne.val); return *this; }
00433
00434 const T& operator*() const { return val; }
00435 operator T() const { return val; }
00436 static void setNames(const char * const* enumnames);
00437 static const std::map<T,std::string>& getPreferredNames() { return valsToNames; }
00438 static const std::map<std::string,T>& getAllNames() { return namesToVals; }
00439 static void clearNames();
00440 static void addNameForVal(const std::string& enumname, const T& val);
00441 static void setPreferredNameForVal(const std::string& enumname, const T& val);
00442
00443
00444 virtual NamedEnumeration& operator=(const PrimitiveBase& pb) {
00445 if(dynamic_cast<const NamedEnumeration*>(&pb)==this)
00446 return *this;
00447 if(const std::string* str = dynamic_cast<const std::string*>(&pb))
00448 set(*str);
00449 else {
00450 T tv=static_cast<T>(pb.toLong());
00451 if(strictValue && valsToNames.find(tv)==valsToNames.end())
00452 throw bad_format(NULL, "NamedEnumeration unable to assign arbitrary integer value because strict checking is requested");
00453 val=tv;
00454 }
00455 return *this;
00456 }
00457
00458
00459 void loadXML(xmlNode* node) {
00460 if(node==NULL)
00461 return;
00462 if(xNodeHasName(node,"true") || xNodeHasName(node,"false")) {
00463 std::string name=(const char*)xNodeGetName(node);
00464 std::cerr << "Warning: plist NamedEnumeration should use <string>" << name << "</string>, not <" << name << "/>" << std::endl;
00465 try {
00466 set(name);
00467 } catch(const bad_format& err) {
00468 throw bad_format(node,err.what());
00469 }
00470 } else if(xNodeHasName(node,"integer") || xNodeHasName(node,"real") || xNodeHasName(node,"string")) {
00471 xmlChar * cont=xmlNodeGetContent(node);
00472 try {
00473 set((const char*)cont);
00474 } catch(const bad_format& err) {
00475 xmlFree(cont);
00476 throw bad_format(node,err.what());
00477 } catch(...) {
00478 xmlFree(cont);
00479 throw;
00480 }
00481 xmlFree(cont);
00482 } else
00483 throw bad_format(node,"Error: plist NamedEnumeration must be numeric or valid string");
00484 }
00485
00486 void saveXML(xmlNode* node) const {
00487 if(node==NULL)
00488 return;
00489 std::string name;
00490 if(getNameForVal(val,name)) {
00491 xmlNodeSetName(node,(const xmlChar*)"string");
00492 } else {
00493 xmlNodeSetName(node,(const xmlChar*)"integer");
00494 }
00495 xmlNodeSetContent(node,(const xmlChar*)name.c_str());
00496 }
00497 void set(const std::string& str) {
00498 prevVal=val;
00499 if(!getValForName(str,val))
00500 throw bad_format(NULL,"Error: plist::NamedEnumeration must be numeric or valid string (cannot be '"+str+"')");
00501 fireValueChanged(prevVal==val);
00502 }
00503 using PrimitiveBase::set;
00504 std::string get() const {
00505 std::string name;
00506 getNameForVal(val,name);
00507 return name;
00508 }
00509 virtual long toLong() const { return static_cast<long>(val); }
00510 virtual double toDouble() const { return static_cast<double>(val); }
00511
00512
00513 PLIST_CLONE_DEF(NamedEnumeration<T>,new NamedEnumeration<T>(*this));
00514
00515 const T& getPreviousValue() const { return prevVal; }
00516
00517 protected:
00518
00519 virtual void getPreferredNames(std::map<int,std::string>& names) const;
00520
00521 virtual void getAllNames(std::map<std::string,int>& names) const;
00522
00523
00524 bool getValForName(std::string name, T& v) const {
00525 std::transform(name.begin(), name.end(), name.begin(), (int(*)(int)) std::toupper);
00526 typename std::map<std::string,T>::const_iterator vit=namesToVals.find(name);
00527 if(vit!=namesToVals.end())
00528 v=vit->second;
00529 else {
00530 int iv;
00531 if(sscanf(name.c_str(),"%d",&iv)==0)
00532 return false;
00533 T tv=static_cast<T>(iv);
00534 if(strictValue && valsToNames.find(tv)==valsToNames.end())
00535 return false;
00536 v=tv;
00537 }
00538 return true;
00539 }
00540
00541 bool getNameForVal(const T& v, std::string& name) const {
00542 typename std::map<T,std::string>::const_iterator nit=valsToNames.find(v);
00543 if(nit!=valsToNames.end()) {
00544 name=nit->second;
00545 return true;
00546 }
00547 std::stringstream str;
00548 str << v;
00549 name=str.str();
00550 return false;
00551 }
00552 T val;
00553 T prevVal;
00554
00555
00556
00557 static std::map<std::string,T> namesToVals;
00558
00559
00560 static std::map<T,std::string> valsToNames;
00561 };
00562
00563 PLIST_CLONE_IMPT(T,NamedEnumeration,new NamedEnumeration<T>(*this));
00564
00565 #ifdef USE_GLOBAL_PLIST_STATICS
00566 template<typename T> std::map<std::string,T> plist::NamedEnumeration<T>::namesToVals;
00567 template<typename T> std::map<T,std::string> plist::NamedEnumeration<T>::valsToNames;
00568 #endif
00569
00570
00571
00572 #define INSTANTIATE_ALL_NAMEDENUMERATION_STATICS() \
00573 template<typename T> std::map<std::string,T> plist::NamedEnumeration<T>::namesToVals; \
00574 template<typename T> std::map<T,std::string> plist::NamedEnumeration<T>::valsToNames;
00575
00576
00577
00578 #define INSTANTIATE_NAMEDENUMERATION_STATICS(T) \
00579 template<> std::map<std::string,T> plist::NamedEnumeration<T>::namesToVals = std::map<std::string,T>(); \
00580 template<> std::map<T,std::string> plist::NamedEnumeration<T>::valsToNames = std::map<T,std::string>();
00581
00582 template<typename T> void NamedEnumeration<T>::setNames(const char * const* enumnames) {
00583 clearNames();
00584 for(unsigned int i=0; *enumnames[i]!='\0'; ++i) {
00585 std::string name=enumnames[i];
00586 valsToNames[static_cast<T>(i)]=name;
00587 std::transform(name.begin(), name.end(), name.begin(), (int(*)(int)) std::toupper);
00588 namesToVals[name]=static_cast<T>(i);
00589 }
00590 }
00591 template<typename T> void NamedEnumeration<T>::clearNames() {
00592 namesToVals.clear();
00593 valsToNames.clear();
00594 }
00595 template<typename T> void NamedEnumeration<T>::addNameForVal(const std::string& enumname, const T& val) {
00596 if(valsToNames.find(val)==valsToNames.end())
00597 valsToNames[val]=enumname;
00598 std::string name=enumname;
00599 std::transform(name.begin(), name.end(), name.begin(), (int(*)(int)) std::toupper);
00600 namesToVals[name]=val;
00601 }
00602 template<typename T> void NamedEnumeration<T>::setPreferredNameForVal(const std::string& enumname, const T& val) {
00603 valsToNames[val]=enumname;
00604 }
00605
00606 template<typename T> void NamedEnumeration<T>::getPreferredNames(std::map<int,std::string>& names) const {
00607 names.clear();
00608 for(typename std::map<T,std::string>::const_iterator it=valsToNames.begin(); it!=valsToNames.end(); ++it)
00609 names.insert(std::pair<int,std::string>(it->first,it->second));
00610 }
00611 template<typename T> void NamedEnumeration<T>::getAllNames(std::map<std::string,int>& names) const {
00612 names.clear();
00613 for(typename std::map<std::string,T>::const_iterator it=namesToVals.begin(); it!=namesToVals.end(); ++it)
00614 names.insert(std::pair<std::string,int>(it->first,it->second));
00615 }
00616
00617 }
00618
00619
00620
00621
00622
00623
00624
00625
00626
00627
00628
00629
00630
00631 #endif