2 // Copyright (c) 2020 Fraunhofer Institute for Applied Information Technology (FIT)
3 // Network Research Group (NET)
4 // Schloss Birlinghoven, 53754 Sankt Augustin, GERMANY
5 // Contact: support@wiback.org
7 // This file is part of the SENF code tree.
8 // It is licensed under the 3-clause BSD License (aka New BSD License).
9 // See LICENSE.txt in the top level directory for details or visit
10 // https://opensource.org/licenses/BSD-3-Clause
15 \brief ParseHelpers internal header */
17 # if !defined(IH_ParseHelpers_)
18 # define IH_ParseHelpers_ 1
21 # include <boost/preprocessor/cat.hpp>
22 # include <boost/preprocessor/if.hpp>
23 # include <boost/preprocessor/expand.hpp>
24 # include <boost/preprocessor/facilities/is_empty.hpp>
25 # include <boost/preprocessor/punctuation/comma.hpp>
26 # include <senf/Utils/preprocessor.hh>
27 # include <senf/Utils/mpl.hh>
29 # //-///////////////////////////////////////////////////////////////////////////////////////////////
31 # //-///////////////////////////////////////////////////////////////////////////////////////////////
32 # // SENF_PARSER_INITIALIZE
34 # define SENF_PARSER_INITIALIZE BOOST_PP_CAT( SENF_PARSER_INITIALIZE_ , SENF_PARSER_TYPE )
36 # define SENF_PARSER_INITIALIZE_fix() \
38 SENF_MPL_SLOT_DEF_ZERO(index); \
39 SENF_MPL_SLOT_DEF_ZERO(offset); \
40 SENF_MPL_SLOT_DEF_ZERO(bit); \
41 SENF_MPL_SLOT_DEF_ZERO(bitfield_size); \
42 void init_chain(senf::mpl::rv<0>*) const {} \
46 # define SENF_PARSER_INITIALIZE_var() \
48 SENF_MPL_SLOT_DEF_ZERO(index); \
49 SENF_MPL_SLOT_DEF_ZERO(init_bytes); \
50 SENF_MPL_SLOT_DEF_ZERO(bit); \
51 SENF_MPL_SLOT_DEF_ZERO(bitfield_size); \
52 SENF_MPL_SLOT_DEF_ZERO(group); \
53 void init_chain(senf::mpl::rv<0>*) const {} \
54 size_type field_offset_(senf::mpl::rv<0>*) const { return 0; } \
58 # //-///////////////////////////////////////////////////////////////////////////////////////////////
59 # // SENF_PARSER_INHERIT_*
61 # define SENF_PARSER_INHERIT_var(name) \
62 typedef name parser_base_type; \
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) ); \
69 void init_chain(senf::mpl::rv<1>*) const { \
74 # define SENF_PARSER_INHERIT_fix(name) \
75 typedef name parser_base_type; \
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 { \
84 # //-///////////////////////////////////////////////////////////////////////////////////////////////
85 # // SENF_PARSER_FIELD*
86 # // SENF_PARSER_P_FIELD_*
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)
93 # define SENF_PARSER_P_FIELD_var(name, type) SENF_PARSER_FIELD_I(name, type, var, rw, protected)
94 # define SENF_PARSER_P_FIELD_fix(name, type) SENF_PARSER_FIELD_I(name, type, fix, rw, protected)
96 # define SENF_PARSER_FIELD_I(name, type, ofstype, rwtype, 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) \
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) ( \
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), \
114 # //-///////////////////////////////////////////////////////////////////////////////////////////////
115 # // SENF_PARSER_I_FIELD_INTRO
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; \
121 SENF_MPL_SLOT_SET(index, BOOST_PP_CAT(name,_index)); \
124 # //-///////////////////////////////////////////////////////////////////////////////////////////////
125 # // SENF_PARSER_I_FIELD_INIT_*
127 # define SENF_PARSER_I_FIELD_INIT_rw(name, type, access) \
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>*>(nullptr)); \
135 # define SENF_PARSER_I_FIELD_INIT_ro(name, type, access) \
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>*>(nullptr)); \
142 # //-///////////////////////////////////////////////////////////////////////////////////////////////
143 # // SENF_PARSER_I_FIELD_OFS_*
145 # define SENF_PARSER_I_FIELD_OFS_var(name, type, access) \
147 size_type BOOST_PP_CAT(name,_offset)() const { \
148 return field_offset_( \
149 static_cast<senf::mpl::rv<BOOST_PP_CAT(name,_index)-1>*>(nullptr)); \
151 static size_type const BOOST_PP_CAT(name, _init_bytes) = \
152 SENF_MPL_SLOT_GET(init_bytes); \
155 # 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); \
161 # //-///////////////////////////////////////////////////////////////////////////////////////////////
162 # // SENF_PARSER_I_ADVANCE_OFS_*
164 # define SENF_PARSER_I_SIZE_var(name, type) senf::bytes(BOOST_PP_CAT(name, _)())
165 # define SENF_PARSER_I_INITBYTES_var(name, type) senf::init_bytes<type>::value
167 # define SENF_PARSER_I_SIZE_fix(name, type) type::fixed_bytes
168 # define SENF_PARSER_I_INITBYTES_fix(name, type) void
170 # define SENF_PARSER_I_ISVAR_fix(name, type) 0
171 # define SENF_PARSER_I_ISVAR_var(name, type) (senf::is_fixed<type>::value?0:1)
173 # define SENF_PARSER_I_ADVANCE_OFS_var(name, type, size, isize, isvar, access) \
174 size_type BOOST_PP_CAT(name, _next_offset)() const { \
175 return BOOST_PP_CAT(name,_offset)() + size; \
177 static size_type const BOOST_PP_CAT(name, _next_init_bytes) = \
178 BOOST_PP_CAT(name, _init_bytes) + isize; \
180 size_type field_offset_(senf::mpl::rv<BOOST_PP_CAT(name,_index)>*) const { \
181 return BOOST_PP_CAT(name, _next_offset)(); \
183 SENF_MPL_SLOT_SET(init_bytes, BOOST_PP_CAT(name,_next_init_bytes)); \
185 static size_type const BOOST_PP_CAT(name, _group) = SENF_MPL_SLOT_GET(group) + isvar; \
187 SENF_MPL_SLOT_SET(group, BOOST_PP_CAT(name, _group)); \
190 # define SENF_PARSER_I_ADVANCE_OFS_fix(name, type, size, isize, isvar, access) \
191 static size_type const BOOST_PP_CAT(name, _next_offset) = \
192 BOOST_PP_CAT(name, _offset) + size; \
194 SENF_MPL_SLOT_SET(offset, BOOST_PP_CAT(name, _next_offset)); \
197 # //-///////////////////////////////////////////////////////////////////////////////////////////////
198 # // SENF_PARSER_I_FIELD_VAL_*
200 # define SENF_PARSER_I_FIELD_VAL_rw(name, type, access) \
202 BOOST_PP_CAT(name, _t) BOOST_PP_CAT(name, _)() const { \
203 return parse<type>( SENF_PARSER_OFFSET(name) ); \
206 BOOST_PP_CAT(name, _t) name() const { \
207 return BOOST_PP_CAT(name,_)(); \
209 template <typename T> \
210 SelfProxy name(T const & v) const { \
211 if (senf::is_fixed<type>::value) \
214 protect(), name() << v; \
215 return SelfProxy(this); \
218 # define SENF_PARSER_I_FIELD_VAL_ro(name, type, access) \
220 BOOST_PP_CAT(name, _t) BOOST_PP_CAT(name, _)() const { \
221 return parse<type>( SENF_PARSER_OFFSET(name) ); \
224 typename BOOST_PP_CAT(name, _t)::value_type name() const { \
225 return BOOST_PP_CAT(name,_)(); \
228 # //-///////////////////////////////////////////////////////////////////////////////////////////////
229 # // SENF_PARSER_CUSTOM_FIELD_*
231 # define SENF_PARSER_CUSTOM_FIELD_var(name, type, size, isize) \
232 SENF_PARSER_CUSTOM_FIELD_I(name, type, size, isize, var)
233 # define SENF_PARSER_CUSTOM_FIELD_fix(name, type, size) \
234 SENF_PARSER_CUSTOM_FIELD_I(name, type, size, size, fix)
236 # define SENF_PARSER_CUSTOM_FIELD_I(name, type, size, isize, ofstype) \
237 SENF_PARSER_I_BITFIELD_RESET() \
238 SENF_PARSER_I_FIELD_INTRO(name, type, public) \
239 SENF_PARSER_I_FIELD_INIT_ro(name, type, public) \
240 BOOST_PP_CAT(SENF_PARSER_I_FIELD_OFS_, ofstype) (name, type, public) \
241 BOOST_PP_CAT(SENF_PARSER_I_ADVANCE_OFS_, ofstype) (name, type, size, isize, 1, public) \
242 BOOST_PP_CAT(name, _t) name() const
244 # //-///////////////////////////////////////////////////////////////////////////////////////////////
245 # // SENF_PARSER_BITFIELD_*
246 # // SENF_PARSER_P_BITFIELD_*
248 # define SENF_PARSER_BITFIELD_var(name, bits, type) \
249 SENF_PARSER_BITFIELD_I(name, bits, type, var, rw, public)
250 # define SENF_PARSER_BITFIELD_RO_var(name, bits, type) \
251 SENF_PARSER_BITFIELD_I(name, bits, type, var, ro, public)
252 # define SENF_PARSER_BITFIELD_fix(name, bits, type) \
253 SENF_PARSER_BITFIELD_I(name, bits, type, fix, rw, public)
254 # define SENF_PARSER_BITFIELD_RO_fix(name, bits, type) \
255 SENF_PARSER_BITFIELD_I(name, bits, type, fix, ro, public)
257 # define SENF_PARSER_P_BITFIELD_var(name, bits, type) \
258 SENF_PARSER_BITFIELD_I(name, bits, type, var, rw, protected)
259 # define SENF_PARSER_P_BITFIELD_fix(name, bits, type) \
260 SENF_PARSER_BITFIELD_I(name, bits, type, fix, rw, protected)
262 # //-///////////////////////////////////////////////////////////////////////////////////////////////
263 # // SENF_PARSER_BITFIELD_I
265 # define SENF_PARSER_BITFIELD_TYPE_signed(start, bits) senf::IntFieldParser<start, start+bits>
266 # define SENF_PARSER_BITFIELD_TYPE_unsigned(start, bits) senf::UIntFieldParser<start, start+bits>
267 # define SENF_PARSER_BITFIELD_TYPE_bool(start, bits) senf::FlagParser<start>
269 # define SENF_PARSER_BITFIELD_I(name, bits, type, ofstype, rwtype, access) \
271 static size_type const BOOST_PP_CAT(name, _bit) = SENF_MPL_SLOT_GET(bit); \
273 SENF_MPL_SLOT_SET(bit, BOOST_PP_CAT(name, _bit) + bits); \
274 typedef BOOST_PP_CAT(SENF_PARSER_BITFIELD_TYPE_, type)( BOOST_PP_CAT(name, _bit), bits ) \
275 BOOST_PP_CAT(name,_bit_t ); \
277 SENF_PARSER_BITFIELD_II( name, bits, BOOST_PP_CAT(name, _bit_t), ofstype, rwtype, access) \
280 # define SENF_PARSER_BITFIELD_II(name, bits, type, ofstype, rwtype, access) \
281 SENF_PARSER_I_FIELD_INTRO(name, type, access) \
282 SENF_PARSER_I_FIELD_INIT_ro(name, type, access) \
283 BOOST_PP_CAT(SENF_PARSER_I_BITFIELD_OFS_, ofstype) (name, type, access) \
284 BOOST_PP_CAT(SENF_PARSER_I_ADVANCE_OFS_, ofstype) ( \
286 BOOST_PP_CAT(name, _t)::fixed_bytes, BOOST_PP_CAT(name, _t)::fixed_bytes, \
290 SENF_MPL_SLOT_SET(bitfield_size, BOOST_PP_CAT(name, _t)::fixed_bytes); \
292 BOOST_PP_CAT(SENF_PARSER_I_FIELD_VAL_, rwtype) (name, type, access) \
295 # //-///////////////////////////////////////////////////////////////////////////////////////////////
296 # // SENF_PARSER_I_BITFIELD_OFS_*
298 # define SENF_PARSER_I_BITFIELD_OFS_var(name, type, access) \
299 size_type BOOST_PP_CAT(name,_offset)() const { \
300 return field_offset_( \
301 static_cast<senf::mpl::rv<BOOST_PP_CAT(name,_index)-1>*>(nullptr)) \
302 - SENF_MPL_SLOT_GET(bitfield_size); \
304 static size_type const BOOST_PP_CAT(name, _init_bytes) = \
305 SENF_MPL_SLOT_GET(init_bytes) - SENF_MPL_SLOT_GET(bitfield_size);
307 # define SENF_PARSER_I_BITFIELD_OFS_fix(name, type, access) \
308 static size_type const BOOST_PP_CAT(name, _offset) = \
309 SENF_MPL_SLOT_GET(offset) - SENF_MPL_SLOT_GET(bitfield_size);
311 # //-///////////////////////////////////////////////////////////////////////////////////////////////
312 # // SENF_PARSER_I_BITFIELD_RESET
314 # define SENF_PARSER_I_BITFIELD_RESET() \
315 SENF_MPL_SLOT_SET(bit, 0); \
316 SENF_MPL_SLOT_SET(bitfield_size, 0);
318 # //-///////////////////////////////////////////////////////////////////////////////////////////////
319 # // SENF_PARSER_SKIP_*
321 # define SENF_PARSER_SKIP_var(bytes, ibytes) \
322 SENF_PARSER_I_SKIP( BOOST_PP_CAT(senf_anon_, __LINE__), bytes, ibytes, var)
324 # define SENF_PARSER_SKIP_fix(bytes) \
325 SENF_PARSER_I_SKIP( BOOST_PP_CAT(senf_anon_, __LINE__), bytes, bytes, fix)
327 # define SENF_PARSER_I_SKIP(name, bytes, ibytes, ofstype) \
329 SENF_PARSER_I_BITFIELD_RESET() \
330 SENF_PARSER_I_FIELD_INTRO(name, void, private) \
331 SENF_PARSER_I_FIELD_INIT_ro(name, void, private) \
332 BOOST_PP_CAT(SENF_PARSER_I_FIELD_OFS_, ofstype) (name, type, access) \
333 BOOST_PP_CAT(SENF_PARSER_I_ADVANCE_OFS_, ofstype) (name, void, bytes, ibytes, 1, \
337 # //-///////////////////////////////////////////////////////////////////////////////////////////////
338 # // SENF_PARSER_SKIP_BITS_*
340 # define SENF_PARSER_SKIP_BITS_var(bits) SENF_PARSER_I_SKIP_BITS(bits, var)
341 # define SENF_PARSER_SKIP_BITS_fix(bits) SENF_PARSER_I_SKIP_BITS(bits, fix)
343 # define SENF_PARSER_I_SKIP_BITS(bits, ofstype) \
345 SENF_MPL_SLOT_SET(bit, SENF_MPL_SLOT_GET(bit) + bits); \
348 # //-///////////////////////////////////////////////////////////////////////////////////////////////
349 # // SENF_PARSER_GOTO_*
351 # define SENF_PARSER_GOTO_var(name) \
352 SENF_PARSER_I_GOTO( BOOST_PP_CAT(senf_anon_, __LINE__), \
353 BOOST_PP_CAT(name, _offset)(), \
354 BOOST_PP_CAT(name, _init_bytes), \
357 # define SENF_PARSER_GOTO_fix(name) \
358 SENF_PARSER_I_GOTO( BOOST_PP_CAT(senf_anon_, __LINE__), \
359 BOOST_PP_CAT(name, _offset), \
360 BOOST_PP_CAT(name, _offset), \
363 # define SENF_PARSER_GOTO_OFFSET_var(offset, isize) \
364 SENF_PARSER_I_GOTO( BOOST_PP_CAT(senf_anon_, __LINE__), offset, isize, var )
366 # define SENF_PARSER_GOTO_OFFSET_fix(offset) \
367 SENF_PARSER_I_GOTO( BOOST_PP_CAT(senf_anon_, __LINE__), offset, offset, fix )
369 # define SENF_PARSER_I_GOTO(name, offset, initsize, ofstype) \
371 SENF_PARSER_I_BITFIELD_RESET() \
372 SENF_PARSER_I_FIELD_INTRO(name, void, private) \
373 SENF_PARSER_I_FIELD_INIT_ro(name, void, private) \
374 BOOST_PP_CAT( SENF_PARSER_I_GOTO_SET_OFS_, ofstype ) (name, offset, initsize) \
377 # define SENF_PARSER_I_GOTO_SET_OFS_var(name, offs, initsize) \
378 size_type field_offset_(senf::mpl::rv<BOOST_PP_CAT(name,_index)>*) const { \
381 SENF_MPL_SLOT_SET(init_bytes, initsize);
383 # define SENF_PARSER_I_GOTO_SET_OFS_fix(name, offs, initsize) \
384 SENF_MPL_SLOT_SET(offset, offs);
386 # //-///////////////////////////////////////////////////////////////////////////////////////////////
387 # // SENF_PARSER_LABEL_*
389 # define SENF_PARSER_LABEL_var(name) SENF_PARSER_I_LABEL( name, var, public )
390 # define SENF_PARSER_LABEL_fix(name) SENF_PARSER_I_LABEL( name, fix, public )
392 # define SENF_PARSER_I_LABEL(name, ofstype, access) \
394 SENF_PARSER_I_BITFIELD_RESET() \
395 SENF_PARSER_I_FIELD_INTRO(name, void, access) \
396 SENF_PARSER_I_FIELD_INIT_ro(name, void, access) \
397 BOOST_PP_CAT(SENF_PARSER_I_FIELD_OFS_, ofstype) (name, type, access) \
398 BOOST_PP_CAT(SENF_PARSER_I_ADVANCE_OFS_, ofstype) (name, void, 0, 0, 0, access) \
401 # //-///////////////////////////////////////////////////////////////////////////////////////////////
402 # // SENF_PARSER_OFFSET_*
404 # define SENF_PARSER_OFFSET_fix(name) BOOST_PP_CAT(name, _offset)
405 # define SENF_PARSER_OFFSET_var(name) BOOST_PP_CAT(name, _offset)()
407 # //-///////////////////////////////////////////////////////////////////////////////////////////////
408 # // SENF_PARSER_FIXED_OFFSET_*
410 # define SENF_PARSER_FIXED_OFFSET_fix(name) BOOST_PP_CAT(name, _offset)
411 # define SENF_PARSER_FIXED_OFFSET_var(name) BOOST_PP_CAT(name, _init_bytes)
413 # //-///////////////////////////////////////////////////////////////////////////////////////////////
414 # // SENF_PARSER_CURRENT_FIXED_OFFSET_*
416 # define SENF_PARSER_CURRENT_FIXED_OFFSET_fix() SENF_MPL_SLOT_GET(offset)
417 # define SENF_PARSER_CURRENT_FIXED_OFFSET_var() SENF_MPL_SLOT_GET(init_bytes)
419 # //-///////////////////////////////////////////////////////////////////////////////////////////////
420 # // SENF_PARSER_FINALIZE_*
422 # define SENF_PARSER_FINALIZE_var(name) \
423 SENF_PARSER_FINALIZE_GENERIC(name) \
424 size_type bytes() const { \
425 return field_offset_(static_cast<senf::mpl::rv<SENF_MPL_SLOT_GET(index)>*>(nullptr));\
427 static size_type const init_bytes = SENF_MPL_SLOT_GET(init_bytes)
429 # define SENF_PARSER_FINALIZE_fix(name) \
430 SENF_PARSER_FINALIZE_GENERIC(name) \
431 static size_type const fixed_bytes = SENF_MPL_SLOT_GET(offset);
433 # define SENF_PARSER_FINALIZE_GENERIC(name) \
434 void defaultInit() const { \
435 init_chain(static_cast<senf::mpl::rv<SENF_MPL_SLOT_GET(index)>*>(nullptr)); \
437 name(data_iterator i, state_type s) : parser_base_type(i,s) {} \
439 template <class T> void init(T) const { defaultInit(); } \
441 void init() const { init(0); } \
443 SelfProxy(name const * p) : p_(p) {} \
444 name const * operator->() { return p_; } \
448 # //-///////////////////////////////////////////////////////////////////////////////////////////////
449 # // SENF_PARSER_REQUIRE_VAR
451 # define SENF_PARSER_REQUIRE_VAR(description) \
452 BOOST_PP_CAT(SENF_PARSER_REQUIRE_VAR_, SENF_PARSER_TYPE)(description)
454 # define SENF_PARSER_REQUIRE_VAR_var(description)
456 # define SENF_PARSER_REQUIRE_VAR_fix(description) \
457 typedef BOOST_PP_CAT( PARSER_ERROR__, \
458 BOOST_PP_CAT(description, _not_allowed_in_fixed_parser) ) \
459 BOOST_PP_CAT(errsym_, __LINE__);
461 # //-///////////////////////////////////////////////////////////////////////////////////////////////
462 # // SENF_PARSER_COLLECTION_I
466 namespace senf { namespace detail { namespace auxtag {
467 struct none {}; } } }
468 namespace senf { namespace detail { namespace auxtag {
469 struct bytes {}; } } }
470 namespace senf { namespace detail { namespace auxtag {
471 template <class Transform, class Tag>
472 struct transform {}; } } }
473 namespace senf { namespace detail { namespace auxtag {
474 struct packetSize {}; } } }
478 # // Each tag is implemented by defining the following macros. If the Tag is <name>(<args>):
479 # // SENF_PARSER_COLLECTION_TAG_GOBBLE__<name>(<args>)
480 # // gobble the tag, that is expand to nothing
481 # // SENF_PARSER_COLLECTION_TAG__<name>(<args>)
482 # // return an intermediate tag. This tag will be used with the next macro to get the aux tag
483 # // this indirection is needed since the tag may include templates with more than one
484 # // argument which cannot be passed through macros ... Ugh ...
485 # // SENF_PARSER_COLLECTION_TAG_EXPAND__<tag>(<tag args>)
486 # // expand to the real tag type
487 # // SENF_PARSER_COLLECTION_TAG_GETAUX__<name>(<args>)
488 # // return the real aux field. More specifically, this is the aux argument to the aux expand
490 # // SENF_PARSER_COLLECTION_TAG_AUXTYPE__<name>(<args>)
491 # // return an identifier selecting the aux type macro to use. If the expansion of this macro
492 # // is <auxtag>, the macro will be called SENF_PARSER_COLLECTION_TAG_AUXDEF__<auxtag>
493 # // SENF_PARSER_COLLECTION_TAG_AUXDEF__<auxtag>(<name>,<auxarg>)
494 # // this command must declare the typedef <fieldname>_aux_type to the base aux policy
496 # define SENF_PARSER_COLLECTION_TAG_GOBBLE__bytes(x)
497 # define SENF_PARSER_COLLECTION_TAG__bytes(x) bytes()
498 # define SENF_PARSER_COLLECTION_TAG_EXPAND__bytes() senf::detail::auxtag::bytes
499 # define SENF_PARSER_COLLECTION_TAG_GETAUX__bytes(x) x
500 # define SENF_PARSER_COLLECTION_TAG_AUXTYPE__bytes(x) auxField
502 # define SENF_PARSER_COLLECTION_TAG_GOBBLE__transform(x,y)
503 # define SENF_PARSER_COLLECTION_TAG__transform(x,y) \
504 transform(x, SENF_PARSER_COLLECTION_TAG_RECURS1(y))
505 # define SENF_PARSER_COLLECTION_TAG_EXPAND__transform(x,y) \
506 senf::detail::auxtag::transform< \
508 SENF_CAT_RECURS1(SENF_PARSER_COLLECTION_TAG_EXPAND__, y)>
509 # define SENF_PARSER_COLLECTION_TAG_GETAUX__transform(x,y) \
510 SENF_PARSER_COLLECTION_TAG_GETAUX_RECURS1(y)
511 # define SENF_PARSER_COLLECTION_TAG_AUXTYPE__transform(x,y) \
512 SENF_PARSER_COLLECTION_TAG_AUXTYPE_RECURS1(y)
514 # define SENF_PARSER_COLLECTION_TAG_GOBBLE__packetSize()
515 # define SENF_PARSER_COLLECTION_TAG__packetSize() packetSize()
516 # define SENF_PARSER_COLLECTION_TAG_EXPAND__packetSize() senf::detail::auxtag::bytes
517 # define SENF_PARSER_COLLECTION_TAG_GETAUX__packetSize() _
518 # define SENF_PARSER_COLLECTION_TAG_AUXTYPE__packetSize() packetSize
520 # define SENF_PARSER_COLLECTION_TAG_EXPAND__none() senf::detail::auxtag::none
522 # define SENF_PARSER_COLLECTION_TAG_RECURS1(aux) \
524 SENF_PARSER_COLLECTION_HAS_KEYWORD(aux), \
525 BOOST_PP_CAT(SENF_PARSER_COLLECTION_TAG__, aux), \
528 # define SENF_PARSER_COLLECTION_TAG_GETAUX_RECURS1(aux) \
530 SENF_PARSER_COLLECTION_HAS_KEYWORD(aux), \
531 BOOST_PP_CAT(SENF_PARSER_COLLECTION_TAG_GETAUX__, aux), \
534 # define SENF_PARSER_COLLECTION_TAG_AUXTYPE_RECURS1(aux) \
536 SENF_PARSER_COLLECTION_HAS_KEYWORD(aux), \
537 BOOST_PP_CAT(SENF_PARSER_COLLECTION_TAG_AUXTYPE__, aux), \
540 # define SENF_PARSER_COLLECTION_HAS_KEYWORD(x) \
541 BOOST_PP_IS_EMPTY( SENF_CAT_RECURS1(SENF_PARSER_COLLECTION_TAG_GOBBLE__, x) )
543 # define SENF_PARSER_COLLECTION_GETAUX(aux) \
544 BOOST_PP_IF( SENF_PARSER_COLLECTION_HAS_KEYWORD(aux), \
545 SENF_CAT_RECURS2(SENF_PARSER_COLLECTION_TAG_GETAUX__, aux), \
548 # define SENF_PARSER_COLLECTION_I(access, name, aux, traits) \
550 SENF_PARSER_COLLECTION_II \
552 SENF_PARSER_COLLECTION_HAS_KEYWORD(aux), \
555 SENF_CAT_RECURS2(SENF_PARSER_COLLECTION_TAG_AUXTYPE__, aux), \
556 SENF_CAT_RECURS2(SENF_PARSER_COLLECTION_TAG_GETAUX__, aux), \
557 SENF_CAT_RECURS2(SENF_PARSER_COLLECTION_TAG__, aux), \
566 # define SENF_PARSER_COLLECTION_II(access, name, auxtype, aux, tag, traits) \
568 BOOST_PP_CAT(SENF_PARSER_COLLECTION_TAG_AUXDEF__, auxtype)(name, aux) \
569 typedef traits::parser< \
570 BOOST_PP_CAT(name,_aux_policy), \
571 BOOST_PP_CAT(SENF_PARSER_COLLECTION_TAG_EXPAND__, tag) \
572 >::type BOOST_PP_CAT(name, _collection_t); \
574 SENF_PARSER_FIELD_SETUP_I( name, \
575 BOOST_PP_CAT(name, _collection_t), \
579 BOOST_PP_CAT(SENF_PARSER_COLLECTION_TAG_VAL__, auxtype)(name, aux, access) \
582 # define SENF_PARSER_COLLECTION_TAG_AUXDEF__auxField(name, aux) \
583 BOOST_PP_CAT(SENF_PARSER_COLLECTION_AUXTYPE_, SENF_PARSER_TYPE)(name, aux) \
584 typedef BOOST_PP_CAT(SENF_PARSER_COLLECTION_AUX_I_, SENF_PARSER_TYPE)(name, aux) \
585 BOOST_PP_CAT(name,_aux_policy);
587 # define SENF_PARSER_COLLECTION_AUXTYPE_var(name, aux) \
588 static bool const BOOST_PP_CAT(name, _aux_fixed) = \
589 (SENF_MPL_SLOT_GET(group) - BOOST_PP_CAT(aux, _group) == 0);
591 # define SENF_PARSER_COLLECTION_AUXTYPE_fix(name, aux)
595 namespace senf { namespace detail {
596 template <class Parser> struct DynamicAuxParserPolicy;
597 template <class Parser, unsigned offset> struct FixedAuxParserPolicy;
598 template <class Parser, unsigned fixedOffset, bool fixedDelta>
599 struct ParserAuxPolicySelect
600 { typedef senf::detail::DynamicAuxParserPolicy<Parser> type; };
601 template <class Parser, unsigned fixedOffset>
602 struct ParserAuxPolicySelect<Parser, fixedOffset, true>
603 { typedef senf::detail::FixedAuxParserPolicy<Parser, fixedOffset> type; };
608 # define SENF_PARSER_COLLECTION_AUX_I_var(name, aux) \
609 senf::detail::ParserAuxPolicySelect< BOOST_PP_CAT(aux, _t), \
610 SENF_PARSER_CURRENT_FIXED_OFFSET() \
611 - SENF_PARSER_FIXED_OFFSET(aux), \
612 BOOST_PP_CAT(name, _aux_fixed) >::type
614 # define SENF_PARSER_COLLECTION_AUX_I_fix(name, aux) \
615 senf::detail::FixedAuxParserPolicy< BOOST_PP_CAT(aux, _t), \
616 SENF_PARSER_CURRENT_FIXED_OFFSET() \
617 - SENF_PARSER_FIXED_OFFSET(aux) >
619 # define SENF_PARSER_COLLECTION_TAG_AUXDEF__packetSize(name, aux) \
620 typedef senf::detail::PacketSizeAuxParserPolicy BOOST_PP_CAT(name, _aux_policy);
622 # define SENF_PARSER_COLLECTION_TAG_VAL__auxField(name, aux, access) \
623 BOOST_PP_CAT(SENF_PARSER_COLLECTION_VAL_, SENF_PARSER_TYPE)(name, aux, access)
625 # define SENF_PARSER_COLLECTION_VAL_var(name,aux,access) \
627 template <class T> T BOOST_PP_CAT(name, _dispatch)(boost::true_type) const \
628 { return parse<T>( SENF_PARSER_OFFSET(name) ); } \
629 template <class T> T BOOST_PP_CAT(name, _dispatch)(boost::false_type) const \
630 { return parse<T>( BOOST_PP_CAT(aux,_)(), SENF_PARSER_OFFSET(name) ); } \
631 BOOST_PP_CAT(name, _t) BOOST_PP_CAT(name, _)() const \
632 { return BOOST_PP_CAT(name, _dispatch) <BOOST_PP_CAT(name, _t)>( \
633 boost::integral_constant<bool, BOOST_PP_CAT(name, _aux_fixed)>()); } \
635 BOOST_PP_CAT(name, _t) name() const \
636 { return BOOST_PP_CAT(name, _)(); }
638 # define SENF_PARSER_COLLECTION_VAL_fix(name,aux,access) \
640 BOOST_PP_CAT(name, _t) BOOST_PP_CAT(name, _)() const \
641 { return parse<BOOST_PP_CAT(name, _t)>( SENF_PARSER_OFFSET(name) ); } \
643 BOOST_PP_CAT(name, _t) name() const \
644 { return BOOST_PP_CAT(name, _)(); }
646 # define SENF_PARSER_COLLECTION_TAG_VAL__packetSize(name, aux, access) \
648 BOOST_PP_CAT(name, _t) BOOST_PP_CAT(name, _)() const \
649 { return parse<BOOST_PP_CAT(name, _t)>( SENF_PARSER_OFFSET(name) ); } \
651 BOOST_PP_CAT(name, _t) name() const \
652 { return BOOST_PP_CAT(name, _)(); }
654 # //-///////////////////////////////////////////////////////////////////////////////////////////////
658 # // Local Variables:
660 # // fill-column: 100
661 # // c-file-style: "senf"
662 # // indent-tabs-mode: nil
663 # // ispell-local-dictionary: "american"
664 # // compile-command: "scons -u test"