libDAI
|
00001 /* This file is part of libDAI - http://www.libdai.org/ 00002 * 00003 * Copyright (c) 2006-2011, The libDAI authors. All rights reserved. 00004 * 00005 * Use of this source code is governed by a BSD-style license that can be found in the LICENSE file. 00006 */ 00007 00008 00011 00012 00013 #ifndef __defined_libdai_properties_h 00014 #define __defined_libdai_properties_h 00015 00016 00017 #include <iostream> 00018 #include <sstream> 00019 #include <boost/any.hpp> 00020 #include <map> 00021 #include <vector> 00022 #include <typeinfo> 00023 #include <dai/exceptions.h> 00024 #include <dai/util.h> 00025 #include <boost/lexical_cast.hpp> 00026 00027 00028 namespace dai { 00029 00030 00032 typedef std::string PropertyKey; 00033 00035 typedef boost::any PropertyValue; 00036 00038 typedef std::pair<PropertyKey, PropertyValue> Property; 00039 00040 00042 00046 std::ostream& operator<< ( std::ostream & os, const Property &p ); 00047 00048 00050 00073 class PropertySet : private std::map<PropertyKey, PropertyValue> { 00074 public: 00076 00077 00078 PropertySet() {} 00079 00081 00083 PropertySet( const std::string& s ) { 00084 std::stringstream ss; 00085 ss << s; 00086 ss >> *this; 00087 } 00089 00091 00092 00093 PropertySet& set( const PropertyKey& key, const PropertyValue& val ) { 00094 this->operator[](key) = val; 00095 return *this; 00096 } 00097 00099 PropertySet& set( const PropertySet& newProps ) { 00100 const std::map<PropertyKey, PropertyValue> *m = &newProps; 00101 foreach(value_type i, *m) 00102 set( i.first, i.second ); 00103 return *this; 00104 } 00105 00107 00112 PropertySet operator()( const PropertyKey& key, const PropertyValue& val ) const { 00113 PropertySet copy = *this; 00114 return copy.set(key,val); 00115 } 00116 00118 00122 template<typename ValueType> 00123 PropertySet& setAsString( const PropertyKey& key, const ValueType& val ) { 00124 try { 00125 return set( key, boost::lexical_cast<std::string>(val) ); 00126 } catch( boost::bad_lexical_cast & ) { 00127 DAI_THROWE(IMPOSSIBLE_TYPECAST,"Cannot cast value of property '" + key + "' to string."); 00128 } 00129 } 00130 00132 00136 template<typename ValueType> 00137 void convertTo( const PropertyKey& key ) { 00138 PropertyValue val = get(key); 00139 if( val.type() != typeid(ValueType) ) { 00140 DAI_ASSERT( val.type() == typeid(std::string) ); 00141 try { 00142 set(key, boost::lexical_cast<ValueType>(getAs<std::string>(key))); 00143 } catch(boost::bad_lexical_cast &) { 00144 DAI_THROWE(IMPOSSIBLE_TYPECAST,"Cannot cast value of property '" + key + "' from string to desired type."); 00145 } 00146 } 00147 } 00149 00151 00153 00154 00155 size_t size() const { 00156 return std::map<PropertyKey, PropertyValue>::size(); 00157 } 00158 00160 void clear() { 00161 std::map<PropertyKey, PropertyValue>::clear(); 00162 } 00163 00165 size_t erase( const PropertyKey &key ) { 00166 return std::map<PropertyKey, PropertyValue>::erase( key ); 00167 } 00168 00170 bool hasKey( const PropertyKey& key ) const { 00171 PropertySet::const_iterator x = find(key); 00172 return (x != this->end()); 00173 } 00174 00176 std::set<PropertyKey> keys() const { 00177 std::set<PropertyKey> res; 00178 const_iterator i; 00179 for( i = begin(); i != end(); i++ ) 00180 res.insert( i->first ); 00181 return res; 00182 } 00183 00185 00187 const PropertyValue& get( const PropertyKey& key ) const { 00188 PropertySet::const_iterator x = find(key); 00189 if( x == this->end() ) 00190 DAI_THROWE(OBJECT_NOT_FOUND,"PropertySet::get cannot find property '" + key + "'"); 00191 return x->second; 00192 } 00193 00195 00199 template<typename ValueType> 00200 ValueType getAs( const PropertyKey& key ) const { 00201 try { 00202 return boost::any_cast<ValueType>(get(key)); 00203 } catch( const boost::bad_any_cast & ) { 00204 DAI_THROWE(IMPOSSIBLE_TYPECAST,"Cannot cast value of property '" + key + "' to desired type."); 00205 return ValueType(); 00206 } 00207 } 00208 00210 00217 template<typename ValueType> 00218 ValueType getStringAs( const PropertyKey& key ) const { 00219 PropertyValue val = get(key); 00220 if( val.type() == typeid(ValueType) ) { 00221 return boost::any_cast<ValueType>(val); 00222 } else if( val.type() == typeid(std::string) ) { 00223 try { 00224 return boost::lexical_cast<ValueType>(getAs<std::string>(key)); 00225 } catch(boost::bad_lexical_cast &) { 00226 DAI_THROWE(IMPOSSIBLE_TYPECAST,"Cannot cast value of property '" + key + "' from string to desired type."); 00227 } 00228 } else 00229 DAI_THROWE(IMPOSSIBLE_TYPECAST,"Cannot cast value of property '" + key + "' from string to desired type."); 00230 return ValueType(); 00231 } 00233 00235 00236 00237 00242 friend std::ostream& operator<< ( std::ostream& os, const PropertySet& ps ); 00243 00245 00249 friend std::istream& operator>> ( std::istream& is, PropertySet& ps ); 00251 }; 00252 00253 00254 } // end of namespace dai 00255 00256 00257 #endif