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