Packets: Implement basic AuxParser
g0dil [Fri, 6 Jun 2008 08:02:26 +0000 (08:02 +0000)]
Packets: Implement generic internel collection parser macro infrastructure
Packets: Update VectorParser to use the new AuxParser/collection infrastructure

git-svn-id: https://svn.berlios.de/svnroot/repos/senf/trunk@868 270642c3-0616-0410-b53a-bc976706d245

12 files changed:
Packets/AuxParser.cti [new file with mode: 0644]
Packets/AuxParser.hh [new file with mode: 0644]
Packets/PacketParser.cti
Packets/PacketParser.hh
Packets/PacketParser.ih
Packets/Packets.hh
Packets/ParseHelpers.ih
Packets/VectorParser.ct
Packets/VectorParser.cti
Packets/VectorParser.hh
Packets/VectorParser.ih
Packets/VectorParser.test.cc

diff --git a/Packets/AuxParser.cti b/Packets/AuxParser.cti
new file mode 100644 (file)
index 0000000..205d88d
--- /dev/null
@@ -0,0 +1,146 @@
+// $Id$
+//
+// Copyright (C) 2008 
+// 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
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc.,
+// 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+/** \file
+    \brief AuxParser inline template implementation */
+
+//#include "AuxParser.ih"
+
+// Custom includes
+
+#define prefix_ inline
+///////////////////////////////cti.p///////////////////////////////////////
+
+///////////////////////////////////////////////////////////////////////////
+// senf::detail::PrefixAuxParserPolicy<P>
+
+template <class P>
+prefix_ typename senf::detail::PrefixAuxParserPolicy<P>::ParserType
+senf::detail::PrefixAuxParserPolicy<P>::aux(PacketParserBase::data_iterator i,
+                                            PacketParserBase::state_type s)
+    const
+{
+    return ParserType(i, s);
+}
+
+template <class P>
+prefix_ senf::PacketParserBase::data_iterator
+senf::detail::PrefixAuxParserPolicy<P>::adjust(PacketParserBase::data_iterator i,
+                                               PacketParserBase::state_type s)
+    const
+{
+    return i+ParserType::fixed_bytes;
+}
+
+///////////////////////////////////////////////////////////////////////////
+// senf::detail::FixedAuxParserPolicy<P>
+
+template <class P, unsigned Dist>
+prefix_ typename senf::detail::FixedAuxParserPolicy<P,Dist>::ParserType
+senf::detail::FixedAuxParserPolicy<P,Dist>::aux(PacketParserBase::data_iterator i,
+                                                PacketParserBase::state_type s)
+    const
+{
+    return ParserType(i-Dist, s);
+}
+
+template <class P, unsigned Dist>
+prefix_ senf::PacketParserBase::data_iterator
+senf::detail::FixedAuxParserPolicy<P,Dist>::adjust(PacketParserBase::data_iterator i,
+                                                   PacketParserBase::state_type s)
+    const
+{
+    return i;
+}
+
+///////////////////////////////////////////////////////////////////////////
+// senf::detail::DynamicAuxParserPolicy<P>
+
+template <class P>
+prefix_ senf::detail::DynamicAuxParserPolicy<P>::DynamicAuxParserPolicy(ParserType p)
+    : p_ (p)
+{}
+
+template <class P>
+prefix_
+senf::detail::DynamicAuxParserPolicy<P>::DynamicAuxParserPolicy(WrapperPolicy const & other)
+    : p_ (* other.p_)
+{}
+
+template <class P>
+prefix_ typename senf::detail::DynamicAuxParserPolicy<P>::ParserType
+senf::detail::DynamicAuxParserPolicy<P>::aux(PacketParserBase::data_iterator i,
+                                             PacketParserBase::state_type s)
+    const
+{
+    return p_;
+}
+
+template <class P>
+prefix_ senf::PacketParserBase::data_iterator
+senf::detail::DynamicAuxParserPolicy<P>::adjust(PacketParserBase::data_iterator i,
+                                                PacketParserBase::state_type s)
+    const
+{
+    return i;
+}
+
+///////////////////////////////////////////////////////////////////////////
+// senf::detail::DynamicWrapperAuxParserPolicy<P>
+
+template <class P>
+prefix_ senf::detail::DynamicWrapperAuxParserPolicy<P>::
+DynamicWrapperAuxParserPolicy(ParserPolicy const & other)
+    : p_ (other.p_)
+{}
+
+template <class P>
+prefix_ typename senf::detail::DynamicWrapperAuxParserPolicy<P>::ParserType
+senf::detail::DynamicWrapperAuxParserPolicy<P>::aux(PacketParserBase::data_iterator i,
+                                                    PacketParserBase::state_type s)
+    const
+{
+    return * p_;
+}
+
+template <class P>
+prefix_ senf::PacketParserBase::data_iterator
+senf::detail::DynamicWrapperAuxParserPolicy<P>::adjust(PacketParserBase::data_iterator i,
+                                                       PacketParserBase::state_type s)
+    const
+{
+    return i;
+}
+
+///////////////////////////////cti.e///////////////////////////////////////
+#undef prefix_
+
+\f
+// Local Variables:
+// mode: c++
+// fill-column: 100
+// comment-column: 40
+// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
+// compile-command: "scons -u test"
+// End:
diff --git a/Packets/AuxParser.hh b/Packets/AuxParser.hh
new file mode 100644 (file)
index 0000000..162657e
--- /dev/null
@@ -0,0 +1,121 @@
+// $Id$
+//
+// Copyright (C) 2008 
+// 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
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc.,
+// 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+/** \file
+    \brief AuxParser public header */
+
+#ifndef HH_AuxParser_
+#define HH_AuxParser_ 1
+
+#ifndef HH_Packets_
+#error "Don't include 'AuxParser.hh' directly, include 'Packets.hh'"
+#endif
+
+// Custom includes
+#include "PacketParser.hh"
+#include "SafeIterator.hh"
+
+//#include "AuxParser.mpp"
+///////////////////////////////hh.p////////////////////////////////////////
+
+namespace senf {
+namespace detail {
+
+    template <class P>
+    struct PrefixAuxParserPolicy
+    {
+        typedef PrefixAuxParserPolicy WrapperPolicy;
+        typedef P ParserType;
+
+        static PacketParserBase::size_type const aux_bytes = ParserType::fixed_bytes;
+        
+        ParserType aux(PacketParserBase::data_iterator i, PacketParserBase::state_type s) const;
+        PacketParserBase::data_iterator adjust(PacketParserBase::data_iterator i, PacketParserBase::state_type s) const;
+    };
+
+    template <class P, unsigned Dist>
+    struct FixedAuxParserPolicy
+    {
+        typedef FixedAuxParserPolicy WrapperPolicy;
+        typedef P ParserType;
+
+        static PacketParserBase::size_type const aux_bytes = 0;
+        
+        ParserType aux(PacketParserBase::data_iterator i, PacketParserBase::state_type s) const;
+        PacketParserBase::data_iterator adjust(PacketParserBase::data_iterator i, PacketParserBase::state_type s) const;
+    };
+
+    template <class P> struct DynamicWrapperAuxParserPolicy;
+    
+    template <class P>
+    struct DynamicAuxParserPolicy
+    {
+        typedef DynamicWrapperAuxParserPolicy<P> WrapperPolicy;
+        typedef P ParserType;
+
+        static PacketParserBase::size_type const aux_bytes = 0;
+
+        DynamicAuxParserPolicy(ParserType p);
+        DynamicAuxParserPolicy(WrapperPolicy const & other);
+        
+        ParserType aux(PacketParserBase::data_iterator i, PacketParserBase::state_type s) const;
+        PacketParserBase::data_iterator adjust(PacketParserBase::data_iterator i, PacketParserBase::state_type s) const;
+
+        ParserType p_;
+    };
+
+    template <class P>
+    struct DynamicWrapperAuxParserPolicy
+    {
+        typedef DynamicAuxParserPolicy<P> ParserPolicy;
+        typedef P ParserType;
+
+        static PacketParserBase::size_type const aux_bytes = 0;
+
+        DynamicWrapperAuxParserPolicy(ParserPolicy const & other);
+        
+        ParserType aux(PacketParserBase::data_iterator i, PacketParserBase::state_type s) const;
+        PacketParserBase::data_iterator adjust(PacketParserBase::data_iterator i, PacketParserBase::state_type s) const;
+
+        SafePacketParserWrapper<ParserType> p_;
+    };
+}}
+
+///////////////////////////////hh.e////////////////////////////////////////
+#endif
+#if !defined(HH_Packets__decls_) && !defined(HH_AuxParser_i_)
+#define HH_AuxParser_i_
+//#include "AuxParser.cci"
+//#include "AuxParser.ct"
+#include "AuxParser.cti"
+#endif
+
+\f
+// Local Variables:
+// mode: c++
+// fill-column: 100
+// comment-column: 40
+// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
+// compile-command: "scons -u test"
+// End:
index 9cb4968..098908f 100644 (file)
@@ -42,6 +42,13 @@ prefix_ Parser senf::PacketParserBase::parse(data_iterator i)
     return Parser(i,state());
 }
 
+template <class Parser, class Arg>
+prefix_ Parser senf::PacketParserBase::parse(Arg const & arg, data_iterator i)
+    const
+{
+    return Parser(arg, i, state());
+}
+
 template <class Parser>
 prefix_ Parser senf::PacketParserBase::parse(size_type n)
     const
@@ -49,6 +56,13 @@ prefix_ Parser senf::PacketParserBase::parse(size_type n)
     return Parser(boost::next(i(),n),state());
 }
 
+template <class Parser, class Arg>
+prefix_ Parser senf::PacketParserBase::parse(Arg const & arg, size_type n)
+    const
+{
+    return Parser(arg, boost::next(i(),n), state());
+}
+
 ///////////////////////////////////////////////////////////////////////////
 // namespace members
 
index c85ff2f..1e389da 100644 (file)
@@ -328,11 +328,22 @@ namespace senf {
                                              beginning at \a i. Automatically passes \a state() to
                                              the new parser. */
 
+        template <class Parser, class Arg> Parser parse(Arg const & arg, data_iterator i) const;
+                                        ///< Create sub-parser
+                                        /**< This is like parse(data_iterator), however it passes
+                                             the extra argument \a arg to the \a Parser
+                                             constructor. */
+
         template <class Parser> Parser parse(size_type n) const; ///< Create sub-parser
                                         /**< Creates a new instance of \a Parser to parse data
                                          * beginning at i()<tt> + </tt>\a n. Automatically passes \a
                                              state() to the new parser. */
 
+        template <class Parser, class Arg> Parser parse(Arg const & arg, size_type n) const;
+                                        ///< Create sub-parser
+                                        /**< This is like parse(size_type), however it passes the
+                                             extra argument \a arg to the \a Parser constructor. */
+
         void defaultInit() const;       ///< Default implementation
                                         /**< This is just an empty default
                                              implementation. Re-implement this member in your own
@@ -370,6 +381,7 @@ namespace senf {
     PacketParserBase::size_type bytes(Parser p);
     
     namespace detail { template <class Parser> class ParserInitBytes; }
+    namespace detail { template <class Parser> class ParserIsFixed; }
 
     /** \brief Return number of bytes to allocate to new object of given type
 
@@ -390,6 +402,10 @@ namespace senf {
     struct init_bytes : public detail::ParserInitBytes<Parser>
     {};
 
+    template <class Parser>
+    struct is_fixed : public detail::ParserIsFixed<Parser>
+    {};
+
 #   ifndef DOXYGEN
     template <class Parser>
     typename boost::enable_if< 
index 450bc03..4596ea8 100644 (file)
@@ -84,6 +84,18 @@ namespace detail {
     struct ParserInitBytes
         : public ParserInitBytes_Choose<Parser,SENF_MPL_RV(ParserInitBytes_Choose_<Parser>(0))> {};
 
+    template <class Parser, unsigned _>
+    struct ParserIsFixed_Choose
+        : public boost::false_type {};
+
+    template <class Parser>
+    struct ParserIsFixed_Choose<Parser, 1>
+        : public boost::true_type {};
+
+    template <class Parser>
+    struct ParserIsFixed
+        : public ParserIsFixed_Choose<Parser,SENF_MPL_RV(ParserInitBytes_Choose_<Parser>(0))> {};
+
 #   endif
 
 }}
index 6cd5626..90036c0 100644 (file)
@@ -38,6 +38,7 @@
 #include "PacketParser.hh"
 #include "SafeIterator.hh"
 #include "ArrayParser.hh"
+#include "AuxParser.hh"
 #include "ListParser.hh"
 #include "ListBParser.hh"
 #include "ListNParser.hh"
@@ -59,6 +60,7 @@
 #include "SafeIterator.hh"
 #include "ArrayParser.hh"
 #include "IntParser.hh"
+#include "AuxParser.hh"
 #include "ListParser.hh"
 #include "ListBParser.hh"
 #include "ListNParser.hh"
index 7e67282..d936097 100644 (file)
@@ -50,6 +50,7 @@
         SENF_MPL_SLOT_DEF_ZERO(init_bytes);                                                       \
         SENF_MPL_SLOT_DEF_ZERO(bit);                                                              \
         SENF_MPL_SLOT_DEF_ZERO(bitfield_size);                                                    \
+        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:
 #
 # 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, access)                       \
-    public:
+            BOOST_PP_CAT(SENF_PARSER_I_ISVAR_, ofstype) (name, type),                             \
+            access )
 #
 # ////////////////////////////////////////
 # // SENF_PARSER_I_FIELD_INTRO
 # ////////////////////////////////////////
 # // 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;                                           \
         }                                                                                         \
             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_FIELD_VAL_rw(name, type, access)                                           \
-        BOOST_PP_CAT(name, _t) name() const {                                                     \
+    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 BOOST_PP_CAT(name,_)();                                                        \
         }
 #
 # define SENF_PARSER_I_FIELD_VAL_ro(name, type, access)                                           \
         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
 #
 # ///////////////////////////////////////////////////////////////////////////
          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);                   \
           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:
 #
 # ///////////////////////////////////////////////////////////////////////////
           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:
 #
 # ///////////////////////////////////////////////////////////////////////////
 # define SENF_PARSER_FIXED_OFFSET_var(name) BOOST_PP_CAT(name, _init_bytes)
 #
 # ///////////////////////////////////////////////////////////////////////////
-# // SENF_PARSER_FIXED_OFFSET_*
+# // 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)
     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
+#
+  namespace senf { namespace detail { namespace auxtag { struct none {}; } } }
+#
+# define SENF_PARSER_COLLECTION_I(access, name, aux, 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                                                          \
+              >::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)
+#
+  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; };
+  }};
+#
+# 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(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                                                      \
+          { 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
 #
index 7d15db4..fb89187 100644 (file)
@@ -37,7 +37,7 @@ template <class ElementParser, class Sizer>
 prefix_ void senf::VectorParser<ElementParser,Sizer>::init()
     const
 {
-    sizer_.init(i(),state());
+    aux(i(), state()) = 0;
     iterator i (begin());
     iterator const e (end());
     for (; i!=e; ++i)
index 4ecf3bb..430427f 100644 (file)
 ///////////////////////////////////////////////////////////////////////////
 // senf::VectorParser<ElementParser,Sizer>
 
-template <class ElementParser, class Sizer>
-prefix_ senf::VectorParser<ElementParser,Sizer>::VectorParser(data_iterator i, state_type s)
-    : PacketParserBase(i,s), sizer_()
+template <class ElementParser, class AuxPolicy>
+prefix_ senf::VectorParser<ElementParser,AuxPolicy>::VectorParser(data_iterator i, state_type s)
+    : PacketParserBase(i,s), AuxPolicy()
 {}
 
-template <class ElementParser, class Sizer>
-prefix_ senf::VectorParser<ElementParser,Sizer>::VectorParser(Sizer sizer, data_iterator i,
-                                                              state_type s)
-    : PacketParserBase(i,s), sizer_(sizer)
+template <class ElementParser, class AuxPolicy>
+prefix_ senf::VectorParser<ElementParser,AuxPolicy>::VectorParser(AuxPolicy policy,
+                                                                  data_iterator i, state_type s)
+    : PacketParserBase(i,s), AuxPolicy(policy)
 {}
 
-template <class ElementParser, class Sizer>
-prefix_ typename senf::VectorParser<ElementParser,Sizer>::size_type
-senf::VectorParser<ElementParser,Sizer>::bytes()
+template <class ElementParser, class AuxPolicy>
+prefix_ typename senf::VectorParser<ElementParser,AuxPolicy>::size_type
+senf::VectorParser<ElementParser,AuxPolicy>::bytes()
     const
 {
-    return size()*ElementParser::fixed_bytes + sizer_.bytes(i(),state());
+    return size()*ElementParser::fixed_bytes + AuxPolicy::aux_bytes;
 }
 
 // Container interface
 
-template <class ElementParser, class Sizer>
-prefix_ typename senf::VectorParser<ElementParser,Sizer>::size_type
-senf::VectorParser<ElementParser,Sizer>::size()
+template <class ElementParser, class AuxPolicy>
+prefix_ typename senf::VectorParser<ElementParser,AuxPolicy>::size_type
+senf::VectorParser<ElementParser,AuxPolicy>::size()
     const
 {
-    return sizer_.size(i(),state());
+    return aux(i(),state());
 }
 
-template <class ElementParser, class Sizer>
-prefix_ bool senf::VectorParser<ElementParser,Sizer>::empty()
+template <class ElementParser, class AuxPolicy>
+prefix_ bool senf::VectorParser<ElementParser,AuxPolicy>::empty()
     const
 {
     return size()==0;
 }
 
-template <class ElementParser, class Sizer>
-prefix_ typename senf::VectorParser<ElementParser,Sizer>::iterator
-senf::VectorParser<ElementParser,Sizer>::begin()
+template <class ElementParser, class AuxPolicy>
+prefix_ typename senf::VectorParser<ElementParser,AuxPolicy>::iterator
+senf::VectorParser<ElementParser,AuxPolicy>::begin()
     const
 {
-    return iterator(sizer_.begin(i(),state()),state());
+    return iterator(adjust(i(),state()),state());
 }
 
-template <class ElementParser, class Sizer>
-prefix_ typename senf::VectorParser<ElementParser,Sizer>::iterator
-senf::VectorParser<ElementParser,Sizer>::end()
+template <class ElementParser, class AuxPolicy>
+prefix_ typename senf::VectorParser<ElementParser,AuxPolicy>::iterator
+senf::VectorParser<ElementParser,AuxPolicy>::end()
     const
 {
     return boost::next(begin(),size());
 }
 
-template <class ElementParser, class Sizer>
-prefix_ typename senf::VectorParser<ElementParser,Sizer>::value_type
-senf::VectorParser<ElementParser,Sizer>::operator[](difference_type i)
+template <class ElementParser, class AuxPolicy>
+prefix_ typename senf::VectorParser<ElementParser,AuxPolicy>::value_type
+senf::VectorParser<ElementParser,AuxPolicy>::operator[](difference_type i)
     const
 {
     return begin()[i];
 }
 
-template <class ElementParser, class Sizer>
-prefix_ typename senf::VectorParser<ElementParser,Sizer>::value_type
-senf::VectorParser<ElementParser,Sizer>::front()
+template <class ElementParser, class AuxPolicy>
+prefix_ typename senf::VectorParser<ElementParser,AuxPolicy>::value_type
+senf::VectorParser<ElementParser,AuxPolicy>::front()
     const
 {
     return begin()[0];
 }
 
-template <class ElementParser, class Sizer>
-prefix_ typename senf::VectorParser<ElementParser,Sizer>::value_type
-senf::VectorParser<ElementParser,Sizer>::back()
+template <class ElementParser, class AuxPolicy>
+prefix_ typename senf::VectorParser<ElementParser,AuxPolicy>::value_type
+senf::VectorParser<ElementParser,AuxPolicy>::back()
     const
 {
     return begin()[size()-1];
@@ -111,51 +111,51 @@ senf::VectorParser<ElementParser,Sizer>::back()
 
 // Mutators
 
-template <class ElementParser, class Sizer>
+template <class ElementParser, class AuxPolicy>
 template <class Value>
-prefix_ void senf::VectorParser<ElementParser,Sizer>::push_back(Value value, size_type n)
+prefix_ void senf::VectorParser<ElementParser,AuxPolicy>::push_back(Value value, size_type n)
     const
 {
     container c (*this);
     c.push_back(value,n);
 }
 
-template <class ElementParser, class Sizer>
-prefix_ void senf::VectorParser<ElementParser,Sizer>::push_back_space(size_type n)
+template <class ElementParser, class AuxPolicy>
+prefix_ void senf::VectorParser<ElementParser,AuxPolicy>::push_back_space(size_type n)
     const
 {
     container c (*this);
     c.push_back_space(n);
 }
 
-template <class ElementParser, class Sizer>
+template <class ElementParser, class AuxPolicy>
 template <class Value>
-prefix_ void senf::VectorParser<ElementParser,Sizer>::push_front(Value value, size_type n)
+prefix_ void senf::VectorParser<ElementParser,AuxPolicy>::push_front(Value value, size_type n)
     const
 {
     container c (*this);
     c.push_front(value,n);
 }
 
-template <class ElementParser, class Sizer>
-prefix_ void senf::VectorParser<ElementParser,Sizer>::push_front_space(size_type n)
+template <class ElementParser, class AuxPolicy>
+prefix_ void senf::VectorParser<ElementParser,AuxPolicy>::push_front_space(size_type n)
     const
 {
     container c (*this);
     c.push_front_space(n);
 }
 
-template <class ElementParser, class Sizer>
-prefix_ void senf::VectorParser<ElementParser,Sizer>::resize(size_type n)
+template <class ElementParser, class AuxPolicy>
+prefix_ void senf::VectorParser<ElementParser,AuxPolicy>::resize(size_type n)
     const
 {
     container c (*this);
     c.resize(n);
 }
 
-template <class ElementParser, class Sizer>
+template <class ElementParser, class AuxPolicy>
 template <class Value>
-prefix_ void senf::VectorParser<ElementParser,Sizer>::resize(size_type n, Value value)
+prefix_ void senf::VectorParser<ElementParser,AuxPolicy>::resize(size_type n, Value value)
     const
 {
     container c (*this);
@@ -163,48 +163,6 @@ prefix_ void senf::VectorParser<ElementParser,Sizer>::resize(size_type n, Value
 }
 
 ///////////////////////////////////////////////////////////////////////////
-// senf::SimpleSizeParser<SizeParser,offset>
-
-template <class SizeParser, unsigned Distance>
-prefix_ typename senf::detail::VectorNParser_Sizer<SizeParser,Distance>::size_type
-senf::detail::VectorNParser_Sizer<SizeParser,Distance>::size(iterator i, state_type s)
-    const
-{
-    return SizeParser(boost::prior(i, Distance), s).value();
-}
-
-template <class SizeParser, unsigned Distance>
-prefix_ void senf::detail::VectorNParser_Sizer<SizeParser,Distance>::size(iterator i,
-                                                                          state_type s,
-                                                                          size_type v)
-    const
-{
-    SizeParser(boost::prior(i, Distance), s).value(v);
-}
-
-template <class SizeParser, unsigned Distance>
-prefix_ typename senf::detail::VectorNParser_Sizer<SizeParser,Distance>::iterator
-senf::detail::VectorNParser_Sizer<SizeParser,Distance>::begin(iterator i, state_type s)
-    const
-{
-    return i;
-}
-
-template <class SizeParser, unsigned Distance>
-prefix_ typename senf::detail::VectorNParser_Sizer<SizeParser,Distance>::size_type
-senf::detail::VectorNParser_Sizer<SizeParser,Distance>::bytes(iterator i, state_type s)
-    const
-{
-    return 0;
-}
-
-template <class SizeParser, unsigned Distance>
-prefix_ void senf::detail::VectorNParser_Sizer<SizeParser,Distance>::init(iterator i,
-                                                                          state_type s)
-    const
-{}
-
-///////////////////////////////////////////////////////////////////////////
 // senf::VectorParser_wrapper<Parser,SizeParser,Container>
 
 // structors and default members
@@ -212,65 +170,65 @@ prefix_ void senf::detail::VectorNParser_Sizer<SizeParser,Distance>::init(iterat
 // hm ... be careful here ! the data() member is called in an incompletely intitialized
 // instance. However, data() only depends on state_ which is initialized before the call. YOU MUST
 // NOT CHANGE THE ORDERING OF THE DATA MEMBERS
-template <class ElementParser, class Sizer>
-prefix_ senf::VectorParser_Container<ElementParser,Sizer>::
+template <class ElementParser, class AuxPolicy>
+prefix_ senf::VectorParser_Container<ElementParser,AuxPolicy>::
 VectorParser_Container(parser_type const & vector)
-    : sizer_ (vector.sizer_), state_ (vector.state()), 
+    : AuxPolicy(vector), state_ (vector.state()), 
       i_ (std::distance(data().begin(),vector.i()))
 {}
 
 // accessors
 
-template <class ElementParser, class Sizer>
-prefix_ typename senf::VectorParser_Container<ElementParser,Sizer>::size_type
-senf::VectorParser_Container<ElementParser,Sizer>::size()
+template <class ElementParser, class AuxPolicy>
+prefix_ typename senf::VectorParser_Container<ElementParser,AuxPolicy>::size_type
+senf::VectorParser_Container<ElementParser,AuxPolicy>::size()
     const
 {
-    return sizer_.size(i(),state());
+    return aux(i(),state());
 }
 
-template <class ElementParser, class Sizer>
-prefix_ bool senf::VectorParser_Container<ElementParser,Sizer>::empty()
+template <class ElementParser, class AuxPolicy>
+prefix_ bool senf::VectorParser_Container<ElementParser,AuxPolicy>::empty()
     const
 {
     return size() == 0;
 }
 
-template <class ElementParser, class Sizer>
-prefix_ typename senf::VectorParser_Container<ElementParser,Sizer>::iterator
-senf::VectorParser_Container<ElementParser,Sizer>::begin()
+template <class ElementParser, class AuxPolicy>
+prefix_ typename senf::VectorParser_Container<ElementParser,AuxPolicy>::iterator
+senf::VectorParser_Container<ElementParser,AuxPolicy>::begin()
     const
 {
-    return iterator(sizer_.begin(i(),state()),state());
+    return iterator(adjust(i(),state()),state());
 }
 
-template <class ElementParser, class Sizer>
-prefix_ typename senf::VectorParser_Container<ElementParser,Sizer>::iterator
-senf::VectorParser_Container<ElementParser,Sizer>::end()
+template <class ElementParser, class AuxPolicy>
+prefix_ typename senf::VectorParser_Container<ElementParser,AuxPolicy>::iterator
+senf::VectorParser_Container<ElementParser,AuxPolicy>::end()
     const
 {
     return boost::next(begin(),size());
 }
 
-template <class ElementParser, class Sizer>
-prefix_ typename senf::VectorParser_Container<ElementParser,Sizer>::value_type
-senf::VectorParser_Container<ElementParser,Sizer>::operator[](difference_type i)
+template <class ElementParser, class AuxPolicy>
+prefix_ typename senf::VectorParser_Container<ElementParser,AuxPolicy>::value_type
+senf::VectorParser_Container<ElementParser,AuxPolicy>::operator[](difference_type i)
     const
 {
     return begin()[i];
 }
 
-template <class ElementParser, class Sizer>
-prefix_ typename senf::VectorParser_Container<ElementParser,Sizer>::value_type
-senf::VectorParser_Container<ElementParser,Sizer>::front()
+template <class ElementParser, class AuxPolicy>
+prefix_ typename senf::VectorParser_Container<ElementParser,AuxPolicy>::value_type
+senf::VectorParser_Container<ElementParser,AuxPolicy>::front()
     const
 {
     return begin()[0];
 }
 
-template <class ElementParser, class Sizer>
-prefix_ typename senf::VectorParser_Container<ElementParser,Sizer>::value_type
-senf::VectorParser_Container<ElementParser,Sizer>::back()
+template <class ElementParser, class AuxPolicy>
+prefix_ typename senf::VectorParser_Container<ElementParser,AuxPolicy>::value_type
+senf::VectorParser_Container<ElementParser,AuxPolicy>::back()
     const
 {
     return begin()[size()-1];
@@ -278,109 +236,109 @@ senf::VectorParser_Container<ElementParser,Sizer>::back()
 
 // Mutators
 
-template <class ElementParser, class Sizer>
+template <class ElementParser, class AuxPolicy>
 template <class Value>
-prefix_ void senf::VectorParser_Container<ElementParser,Sizer>::insert(iterator pos,
+prefix_ void senf::VectorParser_Container<ElementParser,AuxPolicy>::insert(iterator pos,
                                                                        Value const & t)
 {
     *shift(pos) << t;
 }
 
-template <class ElementParser, class Sizer>
-prefix_ void senf::VectorParser_Container<ElementParser,Sizer>::erase(iterator pos, size_type n)
+template <class ElementParser, class AuxPolicy>
+prefix_ void senf::VectorParser_Container<ElementParser,AuxPolicy>::erase(iterator pos, size_type n)
 {
     data().erase(pos.raw(),boost::next(pos.raw(),n*ElementParser::fixed_bytes));
     setSize(size()-n);
 }
 
-template <class ElementParser, class Sizer>
-prefix_ void senf::VectorParser_Container<ElementParser,Sizer>::erase(iterator f, iterator l)
+template <class ElementParser, class AuxPolicy>
+prefix_ void senf::VectorParser_Container<ElementParser,AuxPolicy>::erase(iterator f, iterator l)
 {
     erase(f,std::distance(f,l));
 }
 
-template <class ElementParser, class Sizer>
-prefix_ void senf::VectorParser_Container<ElementParser,Sizer>::clear()
+template <class ElementParser, class AuxPolicy>
+prefix_ void senf::VectorParser_Container<ElementParser,AuxPolicy>::clear()
 {
     erase(begin(),end());
 }
 
-template <class ElementParser, class Sizer>
+template <class ElementParser, class AuxPolicy>
 template <class Value>
-prefix_ void senf::VectorParser_Container<ElementParser,Sizer>::push_back(Value value,
+prefix_ void senf::VectorParser_Container<ElementParser,AuxPolicy>::push_back(Value value,
                                                                           size_type n)
 {
     insert(end(),n,value);
 }
 
-template <class ElementParser, class Sizer>
-prefix_ void senf::VectorParser_Container<ElementParser,Sizer>::push_back_space(size_type n)
+template <class ElementParser, class AuxPolicy>
+prefix_ void senf::VectorParser_Container<ElementParser,AuxPolicy>::push_back_space(size_type n)
 {
     shift(end(),n);
 }
 
-template <class ElementParser, class Sizer>
+template <class ElementParser, class AuxPolicy>
 template <class Value>
-prefix_ void senf::VectorParser_Container<ElementParser,Sizer>::push_front(Value value,
+prefix_ void senf::VectorParser_Container<ElementParser,AuxPolicy>::push_front(Value value,
                                                                            size_type n)
 {
     insert(begin(),n,value);
 }
 
-template <class ElementParser, class Sizer>
-prefix_ void senf::VectorParser_Container<ElementParser,Sizer>::push_front_space(size_type n)
+template <class ElementParser, class AuxPolicy>
+prefix_ void senf::VectorParser_Container<ElementParser,AuxPolicy>::push_front_space(size_type n)
 {
     shift(begin(),n);
 }
 
 // Parser interface
 
-template <class ElementParser, class Sizer>
-prefix_ typename senf::VectorParser_Container<ElementParser,Sizer>::parser_type
-senf::VectorParser_Container<ElementParser,Sizer>::parser()
+template <class ElementParser, class AuxPolicy>
+prefix_ typename senf::VectorParser_Container<ElementParser,AuxPolicy>::parser_type
+senf::VectorParser_Container<ElementParser,AuxPolicy>::parser()
     const
 {
     return parser_type(i(),state());
 }
 
-template <class ElementParser, class Sizer>
-prefix_ typename senf::VectorParser_Container<ElementParser,Sizer>::data_iterator
-senf::VectorParser_Container<ElementParser,Sizer>::i()
+template <class ElementParser, class AuxPolicy>
+prefix_ typename senf::VectorParser_Container<ElementParser,AuxPolicy>::data_iterator
+senf::VectorParser_Container<ElementParser,AuxPolicy>::i()
     const
 {
     return boost::next(data().begin(),i_);
 }
 
-template <class ElementParser, class Sizer>
-prefix_ typename senf::VectorParser_Container<ElementParser,Sizer>::state_type
-senf::VectorParser_Container<ElementParser,Sizer>::state()
+template <class ElementParser, class AuxPolicy>
+prefix_ typename senf::VectorParser_Container<ElementParser,AuxPolicy>::state_type
+senf::VectorParser_Container<ElementParser,AuxPolicy>::state()
     const
 {
     return state_;
 }
 
-template <class ElementParser, class Sizer>
+template <class ElementParser, class AuxPolicy>
 prefix_ senf::PacketData &
-senf::VectorParser_Container<ElementParser,Sizer>::data()
+senf::VectorParser_Container<ElementParser,AuxPolicy>::data()
     const
 {
     return *state_;
 }
 
-template <class ElementParser, class Sizer>
-prefix_ typename senf::VectorParser_Container<ElementParser,Sizer>::size_type
-senf::VectorParser_Container<ElementParser,Sizer>::bytes()
+template <class ElementParser, class AuxPolicy>
+prefix_ typename senf::VectorParser_Container<ElementParser,AuxPolicy>::size_type
+senf::VectorParser_Container<ElementParser,AuxPolicy>::bytes()
     const
 {
-    return size()*ElementParser::fixed_bytes + sizer_.bytes(i(),state());
+    return size()*ElementParser::fixed_bytes + AuxPolicy::aux_bytes;
 }
 
 // private members
 
-template <class ElementParser, class Sizer>
-prefix_ void senf::VectorParser_Container<ElementParser,Sizer>::setSize(size_type value)
+template <class ElementParser, class AuxPolicy>
+prefix_ void senf::VectorParser_Container<ElementParser,AuxPolicy>::setSize(size_type value)
 {
-    sizer_.size(i(),state(),value);
+    aux(i(),state()).value(value);
 }
 
 /////////////////////////////cti.e///////////////////////////////////////
index b135cd8..ac7a15a 100644 (file)
@@ -33,9 +33,9 @@
 #include <boost/type_traits.hpp>
 #include "PacketParser.hh"
 #include "ArrayParser.hh" // for ArrayParser_iterator
+#include "AuxParser.hh" // for the AuxPolicies
 
 //#include "VectorParser.mpp"
-#include "VectorParser.ih"
 ///////////////////////////////hh.p////////////////////////////////////////
 
 namespace senf {
@@ -61,11 +61,13 @@ namespace senf {
         \see ExampleVectorPolicy
         \ingroup parsecollection
      */
-    template <class ElementParser, class Sizer>
-    struct VectorParser : public PacketParserBase
+    template <class ElementParser, class AuxPolicy>
+    struct VectorParser 
+        : public PacketParserBase, 
+          private AuxPolicy
     {
         VectorParser(data_iterator i, state_type s);
-        VectorParser(Sizer sizer, data_iterator i, state_type s);
+        VectorParser(AuxPolicy policy, data_iterator i, state_type s);
                                         ///< Additional sizer specific constructor
                                         /**< This constructor may be used, if the sizer needs
                                              additional parameters. */
@@ -73,7 +75,7 @@ namespace senf {
         size_type bytes() const;
         void init() const;
 
-        static const size_type init_bytes = Sizer::init_bytes;
+        static const size_type init_bytes = AuxPolicy::aux_bytes;
 
         ///////////////////////////////////////////////////////////////////////////
         // Container interface
@@ -81,7 +83,7 @@ namespace senf {
         typedef ElementParser value_type;
         typedef detail::ArrayParser_iterator<value_type> iterator;
         typedef iterator const_iterator;
-        typedef VectorParser_Container<ElementParser,Sizer> container;
+        typedef VectorParser_Container<ElementParser,AuxPolicy> container;
 
         size_type size() const;
         bool empty() const;
@@ -107,33 +109,8 @@ namespace senf {
         template <class Value> void resize           (size_type n, Value value) const;
 
      private:
-        Sizer sizer_;
 
-        friend class VectorParser_Container<ElementParser,Sizer>;
-    };
-
-    /** \brief Vector with prefix sizing
-        
-        This is a 'template typedef'. It defines a vector with a <em>directly preceding</em> size
-        field holding the number of vector elements. The size field is considered part of the
-        vector.
-        \code
-        // Define MyVector as a vector of 16bit unsigned elements with a directly preceding
-        // 8bit unsigned size field
-        typedef senf::VectorNParser<senf::UInt16Parser, senf::UInt8Parser>::parser MyVector;
-        \endcode
-
-        \param ElementParser \e fixed-size parser for parsing the vector elements
-        \param SizeParser parser for parsing the vector size (number of elements)
-
-        \see VectorParser
-        \ingroup parsecollection
-     */
-    template <class ElementParser, class SizeParser, unsigned Distance>
-    struct VectorNParser
-    {
-        typedef VectorParser< ElementParser,
-                              detail::VectorNParser_Sizer<SizeParser, Distance> > parser;
+        friend class VectorParser_Container<ElementParser,AuxPolicy>;
     };
 
     /** \brief Define VectorNParser field
@@ -145,7 +122,7 @@ namespace senf {
         // The size field should be declared private (size is accessible via the vector)
         SENF_PARSER_PRIVATE_FIELD ( vec_size_, senf::UInt16Parser );
         // Define the vector, here it has 32bit unsigned integer elements
-        SENF_PARSER_VEC_N         ( vec,       _vec_size, senf::UInt32Parser );
+        SENF_PARSER_VEC_N         ( vec,       vec_size_, senf::UInt32Parser );
         \endcode
         
         \param[in] name field name
@@ -166,6 +143,14 @@ namespace senf {
 #   define SENF_PARSER_PRIVATE_VEC_N(name, size, elt_type)                                        \
         SENF_PARSER_VEC_N_I(SENF_PARSER_PRIVATE_FIELD, name, size, elt_type)
 
+#   define SENF_PARSER_VECTOR(name, size, elt_type) \
+        SENF_PARSER_VECTOR_I(public, name, size, elt_type)
+
+#   define SENF_PARSER_PRIVATE_VECTOR(name, size, elt_type) \
+        SENF_PARSER_VECTOR_I(private, name, size, elt_type)
+
+
+
     /** \brief VectorParser container wrapper
 
         This is the container wrapper used for vector parsers. The container wrapper will stay valid
@@ -184,14 +169,15 @@ namespace senf {
 
         \see VectorParser
       */
-    template <class ElementParser, class Sizer>
+    template <class ElementParser, class AuxPolicy>
     class VectorParser_Container
+        : private AuxPolicy
     {
     public:
         ///////////////////////////////////////////////////////////////////////////
         // Types
 
-        typedef VectorParser<ElementParser,Sizer> parser_type;
+        typedef VectorParser<ElementParser,AuxPolicy> parser_type;
         typedef PacketParserBase::data_iterator data_iterator;
         typedef PacketParserBase::size_type size_type;
         typedef PacketParserBase::difference_type difference_type;
@@ -276,7 +262,6 @@ namespace senf {
     private:
         void setSize(size_type value);
 
-        Sizer sizer_;
         state_type state_;
         size_type i_;
     };
index c7b4340..6da8f49 100644 (file)
 namespace senf {
 namespace detail {
 
-    /** \brief Internal: Sizer implementing prefix sizing
-
-        \internal
+#   define SENF_PARSER_VEC_N_I(field, name, size, elt_type)                                       \
+        typedef senf::VectorParser<                                                               \
+            elt_type,                                                                             \
+            senf::detail::FixedAuxParserPolicy< BOOST_PP_CAT(size, _t),                           \
+                                                SENF_PARSER_CURRENT_FIXED_OFFSET()                \
+                                                    - SENF_PARSER_FIXED_OFFSET(size) >            \
+        > BOOST_PP_CAT(name, _vec_t);                                                             \
+        field( name, BOOST_PP_CAT(name, _vec_t) )
 
-        This is the sizer policy used by VectorNParser
-     */
-    template <class SizeParser, unsigned Distance>
-    struct VectorNParser_Sizer
+    template <class ElementParser>
+    struct VectorParserTraits
     {
-        typedef PacketParserBase::size_type size_type;
-        typedef PacketParserBase::data_iterator iterator;
-        typedef PacketParserBase::state_type state_type;
-
-        static const size_type init_bytes = 0;
-
-        size_type  size  (iterator i, state_type s) const;
-        void       size  (iterator i, state_type s, size_type v) const;
-        iterator   begin (iterator i, state_type s) const;
-        size_type  bytes (iterator i, state_type s) const;
-        void       init  (iterator i, state_type s) const;
+        template <class AuxPolicy, class AuxTag>
+        struct parser {
+            typedef senf::VectorParser<ElementParser, AuxPolicy> type;
+        };
     };
 
-#   define SENF_PARSER_VEC_N_I(field, name, size, elt_type)                                       \
-        typedef senf::VectorNParser< elt_type,                                                    \
-                                     BOOST_PP_CAT(size, _t),                                      \
-                                     SENF_PARSER_CURRENT_FIXED_OFFSET()                           \
-                                         - SENF_PARSER_FIXED_OFFSET(size)                         \
-            >::parser BOOST_PP_CAT(name, _vec_t);                                                 \
-        field( name, BOOST_PP_CAT(name, _vec_t) )
 
-}}
+#   define SENF_PARSER_VECTOR_I(access, name, size, elt_type)                                     \
+        SENF_PARSER_REQUIRE_VAR(vector)                                                           \
+        SENF_PARSER_COLLECTION_I( access,                                                         \
+                                  name,                                                           \
+                                  size,                                                           \
+                                  senf::detail::VectorParserTraits<elt_type> )
 
+}}
+                              
 ///////////////////////////////ih.e////////////////////////////////////////
 #endif
 
index ef7cffe..b51b392 100644 (file)
@@ -48,7 +48,7 @@ BOOST_AUTO_UNIT_TEST(VectorParser)
     senf::PacketInterpreterBase::ptr p (senf::PacketInterpreter<VoidPacket>::create(data));
     typedef senf::VectorParser<
         senf::UInt16Parser,
-        senf::detail::VectorNParser_Sizer<senf::UInt8Parser, 1u>
+        senf::detail::FixedAuxParserPolicy<senf::UInt8Parser, 1u>
         > UInt16VectorParser;
 
     {
@@ -123,7 +123,7 @@ BOOST_AUTO_UNIT_TEST(VectorParser_wrapper)
     senf::PacketInterpreterBase::ptr p (senf::PacketInterpreter<VoidPacket>::create(data));
     typedef senf::VectorParser<
         senf::UInt16Parser,
-        senf::detail::VectorNParser_Sizer<senf::UInt8Parser, 1u>
+        senf::detail::FixedAuxParserPolicy<senf::UInt8Parser, 1u>
         > UInt16VectorParser;
     UInt16VectorParser v (boost::next(p->data().begin(),1), &p->data());
     UInt16VectorParser::container w (v);
@@ -172,6 +172,74 @@ BOOST_AUTO_UNIT_TEST(VectorParser_wrapper)
     BOOST_CHECK_EQUAL( w.parser().size(), 0u );
 }
 
+BOOST_AUTO_UNIT_TEST(dynamicPolicyVector)
+{
+    unsigned char data[] = { 0x03,                                   // size
+                             0x10, 0x11,  0x12, 0x13,  0x14, 0x15,   // data
+                             0x20, 0x21,  0x22, 0x23,  0x24, 0x25 };
+    senf::PacketInterpreterBase::ptr p (senf::PacketInterpreter<VoidPacket>::create(data));
+
+    typedef senf::VectorParser<
+        senf::UInt16Parser,
+        senf::detail::DynamicAuxParserPolicy<senf::UInt8Parser>
+        > UInt16VectorParser;
+
+    UInt16VectorParser v (senf::UInt8Parser(p->data().begin(), &p->data()),
+                          boost::next(p->data().begin(),1), &p->data());
+    UInt16VectorParser::container w (v);
+    
+    BOOST_CHECK_EQUAL( v.size(), 3u );
+    BOOST_CHECK_EQUAL( w.size(), 3u );
+
+    BOOST_CHECK_EQUAL( v[0], 0x1011 );
+    BOOST_CHECK_EQUAL( v[2], 0x1415 );
+
+    BOOST_CHECK_EQUAL( w[0], 0x1011 );
+    BOOST_CHECK_EQUAL( w[2], 0x1415 );
+}
+
+namespace {
+
+    struct TestVectorParser 
+        : public senf::PacketParserBase
+    {
+#       include SENF_PARSER()
+
+        SENF_PARSER_PRIVATE_FIELD ( size1 , senf::UInt8Parser );
+        SENF_PARSER_PRIVATE_FIELD ( size2 , senf::UInt8Parser );
+        SENF_PARSER_FIELD         ( dummy , senf::UInt32Parser );
+        SENF_PARSER_VECTOR        ( vec1  , size1, senf::UInt16Parser );
+        SENF_PARSER_VECTOR        ( vec2  , size2, senf::UInt16Parser );
+
+        SENF_PARSER_FINALIZE( TestVectorParser );
+    };
+
+}
+
+BOOST_AUTO_UNIT_TEST(vectorMacro)
+{
+    unsigned char data[] = { 0x03,                   // size1
+                             0x02,                   // size2
+                             0x01, 0x02, 0x03, 0x04, // dummy
+                             0x05, 0x06,             // vec1[0]
+                             0x07, 0x08,             // vec1[1]
+                             0x09, 0x0A,             // vec1[2]
+                             0x0B, 0x0C,             // vec2[0]
+                             0x0D, 0x0E };           // vec2[1]
+
+    senf::DataPacket p (senf::DataPacket::create(data));
+    TestVectorParser parser (p.data().begin(), &p.data());
+    
+    BOOST_CHECK_EQUAL( parser.vec1().size(), 3u );
+    BOOST_CHECK_EQUAL( parser.vec2().size(), 2u );
+    BOOST_CHECK_EQUAL( parser.dummy(), 0x01020304u );
+    BOOST_CHECK_EQUAL( parser.vec1()[0], 0x0506u );
+    BOOST_CHECK_EQUAL( parser.vec1()[1], 0x0708u );
+    BOOST_CHECK_EQUAL( parser.vec1()[2], 0x090Au );
+    BOOST_CHECK_EQUAL( parser.vec2()[0], 0x0B0Cu );
+    BOOST_CHECK_EQUAL( parser.vec2()[1], 0x0D0Eu );
+}
+
 ///////////////////////////////cc.e////////////////////////////////////////
 #undef prefix_