Cleaned up BBP and improved documentation of include/dai/bbp.h
[libdai.git] / include / dai / enum.h
1 /* This file is part of libDAI - http://www.libdai.org/
2 *
3 * libDAI is licensed under the terms of the GNU General Public License version
4 * 2, or (at your option) any later version. libDAI is distributed without any
5 * warranty. See the file COPYING for more details.
6 *
7 * Copyright (C) 2006-2009 Joris Mooij [joris dot mooij at libdai dot org]
8 * Copyright (C) 2006-2007 Radboud University Nijmegen, The Netherlands
9 */
10
11
12 /// \file
13 /// \brief Defines the DAI_ENUM macro, which can be used to define an \c enum with additional functionality.
14
15
16 #ifndef __defined_libdai_enum_h
17 #define __defined_libdai_enum_h
18
19
20 #include <cstring>
21 #include <iostream>
22 #include <dai/exceptions.h>
23
24
25 /// Extends the C++ \c enum type by supporting input/output streaming and conversion to and from <tt>const char*</tt> and \c size_t
26 /** For more details see the source code.
27 *
28 * \par Example:
29 * \code
30 * DAI_ENUM(colors,RED,GREEN,BLUE)
31 * \endcode
32 * defines a class \a colors encapsulating an
33 * \code
34 * enum {RED, GREEN, BLUE};
35 * \endcode
36 * which offers additional functionality over the plain \c enum keyword.
37 */
38 #define DAI_ENUM(x,val0,...) class x {\
39 public:\
40 enum value {val0,__VA_ARGS__};\
41 \
42 x() : v(val0) {}\
43 \
44 x(value w) : v(w) {}\
45 \
46 x(char const *w) {\
47 static char const* labelstring = #val0 "," #__VA_ARGS__;\
48 size_t pos_begin = 0;\
49 size_t i = 0;\
50 for( size_t pos_end = 0; ; pos_end++ ) {\
51 if( (labelstring[pos_end] == ',') || (labelstring[pos_end] == '\0') ) {\
52 if( (strlen( w ) == pos_end - pos_begin) && (strncmp( labelstring + pos_begin, w, pos_end - pos_begin ) == 0) ) {\
53 v = (value)i;\
54 return;\
55 } else {\
56 i++;\
57 pos_begin = pos_end + 1;\
58 }\
59 }\
60 if( labelstring[pos_end] == '\0' )\
61 break;\
62 }\
63 DAI_THROWE(UNKNOWN_ENUM_VALUE,"'" + std::string(w) + "' is not in [" + std::string(labelstring) + "]");\
64 }\
65 \
66 operator value() const { return v; }\
67 \
68 operator size_t() const { return (size_t)v; }\
69 \
70 operator char const*() const {\
71 static char labelstring[] = #val0 "," #__VA_ARGS__;\
72 size_t pos_begin = 0;\
73 size_t i = 0;\
74 for( size_t pos_end = 0; ; pos_end++ )\
75 if( (labelstring[pos_end] == ',') || (labelstring[pos_end] == '\0') ) {\
76 if( (size_t)v == i ) {\
77 labelstring[pos_end] = '\0';\
78 return labelstring + pos_begin;\
79 } else {\
80 i++;\
81 pos_begin = pos_end + 1;\
82 }\
83 }\
84 }\
85 \
86 friend std::istream& operator >> (std::istream& is, x& y) {\
87 std::string s;\
88 is >> s;\
89 y = x(s.c_str());\
90 return is;\
91 }\
92 \
93 friend std::ostream& operator << (std::ostream& os, const x& y) {\
94 os << (const char *)y;\
95 return os;\
96 }\
97 \
98 protected:\
99 value v;\
100 };
101
102
103 #endif