From 200de272ed5f024628456bdf8c7186ff21bc22bc Mon Sep 17 00:00:00 2001 From: Antonin Portelli Date: Tue, 8 Dec 2015 13:54:00 +0000 Subject: [PATCH] IO: serialisable enums --- lib/serialisation/BaseIO.h | 40 +++++++++++++++++++++++---- lib/serialisation/MacroMagic.h | 50 ++++++++++++++++++++++++++++++++-- tests/Test_dwf_hdcr.cc | 2 +- tests/Test_serialisation.cc | 18 ++++++++---- 4 files changed, 97 insertions(+), 13 deletions(-) diff --git a/lib/serialisation/BaseIO.h b/lib/serialisation/BaseIO.h index 200b8ee3..60e3e3af 100644 --- a/lib/serialisation/BaseIO.h +++ b/lib/serialisation/BaseIO.h @@ -22,7 +22,12 @@ namespace Grid { typename std::enable_if::value, void>::type write(const std::string& s, const U &output); template - typename std::enable_if::value, void>::type + typename std::enable_if::value, void>::type + write(const std::string& s, const U &output); + template + typename std::enable_if< + !(std::is_base_of::value or std::is_enum::value), + void>::type write(const std::string& s, const U &output); private: T *upcast; @@ -41,7 +46,12 @@ namespace Grid { typename std::enable_if::value, void>::type read(const std::string& s, U &output); template - typename std::enable_if::value, void>::type + typename std::enable_if::value, void>::type + read(const std::string& s, U &output); + template + typename std::enable_if< + !(std::is_base_of::value or std::is_enum::value), + void>::type read(const std::string& s, U &output); protected: template @@ -146,7 +156,17 @@ namespace Grid { template template - typename std::enable_if::value, void>::type + typename std::enable_if::value, void>::type + Writer::write(const std::string &s, const U &output) + { + EnumIO::write(*this, s, output); + } + + template + template + typename std::enable_if< + !(std::is_base_of::value or std::is_enum::value), + void>::type Writer::write(const std::string &s, const U &output) { upcast->writeDefault(s, output); @@ -181,7 +201,17 @@ namespace Grid { template template - typename std::enable_if::value, void>::type + typename std::enable_if::value, void>::type + Reader::read(const std::string &s, U &output) + { + EnumIO::read(*this, s, output); + } + + template + template + typename std::enable_if< + !(std::is_base_of::value or std::is_enum::value), + void>::type Reader::read(const std::string &s, U &output) { upcast->readDefault(s, output); @@ -205,7 +235,7 @@ namespace Grid { abort(); } } - + } #endif diff --git a/lib/serialisation/MacroMagic.h b/lib/serialisation/MacroMagic.h index ee497ce4..34fd893f 100644 --- a/lib/serialisation/MacroMagic.h +++ b/lib/serialisation/MacroMagic.h @@ -109,12 +109,11 @@ THE SOFTWARE. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// #define GRID_MACRO_MEMBER(A,B) A B; - #define GRID_MACRO_OS_WRITE_MEMBER(A,B) os<< #A <<" "#B <<" = "<< obj. B <<" ; " <::type +#define GRID_MACRO_ENUMVAL(A,B) A = B, +#define GRID_MACRO_ENUMCASE(A,B) case GRID_ENUM_TYPE(obj)::A: Grid::write(WR,s,#A); break; +#define GRID_MACRO_ENUMTEST(A,B) else if (buf == #A) {obj = GRID_ENUM_TYPE(obj)::A;} +#define GRID_MACRO_ENUMCASEIO(A,B) case GRID_ENUM_TYPE(obj)::A: os << #A; break; + +namespace Grid { + template + class EnumIO {}; +} + +#define GRID_SERIALIZABLE_ENUM(name,undefname,...)\ + enum class name {\ + GRID_MACRO_EVAL(GRID_MACRO_MAP(GRID_MACRO_ENUMVAL,__VA_ARGS__))\ + undefname = -1\ + };\ + \ + template<>\ + class EnumIO {\ + public:\ + template \ + static void write(Writer &WR,const std::string &s, const name &obj){ \ + switch (obj) {\ + GRID_MACRO_EVAL(GRID_MACRO_MAP(GRID_MACRO_ENUMCASE,__VA_ARGS__))\ + default: Grid::write(WR,s,#undefname); break;\ + }\ + }\ + \ + template \ + static void read(Reader &RD,const std::string &s, name &obj){ \ + std::string buf;\ + Grid::read(RD, s, buf);\ + if (buf == #undefname) {obj = name::undefname;}\ + GRID_MACRO_EVAL(GRID_MACRO_MAP(GRID_MACRO_ENUMTEST,__VA_ARGS__))\ + else {obj = name::undefname;}\ + }\ + };\ + \ + std::ostream & operator << (std::ostream &os, const name &obj ) { \ + switch (obj) {\ + GRID_MACRO_EVAL(GRID_MACRO_MAP(GRID_MACRO_ENUMCASEIO,__VA_ARGS__))\ + default: os << #undefname; break;\ + }\ + return os;\ + }; + #endif diff --git a/tests/Test_dwf_hdcr.cc b/tests/Test_dwf_hdcr.cc index 006d0e5e..469e6cc4 100644 --- a/tests/Test_dwf_hdcr.cc +++ b/tests/Test_dwf_hdcr.cc @@ -9,7 +9,7 @@ using namespace Grid::QCD; class myclass: Serializable { public: - GRID_DECL_CLASS_MEMBERS(myclass, + GRID_SERIALIZABLE_CLASS_MEMBERS(myclass, int, domaindecompose, int, domainsize, int, order, diff --git a/tests/Test_serialisation.cc b/tests/Test_serialisation.cc index cfb4b8e7..5ab85181 100644 --- a/tests/Test_serialisation.cc +++ b/tests/Test_serialisation.cc @@ -1,30 +1,39 @@ #include namespace Grid { + + GRID_SERIALIZABLE_ENUM(myenum, undef, red, 1, blue, 2, green, 3); + class myclass: Serializable { public: - GRID_DECL_CLASS_MEMBERS(myclass, + GRID_SERIALIZABLE_CLASS_MEMBERS(myclass, + myenum, e, + std::vector, ve, + std::string, name, int, x, double, y, bool , b, - std::string, name, std::vector, array, std::vector>, twodimarray, ); myclass() {} myclass(int i) - : array(4,5.1), twodimarray(3,std::vector(2,1.23456)) + : array(4,5.1), twodimarray(3,std::vector(2,1.23456)), ve(2, myenum::blue) { + e=myenum::red; x=i; y=2*i; b=true; name="bother said pooh"; } }; + } +using namespace Grid; + int16_t i16 = 1; uint16_t u16 = 2; int32_t i32 = 3; @@ -35,8 +44,6 @@ float f = M_PI; double d = 2*M_PI; bool b = false; -using namespace Grid; - int main(int argc,char **argv) { { @@ -59,6 +66,7 @@ int main(int argc,char **argv) myclass obj(1234); // non-trivial constructor write(WR,"obj",obj); WR.write("obj2", obj); + std::cout << obj << std::endl; std::vector vec; vec.push_back(myclass(1234));