cdf8f7447099989448bedd56947c5c2d6789c544
[senf.git] / 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/mpl.hh"
34 #
35 # ////////////////////////////////ih.p///////////////////////////////////////
36 #
37 # ///////////////////////////////////////////////////////////////////////////
38 # // SENF_PARSER_INITIALIZE
39 #
40 # define SENF_PARSER_INITIALIZE  BOOST_PP_CAT( SENF_PARSER_INITIALIZE_ , SENF_PARSER_TYPE )
41 #
42 # define SENF_PARSER_INITIALIZE_fix()                                                             \
43     private:                                                                                      \
44         SENF_MPL_SLOT_DEF_ZERO(index);                                                            \
45         SENF_MPL_SLOT_DEF_ZERO(offset);                                                           \
46         SENF_MPL_SLOT_DEF_ZERO(bit);                                                              \
47         SENF_MPL_SLOT_DEF_ZERO(bitfield_size);                                                    \
48         void init_chain(senf::mpl::rv<0>*) const {}                                               \
49     public:
50 #
51 # define SENF_PARSER_INITIALIZE_var()                                                             \
52     private:                                                                                      \
53         SENF_MPL_SLOT_DEF_ZERO(index);                                                            \
54         SENF_MPL_SLOT_DEF_ZERO(init_bytes);                                                       \
55         SENF_MPL_SLOT_DEF_ZERO(bit);                                                              \
56         SENF_MPL_SLOT_DEF_ZERO(bitfield_size);                                                    \
57         SENF_MPL_SLOT_DEF_ZERO(group);                                                            \
58         void init_chain(senf::mpl::rv<0>*) const {}                                               \
59         size_type field_offset_(senf::mpl::rv<0>*) const { return 0; }                            \
60     public:
61 #
62 # ///////////////////////////////////////////////////////////////////////////
63 # // SENF_PARSER_INHERIT_*
64 #
65 # define SENF_PARSER_INHERIT_var(name)                                                            \
66         typedef name parser_base_type;                                                            \
67     private:                                                                                      \
68         SENF_MPL_SLOT_SET(index, 1);                                                              \
69         SENF_MPL_SLOT_SET(init_bytes, senf::init_bytes<name>::value);                             \
70         size_type field_offset_(senf::mpl::rv<1>*) const {                                        \
71             return senf::bytes( *static_cast<name const*>(this) );                                \
72         }                                                                                         \
73         void init_chain(senf::mpl::rv<1>*) const {                                                \
74             name::init();                                                                         \
75         }                                                                                         \
76     public:
77 #
78 # define SENF_PARSER_INHERIT_fix(name)                                                            \
79         typedef name parser_base_type;                                                            \
80     private:                                                                                      \
81         SENF_MPL_SLOT_SET(offset, name::fixed_bytes);                                             \
82         SENF_MPL_SLOT_SET(index, 1);                                                              \
83         void init_chain(senf::mpl::rv<1>*) const {                                                \
84             name::init();                                                                         \
85         }                                                                                         \
86     public:
87 #
88 # ///////////////////////////////////////////////////////////////////////////
89 # // SENF_PARSER_FIELD*
90 # // SENF_PARSER_P_FIELD_*
91 #
92 # define SENF_PARSER_FIELD_var(name, type)    SENF_PARSER_FIELD_I(name, type, var, rw, public)
93 # define SENF_PARSER_FIELD_RO_var(name, type) SENF_PARSER_FIELD_I(name, type, var, ro, public)
94 # define SENF_PARSER_FIELD_fix(name, type)    SENF_PARSER_FIELD_I(name, type, fix, rw, public)
95 # define SENF_PARSER_FIELD_RO_fix(name, type) SENF_PARSER_FIELD_I(name, type, fix, ro, public)
96 #
97 # define SENF_PARSER_P_FIELD_var(name, type)    SENF_PARSER_FIELD_I(name, type, var, rw, private)
98 # define SENF_PARSER_P_FIELD_fix(name, type)    SENF_PARSER_FIELD_I(name, type, fix, rw, private)
99 #
100 # define SENF_PARSER_FIELD_I(name, type, ofstype, rwtype, access)                                 \
101     access:                                                                                       \
102         SENF_PARSER_FIELD_SETUP_I(name, type, ofstype, rwtype, access)                            \
103         BOOST_PP_CAT(SENF_PARSER_I_FIELD_VAL_, rwtype) (name, type, access)                       \
104     public:
105 #
106 # define SENF_PARSER_FIELD_SETUP_I(name, type, ofstype, rwtype, access)                           \
107         SENF_PARSER_I_BITFIELD_RESET()                                                            \
108         SENF_PARSER_I_FIELD_INTRO(name, type, access)                                             \
109         BOOST_PP_CAT(SENF_PARSER_I_FIELD_INIT_, rwtype) (name, type, access)                      \
110         BOOST_PP_CAT(SENF_PARSER_I_FIELD_OFS_, ofstype) (name, type, access)                      \
111         BOOST_PP_CAT(SENF_PARSER_I_ADVANCE_OFS_, ofstype) (                                       \
112             name, type,                                                                           \
113             BOOST_PP_CAT(SENF_PARSER_I_SIZE_, ofstype) (name, type),                              \
114             BOOST_PP_CAT(SENF_PARSER_I_INITBYTES_, ofstype) (name, type),                         \
115             BOOST_PP_CAT(SENF_PARSER_I_ISVAR_, ofstype) (name, type),                             \
116             access )
117 #
118 # ////////////////////////////////////////
119 # // SENF_PARSER_I_FIELD_INTRO
120 #
121 # define SENF_PARSER_I_FIELD_INTRO(name, type, access)                                            \
122         typedef type BOOST_PP_CAT(name, _t);                                                      \
123         static size_type const BOOST_PP_CAT(name,_index) = SENF_MPL_SLOT_GET(index)+1;            \
124     private:                                                                                      \
125         SENF_MPL_SLOT_SET(index, BOOST_PP_CAT(name,_index));                                      \
126     access:
127 #
128 # ////////////////////////////////////////
129 # // SENF_PARSER_I_FIELD_INIT_*
130 #
131 # define SENF_PARSER_I_FIELD_INIT_rw(name, type, access)                                          \
132     private:                                                                                      \
133         void init_chain(senf::mpl::rv<BOOST_PP_CAT(name,_index)>*) const {                        \
134             init_chain(static_cast<senf::mpl::rv<BOOST_PP_CAT(name,_index)-1>*>(0));              \
135             name().init();                                                                        \
136         }                                                                                         \
137     access:
138 #
139 # define SENF_PARSER_I_FIELD_INIT_ro(name, type, access)                                          \
140     private:                                                                                      \
141         void init_chain(senf::mpl::rv<BOOST_PP_CAT(name,_index)>*) const {                        \
142             init_chain(static_cast<senf::mpl::rv<BOOST_PP_CAT(name,_index)-1>*>(0));              \
143         }                                                                                         \
144     access:
145 #
146 # ////////////////////////////////////////
147 # // SENF_PARSER_I_FIELD_OFS_*
148 #
149 # define SENF_PARSER_I_FIELD_OFS_var(name, type, access)                                          \
150         size_type BOOST_PP_CAT(name,_offset)() const {                                            \
151             return field_offset_(static_cast<senf::mpl::rv<BOOST_PP_CAT(name,_index)-1>*>(0));    \
152         }                                                                                         \
153         static size_type const BOOST_PP_CAT(name, _init_bytes) =                                  \
154             SENF_MPL_SLOT_GET(init_bytes);
155 #
156 # define SENF_PARSER_I_FIELD_OFS_fix(name, type, access)                                          \
157         static size_type const BOOST_PP_CAT(name, _offset) =                                      \
158             SENF_MPL_SLOT_GET(offset);
159 #
160 # ////////////////////////////////////////
161 # // SENF_PARSER_I_ADVANCE_OFS_*
162 #
163 # define SENF_PARSER_I_SIZE_var(name, type) senf::bytes(BOOST_PP_CAT(name, _)())
164 # define SENF_PARSER_I_INITBYTES_var(name, type) senf::init_bytes<type>::value
165 #
166 # define SENF_PARSER_I_SIZE_fix(name, type) type::fixed_bytes
167 # define SENF_PARSER_I_INITBYTES_fix(name, type) void
168 #
169 # define SENF_PARSER_I_ISVAR_fix(name, type) 0
170 # define SENF_PARSER_I_ISVAR_var(name, type) (senf::is_fixed<type>::value?0:1)
171 #
172 # define SENF_PARSER_I_ADVANCE_OFS_var(name, type, size, isize, isvar, access)                    \
173         size_type BOOST_PP_CAT(name, _next_offset)() const {                                      \
174             return BOOST_PP_CAT(name,_offset)() + size;                                           \
175         }                                                                                         \
176         static size_type const BOOST_PP_CAT(name, _next_init_bytes) =                             \
177             BOOST_PP_CAT(name, _init_bytes) + isize;                                              \
178     private:                                                                                      \
179         size_type field_offset_(senf::mpl::rv<BOOST_PP_CAT(name,_index)>*) const {                \
180             return BOOST_PP_CAT(name, _next_offset)();                                            \
181         }                                                                                         \
182         SENF_MPL_SLOT_SET(init_bytes, BOOST_PP_CAT(name,_next_init_bytes));                       \
183         static size_type const BOOST_PP_CAT(name, _group) = SENF_MPL_SLOT_GET(group) + isvar;     \
184         SENF_MPL_SLOT_SET(group, BOOST_PP_CAT(name, _group));                                     \
185     access:
186 #
187 # define SENF_PARSER_I_ADVANCE_OFS_fix(name, type, size, isize, isvar, access)                    \
188         static size_type const BOOST_PP_CAT(name, _next_offset) =                                 \
189             BOOST_PP_CAT(name, _offset) + size;                                                   \
190     private:                                                                                      \
191         SENF_MPL_SLOT_SET(offset, BOOST_PP_CAT(name, _next_offset));                              \
192     access:
193 #
194 # ////////////////////////////////////////
195 # // SENF_PARSER_I_FIELD_VAL_*
196 #
197 # define SENF_PARSER_I_FIELD_VAL_rw(name, type, access)                                           \
198     private:                                                                                      \
199         BOOST_PP_CAT(name, _t) BOOST_PP_CAT(name, _)() const {                                    \
200             return parse<type>( SENF_PARSER_OFFSET(name) );                                       \
201         }                                                                                         \
202     access:                                                                                       \
203         BOOST_PP_CAT(name, _t) name() const {                                                     \
204             return BOOST_PP_CAT(name,_)();                                                        \
205         }
206 #
207 # define SENF_PARSER_I_FIELD_VAL_ro(name, type, access)                                           \
208     private:                                                                                      \
209         BOOST_PP_CAT(name, _t) BOOST_PP_CAT(name, _)() const {                                    \
210             return parse<type>( SENF_PARSER_OFFSET(name) );                                       \
211         }                                                                                         \
212     access:                                                                                       \
213         BOOST_PP_CAT(name, _t)::value_type name() const {                                         \
214             return BOOST_PP_CAT(name,_)();                                                        \
215         }
216 #
217 # ///////////////////////////////////////////////////////////////////////////
218 # // SENF_PARSER_CUSTOM_FIELD_*
219 #
220 # define SENF_PARSER_CUSTOM_FIELD_var(name, type, size, isize)                                    \
221       SENF_PARSER_CUSTOM_FIELD_I(name, type, size, isize, var)
222 # define SENF_PARSER_CUSTOM_FIELD_fix(name, type, size)                                           \
223       SENF_PARSER_CUSTOM_FIELD_I(name, type, size, size, fix)
224 #
225 # define SENF_PARSER_CUSTOM_FIELD_I(name, type, size, isize, ofstype)                             \
226         SENF_PARSER_I_BITFIELD_RESET()                                                            \
227         SENF_PARSER_I_FIELD_INTRO(name, type, public)                                             \
228         SENF_PARSER_I_FIELD_INIT_ro(name, type, public)                                           \
229         BOOST_PP_CAT(SENF_PARSER_I_FIELD_OFS_, ofstype) (name, type, public)                      \
230         BOOST_PP_CAT(SENF_PARSER_I_ADVANCE_OFS_, ofstype) (name, type, size, isize, 1, public)    \
231         BOOST_PP_CAT(name, _t) name() const
232 #
233 # ///////////////////////////////////////////////////////////////////////////
234 # // SENF_PARSER_BITFIELD_*
235 # // SENF_PARSER_P_BITFIELD_*
236 #
237 # define SENF_PARSER_BITFIELD_var(name, bits, type)                                               \
238       SENF_PARSER_BITFIELD_I(name, bits, type, var, rw, public)
239 # define SENF_PARSER_BITFIELD_RO_var(name, bits, type)                                            \
240       SENF_PARSER_BITFIELD_I(name, bits, type, var, ro, public)
241 # define SENF_PARSER_BITFIELD_fix(name, bits, type)                                               \
242       SENF_PARSER_BITFIELD_I(name, bits, type, fix, rw, public)
243 # define SENF_PARSER_BITFIELD_RO_fix(name, bits, type)                                            \
244       SENF_PARSER_BITFIELD_I(name, bits, type, fix, ro, public)
245 #
246 # define SENF_PARSER_P_BITFIELD_var(name, bits, type)                                             \
247       SENF_PARSER_BITFIELD_I(name, bits, type, var, rw, private)
248 # define SENF_PARSER_P_BITFIELD_fix(name, bits, type)                                             \
249       SENF_PARSER_BITFIELD_I(name, bits, type, fix, rw, private)
250 #
251 # ////////////////////////////////////////
252 # // SENF_PARSER_BITFIELD_I
253 #
254 # define SENF_PARSER_BITFIELD_TYPE_signed(start, bits)   senf::IntFieldParser<start, start+bits>
255 # define SENF_PARSER_BITFIELD_TYPE_unsigned(start, bits) senf::UIntFieldParser<start, start+bits>
256 # define SENF_PARSER_BITFIELD_TYPE_bool(start, bits)     senf::FlagParser<start>
257 #
258 # define SENF_PARSER_BITFIELD_I(name, bits, type, ofstype, rwtype, access)                        \
259     access:                                                                                       \
260         static size_type const BOOST_PP_CAT(name, _bit) = SENF_MPL_SLOT_GET(bit);                 \
261     private:                                                                                      \
262         SENF_MPL_SLOT_SET(bit, BOOST_PP_CAT(name, _bit) + bits);                                  \
263         typedef BOOST_PP_CAT(SENF_PARSER_BITFIELD_TYPE_, type)( BOOST_PP_CAT(name, _bit), bits )  \
264              BOOST_PP_CAT(name,_bit_t );                                                          \
265     access:                                                                                       \
266         SENF_PARSER_BITFIELD_II( name, bits, BOOST_PP_CAT(name, _bit_t), ofstype, rwtype, access) \
267     public:
268 #
269 # define SENF_PARSER_BITFIELD_II(name, bits, type, ofstype, rwtype, access)                       \
270          SENF_PARSER_I_FIELD_INTRO(name, type, access)                                            \
271          SENF_PARSER_I_FIELD_INIT_ro(name, type, access)                                          \
272          BOOST_PP_CAT(SENF_PARSER_I_BITFIELD_OFS_, ofstype) (name, type, access)                  \
273          BOOST_PP_CAT(SENF_PARSER_I_ADVANCE_OFS_, ofstype) (                                      \
274              name, type,                                                                          \
275              BOOST_PP_CAT(name, _t)::fixed_bytes, BOOST_PP_CAT(name, _t)::fixed_bytes,            \
276              0,                                                                                   \
277              access)                                                                              \
278     private:                                                                                      \
279          SENF_MPL_SLOT_SET(bitfield_size, BOOST_PP_CAT(name, _t)::fixed_bytes);                   \
280     access:                                                                                       \
281          BOOST_PP_CAT(SENF_PARSER_I_FIELD_VAL_, rwtype) (name, type, access)                      \
282     public:
283 #
284 # ////////////////////////////////////////
285 # // SENF_PARSER_I_BITFIELD_OFS_*
286 #
287 # define SENF_PARSER_I_BITFIELD_OFS_var(name, type, access)                                       \
288         size_type BOOST_PP_CAT(name,_offset)() const {                                            \
289             return field_offset_(static_cast<senf::mpl::rv<BOOST_PP_CAT(name,_index)-1>*>(0))     \
290                 - SENF_MPL_SLOT_GET(bitfield_size);                                               \
291         }                                                                                         \
292         static size_type const BOOST_PP_CAT(name, _init_bytes) =                                  \
293             SENF_MPL_SLOT_GET(init_bytes) - SENF_MPL_SLOT_GET(bitfield_size);
294 #
295 # define SENF_PARSER_I_BITFIELD_OFS_fix(name, type, access)                                       \
296         static size_type const BOOST_PP_CAT(name, _offset) =                                      \
297             SENF_MPL_SLOT_GET(offset) - SENF_MPL_SLOT_GET(bitfield_size);
298 #
299 # ////////////////////////////////////////
300 # // SENF_PARSER_I_BITFIELD_RESET
301 #
302 # define SENF_PARSER_I_BITFIELD_RESET()                                                           \
303         SENF_MPL_SLOT_SET(bit, 0);                                                                \
304         SENF_MPL_SLOT_SET(bitfield_size, 0);
305 #
306 # ///////////////////////////////////////////////////////////////////////////
307 # // SENF_PARSER_SKIP_*
308 #
309 # define SENF_PARSER_SKIP_var(bytes, ibytes)                                                      \
310       SENF_PARSER_I_SKIP( BOOST_PP_CAT(senf_anon_, __LINE__), bytes, ibytes, var)
311 #
312 # define SENF_PARSER_SKIP_fix(bytes)                                                              \
313       SENF_PARSER_I_SKIP( BOOST_PP_CAT(senf_anon_, __LINE__), bytes, bytes, fix)
314 #
315 # define SENF_PARSER_I_SKIP(name, bytes, ibytes, ofstype)                                         \
316     private:                                                                                      \
317           SENF_PARSER_I_BITFIELD_RESET()                                                          \
318           SENF_PARSER_I_FIELD_INTRO(name, void, private)                                          \
319           SENF_PARSER_I_FIELD_INIT_ro(name, void, private)                                        \
320           BOOST_PP_CAT(SENF_PARSER_I_FIELD_OFS_, ofstype) (name, type, access)                    \
321           BOOST_PP_CAT(SENF_PARSER_I_ADVANCE_OFS_, ofstype) (name, void, bytes, ibytes, 1,        \
322                                                              private)                             \
323     public:
324 #
325 # ///////////////////////////////////////////////////////////////////////////
326 # // SENF_PARSER_SKIP_BITS_*
327 #
328 # define SENF_PARSER_SKIP_BITS_var(bits) SENF_PARSER_I_SKIP_BITS(bits, var)
329 # define SENF_PARSER_SKIP_BITS_fix(bits) SENF_PARSER_I_SKIP_BITS(bits, fix)
330 #
331 # define SENF_PARSER_I_SKIP_BITS(bits, ofstype)                                                   \
332       private:                                                                                    \
333           SENF_MPL_SLOT_SET(bit, SENF_MPL_SLOT_GET(bit) + bits);                                  \
334       public:
335 #
336 # ///////////////////////////////////////////////////////////////////////////
337 # // SENF_PARSER_GOTO_*
338 #
339 # define SENF_PARSER_GOTO_var(name)                                                               \
340       SENF_PARSER_I_GOTO( BOOST_PP_CAT(senf_anon_, __LINE__),                                     \
341                           BOOST_PP_CAT(name, _offset)(),                                          \
342                           BOOST_PP_CAT(name, _init_bytes),                                        \
343                           var )
344 #
345 # define SENF_PARSER_GOTO_fix(name)                                                               \
346       SENF_PARSER_I_GOTO( BOOST_PP_CAT(senf_anon_, __LINE__),                                     \
347                           BOOST_PP_CAT(name, _offset),                                            \
348                           BOOST_PP_CAT(name, _offset),                                            \
349                           fix )
350 #
351 # define SENF_PARSER_GOTO_OFFSET_var(offset, isize)                                               \
352       SENF_PARSER_I_GOTO( BOOST_PP_CAT(senf_anon_, __LINE__), offset, isize, var )
353 #
354 # define SENF_PARSER_GOTO_OFFSET_fix(offset)                                                      \
355       SENF_PARSER_I_GOTO( BOOST_PP_CAT(senf_anon_, __LINE__), offset, offset, fix )
356 #
357 # define SENF_PARSER_I_GOTO(name, offset, initsize, ofstype)                                      \
358       private:                                                                                    \
359           SENF_PARSER_I_BITFIELD_RESET()                                                          \
360           SENF_PARSER_I_FIELD_INTRO(name, void, private)                                          \
361           SENF_PARSER_I_FIELD_INIT_ro(name, void, private)                                        \
362           BOOST_PP_CAT( SENF_PARSER_I_GOTO_SET_OFS_, ofstype ) (name, offset, initsize)           \
363       public:
364 #
365 # define SENF_PARSER_I_GOTO_SET_OFS_var(name, offs, initsize)                                     \
366           size_type field_offset_(senf::mpl::rv<BOOST_PP_CAT(name,_index)>*) const {              \
367               return offs;                                                                        \
368           }                                                                                       \
369           SENF_MPL_SLOT_SET(init_bytes, initsize);
370 #
371 # define SENF_PARSER_I_GOTO_SET_OFS_fix(name, offs, initsize)                                     \
372           SENF_MPL_SLOT_SET(offset, offs);
373 #
374 # ///////////////////////////////////////////////////////////////////////////
375 # // SENF_PARSER_LABEL_*
376 #
377 # define SENF_PARSER_LABEL_var(name) SENF_PARSER_I_LABEL( name, var, public )
378 # define SENF_PARSER_LABEL_fix(name) SENF_PARSER_I_LABEL( name, fix, public )
379 #
380 # define SENF_PARSER_I_LABEL(name, ofstype, access)                                               \
381       access:                                                                                     \
382           SENF_PARSER_I_BITFIELD_RESET()                                                          \
383           SENF_PARSER_I_FIELD_INTRO(name, void, access)                                           \
384           SENF_PARSER_I_FIELD_INIT_ro(name, void, access)                                         \
385           BOOST_PP_CAT(SENF_PARSER_I_FIELD_OFS_, ofstype) (name, type, access)                    \
386           BOOST_PP_CAT(SENF_PARSER_I_ADVANCE_OFS_, ofstype) (name, void, 0, 0, 0, access)         \
387       public:
388 #
389 # ///////////////////////////////////////////////////////////////////////////
390 # // SENF_PARSER_OFFSET_*
391 #
392 # define SENF_PARSER_OFFSET_fix(name) BOOST_PP_CAT(name, _offset)
393 # define SENF_PARSER_OFFSET_var(name) BOOST_PP_CAT(name, _offset)()
394 #
395 # ///////////////////////////////////////////////////////////////////////////
396 # // SENF_PARSER_FIXED_OFFSET_*
397 #
398 # define SENF_PARSER_FIXED_OFFSET_fix(name) BOOST_PP_CAT(name, _offset)
399 # define SENF_PARSER_FIXED_OFFSET_var(name) BOOST_PP_CAT(name, _init_bytes)
400 #
401 # ///////////////////////////////////////////////////////////////////////////
402 # // SENF_PARSER_CURRENT_FIXED_OFFSET_*
403 #
404 # define SENF_PARSER_CURRENT_FIXED_OFFSET_fix() SENF_MPL_SLOT_GET(offset)
405 # define SENF_PARSER_CURRENT_FIXED_OFFSET_var() SENF_MPL_SLOT_GET(init_bytes)
406 #
407 # ///////////////////////////////////////////////////////////////////////////
408 # // SENF_PARSER_FINALIZE_*
409 #
410 # define SENF_PARSER_FINALIZE_var(name)                                                           \
411     SENF_PARSER_FINALIZE_GENERIC(name)                                                            \
412     size_type bytes() const {                                                                     \
413         return field_offset_(static_cast<senf::mpl::rv<SENF_MPL_SLOT_GET(index)>*>(0));           \
414     }                                                                                             \
415     static size_type const init_bytes = SENF_MPL_SLOT_GET(init_bytes)
416 #
417 # define SENF_PARSER_FINALIZE_fix(name)                                                           \
418     SENF_PARSER_FINALIZE_GENERIC(name)                                                            \
419     static size_type const fixed_bytes = SENF_MPL_SLOT_GET(offset);
420 #
421 # define SENF_PARSER_FINALIZE_GENERIC(name)                                                       \
422          void defaultInit() const {                                                               \
423              init_chain(static_cast<senf::mpl::rv<SENF_MPL_SLOT_GET(index)>*>(0));                \
424          }                                                                                        \
425          name(data_iterator i, state_type s) : parser_base_type(i,s) {}                           \
426     private:                                                                                      \
427          template <class T> void init(T) const { defaultInit(); }                                 \
428     public:                                                                                       \
429          void init() const { init(0); }
430 #
431 # ///////////////////////////////////////////////////////////////////////////
432 # // SENF_PARSER_REQUIRE_VAR
433 #
434 # define SENF_PARSER_REQUIRE_VAR(description) \
435       BOOST_PP_CAT(SENF_PARSER_REQUIRE_VAR_, SENF_PARSER_TYPE)(description)
436 #
437 # define SENF_PARSER_REQUIRE_VAR_var(description)
438 #
439 # define SENF_PARSER_REQUIRE_VAR_fix(description)                                                 \
440       typedef BOOST_PP_CAT( PARSER_ERROR__,                                                       \
441                             BOOST_PP_CAT(description, _not_allowed_in_fixed_parser) )             \
442           BOOST_PP_CAT(errsym_, __LINE__);
443 #
444 # ///////////////////////////////////////////////////////////////////////////
445 # // SENF_PARSER_COLLECTION_I
446 #
447 # ifndef DOXYGEN
448 #
449   namespace senf { namespace detail { namespace auxtag {
450       struct none {}; } } }
451   namespace senf { namespace detail { namespace auxtag {
452       struct bytes {}; } } }
453   namespace senf { namespace detail { namespace auxtag {
454       template <class Transform, class Tag>
455       struct transform {}; } } }
456 #
457 # endif
458 #
459 # define SENF_PARSER_COLLECTION_TAG_GOBBLE__bytes(x)
460 # define SENF_PARSER_COLLECTION_TAG__bytes(x) bytes()
461 # define SENF_PARSER_COLLECTION_TAG_EXPAND__bytes() senf::detail::auxtag::bytes
462 # define SENF_PARSER_COLLECTION_TAG_GETAUX__bytes(x) x
463 #
464 # // No recursive call so we need some more of theese ... ARGH !!!
465 # define SENF_CAT_RECURS1(a, b) SENF_CAT_RECURS1_I(a,b)
466 # define SENF_CAT_RECURS1_I(a, b) a ## b
467 # define SENF_CAT_RECURS2(a, b) SENF_CAT_RECURS2_I(a,b)
468 # define SENF_CAT_RECURS2_I(a, b) a ## b
469 # define SENF_CAT_RECURS3(a, b) SENF_CAT_RECURS3_I(a,b)
470 # define SENF_CAT_RECURS3_I(a, b) a ## b
471 #
472 # define SENF_PARSER_COLLECTION_TAG_GOBBLE__transform(x,y)
473 # define SENF_PARSER_COLLECTION_TAG__transform(x,y) \
474       transform(x, SENF_PARSER_COLLECTION_TAG_RECURS1(y))
475 # define SENF_PARSER_COLLECTION_TAG_EXPAND__transform(x,y)                                        \
476       senf::detail::auxtag::transform<                                                            \
477           x,                                                                                      \
478           SENF_CAT_RECURS1(SENF_PARSER_COLLECTION_TAG_EXPAND__, y)>
479 # define SENF_PARSER_COLLECTION_TAG_GETAUX__transform(x,y) \
480       SENF_PARSER_COLLECTION_TAG_GETAUX_RECURS1(y)
481 #
482 # define SENF_PARSER_COLLECTION_TAG_EXPAND__none() senf::detail::auxtag::none
483 #
484 # define SENF_PARSER_COLLECTION_TAG_RECURS1(aux)                                                  \
485       BOOST_PP_IF(                                                                                \
486           SENF_PARSER_COLLECTION_HAS_KEYWORD(aux),                                                \
487           BOOST_PP_CAT(SENF_PARSER_COLLECTION_TAG__, aux),                                        \
488           none() )
489 #
490 # define SENF_PARSER_COLLECTION_TAG_GETAUX_RECURS1(aux)                                           \
491       BOOST_PP_IF(                                                                                \
492           SENF_PARSER_COLLECTION_HAS_KEYWORD(aux),                                                \
493           BOOST_PP_CAT(SENF_PARSER_COLLECTION_TAG_GETAUX__, aux),                                 \
494           aux)
495 #
496 # define SENF_PARSER_COLLECTION_HAS_KEYWORD(x)                                                    \
497       BOOST_PP_IS_EMPTY( SENF_CAT_RECURS1(SENF_PARSER_COLLECTION_TAG_GOBBLE__, x) )
498 #
499 # define SENF_PARSER_COLLECTION_GETAUX(aux)                                                       \
500       BOOST_PP_IF( SENF_PARSER_COLLECTION_HAS_KEYWORD(aux),                                       \
501                    SENF_CAT_RECURS2(SENF_PARSER_COLLECTION_TAG_GETAUX__, aux),                    \
502                    aux )
503
504 # define SENF_PARSER_COLLECTION_I(access, name, aux, traits)                                      \
505       BOOST_PP_EXPAND(                                                                            \
506           SENF_PARSER_COLLECTION_II                                                               \
507               BOOST_PP_IF(                                                                        \
508                   SENF_PARSER_COLLECTION_HAS_KEYWORD(aux),                                        \
509                   ( access,                                                                       \
510                     name,                                                                         \
511                     SENF_CAT_RECURS2(SENF_PARSER_COLLECTION_TAG_GETAUX__, aux),                   \
512                     SENF_CAT_RECURS2(SENF_PARSER_COLLECTION_TAG__, aux),                          \
513                     traits ),                                                                     \
514                   ( access,                                                                       \
515                     name,                                                                         \
516                     aux,                                                                          \
517                     none(),                                                                       \
518                     traits ) ))
519 #
520 # define SENF_PARSER_COLLECTION_II(access, name, aux, tag, traits)                                \
521       private:                                                                                    \
522           BOOST_PP_CAT(SENF_PARSER_COLLECTION_AUXTYPE_, SENF_PARSER_TYPE)(name, aux)              \
523           typedef BOOST_PP_CAT(SENF_PARSER_COLLECTION_AUX_I_, SENF_PARSER_TYPE)(name, aux)        \
524               BOOST_PP_CAT(name,_aux_policy);                                                     \
525           typedef traits::parser<                                                                 \
526               BOOST_PP_CAT(name,_aux_policy),                                                     \
527               BOOST_PP_CAT(SENF_PARSER_COLLECTION_TAG_EXPAND__, tag)                              \
528               >::type BOOST_PP_CAT(name, _collection_t);                                          \
529       access:                                                                                     \
530           SENF_PARSER_FIELD_SETUP_I( name,                                                        \
531                                      BOOST_PP_CAT(name, _collection_t),                           \
532                                      SENF_PARSER_TYPE,                                            \
533                                      rw,                                                          \
534                                      access )                                                     \
535           BOOST_PP_CAT(SENF_PARSER_COLLECTION_VAL_, SENF_PARSER_TYPE)(name, aux, access)          \
536       public:
537 #
538 # define SENF_PARSER_COLLECTION_AUXTYPE_var(name, aux)                                            \
539       static bool const BOOST_PP_CAT(name, _aux_fixed) =                                          \
540           (SENF_MPL_SLOT_GET(group) - BOOST_PP_CAT(aux, _group) == 0);
541 #
542 # define SENF_PARSER_COLLECTION_AUXTYPE_fix(name, aux)
543 #
544 # ifndef DOXYGEN
545 #
546   namespace senf { namespace detail {
547       template <class Parser> struct DynamicAuxParserPolicy;
548       template <class Parser, unsigned offset> struct FixedAuxParserPolicy;
549       template <class Parser, unsigned fixedOffset, bool fixedDelta>
550       struct ParserAuxPolicySelect
551       { typedef senf::detail::DynamicAuxParserPolicy<Parser> type; };
552       template <class Parser, unsigned fixedOffset>
553       struct ParserAuxPolicySelect<Parser, fixedOffset, true>
554       { typedef senf::detail::FixedAuxParserPolicy<Parser, fixedOffset> type; };
555   }};
556 #
557 # endif
558 #
559 # define SENF_PARSER_COLLECTION_AUX_I_var(name, aux)                                              \
560       senf::detail::ParserAuxPolicySelect< BOOST_PP_CAT(aux, _t),                                 \
561                                            SENF_PARSER_CURRENT_FIXED_OFFSET()                     \
562                                                - SENF_PARSER_FIXED_OFFSET(aux),                   \
563                                            BOOST_PP_CAT(name, _aux_fixed) >::type
564 #
565 # define SENF_PARSER_COLLECTION_AUX_I_fix(name, aux)                                              \
566       senf::detail::FixedAuxParserPolicy< BOOST_PP_CAT(aux, _t),                                  \
567                                           SENF_PARSER_CURRENT_FIXED_OFFSET()                      \
568                                               - SENF_PARSER_FIXED_OFFSET(aux) >
569 #
570 # define SENF_PARSER_COLLECTION_VAL_var(name,aux,access)                                          \
571       private:                                                                                    \
572           template <class T> T BOOST_PP_CAT(name, _dispatch)(boost::true_type) const              \
573           { return parse<T>( SENF_PARSER_OFFSET(name) ); }                                        \
574           template <class T> T BOOST_PP_CAT(name, _dispatch)(boost::false_type) const             \
575           { return parse<T>( BOOST_PP_CAT(aux,_)(), SENF_PARSER_OFFSET(name) ); }                                 \
576           BOOST_PP_CAT(name, _t) BOOST_PP_CAT(name, _)() const                                    \
577           { return BOOST_PP_CAT(name, _dispatch) <BOOST_PP_CAT(name, _t)>(                        \
578                   boost::integral_constant<bool, BOOST_PP_CAT(name, _aux_fixed)>()); }            \
579       access:                                                                                     \
580           BOOST_PP_CAT(name, _t) name() const                                                     \
581           { return BOOST_PP_CAT(name, _)(); }
582 #
583 # define SENF_PARSER_COLLECTION_VAL_fix(name,aux,access)                                          \
584       private:                                                                                    \
585           BOOST_PP_CAT(name, _t) BOOST_PP_CAT(name, _)() const                                    \
586           { return parse<BOOST_PP_CAT(name, _t)>( SENF_PARSER_OFFSET(name) ); }                   \
587       access:                                                                                     \
588           BOOST_PP_CAT(name, _t) name() const                                                     \
589           { return BOOST_PP_CAT(name, _)(); }
590 #
591 # ////////////////////////////////ih.e///////////////////////////////////////
592 # endif
593 #
594 #
595 # // Local Variables:
596 # // mode: c++
597 # // fill-column: 100
598 # // c-file-style: "senf"
599 # // indent-tabs-mode: nil
600 # // ispell-local-dictionary: "american"
601 # // compile-command: "scons -u test"
602 # // End: