#ifndef RICH_ENUM_H #define RICH_ENUM_H #include #include #include #include #define RICH_ENUM_STRINGIZE(s, data, elem) BOOST_PP_STRINGIZE(elem) #define RICH_ENUM_ADD_UNDERSCORE(s, data, elem) BOOST_PP_CAT(elem, _) #define DECLARE_RICH_ENUM(type, seq) \ template class BOOST_PP_CAT(type, T) \ { \ private: \ enum MyEnum {BOOST_PP_SEQ_ENUM(BOOST_PP_SEQ_PUSH_BACK(BOOST_PP_SEQ_TRANSFORM(RICH_ENUM_ADD_UNDERSCORE, ~, seq), Invalid))}; \ MyEnum myValue; \ public: \ static BOOST_PP_CAT(type, T) const BOOST_PP_SEQ_ENUM(seq); \ BOOST_PP_CAT(type, T)(BOOST_PP_CAT(type, T) const & other) : myValue(other.myValue) { } \ explicit BOOST_PP_CAT(type, T)(MyEnum val) : myValue(val) { } \ explicit BOOST_PP_CAT(type, T)() : myValue(Invalid) { } \ bool operator<(BOOST_PP_CAT(type, T) const & other) const {return myValue < other.myValue;} \ bool operator==(BOOST_PP_CAT(type, T) const & other) const {return myValue == other.myValue;} \ bool operator!=(BOOST_PP_CAT(type, T) const & other) const {return myValue != other.myValue;} \ static BOOST_PP_CAT(type, T) begin() {return BOOST_PP_SEQ_HEAD(seq);} \ static BOOST_PP_CAT(type, T) end() {return BOOST_PP_CAT(type, T)(Invalid);} \ BOOST_PP_CAT(type, T) operator++() \ { \ if(myValue != Invalid) \ myValue=static_cast(myValue+1); \ return *this; \ } \ BOOST_PP_CAT(type, T) operator--() \ { \ if(myValue != BOOST_PP_CAT(BOOST_PP_SEQ_HEAD(seq), _)) \ myValue=static_cast(myValue-1); \ return *this; \ } \ BOOST_PP_CAT(type, T) operator++(int) {BOOST_PP_CAT(type, T) result = *this; operator++() ; return result;}\ BOOST_PP_CAT(type, T) operator--(int) {BOOST_PP_CAT(type, T) result = *this; operator--() ; return result;}\ \ \ template \ friend std::basic_ostream& \ operator<<(std::basic_ostream& gensym_o, BOOST_PP_CAT(type, T) gensym_c) \ { \ switch (gensym_c.myValue) \ { \ BOOST_PP_SEQ_FOR_EACH(RICH_ENUM_ITERATE_CASE, ~, seq) \ default: \ return gensym_o << "Invalid " << BOOST_PP_STRINGIZE(type); \ } \ \ } \ template void serialize(Archive & ar, const unsigned int version) \ { \ ar & myValue; \ }\ }; \ typedef BOOST_PP_CAT(type, T) type;\ BOOST_CLASS_TRACKING(type, boost::serialization::track_never) \ BOOST_PP_SEQ_FOR_EACH(RICH_ENUM_ITERATE_CONST, type, seq) \ #define RICH_ENUM_ITERATE_CASE(s, data, elem) \ case BOOST_PP_CAT(elem, _): \ return gensym_o << BOOST_PP_STRINGIZE(elem); #define RICH_ENUM_ITERATE_CONST(s, data , elem) \ data const data::elem(data::BOOST_PP_CAT(elem, _)); #endif // RICH_ENUM_H