84564a46d9ac7bbb26306958c2c39cc1436e208c
[senf.git] / Packets / ParseVariant.hh
1 // $Id$
2 //
3 // Copyright (C) 2007 
4 // Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
5 // Kompetenzzentrum fuer NETwork research (NET)
6 //     Stefan Bund <g0dil@berlios.de>
7 //
8 // This program is free software; you can redistribute it and/or modify
9 // it under the terms of the GNU General Public License as published by
10 // the Free Software Foundation; either version 2 of the License, or
11 // (at your option) any later version.
12 //
13 // This program is distributed in the hope that it will be useful,
14 // but WITHOUT ANY WARRANTY; without even the implied warranty of
15 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 // GNU General Public License for more details.
17 //
18 // You should have received a copy of the GNU General Public License
19 // along with this program; if not, write to the
20 // Free Software Foundation, Inc.,
21 // 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
22
23 /** \file
24     \brief ParseVariant public header */
25
26 #ifndef HH_ParseVariant_
27 #define HH_ParseVariant_ 1
28
29 #ifndef HH_Packets_
30 #error "Don't include 'ParseVariant.hh' directly, include 'Packets.hh'"
31 #endif
32
33 // Custom includes
34 #include <boost/mpl/vector.hpp>
35 #include <boost/mpl/at.hpp>
36 #include <boost/preprocessor/repetition/enum_params_with_a_default.hpp>
37 #include <boost/preprocessor/repetition/enum_params.hpp>
38 #include <boost/preprocessor/seq/for_each.hpp>
39 #include "PacketParser.hh"
40
41 //#include "ParseVariant.mpp"
42 #include "ParseVariant.ih"
43 ///////////////////////////////hh.p////////////////////////////////////////
44
45 namespace senf {
46
47 #   ifndef SENF_LIMIT_PARSER_VARIANT
48 #       define SENF_LIMIT_PARSE_VARIANT 10
49 #   endif
50
51 #   define SENF_PARSE_VARIANT_TPL_ARGS_DFL(n)                                                     \
52         BOOST_PP_ENUM_PARAMS_WITH_A_DEFAULT( SENF_LIMIT_PARSE_VARIANT,                            \
53                                              n,                                                   \
54                                              boost::mpl::na )
55
56 #   define SENF_PARSE_VARIANT_TPL_ARGS(n) BOOST_PP_ENUM_PARAMS( SENF_LIMIT_PARSE_VARIANT, n )
57
58     template <class VariantPolicy, SENF_PARSE_VARIANT_TPL_ARGS_DFL(class P)>
59     class Parse_Variant 
60         : public PacketParserBase, private VariantPolicy
61     {
62         typedef boost::mpl::vector< SENF_PARSE_VARIANT_TPL_ARGS(P) > parsers;
63
64     public:
65         Parse_Variant(data_iterator i, state_type s);
66         Parse_Variant(VariantPolicy policy, data_iterator i, state_type s);
67
68         size_type bytes() const;
69         void init();
70         
71         static const size_type init_bytes = 
72             senf::init_bytes<P0>::value + VariantPolicy::init_bytes;
73
74         ///////////////////////////////////////////////////////////////////////////
75
76         unsigned variant() const;
77         
78         template <unsigned N>
79         typename boost::mpl::at< parsers, boost::mpl::int_<N> >::type get() const;
80
81         template <unsigned N>
82         void init();
83
84     private:
85     };
86
87     template <class ChooserType, unsigned Distance, SENF_PARSE_VARIANT_TPL_ARGS_DFL(class P)>
88     struct Parse_Variant_Direct
89     {
90         typedef Parse_Variant< detail::Parse_Variant_Direct<ChooserType, Distance>,
91                                SENF_PARSE_VARIANT_TPL_ARGS(P) > parser;
92     };
93
94 #   define SENF_PARSER_VARIANT_(r, data, elem) ,elem
95
96 #   define SENF_PARSER_VARIANT(name, chooser, types)                                              \
97         typedef senf::Parse_Variant_Direct<                                                       \
98             BOOST_PP_CAT(chooser, _t),                                                            \
99             SENF_PARSER_CURRENT_FIXED_OFFSET() - SENF_PARSER_FIXED_OFFSET(chooser)                \
100             BOOST_PP_SEQ_FOR_EACH( SENF_PARSER_VARIANT_, _, types )                               \
101             >::parser BOOST_PP_CAT(name, _variant_t);                                             \
102         SENF_PARSER_FIELD( name, BOOST_PP_CAT(name, _variant_t) )
103
104 #   define SENF_PARSER_PRIVATE_VARIANT(name, chooser, types)                                      \
105         typedef senf::Parse_Variant_Direct<                                                       \
106             BOOST_PP_CAT(chooser, _t),                                                            \
107             SENF_PARSER_CURRENT_FIXED_OFFSET() - SENF_PARSER_FIXED_OFFSET(chooser)                \
108             BOOST_PP_SEQ_FOR_EACH( SENF_PARSER_VARIANT_, _, types )                               \
109             >::parser BOOST_PP_CAT(name, _variant_t);                                             \
110         SENF_PARSER_PRIVATE_FIELD( name, BOOST_PP_CAT(name, _variant_t) )
111
112 }
113
114 ///////////////////////////////hh.e////////////////////////////////////////
115 #endif
116 #if !defined(HH_Packets__decls_) && !defined(HH_ParseVariant_i_)
117 #define HH_ParseVariant_i_
118 //#include "ParseVariant.cci"
119 #include "ParseVariant.ct"
120 #include "ParseVariant.cti"
121 #endif
122
123 \f
124 // Local Variables:
125 // mode: c++
126 // fill-column: 100
127 // comment-column: 40
128 // c-file-style: "senf"
129 // indent-tabs-mode: nil
130 // ispell-local-dictionary: "american"
131 // compile-command: "scons -u test"
132 // End: