// $Id$ // // 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 // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the // Free Software Foundation, Inc., // 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. /** \file \brief VariantParser internal header */ #ifndef IH_VariantParser_ #define IH_VariantParser_ 1 // Custom includes #include "PacketParser.hh" #include #include #include #include #include #include ///////////////////////////////ih.p//////////////////////////////////////// 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) \ 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( \ access, name, chooser, BOOST_PP_CAT(name, _traits) ); \ BOOST_PP_SEQ_FOR_EACH_I(SENF_PARSER_VARIANT_ACCESSOR, name, types) # 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_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) \ BOOST_PP_IF( SENF_PARSER_VARIANT_HASVALUE(elem), \ SENF_PARSER_VARIANT_MAKEVACCESSOR, \ SENF_PARSER_VARIANT_MAKENVACCESSOR )(name, i, elem) # define SENF_PARSER_VARIANT_MAKEVACCESSOR(name, i, elem) \ typedef SENF_PARSER_VARIANT_GETTYPE(elem) \ BOOST_PP_CAT(SENF_PARSER_VARIANT_GETID(elem), _t); \ SENF_PARSER_VARIANT_GETTYPE(elem) SENF_PARSER_VARIANT_GETID(elem)() const \ { return name().get(); } \ void BOOST_PP_CAT(init_, SENF_PARSER_VARIANT_GETID(elem))() const \ { name().init(); } \ bool BOOST_PP_CAT(has_, SENF_PARSER_VARIANT_GETID(elem))() const \ { return name().variant() == i; } # define SENF_PARSER_VARIANT_MAKENVACCESSOR(name, i, elem) \ void SENF_PARSER_VARIANT_GETID(elem)() 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_GOBBLE__novalue(id, value) # define SENF_PARSER_VARIANT_ID_GETID__novalue(id, value) id # define SENF_PARSER_VARIANT_ID_GETVALUE__novalue(id, value) value # define SENF_PARSER_VARIANT_HASVALUE_GOBBLE__id(id, value) # 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_GETVALUE(x) \ BOOST_PP_IF( SENF_PARSER_VARIANT_HASID(x), \ BOOST_PP_CAT(SENF_PARSER_VARIANT_ID_GETVALUE__, x), \ x ) # define SENF_PARSER_VARIANT_HASVALUE(x) \ BOOST_PP_IS_EMPTY( SENF_CAT_RECURS3(SENF_PARSER_VARIANT_HASVALUE_GOBBLE__, 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_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 }} ///////////////////////////////ih.e//////////////////////////////////////// #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: