X-Git-Url: http://g0dil.de/git?a=blobdiff_plain;f=Packets%2FVariantParser.ih;h=d667f860857d5448d4f51f4350002749d4852f2a;hb=b89e3166f7680755683dccee5e48cb3a820185c0;hp=5e1a4a8ce54970035d42f84403b2fc4119ebc254;hpb=a1001797645cc68c869ef296f5e9ba13aa8e80c4;p=senf.git diff --git a/Packets/VariantParser.ih b/Packets/VariantParser.ih index 5e1a4a8..d667f86 100644 --- a/Packets/VariantParser.ih +++ b/Packets/VariantParser.ih @@ -1,8 +1,8 @@ // $Id$ // -// Copyright (C) 2007 -// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS) -// Kompetenzzentrum fuer NETwork research (NET) +// Copyright (C) 2007 +// Fraunhofer Institute for Open Communication Systems (FOKUS) +// Competence Center NETwork research (NET), St. Augustin, GERMANY // Stefan Bund // // This program is free software; you can redistribute it and/or modify @@ -23,25 +23,26 @@ /** \file \brief VariantParser internal header */ -#ifndef IH_VariantParser_ -#define IH_VariantParser_ 1 +#ifndef IH_SENF_Packets_VariantParser_ +#define IH_SENF_Packets_VariantParser_ 1 // Custom includes #include "PacketParser.hh" +#include +#include +#include +#include +#include +#include +#include +#include ///////////////////////////////ih.p//////////////////////////////////////// namespace senf { namespace detail { -# define SENF_PARSE_VARIANT_TPL_ARGS_DFL(n) \ - BOOST_PP_ENUM_PARAMS_WITH_A_DEFAULT( SENF_LIMIT_PARSE_VARIANT, \ - n, \ - boost::mpl::na ) - -# define SENF_PARSE_VARIANT_TPL_ARGS(n) BOOST_PP_ENUM_PARAMS( SENF_LIMIT_PARSE_VARIANT, n ) - -# ifndef DOXYGEN +#ifndef DOXYGEN template struct VariantBytes { @@ -53,49 +54,242 @@ namespace detail { static PacketParserBase::size_type bytes(Variant const & v, unsigned n); }; -# endif - - /** \brief Internal: Variant Policy used by senf::DirectVariantParser */ - template - struct DirectVariantParser + template + struct VariantParserPolicy; + + template + struct VariantParserPolicy + {}; + + template + struct VariantParserPolicy + : public VariantParserPolicy< void, + TransformAuxParserPolicy, AuxTag > + {}; + + template + struct VariantParserPolicy + { + typedef AuxPolicy type; + }; + + template + struct VariantParserPolicy > + { + typedef TransformAuxParserPolicy type; + }; + + template + struct VariantParserTraits + { + template + struct parser { + typedef senf::VariantParser< + typename VariantParserPolicy::type, + Parsers> type; + }; + }; + + template + struct VariantKey + { + static T key() { return (*KeyFn)(); } + }; + + template + struct VariantKeyTransform + { + typedef unsigned value_type; + typedef T input_type; + static unsigned get(input_type v); + static input_type set(unsigned v); + }; + + template + struct VariantKeyTransformCheck { - typedef PacketParserBase::data_iterator data_iterator; - typedef PacketParserBase::state_type state_type; - typedef PacketParserBase::size_type size_type; - - static size_type const init_bytes = 0; - size_type bytes(data_iterator i, state_type s) const { return 0; } - data_iterator begin(data_iterator i, state_type s) const { return i; } - - ChooserType chooser(data_iterator i, state_type s) const { - return ChooserType(boost::prior(i, Distance),s); - } - - unsigned variant(data_iterator i, state_type s) const { - return Translator::fromChooser(chooser(i,s).value()); - } - - void variant(unsigned v, data_iterator i, state_type s) { - chooser(i,s).value(Translator::toChooser(v)); - } + static Out get(In v); + static In set(Out v); }; - /** \brief Internal: Identity chooser translator */ - struct VariantParser_IdentityTranslator { - static unsigned fromChooser(unsigned value) { return value; } - static unsigned toChooser(unsigned value) { return value; } + template + struct VariantKeyTransformCheck + { + static Out get(In v); + static In set(Out v); }; + +# define SENF_PARSER_VARIANT_I(access, name, chooser, types) \ + SENF_PARSER_REQUIRE_VAR(variant) \ + private: \ + typedef boost::mpl::vector< BOOST_PP_SEQ_ENUM(SENF_PARSER_VARIANT_TYPES(types)) > \ + BOOST_PP_CAT(name, _parsers); \ + typedef BOOST_PP_CAT(SENF_PARSER_COLLECTION_GETAUX(chooser), _t)::value_type \ + BOOST_PP_CAT(name,_chooser_value_type); \ + BOOST_PP_IF( SENF_PARSER_VARIANT_NEEDTRANSFORM(types), \ + SENF_PARSER_VARIANT_MAKETRANSFORM, \ + SENF_PARSER_VARIANT_NOTRANSFORM )(name, \ + types) \ + typedef senf::detail::VariantParserTraits< BOOST_PP_CAT(name, _parsers), \ + BOOST_PP_CAT(name, _transform) > \ + BOOST_PP_CAT(name, _traits); \ + public: \ + SENF_PARSER_COLLECTION_I( \ + BOOST_PP_IIF( SENF_PARSER_VARIANT_NEEDACCESSORS(types), private, access), \ + name, chooser, BOOST_PP_CAT(name, _traits) ); \ + access: \ + BOOST_PP_SEQ_FOR_EACH_I(SENF_PARSER_VARIANT_ACCESSOR, name, types) \ + public: + +# define SENF_PARSER_VARIANT_MAKETRANSFORM(name, types) \ + BOOST_PP_SEQ_FOR_EACH_I(SENF_PARSER_VARIANT_KEYVALUE, name, types) \ + template \ + struct BOOST_PP_CAT(name, _key_value_template) \ + : public senf::detail::VariantKey {}; \ + template friend class senf::detail::VariantKey; \ + typedef senf::detail::VariantKeyTransform< \ + BOOST_PP_CAT(name,_chooser_value_type), \ + boost::mpl::vector< \ + BOOST_PP_SEQ_ENUM(SENF_PARSER_VARIANT_KEYVALUES(name, types)) \ + > > BOOST_PP_CAT(name, _transform); + +# define SENF_PARSER_VARIANT_KEYVALUE(r, name, i, elem) \ + static BOOST_PP_CAT(name, _chooser_value_type) \ + BOOST_PP_CAT(BOOST_PP_CAT(name, _key_),i)() \ + { return SENF_PARSER_VARIANT_GETKEY(elem, i); } + +# define SENF_PARSER_VARIANT_NOTRANSFORM(name, types) \ + typedef void BOOST_PP_CAT(name, _transform); + +# define SENF_PARSER_VARIANT_KEYVALUES(name, types) \ + BOOST_PP_SEQ_FOR_EACH_I(SENF_PARSER_VARIANT_KEYVALUES_, name, types) + +# define SENF_PARSER_VARIANT_KEYVALUES_(r, name, i, elem) \ + (BOOST_PP_CAT(name,_key_value_template)< \ + & BOOST_PP_CAT(BOOST_PP_CAT(name, _key_), i) >) -# define SENF_PARSER_VARIANT_(r, data, elem) ,elem +# define SENF_PARSER_VARIANT_ACCESSOR(r, name, i, elem) \ + BOOST_PP_IF( SENF_PARSER_VARIANT_HASID(elem), \ + SENF_PARSER_VARIANT_MAKEACCESSOR, \ + SENF_PARSER_VARIANT_NOACCESSOR )(name, i, elem) -# define SENF_PARSER_VARIANT_I(field, name, chooser, translator, types) \ - typedef senf::DirectVariantParser< \ - BOOST_PP_CAT(chooser, _t), \ - SENF_PARSER_CURRENT_FIXED_OFFSET() - SENF_PARSER_FIXED_OFFSET(chooser), \ - translator \ - BOOST_PP_SEQ_FOR_EACH( SENF_PARSER_VARIANT_, _, types ) \ - >::parser BOOST_PP_CAT(name, _variant_t); \ - field( name, BOOST_PP_CAT(name, _variant_t) ) +# define SENF_PARSER_VARIANT_NOACCESSOR(name, i, elem) +# define SENF_PARSER_VARIANT_MAKEACCESSOR(name, i, elem) \ + SENF_PARSER_VARIANT_MAKEACCESSOR_VALUE(name, i, elem, SENF_PARSER_VARIANT_GETID(elem)) \ + SENF_PARSER_VARIANT_MAKEACCESSOR_HAS(name, i, elem, SENF_PARSER_VARIANT_GETHASID(elem)) \ + SENF_PARSER_VARIANT_MAKEACCESSOR_INIT(name, i, elem, SENF_PARSER_VARIANT_GETINITID(elem)) + +# define SENF_PARSER_VARIANT_IFNOTNA(id, x) \ + BOOST_PP_EXPR_IIF( BOOST_PP_NOT( SENF_PARSER_VARIANT_NA(id) ), x ) + +# define SENF_PARSER_VARIANT_MAKEACCESSOR_VALUE(name, i, elem, id) \ + SENF_PARSER_VARIANT_IFNOTNA( id, \ + typedef SENF_PARSER_VARIANT_GETTYPE(elem) \ + BOOST_PP_CAT(id, _t); \ + BOOST_PP_CAT(id, _t) id() const \ + { return name().get(); } \ + ) + +# define SENF_PARSER_VARIANT_MAKEACCESSOR_HAS(name, i, elem, id) \ + SENF_PARSER_VARIANT_IFNOTNA( id, \ + bool id() const \ + { return name().variant() == i; } \ + ) + +# define SENF_PARSER_VARIANT_MAKEACCESSOR_INIT(name, i, elem, id) \ + SENF_PARSER_VARIANT_IFNOTNA( id, \ + void id() const \ + { name().init(); } \ + ) + +# define SENF_PARSER_VARIANT_KEY_GOBBLE__key(key, type) +# define SENF_PARSER_VARIANT_KEY_GETKEY__key(key, type) key +# define SENF_PARSER_VARIANT_KEY_GETTYPE__key(key, type) type + +# define SENF_PARSER_VARIANT_ID_GOBBLE__id(id, value) +# define SENF_PARSER_VARIANT_ID_GETID__id(id, value) id +# define SENF_PARSER_VARIANT_ID_GETVALUE__id(id, value) value +# define SENF_PARSER_VARIANT_ID_GETHASID__id(id, value) SENF_CAT_RECURS3(has_, id) +# define SENF_PARSER_VARIANT_ID_GETINITID__id(id, value) SENF_CAT_RECURS3(init_, id) + +# define SENF_PARSER_VARIANT_ID_GOBBLE__novalue(id, value) +# define SENF_PARSER_VARIANT_ID_GETID__novalue(id, value) na +# define SENF_PARSER_VARIANT_ID_GETVALUE__novalue(id, value) value +# define SENF_PARSER_VARIANT_ID_GETHASID__novalue(id, value) na +# define SENF_PARSER_VARIANT_ID_GETINITID__novalue(id, value) id + +# define SENF_PARSER_VARIANT_ID_GOBBLE__ids(id, hasid, initid, value) +# define SENF_PARSER_VARIANT_ID_GETID__ids(id, hasid, initid, value) id +# define SENF_PARSER_VARIANT_ID_GETVALUE__ids(id, hasid, initid, value) value +# define SENF_PARSER_VARIANT_ID_GETHASID__ids(id, hasid, initid, value) hasid +# define SENF_PARSER_VARIANT_ID_GETINITID__ids(id, hasid, initid, value) initid + +# define SENF_PARSER_VARIANT_NA_GOBBLE__na + +# define SENF_PARSER_VARIANT_NA(x) \ + BOOST_PP_IS_EMPTY( SENF_CAT_RECURS1(SENF_PARSER_VARIANT_NA_GOBBLE__, x) ) + +# define SENF_PARSER_VARIANT_HASKEY(x) \ + SENF_PARSER_VARIANT_HASKEY_( SENF_PARSER_VARIANT_GETVALUE(x) ) + +# define SENF_PARSER_VARIANT_HASKEY_(x) \ + BOOST_PP_IS_EMPTY( SENF_CAT_RECURS1(SENF_PARSER_VARIANT_KEY_GOBBLE__, x) ) + +# define SENF_PARSER_VARIANT_GETKEY(x, default) \ + SENF_PARSER_VARIANT_GETKEY_( SENF_PARSER_VARIANT_GETVALUE(x), default ) + +# define SENF_PARSER_VARIANT_GETKEY_(x, default) \ + BOOST_PP_IF( SENF_PARSER_VARIANT_HASKEY_(x), \ + BOOST_PP_CAT(SENF_PARSER_VARIANT_KEY_GETKEY__, x), \ + default ) + +# define SENF_PARSER_VARIANT_HASID(x) \ + BOOST_PP_IS_EMPTY( SENF_CAT_RECURS2(SENF_PARSER_VARIANT_ID_GOBBLE__, x) ) + +# define SENF_PARSER_VARIANT_GETID(x) \ + BOOST_PP_CAT(SENF_PARSER_VARIANT_ID_GETID__, x) + +# define SENF_PARSER_VARIANT_GETHASID(x) \ + BOOST_PP_CAT(SENF_PARSER_VARIANT_ID_GETHASID__, x) + +# define SENF_PARSER_VARIANT_GETINITID(x) \ + BOOST_PP_CAT(SENF_PARSER_VARIANT_ID_GETINITID__, x) + +# define SENF_PARSER_VARIANT_GETVALUE(x) \ + BOOST_PP_IF( SENF_PARSER_VARIANT_HASID(x), \ + BOOST_PP_CAT(SENF_PARSER_VARIANT_ID_GETVALUE__, x), \ + x ) + +# define SENF_PARSER_VARIANT_GETTYPE(x) \ + SENF_PARSER_VARIANT_GETTYPE_( SENF_PARSER_VARIANT_GETVALUE(x) ) + +# define SENF_PARSER_VARIANT_GETTYPE_(x) \ + BOOST_PP_IF( SENF_PARSER_VARIANT_HASKEY_(x), \ + BOOST_PP_CAT(SENF_PARSER_VARIANT_KEY_GETTYPE__, x), \ + x ) + +# define SENF_PARSER_VARIANT_NEEDTRANSFORM(types) \ + BOOST_PP_SEQ_FOLD_LEFT(SENF_PARSER_VARIANT_NEEDTRANSFORM_, 0, types) + +# define SENF_PARSER_VARIANT_NEEDTRANSFORM_(s, state, elem) \ + BOOST_PP_OR(state, SENF_PARSER_VARIANT_HASKEY(elem)) + +# define SENF_PARSER_VARIANT_NEEDACCESSORS(types) \ + BOOST_PP_SEQ_FOLD_LEFT(SENF_PARSER_VARIANT_NEEDACCESSORS_, 0, types) + +# define SENF_PARSER_VARIANT_NEEDACCESSORS_(s, state, elem) \ + BOOST_PP_OR(state, SENF_PARSER_VARIANT_HASID(elem)) + +# define SENF_PARSER_VARIANT_TYPES(types) \ + BOOST_PP_SEQ_FOR_EACH(SENF_PARSER_VARIANT_TYPES_, _, types) + +# define SENF_PARSER_VARIANT_TYPES_(r, _, elem) \ + (SENF_PARSER_VARIANT_GETTYPE(elem)) + +#endif }}