Replaced ENUM2,ENUM3,ENUM4,ENUM5,ENUM6 by single DAI_ENUM macro.
authorJoris Mooij <jorism@marvin.jorismooij.nl>
Tue, 23 Sep 2008 06:04:12 +0000 (08:04 +0200)
committerJoris Mooij <jorism@marvin.jorismooij.nl>
Tue, 23 Sep 2008 06:04:12 +0000 (08:04 +0200)
ChangeLog
include/dai/bp.h
include/dai/enum.h
include/dai/hak.h
include/dai/jtree.h
include/dai/lc.h
include/dai/mr.h
include/dai/treeep.h
src/mr.cpp

index 973f7a2..3db77fc 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -3,6 +3,7 @@ libDAI-0.2.2 (2008-??-??)
 
 * Now compiles also under Visual C++.
 * Added Exceptions framework.
+* Replaced ENUM2,ENUM3,ENUM4,ENUM5,ENUM6 by single DAI_ENUM macro.
 * Added more features to utils/createfg for creating factor graphs.
 * Pervasive change of BipartiteGraph implementation (based on an idea by
   Giuseppe Passino). BipartiteGraph no longer stores the node properties 
index 04cfd7b..cfb7a15 100644 (file)
@@ -50,7 +50,7 @@ class BP : public DAIAlgFG {
             size_t maxiter;
             double tol;
             bool logdomain;
-            ENUM4(UpdateType,SEQFIX,SEQRND,SEQMAX,PARALL)
+            DAI_ENUM(UpdateType,SEQFIX,SEQRND,SEQMAX,PARALL)
             UpdateType updates;
         } props;
         double maxdiff;
index bc1ccb8..e99bb5e 100644 (file)
 #include <dai/exceptions.h>
 
 
-namespace dai {
+/// Extends the C++ enum type by supporting io streaming and conversion to and from const char* (using anonymous variadic macros)
 
 
-// C++ enums are too limited for my purposes. This defines wrapper classes
-// that provide much more functionality than a simple enum. The only
-// disadvantage is that one wrapper class needs to be written for each
-// number of values an enum can take... a better solution is needed.
-
-
-#define ENUM2(x,a,b) class x {\
-    public:\
-        enum value {a, b};\
-\
-        x() : v(a) {}\
-\
-        x(value w) : v(w) {}\
-\
-        x(char const *w) {\
-           static char const* labels[] = {#a, #b};\
-           size_t i = 0;\
-           for( ; i < sizeof(labels) / sizeof(char const *); i++ )\
-               if( strcmp( w, labels[i] ) == 0 ) {\
-                   v = (value)i;\
-                   break;\
-               }\
-           if( i == sizeof(labels) / sizeof(char const *) )\
-               DAI_THROW(UNKNOWN_ENUM_VALUE);\
-        }\
-\
-        operator value () const { return v; }\
-\
-        operator size_t () const { return (size_t)v; }\
-\
-        operator char const* () const {\
-           static char const* labels[] = {#a, #b};\
-           return labels[v];\
-        }\
-\
-        friend std::istream& operator >> (std::istream& is, x& y) {\
-            std::string s;\
-            is >> s;\
-            y = x(s.c_str());\
-            return is;\
-        }\
-\
-        friend std::ostream& operator << (std::ostream& os, const x& y) {\
-            os << (const char *)y;\
-            return os;\
-        }\
-\
-    private:\
-        value v;\
-};
-
-
-#define ENUM3(x,a,b,c) class x {\
-    public:\
-        enum value {a, b, c};\
-\
-        x() : v(a) {}\
-\
-        x(value w) : v(w) {}\
-\
-        x(char const *w) {\
-           static char const* labels[] = {#a, #b, #c};\
-           size_t i = 0;\
-           for( ; i < sizeof(labels) / sizeof(char const *); i++ )\
-               if( strcmp( w, labels[i] ) == 0 ) {\
-                   v = (value)i;\
-                   break;\
-               }\
-           if( i == sizeof(labels) / sizeof(char const *) )\
-               DAI_THROW(UNKNOWN_ENUM_VALUE);\
-        }\
-\
-        operator value () const { return v; }\
-\
-        operator size_t () const { return (size_t)v; }\
-\
-        operator char const* () const {\
-           static char const* labels[] = {#a, #b, #c};\
-           return labels[v];\
-        }\
-\
-        friend std::istream& operator >> (std::istream& is, x& y) {\
-            std::string s;\
-            is >> s;\
-            y = x(s.c_str());\
-            return is;\
-        }\
-\
-        friend std::ostream& operator << (std::ostream& os, const x& y) {\
-            os << (const char *)y;\
-            return os;\
-        }\
-\
-    private:\
-        value v;\
-};
-
-
-#define ENUM4(x,a,b,c,d) class x {\
-    public:\
-        enum value {a, b, c, d};\
-\
-        x() : v(a) {}\
-\
-        x(value w) : v(w) {}\
-\
-        x(char const *w) {\
-           static char const* labels[] = {#a, #b, #c, #d};\
-           size_t i = 0;\
-           for( ; i < sizeof(labels) / sizeof(char const *); i++ )\
-               if( strcmp( w, labels[i] ) == 0 ) {\
-                   v = (value)i;\
-                   break;\
-               }\
-           if( i == sizeof(labels) / sizeof(char const *) )\
-               DAI_THROW(UNKNOWN_ENUM_VALUE);\
-        }\
-\
-        operator value () const { return v; }\
-\
-        operator size_t () const { return (size_t)v; }\
-\
-        operator char const* () const {\
-           static char const* labels[] = {#a, #b, #c, #d};\
-           return labels[v];\
-        }\
-\
-        friend std::istream& operator >> (std::istream& is, x& y) {\
-            std::string s;\
-            is >> s;\
-            y = x(s.c_str());\
-            return is;\
-        }\
-\
-        friend std::ostream& operator << (std::ostream& os, const x& y) {\
-            os << (const char *)y;\
-            return os;\
-        }\
-\
-    private:\
-        value v;\
-};
-
-
-#define ENUM5(x,a,b,c,d,e) class x {\
-    public:\
-        enum value {a, b, c, d, e};\
-\
-        x() : v(a) {}\
-\
-        x(value w) : v(w) {}\
-\
-        x(char const *w) {\
-           static char const* labels[] = {#a, #b, #c, #d, #e};\
-           size_t i = 0;\
-           for( ; i < sizeof(labels) / sizeof(char const *); i++ )\
-               if( strcmp( w, labels[i] ) == 0 ) {\
-                   v = (value)i;\
-                   break;\
-               }\
-           if( i == sizeof(labels) / sizeof(char const *) )\
-               DAI_THROW(UNKNOWN_ENUM_VALUE);\
-        }\
-\
-        operator value () const { return v; }\
-\
-        operator size_t () const { return (size_t)v; }\
-\
-        operator char const* () const {\
-           static char const* labels[] = {#a, #b, #c, #d, #e};\
-           return labels[v];\
-        }\
-\
-        friend std::istream& operator >> (std::istream& is, x& y) {\
-            std::string s;\
-            is >> s;\
-            y = x(s.c_str());\
-            return is;\
-        }\
-\
-        friend std::ostream& operator << (std::ostream& os, const x& y) {\
-            os << (const char *)y;\
-            return os;\
-        }\
-\
-    private:\
-        value v;\
-};
-
-
-#define ENUM6(x,a,b,c,d,e,f) class x {\
+#define DAI_ENUM(x,val0,...) class x {\
     public:\
-        enum value {a, b, c, d, e, f};\
+        enum value {val0,__VA_ARGS__};\
 \
-        x() : v(a) {}\
+        x() : v(val0) {}\
 \
         x(value w) : v(w) {}\
 \
         x(char const *w) {\
-           static char const* labels[] = {#a, #b, #c, #d, #e, #f};\
-           size_t i = 0;\
-           for( ; i < sizeof(labels) / sizeof(char const *); i++ )\
-               if( strcmp( w, labels[i] ) == 0 ) {\
-                   v = (value)i;\
-                   break;\
-               }\
-           if( i == sizeof(labels) / sizeof(char const *) )\
-               DAI_THROW(UNKNOWN_ENUM_VALUE);\
-        }\
-\
-        operator value () const { return v; }\
-\
-        operator size_t () const { return (size_t)v; }\
-\
-        operator char const* () const {\
-           static char const* labels[] = {#a, #b, #c, #d, #e, #f};\
-           return labels[v];\
+            static char const* labelstring = #val0 "," #__VA_ARGS__ ",";\
+            size_t pos_begin = 0;\
+            size_t i = 0;\
+            for( size_t pos_end = 0; labelstring[pos_end] != '\0'; pos_end++ )\
+                if( (labelstring[pos_end] == ',') ) {\
+                    if( (strlen( w ) == pos_end - pos_begin) && (strncmp( labelstring + pos_begin, w, pos_end - pos_begin ) == 0) ) {\
+                        v = (value)i;\
+                        return;\
+                    } else {\
+                        i++;\
+                        pos_begin = pos_end + 1;\
+                    }\
+                }\
+            DAI_THROW(UNKNOWN_ENUM_VALUE);\
+        }\
+\
+        operator value() const { return v; }\
+\
+        operator size_t() const { return (size_t)v; }\
+\
+        operator char const*() const {\
+            static char labelstring[] = #val0 "," #__VA_ARGS__;\
+            size_t pos_begin = 0;\
+            size_t i = 0;\
+            for( size_t pos_end = 0; ; pos_end++ )\
+                if( (labelstring[pos_end] == ',') || (labelstring[pos_end] == '\0') ) {\
+                    if( (size_t)v == i ) {\
+                        labelstring[pos_end] = '\0';\
+                        return labelstring + pos_begin;\
+                    } else {\
+                        i++;\
+                        pos_begin = pos_end + 1;\
+                    }\
+                }\
         }\
 \
         friend std::istream& operator >> (std::istream& is, x& y) {\
@@ -267,7 +93,4 @@ namespace dai {
 };
 
 
-} // end of namespace dai
-
-
 #endif
index 7ce573b..d3f2cde 100644 (file)
@@ -46,7 +46,7 @@ class HAK : public DAIAlgRG {
             size_t verbose;
             size_t maxiter;
             double tol;
-            ENUM3(ClustersType,MIN,DELTA,LOOP)
+            DAI_ENUM(ClustersType,MIN,DELTA,LOOP)
             ClustersType clusters;
             bool doubleloop;
             size_t loopdepth;
index 9fd1637..12f4fef 100644 (file)
@@ -49,7 +49,7 @@ class JTree : public DAIAlgRG {
     public:
         struct Properties {
             size_t verbose;
-            ENUM2(UpdateType,HUGIN,SHSH)
+            DAI_ENUM(UpdateType,HUGIN,SHSH)
             UpdateType updates;
         } props;
 
index f1fab99..354e52b 100644 (file)
@@ -49,9 +49,9 @@ class LC : public DAIAlgFG {
             size_t verbose;
             size_t maxiter;
             double tol;
-            ENUM6(CavityType,FULL,PAIR,PAIR2,PAIRINT,PAIRCUM,UNIFORM)
+            DAI_ENUM(CavityType,FULL,PAIR,PAIR2,PAIRINT,PAIRCUM,UNIFORM)
             CavityType cavity;
-            ENUM3(UpdateType,SEQFIX,SEQRND,NONE)
+            DAI_ENUM(UpdateType,SEQFIX,SEQRND,NONE)
             UpdateType updates;
             std::string cavainame;
             PropertySet cavaiopts;
index 41610e7..f7c9941 100644 (file)
@@ -60,8 +60,8 @@ class MR : public DAIAlgFG {
         struct Properties {
             size_t verbose;
             double tol;
-            ENUM2(UpdateType,FULL,LINEAR)
-            ENUM3(InitType,RESPPROP,CLAMPING,EXACT)
+            DAI_ENUM(UpdateType,FULL,LINEAR)
+            DAI_ENUM(InitType,RESPPROP,CLAMPING,EXACT)
             UpdateType updates;
             InitType inits;
         } props;
index f6a4813..482534f 100644 (file)
@@ -89,7 +89,7 @@ class TreeEP : public JTree {
             size_t verbose;
             size_t maxiter;
             double tol;
-            ENUM2(TypeType,ORG,ALT)
+            DAI_ENUM(TypeType,ORG,ALT)
             TypeType type;
         } props;
         double maxdiff;
index b49b9c4..c42d89e 100644 (file)
@@ -496,11 +496,11 @@ void MR::init_cor() {
     for( size_t i = 0; i < nrVars(); i++ ) {
         vector<Factor> pairq;
         if( props.inits == Properties::InitType::CLAMPING ) {
-            BP bpcav(*this, PropertySet()("updates",string("SEQMAX"))("tol", string("1e-9"))("maxiter", string("1000UL"))("verbose", string("0UL"))("logdomain", string("0")));
+            BP bpcav(*this, PropertySet()("updates", string("SEQMAX"))("tol", string("1e-9"))("maxiter", string("1000UL"))("verbose", string("0UL"))("logdomain", string("0")));
             bpcav.makeCavity( i );
             pairq = calcPairBeliefs( bpcav, delta(i), false );
         } else if( props.inits == Properties::InitType::EXACT ) {
-            JTree jtcav(*this, PropertySet()("updates",string("HUGIN"))("verbose", 0UL) );
+            JTree jtcav(*this, PropertySet()("updates", string("HUGIN"))("verbose", string("0UL")) );
             jtcav.makeCavity( i );
             pairq = calcPairBeliefs( jtcav, delta(i), false );
         }