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