Cleanup of BBP code
[libdai.git] / include / dai / enum.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 /// \file
24 /// \brief Defines the DAI_ENUM macro
25
26
27 #ifndef __defined_libdai_enum_h
28 #define __defined_libdai_enum_h
29
30
31 #include <cstring>
32 #include <iostream>
33 #include <dai/exceptions.h>
34
35
36 /// Extends the C++ enum type by supporting input/output streaming and conversion to and from const char* and size_t
37 /** For more details see the source code.
38 *
39 * \par Example:
40 * \code
41 * DAI_ENUM(colors,RED,GREEN,BLUE)
42 * \endcode
43 * defines a class \a colors encapsulating an
44 * \code
45 * enum {RED, GREEN, BLUE};
46 * \endcode
47 * which offers additional functionality over the plain \c enum keyword.
48 */
49 #define DAI_ENUM(x,val0,...) class x {\
50 public:\
51 enum value {val0,__VA_ARGS__};\
52 \
53 x() : v(val0) {}\
54 \
55 x(value w) : v(w) {}\
56 \
57 x(char const *w) {\
58 static char const* labelstring = #val0 "," #__VA_ARGS__ ",";\
59 size_t pos_begin = 0;\
60 size_t i = 0;\
61 for( size_t pos_end = 0; labelstring[pos_end] != '\0'; pos_end++ )\
62 if( (labelstring[pos_end] == ',') ) {\
63 if( (strlen( w ) == pos_end - pos_begin) && (strncmp( labelstring + pos_begin, w, pos_end - pos_begin ) == 0) ) {\
64 v = (value)i;\
65 return;\
66 } else {\
67 i++;\
68 pos_begin = pos_end + 1;\
69 }\
70 }\
71 DAI_THROW(UNKNOWN_ENUM_VALUE);\
72 }\
73 \
74 operator value() const { return v; }\
75 \
76 operator size_t() const { return (size_t)v; }\
77 \
78 operator char const*() const {\
79 static char labelstring[] = #val0 "," #__VA_ARGS__;\
80 size_t pos_begin = 0;\
81 size_t i = 0;\
82 for( size_t pos_end = 0; ; pos_end++ )\
83 if( (labelstring[pos_end] == ',') || (labelstring[pos_end] == '\0') ) {\
84 if( (size_t)v == i ) {\
85 labelstring[pos_end] = '\0';\
86 return labelstring + pos_begin;\
87 } else {\
88 i++;\
89 pos_begin = pos_end + 1;\
90 }\
91 }\
92 }\
93 \
94 friend std::istream& operator >> (std::istream& is, x& y) {\
95 std::string s;\
96 is >> s;\
97 y = x(s.c_str());\
98 return is;\
99 }\
100 \
101 friend std::ostream& operator << (std::ostream& os, const x& y) {\
102 os << (const char *)y;\
103 return os;\
104 }\
105 \
106 private:\
107 value v;\
108 };
109
110
111 #endif