// $Id$ // // Copyright (C) 2007 // Fraunhofer Institute for Open Communication Systems (FOKUS) // // The contents of this file are subject to the Fraunhofer FOKUS Public License // Version 1.0 (the "License"); you may not use this file except in compliance // with the License. You may obtain a copy of the License at // http://senf.berlios.de/license.html // // The Fraunhofer FOKUS Public License Version 1.0 is based on, // but modifies the Mozilla Public License Version 1.1. // See the full license text for the amendments. // // Software distributed under the License is distributed on an "AS IS" basis, // WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License // for the specific language governing rights and limitations under the License. // // The Original Code is Fraunhofer FOKUS code. // // The Initial Developer of the Original Code is Fraunhofer-Gesellschaft e.V. // (registered association), Hansastraße 27 c, 80686 Munich, Germany. // All Rights Reserved. // // Contributor(s): // Stefan Bund /** \file \brief VariantParser internal header */ #ifndef IH_SENF_Packets_VariantParser_ #define IH_SENF_Packets_VariantParser_ 1 // Custom includes #include "PacketParser.hh" #include #include #include #include #include #include #include #include //-///////////////////////////////////////////////////////////////////////////////////////////////// namespace senf { namespace detail { #ifndef DOXYGEN template struct VariantBytes { static PacketParserBase::size_type bytes(Variant const & v, unsigned n); }; template struct VariantBytes { static PacketParserBase::size_type bytes(Variant const & v, unsigned n); }; 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 { static Out get(In v); static In set(Out v); }; 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) \ protected: \ typedef boost::mpl::vector< BOOST_PP_SEQ_ENUM(SENF_PARSER_VARIANT_TYPES(types)) > \ BOOST_PP_CAT(name, _parsers); \ private: \ 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), protected, 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 struct 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_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_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 }} //-///////////////////////////////////////////////////////////////////////////////////////////////// #endif // Local Variables: // mode: c++ // fill-column: 100 // comment-column: 40 // c-file-style: "senf" // indent-tabs-mode: nil // ispell-local-dictionary: "american" // compile-command: "scons -u test" // End: