Main Page   Namespace List   Class Hierarchy   Compound List   File List   Namespace Members   Compound Members   File Members   Examples  

Attributes.H

Go to the documentation of this file.
00001 
00020 #ifndef _ATTRIBUTE_H
00021 #define _ATTRIBUTE_H
00022 
00023 #include <exception>
00024 #include <Vector.H>
00025 #include <string>
00026 
00027 using namespace std;
00028 
00029 
00030 namespace xchen
00031 {
00032 
00033   class Attribute 
00034   {
00035       friend class Attributes;
00036 
00037       string id;
00038       char const* type;
00039       void* val;    
00040 
00041   public:
00042       Attribute(Attribute const&);
00043       Attribute& operator=(Attribute const&);
00044       
00045 
00046       template<typename T>
00047       Attribute(string const& name, T const&v) : id(name), type(typeid(T).name()), val(new T(v)) { }                
00048       Attribute(string const& name, type_info const& t) : id(name), type(t.name()), val(0)       { }                
00049       ~Attribute()                                                                               { deallocate(); }  
00050       
00051       template<typename T>
00052       void SetValue(T const& v) { if(strcmp(typeid(T).name(),type)) throw "Attributes::SetValue() type mismatch!\n"; if(!val)val = new T(); *(T*)val = v; } 
00053       void const* GetValue()                                          { return val; }
00054       bool operator<(Attribute const& rhs) const                      { return id < rhs.id; }
00055       
00056       friend istream& operator>> (istream& is, Attribute& a);                                    
00057       friend ostream& operator<< (ostream& os, Attribute const& a);
00058       
00059   private:
00060       Attribute(string const& name) : id(name), type(typeid(int).name()), val(0) { }             // used by Attributes class for searching.
00061       Attribute(string const& name, char*) { throw "Attribute(string const&, char*) disabled, use Attribute(string const&, string const&) instead.\n"; }
00062 
00063       void deallocate();
00064       void allocate(void* v);                                       // deallocate, allocate and init value if v!=0.
00065   };
00066 
00067 
00068   class Attributes
00069   {
00070   public:
00071       template<typename T>
00072       void Register(string const& id, T const&v);                     
00073       void Register(string const& id, type_info const& t);            
00074 
00075       Attribute& operator[](string const& id);
00076       
00077       void ReadFrom(int argc, char** argv);                           
00078       void ReadFrom(string const& str);                               
00079         
00080       friend istream& operator>> (istream& is, Attributes&);          
00081       friend ostream& operator<< (ostream& os, Attributes const&);
00082       
00083   private:
00084       set<Attribute> attr;
00085   };
00086 
00087 
00088 
00089 
00090   inline Attribute :: Attribute(Attribute const& rhs) : id(rhs.id), type(rhs.type), val(0)
00091   {
00092     allocate(rhs.val);
00093   }
00094   
00095   inline Attribute& Attribute :: operator=(Attribute const& rhs)
00096   {
00097     if(this != &rhs)
00098     {
00099       id = rhs.id;
00100       type = rhs.type;
00101       allocate(rhs.val);
00102     }
00103     return *this;
00104   }
00105   
00106   inline void  Attribute::deallocate()
00107   {
00108     if(!val) return;
00109     
00110     if     (! strcmp(type, typeid(char).name()) )      delete (char*)val;
00111     else if(! strcmp(type, typeid(int).name()) )       delete (int*)val;
00112     else if(! strcmp(type, typeid(double).name()) )    delete (double*)val;
00113     else if(! strcmp(type, typeid(dVector2D).name()) ) delete (dVector2D*)val;
00114     else if(! strcmp(type, typeid(dVector3D).name()) ) delete (dVector3D*)val;
00115     else if(! strcmp(type, typeid(dVector4D).name()) ) delete (dVector4D*)val;
00116     else if(! strcmp(type, typeid(dVector5D).name()) ) delete (dVector5D*)val;
00117     else if(! strcmp(type, typeid(iVector2D).name()) ) delete (iVector2D*)val;
00118     else if(! strcmp(type, typeid(iVector3D).name()) ) delete (iVector3D*)val;
00119     else if(! strcmp(type, typeid(iVector4D).name()) ) delete (iVector4D*)val;
00120     else if(! strcmp(type, typeid(iVector5D).name()) ) delete (iVector5D*)val;
00121     else if(! strcmp(type, typeid(string).name()) )    delete (string*)val;
00122     else { throw "supported attributes types are int, char, double, dVector[2-5]D, string\n"; }
00123   }
00124   
00125 
00126   inline void  Attribute::allocate(void *v)
00127   {
00128     if(!v) return;
00129     
00130     if     (! strcmp(type, typeid(char).name()) )      { delete (char*)val;      val = new char(*(char*)v); }      
00131     else if(! strcmp(type, typeid(int).name()) )       { delete (int*)val;       val = new int(*(int*)v); }       
00132     else if(! strcmp(type, typeid(double).name()) )    { delete (double*)val;    val = new double(*(double*)v); }    
00133     else if(! strcmp(type, typeid(dVector2D).name()) ) { delete (dVector2D*)val; val = new dVector2D(*(dVector2D*)v); } 
00134     else if(! strcmp(type, typeid(dVector3D).name()) ) { delete (dVector3D*)val; val = new dVector3D(*(dVector3D*)v); } 
00135     else if(! strcmp(type, typeid(dVector4D).name()) ) { delete (dVector4D*)val; val = new dVector4D(*(dVector4D*)v); } 
00136     else if(! strcmp(type, typeid(dVector5D).name()) ) { delete (dVector5D*)val; val = new dVector5D(*(dVector5D*)v); } 
00137     else if(! strcmp(type, typeid(iVector2D).name()) ) { delete (iVector2D*)val; val = new iVector2D(*(iVector2D*)v); } 
00138     else if(! strcmp(type, typeid(iVector3D).name()) ) { delete (iVector3D*)val; val = new iVector3D(*(iVector3D*)v); } 
00139     else if(! strcmp(type, typeid(iVector4D).name()) ) { delete (iVector4D*)val; val = new iVector4D(*(iVector4D*)v); } 
00140     else if(! strcmp(type, typeid(iVector5D).name()) ) { delete (iVector5D*)val; val = new iVector5D(*(iVector5D*)v); } 
00141     else if(! strcmp(type, typeid(string).name()) )    { delete (string*)val;    val = new string(*(string*)v); }    
00142     else { throw "supported attributes types are int, char, double, dVector[2-5]D, string\n"; }
00143   }
00144 
00145 
00146 
00147   inline void Attributes :: Register(string const& id, type_info const& t) 
00148   { 
00149     if(! attr.insert(Attribute(id, t)).second) 
00150       cerr << "Registration Attribute \"" << id << "\" failed: an attribute of the same id has already registered.\n"; 
00151   }
00152 
00153   template<typename T>
00154   inline void Attributes :: Register(string const& id, T const&v)                      
00155   { 
00156     pair<set<Attribute>::iterator, bool> result = attr.insert(Attribute(id, typeid(T)));
00157     if(!result.second)
00158       cerr << "Registration Attribute \"" << id << "\" failed: an attribute of the same id has already registered.\n"; 
00159     else  
00160     {
00161       ((Attribute&)(*result.first)).SetValue(v); 
00162     }
00163     
00164   }
00165 
00166   inline Attribute& Attributes :: operator[](string const& id)
00167   {
00168     set<Attribute>::iterator itr = attr.find(Attribute(id)); 
00169     if(itr == attr.end())
00170       throw "attribute " + id + " unregistered.\n";
00171     return (Attribute&)(*itr);
00172   }
00173 
00174 
00175   typedef Attributes CommandLineArguments;
00176 }//end namespace xchen
00177 
00178 
00179 
00180 #endif

Generated on Wed Apr 7 21:40:49 2004 by doxygen1.2.18