00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00026 #ifndef IH_SENF_Packets_VariantParser_
00027 #define IH_SENF_Packets_VariantParser_ 1
00028
00029
00030 #include "PacketParser.hh"
00031 #include <boost/preprocessor/cat.hpp>
00032 #include <boost/preprocessor/seq/enum.hpp>
00033 #include <boost/preprocessor/seq/fold_left.hpp>
00034 #include <boost/preprocessor/seq/for_each.hpp>
00035 #include <boost/preprocessor/logical/or.hpp>
00036 #include <boost/preprocessor/seq/for_each_i.hpp>
00037 #include <boost/preprocessor/logical/not.hpp>
00038 #include <boost/preprocessor/expr_if.hpp>
00039
00040
00041
00042 namespace senf {
00043 namespace detail {
00044
00045 #ifndef DOXYGEN
00046
00047 template <class Variant, unsigned N>
00048 struct VariantBytes {
00049 static PacketParserBase::size_type bytes(Variant const & v, unsigned n);
00050 };
00051
00052 template <class Variant>
00053 struct VariantBytes<Variant,0> {
00054 static PacketParserBase::size_type bytes(Variant const & v, unsigned n);
00055 };
00056
00057 template <class Transform, class AuxPolicy, class AuxTag>
00058 struct VariantParserPolicy;
00059
00060 template <class AuxPolicy, class AuxTag>
00061 struct VariantParserPolicy<void, AuxPolicy, AuxTag>
00062 {};
00063
00064 template <class Transform, class AuxPolicy, class AuxTag>
00065 struct VariantParserPolicy
00066 : public VariantParserPolicy< void,
00067 TransformAuxParserPolicy<AuxPolicy, Transform>, AuxTag >
00068 {};
00069
00070 template <class AuxPolicy>
00071 struct VariantParserPolicy<void, AuxPolicy, senf::detail::auxtag::none>
00072 {
00073 typedef AuxPolicy type;
00074 };
00075
00076 template <class AuxPolicy, class Transform>
00077 struct VariantParserPolicy<void,
00078 AuxPolicy,
00079 senf::detail::auxtag::transform<Transform,
00080 senf::detail::auxtag::none> >
00081 {
00082 typedef TransformAuxParserPolicy<AuxPolicy, Transform> type;
00083 };
00084
00085 template <class Parsers, class Transform>
00086 struct VariantParserTraits
00087 {
00088 template <class AuxPolicy, class AuxTag>
00089 struct parser {
00090 typedef senf::VariantParser<
00091 typename VariantParserPolicy<Transform, AuxPolicy, AuxTag>::type,
00092 Parsers> type;
00093 };
00094 };
00095
00096 template <class T, T (*KeyFn)()>
00097 struct VariantKey
00098 {
00099 static T key() { return (*KeyFn)(); }
00100 };
00101
00102 template <class T, class Keys>
00103 struct VariantKeyTransform
00104 {
00105 typedef unsigned value_type;
00106 typedef T input_type;
00107 static unsigned get(input_type v);
00108 static input_type set(unsigned v);
00109 };
00110
00111 template <class In, class Out, class Keys, unsigned N>
00112 struct VariantKeyTransformCheck
00113 {
00114 static Out get(In v);
00115 static In set(Out v);
00116 };
00117
00118 template <class In, class Out, class Keys>
00119 struct VariantKeyTransformCheck<In, Out, Keys, 0>
00120 {
00121 static Out get(In v);
00122 static In set(Out v);
00123 };
00124
00125 # define SENF_PARSER_VARIANT_I(access, name, chooser, types) \
00126 SENF_PARSER_REQUIRE_VAR(variant) \
00127 protected: \
00128 typedef boost::mpl::vector< BOOST_PP_SEQ_ENUM(SENF_PARSER_VARIANT_TYPES(types)) > \
00129 BOOST_PP_CAT(name, _parsers); \
00130 private: \
00131 typedef BOOST_PP_CAT(SENF_PARSER_COLLECTION_GETAUX(chooser), _t)::value_type \
00132 BOOST_PP_CAT(name,_chooser_value_type); \
00133 BOOST_PP_IF( SENF_PARSER_VARIANT_NEEDTRANSFORM(types), \
00134 SENF_PARSER_VARIANT_MAKETRANSFORM, \
00135 SENF_PARSER_VARIANT_NOTRANSFORM )(name, \
00136 types) \
00137 typedef senf::detail::VariantParserTraits< BOOST_PP_CAT(name, _parsers), \
00138 BOOST_PP_CAT(name, _transform) > \
00139 BOOST_PP_CAT(name, _traits); \
00140 public: \
00141 SENF_PARSER_COLLECTION_I( \
00142 BOOST_PP_IIF( SENF_PARSER_VARIANT_NEEDACCESSORS(types), protected, access), \
00143 name, chooser, BOOST_PP_CAT(name, _traits) ); \
00144 access: \
00145 BOOST_PP_SEQ_FOR_EACH_I(SENF_PARSER_VARIANT_ACCESSOR, name, types) \
00146 public:
00147
00148 # define SENF_PARSER_VARIANT_MAKETRANSFORM(name, types) \
00149 BOOST_PP_SEQ_FOR_EACH_I(SENF_PARSER_VARIANT_KEYVALUE, name, types) \
00150 template <BOOST_PP_CAT(name, _chooser_value_type) (*KeyFn)()> \
00151 struct BOOST_PP_CAT(name, _key_value_template) \
00152 : public senf::detail::VariantKey<BOOST_PP_CAT(name, _chooser_value_type), KeyFn> {}; \
00153 template <class T, T (*K)()> friend class senf::detail::VariantKey; \
00154 typedef senf::detail::VariantKeyTransform< \
00155 BOOST_PP_CAT(name,_chooser_value_type), \
00156 boost::mpl::vector< \
00157 BOOST_PP_SEQ_ENUM(SENF_PARSER_VARIANT_KEYVALUES(name, types)) \
00158 > > BOOST_PP_CAT(name, _transform);
00159
00160 # define SENF_PARSER_VARIANT_KEYVALUE(r, name, i, elem) \
00161 static BOOST_PP_CAT(name, _chooser_value_type) \
00162 BOOST_PP_CAT(BOOST_PP_CAT(name, _key_),i)() \
00163 { return SENF_PARSER_VARIANT_GETKEY(elem, i); }
00164
00165 # define SENF_PARSER_VARIANT_NOTRANSFORM(name, types) \
00166 typedef void BOOST_PP_CAT(name, _transform);
00167
00168 # define SENF_PARSER_VARIANT_KEYVALUES(name, types) \
00169 BOOST_PP_SEQ_FOR_EACH_I(SENF_PARSER_VARIANT_KEYVALUES_, name, types)
00170
00171 # define SENF_PARSER_VARIANT_KEYVALUES_(r, name, i, elem) \
00172 (BOOST_PP_CAT(name,_key_value_template)< \
00173 & BOOST_PP_CAT(BOOST_PP_CAT(name, _key_), i) >)
00174
00175 # define SENF_PARSER_VARIANT_ACCESSOR(r, name, i, elem) \
00176 BOOST_PP_IF( SENF_PARSER_VARIANT_HASID(elem), \
00177 SENF_PARSER_VARIANT_MAKEACCESSOR, \
00178 SENF_PARSER_VARIANT_NOACCESSOR )(name, i, elem)
00179
00180 # define SENF_PARSER_VARIANT_NOACCESSOR(name, i, elem)
00181 # define SENF_PARSER_VARIANT_MAKEACCESSOR(name, i, elem) \
00182 SENF_PARSER_VARIANT_MAKEACCESSOR_VALUE(name, i, elem, SENF_PARSER_VARIANT_GETID(elem)) \
00183 SENF_PARSER_VARIANT_MAKEACCESSOR_HAS(name, i, elem, SENF_PARSER_VARIANT_GETHASID(elem)) \
00184 SENF_PARSER_VARIANT_MAKEACCESSOR_INIT(name, i, elem, SENF_PARSER_VARIANT_GETINITID(elem))
00185
00186 # define SENF_PARSER_VARIANT_IFNOTNA(id, x) \
00187 BOOST_PP_EXPR_IIF( BOOST_PP_NOT( SENF_PARSER_VARIANT_NA(id) ), x )
00188
00189 # define SENF_PARSER_VARIANT_MAKEACCESSOR_VALUE(name, i, elem, id) \
00190 SENF_PARSER_VARIANT_IFNOTNA( id, \
00191 typedef SENF_PARSER_VARIANT_GETTYPE(elem) \
00192 BOOST_PP_CAT(id, _t); \
00193 BOOST_PP_CAT(id, _t) id() const \
00194 { return name().get<i>(); } \
00195 )
00196
00197 # define SENF_PARSER_VARIANT_MAKEACCESSOR_HAS(name, i, elem, id) \
00198 SENF_PARSER_VARIANT_IFNOTNA( id, \
00199 bool id() const \
00200 { return name().variant() == i; } \
00201 )
00202
00203 # define SENF_PARSER_VARIANT_MAKEACCESSOR_INIT(name, i, elem, id) \
00204 SENF_PARSER_VARIANT_IFNOTNA( id, \
00205 void id() const \
00206 { name().init<i>(); } \
00207 )
00208
00209 # define SENF_PARSER_VARIANT_KEY_GOBBLE__key(key, type)
00210 # define SENF_PARSER_VARIANT_KEY_GETKEY__key(key, type) key
00211 # define SENF_PARSER_VARIANT_KEY_GETTYPE__key(key, type) type
00212
00213 # define SENF_PARSER_VARIANT_ID_GOBBLE__id(id, value)
00214 # define SENF_PARSER_VARIANT_ID_GETID__id(id, value) id
00215 # define SENF_PARSER_VARIANT_ID_GETVALUE__id(id, value) value
00216 # define SENF_PARSER_VARIANT_ID_GETHASID__id(id, value) SENF_CAT_RECURS3(has_, id)
00217 # define SENF_PARSER_VARIANT_ID_GETINITID__id(id, value) SENF_CAT_RECURS3(init_, id)
00218
00219 # define SENF_PARSER_VARIANT_ID_GOBBLE__novalue(id, value)
00220 # define SENF_PARSER_VARIANT_ID_GETID__novalue(id, value) na
00221 # define SENF_PARSER_VARIANT_ID_GETVALUE__novalue(id, value) value
00222 # define SENF_PARSER_VARIANT_ID_GETHASID__novalue(id, value) na
00223 # define SENF_PARSER_VARIANT_ID_GETINITID__novalue(id, value) id
00224
00225 # define SENF_PARSER_VARIANT_ID_GOBBLE__ids(id, hasid, initid, value)
00226 # define SENF_PARSER_VARIANT_ID_GETID__ids(id, hasid, initid, value) id
00227 # define SENF_PARSER_VARIANT_ID_GETVALUE__ids(id, hasid, initid, value) value
00228 # define SENF_PARSER_VARIANT_ID_GETHASID__ids(id, hasid, initid, value) hasid
00229 # define SENF_PARSER_VARIANT_ID_GETINITID__ids(id, hasid, initid, value) initid
00230
00231 # define SENF_PARSER_VARIANT_NA_GOBBLE__na
00232
00233 # define SENF_PARSER_VARIANT_NA(x) \
00234 BOOST_PP_IS_EMPTY( SENF_CAT_RECURS1(SENF_PARSER_VARIANT_NA_GOBBLE__, x) )
00235
00236 # define SENF_PARSER_VARIANT_HASKEY(x) \
00237 SENF_PARSER_VARIANT_HASKEY_( SENF_PARSER_VARIANT_GETVALUE(x) )
00238
00239 # define SENF_PARSER_VARIANT_HASKEY_(x) \
00240 BOOST_PP_IS_EMPTY( SENF_CAT_RECURS1(SENF_PARSER_VARIANT_KEY_GOBBLE__, x) )
00241
00242 # define SENF_PARSER_VARIANT_GETKEY(x, default) \
00243 SENF_PARSER_VARIANT_GETKEY_( SENF_PARSER_VARIANT_GETVALUE(x), default )
00244
00245 # define SENF_PARSER_VARIANT_GETKEY_(x, default) \
00246 BOOST_PP_IF( SENF_PARSER_VARIANT_HASKEY_(x), \
00247 BOOST_PP_CAT(SENF_PARSER_VARIANT_KEY_GETKEY__, x), \
00248 default )
00249
00250 # define SENF_PARSER_VARIANT_HASID(x) \
00251 BOOST_PP_IS_EMPTY( SENF_CAT_RECURS2(SENF_PARSER_VARIANT_ID_GOBBLE__, x) )
00252
00253 # define SENF_PARSER_VARIANT_GETID(x) \
00254 BOOST_PP_CAT(SENF_PARSER_VARIANT_ID_GETID__, x)
00255
00256 # define SENF_PARSER_VARIANT_GETHASID(x) \
00257 BOOST_PP_CAT(SENF_PARSER_VARIANT_ID_GETHASID__, x)
00258
00259 # define SENF_PARSER_VARIANT_GETINITID(x) \
00260 BOOST_PP_CAT(SENF_PARSER_VARIANT_ID_GETINITID__, x)
00261
00262 # define SENF_PARSER_VARIANT_GETVALUE(x) \
00263 BOOST_PP_IF( SENF_PARSER_VARIANT_HASID(x), \
00264 BOOST_PP_CAT(SENF_PARSER_VARIANT_ID_GETVALUE__, x), \
00265 x )
00266
00267 # define SENF_PARSER_VARIANT_GETTYPE(x) \
00268 SENF_PARSER_VARIANT_GETTYPE_( SENF_PARSER_VARIANT_GETVALUE(x) )
00269
00270 # define SENF_PARSER_VARIANT_GETTYPE_(x) \
00271 BOOST_PP_IF( SENF_PARSER_VARIANT_HASKEY_(x), \
00272 BOOST_PP_CAT(SENF_PARSER_VARIANT_KEY_GETTYPE__, x), \
00273 x )
00274
00275 # define SENF_PARSER_VARIANT_NEEDTRANSFORM(types) \
00276 BOOST_PP_SEQ_FOLD_LEFT(SENF_PARSER_VARIANT_NEEDTRANSFORM_, 0, types)
00277
00278 # define SENF_PARSER_VARIANT_NEEDTRANSFORM_(s, state, elem) \
00279 BOOST_PP_OR(state, SENF_PARSER_VARIANT_HASKEY(elem))
00280
00281 # define SENF_PARSER_VARIANT_NEEDACCESSORS(types) \
00282 BOOST_PP_SEQ_FOLD_LEFT(SENF_PARSER_VARIANT_NEEDACCESSORS_, 0, types)
00283
00284 # define SENF_PARSER_VARIANT_NEEDACCESSORS_(s, state, elem) \
00285 BOOST_PP_OR(state, SENF_PARSER_VARIANT_HASID(elem))
00286
00287 # define SENF_PARSER_VARIANT_TYPES(types) \
00288 BOOST_PP_SEQ_FOR_EACH(SENF_PARSER_VARIANT_TYPES_, _, types)
00289
00290 # define SENF_PARSER_VARIANT_TYPES_(r, _, elem) \
00291 (SENF_PARSER_VARIANT_GETTYPE(elem))
00292
00293 #endif
00294
00295 }}
00296
00297
00298 #endif
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309