00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #ifndef OST_GENETRIC_PROPERTY_HH
00020 #define OST_GENETRIC_PROPERTY_HH
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031 #include <exception>
00032 #include <sstream>
00033 #include <map>
00034 #include <boost/variant.hpp>
00035
00036 #include <ost/module_config.hh>
00037
00038 namespace ost {
00039
00040 struct TEMPLATE_EXPORT GenericPropError: public std::exception
00041 {
00042 GenericPropError(const String& m):
00043 m_(m)
00044 {}
00045 virtual ~GenericPropError() throw() {}
00046 virtual const char* what() const throw() {
00047 return m_.c_str();
00048 }
00049 String m_;
00050 };
00051
00052 typedef boost::variant<String, Real, int, bool> GenericPropValue;
00053
00055 class TEMPLATE_EXPORT GenericPropContainerImpl
00056 {
00057 typedef std::map<String,GenericPropValue> PropertyMap;
00058
00059 public:
00060 GenericPropContainerImpl(): map_(NULL) {}
00061 ~GenericPropContainerImpl()
00062 {
00063 if (map_) {
00064 delete map_;
00065 }
00066 }
00067 GenericPropContainerImpl(const GenericPropContainerImpl& rhs):
00068 map_(rhs.map_ ? new PropertyMap(*rhs.map_) : NULL)
00069 { }
00070
00071 GenericPropContainerImpl& operator=(const GenericPropContainerImpl& r)
00072 {
00073 this->Assign(r);
00074 return *this;
00075 }
00076
00077 GenericPropValue& GenericProp(const String& key)
00078 {
00079 if (!map_) {
00080 map_=new PropertyMap;
00081 }
00082 return (*map_)[key];
00083 }
00084
00085 const GenericPropValue& GenericProp(const String& key) const
00086 {
00087 if (!map_) {
00088 map_=new PropertyMap;
00089 }
00090 return (*map_)[key];
00091 }
00092
00093 bool HasProp(const String& key) const
00094 {
00095 return map_ && map_->find(key) != map_->end();
00096 }
00097
00098 void ClearProps()
00099 {
00100 if (map_) {
00101 map_->clear();
00102 }
00103 }
00104
00105 void Assign(const GenericPropContainerImpl& impl)
00106 {
00107 if (impl.map_) {
00108 if (!map_) {
00109 map_=new PropertyMap(*impl.map_);
00110 } else {
00111 *map_=*impl.map_;
00112 }
00113 } else {
00114 this->ClearProps();
00115 }
00116 }
00117
00118 PropertyMap GetPropMap() const
00119 {
00120 if (!map_) {
00121 map_=new PropertyMap;
00122 }
00123 return *map_;
00124 }
00125
00126
00127 private:
00128 mutable PropertyMap* map_;
00129 };
00130
00131 template <typename H>
00132 class TEMPLATE_EXPORT ConstGenericPropContainer {
00133 protected:
00134
00135 template<typename T>
00136 T gp_get(const String& key) const {
00137 if(HasProp(key)) {
00138 return boost::get<T>(GetImpl()->GenericProp(key));
00139 } else {
00140 std::ostringstream m("");
00141 m << "unknown property " << key;
00142 throw GenericPropError(m.str());
00143 }
00144 }
00145
00146 template<typename T>
00147 T gp_get(const String& key, const T& def) const {
00148 if(HasProp(key)) {
00149 return boost::get<T>(GetImpl()->GenericProp(key));
00150 }
00151 return def;
00152 }
00153 GenericPropContainerImpl* GetImpl()
00154 {
00155 return static_cast<H*>(this)->GpImpl();
00156 }
00157
00158 const GenericPropContainerImpl* GetImpl() const
00159 {
00160 return static_cast<const H*>(this)->GpImpl();
00161 }
00162 public:
00164 bool HasProp(const String& key) const {
00165 return this->GetImpl()->HasProp(key);
00166 }
00167
00175 String GetPropAsString(const String& key) const
00176 {
00177 if(!HasProp(key)) return "";
00178 std::ostringstream rep("");
00179 rep << this->GetImpl()->GenericProp(key);
00180 return rep.str();
00181 }
00183 String GetStringProp(const String& key) const
00184 {
00185 return this->gp_get<String>(key);
00186 }
00187
00190 Real GetFloatProp(const String& key) const
00191 {
00192 if(HasProp(key)) {
00193 GenericPropValue value=this->GetImpl()->GenericProp(key);
00194 if (value.which()==1) {
00195 return boost::get<Real>(this->GetImpl()->GenericProp(key));
00196 } else if (value.which()==2) {
00197 return boost::get<int>(this->GetImpl()->GenericProp(key));
00198 }
00199 std::ostringstream m("");
00200 m << "property '" << key << "' is not numeric";
00201 throw GenericPropError(m.str());
00202 } else {
00203 std::ostringstream m("");
00204 m << "unknown property " << key;
00205 throw GenericPropError(m.str());
00206 }
00207 }
00208
00209
00211 int GetIntProp(const String& key) const
00212 {
00213 return this->gp_get<int>(key);
00214 }
00215
00217 bool GetBoolProp(const String& key) const
00218 {
00219 return this->gp_get<bool>(key);
00220 }
00221
00223 String GetStringProp(const String& key, const String& def) const
00224 {
00225 return this->gp_get<String>(key,def);
00226 }
00227
00230 Real GetFloatProp(const String& key, Real def) const
00231 {
00232 if(this->HasProp(key)) {
00233 GenericPropValue value=GetImpl()->GenericProp(key);
00234 if (value.which()==1) {
00235 return boost::get<Real>(GetImpl()->GenericProp(key));
00236 } else if (value.which()==2) {
00237 return boost::get<int>(GetImpl()->GenericProp(key));
00238 }
00239 std::ostringstream m("");
00240 m << "property '" << key << "' is not numeric";
00241 throw GenericPropError(m.str());
00242 } else {
00243 return def;
00244 }
00245 }
00246
00248 int GetIntProp(const String& key, int def) const
00249 {
00250 return this->gp_get<int>(key, def);
00251 }
00252
00254 bool GetBoolProp(const String& key, bool def) const
00255 {
00256 return this->gp_get<bool>(key, def);
00257 }
00258
00259 std::map<String,GenericPropValue> GetPropMap() const
00260 {
00261 return this->GetImpl()->GetPropMap();
00262 }
00263 };
00264
00266 template <typename H>
00267 class TEMPLATE_EXPORT GenericPropContainer :
00268 public ConstGenericPropContainer<H>
00269 {
00270 public:
00271 void ClearProps()
00272 {
00273 this->GetImpl()->ClearProps();
00274 }
00275
00277 void SetStringProp(const String& key, const String& value)
00278 {
00279 this->GetImpl()->GenericProp(key)=value;
00280 }
00281
00283 void SetFloatProp(const String& key, Real value)
00284 {
00285 this->GetImpl()->GenericProp(key)=value;
00286 }
00287
00289 void SetIntProp(const String& key, int value)
00290 {
00291 this->GetImpl()->GenericProp(key)=value;
00292 }
00293
00295 void SetBoolProp(const String& key, bool value)
00296 {
00297 this->GetImpl()->GenericProp(key)=value;
00298 }
00299 };
00300
00301
00302 }
00303
00304 #endif