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 PropertySet& set( const PropertySet& newProps ) {
00103 const std::map<PropertyKey, PropertyValue> *m = &newProps;
00104 foreach(value_type i, *m)
00105 set( i.first, i.second );
00106 return *this;
00107 }
00108
00110
00115 PropertySet operator()( const PropertyKey& key, const PropertyValue& val ) const {
00116 PropertySet copy = *this;
00117 return copy.set(key,val);
00118 }
00119
00121
00125 template<typename ValueType>
00126 PropertySet& setAsString( const PropertyKey& key, const ValueType& val ) {
00127 try {
00128 return set( key, boost::lexical_cast<std::string>(val) );
00129 } catch( boost::bad_lexical_cast & ) {
00130 DAI_THROWE(IMPOSSIBLE_TYPECAST,"Cannot cast value of property '" + key + "' to string.");
00131 }
00132 }
00133
00135
00139 template<typename ValueType>
00140 void convertTo( const PropertyKey& key ) {
00141 PropertyValue val = get(key);
00142 if( val.type() != typeid(ValueType) ) {
00143 DAI_ASSERT( val.type() == typeid(std::string) );
00144 try {
00145 set(key, boost::lexical_cast<ValueType>(getAs<std::string>(key)));
00146 } catch(boost::bad_lexical_cast &) {
00147 DAI_THROWE(IMPOSSIBLE_TYPECAST,"Cannot cast value of property '" + key + "' from string to desired type.");
00148 }
00149 }
00150 }
00152
00154
00156
00157
00158 size_t size() const {
00159 return std::map<PropertyKey, PropertyValue>::size();
00160 }
00161
00163 void clear() {
00164 std::map<PropertyKey, PropertyValue>::clear();
00165 }
00166
00168 size_t erase( const PropertyKey &key ) {
00169 return std::map<PropertyKey, PropertyValue>::erase( key );
00170 }
00171
00173 bool hasKey( const PropertyKey& key ) const {
00174 PropertySet::const_iterator x = find(key);
00175 return (x != this->end());
00176 }
00177
00179 std::set<PropertyKey> keys() const {
00180 std::set<PropertyKey> res;
00181 const_iterator i;
00182 for( i = begin(); i != end(); i++ )
00183 res.insert( i->first );
00184 return res;
00185 }
00186
00188
00190 const PropertyValue& get( const PropertyKey& key ) const {
00191 PropertySet::const_iterator x = find(key);
00192 if( x == this->end() )
00193 DAI_THROWE(OBJECT_NOT_FOUND,"PropertySet::get cannot find property '" + key + "'");
00194 return x->second;
00195 }
00196
00198
00202 template<typename ValueType>
00203 ValueType getAs( const PropertyKey& key ) const {
00204 try {
00205 return boost::any_cast<ValueType>(get(key));
00206 } catch( const boost::bad_any_cast & ) {
00207 DAI_THROWE(IMPOSSIBLE_TYPECAST,"Cannot cast value of property '" + key + "' to desired type.");
00208 return ValueType();
00209 }
00210 }
00211
00213
00220 template<typename ValueType>
00221 ValueType getStringAs( const PropertyKey& key ) const {
00222 PropertyValue val = get(key);
00223 if( val.type() == typeid(ValueType) ) {
00224 return boost::any_cast<ValueType>(val);
00225 } else if( val.type() == typeid(std::string) ) {
00226 try {
00227 return boost::lexical_cast<ValueType>(getAs<std::string>(key));
00228 } catch(boost::bad_lexical_cast &) {
00229 DAI_THROWE(IMPOSSIBLE_TYPECAST,"Cannot cast value of property '" + key + "' from string to desired type.");
00230 }
00231 } else
00232 DAI_THROWE(IMPOSSIBLE_TYPECAST,"Cannot cast value of property '" + key + "' from string to desired type.");
00233 return ValueType();
00234 }
00236
00238
00239
00240
00245 friend std::ostream& operator<< ( std::ostream& os, const PropertySet& ps );
00246
00248
00252 friend std::istream& operator>> ( std::istream& is, PropertySet& ps );
00254 };
00255
00256
00257 }
00258
00259
00260 #endif