ParseHelpers.ih
Go to the documentation of this file.
1 //
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
6 //
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
11 //
12 
13 
14 /** \file
15  \brief ParseHelpers internal header */
16 
17 # if !defined(IH_ParseHelpers_)
18 # define IH_ParseHelpers_ 1
19 #
20 # // Custom includes
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>
28 #
29 # //-///////////////////////////////////////////////////////////////////////////////////////////////
30 #
31 # //-///////////////////////////////////////////////////////////////////////////////////////////////
32 # // SENF_PARSER_INITIALIZE
33 #
34 # define SENF_PARSER_INITIALIZE BOOST_PP_CAT( SENF_PARSER_INITIALIZE_ , SENF_PARSER_TYPE )
35 #
36 # define SENF_PARSER_INITIALIZE_fix() \
37  private: \
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 {} \
43  public: \
44  struct SelfProxy;
45 #
46 # define SENF_PARSER_INITIALIZE_var() \
47  private: \
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; } \
55  public: \
56  struct SelfProxy;
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, protected)
94 # define SENF_PARSER_P_FIELD_fix(name, type) SENF_PARSER_FIELD_I(name, type, fix, rw, protected)
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>*>(nullptr)); \
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>*>(nullptr)); \
139  } \
140  access:
141 #
142 # //-///////////////////////////////////////////////////////////////////////////////////////////////
143 # // SENF_PARSER_I_FIELD_OFS_*
144 #
145 # define SENF_PARSER_I_FIELD_OFS_var(name, type, access) \
146  protected: \
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)); \
150  } \
151  static size_type const BOOST_PP_CAT(name, _init_bytes) = \
152  SENF_MPL_SLOT_GET(init_bytes); \
153  private:
154 #
155 # define SENF_PARSER_I_FIELD_OFS_fix(name, type, access) \
156  protected: \
157  static size_type const BOOST_PP_CAT(name, _offset) = \
158  SENF_MPL_SLOT_GET(offset); \
159  private:
160 #
161 # //-///////////////////////////////////////////////////////////////////////////////////////////////
162 # // SENF_PARSER_I_ADVANCE_OFS_*
163 #
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
166 #
167 # define SENF_PARSER_I_SIZE_fix(name, type) type::fixed_bytes
168 # define SENF_PARSER_I_INITBYTES_fix(name, type) void
169 #
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)
172 #
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; \
176  } \
177  static size_type const BOOST_PP_CAT(name, _next_init_bytes) = \
178  BOOST_PP_CAT(name, _init_bytes) + isize; \
179  private: \
180  size_type field_offset_(senf::mpl::rv<BOOST_PP_CAT(name,_index)>*) const { \
181  return BOOST_PP_CAT(name, _next_offset)(); \
182  } \
183  SENF_MPL_SLOT_SET(init_bytes, BOOST_PP_CAT(name,_next_init_bytes)); \
184  protected: \
185  static size_type const BOOST_PP_CAT(name, _group) = SENF_MPL_SLOT_GET(group) + isvar; \
186  private: \
187  SENF_MPL_SLOT_SET(group, BOOST_PP_CAT(name, _group)); \
188  access:
189 #
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; \
193  private: \
194  SENF_MPL_SLOT_SET(offset, BOOST_PP_CAT(name, _next_offset)); \
195  access:
196 #
197 # //-///////////////////////////////////////////////////////////////////////////////////////////////
198 # // SENF_PARSER_I_FIELD_VAL_*
199 #
200 # define SENF_PARSER_I_FIELD_VAL_rw(name, type, access) \
201  protected: \
202  BOOST_PP_CAT(name, _t) BOOST_PP_CAT(name, _)() const { \
203  return parse<type>( SENF_PARSER_OFFSET(name) ); \
204  } \
205  access: \
206  BOOST_PP_CAT(name, _t) name() const { \
207  return BOOST_PP_CAT(name,_)(); \
208  } \
209  template <typename T> \
210  SelfProxy name(T const & v) const { \
211  if (senf::is_fixed<type>::value) \
212  name() << v; \
213  else \
214  protect(), name() << v; \
215  return SelfProxy(this); \
216  }
217 #
218 # define SENF_PARSER_I_FIELD_VAL_ro(name, type, access) \
219  protected: \
220  BOOST_PP_CAT(name, _t) BOOST_PP_CAT(name, _)() const { \
221  return parse<type>( SENF_PARSER_OFFSET(name) ); \
222  } \
223  access: \
224  typename BOOST_PP_CAT(name, _t)::value_type name() const { \
225  return BOOST_PP_CAT(name,_)(); \
226  }
227 #
228 # //-///////////////////////////////////////////////////////////////////////////////////////////////
229 # // SENF_PARSER_CUSTOM_FIELD_*
230 #
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)
235 #
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
243 #
244 # //-///////////////////////////////////////////////////////////////////////////////////////////////
245 # // SENF_PARSER_BITFIELD_*
246 # // SENF_PARSER_P_BITFIELD_*
247 #
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)
256 #
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)
261 #
262 # //-///////////////////////////////////////////////////////////////////////////////////////////////
263 # // SENF_PARSER_BITFIELD_I
264 #
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>
268 #
269 # define SENF_PARSER_BITFIELD_I(name, bits, type, ofstype, rwtype, access) \
270  access: \
271  static size_type const BOOST_PP_CAT(name, _bit) = SENF_MPL_SLOT_GET(bit); \
272  private: \
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 ); \
276  access: \
277  SENF_PARSER_BITFIELD_II( name, bits, BOOST_PP_CAT(name, _bit_t), ofstype, rwtype, access) \
278  public:
279 #
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) ( \
285  name, type, \
286  BOOST_PP_CAT(name, _t)::fixed_bytes, BOOST_PP_CAT(name, _t)::fixed_bytes, \
287  0, \
288  access) \
289  private: \
290  SENF_MPL_SLOT_SET(bitfield_size, BOOST_PP_CAT(name, _t)::fixed_bytes); \
291  access: \
292  BOOST_PP_CAT(SENF_PARSER_I_FIELD_VAL_, rwtype) (name, type, access) \
293  public:
294 #
295 # //-///////////////////////////////////////////////////////////////////////////////////////////////
296 # // SENF_PARSER_I_BITFIELD_OFS_*
297 #
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); \
303  } \
304  static size_type const BOOST_PP_CAT(name, _init_bytes) = \
305  SENF_MPL_SLOT_GET(init_bytes) - SENF_MPL_SLOT_GET(bitfield_size);
306 #
307 # define SENF_PARSER_I_BITFIELD_OFS_fix(name, type, access) \
308  static size_type const BOOST_PP_CAT(name, _offset) = \
309  SENF_MPL_SLOT_GET(offset) - SENF_MPL_SLOT_GET(bitfield_size);
310 #
311 # //-///////////////////////////////////////////////////////////////////////////////////////////////
312 # // SENF_PARSER_I_BITFIELD_RESET
313 #
314 # define SENF_PARSER_I_BITFIELD_RESET() \
315  SENF_MPL_SLOT_SET(bit, 0); \
316  SENF_MPL_SLOT_SET(bitfield_size, 0);
317 #
318 # //-///////////////////////////////////////////////////////////////////////////////////////////////
319 # // SENF_PARSER_SKIP_*
320 #
321 # define SENF_PARSER_SKIP_var(bytes, ibytes) \
322  SENF_PARSER_I_SKIP( BOOST_PP_CAT(senf_anon_, __LINE__), bytes, ibytes, var)
323 #
324 # define SENF_PARSER_SKIP_fix(bytes) \
325  SENF_PARSER_I_SKIP( BOOST_PP_CAT(senf_anon_, __LINE__), bytes, bytes, fix)
326 #
327 # define SENF_PARSER_I_SKIP(name, bytes, ibytes, ofstype) \
328  private: \
329  SENF_PARSER_I_BITFIELD_RESET() \
330  SENF_PARSER_I_FIELD_INTRO(name, void, private) \
331  SENF_PARSER_I_FIELD_INIT_ro(name, void, private) \
332  BOOST_PP_CAT(SENF_PARSER_I_FIELD_OFS_, ofstype) (name, type, access) \
333  BOOST_PP_CAT(SENF_PARSER_I_ADVANCE_OFS_, ofstype) (name, void, bytes, ibytes, 1, \
334  private) \
335  public:
336 #
337 # //-///////////////////////////////////////////////////////////////////////////////////////////////
338 # // SENF_PARSER_SKIP_BITS_*
339 #
340 # define SENF_PARSER_SKIP_BITS_var(bits) SENF_PARSER_I_SKIP_BITS(bits, var)
341 # define SENF_PARSER_SKIP_BITS_fix(bits) SENF_PARSER_I_SKIP_BITS(bits, fix)
342 #
343 # define SENF_PARSER_I_SKIP_BITS(bits, ofstype) \
344  private: \
345  SENF_MPL_SLOT_SET(bit, SENF_MPL_SLOT_GET(bit) + bits); \
346  public:
347 #
348 # //-///////////////////////////////////////////////////////////////////////////////////////////////
349 # // SENF_PARSER_GOTO_*
350 #
351 # define SENF_PARSER_GOTO_var(name) \
352  SENF_PARSER_I_GOTO( BOOST_PP_CAT(senf_anon_, __LINE__), \
353  BOOST_PP_CAT(name, _offset)(), \
354  BOOST_PP_CAT(name, _init_bytes), \
355  var )
356 #
357 # define SENF_PARSER_GOTO_fix(name) \
358  SENF_PARSER_I_GOTO( BOOST_PP_CAT(senf_anon_, __LINE__), \
359  BOOST_PP_CAT(name, _offset), \
360  BOOST_PP_CAT(name, _offset), \
361  fix )
362 #
363 # define SENF_PARSER_GOTO_OFFSET_var(offset, isize) \
364  SENF_PARSER_I_GOTO( BOOST_PP_CAT(senf_anon_, __LINE__), offset, isize, var )
365 #
366 # define SENF_PARSER_GOTO_OFFSET_fix(offset) \
367  SENF_PARSER_I_GOTO( BOOST_PP_CAT(senf_anon_, __LINE__), offset, offset, fix )
368 #
369 # define SENF_PARSER_I_GOTO(name, offset, initsize, ofstype) \
370  private: \
371  SENF_PARSER_I_BITFIELD_RESET() \
372  SENF_PARSER_I_FIELD_INTRO(name, void, private) \
373  SENF_PARSER_I_FIELD_INIT_ro(name, void, private) \
374  BOOST_PP_CAT( SENF_PARSER_I_GOTO_SET_OFS_, ofstype ) (name, offset, initsize) \
375  public:
376 #
377 # define SENF_PARSER_I_GOTO_SET_OFS_var(name, offs, initsize) \
378  size_type field_offset_(senf::mpl::rv<BOOST_PP_CAT(name,_index)>*) const { \
379  return offs; \
380  } \
381  SENF_MPL_SLOT_SET(init_bytes, initsize);
382 #
383 # define SENF_PARSER_I_GOTO_SET_OFS_fix(name, offs, initsize) \
384  SENF_MPL_SLOT_SET(offset, offs);
385 #
386 # //-///////////////////////////////////////////////////////////////////////////////////////////////
387 # // SENF_PARSER_LABEL_*
388 #
389 # define SENF_PARSER_LABEL_var(name) SENF_PARSER_I_LABEL( name, var, public )
390 # define SENF_PARSER_LABEL_fix(name) SENF_PARSER_I_LABEL( name, fix, public )
391 #
392 # define SENF_PARSER_I_LABEL(name, ofstype, access) \
393  access: \
394  SENF_PARSER_I_BITFIELD_RESET() \
395  SENF_PARSER_I_FIELD_INTRO(name, void, access) \
396  SENF_PARSER_I_FIELD_INIT_ro(name, void, access) \
397  BOOST_PP_CAT(SENF_PARSER_I_FIELD_OFS_, ofstype) (name, type, access) \
398  BOOST_PP_CAT(SENF_PARSER_I_ADVANCE_OFS_, ofstype) (name, void, 0, 0, 0, access) \
399  public:
400 #
401 # //-///////////////////////////////////////////////////////////////////////////////////////////////
402 # // SENF_PARSER_OFFSET_*
403 #
404 # define SENF_PARSER_OFFSET_fix(name) BOOST_PP_CAT(name, _offset)
405 # define SENF_PARSER_OFFSET_var(name) BOOST_PP_CAT(name, _offset)()
406 #
407 # //-///////////////////////////////////////////////////////////////////////////////////////////////
408 # // SENF_PARSER_FIXED_OFFSET_*
409 #
410 # define SENF_PARSER_FIXED_OFFSET_fix(name) BOOST_PP_CAT(name, _offset)
411 # define SENF_PARSER_FIXED_OFFSET_var(name) BOOST_PP_CAT(name, _init_bytes)
412 #
413 # //-///////////////////////////////////////////////////////////////////////////////////////////////
414 # // SENF_PARSER_CURRENT_FIXED_OFFSET_*
415 #
416 # define SENF_PARSER_CURRENT_FIXED_OFFSET_fix() SENF_MPL_SLOT_GET(offset)
417 # define SENF_PARSER_CURRENT_FIXED_OFFSET_var() SENF_MPL_SLOT_GET(init_bytes)
418 #
419 # //-///////////////////////////////////////////////////////////////////////////////////////////////
420 # // SENF_PARSER_FINALIZE_*
421 #
422 # define SENF_PARSER_FINALIZE_var(name) \
423  SENF_PARSER_FINALIZE_GENERIC(name) \
424  size_type bytes() const { \
425  return field_offset_(static_cast<senf::mpl::rv<SENF_MPL_SLOT_GET(index)>*>(nullptr));\
426  } \
427  static size_type const init_bytes = SENF_MPL_SLOT_GET(init_bytes)
428 #
429 # define SENF_PARSER_FINALIZE_fix(name) \
430  SENF_PARSER_FINALIZE_GENERIC(name) \
431  static size_type const fixed_bytes = SENF_MPL_SLOT_GET(offset);
432 #
433 # define SENF_PARSER_FINALIZE_GENERIC(name) \
434  void defaultInit() const { \
435  init_chain(static_cast<senf::mpl::rv<SENF_MPL_SLOT_GET(index)>*>(nullptr)); \
436  } \
437  name(data_iterator i, state_type s) : parser_base_type(i,s) {} \
438  private: \
439  template <class T> void init(T) const { defaultInit(); } \
440  public: \
441  void init() const { init(0); } \
442  struct SelfProxy { \
443  SelfProxy(name const * p) : p_(p) {} \
444  name const * operator->() { return p_; } \
445  name const * p_; \
446  };
447 #
448 # //-///////////////////////////////////////////////////////////////////////////////////////////////
449 # // SENF_PARSER_REQUIRE_VAR
450 #
451 # define SENF_PARSER_REQUIRE_VAR(description) \
452  BOOST_PP_CAT(SENF_PARSER_REQUIRE_VAR_, SENF_PARSER_TYPE)(description)
453 #
454 # define SENF_PARSER_REQUIRE_VAR_var(description)
455 #
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__);
460 #
461 # //-///////////////////////////////////////////////////////////////////////////////////////////////
462 # // SENF_PARSER_COLLECTION_I
463 #
464 # ifndef DOXYGEN
465 #
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 {}; } } }
475 #
476 # endif
477 #
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
489 # // macro
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
495 #
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
501 #
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< \
507  x, \
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)
513 #
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
519 #
520 # define SENF_PARSER_COLLECTION_TAG_EXPAND__none() senf::detail::auxtag::none
521 #
522 # define SENF_PARSER_COLLECTION_TAG_RECURS1(aux) \
523  BOOST_PP_IF( \
524  SENF_PARSER_COLLECTION_HAS_KEYWORD(aux), \
525  BOOST_PP_CAT(SENF_PARSER_COLLECTION_TAG__, aux), \
526  none() )
527 #
528 # define SENF_PARSER_COLLECTION_TAG_GETAUX_RECURS1(aux) \
529  BOOST_PP_IF( \
530  SENF_PARSER_COLLECTION_HAS_KEYWORD(aux), \
531  BOOST_PP_CAT(SENF_PARSER_COLLECTION_TAG_GETAUX__, aux), \
532  aux)
533 #
534 # define SENF_PARSER_COLLECTION_TAG_AUXTYPE_RECURS1(aux) \
535  BOOST_PP_IF( \
536  SENF_PARSER_COLLECTION_HAS_KEYWORD(aux), \
537  BOOST_PP_CAT(SENF_PARSER_COLLECTION_TAG_AUXTYPE__, aux), \
538  auxField)
539 #
540 # define SENF_PARSER_COLLECTION_HAS_KEYWORD(x) \
541  BOOST_PP_IS_EMPTY( SENF_CAT_RECURS1(SENF_PARSER_COLLECTION_TAG_GOBBLE__, x) )
542 #
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), \
546  aux )
547 
548 # define SENF_PARSER_COLLECTION_I(access, name, aux, traits) \
549  BOOST_PP_EXPAND( \
550  SENF_PARSER_COLLECTION_II \
551  BOOST_PP_IF( \
552  SENF_PARSER_COLLECTION_HAS_KEYWORD(aux), \
553  ( access, \
554  name, \
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), \
558  traits ), \
559  ( access, \
560  name, \
561  auxField, \
562  aux, \
563  none(), \
564  traits ) ))
565 #
566 # define SENF_PARSER_COLLECTION_II(access, name, auxtype, aux, tag, traits) \
567  private: \
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); \
573  access: \
574  SENF_PARSER_FIELD_SETUP_I( name, \
575  BOOST_PP_CAT(name, _collection_t), \
576  SENF_PARSER_TYPE, \
577  rw, \
578  access ) \
579  BOOST_PP_CAT(SENF_PARSER_COLLECTION_TAG_VAL__, auxtype)(name, aux, access) \
580  public:
581 #
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);
586 #
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);
590 #
591 # define SENF_PARSER_COLLECTION_AUXTYPE_fix(name, aux)
592 #
593 # ifndef DOXYGEN
594 #
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; };
604  }};
605 #
606 # endif
607 #
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
613 #
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) >
618 #
619 # define SENF_PARSER_COLLECTION_TAG_AUXDEF__packetSize(name, aux) \
620  typedef senf::detail::PacketSizeAuxParserPolicy BOOST_PP_CAT(name, _aux_policy);
621 #
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)
624 #
625 # define SENF_PARSER_COLLECTION_VAL_var(name,aux,access) \
626  private: \
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)>()); } \
634  access: \
635  BOOST_PP_CAT(name, _t) name() const \
636  { return BOOST_PP_CAT(name, _)(); }
637 #
638 # define SENF_PARSER_COLLECTION_VAL_fix(name,aux,access) \
639  private: \
640  BOOST_PP_CAT(name, _t) BOOST_PP_CAT(name, _)() const \
641  { return parse<BOOST_PP_CAT(name, _t)>( SENF_PARSER_OFFSET(name) ); } \
642  access: \
643  BOOST_PP_CAT(name, _t) name() const \
644  { return BOOST_PP_CAT(name, _)(); }
645 #
646 # define SENF_PARSER_COLLECTION_TAG_VAL__packetSize(name, aux, access) \
647  private: \
648  BOOST_PP_CAT(name, _t) BOOST_PP_CAT(name, _)() const \
649  { return parse<BOOST_PP_CAT(name, _t)>( SENF_PARSER_OFFSET(name) ); } \
650  access: \
651  BOOST_PP_CAT(name, _t) name() const \
652  { return BOOST_PP_CAT(name, _)(); }
653 #
654 # //-///////////////////////////////////////////////////////////////////////////////////////////////
655 # endif
656 #
657 #
658 # // Local Variables:
659 # // mode: c++
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"
665 # // End: