00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00014
00015
00016 #ifndef __defined_libdai_properties_h
00017 #define __defined_libdai_properties_h
00018
00019
00020 #include <iostream>
00021 #include <sstream>
00022 #include <boost/any.hpp>
00023 #include <map>
00024 #include <vector>
00025 #include <typeinfo>
00026 #include <dai/exceptions.h>
00027 #include <dai/util.h>
00028 #include <boost/lexical_cast.hpp>
00029
00030
00031 namespace dai {
00032
00033
00035 typedef std::string PropertyKey;
00036
00038 typedef boost::any PropertyValue;
00039
00041 typedef std::pair<PropertyKey, PropertyValue> Property;
00042
00043
00045
00049 std::ostream& operator<< ( std::ostream & os, const Property &p );
00050
00051
00053
00076 class PropertySet : private std::map<PropertyKey, PropertyValue> {
00077 public:
00079
00080
00081 PropertySet() {}
00082
00084
00086 PropertySet( const std::string& s ) {
00087 std::stringstream ss;
00088 ss << s;
00089 ss >> *this;
00090 }
00092
00094
00095
00096 PropertySet& set( const PropertyKey& key, const PropertyValue& val ) {
00097 this->operator[](key) = val;
00098 return *this;
00099 }
00100
00102
00104 PropertySet& Set( const PropertyKey& key, const PropertyValue& val ) {
00105 return set( key, val );
00106 }
00107
00109 PropertySet& set( const PropertySet& newProps ) {
00110 const std::map<PropertyKey, PropertyValue> *m = &newProps;
00111 foreach(value_type i, *m)
00112 set( i.first, i.second );
00113 return *this;
00114 }
00115
00117
00119 PropertySet& Set( const PropertySet& newProps ) {
00120 return set( newProps );
00121 }
00122
00124
00129 PropertySet operator()( const PropertyKey& key, const PropertyValue& val ) const {
00130 PropertySet copy = *this;
00131 return copy.set(key,val);
00132 }
00133
00135
00139 template<typename ValueType>
00140 PropertySet& setAsString( const PropertyKey& key, const ValueType& val ) {
00141 try {
00142 return set( key, boost::lexical_cast<std::string>(val) );
00143 } catch( boost::bad_lexical_cast & ) {
00144 DAI_THROWE(IMPOSSIBLE_TYPECAST,"Cannot cast value of property '" + key + "' to string.");
00145 }
00146 }
00147
00149
00153 template<typename ValueType>
00154 void convertTo( const PropertyKey& key ) {
00155 PropertyValue val = get(key);
00156 if( val.type() != typeid(ValueType) ) {
00157 DAI_ASSERT( val.type() == typeid(std::string) );
00158 try {
00159 set(key, boost::lexical_cast<ValueType>(getAs<std::string>(key)));
00160 } catch(boost::bad_lexical_cast &) {
00161 DAI_THROWE(IMPOSSIBLE_TYPECAST,"Cannot cast value of property '" + key + "' from string to desired type.");
00162 }
00163 }
00164 }
00165
00167
00172 template<typename ValueType>
00173 void ConvertTo( const PropertyKey& key ) {
00174 convertTo<ValueType>( key );
00175 }
00177
00179
00181
00182
00183 size_t size() const {
00184 return std::map<PropertyKey, PropertyValue>::size();
00185 }
00186
00188 void clear() {
00189 std::map<PropertyKey, PropertyValue>::clear();
00190 }
00191
00193 size_t erase( const PropertyKey &key ) {
00194 return std::map<PropertyKey, PropertyValue>::erase( key );
00195 }
00196
00198 bool hasKey( const PropertyKey& key ) const {
00199 PropertySet::const_iterator x = find(key);
00200 return (x != this->end());
00201 }
00202
00204 std::set<PropertyKey> keys() const {
00205 std::set<PropertyKey> res;
00206 const_iterator i;
00207 for( i = begin(); i != end(); i++ )
00208 res.insert( i->first );
00209 return res;
00210 }
00211
00213
00215 const PropertyValue& get( const PropertyKey& key ) const {
00216 PropertySet::const_iterator x = find(key);
00217 if( x == this->end() )
00218 DAI_THROWE(OBJECT_NOT_FOUND,"PropertySet::get cannot find property '" + key + "'");
00219 return x->second;
00220 }
00221
00223
00226 const PropertyValue& Get( const PropertyKey& key ) const {
00227 return get( key );
00228 }
00229
00231
00235 template<typename ValueType>
00236 ValueType getAs( const PropertyKey& key ) const {
00237 try {
00238 return boost::any_cast<ValueType>(get(key));
00239 } catch( const boost::bad_any_cast & ) {
00240 DAI_THROWE(IMPOSSIBLE_TYPECAST,"Cannot cast value of property '" + key + "' to desired type.");
00241 return ValueType();
00242 }
00243 }
00244
00246
00251 template<typename ValueType>
00252 ValueType GetAs( const PropertyKey& key ) const {
00253 return getAs<ValueType>( key );
00254 }
00255
00257
00264 template<typename ValueType>
00265 ValueType getStringAs( const PropertyKey& key ) const {
00266 PropertyValue val = get(key);
00267 if( val.type() == typeid(ValueType) ) {
00268 return boost::any_cast<ValueType>(val);
00269 } else if( val.type() == typeid(std::string) ) {
00270 try {
00271 return boost::lexical_cast<ValueType>(getAs<std::string>(key));
00272 } catch(boost::bad_lexical_cast &) {
00273 DAI_THROWE(IMPOSSIBLE_TYPECAST,"Cannot cast value of property '" + key + "' from string to desired type.");
00274 }
00275 } else
00276 DAI_THROWE(IMPOSSIBLE_TYPECAST,"Cannot cast value of property '" + key + "' from string to desired type.");
00277 return ValueType();
00278 }
00280
00282
00283
00284
00289 friend std::ostream& operator<< ( std::ostream& os, const PropertySet& ps );
00290
00292
00296 friend std::istream& operator>> ( std::istream& is, PropertySet& ps );
00298 };
00299
00300
00301 }
00302
00303
00304 #endif