Packets: Update AuxParser interface
[senf.git] / Packets / ParseHelpers.ih
index d936097..18f58e5 100644 (file)
@@ -26,6 +26,9 @@
 #
 # // 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 "../Utils/mpl.hh"
 #
 # ////////////////////////////////ih.p///////////////////////////////////////
 # ///////////////////////////////////////////////////////////////////////////
 # // SENF_PARSER_COLLECTION_I
 #
-  namespace senf { namespace detail { namespace auxtag { struct none {}; } } }
+  namespace senf { namespace detail { namespace auxtag { 
+      struct none {}; } } }
+  namespace senf { namespace detail { namespace auxtag { 
+      struct bytes {}; } } }
+  namespace senf { namespace detail { namespace auxtag { 
+      template <class T> 
+      struct transform {}; } } }
+#
+# define SENF_PARSER_COLLECTION_TAG_GOBBLE__bytes(x)
+# define SENF_PARSER_COLLECTION_TAG__bytes(x) senf::detail::auxtag::bytes
+# define SENF_PARSER_COLLECTION_TAG_GETAUX__bytes(x) x
+#
+# define SENF_PARSER_COLLECTION_TAG_GOBBLE__transform(x,y)
+# define SENF_PARSER_COLLECTION_TAG__transform(x,y) senf::detail::auxtag::transform<x>
+# define SENF_PARSER_COLLECTION_TAG_GETAUX__transform(x,y) y
+#
+# define SENF_PARSER_COLLECTION_HAS_KEYWORD(x)                                                    \
+      BOOST_PP_IS_EMPTY( BOOST_PP_CAT(SENF_PARSER_COLLECTION_TAG_GOBBLE__, x) )
 #
 # 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,                                                                         \
+                    BOOST_PP_CAT(SENF_PARSER_COLLECTION_TAG_GETAUX__, aux),                       \
+                    BOOST_PP_CAT(SENF_PARSER_COLLECTION_TAG__, aux),                              \
+                    traits ),                                                                     \
+                  ( access,                                                                       \
+                    name,                                                                         \
+                    aux,                                                                          \
+                    senf::detail::auxtag::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),                                                     \
-              senf::detail::auxtag::none                                                          \
+              tag                                                                                 \
               >::type BOOST_PP_CAT(name, _collection_t);                                          \
       access:                                                                                     \
           SENF_PARSER_FIELD_SETUP_I( name,                                                        \
                                           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(name, _aux_policy)(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                                                      \
+# 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>( 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)                                          \