4e661dc68022590e9e12589654f1d9070f66b4d6
1 /* Copyright (C) 2006-2008 Joris Mooij [joris dot mooij at tuebingen dot mpg dot de]
2 Radboud University Nijmegen, The Netherlands /
3 Max Planck Institute for Biological Cybernetics, Germany
5 This file is part of libDAI.
7 libDAI is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 libDAI is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with libDAI; if not, write to the Free Software
19 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
24 /// \brief Defines the Property and PropertySet classes
25 /// \todo Improve documentation
28 #ifndef __defined_libdai_properties_h
29 #define __defined_libdai_properties_h
34 #include <boost/any.hpp>
39 #include <dai/exceptions.h>
41 #include <boost/lexical_cast.hpp>
47 /// Type of the key of a Property
48 typedef std::string PropertyKey
;
50 /// Type of the value of a Property
51 typedef boost::any PropertyValue
;
53 /// A Property is a pair of a key and a corresponding value
54 typedef std::pair
<PropertyKey
, PropertyValue
> Property
;
57 /// Writes a Property object to an output stream
58 std::ostream
& operator<< (std::ostream
& os
, const Property
& p
);
61 /// Represents a set of properties, mapping keys (of type PropertyKey) to values (of type PropertyValue)
62 class PropertySet
: private std::map
<PropertyKey
, PropertyValue
> {
64 /// Default constructor
67 /// Construct PropertySet from a string
68 PropertySet( const std::string
&s
) {
75 const PropertyValue
& Get(const PropertyKey
&key
) const {
76 PropertySet::const_iterator x
= find(key
);
78 if( x
== this->end() )
79 std::cerr
<< "PropertySet::Get cannot find property " << key
<< std::endl
;
81 assert( x
!= this->end() );
86 PropertySet
& Set(const PropertyKey
&key
, const PropertyValue
&val
) { this->operator[](key
) = val
; return *this; }
88 /// Set properties according to those in newProps, overriding properties that already exist with new values
89 PropertySet
& Set( const PropertySet
&newProps
) {
90 const std::map
<PropertyKey
, PropertyValue
> *m
= &newProps
;
91 foreach(value_type i
, *m
)
92 Set( i
.first
, i
.second
);
96 /// Gets a property, casted as ValueType
97 template<typename ValueType
>
98 ValueType
GetAs(const PropertyKey
&key
) const {
100 return boost::any_cast
<ValueType
>(Get(key
));
101 } catch( const boost::bad_any_cast
& ) {
102 DAI_THROWE(IMPOSSIBLE_TYPECAST
,"Cannot cast value of property '" + key
+ "' to desired type.");
107 /// Converts a property from string to ValueType (if necessary)
108 template<typename ValueType
>
109 void ConvertTo(const PropertyKey
&key
) {
110 PropertyValue val
= Get(key
);
111 if( val
.type() != typeid(ValueType
) ) {
112 assert( val
.type() == typeid(std::string
) );
114 Set(key
, boost::lexical_cast
<ValueType
>(GetAs
<std::string
>(key
)));
115 } catch(boost::bad_lexical_cast
&) {
116 DAI_THROWE(IMPOSSIBLE_TYPECAST
,"Cannot cast value of property '" + key
+ "' from string to desired type.");
121 /// Converts a property from string to ValueType (if necessary)
122 template<typename ValueType
>
123 ValueType
getStringAs(const PropertyKey
&key
) const {
124 PropertyValue val
= Get(key
);
125 if( val
.type() == typeid(ValueType
) ) {
126 return boost::any_cast
<ValueType
>(val
);
127 } else if( val
.type() == typeid(std::string
) ) {
129 return boost::lexical_cast
<ValueType
>(GetAs
<std::string
>(key
));
130 } catch(boost::bad_lexical_cast
&) {
131 DAI_THROWE(IMPOSSIBLE_TYPECAST
,"Cannot cast value of property '" + key
+ "' from string to desired type.");
134 DAI_THROWE(IMPOSSIBLE_TYPECAST
,"Cannot cast value of property '" + key
+ "' from string to desired type.");
138 /// Converts a property from ValueType to string (if necessary)
139 template<typename ValueType
>
140 PropertySet
& setAsString(const PropertyKey
&key
, ValueType
&val
) {
142 return Set( key
, boost::lexical_cast
<std::string
>(val
) );
143 } catch( boost::bad_lexical_cast
& ) {
144 DAI_THROWE(IMPOSSIBLE_TYPECAST
,"Cannot cast value of property '" + key
+ "' to string.");
148 /// Shorthand for (temporarily) adding properties, e.g. PropertySet p()("method","BP")("verbose",1)("tol",1e-9)
149 PropertySet
operator()(const PropertyKey
&key
, const PropertyValue
&val
) const { PropertySet copy
= *this; return copy
.Set(key
,val
); }
151 /// Check if a property with the given key exists
152 bool hasKey(const PropertyKey
&key
) const { PropertySet::const_iterator x
= find(key
); return (x
!= this->end()); }
154 /// Returns a set containing all keys
155 std::set
<PropertyKey
> allKeys() const {
156 std::set
<PropertyKey
> res
;
158 for( i
= begin(); i
!= end(); i
++ )
159 res
.insert( i
->first
);
163 /// Returns a vector containing all keys
164 std::vector
<PropertyKey
> keys() const {
165 std::vector
<PropertyKey
> result
;
166 result
.reserve( size() );
167 for( PropertySet::const_iterator i
= begin(); i
!= end(); ++i
)
168 result
.push_back( i
->first
);
172 /// Writes a PropertySet object to an output stream
173 friend std::ostream
& operator<< (std::ostream
& os
, const PropertySet
& ps
);
175 /// Reads a PropertySet object from an input stream, storing values as strings
176 friend std::istream
& operator>> (std::istream
& is
, PropertySet
& ps
);
180 } // end of namespace dai