Packets: Fix VariantParser invalid parser access bug
[senf.git] / Packets / ParseHelpers.ih
index dc1191c..6392b69 100644 (file)
@@ -1,6 +1,6 @@
 # // Copyright (C) 2007
-# // Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
-# // Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
+# // Fraunhofer Institute for Open Communication Systems (FOKUS)
+# // Competence Center NETwork research (NET), St. Augustin, GERMANY
 # //     Stefan Bund <g0dil@berlios.de>
 # //
 # // This program is free software; you can redistribute it and/or modify
 #
 # // Custom includes
 # include <boost/preprocessor/cat.hpp>
+# include <boost/preprocessor/if.hpp>
+# include <boost/preprocessor/expand.hpp>
+# include <boost/preprocessor/facilities/is_empty.hpp>
+# include <boost/preprocessor/punctuation/comma.hpp>
 # include "../Utils/mpl.hh"
 #
 # ////////////////////////////////ih.p///////////////////////////////////////
@@ -41,7 +45,7 @@
         SENF_MPL_SLOT_DEF_ZERO(offset);                                                           \
         SENF_MPL_SLOT_DEF_ZERO(bit);                                                              \
         SENF_MPL_SLOT_DEF_ZERO(bitfield_size);                                                    \
-        void init_chain(senf::mpl::rv<0>*) {}                                                     \
+        void init_chain(senf::mpl::rv<0>*) const {}                                               \
     public:
 #
 # define SENF_PARSER_INITIALIZE_var()                                                             \
@@ -50,7 +54,8 @@
         SENF_MPL_SLOT_DEF_ZERO(init_bytes);                                                       \
         SENF_MPL_SLOT_DEF_ZERO(bit);                                                              \
         SENF_MPL_SLOT_DEF_ZERO(bitfield_size);                                                    \
-        void init_chain(senf::mpl::rv<0>*) {}                                                     \
+        SENF_MPL_SLOT_DEF_ZERO(group);                                                            \
+        void init_chain(senf::mpl::rv<0>*) const {}                                               \
         size_type field_offset_(senf::mpl::rv<0>*) const { return 0; }                            \
     public:
 #
@@ -65,7 +70,7 @@
         size_type field_offset_(senf::mpl::rv<1>*) const {                                        \
             return senf::bytes( *static_cast<name const*>(this) );                                \
         }                                                                                         \
-        void init_chain(senf::mpl::rv<1>*) {                                                      \
+        void init_chain(senf::mpl::rv<1>*) const {                                                \
             name::init();                                                                         \
         }                                                                                         \
     public:
     private:                                                                                      \
         SENF_MPL_SLOT_SET(offset, name::fixed_bytes);                                             \
         SENF_MPL_SLOT_SET(index, 1);                                                              \
-        void init_chain(senf::mpl::rv<1>*) {                                                      \
+        void init_chain(senf::mpl::rv<1>*) const {                                                \
             name::init();                                                                         \
         }                                                                                         \
     public:
 #
 # ///////////////////////////////////////////////////////////////////////////
-# // SENF_PARSER_FIELD_*
+# // SENF_PARSER_FIELD*
 # // SENF_PARSER_P_FIELD_*
 #
 # define SENF_PARSER_FIELD_var(name, type)    SENF_PARSER_FIELD_I(name, type, var, rw, public)
 # define SENF_PARSER_FIELD_RO_fix(name, type) SENF_PARSER_FIELD_I(name, type, fix, ro, public)
 #
 # define SENF_PARSER_P_FIELD_var(name, type)    SENF_PARSER_FIELD_I(name, type, var, rw, private)
-# define SENF_PARSER_P_FIELD_RO_var(name, type) SENF_PARSER_FIELD_I(name, type, var, ro, private)
 # define SENF_PARSER_P_FIELD_fix(name, type)    SENF_PARSER_FIELD_I(name, type, fix, rw, private)
-# define SENF_PARSER_P_FIELD_RO_fix(name, type) SENF_PARSER_FIELD_I(name, type, fix, ro, private)
 #
 # define SENF_PARSER_FIELD_I(name, type, ofstype, rwtype, access)                                 \
     access:                                                                                       \
+        SENF_PARSER_FIELD_SETUP_I(name, type, ofstype, rwtype, access)                            \
+        BOOST_PP_CAT(SENF_PARSER_I_FIELD_VAL_, rwtype) (name, type, access)                       \
+    public:
+#
+# define SENF_PARSER_FIELD_SETUP_I(name, type, ofstype, rwtype, access)                           \
         SENF_PARSER_I_BITFIELD_RESET()                                                            \
         SENF_PARSER_I_FIELD_INTRO(name, type, access)                                             \
         BOOST_PP_CAT(SENF_PARSER_I_FIELD_INIT_, rwtype) (name, type, access)                      \
             name, type,                                                                           \
             BOOST_PP_CAT(SENF_PARSER_I_SIZE_, ofstype) (name, type),                              \
             BOOST_PP_CAT(SENF_PARSER_I_INITBYTES_, ofstype) (name, type),                         \
-            access )                                                                              \
-        BOOST_PP_CAT(SENF_PARSER_I_FIELD_VAL_, rwtype) (name, type, ofstype, access)              \
-    public:
+            BOOST_PP_CAT(SENF_PARSER_I_ISVAR_, ofstype) (name, type),                             \
+            access )
 #
 # ////////////////////////////////////////
 # // SENF_PARSER_I_FIELD_INTRO
 # ////////////////////////////////////////
 # // SENF_PARSER_I_FIELD_INIT_*
 #
-# define SENF_PARSER_I_FIELD_INIT_rw(name, type, access)                                                  \
+# define SENF_PARSER_I_FIELD_INIT_rw(name, type, access)                                          \
     private:                                                                                      \
-        void init_chain(senf::mpl::rv<BOOST_PP_CAT(name,_index)>*) {                              \
+        void init_chain(senf::mpl::rv<BOOST_PP_CAT(name,_index)>*) const {                        \
             init_chain(static_cast<senf::mpl::rv<BOOST_PP_CAT(name,_index)-1>*>(0));              \
             name().init();                                                                        \
         }                                                                                         \
     access:
 #
-# define SENF_PARSER_I_FIELD_INIT_ro(name, type, access)                                                  \
+# define SENF_PARSER_I_FIELD_INIT_ro(name, type, access)                                          \
     private:                                                                                      \
-        void init_chain(senf::mpl::rv<BOOST_PP_CAT(name,_index)>*) {                              \
+        void init_chain(senf::mpl::rv<BOOST_PP_CAT(name,_index)>*) const {                        \
             init_chain(static_cast<senf::mpl::rv<BOOST_PP_CAT(name,_index)-1>*>(0));              \
         }                                                                                         \
     access:
 # define SENF_PARSER_I_FIELD_OFS_var(name, type, access)                                          \
         size_type BOOST_PP_CAT(name,_offset)() const {                                            \
             return field_offset_(static_cast<senf::mpl::rv<BOOST_PP_CAT(name,_index)-1>*>(0));    \
-        }
+        }                                                                                         \
+        static size_type const BOOST_PP_CAT(name, _init_bytes) =                                  \
+            SENF_MPL_SLOT_GET(init_bytes);
 #
 # define SENF_PARSER_I_FIELD_OFS_fix(name, type, access)                                          \
-        static size_type const BOOST_PP_CAT(name, _offset) = SENF_MPL_SLOT_GET(offset);
+        static size_type const BOOST_PP_CAT(name, _offset) =                                      \
+            SENF_MPL_SLOT_GET(offset);
 #
 # ////////////////////////////////////////
 # // SENF_PARSER_I_ADVANCE_OFS_*
 #
-# // Can't call 'name()' here if 'name' is an ro field ...
-# define SENF_PARSER_I_SIZE_var(name, type) senf::bytes(parse<type>(BOOST_PP_CAT(name,_offset)()))
+# define SENF_PARSER_I_SIZE_var(name, type) senf::bytes(BOOST_PP_CAT(name, _)())
 # define SENF_PARSER_I_INITBYTES_var(name, type) senf::init_bytes<type>::value
 #
 # define SENF_PARSER_I_SIZE_fix(name, type) type::fixed_bytes
 # define SENF_PARSER_I_INITBYTES_fix(name, type) void
 #
-# define SENF_PARSER_I_ADVANCE_OFS_var(name, type, size, isize, access)                           \
+# define SENF_PARSER_I_ISVAR_fix(name, type) 0
+# define SENF_PARSER_I_ISVAR_var(name, type) (senf::is_fixed<type>::value?0:1)
+#
+# define SENF_PARSER_I_ADVANCE_OFS_var(name, type, size, isize, isvar, access)                    \
         size_type BOOST_PP_CAT(name, _next_offset)() const {                                      \
             return BOOST_PP_CAT(name,_offset)() + size;                                           \
         }                                                                                         \
-        static size_type const BOOST_PP_CAT(name, _init_bytes) = SENF_MPL_SLOT_GET(init_bytes);   \
         static size_type const BOOST_PP_CAT(name, _next_init_bytes) =                             \
             BOOST_PP_CAT(name, _init_bytes) + isize;                                              \
     private:                                                                                      \
             return BOOST_PP_CAT(name, _next_offset)();                                            \
         }                                                                                         \
         SENF_MPL_SLOT_SET(init_bytes, BOOST_PP_CAT(name,_next_init_bytes));                       \
+        static size_type const BOOST_PP_CAT(name, _group) = SENF_MPL_SLOT_GET(group) + isvar;     \
+        SENF_MPL_SLOT_SET(group, BOOST_PP_CAT(name, _group));                                     \
     access:
 #
-# define SENF_PARSER_I_ADVANCE_OFS_fix(name, type, size, isize, access)                           \
+# define SENF_PARSER_I_ADVANCE_OFS_fix(name, type, size, isize, isvar, access)                    \
         static size_type const BOOST_PP_CAT(name, _next_offset) =                                 \
             BOOST_PP_CAT(name, _offset) + size;                                                   \
     private:                                                                                      \
 # ////////////////////////////////////////
 # // SENF_PARSER_I_FIELD_VAL_*
 #
-# define SENF_PARSER_I_MAYBECALL_var() ()
-# define SENF_PARSER_I_MAYBECALL_fix()
-#
-# define SENF_PARSER_I_FIELD_VAL_rw(name, type, ofstype, access)                                  \
+# define SENF_PARSER_I_FIELD_VAL_rw(name, type, access)                                           \
+    private:                                                                                      \
+        BOOST_PP_CAT(name, _t) BOOST_PP_CAT(name, _)() const {                                    \
+            return parse<type>( SENF_PARSER_OFFSET(name) );                                       \
+        }                                                                                         \
+    access:                                                                                       \
         BOOST_PP_CAT(name, _t) name() const {                                                     \
-            return parse<type>(                                                                   \
-                BOOST_PP_CAT(name,_offset) BOOST_PP_CAT(SENF_PARSER_I_MAYBECALL_, ofstype)());    \
+            return BOOST_PP_CAT(name,_)();                                                        \
         }
 #
-# define SENF_PARSER_I_FIELD_VAL_ro(name, type, ofstype, access)                                  \
+# define SENF_PARSER_I_FIELD_VAL_ro(name, type, access)                                           \
+    private:                                                                                      \
+        BOOST_PP_CAT(name, _t) BOOST_PP_CAT(name, _)() const {                                    \
+            return parse<type>( SENF_PARSER_OFFSET(name) );                                       \
+        }                                                                                         \
+    access:                                                                                       \
         BOOST_PP_CAT(name, _t)::value_type name() const {                                         \
-            return parse<type>(                                                                   \
-                BOOST_PP_CAT(name,_offset) BOOST_PP_CAT(SENF_PARSER_I_MAYBECALL_, ofstype)())     \
-                    .value();                                                                     \
+            return BOOST_PP_CAT(name,_)();                                                        \
         }
 #
 # ///////////////////////////////////////////////////////////////////////////
 # // SENF_PARSER_CUSTOM_FIELD_*
 #
-# define SENF_PARSER_CUSTOM_FIELD_var(name, type, size, isize)                                     \
+# define SENF_PARSER_CUSTOM_FIELD_var(name, type, size, isize)                                    \
       SENF_PARSER_CUSTOM_FIELD_I(name, type, size, isize, var)
-# define SENF_PARSER_CUSTOM_FIELD_fix(name, type, size)                                            \
+# define SENF_PARSER_CUSTOM_FIELD_fix(name, type, size)                                           \
       SENF_PARSER_CUSTOM_FIELD_I(name, type, size, size, fix)
 #
 # define SENF_PARSER_CUSTOM_FIELD_I(name, type, size, isize, ofstype)                             \
         SENF_PARSER_I_FIELD_INTRO(name, type, public)                                             \
         SENF_PARSER_I_FIELD_INIT_ro(name, type, public)                                           \
         BOOST_PP_CAT(SENF_PARSER_I_FIELD_OFS_, ofstype) (name, type, public)                      \
-        BOOST_PP_CAT(SENF_PARSER_I_ADVANCE_OFS_, ofstype) (name, type, size, isize, public)       \
+        BOOST_PP_CAT(SENF_PARSER_I_ADVANCE_OFS_, ofstype) (name, type, size, isize, 1, public)    \
         BOOST_PP_CAT(name, _t) name() const
 #
 # ///////////////////////////////////////////////////////////////////////////
 # // SENF_PARSER_BITFIELD_*
 # // SENF_PARSER_P_BITFIELD_*
 #
-# define SENF_PARSER_BITFIELD_var(name, bits, type)                                                \
+# define SENF_PARSER_BITFIELD_var(name, bits, type)                                               \
       SENF_PARSER_BITFIELD_I(name, bits, type, var, rw, public)
-# define SENF_PARSER_BITFIELD_RO_var(name, bits, type)                                             \
+# define SENF_PARSER_BITFIELD_RO_var(name, bits, type)                                            \
       SENF_PARSER_BITFIELD_I(name, bits, type, var, ro, public)
-# define SENF_PARSER_BITFIELD_fix(name, bits, type)                                                \
+# define SENF_PARSER_BITFIELD_fix(name, bits, type)                                               \
       SENF_PARSER_BITFIELD_I(name, bits, type, fix, rw, public)
-# define SENF_PARSER_BITFIELD_RO_fix(name, bits, type)                                             \
+# define SENF_PARSER_BITFIELD_RO_fix(name, bits, type)                                            \
       SENF_PARSER_BITFIELD_I(name, bits, type, fix, ro, public)
 #
-# define SENF_PARSER_P_BITFIELD_var(name, bits, type)                                              \
+# define SENF_PARSER_P_BITFIELD_var(name, bits, type)                                             \
       SENF_PARSER_BITFIELD_I(name, bits, type, var, rw, private)
-# define SENF_PARSER_P_BITFIELD_RO_var(name, bits, type)                                           \
-      SENF_PARSER_BITFIELD_I(name, bits, type, var, ro, private)
-# define SENF_PARSER_P_BITFIELD_fix(name, bits, type)                                              \
+# define SENF_PARSER_P_BITFIELD_fix(name, bits, type)                                             \
       SENF_PARSER_BITFIELD_I(name, bits, type, fix, rw, private)
-# define SENF_PARSER_P_BITFIELD_RO_fix(name, bits, type)                                           \
-      SENF_PARSER_BITFIELD_I(name, bits, type, fix, ro, private)
 #
 # ////////////////////////////////////////
 # // SENF_PARSER_BITFIELD_I
 #
-# define SENF_PARSER_BITFIELD_TYPE_signed(start, bits)   senf::Parse_IntField<start, start+bits>
-# define SENF_PARSER_BITFIELD_TYPE_unsigned(start, bits) senf::Parse_UIntField<start, start+bits>
-# define SENF_PARSER_BITFIELD_TYPE_bool(start, bits)     senf::Parse_Flag<start>
+# define SENF_PARSER_BITFIELD_TYPE_signed(start, bits)   senf::IntFieldParser<start, start+bits>
+# define SENF_PARSER_BITFIELD_TYPE_unsigned(start, bits) senf::UIntFieldParser<start, start+bits>
+# define SENF_PARSER_BITFIELD_TYPE_bool(start, bits)     senf::FlagParser<start>
 #
 # define SENF_PARSER_BITFIELD_I(name, bits, type, ofstype, rwtype, access)                        \
     access:                                                                                       \
          BOOST_PP_CAT(SENF_PARSER_I_ADVANCE_OFS_, ofstype) (                                      \
              name, type,                                                                          \
              BOOST_PP_CAT(name, _t)::fixed_bytes, BOOST_PP_CAT(name, _t)::fixed_bytes,            \
+             0,                                                                                   \
              access)                                                                              \
     private:                                                                                      \
          SENF_MPL_SLOT_SET(bitfield_size, BOOST_PP_CAT(name, _t)::fixed_bytes);                   \
     access:                                                                                       \
-         BOOST_PP_CAT(SENF_PARSER_I_FIELD_VAL_, rwtype) (name, type, ofstype, access)             \
+         BOOST_PP_CAT(SENF_PARSER_I_FIELD_VAL_, rwtype) (name, type, access)                      \
     public:
 #
 # ////////////////////////////////////////
         size_type BOOST_PP_CAT(name,_offset)() const {                                            \
             return field_offset_(static_cast<senf::mpl::rv<BOOST_PP_CAT(name,_index)-1>*>(0))     \
                 - SENF_MPL_SLOT_GET(bitfield_size);                                               \
-        }
+        }                                                                                         \
+        static size_type const BOOST_PP_CAT(name, _init_bytes) =                                  \
+            SENF_MPL_SLOT_GET(init_bytes) - SENF_MPL_SLOT_GET(bitfield_size);
 #
 # define SENF_PARSER_I_BITFIELD_OFS_fix(name, type, access)                                       \
-        static size_type const BOOST_PP_CAT(name, _offset) = SENF_MPL_SLOT_GET(offset)            \
-            - SENF_MPL_SLOT_GET(bitfield_size);
+        static size_type const BOOST_PP_CAT(name, _offset) =                                      \
+            SENF_MPL_SLOT_GET(offset) - SENF_MPL_SLOT_GET(bitfield_size);
 #
 # ////////////////////////////////////////
 # // SENF_PARSER_I_BITFIELD_RESET
         SENF_MPL_SLOT_SET(bitfield_size, 0);
 #
 # ///////////////////////////////////////////////////////////////////////////
-# // SENF_PARSER_FINALIZE_*
-#
-# define SENF_PARSER_FINALIZE_var(name)                                                           \
-    SENF_PARSER_FINALIZE_GENERIC(name)                                                            \
-    size_type bytes() const {                                                                     \
-        return field_offset_(static_cast<senf::mpl::rv<SENF_MPL_SLOT_GET(index)>*>(0));           \
-    }                                                                                             \
-    static size_type const init_bytes = SENF_MPL_SLOT_GET(init_bytes)
-#
-# define SENF_PARSER_FINALIZE_fix(name)                                                           \
-    SENF_PARSER_FINALIZE_GENERIC(name)                                                            \
-    static size_type const fixed_bytes = SENF_MPL_SLOT_GET(offset);
-#
-# define SENF_PARSER_FINALIZE_GENERIC(name)                                                       \
-         void defaultInit() {                                                                     \
-             init_chain(static_cast<senf::mpl::rv<SENF_MPL_SLOT_GET(index)>*>(0));                \
-         }                                                                                        \
-         name(data_iterator i, state_type s) : parser_base_type(i,s) {}                           \
-    private:                                                                                      \
-         template <class T> void init(T) { defaultInit(); }                                       \
-    public:                                                                                       \
-         void init() { init(0); }
-#
-# ///////////////////////////////////////////////////////////////////////////
 # // SENF_PARSER_SKIP_*
 #
 # define SENF_PARSER_SKIP_var(bytes, ibytes)                                                      \
           SENF_PARSER_I_FIELD_INTRO(name, void, private)                                          \
           SENF_PARSER_I_FIELD_INIT_ro(name, void, private)                                        \
           BOOST_PP_CAT(SENF_PARSER_I_FIELD_OFS_, ofstype) (name, type, access)                    \
-          BOOST_PP_CAT(SENF_PARSER_I_ADVANCE_OFS_, ofstype) (name, void, bytes, ibytes, private)  \
+          BOOST_PP_CAT(SENF_PARSER_I_ADVANCE_OFS_, ofstype) (name, void, bytes, ibytes, 1,        \
+                                                             private)                             \
     public:
 #
 # ///////////////////////////////////////////////////////////////////////////
 # define SENF_PARSER_SKIP_BITS_fix(bits) SENF_PARSER_I_SKIP_BITS(bits, fix)
 #
 # define SENF_PARSER_I_SKIP_BITS(bits, ofstype)                                                   \
-      SENF_MPL_SLOT_SET(bit, SENF_MPL_SLOT_GET(bit) + bits)
+      private:                                                                                    \
+          SENF_MPL_SLOT_SET(bit, SENF_MPL_SLOT_GET(bit) + bits);                                  \
+      public:
 #
 # ///////////////////////////////////////////////////////////////////////////
 # // SENF_PARSER_GOTO_*
           SENF_PARSER_I_BITFIELD_RESET()                                                          \
           SENF_PARSER_I_FIELD_INTRO(name, void, private)                                          \
           SENF_PARSER_I_FIELD_INIT_ro(name, void, private)                                        \
-          BOOST_PP_CAT( SENF_PARSER_I_GOTO_SET_OFS_, ofstype ) (name, offset, initsize)            \
+          BOOST_PP_CAT( SENF_PARSER_I_GOTO_SET_OFS_, ofstype ) (name, offset, initsize)           \
       public:
 #
-# define SENF_PARSER_I_GOTO_SET_OFS_var(name, offs, initsize)                                      \
+# define SENF_PARSER_I_GOTO_SET_OFS_var(name, offs, initsize)                                     \
           size_type field_offset_(senf::mpl::rv<BOOST_PP_CAT(name,_index)>*) const {              \
               return offs;                                                                        \
           }                                                                                       \
           SENF_MPL_SLOT_SET(init_bytes, initsize);
 #
-# define SENF_PARSER_I_GOTO_SET_OFS_fix(name, offs, initsize)                                      \
+# define SENF_PARSER_I_GOTO_SET_OFS_fix(name, offs, initsize)                                     \
           SENF_MPL_SLOT_SET(offset, offs);
 #
 # ///////////////////////////////////////////////////////////////////////////
           SENF_PARSER_I_FIELD_INTRO(name, void, access)                                           \
           SENF_PARSER_I_FIELD_INIT_ro(name, void, access)                                         \
           BOOST_PP_CAT(SENF_PARSER_I_FIELD_OFS_, ofstype) (name, type, access)                    \
-          BOOST_PP_CAT(SENF_PARSER_I_ADVANCE_OFS_, ofstype) (name, void, 0, 0,access)             \
+          BOOST_PP_CAT(SENF_PARSER_I_ADVANCE_OFS_, ofstype) (name, void, 0, 0, 0, access)         \
       public:
 #
+# ///////////////////////////////////////////////////////////////////////////
+# // SENF_PARSER_OFFSET_*
+#
+# define SENF_PARSER_OFFSET_fix(name) BOOST_PP_CAT(name, _offset)
+# define SENF_PARSER_OFFSET_var(name) BOOST_PP_CAT(name, _offset)()
+#
+# ///////////////////////////////////////////////////////////////////////////
+# // SENF_PARSER_FIXED_OFFSET_*
+#
+# define SENF_PARSER_FIXED_OFFSET_fix(name) BOOST_PP_CAT(name, _offset)
+# define SENF_PARSER_FIXED_OFFSET_var(name) BOOST_PP_CAT(name, _init_bytes)
+#
+# ///////////////////////////////////////////////////////////////////////////
+# // SENF_PARSER_CURRENT_FIXED_OFFSET_*
+#
+# define SENF_PARSER_CURRENT_FIXED_OFFSET_fix() SENF_MPL_SLOT_GET(offset)
+# define SENF_PARSER_CURRENT_FIXED_OFFSET_var() SENF_MPL_SLOT_GET(init_bytes)
+#
+# ///////////////////////////////////////////////////////////////////////////
+# // SENF_PARSER_FINALIZE_*
+#
+# define SENF_PARSER_FINALIZE_var(name)                                                           \
+    SENF_PARSER_FINALIZE_GENERIC(name)                                                            \
+    size_type bytes() const {                                                                     \
+        return field_offset_(static_cast<senf::mpl::rv<SENF_MPL_SLOT_GET(index)>*>(0));           \
+    }                                                                                             \
+    static size_type const init_bytes = SENF_MPL_SLOT_GET(init_bytes)
+#
+# define SENF_PARSER_FINALIZE_fix(name)                                                           \
+    SENF_PARSER_FINALIZE_GENERIC(name)                                                            \
+    static size_type const fixed_bytes = SENF_MPL_SLOT_GET(offset);
+#
+# define SENF_PARSER_FINALIZE_GENERIC(name)                                                       \
+         void defaultInit() const {                                                               \
+             init_chain(static_cast<senf::mpl::rv<SENF_MPL_SLOT_GET(index)>*>(0));                \
+         }                                                                                        \
+         name(data_iterator i, state_type s) : parser_base_type(i,s) {}                           \
+    private:                                                                                      \
+         template <class T> void init(T) const { defaultInit(); }                                 \
+    public:                                                                                       \
+         void init() const { init(0); }
+#
+# ///////////////////////////////////////////////////////////////////////////
+# // SENF_PARSER_REQUIRE_VAR
+#
+# define SENF_PARSER_REQUIRE_VAR(description) \
+      BOOST_PP_CAT(SENF_PARSER_REQUIRE_VAR_, SENF_PARSER_TYPE)(description)
+#
+# define SENF_PARSER_REQUIRE_VAR_var(description)
+#
+# define SENF_PARSER_REQUIRE_VAR_fix(description)                                                 \
+      typedef BOOST_PP_CAT( PARSER_ERROR__,                                                       \
+                            BOOST_PP_CAT(description, _not_allowed_in_fixed_parser) )             \
+          BOOST_PP_CAT(errsym_, __LINE__);
+#
+# ///////////////////////////////////////////////////////////////////////////
+# // SENF_PARSER_COLLECTION_I
+#
+# ifndef DOXYGEN
+#
+  namespace senf { namespace detail { namespace auxtag {
+      struct none {}; } } }
+  namespace senf { namespace detail { namespace auxtag {
+      struct bytes {}; } } }
+  namespace senf { namespace detail { namespace auxtag {
+      template <class Transform, class Tag>
+      struct transform {}; } } }
+#
+# endif
+#
+# define SENF_PARSER_COLLECTION_TAG_GOBBLE__bytes(x)
+# define SENF_PARSER_COLLECTION_TAG__bytes(x) bytes()
+# define SENF_PARSER_COLLECTION_TAG_EXPAND__bytes() senf::detail::auxtag::bytes
+# define SENF_PARSER_COLLECTION_TAG_GETAUX__bytes(x) x
+#
+# // No recursive call so we need some more of theese ... ARGH !!!
+# define SENF_CAT_RECURS1(a, b) SENF_CAT_RECURS1_I(a,b)
+# define SENF_CAT_RECURS1_I(a, b) a ## b
+# define SENF_CAT_RECURS2(a, b) SENF_CAT_RECURS2_I(a,b)
+# define SENF_CAT_RECURS2_I(a, b) a ## b
+# define SENF_CAT_RECURS3(a, b) SENF_CAT_RECURS3_I(a,b)
+# define SENF_CAT_RECURS3_I(a, b) a ## b
+#
+# define SENF_PARSER_COLLECTION_TAG_GOBBLE__transform(x,y)
+# define SENF_PARSER_COLLECTION_TAG__transform(x,y) \
+      transform(x, SENF_PARSER_COLLECTION_TAG_RECURS1(y))
+# define SENF_PARSER_COLLECTION_TAG_EXPAND__transform(x,y)                                        \
+      senf::detail::auxtag::transform<                                                            \
+          x,                                                                                      \
+          SENF_CAT_RECURS1(SENF_PARSER_COLLECTION_TAG_EXPAND__, y)>
+# define SENF_PARSER_COLLECTION_TAG_GETAUX__transform(x,y) \
+      SENF_PARSER_COLLECTION_TAG_GETAUX_RECURS1(y)
+#
+# define SENF_PARSER_COLLECTION_TAG_EXPAND__none() senf::detail::auxtag::none
+#
+# define SENF_PARSER_COLLECTION_TAG_RECURS1(aux)                                                  \
+      BOOST_PP_IF(                                                                                \
+          SENF_PARSER_COLLECTION_HAS_KEYWORD(aux),                                                \
+          BOOST_PP_CAT(SENF_PARSER_COLLECTION_TAG__, aux),                                        \
+          none() )
+#
+# define SENF_PARSER_COLLECTION_TAG_GETAUX_RECURS1(aux)                                           \
+      BOOST_PP_IF(                                                                                \
+          SENF_PARSER_COLLECTION_HAS_KEYWORD(aux),                                                \
+          BOOST_PP_CAT(SENF_PARSER_COLLECTION_TAG_GETAUX__, aux),                                 \
+          aux)
+#
+# define SENF_PARSER_COLLECTION_HAS_KEYWORD(x)                                                    \
+      BOOST_PP_IS_EMPTY( SENF_CAT_RECURS1(SENF_PARSER_COLLECTION_TAG_GOBBLE__, x) )
+#
+# define SENF_PARSER_COLLECTION_GETAUX(aux)                                                       \
+      BOOST_PP_IF( SENF_PARSER_COLLECTION_HAS_KEYWORD(aux),                                       \
+                   SENF_CAT_RECURS2(SENF_PARSER_COLLECTION_TAG_GETAUX__, aux),                    \
+                   aux )
+
+# define SENF_PARSER_COLLECTION_I(access, name, aux, traits)                                      \
+      BOOST_PP_EXPAND(                                                                            \
+          SENF_PARSER_COLLECTION_II                                                               \
+              BOOST_PP_IF(                                                                        \
+                  SENF_PARSER_COLLECTION_HAS_KEYWORD(aux),                                        \
+                  ( access,                                                                       \
+                    name,                                                                         \
+                    SENF_CAT_RECURS2(SENF_PARSER_COLLECTION_TAG_GETAUX__, aux),                   \
+                    SENF_CAT_RECURS2(SENF_PARSER_COLLECTION_TAG__, aux),                          \
+                    traits ),                                                                     \
+                  ( access,                                                                       \
+                    name,                                                                         \
+                    aux,                                                                          \
+                    none(),                                                                       \
+                    traits ) ))
+#
+# define SENF_PARSER_COLLECTION_II(access, name, aux, tag, traits)                                \
+      private:                                                                                    \
+          BOOST_PP_CAT(SENF_PARSER_COLLECTION_AUXTYPE_, SENF_PARSER_TYPE)(name, aux)              \
+          typedef BOOST_PP_CAT(SENF_PARSER_COLLECTION_AUX_I_, SENF_PARSER_TYPE)(name, aux)        \
+              BOOST_PP_CAT(name,_aux_policy);                                                     \
+          typedef traits::parser<                                                                 \
+              BOOST_PP_CAT(name,_aux_policy),                                                     \
+              BOOST_PP_CAT(SENF_PARSER_COLLECTION_TAG_EXPAND__, tag)                              \
+              >::type BOOST_PP_CAT(name, _collection_t);                                          \
+      access:                                                                                     \
+          SENF_PARSER_FIELD_SETUP_I( name,                                                        \
+                                     BOOST_PP_CAT(name, _collection_t),                           \
+                                     SENF_PARSER_TYPE,                                            \
+                                     rw,                                                          \
+                                     access )                                                     \
+          BOOST_PP_CAT(SENF_PARSER_COLLECTION_VAL_, SENF_PARSER_TYPE)(name, aux, access)          \
+      public:
+#
+# define SENF_PARSER_COLLECTION_AUXTYPE_var(name, aux)                                            \
+      static bool const BOOST_PP_CAT(name, _aux_fixed) =                                          \
+          (SENF_MPL_SLOT_GET(group) - BOOST_PP_CAT(aux, _group) == 0);
+#
+# define SENF_PARSER_COLLECTION_AUXTYPE_fix(name, aux)
+#
+# ifndef DOXYGEN
+#
+  namespace senf { namespace detail {
+      template <class Parser> struct DynamicAuxParserPolicy;
+      template <class Parser, unsigned offset> struct FixedAuxParserPolicy;
+      template <class Parser, unsigned fixedOffset, bool fixedDelta>
+      struct ParserAuxPolicySelect
+      { typedef senf::detail::DynamicAuxParserPolicy<Parser> type; };
+      template <class Parser, unsigned fixedOffset>
+      struct ParserAuxPolicySelect<Parser, fixedOffset, true>
+      { typedef senf::detail::FixedAuxParserPolicy<Parser, fixedOffset> type; };
+  }};
+#
+# endif
+#
+# define SENF_PARSER_COLLECTION_AUX_I_var(name, aux)                                              \
+      senf::detail::ParserAuxPolicySelect< BOOST_PP_CAT(aux, _t),                                 \
+                                           SENF_PARSER_CURRENT_FIXED_OFFSET()                     \
+                                               - SENF_PARSER_FIXED_OFFSET(aux),                   \
+                                           BOOST_PP_CAT(name, _aux_fixed) >::type
+#
+# define SENF_PARSER_COLLECTION_AUX_I_fix(name, aux)                                              \
+      senf::detail::FixedAuxParserPolicy< BOOST_PP_CAT(aux, _t),                                  \
+                                          SENF_PARSER_CURRENT_FIXED_OFFSET()                      \
+                                              - SENF_PARSER_FIXED_OFFSET(aux) >
+#
+# define SENF_PARSER_COLLECTION_VAL_var(name,aux,access)                                          \
+      private:                                                                                    \
+          template <class T> T BOOST_PP_CAT(name, _dispatch)(boost::true_type) const              \
+          { return parse<T>( SENF_PARSER_OFFSET(name) ); }                                        \
+          template <class T> T BOOST_PP_CAT(name, _dispatch)(boost::false_type) const             \
+          { return parse<T>( BOOST_PP_CAT(aux,_)(), SENF_PARSER_OFFSET(name) ); }                 \
+          BOOST_PP_CAT(name, _t) BOOST_PP_CAT(name, _)() const                                    \
+          { return BOOST_PP_CAT(name, _dispatch) <BOOST_PP_CAT(name, _t)>(                        \
+                  boost::integral_constant<bool, BOOST_PP_CAT(name, _aux_fixed)>()); }            \
+      access:                                                                                     \
+          BOOST_PP_CAT(name, _t) name() const                                                     \
+          { return BOOST_PP_CAT(name, _)(); }
+#
+# define SENF_PARSER_COLLECTION_VAL_fix(name,aux,access)                                          \
+      private:                                                                                    \
+          BOOST_PP_CAT(name, _t) BOOST_PP_CAT(name, _)() const                                    \
+          { return parse<BOOST_PP_CAT(name, _t)>( SENF_PARSER_OFFSET(name) ); }                   \
+      access:                                                                                     \
+          BOOST_PP_CAT(name, _t) name() const                                                     \
+          { return BOOST_PP_CAT(name, _)(); }
+#
 # ////////////////////////////////ih.e///////////////////////////////////////
 # endif
 #