switch to new MPL based Fraunhofer FOKUS Public License
[senf.git] / senf / Packets / ParseHelpers.ih
1 // $Id$
2 //
3 // Copyright (C) 2007
4 // Fraunhofer Institute for Open Communication Systems (FOKUS)
5 //
6 // The contents of this file are subject to the Fraunhofer FOKUS Public License
7 // Version 1.0 (the "License"); you may not use this file except in compliance
8 // with the License. You may obtain a copy of the License at
9 // http://senf.berlios.de/license.html
10 //
11 // The Fraunhofer FOKUS Public License Version 1.0 is based on,
12 // but modifies the Mozilla Public License Version 1.1.
13 // See the full license text for the amendments.
14 //
15 // Software distributed under the License is distributed on an "AS IS" basis,
16 // WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
17 // for the specific language governing rights and limitations under the License.
18 //
19 // The Original Code is Fraunhofer FOKUS code.
20 //
21 // The Initial Developer of the Original Code is Fraunhofer-Gesellschaft e.V.
22 // (registered association), Hansastraße 27 c, 80686 Munich, Germany.
23 //
24 // Contributor(s):
25 //   Stefan Bund <g0dil@berlios.de>
26 /** \file
27      \brief ParseHelpers internal header */
28
29 # if !defined(IH_ParseHelpers_)
30 # define IH_ParseHelpers_ 1
31 #
32 # // Custom includes
33 # include <boost/preprocessor/cat.hpp>
34 # include <boost/preprocessor/if.hpp>
35 # include <boost/preprocessor/expand.hpp>
36 # include <boost/preprocessor/facilities/is_empty.hpp>
37 # include <boost/preprocessor/punctuation/comma.hpp>
38 # include "../Utils/preprocessor.hh"
39 # include "../Utils/mpl.hh"
40 #
41 # //-///////////////////////////////////////////////////////////////////////////////////////////////
42 #
43 # //-///////////////////////////////////////////////////////////////////////////////////////////////
44 # // SENF_PARSER_INITIALIZE
45 #
46 # define SENF_PARSER_INITIALIZE  BOOST_PP_CAT( SENF_PARSER_INITIALIZE_ , SENF_PARSER_TYPE )
47 #
48 # define SENF_PARSER_INITIALIZE_fix()                                                             \
49     private:                                                                                      \
50         SENF_MPL_SLOT_DEF_ZERO(index);                                                            \
51         SENF_MPL_SLOT_DEF_ZERO(offset);                                                           \
52         SENF_MPL_SLOT_DEF_ZERO(bit);                                                              \
53         SENF_MPL_SLOT_DEF_ZERO(bitfield_size);                                                    \
54         void init_chain(senf::mpl::rv<0>*) const {}                                               \
55     public:
56 #
57 # define SENF_PARSER_INITIALIZE_var()                                                             \
58     private:                                                                                      \
59         SENF_MPL_SLOT_DEF_ZERO(index);                                                            \
60         SENF_MPL_SLOT_DEF_ZERO(init_bytes);                                                       \
61         SENF_MPL_SLOT_DEF_ZERO(bit);                                                              \
62         SENF_MPL_SLOT_DEF_ZERO(bitfield_size);                                                    \
63         SENF_MPL_SLOT_DEF_ZERO(group);                                                            \
64         void init_chain(senf::mpl::rv<0>*) const {}                                               \
65         size_type field_offset_(senf::mpl::rv<0>*) const { return 0; }                            \
66     public:
67 #
68 # //-///////////////////////////////////////////////////////////////////////////////////////////////
69 # // SENF_PARSER_INHERIT_*
70 #
71 # define SENF_PARSER_INHERIT_var(name)                                                            \
72         typedef name parser_base_type;                                                            \
73     private:                                                                                      \
74         SENF_MPL_SLOT_SET(index, 1);                                                              \
75         SENF_MPL_SLOT_SET(init_bytes, senf::init_bytes<name>::value);                             \
76         size_type field_offset_(senf::mpl::rv<1>*) const {                                        \
77             return senf::bytes( *static_cast<name const*>(this) );                                \
78         }                                                                                         \
79         void init_chain(senf::mpl::rv<1>*) const {                                                \
80             name::init();                                                                         \
81         }                                                                                         \
82     public:
83 #
84 # define SENF_PARSER_INHERIT_fix(name)                                                            \
85         typedef name parser_base_type;                                                            \
86     private:                                                                                      \
87         SENF_MPL_SLOT_SET(offset, name::fixed_bytes);                                             \
88         SENF_MPL_SLOT_SET(index, 1);                                                              \
89         void init_chain(senf::mpl::rv<1>*) const {                                                \
90             name::init();                                                                         \
91         }                                                                                         \
92     public:
93 #
94 # //-///////////////////////////////////////////////////////////////////////////////////////////////
95 # // SENF_PARSER_FIELD*
96 # // SENF_PARSER_P_FIELD_*
97 #
98 # define SENF_PARSER_FIELD_var(name, type)    SENF_PARSER_FIELD_I(name, type, var, rw, public)
99 # define SENF_PARSER_FIELD_RO_var(name, type) SENF_PARSER_FIELD_I(name, type, var, ro, public)
100 # define SENF_PARSER_FIELD_fix(name, type)    SENF_PARSER_FIELD_I(name, type, fix, rw, public)
101 # define SENF_PARSER_FIELD_RO_fix(name, type) SENF_PARSER_FIELD_I(name, type, fix, ro, public)
102 #
103 # define SENF_PARSER_P_FIELD_var(name, type)    SENF_PARSER_FIELD_I(name, type, var, rw, protected)
104 # define SENF_PARSER_P_FIELD_fix(name, type)    SENF_PARSER_FIELD_I(name, type, fix, rw, protected)
105 #
106 # define SENF_PARSER_FIELD_I(name, type, ofstype, rwtype, access)                                 \
107     access:                                                                                       \
108         SENF_PARSER_FIELD_SETUP_I(name, type, ofstype, rwtype, access)                            \
109         BOOST_PP_CAT(SENF_PARSER_I_FIELD_VAL_, rwtype) (name, type, access)                       \
110     public:
111 #
112 # define SENF_PARSER_FIELD_SETUP_I(name, type, ofstype, rwtype, access)                           \
113         SENF_PARSER_I_BITFIELD_RESET()                                                            \
114         SENF_PARSER_I_FIELD_INTRO(name, type, access)                                             \
115         BOOST_PP_CAT(SENF_PARSER_I_FIELD_INIT_, rwtype) (name, type, access)                      \
116         BOOST_PP_CAT(SENF_PARSER_I_FIELD_OFS_, ofstype) (name, type, access)                      \
117         BOOST_PP_CAT(SENF_PARSER_I_ADVANCE_OFS_, ofstype) (                                       \
118             name, type,                                                                           \
119             BOOST_PP_CAT(SENF_PARSER_I_SIZE_, ofstype) (name, type),                              \
120             BOOST_PP_CAT(SENF_PARSER_I_INITBYTES_, ofstype) (name, type),                         \
121             BOOST_PP_CAT(SENF_PARSER_I_ISVAR_, ofstype) (name, type),                             \
122             access )
123 #
124 # //-///////////////////////////////////////////////////////////////////////////////////////////////
125 # // SENF_PARSER_I_FIELD_INTRO
126 #
127 # define SENF_PARSER_I_FIELD_INTRO(name, type, access)                                            \
128         typedef type BOOST_PP_CAT(name, _t);                                                      \
129         static size_type const BOOST_PP_CAT(name,_index) = SENF_MPL_SLOT_GET(index)+1;            \
130     private:                                                                                      \
131         SENF_MPL_SLOT_SET(index, BOOST_PP_CAT(name,_index));                                      \
132     access:
133 #
134 # //-///////////////////////////////////////////////////////////////////////////////////////////////
135 # // SENF_PARSER_I_FIELD_INIT_*
136 #
137 # define SENF_PARSER_I_FIELD_INIT_rw(name, type, access)                                          \
138     private:                                                                                      \
139         void init_chain(senf::mpl::rv<BOOST_PP_CAT(name,_index)>*) const {                        \
140             init_chain(static_cast<senf::mpl::rv<BOOST_PP_CAT(name,_index)-1>*>(0));              \
141             name().init();                                                                        \
142         }                                                                                         \
143     access:
144 #
145 # define SENF_PARSER_I_FIELD_INIT_ro(name, type, access)                                          \
146     private:                                                                                      \
147         void init_chain(senf::mpl::rv<BOOST_PP_CAT(name,_index)>*) const {                        \
148             init_chain(static_cast<senf::mpl::rv<BOOST_PP_CAT(name,_index)-1>*>(0));              \
149         }                                                                                         \
150     access:
151 #
152 # //-///////////////////////////////////////////////////////////////////////////////////////////////
153 # // SENF_PARSER_I_FIELD_OFS_*
154 #
155 # define SENF_PARSER_I_FIELD_OFS_var(name, type, access)                                          \
156     protected:                                                                                    \
157         size_type BOOST_PP_CAT(name,_offset)() const {                                            \
158             return field_offset_(static_cast<senf::mpl::rv<BOOST_PP_CAT(name,_index)-1>*>(0));    \
159         }                                                                                         \
160         static size_type const BOOST_PP_CAT(name, _init_bytes) =                                  \
161             SENF_MPL_SLOT_GET(init_bytes);                                                        \
162     private:
163 #
164 # define SENF_PARSER_I_FIELD_OFS_fix(name, type, access)                                          \
165     protected:                                                                                    \
166         static size_type const BOOST_PP_CAT(name, _offset) =                                      \
167             SENF_MPL_SLOT_GET(offset);                                                            \
168     private:
169 #
170 # //-///////////////////////////////////////////////////////////////////////////////////////////////
171 # // SENF_PARSER_I_ADVANCE_OFS_*
172 #
173 # define SENF_PARSER_I_SIZE_var(name, type) senf::bytes(BOOST_PP_CAT(name, _)())
174 # define SENF_PARSER_I_INITBYTES_var(name, type) senf::init_bytes<type>::value
175 #
176 # define SENF_PARSER_I_SIZE_fix(name, type) type::fixed_bytes
177 # define SENF_PARSER_I_INITBYTES_fix(name, type) void
178 #
179 # define SENF_PARSER_I_ISVAR_fix(name, type) 0
180 # define SENF_PARSER_I_ISVAR_var(name, type) (senf::is_fixed<type>::value?0:1)
181 #
182 # define SENF_PARSER_I_ADVANCE_OFS_var(name, type, size, isize, isvar, access)                    \
183         size_type BOOST_PP_CAT(name, _next_offset)() const {                                      \
184             return BOOST_PP_CAT(name,_offset)() + size;                                           \
185         }                                                                                         \
186         static size_type const BOOST_PP_CAT(name, _next_init_bytes) =                             \
187             BOOST_PP_CAT(name, _init_bytes) + isize;                                              \
188     private:                                                                                      \
189         size_type field_offset_(senf::mpl::rv<BOOST_PP_CAT(name,_index)>*) const {                \
190             return BOOST_PP_CAT(name, _next_offset)();                                            \
191         }                                                                                         \
192         SENF_MPL_SLOT_SET(init_bytes, BOOST_PP_CAT(name,_next_init_bytes));                       \
193     protected:                                                                                    \
194         static size_type const BOOST_PP_CAT(name, _group) = SENF_MPL_SLOT_GET(group) + isvar;     \
195     private:                                                                                      \
196         SENF_MPL_SLOT_SET(group, BOOST_PP_CAT(name, _group));                                     \
197     access:
198 #
199 # define SENF_PARSER_I_ADVANCE_OFS_fix(name, type, size, isize, isvar, access)                    \
200         static size_type const BOOST_PP_CAT(name, _next_offset) =                                 \
201             BOOST_PP_CAT(name, _offset) + size;                                                   \
202     private:                                                                                      \
203         SENF_MPL_SLOT_SET(offset, BOOST_PP_CAT(name, _next_offset));                              \
204     access:
205 #
206 # //-///////////////////////////////////////////////////////////////////////////////////////////////
207 # // SENF_PARSER_I_FIELD_VAL_*
208 #
209 # define SENF_PARSER_I_FIELD_VAL_rw(name, type, access)                                           \
210     protected:                                                                                    \
211         BOOST_PP_CAT(name, _t) BOOST_PP_CAT(name, _)() const {                                    \
212             return parse<type>( SENF_PARSER_OFFSET(name) );                                       \
213         }                                                                                         \
214     access:                                                                                       \
215         BOOST_PP_CAT(name, _t) name() const {                                                     \
216             return BOOST_PP_CAT(name,_)();                                                        \
217         }
218 #
219 # define SENF_PARSER_I_FIELD_VAL_ro(name, type, access)                                           \
220     protected:                                                                                    \
221         BOOST_PP_CAT(name, _t) BOOST_PP_CAT(name, _)() const {                                    \
222             return parse<type>( SENF_PARSER_OFFSET(name) );                                       \
223         }                                                                                         \
224     access:                                                                                       \
225         BOOST_PP_CAT(name, _t)::value_type name() const {                                         \
226             return BOOST_PP_CAT(name,_)();                                                        \
227         }
228 #
229 # //-///////////////////////////////////////////////////////////////////////////////////////////////
230 # // SENF_PARSER_CUSTOM_FIELD_*
231 #
232 # define SENF_PARSER_CUSTOM_FIELD_var(name, type, size, isize)                                    \
233       SENF_PARSER_CUSTOM_FIELD_I(name, type, size, isize, var)
234 # define SENF_PARSER_CUSTOM_FIELD_fix(name, type, size)                                           \
235       SENF_PARSER_CUSTOM_FIELD_I(name, type, size, size, fix)
236 #
237 # define SENF_PARSER_CUSTOM_FIELD_I(name, type, size, isize, ofstype)                             \
238         SENF_PARSER_I_BITFIELD_RESET()                                                            \
239         SENF_PARSER_I_FIELD_INTRO(name, type, public)                                             \
240         SENF_PARSER_I_FIELD_INIT_ro(name, type, public)                                           \
241         BOOST_PP_CAT(SENF_PARSER_I_FIELD_OFS_, ofstype) (name, type, public)                      \
242         BOOST_PP_CAT(SENF_PARSER_I_ADVANCE_OFS_, ofstype) (name, type, size, isize, 1, public)    \
243         BOOST_PP_CAT(name, _t) name() const
244 #
245 # //-///////////////////////////////////////////////////////////////////////////////////////////////
246 # // SENF_PARSER_BITFIELD_*
247 # // SENF_PARSER_P_BITFIELD_*
248 #
249 # define SENF_PARSER_BITFIELD_var(name, bits, type)                                               \
250       SENF_PARSER_BITFIELD_I(name, bits, type, var, rw, public)
251 # define SENF_PARSER_BITFIELD_RO_var(name, bits, type)                                            \
252       SENF_PARSER_BITFIELD_I(name, bits, type, var, ro, public)
253 # define SENF_PARSER_BITFIELD_fix(name, bits, type)                                               \
254       SENF_PARSER_BITFIELD_I(name, bits, type, fix, rw, public)
255 # define SENF_PARSER_BITFIELD_RO_fix(name, bits, type)                                            \
256       SENF_PARSER_BITFIELD_I(name, bits, type, fix, ro, public)
257 #
258 # define SENF_PARSER_P_BITFIELD_var(name, bits, type)                                             \
259       SENF_PARSER_BITFIELD_I(name, bits, type, var, rw, protected)
260 # define SENF_PARSER_P_BITFIELD_fix(name, bits, type)                                             \
261       SENF_PARSER_BITFIELD_I(name, bits, type, fix, rw, protected)
262 #
263 # //-///////////////////////////////////////////////////////////////////////////////////////////////
264 # // SENF_PARSER_BITFIELD_I
265 #
266 # define SENF_PARSER_BITFIELD_TYPE_signed(start, bits)   senf::IntFieldParser<start, start+bits>
267 # define SENF_PARSER_BITFIELD_TYPE_unsigned(start, bits) senf::UIntFieldParser<start, start+bits>
268 # define SENF_PARSER_BITFIELD_TYPE_bool(start, bits)     senf::FlagParser<start>
269 #
270 # define SENF_PARSER_BITFIELD_I(name, bits, type, ofstype, rwtype, access)                        \
271     access:                                                                                       \
272         static size_type const BOOST_PP_CAT(name, _bit) = SENF_MPL_SLOT_GET(bit);                 \
273     private:                                                                                      \
274         SENF_MPL_SLOT_SET(bit, BOOST_PP_CAT(name, _bit) + bits);                                  \
275         typedef BOOST_PP_CAT(SENF_PARSER_BITFIELD_TYPE_, type)( BOOST_PP_CAT(name, _bit), bits )  \
276              BOOST_PP_CAT(name,_bit_t );                                                          \
277     access:                                                                                       \
278         SENF_PARSER_BITFIELD_II( name, bits, BOOST_PP_CAT(name, _bit_t), ofstype, rwtype, access) \
279     public:
280 #
281 # define SENF_PARSER_BITFIELD_II(name, bits, type, ofstype, rwtype, access)                       \
282          SENF_PARSER_I_FIELD_INTRO(name, type, access)                                            \
283          SENF_PARSER_I_FIELD_INIT_ro(name, type, access)                                          \
284          BOOST_PP_CAT(SENF_PARSER_I_BITFIELD_OFS_, ofstype) (name, type, access)                  \
285          BOOST_PP_CAT(SENF_PARSER_I_ADVANCE_OFS_, ofstype) (                                      \
286              name, type,                                                                          \
287              BOOST_PP_CAT(name, _t)::fixed_bytes, BOOST_PP_CAT(name, _t)::fixed_bytes,            \
288              0,                                                                                   \
289              access)                                                                              \
290     private:                                                                                      \
291          SENF_MPL_SLOT_SET(bitfield_size, BOOST_PP_CAT(name, _t)::fixed_bytes);                   \
292     access:                                                                                       \
293          BOOST_PP_CAT(SENF_PARSER_I_FIELD_VAL_, rwtype) (name, type, access)                      \
294     public:
295 #
296 # //-///////////////////////////////////////////////////////////////////////////////////////////////
297 # // SENF_PARSER_I_BITFIELD_OFS_*
298 #
299 # define SENF_PARSER_I_BITFIELD_OFS_var(name, type, access)                                       \
300         size_type BOOST_PP_CAT(name,_offset)() const {                                            \
301             return field_offset_(static_cast<senf::mpl::rv<BOOST_PP_CAT(name,_index)-1>*>(0))     \
302                 - SENF_MPL_SLOT_GET(bitfield_size);                                               \
303         }                                                                                         \
304         static size_type const BOOST_PP_CAT(name, _init_bytes) =                                  \
305             SENF_MPL_SLOT_GET(init_bytes) - SENF_MPL_SLOT_GET(bitfield_size);
306 #
307 # define SENF_PARSER_I_BITFIELD_OFS_fix(name, type, access)                                       \
308         static size_type const BOOST_PP_CAT(name, _offset) =                                      \
309             SENF_MPL_SLOT_GET(offset) - SENF_MPL_SLOT_GET(bitfield_size);
310 #
311 # //-///////////////////////////////////////////////////////////////////////////////////////////////
312 # // SENF_PARSER_I_BITFIELD_RESET
313 #
314 # define SENF_PARSER_I_BITFIELD_RESET()                                                           \
315         SENF_MPL_SLOT_SET(bit, 0);                                                                \
316         SENF_MPL_SLOT_SET(bitfield_size, 0);
317 #
318 # //-///////////////////////////////////////////////////////////////////////////////////////////////
319 # // SENF_PARSER_SKIP_*
320 #
321 # define SENF_PARSER_SKIP_var(bytes, ibytes)                                                      \
322       SENF_PARSER_I_SKIP( BOOST_PP_CAT(senf_anon_, __LINE__), bytes, ibytes, var)
323 #
324 # define SENF_PARSER_SKIP_fix(bytes)                                                              \
325       SENF_PARSER_I_SKIP( BOOST_PP_CAT(senf_anon_, __LINE__), bytes, bytes, fix)
326 #
327 # define SENF_PARSER_I_SKIP(name, bytes, ibytes, ofstype)                                         \
328     private:                                                                                      \
329           SENF_PARSER_I_BITFIELD_RESET()                                                          \
330           SENF_PARSER_I_FIELD_INTRO(name, void, private)                                          \
331           SENF_PARSER_I_FIELD_INIT_ro(name, void, private)                                        \
332           BOOST_PP_CAT(SENF_PARSER_I_FIELD_OFS_, ofstype) (name, type, access)                    \
333           BOOST_PP_CAT(SENF_PARSER_I_ADVANCE_OFS_, ofstype) (name, void, bytes, ibytes, 1,        \
334                                                              private)                             \
335     public:
336 #
337 # //-///////////////////////////////////////////////////////////////////////////////////////////////
338 # // SENF_PARSER_SKIP_BITS_*
339 #
340 # define SENF_PARSER_SKIP_BITS_var(bits) SENF_PARSER_I_SKIP_BITS(bits, var)
341 # define SENF_PARSER_SKIP_BITS_fix(bits) SENF_PARSER_I_SKIP_BITS(bits, fix)
342 #
343 # define SENF_PARSER_I_SKIP_BITS(bits, ofstype)                                                   \
344       private:                                                                                    \
345           SENF_MPL_SLOT_SET(bit, SENF_MPL_SLOT_GET(bit) + bits);                                  \
346       public:
347 #
348 # //-///////////////////////////////////////////////////////////////////////////////////////////////
349 # // SENF_PARSER_GOTO_*
350 #
351 # define SENF_PARSER_GOTO_var(name)                                                               \
352       SENF_PARSER_I_GOTO( BOOST_PP_CAT(senf_anon_, __LINE__),                                     \
353                           BOOST_PP_CAT(name, _offset)(),                                          \
354                           BOOST_PP_CAT(name, _init_bytes),                                        \
355                           var )
356 #
357 # define SENF_PARSER_GOTO_fix(name)                                                               \
358       SENF_PARSER_I_GOTO( BOOST_PP_CAT(senf_anon_, __LINE__),                                     \
359                           BOOST_PP_CAT(name, _offset),                                            \
360                           BOOST_PP_CAT(name, _offset),                                            \
361                           fix )
362 #
363 # define SENF_PARSER_GOTO_OFFSET_var(offset, isize)                                               \
364       SENF_PARSER_I_GOTO( BOOST_PP_CAT(senf_anon_, __LINE__), offset, isize, var )
365 #
366 # define SENF_PARSER_GOTO_OFFSET_fix(offset)                                                      \
367       SENF_PARSER_I_GOTO( BOOST_PP_CAT(senf_anon_, __LINE__), offset, offset, fix )
368 #
369 # define SENF_PARSER_I_GOTO(name, offset, initsize, ofstype)                                      \
370       private:                                                                                    \
371           SENF_PARSER_I_BITFIELD_RESET()                                                          \
372           SENF_PARSER_I_FIELD_INTRO(name, void, private)                                          \
373           SENF_PARSER_I_FIELD_INIT_ro(name, void, private)                                        \
374           BOOST_PP_CAT( SENF_PARSER_I_GOTO_SET_OFS_, ofstype ) (name, offset, initsize)           \
375       public:
376 #
377 # define SENF_PARSER_I_GOTO_SET_OFS_var(name, offs, initsize)                                     \
378           size_type field_offset_(senf::mpl::rv<BOOST_PP_CAT(name,_index)>*) const {              \
379               return offs;                                                                        \
380           }                                                                                       \
381           SENF_MPL_SLOT_SET(init_bytes, initsize);
382 #
383 # define SENF_PARSER_I_GOTO_SET_OFS_fix(name, offs, initsize)                                     \
384           SENF_MPL_SLOT_SET(offset, offs);
385 #
386 # //-///////////////////////////////////////////////////////////////////////////////////////////////
387 # // SENF_PARSER_LABEL_*
388 #
389 # define SENF_PARSER_LABEL_var(name) SENF_PARSER_I_LABEL( name, var, public )
390 # define SENF_PARSER_LABEL_fix(name) SENF_PARSER_I_LABEL( name, fix, public )
391 #
392 # define SENF_PARSER_I_LABEL(name, ofstype, access)                                               \
393       access:                                                                                     \
394           SENF_PARSER_I_BITFIELD_RESET()                                                          \
395           SENF_PARSER_I_FIELD_INTRO(name, void, access)                                           \
396           SENF_PARSER_I_FIELD_INIT_ro(name, void, access)                                         \
397           BOOST_PP_CAT(SENF_PARSER_I_FIELD_OFS_, ofstype) (name, type, access)                    \
398           BOOST_PP_CAT(SENF_PARSER_I_ADVANCE_OFS_, ofstype) (name, void, 0, 0, 0, access)         \
399       public:
400 #
401 # //-///////////////////////////////////////////////////////////////////////////////////////////////
402 # // SENF_PARSER_OFFSET_*
403 #
404 # define SENF_PARSER_OFFSET_fix(name) BOOST_PP_CAT(name, _offset)
405 # define SENF_PARSER_OFFSET_var(name) BOOST_PP_CAT(name, _offset)()
406 #
407 # //-///////////////////////////////////////////////////////////////////////////////////////////////
408 # // SENF_PARSER_FIXED_OFFSET_*
409 #
410 # define SENF_PARSER_FIXED_OFFSET_fix(name) BOOST_PP_CAT(name, _offset)
411 # define SENF_PARSER_FIXED_OFFSET_var(name) BOOST_PP_CAT(name, _init_bytes)
412 #
413 # //-///////////////////////////////////////////////////////////////////////////////////////////////
414 # // SENF_PARSER_CURRENT_FIXED_OFFSET_*
415 #
416 # define SENF_PARSER_CURRENT_FIXED_OFFSET_fix() SENF_MPL_SLOT_GET(offset)
417 # define SENF_PARSER_CURRENT_FIXED_OFFSET_var() SENF_MPL_SLOT_GET(init_bytes)
418 #
419 # //-///////////////////////////////////////////////////////////////////////////////////////////////
420 # // SENF_PARSER_FINALIZE_*
421 #
422 # define SENF_PARSER_FINALIZE_var(name)                                                           \
423     SENF_PARSER_FINALIZE_GENERIC(name)                                                            \
424     size_type bytes() const {                                                                     \
425         return field_offset_(static_cast<senf::mpl::rv<SENF_MPL_SLOT_GET(index)>*>(0));           \
426     }                                                                                             \
427     static size_type const init_bytes = SENF_MPL_SLOT_GET(init_bytes)
428 #
429 # define SENF_PARSER_FINALIZE_fix(name)                                                           \
430     SENF_PARSER_FINALIZE_GENERIC(name)                                                            \
431     static size_type const fixed_bytes = SENF_MPL_SLOT_GET(offset);
432 #
433 # define SENF_PARSER_FINALIZE_GENERIC(name)                                                       \
434          void defaultInit() const {                                                               \
435              init_chain(static_cast<senf::mpl::rv<SENF_MPL_SLOT_GET(index)>*>(0));                \
436          }                                                                                        \
437          name(data_iterator i, state_type s) : parser_base_type(i,s) {}                           \
438     private:                                                                                      \
439          template <class T> void init(T) const { defaultInit(); }                                 \
440     public:                                                                                       \
441          void init() const { init(0); }
442 #
443 # //-///////////////////////////////////////////////////////////////////////////////////////////////
444 # // SENF_PARSER_REQUIRE_VAR
445 #
446 # define SENF_PARSER_REQUIRE_VAR(description) \
447       BOOST_PP_CAT(SENF_PARSER_REQUIRE_VAR_, SENF_PARSER_TYPE)(description)
448 #
449 # define SENF_PARSER_REQUIRE_VAR_var(description)
450 #
451 # define SENF_PARSER_REQUIRE_VAR_fix(description)                                                 \
452       typedef BOOST_PP_CAT( PARSER_ERROR__,                                                       \
453                             BOOST_PP_CAT(description, _not_allowed_in_fixed_parser) )             \
454           BOOST_PP_CAT(errsym_, __LINE__);
455 #
456 # //-///////////////////////////////////////////////////////////////////////////////////////////////
457 # // SENF_PARSER_COLLECTION_I
458 #
459 # ifndef DOXYGEN
460 #
461   namespace senf { namespace detail { namespace auxtag {
462       struct none {}; } } }
463   namespace senf { namespace detail { namespace auxtag {
464       struct bytes {}; } } }
465   namespace senf { namespace detail { namespace auxtag {
466       template <class Transform, class Tag>
467       struct transform {}; } } }
468   namespace senf { namespace detail { namespace auxtag {
469       struct packetSize {}; } } }
470 #
471 # endif
472 #
473 # // Each tag is implemented by defining the following macros. If the Tag is <name>(<args>):
474 # //   SENF_PARSER_COLLECTION_TAG_GOBBLE__<name>(<args>)
475 # //       gobble the tag, that is expand to nothing
476 # //   SENF_PARSER_COLLECTION_TAG__<name>(<args>)
477 # //       return an intermediate tag. This tag will be used with the next macro to get the aux tag
478 # //       this indirection is needed since the tag may include templates with more than one
479 # //       argument which cannot be passed through macros ... Ugh ...
480 # //   SENF_PARSER_COLLECTION_TAG_EXPAND__<tag>(<tag args>)
481 # //       expand to the real tag type
482 # //   SENF_PARSER_COLLECTION_TAG_GETAUX__<name>(<args>)
483 # //       return the real aux field. More specifically, this is the aux argument to the aux expand
484 # //       macro
485 # //   SENF_PARSER_COLLECTION_TAG_AUXTYPE__<name>(<args>)
486 # //       return an identifier selecting the aux type macro to use. If the expansion of this macro
487 # //       is <auxtag>, the macro will be called SENF_PARSER_COLLECTION_TAG_AUXDEF__<auxtag>
488 # //   SENF_PARSER_COLLECTION_TAG_AUXDEF__<auxtag>(<name>,<auxarg>)
489 # //       this command must declare the typedef <fieldname>_aux_type to the base aux policy
490 #
491 # define SENF_PARSER_COLLECTION_TAG_GOBBLE__bytes(x)
492 # define SENF_PARSER_COLLECTION_TAG__bytes(x) bytes()
493 # define SENF_PARSER_COLLECTION_TAG_EXPAND__bytes() senf::detail::auxtag::bytes
494 # define SENF_PARSER_COLLECTION_TAG_GETAUX__bytes(x) x
495 # define SENF_PARSER_COLLECTION_TAG_AUXTYPE__bytes(x) auxField
496 #
497 # define SENF_PARSER_COLLECTION_TAG_GOBBLE__transform(x,y)
498 # define SENF_PARSER_COLLECTION_TAG__transform(x,y) \
499       transform(x, SENF_PARSER_COLLECTION_TAG_RECURS1(y))
500 # define SENF_PARSER_COLLECTION_TAG_EXPAND__transform(x,y)                                        \
501       senf::detail::auxtag::transform<                                                            \
502           x,                                                                                      \
503           SENF_CAT_RECURS1(SENF_PARSER_COLLECTION_TAG_EXPAND__, y)>
504 # define SENF_PARSER_COLLECTION_TAG_GETAUX__transform(x,y) \
505       SENF_PARSER_COLLECTION_TAG_GETAUX_RECURS1(y)
506 # define SENF_PARSER_COLLECTION_TAG_AUXTYPE__transform(x,y) \
507       SENF_PARSER_COLLECTION_TAG_AUXTYPE_RECURS1(y)
508 #
509 # define SENF_PARSER_COLLECTION_TAG_GOBBLE__packetSize()
510 # define SENF_PARSER_COLLECTION_TAG__packetSize() packetSize()
511 # define SENF_PARSER_COLLECTION_TAG_EXPAND__packetSize() senf::detail::auxtag::bytes
512 # define SENF_PARSER_COLLECTION_TAG_GETAUX__packetSize() _
513 # define SENF_PARSER_COLLECTION_TAG_AUXTYPE__packetSize() packetSize
514 #
515 # define SENF_PARSER_COLLECTION_TAG_EXPAND__none() senf::detail::auxtag::none
516 #
517 # define SENF_PARSER_COLLECTION_TAG_RECURS1(aux)                                                  \
518       BOOST_PP_IF(                                                                                \
519           SENF_PARSER_COLLECTION_HAS_KEYWORD(aux),                                                \
520           BOOST_PP_CAT(SENF_PARSER_COLLECTION_TAG__, aux),                                        \
521           none() )
522 #
523 # define SENF_PARSER_COLLECTION_TAG_GETAUX_RECURS1(aux)                                           \
524       BOOST_PP_IF(                                                                                \
525           SENF_PARSER_COLLECTION_HAS_KEYWORD(aux),                                                \
526           BOOST_PP_CAT(SENF_PARSER_COLLECTION_TAG_GETAUX__, aux),                                 \
527           aux)
528 #
529 # define SENF_PARSER_COLLECTION_TAG_AUXTYPE_RECURS1(aux)                                          \
530       BOOST_PP_IF(                                                                                \
531           SENF_PARSER_COLLECTION_HAS_KEYWORD(aux),                                                \
532           BOOST_PP_CAT(SENF_PARSER_COLLECTION_TAG_AUXTYPE__, aux),                                \
533           auxField)
534 #
535 # define SENF_PARSER_COLLECTION_HAS_KEYWORD(x)                                                    \
536       BOOST_PP_IS_EMPTY( SENF_CAT_RECURS1(SENF_PARSER_COLLECTION_TAG_GOBBLE__, x) )
537 #
538 # define SENF_PARSER_COLLECTION_GETAUX(aux)                                                       \
539       BOOST_PP_IF( SENF_PARSER_COLLECTION_HAS_KEYWORD(aux),                                       \
540                    SENF_CAT_RECURS2(SENF_PARSER_COLLECTION_TAG_GETAUX__, aux),                    \
541                    aux )
542
543 # define SENF_PARSER_COLLECTION_I(access, name, aux, traits)                                      \
544       BOOST_PP_EXPAND(                                                                            \
545           SENF_PARSER_COLLECTION_II                                                               \
546               BOOST_PP_IF(                                                                        \
547                   SENF_PARSER_COLLECTION_HAS_KEYWORD(aux),                                        \
548                   ( access,                                                                       \
549                     name,                                                                         \
550                     SENF_CAT_RECURS2(SENF_PARSER_COLLECTION_TAG_AUXTYPE__, aux),                  \
551                     SENF_CAT_RECURS2(SENF_PARSER_COLLECTION_TAG_GETAUX__, aux),                   \
552                     SENF_CAT_RECURS2(SENF_PARSER_COLLECTION_TAG__, aux),                          \
553                     traits ),                                                                     \
554                   ( access,                                                                       \
555                     name,                                                                         \
556                     auxField,                                                                     \
557                     aux,                                                                          \
558                     none(),                                                                       \
559                     traits ) ))
560 #
561 # define SENF_PARSER_COLLECTION_II(access, name, auxtype, aux, tag, traits)                       \
562       private:                                                                                    \
563           BOOST_PP_CAT(SENF_PARSER_COLLECTION_TAG_AUXDEF__, auxtype)(name, aux)                   \
564           typedef traits::parser<                                                                 \
565               BOOST_PP_CAT(name,_aux_policy),                                                     \
566               BOOST_PP_CAT(SENF_PARSER_COLLECTION_TAG_EXPAND__, tag)                              \
567               >::type BOOST_PP_CAT(name, _collection_t);                                          \
568       access:                                                                                     \
569           SENF_PARSER_FIELD_SETUP_I( name,                                                        \
570                                      BOOST_PP_CAT(name, _collection_t),                           \
571                                      SENF_PARSER_TYPE,                                            \
572                                      rw,                                                          \
573                                      access )                                                     \
574           BOOST_PP_CAT(SENF_PARSER_COLLECTION_TAG_VAL__, auxtype)(name, aux, access)              \
575       public:
576 #
577 # define SENF_PARSER_COLLECTION_TAG_AUXDEF__auxField(name, aux)                                   \
578           BOOST_PP_CAT(SENF_PARSER_COLLECTION_AUXTYPE_, SENF_PARSER_TYPE)(name, aux)              \
579           typedef BOOST_PP_CAT(SENF_PARSER_COLLECTION_AUX_I_, SENF_PARSER_TYPE)(name, aux)        \
580               BOOST_PP_CAT(name,_aux_policy);
581 #
582 # define SENF_PARSER_COLLECTION_AUXTYPE_var(name, aux)                                            \
583       static bool const BOOST_PP_CAT(name, _aux_fixed) =                                          \
584           (SENF_MPL_SLOT_GET(group) - BOOST_PP_CAT(aux, _group) == 0);
585 #
586 # define SENF_PARSER_COLLECTION_AUXTYPE_fix(name, aux)
587 #
588 # ifndef DOXYGEN
589 #
590   namespace senf { namespace detail {
591       template <class Parser> struct DynamicAuxParserPolicy;
592       template <class Parser, unsigned offset> struct FixedAuxParserPolicy;
593       template <class Parser, unsigned fixedOffset, bool fixedDelta>
594       struct ParserAuxPolicySelect
595       { typedef senf::detail::DynamicAuxParserPolicy<Parser> type; };
596       template <class Parser, unsigned fixedOffset>
597       struct ParserAuxPolicySelect<Parser, fixedOffset, true>
598       { typedef senf::detail::FixedAuxParserPolicy<Parser, fixedOffset> type; };
599   }};
600 #
601 # endif
602 #
603 # define SENF_PARSER_COLLECTION_AUX_I_var(name, aux)                                              \
604       senf::detail::ParserAuxPolicySelect< BOOST_PP_CAT(aux, _t),                                 \
605                                            SENF_PARSER_CURRENT_FIXED_OFFSET()                     \
606                                                - SENF_PARSER_FIXED_OFFSET(aux),                   \
607                                            BOOST_PP_CAT(name, _aux_fixed) >::type
608 #
609 # define SENF_PARSER_COLLECTION_AUX_I_fix(name, aux)                                              \
610       senf::detail::FixedAuxParserPolicy< BOOST_PP_CAT(aux, _t),                                  \
611                                           SENF_PARSER_CURRENT_FIXED_OFFSET()                      \
612                                               - SENF_PARSER_FIXED_OFFSET(aux) >
613 #
614 # define SENF_PARSER_COLLECTION_TAG_AUXDEF__packetSize(name, aux)                                 \
615           typedef senf::detail::PacketSizeAuxParserPolicy BOOST_PP_CAT(name, _aux_policy);
616 #
617 # define SENF_PARSER_COLLECTION_TAG_VAL__auxField(name, aux, access)                              \
618           BOOST_PP_CAT(SENF_PARSER_COLLECTION_VAL_, SENF_PARSER_TYPE)(name, aux, access)
619 #
620 # define SENF_PARSER_COLLECTION_VAL_var(name,aux,access)                                          \
621       private:                                                                                    \
622           template <class T> T BOOST_PP_CAT(name, _dispatch)(boost::true_type) const              \
623           { return parse<T>( SENF_PARSER_OFFSET(name) ); }                                        \
624           template <class T> T BOOST_PP_CAT(name, _dispatch)(boost::false_type) const             \
625           { return parse<T>( BOOST_PP_CAT(aux,_)(), SENF_PARSER_OFFSET(name) ); }                 \
626           BOOST_PP_CAT(name, _t) BOOST_PP_CAT(name, _)() const                                    \
627           { return BOOST_PP_CAT(name, _dispatch) <BOOST_PP_CAT(name, _t)>(                        \
628                   boost::integral_constant<bool, BOOST_PP_CAT(name, _aux_fixed)>()); }            \
629       access:                                                                                     \
630           BOOST_PP_CAT(name, _t) name() const                                                     \
631           { return BOOST_PP_CAT(name, _)(); }
632 #
633 # define SENF_PARSER_COLLECTION_VAL_fix(name,aux,access)                                          \
634       private:                                                                                    \
635           BOOST_PP_CAT(name, _t) BOOST_PP_CAT(name, _)() const                                    \
636           { return parse<BOOST_PP_CAT(name, _t)>( SENF_PARSER_OFFSET(name) ); }                   \
637       access:                                                                                     \
638           BOOST_PP_CAT(name, _t) name() const                                                     \
639           { return BOOST_PP_CAT(name, _)(); }
640 #
641 # define SENF_PARSER_COLLECTION_TAG_VAL__packetSize(name, aux, access)                            \
642       private:                                                                                    \
643           BOOST_PP_CAT(name, _t) BOOST_PP_CAT(name, _)() const                                    \
644           { return parse<BOOST_PP_CAT(name, _t)>( SENF_PARSER_OFFSET(name) ); }                   \
645       access:                                                                                     \
646           BOOST_PP_CAT(name, _t) name() const                                                     \
647           { return BOOST_PP_CAT(name, _)(); }
648 #
649 # //-///////////////////////////////////////////////////////////////////////////////////////////////
650 # endif
651 #
652 #
653 # // Local Variables:
654 # // mode: c++
655 # // fill-column: 100
656 # // c-file-style: "senf"
657 # // indent-tabs-mode: nil
658 # // ispell-local-dictionary: "american"
659 # // compile-command: "scons -u test"
660 # // End: