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