Merge branch 'master' of git@git.tuebingen.mpg.de:libdai
[libdai.git] / src / properties.cpp
1 /* Copyright (C) 2006-2008 Joris Mooij [j dot mooij at science dot ru dot nl]
2 Radboud University Nijmegen, The Netherlands
3
4 This file is part of libDAI.
5
6 libDAI is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 libDAI is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with libDAI; if not, write to the Free Software
18 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
21
22 #include <iostream>
23 #include <dai/properties.h>
24 #include <dai/alldai.h>
25 #include <dai/exceptions.h>
26
27
28 namespace dai {
29
30
31 /// Sends a single Property object to an output stream
32 std::ostream& operator<< (std::ostream & os, const Property & p) {
33 os << p.first << "=";
34 if( p.second.type() == typeid(size_t) )
35 os << boost::any_cast<size_t>(p.second);
36 else if( p.second.type() == typeid(std::string) )
37 os << boost::any_cast<std::string>(p.second);
38 else if( p.second.type() == typeid(double) )
39 os << boost::any_cast<double>(p.second);
40 else if( p.second.type() == typeid(bool) )
41 os << boost::any_cast<bool>(p.second);
42 else if( p.second.type() == typeid(PropertySet) )
43 os << boost::any_cast<PropertySet>(p.second);
44 #ifdef WITH_BP
45 else if( p.second.type() == typeid(BP::Properties::UpdateType) )
46 os << boost::any_cast<BP::Properties::UpdateType>(p.second);
47 #endif
48 #ifdef WITH_HAK
49 else if( p.second.type() == typeid(HAK::Properties::ClustersType) )
50 os << boost::any_cast<HAK::Properties::ClustersType>(p.second);
51 #endif
52 #ifdef WITH_JTREE
53 else if( p.second.type() == typeid(JTree::Properties::UpdateType) )
54 os << boost::any_cast<JTree::Properties::UpdateType>(p.second);
55 #endif
56 #ifdef WITH_MR
57 else if( p.second.type() == typeid(MR::Properties::UpdateType) )
58 os << boost::any_cast<MR::Properties::UpdateType>(p.second);
59 else if( p.second.type() == typeid(MR::Properties::InitType) )
60 os << boost::any_cast<MR::Properties::InitType>(p.second);
61 #endif
62 #ifdef WITH_TREEEP
63 else if( p.second.type() == typeid(TreeEP::Properties::TypeType) )
64 os << boost::any_cast<TreeEP::Properties::TypeType>(p.second);
65 #endif
66 #ifdef WITH_LC
67 else if( p.second.type() == typeid(LC::Properties::CavityType) )
68 os << boost::any_cast<LC::Properties::CavityType>(p.second);
69 else if( p.second.type() == typeid(LC::Properties::UpdateType) )
70 os << boost::any_cast<LC::Properties::UpdateType>(p.second);
71 #endif
72 else
73 DAI_THROW(UNKNOWN_PROPERTY_TYPE);
74 return( os );
75 }
76
77
78 /// Sends a PropertySet object to an output stream
79 std::ostream& operator<< (std::ostream & os, const PropertySet & ps) {
80 os << "[";
81 for( PropertySet::const_iterator p = ps.begin(); p != ps.end(); p++ ) {
82 if( p != ps.begin() )
83 os << ",";
84 os << (Property)*p;
85 }
86 os << "]";
87 return os;
88 }
89
90
91 /// Reads a PropertySet object from an input stream, storing values as strings
92 std::istream& operator >> (std::istream& is, PropertySet & ps) {
93 ps = PropertySet();
94
95 std::string s;
96 is >> s;
97
98 // Check whether s is of the form "[.*]"
99 if( (s.length() < 2) || (s.at(0) != '[') || (s.at(s.length()-1)) != ']' )
100 DAI_THROW(MALFORMED_PROPERTY);
101
102 size_t N = s.length() - 1;
103 for( size_t token_start = 1; token_start < N; ) {
104 size_t token_end;
105
106 // scan until '=' is found
107 for( token_end = token_start + 1; token_end < N; token_end++ )
108 if( s[token_end] == '=' )
109 break;
110 if( token_end == N )
111 DAI_THROW(MALFORMED_PROPERTY);
112 // we found a key
113 std::string key = s.substr(token_start, token_end - token_start);
114
115 token_start = token_end + 1;
116 // scan until matching ',' is found
117 int level = 0;
118 for( token_end = token_start; token_end < N; token_end++ ) {
119 if( s[token_end] == '[' )
120 level++;
121 else if( s[token_end] == ']' )
122 level--;
123 else if( (s[token_end] == ',') && (level == 0) )
124 break;
125 }
126 if( !(level == 0) )
127 DAI_THROW(MALFORMED_PROPERTY);
128 // we found a vlue
129 std::string value = s.substr(token_start, token_end - token_start);
130
131 // store the key,value pair
132 ps.Set(key,value);
133
134 // go on with the next one
135 token_start = token_end + 1;
136 }
137
138 return is;
139 }
140
141
142 } // end of namespace dai