libtenum
include/tenum/dynamic_enum.hpp
Go to the documentation of this file.
00001 
00008 #ifndef TENUM_DYNAMIC_ENUM_HPP_
00009 #define TENUM_DYNAMIC_ENUM_HPP_
00010 
00011 #include <boost/lexical_cast.hpp>
00012 #include <tenum/static_enum.hpp>
00013 
00014 #define TENUM_SERIALIZE_DYNAMIC_SIGNATURE(type_m,tuples_m) \
00015   template< > \
00016   template< > \
00017   inline ::std::string \
00018   enum_helper< TENUM_TYPE(type_m) >::serialize_impl< true, false >(TENUM_TYPE(type_m) const value_in, \
00019                                                                    ::boost::true_type const&, \
00020                                                                    ::boost::false_type const&)
00021 
00022 #define TENUM_SERIALIZE_DYNAMIC_DECLARATION(type_m,tuples_m) \
00023   TENUM_SERIALIZE_DYNAMIC_SIGNATURE(type_m,tuples_m);
00024 
00025 #define TENUM_SERIALIZE_DYNAMIC_DEFINITION(type_m,tuples_m) \
00026   TENUM_SERIALIZE_DYNAMIC_SIGNATURE(type_m,tuples_m) { \
00027     TENUM_TYPE(type_m) base_value = get_base_of(value_in); \
00028     \
00029     ::std::ostringstream stream; \
00030     stream << serialize_impl< false, false >(base_value, ::boost::false_type(), ::boost::false_type()); \
00031     \
00032     ::boost::uint64_t offset = (TENUM_CAST_UINT(value_in) - TENUM_CAST_UINT(base_value)); \
00033     if (base_value != TENUM_VALUE_UNKNOWN(type_m) && offset > 0) { \
00034       stream << TENUM_DEFAULT_SEPARATOR_DYNAMIC_ENUM << offset; \
00035     } \
00036     \
00037     return stream.str(); \
00038   }
00039 
00040 #define TENUM_DESERIALIZE_DYNAMIC_SIGNATURE(type_m,tuples_m) \
00041   template< > \
00042   template< > \
00043   inline TENUM_TYPE(type_m) \
00044   enum_helper< TENUM_TYPE(type_m) >::deserialize_impl< true, false >(::std::string const& value_in, \
00045                                                                      ::boost::true_type const&, \
00046                                                                      ::boost::false_type const&)
00047 
00048 #define TENUM_DESERIALIZE_DYNAMIC_DECLARATION(type_m,tuples_m) \
00049   TENUM_DESERIALIZE_DYNAMIC_SIGNATURE(type_m,tuples_m);
00050 
00051 #define TENUM_DESERIALIZE_DYNAMIC_DEFINITION(type_m,tuples_m) \
00052   TENUM_DESERIALIZE_DYNAMIC_SIGNATURE(type_m,tuples_m) { \
00053     ::std::size_t separator_pos = value_in.find(TENUM_DEFAULT_SEPARATOR_DYNAMIC_ENUM); \
00054     TENUM_TYPE(type_m) base_value = deserialize_impl< false, false >(value_in.substr(0, separator_pos), \
00055                                                                      ::boost::false_type(), \
00056                                                                      ::boost::false_type()); \
00057     \
00058     ::boost::uint64_t offset = 0; \
00059     if (separator_pos != ::std::string::npos) { \
00060       offset = ::boost::lexical_cast< ::boost::uint64_t >(value_in.substr(separator_pos + 1)); \
00061     } \
00062     \
00063     TENUM_TYPE(type_m) right_base_value = get_base_of(TENUM_CAST_ENUM(type_m,base_value + offset)); \
00064     if(right_base_value == TENUM_VALUE_UNKNOWN(type_m)) { \
00065       offset = 0; \
00066     } else { \
00067       offset -= TENUM_CAST_UINT(right_base_value) - TENUM_CAST_UINT(base_value); \
00068     } \
00069     \
00070     return TENUM_CAST_ENUM(type_m,right_base_value + offset); \
00071   }
00072 
00073 #define TENUM_DYNAMIC_ENUM_SERIALIZATION_DECLARATION(type_m,tuples_m) \
00074   namespace tenum { \
00075     template< > struct is_dynamic< TENUM_TYPE(type_m) > : ::boost::true_type {}; \
00076     TENUM_GET_BASE_OF_DECLARATION(type_m,tuples_m) \
00077     TENUM_SERIALIZE_DECLARATION(type_m,tuples_m) \
00078     TENUM_DESERIALIZE_DECLARATION(type_m,tuples_m) \
00079     TENUM_SERIALIZE_DYNAMIC_DECLARATION(type_m,tuples_m) \
00080     TENUM_DESERIALIZE_DYNAMIC_DECLARATION(type_m,tuples_m) \
00081   } \
00082   TENUM_STREAM_OPERATORS_DECLARATION(type_m)
00083 
00084 #define TENUM_DYNAMIC_ENUM_SERIALIZATION_DEFINITION(type_m,tuples_m) \
00085   namespace tenum { \
00086     TENUM_GET_BASE_OF_DEFINITION(type_m,tuples_m) \
00087     TENUM_SERIALIZE_DEFINITION(type_m,tuples_m) \
00088     TENUM_DESERIALIZE_DEFINITION(type_m,tuples_m) \
00089     TENUM_SERIALIZE_DYNAMIC_DEFINITION(type_m,tuples_m) \
00090     TENUM_DESERIALIZE_DYNAMIC_DEFINITION(type_m,tuples_m) \
00091   } \
00092   TENUM_STREAM_OPERATORS_DEFINITION(type_m)
00093 
00094 #define TENUM_DYNAMIC_ENUM_DECLARATION(type_m,tuples_m,unknown_tuple_m,underlying_m) \
00095   TENUM_ENUM_DEFINITION(type_m,BOOST_PP_SEQ_PUSH_BACK(tuples_m,unknown_tuple_m),underlying_m) \
00096   TENUM_ENUM_OPERATORS_DECLARATION(type_m) \
00097   TENUM_DYNAMIC_ENUM_OPERATORS_DECLARATION(type_m) \
00098   TENUM_DYNAMIC_ENUM_SERIALIZATION_DECLARATION(type_m,tuples_m)
00099 
00100 #define TENUM_DYNAMIC_ENUM_DEFINITION(type_m,tuples_m) \
00101   TENUM_ENUM_OPERATORS_DEFINITION(type_m) \
00102   TENUM_DYNAMIC_ENUM_OPERATORS_DEFINITION(type_m) \
00103   TENUM_DYNAMIC_ENUM_SERIALIZATION_DEFINITION(type_m,tuples_m)
00104 
00105 #define TENUM_DYNAMIC_ENUM_I(type_m,tuples_m,unknown_tuple_m,underlying_m) \
00106   TENUM_DYNAMIC_ENUM_DECLARATION(type_m,tuples_m,unknown_tuple_m,underlying_m) \
00107   TENUM_DYNAMIC_ENUM_DEFINITION(type_m,tuples_m)
00108 
00109 #define TENUM_DYNAMIC_ENUM(type_m,tuples_m,unknown_value_m,underlying_m) \
00110   TENUM_DYNAMIC_ENUM_I(type_m,tuples_m,TENUM_TUPLE_VALUED(lte_unknown,unknown_value_m),:underlying_m)
00111 #define TENUM_SIMPLE_DYNAMIC_ENUM(type_m,values_m) \
00112   TENUM_DYNAMIC_ENUM_I(type_m,TENUM_ENUM_VALUES_COMPLETE(values_m),TENUM_TUPLE(lte_unknown),BOOST_PP_EMPTY())
00113 
00114 #endif /* TENUM_DYNAMIC_ENUM_HPP_ */
 All Classes Namespaces Files Functions Defines