libDAI
include/dai/enum.h
Go to the documentation of this file.
00001 /*  This file is part of libDAI - http://www.libdai.org/
00002  *
00003  *  Copyright (c) 2006-2011, The libDAI authors. All rights reserved.
00004  *
00005  *  Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
00006  */
00007 
00008 
00011 
00012 
00013 #ifndef __defined_libdai_enum_h
00014 #define __defined_libdai_enum_h
00015 
00016 
00017 #include <cstring>
00018 #include <iostream>
00019 #include <dai/exceptions.h>
00020 
00021 
00023 
00035 #define DAI_ENUM(x,val0,...) class x {\
00036     public:\
00037         enum value {val0,__VA_ARGS__};\
00038 \
00039         x() : v(val0) {}\
00040 \
00041         x(value w) : v(w) {}\
00042 \
00043         x(char const *w) {\
00044             static char const* labelstring = #val0 "," #__VA_ARGS__;\
00045             size_t pos_begin = 0;\
00046             size_t i = 0;\
00047             for( size_t pos_end = 0; ; pos_end++ ) {\
00048                 if( (labelstring[pos_end] == ',') || (labelstring[pos_end] == '\0') ) {\
00049                     if( (strlen( w ) == pos_end - pos_begin) && (strncmp( labelstring + pos_begin, w, pos_end - pos_begin ) == 0) ) {\
00050                         v = (value)i;\
00051                         return;\
00052                     } else {\
00053                         i++;\
00054                         pos_begin = pos_end + 1;\
00055                     }\
00056                 }\
00057                 if( labelstring[pos_end] == '\0' )\
00058                     break;\
00059             }\
00060             DAI_THROWE(UNKNOWN_ENUM_VALUE,"'" + std::string(w) + "' is not in [" + std::string(labelstring) + "]");\
00061         }\
00062 \
00063         operator value() const { return v; }\
00064 \
00065         operator size_t() const { return (size_t)v; }\
00066 \
00067         operator char const*() const {\
00068             static char labelstring[] = #val0 "," #__VA_ARGS__;\
00069             size_t pos_begin = 0;\
00070             size_t i = 0;\
00071             for( size_t pos_end = 0; ; pos_end++ )\
00072                 if( (labelstring[pos_end] == ',') || (labelstring[pos_end] == '\0') ) {\
00073                     if( (size_t)v == i ) {\
00074                         labelstring[pos_end] = '\0';\
00075                         return labelstring + pos_begin;\
00076                     } else {\
00077                         i++;\
00078                         pos_begin = pos_end + 1;\
00079                     }\
00080                 }\
00081         }\
00082 \
00083         friend std::istream& operator >> (std::istream& is, x& y) {\
00084             std::string s;\
00085             is >> s;\
00086             y = x(s.c_str());\
00087             return is;\
00088         }\
00089 \
00090         friend std::ostream& operator << (std::ostream& os, const x& y) {\
00091             os << (const char *)y;\
00092             return os;\
00093         }\
00094 \
00095     protected:\
00096         value v;\
00097 };
00098 
00099 
00100 #endif