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 std::ostream& operator<< ( std::ostream & os, const Property &p );
00046
00047
00049
00072 class PropertySet : private std::map<PropertyKey, PropertyValue> {
00073 public:
00075
00076
00077 PropertySet() {}
00078
00080
00082 PropertySet( const std::string& s ) {
00083 std::stringstream ss;
00084 ss << s;
00085 ss >> *this;
00086 }
00088
00090
00091
00092 PropertySet& Set( const PropertyKey& key, const PropertyValue& val ) {
00093 this->operator[](key) = val;
00094 return *this;
00095 }
00096
00098 PropertySet& Set( const PropertySet& newProps ) {
00099 const std::map<PropertyKey, PropertyValue> *m = &newProps;
00100 foreach(value_type i, *m)
00101 Set( i.first, i.second );
00102 return *this;
00103 }
00104
00106
00111 PropertySet operator()( const PropertyKey& key, const PropertyValue& val ) const {
00112 PropertySet copy = *this;
00113 return copy.Set(key,val);
00114 }
00115
00117
00121 template<typename ValueType>
00122 PropertySet& setAsString( const PropertyKey& key, ValueType& val ) {
00123 try {
00124 return Set( key, boost::lexical_cast<std::string>(val) );
00125 } catch( boost::bad_lexical_cast & ) {
00126 DAI_THROWE(IMPOSSIBLE_TYPECAST,"Cannot cast value of property '" + key + "' to string.");
00127 }
00128 }
00129
00131
00135 template<typename ValueType>
00136 void ConvertTo( const PropertyKey& key ) {
00137 PropertyValue val = Get(key);
00138 if( val.type() != typeid(ValueType) ) {
00139 DAI_ASSERT( val.type() == typeid(std::string) );
00140 try {
00141 Set(key, boost::lexical_cast<ValueType>(GetAs<std::string>(key)));
00142 } catch(boost::bad_lexical_cast &) {
00143 DAI_THROWE(IMPOSSIBLE_TYPECAST,"Cannot cast value of property '" + key + "' from string to desired type.");
00144 }
00145 }
00146 }
00148
00150
00152
00153
00154 bool hasKey( const PropertyKey& key ) const {
00155 PropertySet::const_iterator x = find(key);
00156 return (x != this->end());
00157 }
00158
00160 std::set<PropertyKey> keys() const {
00161 std::set<PropertyKey> res;
00162 const_iterator i;
00163 for( i = begin(); i != end(); i++ )
00164 res.insert( i->first );
00165 return res;
00166 }
00167
00169
00171 const PropertyValue& Get( const PropertyKey& key ) const {
00172 PropertySet::const_iterator x = find(key);
00173 if( x == this->end() )
00174 DAI_THROWE(OBJECT_NOT_FOUND,"PropertySet::Get cannot find property '" + key + "'");
00175 return x->second;
00176 }
00177
00179
00183 template<typename ValueType>
00184 ValueType GetAs( const PropertyKey& key ) const {
00185 try {
00186 return boost::any_cast<ValueType>(Get(key));
00187 } catch( const boost::bad_any_cast & ) {
00188 DAI_THROWE(IMPOSSIBLE_TYPECAST,"Cannot cast value of property '" + key + "' to desired type.");
00189 return ValueType();
00190 }
00191 }
00192
00194
00201 template<typename ValueType>
00202 ValueType getStringAs( const PropertyKey& key ) const {
00203 PropertyValue val = Get(key);
00204 if( val.type() == typeid(ValueType) ) {
00205 return boost::any_cast<ValueType>(val);
00206 } else if( val.type() == typeid(std::string) ) {
00207 try {
00208 return boost::lexical_cast<ValueType>(GetAs<std::string>(key));
00209 } catch(boost::bad_lexical_cast &) {
00210 DAI_THROWE(IMPOSSIBLE_TYPECAST,"Cannot cast value of property '" + key + "' from string to desired type.");
00211 }
00212 } else
00213 DAI_THROWE(IMPOSSIBLE_TYPECAST,"Cannot cast value of property '" + key + "' from string to desired type.");
00214 return ValueType();
00215 }
00217
00219
00220
00221
00226 friend std::ostream& operator<< ( std::ostream& os, const PropertySet& ps );
00227
00229
00233 friend std::istream& operator>> ( std::istream& is, PropertySet& ps );
00235 };
00236
00237
00238 }
00239
00240
00241 #endif