Significant improvement of documentation
[libdai.git] / include / dai / properties.h
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
4
5 This file is part of libDAI.
6
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.
11
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.
16
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
20 */
21
22
23 /// \file
24 /// \brief Defines the Property and PropertySet classes
25
26
27 #ifndef __defined_libdai_properties_h
28 #define __defined_libdai_properties_h
29
30
31 #include <iostream>
32 #include <sstream>
33 #include <boost/any.hpp>
34 #include <map>
35 #include <cassert>
36 #include <typeinfo>
37 #include <dai/exceptions.h>
38
39
40 namespace dai {
41
42
43 /// Type of the key of a Property
44 typedef std::string PropertyKey;
45
46 /// Type of the value of a Property
47 typedef boost::any PropertyValue;
48
49 /// A Property is a pair of a key and a corresponding value
50 typedef std::pair<PropertyKey, PropertyValue> Property;
51
52
53 /// Writes a Property object to an output stream
54 std::ostream& operator<< (std::ostream & os, const Property & p);
55
56
57 /// Represents a set of properties, mapping keys (of type PropertyKey) to values (of type PropertyValue)
58 class PropertySet : private std::map<PropertyKey, PropertyValue> {
59 public:
60 /// Gets a property
61 const PropertyValue & Get(const PropertyKey &key) const {
62 PropertySet::const_iterator x = find(key);
63 #ifdef DAI_DEBUG
64 if( x == this->end() )
65 std::cerr << "PropertySet::Get cannot find property " << key << std::endl;
66 #endif
67 assert( x != this->end() );
68 return x->second;
69 }
70
71 /// Sets a property
72 PropertySet & Set(const PropertyKey &key, const PropertyValue &val) { this->operator[](key) = val; return *this; }
73
74 /// Gets a property, casted as ValueType
75 template<typename ValueType>
76 ValueType GetAs(const PropertyKey &key) const {
77 try {
78 return boost::any_cast<ValueType>(Get(key));
79 } catch( const boost::bad_any_cast & ) {
80 std::cerr << "Cannot cast property " << key << " to ";
81 std::cerr << typeid(ValueType).name() << std::endl;
82 return boost::any_cast<ValueType>(Get(key));
83 }
84 }
85
86 /// Converts a property from string to ValueType (if necessary)
87 template<typename ValueType>
88 void ConvertTo(const PropertyKey &key) {
89 PropertyValue val = Get(key);
90 if( val.type() != typeid(ValueType) ) {
91 assert( val.type() == typeid(std::string) );
92
93 std::stringstream ss;
94 ss << GetAs<std::string>(key);
95 ValueType result;
96 ss >> result;
97
98 Set(key, result);
99 }
100 }
101
102 /// Converts a property from string to ValueType (if necessary)
103 template<typename ValueType>
104 ValueType getStringAs(const PropertyKey &key) const {
105 PropertyValue val = Get(key);
106 if( val.type() == typeid(std::string) ) {
107 std::stringstream ss;
108 ss << GetAs<std::string>(key);
109 ValueType result;
110 ss >> result;
111 return result;
112 } else if( val.type() == typeid(ValueType) ) {
113 return boost::any_cast<ValueType>(val);
114 } else {
115 DAI_THROW(IMPOSSIBLE_TYPECAST);
116 return ValueType();
117 }
118 }
119
120 /// Converts a property from ValueType to string (if necessary)
121 template<typename ValueType>
122 PropertySet & setAsString(const PropertyKey &key, ValueType &val) {
123 if( val.type() == typeid(std::string) ) {
124 return Set(key, val);
125 } else {
126 std::stringstream ss (std::stringstream::out);
127 ss << val;
128 return Set(key, ss.str());
129 }
130 }
131
132 /// Shorthand for (temporarily) adding properties, e.g. PropertySet p()("method","BP")("verbose",1)("tol",1e-9)
133 PropertySet operator()(const PropertyKey &key, const PropertyValue &val) const { PropertySet copy = *this; return copy.Set(key,val); }
134
135 /// Check if a property with the given key exists
136 bool hasKey(const PropertyKey &key) const { PropertySet::const_iterator x = find(key); return (x != this->end()); }
137
138 // Friends
139 friend std::ostream& operator<< (std::ostream & os, const PropertySet & ps);
140 friend std::istream& operator>> (std::istream& is, PropertySet & ps);
141 };
142
143
144 } // end of namespace dai
145
146
147 #endif