Merge branch 'master' of git@git.tuebingen.mpg.de:libdai
[libdai.git] / include / dai / enum.h
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 #ifndef __defined_libdai_enum_h
23 #define __defined_libdai_enum_h
24
25
26 #include <cstring>
27 #include <iostream>
28 #include <dai/exceptions.h>
29
30
31 namespace dai {
32
33
34 // C++ enums are too limited for my purposes. This defines wrapper classes
35 // that provide much more functionality than a simple enum. The only
36 // disadvantage is that one wrapper class needs to be written for each
37 // number of values an enum can take... a better solution is needed.
38
39
40 #define ENUM2(x,a,b) class x {\
41 public:\
42 enum value {a, b};\
43 \
44 x() : v(a) {}\
45 \
46 x(value w) : v(w) {}\
47 \
48 x(char const *w) {\
49 static char const* labels[] = {#a, #b};\
50 size_t i = 0;\
51 for( ; i < sizeof(labels) / sizeof(char const *); i++ )\
52 if( strcmp( w, labels[i] ) == 0 ) {\
53 v = (value)i;\
54 break;\
55 }\
56 if( i == sizeof(labels) / sizeof(char const *) )\
57 DAI_THROW(UNKNOWN_ENUM_VALUE);\
58 }\
59 \
60 operator value () const { return v; }\
61 \
62 operator size_t () const { return (size_t)v; }\
63 \
64 operator char const* () const {\
65 static char const* labels[] = {#a, #b};\
66 return labels[v];\
67 }\
68 \
69 friend std::istream& operator >> (std::istream& is, x& y) {\
70 std::string s;\
71 is >> s;\
72 y = x(s.c_str());\
73 return is;\
74 }\
75 \
76 friend std::ostream& operator << (std::ostream& os, const x& y) {\
77 os << (const char *)y;\
78 return os;\
79 }\
80 \
81 private:\
82 value v;\
83 };
84
85
86 #define ENUM3(x,a,b,c) class x {\
87 public:\
88 enum value {a, b, c};\
89 \
90 x() : v(a) {}\
91 \
92 x(value w) : v(w) {}\
93 \
94 x(char const *w) {\
95 static char const* labels[] = {#a, #b, #c};\
96 size_t i = 0;\
97 for( ; i < sizeof(labels) / sizeof(char const *); i++ )\
98 if( strcmp( w, labels[i] ) == 0 ) {\
99 v = (value)i;\
100 break;\
101 }\
102 if( i == sizeof(labels) / sizeof(char const *) )\
103 DAI_THROW(UNKNOWN_ENUM_VALUE);\
104 }\
105 \
106 operator value () const { return v; }\
107 \
108 operator size_t () const { return (size_t)v; }\
109 \
110 operator char const* () const {\
111 static char const* labels[] = {#a, #b, #c};\
112 return labels[v];\
113 }\
114 \
115 friend std::istream& operator >> (std::istream& is, x& y) {\
116 std::string s;\
117 is >> s;\
118 y = x(s.c_str());\
119 return is;\
120 }\
121 \
122 friend std::ostream& operator << (std::ostream& os, const x& y) {\
123 os << (const char *)y;\
124 return os;\
125 }\
126 \
127 private:\
128 value v;\
129 };
130
131
132 #define ENUM4(x,a,b,c,d) class x {\
133 public:\
134 enum value {a, b, c, d};\
135 \
136 x() : v(a) {}\
137 \
138 x(value w) : v(w) {}\
139 \
140 x(char const *w) {\
141 static char const* labels[] = {#a, #b, #c, #d};\
142 size_t i = 0;\
143 for( ; i < sizeof(labels) / sizeof(char const *); i++ )\
144 if( strcmp( w, labels[i] ) == 0 ) {\
145 v = (value)i;\
146 break;\
147 }\
148 if( i == sizeof(labels) / sizeof(char const *) )\
149 DAI_THROW(UNKNOWN_ENUM_VALUE);\
150 }\
151 \
152 operator value () const { return v; }\
153 \
154 operator size_t () const { return (size_t)v; }\
155 \
156 operator char const* () const {\
157 static char const* labels[] = {#a, #b, #c, #d};\
158 return labels[v];\
159 }\
160 \
161 friend std::istream& operator >> (std::istream& is, x& y) {\
162 std::string s;\
163 is >> s;\
164 y = x(s.c_str());\
165 return is;\
166 }\
167 \
168 friend std::ostream& operator << (std::ostream& os, const x& y) {\
169 os << (const char *)y;\
170 return os;\
171 }\
172 \
173 private:\
174 value v;\
175 };
176
177
178 #define ENUM5(x,a,b,c,d,e) class x {\
179 public:\
180 enum value {a, b, c, d, e};\
181 \
182 x() : v(a) {}\
183 \
184 x(value w) : v(w) {}\
185 \
186 x(char const *w) {\
187 static char const* labels[] = {#a, #b, #c, #d, #e};\
188 size_t i = 0;\
189 for( ; i < sizeof(labels) / sizeof(char const *); i++ )\
190 if( strcmp( w, labels[i] ) == 0 ) {\
191 v = (value)i;\
192 break;\
193 }\
194 if( i == sizeof(labels) / sizeof(char const *) )\
195 DAI_THROW(UNKNOWN_ENUM_VALUE);\
196 }\
197 \
198 operator value () const { return v; }\
199 \
200 operator size_t () const { return (size_t)v; }\
201 \
202 operator char const* () const {\
203 static char const* labels[] = {#a, #b, #c, #d, #e};\
204 return labels[v];\
205 }\
206 \
207 friend std::istream& operator >> (std::istream& is, x& y) {\
208 std::string s;\
209 is >> s;\
210 y = x(s.c_str());\
211 return is;\
212 }\
213 \
214 friend std::ostream& operator << (std::ostream& os, const x& y) {\
215 os << (const char *)y;\
216 return os;\
217 }\
218 \
219 private:\
220 value v;\
221 };
222
223
224 #define ENUM6(x,a,b,c,d,e,f) class x {\
225 public:\
226 enum value {a, b, c, d, e, f};\
227 \
228 x() : v(a) {}\
229 \
230 x(value w) : v(w) {}\
231 \
232 x(char const *w) {\
233 static char const* labels[] = {#a, #b, #c, #d, #e, #f};\
234 size_t i = 0;\
235 for( ; i < sizeof(labels) / sizeof(char const *); i++ )\
236 if( strcmp( w, labels[i] ) == 0 ) {\
237 v = (value)i;\
238 break;\
239 }\
240 if( i == sizeof(labels) / sizeof(char const *) )\
241 DAI_THROW(UNKNOWN_ENUM_VALUE);\
242 }\
243 \
244 operator value () const { return v; }\
245 \
246 operator size_t () const { return (size_t)v; }\
247 \
248 operator char const* () const {\
249 static char const* labels[] = {#a, #b, #c, #d, #e, #f};\
250 return labels[v];\
251 }\
252 \
253 friend std::istream& operator >> (std::istream& is, x& y) {\
254 std::string s;\
255 is >> s;\
256 y = x(s.c_str());\
257 return is;\
258 }\
259 \
260 friend std::ostream& operator << (std::ostream& os, const x& y) {\
261 os << (const char *)y;\
262 return os;\
263 }\
264 \
265 private:\
266 value v;\
267 };
268
269
270 } // end of namespace dai
271
272
273 #endif