Search:

SENF Extensible Network Framework

  • Home
  • Download
  • Wiki
  • BerliOS
  • ChangeLog
  • Browse SVN
  • Bug Tracker
  • Overview
  • Examples
  • HowTos
  • Glossary
  • PPI
  • Packets
  • Scheduler
  • Socket
  • Utils
  • Console
  • Daemon
  • Logger
  • Termlib
  • Main Page
  • Related Pages
  • Modules
  • Namespaces
  • Classes
  • Files
  • File List
  • File Members

VariantParser.ih

Go to the documentation of this file.
00001 // $Id: VariantParser.ih 1742 2010-11-04 14:51:56Z g0dil $
00002 //
00003 // Copyright (C) 2007
00004 // Fraunhofer (FOKUS)
00005 // Competence Center NETwork research (NET), St. Augustin, GERMANY
00006 //     Stefan Bund <g0dil@berlios.de>
00007 //
00008 // This program is free software; you can redistribute it and/or modify
00009 // it under the terms of the GNU General Public License as published by
00010 // the Free Software Foundation; either version 2 of the License, or
00011 // (at your option) any later version.
00012 //
00013 // This program is distributed in the hope that it will be useful,
00014 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00015 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00016 // GNU General Public License for more details.
00017 //
00018 // You should have received a copy of the GNU General Public License
00019 // along with this program; if not, write to the
00020 // Free Software Foundation, Inc.,
00021 // 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
00022 
00026 #ifndef IH_SENF_Packets_VariantParser_
00027 #define IH_SENF_Packets_VariantParser_ 1
00028 
00029 // Custom includes
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 // Local Variables:
00302 // mode: c++
00303 // fill-column: 100
00304 // comment-column: 40
00305 // c-file-style: "senf"
00306 // indent-tabs-mode: nil
00307 // ispell-local-dictionary: "american"
00308 // compile-command: "scons -u test"
00309 // End:

Contact: senf-dev@lists.berlios.de | © 2006-2010 Fraunhofer Institute for Open Communication Systems, Network Research