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