Pervasive change of BipartiteGraph implementation
[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
26
27 namespace dai {
28
29
30 /// Sends a single Property object to an output stream
31 std::ostream& operator<< (std::ostream & os, const Property & p) {
32 os << p.first << "=";
33 if( p.second.type() == typeid(size_t) )
34 os << boost::any_cast<size_t>(p.second);
35 else if( p.second.type() == typeid(std::string) )
36 os << boost::any_cast<std::string>(p.second);
37 else if( p.second.type() == typeid(double) )
38 os << boost::any_cast<double>(p.second);
39 else if( p.second.type() == typeid(bool) )
40 os << boost::any_cast<bool>(p.second);
41 else if( p.second.type() == typeid(Properties) )
42 os << boost::any_cast<Properties>(p.second);
43 #ifdef WITH_BP
44 else if( p.second.type() == typeid(BP::UpdateType) )
45 os << boost::any_cast<BP::UpdateType>(p.second);
46 #endif
47 #ifdef WITH_HAK
48 else if( p.second.type() == typeid(HAK::ClustersType) )
49 os << boost::any_cast<HAK::ClustersType>(p.second);
50 #endif
51 #ifdef WITH_JTREE
52 else if( p.second.type() == typeid(JTree::UpdateType) )
53 os << boost::any_cast<JTree::UpdateType>(p.second);
54 #endif
55 #ifdef WITH_MR
56 else if( p.second.type() == typeid(MR::UpdateType) )
57 os << boost::any_cast<MR::UpdateType>(p.second);
58 else if( p.second.type() == typeid(MR::InitType) )
59 os << boost::any_cast<MR::InitType>(p.second);
60 #endif
61 #ifdef WITH_TREEEP
62 else if( p.second.type() == typeid(TreeEP::TypeType) )
63 os << boost::any_cast<TreeEP::TypeType>(p.second);
64 #endif
65 #ifdef WITH_LC
66 else if( p.second.type() == typeid(LC::CavityType) )
67 os << boost::any_cast<LC::CavityType>(p.second);
68 else if( p.second.type() == typeid(LC::UpdateType) )
69 os << boost::any_cast<LC::UpdateType>(p.second);
70 #endif
71 else
72 throw "Unknown property type";
73 return( os );
74 }
75
76
77 /// Sends a Properties object to an output stream
78 std::ostream& operator<< (std::ostream & os, const Properties & ps) {
79 os << "[";
80 for( Properties::const_iterator p = ps.begin(); p != ps.end(); p++ ) {
81 if( p != ps.begin() )
82 os << ",";
83 os << *p;
84 }
85 os << "]";
86 return os;
87 }
88
89
90 /// Reads a Properties object from an input stream, storing values as strings
91 std::istream& operator >> (std::istream& is, Properties & ps) {
92 ps = Properties();
93
94 std::string s;
95 is >> s;
96
97 // Check whether s is of the form "[.*]"
98 if( (s.length() < 2) || (s.at(0) != '[') || (s.at(s.length()-1)) != ']' )
99 throw "Malformed property";
100
101 size_t N = s.length() - 1;
102 for( size_t token_start = 1; token_start < N; ) {
103 size_t token_end;
104
105 // scan until '=' is found
106 for( token_end = token_start + 1; token_end < N; token_end++ )
107 if( s[token_end] == '=' )
108 break;
109 if( token_end == N )
110 throw "Malformed property key";
111 // we found a key
112 std::string key = s.substr(token_start, token_end - token_start);
113
114 token_start = token_end + 1;
115 // scan until matching ',' is found
116 int level = 0;
117 for( token_end = token_start; token_end < N; token_end++ ) {
118 if( s[token_end] == '[' )
119 level++;
120 else if( s[token_end] == ']' )
121 level--;
122 else if( (s[token_end] == ',') && (level == 0) )
123 break;
124 }
125 if( !(level == 0) )
126 throw "Malformed property value";
127 // we found a vlue
128 std::string value = s.substr(token_start, token_end - token_start);
129
130 // store the key,value pair
131 ps.Set(key,value);
132
133 // go on with the next one
134 token_start = token_end + 1;
135 }
136
137 return is;
138 }
139
140
141 } // end of namespace dai