// senf::detail::PrefixAuxParserPolicy<P>
template <class P>
-prefix_ typename senf::detail::PrefixAuxParserPolicy<P>::ParserType
+prefix_ typename P::value_type
senf::detail::PrefixAuxParserPolicy<P>::aux(PacketParserBase::data_iterator i,
PacketParserBase::state_type s)
const
{
- return ParserType(i, s);
+ return P(i, s).value();
+}
+
+template <class P>
+prefix_ void senf::detail::PrefixAuxParserPolicy<P>::aux(typename P::value_type const & v,
+ PacketParserBase::data_iterator i,
+ PacketParserBase::state_type s)
+ const
+{
+ P(i, s).value(v);
}
template <class P>
PacketParserBase::state_type s)
const
{
- return i+ParserType::fixed_bytes;
+ return i+P::fixed_bytes;
}
///////////////////////////////////////////////////////////////////////////
// senf::detail::FixedAuxParserPolicy<P>
template <class P, unsigned Dist>
-prefix_ typename senf::detail::FixedAuxParserPolicy<P,Dist>::ParserType
+prefix_ typename P::value_type
senf::detail::FixedAuxParserPolicy<P,Dist>::aux(PacketParserBase::data_iterator i,
PacketParserBase::state_type s)
const
{
- return ParserType(i-Dist, s);
+ return P(i-Dist, s).value();
+}
+
+template <class P, unsigned Dist>
+prefix_ void senf::detail::FixedAuxParserPolicy<P,Dist>::aux(typename P::value_type const & v,
+ PacketParserBase::data_iterator i,
+ PacketParserBase::state_type s)
+ const
+{
+ P(i-Dist, s).value(v);
}
template <class P, unsigned Dist>
// senf::detail::DynamicAuxParserPolicy<P>
template <class P>
-prefix_ senf::detail::DynamicAuxParserPolicy<P>::DynamicAuxParserPolicy(ParserType p)
+prefix_ senf::detail::DynamicAuxParserPolicy<P>::DynamicAuxParserPolicy(P p)
: p_ (p)
{}
{}
template <class P>
-prefix_ typename senf::detail::DynamicAuxParserPolicy<P>::ParserType
+prefix_ typename P::value_type
senf::detail::DynamicAuxParserPolicy<P>::aux(PacketParserBase::data_iterator i,
PacketParserBase::state_type s)
const
{
- return p_;
+ return p_.value();
+}
+
+template <class P>
+prefix_ void senf::detail::DynamicAuxParserPolicy<P>::aux(typename P::value_type const & v,
+ PacketParserBase::data_iterator i,
+ PacketParserBase::state_type s)
+ const
+{
+ p_.value(v);
}
template <class P>
{}
template <class P>
-prefix_ typename senf::detail::DynamicWrapperAuxParserPolicy<P>::ParserType
+prefix_ typename P::value_type
senf::detail::DynamicWrapperAuxParserPolicy<P>::aux(PacketParserBase::data_iterator i,
PacketParserBase::state_type s)
const
{
- return * p_;
+ return p_->value();
+}
+
+template <class P>
+prefix_ void
+senf::detail::DynamicWrapperAuxParserPolicy<P>::aux(typename P::value_type const & v,
+ PacketParserBase::data_iterator i,
+ PacketParserBase::state_type s)
+ const
+{
+ p_->value(v);
}
template <class P>
return i;
}
+///////////////////////////////////////////////////////////////////////////
+// senf::detail::TransformAuxParserPolicy<Policy,Transform>
+
+template <class Policy, class Transform>
+prefix_ senf::detail::TransformAuxParserPolicy<Policy,Transform>::TransformAuxParserPolicy()
+{}
+
+template <class Policy, class Transform>
+template <class Arg>
+prefix_ senf::detail::TransformAuxParserPolicy<Policy,Transform>::
+TransformAuxParserPolicy(Arg const & arg)
+ : Policy(arg)
+{}
+
+template <class Policy, class Transform>
+prefix_ typename Transform::value_type
+senf::detail::TransformAuxParserPolicy<Policy,Transform>::aux(PacketParserBase::data_iterator i,
+ PacketParserBase::state_type s)
+ const
+{
+ return Transform::get(Policy::aux(i,s));
+}
+
+template <class Policy, class Transform>
+prefix_ void senf::detail::TransformAuxParserPolicy<Policy,Transform>::
+aux(typename Transform::value_type const & v, PacketParserBase::data_iterator i,
+ PacketParserBase::state_type s)
+ const
+{
+ Policy::aux(Transform::set(v), i, s);
+}
+
///////////////////////////////cti.e///////////////////////////////////////
#undef prefix_
struct PrefixAuxParserPolicy
{
typedef PrefixAuxParserPolicy WrapperPolicy;
- typedef P ParserType;
+ typedef PrefixAuxParserPolicy ParserPolicy;
- static PacketParserBase::size_type const aux_bytes = ParserType::fixed_bytes;
+ static PacketParserBase::size_type const aux_bytes = P::fixed_bytes;
- ParserType aux(PacketParserBase::data_iterator i, PacketParserBase::state_type s) const;
+ typename P::value_type aux(PacketParserBase::data_iterator i, PacketParserBase::state_type s) const;
+ void aux(typename P::value_type const & v, PacketParserBase::data_iterator i, PacketParserBase::state_type s) const;
PacketParserBase::data_iterator adjust(PacketParserBase::data_iterator i, PacketParserBase::state_type s) const;
};
struct FixedAuxParserPolicy
{
typedef FixedAuxParserPolicy WrapperPolicy;
- typedef P ParserType;
+ typedef FixedAuxParserPolicy ParserPolicy;
static PacketParserBase::size_type const aux_bytes = 0;
- ParserType aux(PacketParserBase::data_iterator i, PacketParserBase::state_type s) const;
+ typename P::value_type aux(PacketParserBase::data_iterator i, PacketParserBase::state_type s) const;
+ void aux(typename P::value_type const & v, PacketParserBase::data_iterator i, PacketParserBase::state_type s) const;
PacketParserBase::data_iterator adjust(PacketParserBase::data_iterator i, PacketParserBase::state_type s) const;
};
struct DynamicAuxParserPolicy
{
typedef DynamicWrapperAuxParserPolicy<P> WrapperPolicy;
- typedef P ParserType;
+ typedef DynamicAuxParserPolicy<P> ParserPolicy;
static PacketParserBase::size_type const aux_bytes = 0;
- DynamicAuxParserPolicy(ParserType p);
+ DynamicAuxParserPolicy(P p);
DynamicAuxParserPolicy(WrapperPolicy const & other);
- ParserType aux(PacketParserBase::data_iterator i, PacketParserBase::state_type s) const;
+ typename P::value_type aux(PacketParserBase::data_iterator i, PacketParserBase::state_type s) const;
+ void aux(typename P::value_type const & v, PacketParserBase::data_iterator i, PacketParserBase::state_type s) const;
PacketParserBase::data_iterator adjust(PacketParserBase::data_iterator i, PacketParserBase::state_type s) const;
- ParserType p_;
+ mutable P p_;
};
template <class P>
struct DynamicWrapperAuxParserPolicy
{
+ typedef DynamicWrapperAuxParserPolicy<P> WrapperPolicy;
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;
+ typename P::value_type aux(PacketParserBase::data_iterator i, PacketParserBase::state_type s) const;
+ void aux(typename P::value_type const & v, 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_;
+ mutable SafePacketParserWrapper<P> p_;
+ };
+
+ template <class Policy, class Transform>
+ struct TransformAuxParserPolicy
+ : public Policy
+ {
+ typedef TransformAuxParserPolicy<typename Policy::WrapperPolicy, Transform> WrapperPolicy;
+ typedef TransformAuxParserPolicy<typename Policy::ParserPolicy, Transform> ParserPolicy;
+
+ static PacketParserBase::size_type const aux_bytes = Policy::aux_bytes;
+
+ TransformAuxParserPolicy();
+ template <class Arg> TransformAuxParserPolicy(Arg const & arg);
+
+ typename Transform::value_type aux(PacketParserBase::data_iterator i, PacketParserBase::state_type s) const;
+ void aux(typename Transform::value_type const & v, PacketParserBase::data_iterator i, PacketParserBase::state_type s) const;
};
}}
///////////////////////////////cti.p///////////////////////////////////////
///////////////////////////////////////////////////////////////////////////
-// senf::detail::ListBParser_Policy<ElementParser,BytesParser>
+// senf::detail::ListBParser_Policy<ElementParser,AuxPolicy>
+
+template <class ElementParser, class AuxPolicy>
+prefix_ senf::detail::ListBParser_Policy<ElementParser,AuxPolicy>::ListBParser_Policy()
+{}
-template <class ElementParser, class BytesParser>
-prefix_ typename senf::detail::ListBParser_Policy<ElementParser,BytesParser>::size_type
-senf::detail::ListBParser_Policy<ElementParser,BytesParser>::bytes(iterator i, state_type s)
+template <class ElementParser, class AuxPolicy>
+template <class Arg>
+prefix_
+senf::detail::ListBParser_Policy<ElementParser,AuxPolicy>::ListBParser_Policy(Arg const & arg)
+ : AuxPolicy (arg)
+{}
+
+template <class ElementParser, class AuxPolicy>
+prefix_ typename senf::detail::ListBParser_Policy<ElementParser,AuxPolicy>::size_type
+senf::detail::ListBParser_Policy<ElementParser,AuxPolicy>::bytes(data_iterator i, state_type s)
const
{
- return BytesParser(i,s) + BytesParser::fixed_bytes;
+ return AuxPolicy::aux(i,s) + AuxPolicy::aux_bytes;
}
-template <class ElementParser, class BytesParser>
-prefix_ typename senf::detail::ListBParser_Policy<ElementParser,BytesParser>::size_type
-senf::detail::ListBParser_Policy<ElementParser,BytesParser>::size(iterator i, state_type s)
+template <class ElementParser, class AuxPolicy>
+prefix_ typename senf::detail::ListBParser_Policy<ElementParser,AuxPolicy>::size_type
+senf::detail::ListBParser_Policy<ElementParser,AuxPolicy>::size(data_iterator i, state_type s)
const
{
- parser_type l (i,s);
- return std::distance(l.begin(),l.end());
+ parser_type p (*this, i, s);
+ container_type c (p);
+ return std::distance(c.begin(),c.end());
}
-template <class ElementParser, class BytesParser>
-prefix_ void senf::detail::ListBParser_Policy<ElementParser,BytesParser>::init(iterator i,
- state_type s)
+template <class ElementParser, class AuxPolicy>
+prefix_ void senf::detail::ListBParser_Policy<ElementParser,AuxPolicy>::init(data_iterator i,
+ state_type s)
const
-{}
-
-///////////////////////////////////////////////////////////////////////////
-// senf::detail::ListBParser_Policy<ElementParser,BytesParser>::iterator_policy
-
-template <class ElementParser, class BytesParser>
-prefix_ typename senf::detail::ListBParser_Policy<ElementParser,BytesParser>::iterator
-senf::detail::ListBParser_Policy<ElementParser,BytesParser>::iterator_policy::
-setBegin(iterator i, state_type s)
{
- return boost::next(i,BytesParser::fixed_bytes);
+ AuxPolicy::aux(0,i,s);
}
-template <class ElementParser, class BytesParser>
-prefix_ typename senf::detail::ListBParser_Policy<ElementParser,BytesParser>::iterator
-senf::detail::ListBParser_Policy<ElementParser,BytesParser>::iterator_policy::
-setEnd(iterator i, state_type s)
+///////////////////////////////////////////////////////////////////////////
+// senf::detail::ListBParser_Policy<ElementParser,BytesParser>
+
+template <class ElementParser, class AuxPolicy>
+prefix_
+senf::detail::ListBParser_Policy<ElementParser,AuxPolicy>::container_policy::
+container_policy(parser_policy const & p)
+ : AuxPolicy (p)
{
- return boost::next(i,BytesParser(i,s) + BytesParser::fixed_bytes);
+ data_iterator const e (boost::next(parser_type::get(p).i(),parser_type::get(p).bytes()));
+ data_iterator i (AuxPolicy::adjust(parser_type::get(p).i(), parser_type::get(p).state()));
+ for( n_=0; i!=e;
+ ++n_, std::advance(i,senf::bytes(ElementParser(i,parser_type::get(p).state())))) ;
+ container_size_ = parser_type::get(p).data().size();
}
-template <class ElementParser, class BytesParser>
-prefix_ void
-senf::detail::ListBParser_Policy<ElementParser,BytesParser>::iterator_policy::
-setFromPosition(iterator i, state_type s, iterator p)
-{}
-
-template <class ElementParser, class BytesParser>
-prefix_ typename senf::detail::ListBParser_Policy<ElementParser,BytesParser>::iterator
-senf::detail::ListBParser_Policy<ElementParser,BytesParser>::iterator_policy::next(iterator i,
+template <class ElementParser, class AuxPolicy>
+prefix_ typename senf::detail::ListBParser_Policy<ElementParser,AuxPolicy>::container_policy::size_type
+senf::detail::ListBParser_Policy<ElementParser,AuxPolicy>::container_policy::bytes(data_iterator i,
state_type s)
+ const
{
- return boost::next(i,senf::bytes(ElementParser(i,s)));
+ return AuxPolicy::aux(i,s) + AuxPolicy::aux_bytes;
}
-template <class ElementParser, class BytesParser>
-prefix_ typename senf::detail::ListBParser_Policy<ElementParser,BytesParser>::iterator
-senf::detail::ListBParser_Policy<ElementParser,BytesParser>::iterator_policy::raw(iterator i,
+template <class ElementParser, class AuxPolicy>
+prefix_ typename senf::detail::ListBParser_Policy<ElementParser,AuxPolicy>::container_policy::size_type
+senf::detail::ListBParser_Policy<ElementParser,AuxPolicy>::container_policy::size(data_iterator i,
state_type s)
const
{
- return i;
+ return n_;
}
-///////////////////////////////////////////////////////////////////////////
-// senf::detail::ListBParser_Policy<ElementParser,BytesParser>
+template <class ElementParser, class AuxPolicy>
+prefix_ void senf::detail::ListBParser_Policy<ElementParser,AuxPolicy>::container_policy::
+init(data_iterator i, state_type s)
+{
+ n_ = 0;
+ container_size_ = s->size();
+ AuxPolicy::aux(0,i,s);
+}
-template <class ElementParser, class BytesParser>
-prefix_
-senf::detail::ListBParser_Policy<ElementParser,BytesParser>::container_policy::
-container_policy(parser_type const & list)
+template <class ElementParser, class AuxPolicy>
+prefix_ void senf::detail::ListBParser_Policy<ElementParser,AuxPolicy>::container_policy::
+erase(container_type & c, data_iterator p)
{
- iterator const e (boost::next(list.i(),list.bytes()));
- iterator i (boost::next(list.i(), BytesParser::fixed_bytes));
- for(n_=0; i!=e; ++n_, std::advance(i,ElementParser(i,list.state()).bytes())) ;
- container_size_ = list.data().size();
+ size_type b (senf::bytes(ElementParser(p,c.state())));
+ AuxPolicy::aux( AuxPolicy::aux(c.i(), c.state())-b, c.i(), c.state());
+ --n_;
+ // The container will be reduced by b bytes directly after this call
+ container_size_ = c.data().size()-b;
}
-template <class ElementParser, class BytesParser>
-prefix_ typename senf::detail::ListBParser_Policy<ElementParser,BytesParser>::size_type
-senf::detail::ListBParser_Policy<ElementParser,BytesParser>::container_policy::
-bytes(iterator i, state_type s)
- const
+template <class ElementParser, class AuxPolicy>
+prefix_ void
+senf::detail::ListBParser_Policy<ElementParser,AuxPolicy>::container_policy::
+insert(container_type & c, data_iterator p)
{
- return BytesParser(i,s) + BytesParser::fixed_bytes;
+ size_type b (senf::bytes(ElementParser(p,c.state())));
+ AuxPolicy::aux( AuxPolicy::aux(c.i(), c.state())+b, c.i(), c.state());
+ ++n_;
+ container_size_ = c.data().size();
}
-template <class ElementParser, class BytesParser>
-prefix_ typename senf::detail::ListBParser_Policy<ElementParser,BytesParser>::size_type
-senf::detail::ListBParser_Policy<ElementParser,BytesParser>::container_policy::
-size(iterator i, state_type s)
+template <class ElementParser, class AuxPolicy>
+prefix_ void
+senf::detail::ListBParser_Policy<ElementParser,AuxPolicy>::container_policy::
+update(container_type const & c)
const
{
- return n_;
+ if (container_size_ == c.data().size())
+ return;
+ data_iterator i (AuxPolicy::adjust(c.i(), c.state()));
+ data_iterator j (i);
+ for (size_type n (n_); n; --n, std::advance(j,senf::bytes(ElementParser(j,c.state())))) ;
+ aux( std::distance(i,j), c.i(), c.state() );
+ container_size_ = c.data().size();
}
-template <class ElementParser, class BytesParser>
-prefix_ void
-senf::detail::ListBParser_Policy<ElementParser,BytesParser>::container_policy::
-erase(iterator i, state_type s, iterator p)
+template <class ElementParser, class AuxPolicy>
+prefix_ typename senf::detail::ListBParser_Policy<ElementParser,AuxPolicy>::container_policy::data_iterator
+senf::detail::ListBParser_Policy<ElementParser,AuxPolicy>::container_policy::
+setBegin(container_type const & c, iterator_data & d)
+ const
{
- size_type b (senf::bytes(ElementParser(p,s)));
- BytesParser(i,s) -= b;
- --n_;
- // The container will be reduced by b bytes directly after this call
- container_size_ = s->size()-b;
+ return AuxPolicy::adjust(c.i(), c.state());
}
-template <class ElementParser, class BytesParser>
-prefix_ void
-senf::detail::ListBParser_Policy<ElementParser,BytesParser>::container_policy::
-insert(iterator i, state_type s, iterator p)
+template <class ElementParser, class AuxPolicy>
+prefix_ typename senf::detail::ListBParser_Policy<ElementParser,AuxPolicy>::container_policy::data_iterator
+senf::detail::ListBParser_Policy<ElementParser,AuxPolicy>::container_policy::
+setEnd(container_type const & c, iterator_data & d)
+ const
{
- BytesParser(i,s) += senf::bytes(ElementParser(p,s));
- ++n_;
- container_size_ = s->size();
+ return boost::next(AuxPolicy::adjust(c.i(), c.state()),aux(c.i(),c.state()));
}
-template <class ElementParser, class BytesParser>
+template <class ElementParser, class AuxPolicy>
prefix_ void
-senf::detail::ListBParser_Policy<ElementParser,BytesParser>::container_policy::
-init(iterator i, state_type s)
+senf::detail::ListBParser_Policy<ElementParser,AuxPolicy>::container_policy::
+setFromPosition(container_type const & c, iterator_data & d, data_iterator p)
+ const
+{}
+
+template <class ElementParser, class AuxPolicy>
+prefix_ typename senf::detail::ListBParser_Policy<ElementParser,AuxPolicy>::container_policy::data_iterator
+senf::detail::ListBParser_Policy<ElementParser,AuxPolicy>::container_policy::
+next(container_type const & c, iterator_data & d)
+ const
{
- n_ = 0;
- container_size_ = s->size();
+ return boost::next( container_type::iterator::get(d).i(),
+ senf::bytes(ElementParser( container_type::iterator::get(d).i(),
+ c.state() )) );
}
-template <class ElementParser, class BytesParser>
-prefix_ void
-senf::detail::ListBParser_Policy<ElementParser,BytesParser>::container_policy::
-update(iterator i, state_type s)
+template <class ElementParser, class AuxPolicy>
+prefix_ typename senf::detail::ListBParser_Policy<ElementParser,AuxPolicy>::container_policy::data_iterator
+senf::detail::ListBParser_Policy<ElementParser,AuxPolicy>::container_policy::
+raw(container_type const & c, iterator_data const & d)
const
{
- if (container_size_ == s->size())
- return;
- iterator j (boost::next(i,BytesParser::fixed_bytes));
- for (size_type n (n_); n; --n, std::advance(j,ElementParser(j,s).bytes())) ;
- BytesParser(i,s) = std::distance(i,j) - BytesParser::fixed_bytes;
- container_size_ = s->size();
+ return container_type::iterator::get(d).i();
}
///////////////////////////////cti.e///////////////////////////////////////
*/
template <class ElementParser, class BytesParser>
struct ListBParser {
- typedef ListParser< detail::ListBParser_Policy<ElementParser,BytesParser> > parser;
+ typedef ListParser<
+ detail::ListBParser_Policy< ElementParser,
+ detail::PrefixAuxParserPolicy<BytesParser> > > parser;
};
/** \brief Define ListBParser field
# define SENF_PARSER_LIST_B(name, elt_type, size_type) \
typedef senf::ListBParser<elt_type, size_type>::parser BOOST_PP_CAT(name, _list_t); \
SENF_PARSER_FIELD( name, BOOST_PP_CAT(name, _list_t) )
-
}
///////////////////////////////hh.e////////////////////////////////////////
#define IH_ListBParser_ 1
// Custom includes
+#include "ListParser.ih"
///////////////////////////////ih.p////////////////////////////////////////
\internal
\see \ref ListBParser
*/
- template <class ElementParser, class BytesParser>
+ template <class ElementParser, class AuxPolicy>
struct ListBParser_Policy
+ : public AuxPolicy
{
// This policy needs to work around a serious problem with this type of list: When we change
- // the size of any (direct or indirect) subelement of the list, This will change will render
- // the list completely invalid and unparseable since the 'byte' field will now be invalid.
+ // the size of any (direct or indirect) sub-element of the list, this will change will
+ // render the list completely invalid and un-parseable since the 'byte' field will now be
+ // invalid.
//
// The solution we apply is to store the *size* (i.e. the number of elements) of the list
- // when creating the container wrapper. We also maintain this value accross insert/erase
+ // when creating the container wrapper. We also maintain this value across insert/erase
// statements. Additionally we also safe the complete size of the data container (the vector
// holding the bytes). Since we only allow packet changes through this container while it
// exists, any change in the container size must be a change within this list and therefore
struct container_policy;
- typedef PacketParserBase::data_iterator iterator;
+ typedef PacketParserBase::data_iterator data_iterator;
typedef PacketParserBase::state_type state_type;
typedef PacketParserBase::size_type size_type;
+
typedef ElementParser element_type;
typedef ListParser< ListBParser_Policy > parser_type;
typedef ListParser_Container< container_policy > container_type;
- static const size_type init_bytes = BytesParser::fixed_bytes;
+ static const size_type init_bytes = AuxPolicy::aux_bytes;
- size_type bytes (iterator i, state_type s) const;
- size_type size (iterator i, state_type s) const;
- void init (iterator i, state_type s) const;
+ ListBParser_Policy();
+ template <class Arg> ListBParser_Policy(Arg const & arg);
- /** \brief Internal: ListBParser_Policy's iterator policy
- \internal
- */
- struct iterator_policy
- {
- iterator setBegin (iterator i, state_type s);
- iterator setEnd (iterator i, state_type s);
- void setFromPosition (iterator i, state_type s, iterator p);
- iterator next (iterator i, state_type s);
- iterator raw (iterator i, state_type s) const;
- };
+ size_type bytes (data_iterator i, state_type s) const;
+ size_type size (data_iterator i, state_type s) const;
+ void init (data_iterator i, state_type s) const;
- /** \brief Internal: ListBParser_Policy's container policy
- \internal
- */
struct container_policy
+ : public AuxPolicy
{
- typedef typename ListBParser_Policy<
- ElementParser,BytesParser>::iterator_policy iterator_policy;
- typedef typename ListBParser_Policy<
- ElementParser,BytesParser>::parser_type parser_type;
- typedef typename ListBParser_Policy<
- ElementParser,BytesParser>::element_type element_type;
+ typedef PacketParserBase::data_iterator data_iterator;
+ typedef PacketParserBase::state_type state_type;
+ typedef PacketParserBase::size_type size_type;
+
+ typedef ListBParser_Policy<ElementParser, AuxPolicy> parser_policy;
+ typedef typename parser_policy::element_type element_type;
+ typedef typename parser_policy::parser_type parser_type;
+ typedef typename parser_policy::container_type container_type;
+
+ static const size_type init_bytes = parser_policy::init_bytes;
+
+ container_policy(parser_policy const & p);
- static const size_type init_bytes = ListBParser_Policy<
- ElementParser,BytesParser>::init_bytes;
+ size_type bytes (data_iterator i, state_type s) const;
+ size_type size (data_iterator i, state_type s) const;
+ void init (data_iterator i, state_type s);
- container_policy(parser_type const & list);
+ void erase (container_type & c, data_iterator p);
+ void insert (container_type & c, data_iterator p);
+ void update (container_type const & c) const;
- size_type bytes (iterator i, state_type s) const;
- size_type size (iterator i, state_type s) const;
- void erase (iterator i, state_type s, iterator p);
- void insert (iterator i, state_type s, iterator p);
- void init (iterator i, state_type s);
- void update (iterator i, state_type s) const;
+ struct iterator_data {};
+
+ data_iterator setBegin (container_type const & c, iterator_data & d) const;
+ data_iterator setEnd (container_type const & c, iterator_data & d) const;
+ void setFromPosition (container_type const & c, iterator_data & d,
+ data_iterator p) const;
+
+ data_iterator next (container_type const & c, iterator_data & d) const;
+ data_iterator raw (container_type const & c, iterator_data const & d) const;
size_type n_;
mutable size_type container_size_;
};
};
+ template <class ElementParser, class AuxPolicy>
+ struct ListParserPolicy<ElementParser, AuxPolicy, senf::detail::auxtag::bytes>
+ {
+ typedef ListBParser_Policy<ElementParser, AuxPolicy> type;
+ };
+
}}
///////////////////////////////ih.e////////////////////////////////////////
BOOST_CHECK_EQUAL( p.size(), 0u );
BOOST_CHECK_EQUAL( p.bytes(), 2u );
BOOST_CHECK( p.empty() );
- BOOST_CHECK( p.begin() == p.end() );
// the mutators are really tested together with the container wrappers since they are based
// on the container wrapper. Here we only need one call to make the list larger ...
BOOST_CHECK_EQUAL( p.bytes(), 3u );
BOOST_CHECK_EQUAL( p.size(), 1u );
BOOST_CHECK( ! p.empty() );
- BOOST_CHECK( p.begin() != p.end() );
}
BOOST_AUTO_UNIT_TEST(ListBParser_container)
}
}
+namespace {
+
+ struct TestListParser
+ : 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_LIST ( list1 , bytes(size1) , VectorParser );
+ SENF_PARSER_LIST ( list2 , bytes(size2) , VectorParser );
+
+ SENF_PARSER_FINALIZE(TestListParser);
+ };
+
+}
+
+BOOST_AUTO_UNIT_TEST(listBytesMacro)
+{
+ unsigned char data[] = { 0x08, // size1
+ 0x09, // size2
+ 0x01, 0x02, 0x03, 0x04, // dummy
+ 0x01, // list1()[0].size()
+ 0x05, 0x06, // list1().vec()[0]
+ 0x02, // list1()[1].size()
+ 0x07, 0x08, // list1()[1].vec()[0]
+ 0x09, 0x0A, // list1()[1].vec()[1]
+ 0x00, // list2()[0].size()
+ 0x02, // list2()[1].size()
+ 0x0B, 0x0C, // list2()[1].vec()[0]
+ 0x0D, 0x0E, // list2()[1].vec()[1]
+ 0x01, // list2()[2].size()
+ 0x0F, 0x10 }; // list2()[2].vec()[0]
+
+ senf::DataPacket p (senf::DataPacket::create(data));
+ TestListParser parser (p.data().begin(), &p.data());
+
+ BOOST_CHECK_EQUAL( parser.list1().size(), 2u );
+ BOOST_CHECK_EQUAL( parser.list2().size(), 3u );
+ BOOST_CHECK_EQUAL( parser.dummy(), 0x01020304u );
+
+ TestListParser::list2_t::container list2 (parser.list2());
+
+ {
+ TestListParser::list1_t::container list (parser.list1());
+ BOOST_CHECK_EQUAL( list.size(), 2u );
+
+ TestListParser::list1_t::container::iterator i (list.begin());
+ BOOST_CHECK_EQUAL( i->vec().size(), 1u );
+ BOOST_CHECK_EQUAL( i->vec()[0], 0x0506u );
+
+ ++i;
+ BOOST_CHECK_EQUAL( i->vec().size(), 2u );
+ BOOST_CHECK_EQUAL( i->vec()[0], 0x0708u );
+ BOOST_CHECK_EQUAL( i->vec()[1], 0x090Au );
+
+ ++i;
+ BOOST_CHECK( i == list.end() );
+ }
+
+ {
+ TestListParser::list2_t::container list (parser.list2());
+ BOOST_CHECK_EQUAL( list.size(), 3u );
+
+ TestListParser::list2_t::container::iterator i (list.begin());
+ BOOST_CHECK_EQUAL( i->vec().size(), 0u );
+
+ ++i;
+ BOOST_CHECK_EQUAL( i->vec().size(), 2u );
+ BOOST_CHECK_EQUAL( i->vec()[0], 0x0B0Cu );
+ BOOST_CHECK_EQUAL( i->vec()[1], 0x0D0Eu );
+
+ ++i;
+ BOOST_CHECK_EQUAL( i->vec().size(), 1u );
+ BOOST_CHECK_EQUAL( i->vec()[0], 0x0F10u );
+
+ ++i;
+ BOOST_CHECK( i == list.end() );
+ }
+
+}
+
+
///////////////////////////////cc.e////////////////////////////////////////
#undef prefix_
#define prefix_
///////////////////////////////ct.p////////////////////////////////////////
-template <class ElementParser, class SizeParser>
+template <class ElementParser, class AuxPolicy>
prefix_ void
-senf::detail::ListNParser_Policy<ElementParser,SizeParser>::iterator_policy::
-setFromPosition(iterator i, state_type s, iterator p)
+senf::detail::ListNParser_Policy<ElementParser,AuxPolicy>::setFromPosition(container_type const & c,
+ iterator_data & d,
+ data_iterator p)
+ const
{
- l_ = i;
- if (p == data(s).end()) {
- n_ = 0;
+ if (p == c.data().end()) {
+ d.n_ = 0;
return;
}
- n_ = SizeParser(i,s);
- iterator j (boost::next(i,SizeParser::fixed_bytes));
- for (; n_; --n_, j += ElementParser(j,s).bytes())
+ d.n_ = this->aux(c.i(),c.state());
+ data_iterator j (this->adjust(c.i(),c.state()));
+ for (; d.n_; --d.n_, j += ElementParser(j,c.state()).bytes())
if (j==p)
return;
SENF_ASSERT( false );
}
-template <class ElementParser, class SizeParser>
-prefix_ typename senf::detail::ListNParser_Policy<ElementParser,SizeParser>::iterator
-senf::detail::ListNParser_Policy<ElementParser,SizeParser>::iterator_policy::raw(iterator i,
- state_type s)
+template <class ElementParser, class AuxPolicy>
+prefix_ typename senf::detail::ListNParser_Policy<ElementParser,AuxPolicy>::data_iterator
+senf::detail::ListNParser_Policy<ElementParser,AuxPolicy>::raw(container_type const & c,
+ iterator_data const & d)
const
{
- if (i != data(s).end())
- return i;
- size_type n (SizeParser(l_,s));
- iterator j (boost::next(l_,SizeParser::fixed_bytes));
+ if (container_type::iterator::get(d).i() != c.data().end())
+ return container_type::iterator::get(d).i();
+ size_type n (this->aux(c.i(),c.state()));
+ data_iterator j (this->adjust(c.i(),c.state()));
for (; n; --n)
- j += ElementParser(j,s).bytes();
+ j += ElementParser(j,c.state()).bytes();
return j;
}
#define prefix_ inline
///////////////////////////////cti.p///////////////////////////////////////
-template <class ElementParser, class SizeParser>
-prefix_ typename senf::detail::ListNParser_Policy<ElementParser,SizeParser>::size_type
-senf::detail::ListNParser_Policy<ElementParser,SizeParser>::bytes(iterator i, state_type s)
+template <class ElementParser, class AuxPolicy>
+prefix_ senf::detail::ListNParser_Policy<ElementParser,AuxPolicy>::ListNParser_Policy()
+{}
+
+template <class ElementParser, class AuxPolicy>
+template <class Arg>
+prefix_
+senf::detail::ListNParser_Policy<ElementParser,AuxPolicy>::ListNParser_Policy(Arg const & aux)
+ : AuxPolicy (aux)
+{}
+
+template <class ElementParser, class AuxPolicy>
+prefix_ typename senf::detail::ListNParser_Policy<ElementParser,AuxPolicy>::size_type
+senf::detail::ListNParser_Policy<ElementParser,AuxPolicy>::bytes(data_iterator i, state_type s)
const
{
- return std::distance(i,parser_type(i,s).end().raw());
+ container_type c (parser_type(*this, i, s));
+ return std::distance(i,c.end().raw());
}
-template <class ElementParser, class SizeParser>
-prefix_ typename senf::detail::ListNParser_Policy<ElementParser,SizeParser>::size_type
-senf::detail::ListNParser_Policy<ElementParser,SizeParser>::size(iterator i, state_type s)
+template <class ElementParser, class AuxPolicy>
+prefix_ typename senf::detail::ListNParser_Policy<ElementParser,AuxPolicy>::size_type
+senf::detail::ListNParser_Policy<ElementParser,AuxPolicy>::size(data_iterator i, state_type s)
const
{
- return SizeParser(i,s);
+ return AuxPolicy::aux(i,s);
}
-template <class ElementParser, class SizeParser>
-prefix_ void senf::detail::ListNParser_Policy<ElementParser,SizeParser>::init(iterator i,
- state_type s)
+template <class ElementParser, class AuxPolicy>
+prefix_ void senf::detail::ListNParser_Policy<ElementParser,AuxPolicy>::init(data_iterator i,
+ state_type s)
const
-{}
+{
+ AuxPolicy::aux(0,i,s);
+}
-template <class ElementParser, class SizeParser>
-prefix_ void senf::detail::ListNParser_Policy<ElementParser,SizeParser>::erase(iterator i,
- state_type s,
- iterator p)
+template <class ElementParser, class AuxPolicy>
+prefix_ void
+senf::detail::ListNParser_Policy<ElementParser,AuxPolicy>::erase(container_type & c,
+ data_iterator p)
const
{
- --SizeParser(i,s);
+ this->aux(this->aux(c.i(),c.state())-1,c.i(),c.state());
}
-template <class ElementParser, class SizeParser>
-prefix_ void senf::detail::ListNParser_Policy<ElementParser,SizeParser>::insert(iterator i,
- state_type s,
- iterator p)
+template <class ElementParser, class AuxPolicy>
+prefix_ void
+senf::detail::ListNParser_Policy<ElementParser,AuxPolicy>::insert(container_type & c,
+ data_iterator p)
const
{
- ++SizeParser(i,s);
+ this->aux(this->aux(c.i(),c.state())+1,c.i(),c.state());
}
-template <class ElementParser, class SizeParser>
-prefix_ void senf::detail::ListNParser_Policy<ElementParser,SizeParser>::update(iterator i,
- state_type s)
+template <class ElementParser, class AuxPolicy>
+prefix_ void
+senf::detail::ListNParser_Policy<ElementParser,AuxPolicy>::update(container_type const & c)
const
{}
-template <class ElementParser, class SizeParser>
-prefix_ typename senf::detail::ListNParser_Policy<ElementParser,SizeParser>::iterator
-senf::detail::ListNParser_Policy<ElementParser,SizeParser>::iterator_policy::
-setBegin(iterator i, state_type s)
-{
- l_ = i;
- n_ = SizeParser(i,s);
- return n_ ? boost::next(i,SizeParser::fixed_bytes) : data(s).end();
-}
-
-template <class ElementParser, class SizeParser>
-prefix_ typename senf::detail::ListNParser_Policy<ElementParser,SizeParser>::iterator
-senf::detail::ListNParser_Policy<ElementParser,SizeParser>::iterator_policy::
-setEnd(iterator i, state_type s)
+template <class ElementParser, class AuxPolicy>
+prefix_ typename senf::detail::ListNParser_Policy<ElementParser,AuxPolicy>::data_iterator
+senf::detail::ListNParser_Policy<ElementParser,AuxPolicy>::setBegin(container_type const & c,
+ iterator_data & d)
+ const
{
- l_ = i;
- n_ = 0;
- return data(s).end();
+ d.n_ = this->aux(c.i(),c.state());
+ return d.n_ ? this->adjust(c.i(),c.state()) : c.data().end();
}
-template <class ElementParser, class SizeParser>
-prefix_ typename senf::detail::ListNParser_Policy<ElementParser,SizeParser>::iterator
-senf::detail::ListNParser_Policy<ElementParser,SizeParser>::iterator_policy::next(iterator i,
- state_type s)
+template <class ElementParser, class AuxPolicy>
+prefix_ typename senf::detail::ListNParser_Policy<ElementParser,AuxPolicy>::data_iterator
+senf::detail::ListNParser_Policy<ElementParser,AuxPolicy>::setEnd(container_type const & c,
+ iterator_data & d)
+ const
{
- --n_;
- return n_ ? boost::next(i,senf::bytes(ElementParser(i,s))) : data(s).end();
+ d.n_ = 0;
+ return c.data().end();
}
-template <class ElementParser, class SizeParser>
-prefix_ senf::PacketData &
-senf::detail::ListNParser_Policy<ElementParser,SizeParser>::data(state_type s)
+template <class ElementParser, class AuxPolicy>
+prefix_ typename senf::detail::ListNParser_Policy<ElementParser,AuxPolicy>::data_iterator
+senf::detail::ListNParser_Policy<ElementParser,AuxPolicy>::next(container_type const & c,
+ iterator_data & d)
+ const
{
- return *s;
+ --d.n_;
+ return d.n_ ? boost::next( container_type::iterator::get(d).i(),
+ senf::bytes(* container_type::iterator::get(d)) )
+ : c.data().end();
}
///////////////////////////////cti.e///////////////////////////////////////
// Custom includes
#include "ListParser.hh"
+#include "AuxParser.hh"
//#include "ListNParser.mpp"
+#include "ListNParser.ih"
///////////////////////////////hh.p////////////////////////////////////////
namespace senf {
- namespace detail { template <class ElementParser, class SizeParser>
- class ListNParser_Policy; }
-
/** \brief List parser with size-field giving number of list elements
This parser will parse a list which size is giving by a preceding field containing the
*/
template <class ElementParser, class SizeParser>
struct ListNParser {
- typedef ListParser< detail::ListNParser_Policy<ElementParser,SizeParser> > parser;
+ typedef ListParser< detail::ListNParser_Policy<
+ ElementParser,
+ detail::PrefixAuxParserPolicy<SizeParser> > > parser;
};
/** \brief Define ListNParser field
# define SENF_PARSER_LIST_N(name, elt_type, size_type) \
typedef senf::ListNParser<elt_type, size_type>::parser BOOST_PP_CAT(name, _list_t); \
SENF_PARSER_FIELD( name, BOOST_PP_CAT(name, _list_t) )
-
}
///////////////////////////////hh.e////////////////////////////////////////
#define IH_ListNParser_ 1
// Custom includes
+#include "ListParser.ih"
///////////////////////////////ih.p////////////////////////////////////////
\internal
\see \ref ListNParser
*/
- template <class ElementParser, class SizeParser>
+ template <class ElementParser, class AuxPolicy>
struct ListNParser_Policy
+ : public AuxPolicy
{
- typedef PacketParserBase::data_iterator iterator;
+ typedef PacketParserBase::data_iterator data_iterator;
typedef PacketParserBase::state_type state_type;
typedef PacketParserBase::size_type size_type;
typedef ElementParser element_type;
typedef ListParser< ListNParser_Policy > parser_type;
typedef ListParser_Container< ListNParser_Policy > container_type;
- static const size_type init_bytes = SizeParser::fixed_bytes;
-
- size_type bytes (iterator i, state_type s) const;
- size_type size (iterator i, state_type s) const;
- void init (iterator i, state_type s) const;
- void erase (iterator i, state_type s, iterator p) const;
- void insert (iterator i, state_type s, iterator p) const;
- void update (iterator i, state_type s) const;
-
- /** \brief Iternal: ListNParser_Policy's iterator policy
- \internal
- */
- struct iterator_policy
- {
- iterator setBegin (iterator i, state_type s);
- iterator setEnd (iterator i, state_type s);
- void setFromPosition (iterator i, state_type s, iterator p);
- iterator next (iterator i, state_type s);
- iterator raw (iterator i, state_type s) const;
+ static const size_type init_bytes = AuxPolicy::aux_bytes;
+ ListNParser_Policy();
+ template <class Arg> ListNParser_Policy(Arg const & aux);
+
+ size_type bytes (data_iterator i, state_type s) const;
+ size_type size (data_iterator i, state_type s) const;
+ void init (data_iterator i, state_type s) const;
+
+ void erase (container_type & c, data_iterator p) const;
+ void insert (container_type & c, data_iterator p) const;
+ void update (container_type const & c) const;
+
+ struct iterator_data {
size_type n_;
- iterator l_;
};
- static PacketData & data(state_type s);
+ data_iterator setBegin (container_type const & c, iterator_data & d) const;
+ data_iterator setEnd (container_type const & c, iterator_data & d) const;
+ void setFromPosition (container_type const & c, iterator_data & d, data_iterator p) const;
+ data_iterator next (container_type const & c, iterator_data & d) const;
+ data_iterator raw (container_type const & c, iterator_data const & d) const;
+ };
+
+ template <class ElementParser, class AuxPolicy>
+ struct ListParserPolicy<ElementParser, AuxPolicy, senf::detail::auxtag::none>
+ {
+ typedef ListNParser_Policy<ElementParser, AuxPolicy> type;
+ };
+
+ template <class ElementParser, class AuxPolicy, class Transform>
+ struct ListParserPolicy<ElementParser, AuxPolicy, senf::detail::auxtag::transform<Transform> >
+ {
+ typedef ListNParser_Policy< ElementParser,
+ TransformAuxParserPolicy<AuxPolicy, Transform> > type;
};
}}
};
}
+BOOST_AUTO_UNIT_TEST(ListNParser_container)
+{
+ typedef senf::ListNParser<MyVec,senf::UInt16Parser>::parser MyListNParser;
+
+ VoidPacket vp (VoidPacket::create(MyListNParser::init_bytes));
+ MyListNParser(vp.data().begin(),&vp.data()).init();
+
+ {
+ MyListNParser::container c (MyListNParser(vp.data().begin(),&vp.data()));
+
+ c.push_back_space(2u);
+ BOOST_CHECK_EQUAL( std::distance(c.begin(), c.end()), 2 );
+ BOOST_CHECK_EQUAL( std::distance(c.data().begin(), c.begin().raw()), 2 );
+ BOOST_CHECK_EQUAL( std::distance(c.data().begin(), c.front().vec().begin().raw()), 3 );
+ BOOST_CHECK_EQUAL( std::distance(c.data().begin(), c.front().vec().end().raw()), 3 );
+ BOOST_CHECK_EQUAL( std::distance(c.data().begin(), c.back().vec().begin().raw()), 4 );
+ BOOST_CHECK_EQUAL( std::distance(c.data().begin(), c.back().vec().end().raw()), 4 );
+ BOOST_CHECK_EQUAL( std::distance(c.data().begin(), c.end().raw()), 4 );
+ BOOST_CHECK_EQUAL( c.bytes(), 4u );
+
+ MyListNParser::container::iterator i (c.begin());
+ BOOST_CHECK_EQUAL( std::distance(c.data().begin(), i->i()), 2 );
+ BOOST_CHECK( i != c.end() );
+ ++i;
+ BOOST_CHECK_EQUAL( std::distance(c.data().begin(), i->i()), 3 );
+ BOOST_CHECK( i != c.end() );
+ ++i;
+ BOOST_CHECK( i == c.end() );
+ }
+}
+
BOOST_AUTO_UNIT_TEST(ListNParser)
{
typedef senf::ListNParser<MyVec,senf::UInt16Parser>::parser MyListNParser;
BOOST_CHECK_EQUAL( p.size(), 0u );
BOOST_CHECK_EQUAL( p.bytes(), 2u );
BOOST_CHECK( p.empty() );
- BOOST_CHECK( p.begin() == p.end() );
}
{
p.front().vec().push_back(0x2345u);
BOOST_CHECK_EQUAL( p.front().vec().back(), 0x2345u );
+ BOOST_CHECK_EQUAL( p.front().vec().size(), 2u );
BOOST_CHECK_EQUAL( p.bytes(), 7u );
p.push_back_space();
BOOST_CHECK_EQUAL( p.size(), 2u );
BOOST_CHECK_EQUAL( p.bytes(), 8u );
+ BOOST_CHECK_EQUAL( p.back().vec().size(), 0u );
p.back().vec().push_front(0x0123u);
BOOST_CHECK_EQUAL( p.front().vec().size(), 2u );
}
}
-BOOST_AUTO_UNIT_TEST(ListNParser_container)
-{
- typedef senf::ListNParser<MyVec,senf::UInt16Parser>::parser MyListNParser;
+namespace {
- VoidPacket vp (VoidPacket::create(MyListNParser::init_bytes));
+ struct TestTransform
+ {
+ typedef unsigned value_type;
+ static unsigned get(unsigned v) { return v/2; }
+ static unsigned set(unsigned v) { return 2*v; }
+ };
- MyListNParser(vp.data().begin(),&vp.data()).init();
+ struct TestListParser
+ : 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_LIST ( list1 , transform(TestTransform, size1) , MyVec );
+ SENF_PARSER_LIST ( list2 , size2 , MyVec );
+
+ SENF_PARSER_FINALIZE(TestListParser);
+ };
-
}
+BOOST_AUTO_UNIT_TEST(listMacro)
+{
+ unsigned char data[] = { 0x04, // size1
+ 0x03, // size2
+ 0x01, 0x02, 0x03, 0x04, // dummy
+ 0x01, // list1()[0].size()
+ 0x05, 0x06, // list1().vec()[0]
+ 0x02, // list1()[1].size()
+ 0x07, 0x08, // list1()[1].vec()[0]
+ 0x09, 0x0A, // list1()[1].vec()[1]
+ 0x00, // list2()[0].size()
+ 0x02, // list2()[1].size()
+ 0x0B, 0x0C, // list2()[1].vec()[0]
+ 0x0D, 0x0E, // list2()[1].vec()[1]
+ 0x01, // list2()[2].size()
+ 0x0F, 0x10 }; // list2()[2].vec()[0]
+
+ senf::DataPacket p (senf::DataPacket::create(data));
+ TestListParser parser (p.data().begin(), &p.data());
+
+ BOOST_CHECK_EQUAL( parser.list1().size(), 2u );
+ BOOST_CHECK_EQUAL( parser.list2().size(), 3u );
+ BOOST_CHECK_EQUAL( parser.dummy(), 0x01020304u );
+
+ TestListParser::list2_t::container list2 (parser.list2());
+
+ {
+ TestListParser::list1_t::container list (parser.list1());
+ BOOST_CHECK_EQUAL( list.size(), 2u );
+
+ TestListParser::list1_t::container::iterator i (list.begin());
+ BOOST_CHECK_EQUAL( i->vec().size(), 1u );
+ BOOST_CHECK_EQUAL( i->vec()[0], 0x0506u );
+
+ ++i;
+ BOOST_CHECK_EQUAL( i->vec().size(), 2u );
+ BOOST_CHECK_EQUAL( i->vec()[0], 0x0708u );
+ BOOST_CHECK_EQUAL( i->vec()[1], 0x090Au );
+
+ ++i;
+ BOOST_CHECK( i == list.end() );
+ }
+
+ {
+ TestListParser::list2_t::container list (parser.list2());
+ BOOST_CHECK_EQUAL( list.size(), 3u );
+
+ TestListParser::list2_t::container::iterator i (list.begin());
+ BOOST_CHECK_EQUAL( i->vec().size(), 0u );
+
+ ++i;
+ BOOST_CHECK_EQUAL( i->vec().size(), 2u );
+ BOOST_CHECK_EQUAL( i->vec()[0], 0x0B0Cu );
+ BOOST_CHECK_EQUAL( i->vec()[1], 0x0D0Eu );
+
+ ++i;
+ BOOST_CHECK_EQUAL( i->vec().size(), 1u );
+ BOOST_CHECK_EQUAL( i->vec()[0], 0x0F10u );
+
+ ++i;
+ BOOST_CHECK( i == list.end() );
+ }
+
+}
///////////////////////////////cc.e////////////////////////////////////////
#undef prefix_
const
{
ListPolicy::init(i(),state());
- iterator i (begin());
- iterator const e (end());
+ container c (*this);
+ typename container::iterator i (c.begin());
+ typename container::iterator const e (c.end());
for(; i!=e; ++i)
i->init();
}
const
{
SENF_ASSERT( ! empty() );
- iterator i (begin()), j;
- iterator const e (end());
+ container c(*this);
+ typename container::iterator i (c.begin()), j;
+ typename container::iterator const e (c.end());
for (j=i; i!=e; j=i, ++i) ;
return *j;
}
template <class ListPolicy>
prefix_ void senf::ListParser_Container<ListPolicy>::shift(iterator pos, size_type n)
{
- ListPolicy::update(i(),state());
+ ListPolicy::update(*this);
safe_data_iterator sp (data(),pos.raw());
- safe_data_iterator si (data(),i());
for (; n>0; --n) {
data().insert(sp,senf::init_bytes<value_type>::value,0);
value_type(sp,state()).init();
- ListPolicy::insert(si,state(),sp);
+ ListPolicy::insert(*this,sp);
}
}
size_type n,
Value const & t)
{
- ListPolicy::update(i(),state());
+ ListPolicy::update(*this);
safe_data_iterator sp (data(),pos.raw());
- safe_data_iterator si (data(),i());
for (; n>0; --n) {
data().insert(sp,senf::init_bytes<value_type>::value,0);
value_type(sp,state()).init();
value_type(sp,state()) << t;
- ListPolicy::insert(si,state(),sp);
+ ListPolicy::insert(*this,sp);
}
}
insert(iterator pos, ForwardIterator f, ForwardIterator l,
typename boost::disable_if< boost::is_convertible<ForwardIterator,size_type> >::type *)
{
- ListPolicy::update(i(),state());
+ ListPolicy::update(*this);
safe_data_iterator sp (data(),pos.raw());
- safe_data_iterator si (data(),i());
for (; f!=l; ++f) {
data().insert(sp,senf::init_bytes<value_type>::value,0);
value_type(sp,state()).init();
value_type(sp,state()) << *f;
- ListPolicy::insert(si,state(),sp);
+ ListPolicy::insert(*this,sp);
sp += senf::bytes(value_type(sp,state()));
}
}
prefix_ void senf::ListParser_Container<ListPolicy>::erase(iterator pos,
size_type n)
{
- ListPolicy::update(i(),state());
- safe_data_iterator si (data(),i());
+ ListPolicy::update(*this);
safe_data_iterator sp (data(),pos.raw());
for (; n>0; --n) {
- ListPolicy::erase(si,state(),sp);
+ ListPolicy::erase(*this,sp);
data().erase(sp,boost::next(sp,senf::bytes(value_type(sp,state()))));
}
}
prefix_ bool senf::ListParser<ListPolicy>::empty()
const
{
- return begin() == end();
-}
-
-template <class ListPolicy>
-prefix_ typename senf::ListParser<ListPolicy>::iterator
-senf::ListParser<ListPolicy>::begin()
- const
-{
- return iterator(i(),state(),iterator::Begin);
-}
-
-template <class ListPolicy>
-prefix_ typename senf::ListParser<ListPolicy>::iterator
-senf::ListParser<ListPolicy>::end()
- const
-{
- return iterator(i(),state(),iterator::End);
+ container c (*this);
+ return c.empty();
}
template <class ListPolicy>
const
{
SENF_ASSERT( ! empty() );
- return *begin();
+ container c(*this);
+ return *(c.begin());
}
template <class ListPolicy>
c.resize(n,value);
}
+template <class ListPolicy>
+prefix_ typename senf::ListParser<ListPolicy> &
+senf::ListParser<ListPolicy>::get(ListPolicy & p)
+{
+ return static_cast<ListParser &>(p);
+}
+
+template <class ListPolicy>
+prefix_ typename senf::ListParser<ListPolicy> const &
+senf::ListParser<ListPolicy>::get(ListPolicy const & p)
+{
+ return static_cast<ListParser const &>(p);
+}
+
///////////////////////////////////////////////////////////////////////////
// senf::detail::ListParser_Iterator<ElementParser,IteratorPolicy>
-template <class ElementParser, class IteratorPolicy>
-prefix_ senf::detail::ListParser_Iterator<ElementParser,IteratorPolicy>::ListParser_Iterator()
-{}
-
-template <class ElementParser, class IteratorPolicy>
-prefix_ senf::detail::ListParser_Iterator<ElementParser,IteratorPolicy>::
-ListParser_Iterator(PacketParserBase::data_iterator i, PacketParserBase::state_type s, Begin_t)
- : IteratorPolicy(), i_(IteratorPolicy::setBegin(i,s)), s_(s)
+template <class Container>
+prefix_ senf::detail::ListParser_Iterator<Container>::ListParser_Iterator()
{}
-template <class ElementParser, class IteratorPolicy>
-prefix_ senf::detail::ListParser_Iterator<ElementParser,IteratorPolicy>::
-ListParser_Iterator(PacketParserBase::data_iterator i, PacketParserBase::state_type s, End_t)
- : IteratorPolicy(), i_(IteratorPolicy::setEnd(i,s)), s_(s)
+template <class Container>
+prefix_ senf::detail::ListParser_Iterator<Container>::ListParser_Iterator(Container const & c)
+ : c_ (&c)
{}
-template <class ElementParser, class IteratorPolicy>
-prefix_ senf::detail::ListParser_Iterator<ElementParser,IteratorPolicy>::
-ListParser_Iterator(PacketParserBase::data_iterator i, PacketParserBase::state_type s,
- PacketParserBase::data_iterator p)
- : IteratorPolicy(), i_(p), s_(s)
+template <class Container>
+prefix_ senf::PacketParserBase::data_iterator
+senf::detail::ListParser_Iterator<Container>::raw()
+ const
{
- IteratorPolicy::setFromPosition(i,s,p);
+ return c_->Container::policy::raw(*c_, *this);
}
-template <class ElementParser, class IteratorPolicy>
+template <class Container>
prefix_ senf::PacketParserBase::data_iterator
-senf::detail::ListParser_Iterator<ElementParser,IteratorPolicy>::raw()
+senf::detail::ListParser_Iterator<Container>::i()
const
{
- return IteratorPolicy::raw(i_,s_);
+ return i_;
+}
+
+template <class Container>
+prefix_ typename senf::detail::ListParser_Iterator<Container> &
+senf::detail::ListParser_Iterator<Container>::get(typename Container::policy::iterator_data & d)
+{
+ return static_cast<ListParser_Iterator &>(d);
+}
+
+template <class Container>
+prefix_ typename senf::detail::ListParser_Iterator<Container> const &
+senf::detail::ListParser_Iterator<Container>::
+get(typename Container::policy::iterator_data const & d)
+{
+ return static_cast<ListParser_Iterator const &>(d);
}
-template <class ElementParser, class IteratorPolicy>
-prefix_ ElementParser
-senf::detail::ListParser_Iterator<ElementParser,IteratorPolicy>::dereference()
+template <class Container>
+prefix_ typename senf::detail::ListParser_Iterator<Container>::value_type
+senf::detail::ListParser_Iterator<Container>::dereference()
const
{
- return ElementParser(i_,s_);
+ return value_type(i_,c_->state());
}
-template <class ElementParser, class IteratorPolicy>
-prefix_ bool senf::detail::ListParser_Iterator<ElementParser,IteratorPolicy>::
-equal(ListParser_Iterator const & other)
+template <class Container>
+prefix_ bool
+senf::detail::ListParser_Iterator<Container>::equal(ListParser_Iterator const & other)
const
{
return i_ == other.i_;
}
-template <class ElementParser, class IteratorPolicy>
-prefix_ void senf::detail::ListParser_Iterator<ElementParser,IteratorPolicy>::increment()
+template <class Container>
+prefix_ void senf::detail::ListParser_Iterator<Container>::increment()
{
- i_ = IteratorPolicy::next(i_,s_);
+ i_ = c_->Container::policy::next(*c_, *this);
}
///////////////////////////////////////////////////////////////////////////
template <class ListPolicy>
prefix_ senf::ListParser_Container<ListPolicy>::
ListParser_Container(parser_type const & list)
- : ListPolicy(list), state_(list.state()), i_(std::distance(data().begin(),list.i()))
+ : ListPolicy(static_cast<typename parser_type::policy const &>(list)),
+ state_(list.state()), i_(std::distance(data().begin(),list.i()))
{}
template <class ListPolicy>
prefix_ senf::ListParser_Container<ListPolicy>::~ListParser_Container()
{
- ListPolicy::update(i(),state());
+ ListPolicy::update(*this);
}
// Accessors
senf::ListParser_Container<ListPolicy>::size()
const
{
- ListPolicy::update(i(),state());
+ ListPolicy::update(*this);
return ListPolicy::size(i(),state());
}
prefix_ bool senf::ListParser_Container<ListPolicy>::empty()
const
{
- ListPolicy::update(i(),state());
+ ListPolicy::update(*this);
return begin() == end();
}
senf::ListParser_Container<ListPolicy>::begin()
const
{
- ListPolicy::update(i(),state());
- return iterator(i(),state(),iterator::Begin);
+ ListPolicy::update(*this);
+ iterator i (*this);
+ i.i_ = ListPolicy::setBegin(*this, i);
+ return i;
}
template <class ListPolicy>
senf::ListParser_Container<ListPolicy>::end()
const
{
- ListPolicy::update(i(),state());
- return iterator(i(),state(),iterator::End);
+ ListPolicy::update(*this);
+ iterator i (*this);
+ i.i_ = ListPolicy::setEnd(*this, i);
+ return i;
}
template <class ListPolicy>
senf::ListParser_Container<ListPolicy>::parser()
const
{
- ListPolicy::update(i(),state());
+ ListPolicy::update(*this);
return parser_type(i(),state());
}
senf::ListParser_Container<ListPolicy>::bytes()
const
{
- ListPolicy::update(i(),state());
+ ListPolicy::update(*this);
return ListPolicy::bytes(i(),state());
}
void init (data_iterator i, state_type s) const;
// Members needed only in the container policy
- void erase (data_iterator i, state_type s, iterator p) const;
- void insert (data_iterator i, state_type s, iterator p) const;
-
- struct iterator_policy
- {
- iterator setBegin (data_iterator i, state_type s);
- iterator setEnd (data_iterator i, state_type s);
- void setFromPosition (data_iterator i, state_type s, iterator p);
- iterator next (data_iterator i, state_type s);
- iterator raw (data_iterator i, state_type s) const;
- };
+ void erase (container_type & c, data_iterator p) const;
+ void insert (container_type & c, data_iterator p) const;
+ void update (container_type const & c, data_iterator p) const;
+
+ // Members needed in the container policy for iteration
+ struct iterator_data {};
+
+ data_iterator setBegin (container_type const & c, iterator_data & d) const;
+ data_iterator setEnd (container_type const & c, iterator_data & d) const;
+ void setFromPosition (container_type const & c, iterator_data & d, iterator p) const;
+ data_iterator next (container_type const & c, iterator_data & d) const;
+ data_iterator raw (container_type const & c, iterator_data const & d) const;
};
\endcode
typedef PacketParserBase::state_type state_type;
typedef PacketParserBase::size_type size_type;
- typedef void element_type; ///< Type of list elements
+ typedef unspecified element_type; ///< Type of list elements
/**< This is the parser used to parse the list elements. */
- typedef void parser_type; ///< List parser type
+ typedef unspecified parser_type; ///< List parser type
/**< parser_type is the list parser used to parse a list of
this type,
e.g. <tt>senf::Parse_List<ExampleListPolicy></tt>. */
- typedef void container_type; ///< Type of container wrapper
+ typedef unspecified container_type; ///< Type of container wrapper
/**< This is the container wrapper of the list, e.g.
<tt>Parse_List_Container<ExampleListPolicy></tt>. The
container may however use a \e different policy, as
/**< This is called after an element has been inserted at p
into the List (i,s) to update the meta-data. */
- /** \brief Example of a list iterator policy. ONLY FOR EXPOSITION.
-
- \see \ref ExampleListPolicy \n
- \ref ListParser
- */
- struct iterator_policy
- {
- iterator setBegin(iterator i, state_type s); ///< Initialize iterator to begin()
+ iterator setBegin(iterator i, state_type s); ///< Initialize iterator to begin()
/**< Initialize the policy from the given List (i,s). Set
the iterator to the beginning iterator. Return
data_iterator to the first element.
\warning if the list is empty, the returned iterator
\e must be the same as the one returned by setEnd. */
- iterator setEnd(iterator i, state_type s); ///< Initialize iterator to end()
+ iterator setEnd(iterator i, state_type s); ///< Initialize iterator to end()
/**< Initialize the policy from the given List (i,s). Set
the iterator to the end iterator. Return data_iterator
used to mark the end of the range. This may be a
special sentinel value (e.g. data().end()) if
needed. */
- void setFromPosition(iterator i, state_type s, iterator p);
+ void setFromPosition(iterator i, state_type s, iterator p);
///< Initialize iterator from the given raw position
/**< Set the iterator to the Element at raw position p. This
operation can potentially be very inefficient if the
list needs to be traversed from the beginning until the
iterator is found. */
- iterator next(iterator i, state_type s); ///< Advance to next element
+ iterator next(iterator i, state_type s); ///< Advance to next element
/**< given an iterator to an element, go to the next
element. */
- iterator raw(iterator i, state_type s); ///< Return raw position of element
+ iterator raw(iterator i, state_type s); ///< Return raw position of element
/**< Given the iterator state (i,s), return the raw iterator
to the datum. This will be i in almost all cases EXCEPT
if a special sentinel value is used as end() value. In
this case, this member must return the real position
after the last element. */
- };
- /** \brief Example of a list container policy. ONLY FOR EXPOSITION
+ void update(iterator i, state_type s); ///< Called before every container access
- \see \ref ExampleListPolicy \n
- \ref ListParser
- */
- struct container_policy
- {
- void init(iterator i, state_type s); ///< Initialize new container
- void update(iterator i, state_type s); ///< Called before every container access
- };
+ struct iterator_data
+ {};
};
}
namespace senf {
- namespace detail { template <class ElementParser, class IteratorPolicy>
- class ListParser_Iterator; }
+ namespace detail { template <class Container> class ListParser_Iterator; }
template <class ListPolicy>
class ListParser_Container;
private ListPolicy
{
public:
+ typedef ListPolicy policy;
+
ListParser(data_iterator i, state_type s);
ListParser(ListPolicy policy, data_iterator i, state_type s);
///< Additional policy specific constructor
// Container interface
typedef typename ListPolicy::element_type value_type;
- typedef detail::ListParser_Iterator<
- value_type, typename ListPolicy::iterator_policy > iterator;
- typedef iterator const_iterator;
typedef typename ListPolicy::container_type container;
size_type size() const;
bool empty() const;
- iterator begin() const;
- iterator end() const;
-
value_type front() const;
value_type back() const;
void resize (size_type n) const;
template <class Value> void resize (size_type n, Value value) const;
+ static ListParser & get(ListPolicy & p);
+ static ListParser const & get(ListPolicy const & p);
+
private:
template <class Policy> friend class ListParser_Container;
};
///////////////////////////////////////////////////////////////////////////
// Types
+ typedef ListPolicy policy;
typedef typename ListPolicy::parser_type parser_type;
typedef PacketParserBase::data_iterator data_iterator;
typedef PacketParserBase::size_type size_type;
typedef PacketParserBase::difference_type difference_type;
typedef typename ListPolicy::element_type value_type;
- typedef detail::ListParser_Iterator<
- value_type, typename ListPolicy::iterator_policy> iterator;
+ typedef detail::ListParser_Iterator<ListParser_Container> iterator;
typedef iterator const_iterator;
typedef PacketParserBase::state_type state_type;
///@}
private:
+ friend class detail::ListParser_Iterator<ListParser_Container>;
+
state_type state_;
size_type i_;
};
+# define SENF_PARSER_LIST(name, size, elt_type) \
+ SENF_PARSER_LIST_I(public, name, size, elt_type)
+
+# define SENF_PARSER_PRIVATE_LIST(name, size, elt_type) \
+ SENF_PARSER_LIST_I(private, name, size, elt_type)
}
\internal
*/
- template <class ElementParser, class IteratorPolicy>
+ template <class Container>
class ListParser_Iterator
- : public boost::iterator_facade< ListParser_Iterator<ElementParser,IteratorPolicy>,
- ElementParser,
+ : public boost::iterator_facade< ListParser_Iterator<Container>,
+ typename Container::value_type,
boost::forward_traversal_tag,
- ElementParser >,
- private IteratorPolicy
+ typename Container::value_type >,
+ private Container::policy::iterator_data
{
public:
- enum Begin_t { Begin };
- enum End_t { End };
+ typedef typename Container::value_type value_type;
ListParser_Iterator();
- ListParser_Iterator(PacketParserBase::data_iterator i, PacketParserBase::state_type s,
- Begin_t);
- ListParser_Iterator(PacketParserBase::data_iterator i, PacketParserBase::state_type s,
- End_t);
- ListParser_Iterator(PacketParserBase::data_iterator i, PacketParserBase::state_type s,
- PacketParserBase::data_iterator p);
+ explicit ListParser_Iterator(Container const & c);
PacketParserBase::data_iterator raw() const;
+ PacketParserBase::data_iterator i() const;
+ static ListParser_Iterator & get(typename Container::policy::iterator_data & d);
+ static ListParser_Iterator const & get(typename Container::policy::iterator_data const & d);
+
private:
friend class boost::iterator_core_access;
+ template <class P> friend class ListParser_Container;
- ElementParser dereference() const;
+ value_type dereference() const;
bool equal(ListParser_Iterator const & other) const;
void increment();
PacketParserBase::data_iterator i_;
- PacketParserBase::state_type s_;
+ Container const * c_;
+ };
+
+ template <class ElementParser, class AuxPolicy, class AuxTag>
+ struct ListParserPolicy
+ {};
+
+ template <class ElementParser>
+ struct ListParserTraits
+ {
+ template <class AuxPolicy, class AuxTag>
+ struct parser {
+ typedef senf::ListParser<
+ typename ListParserPolicy<ElementParser, AuxPolicy, AuxTag>::type > type;
+ };
};
+# define SENF_PARSER_LIST_I(access, name, size, elt_type) \
+ SENF_PARSER_REQUIRE_VAR(list) \
+ SENF_PARSER_COLLECTION_I( access, \
+ name, \
+ size, \
+ senf::detail::ListParserTraits<elt_type> )
+
}}
///////////////////////////////ih.e////////////////////////////////////////
#
# // 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) \
///////////////////////////////ct.p////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////
-// senf::VectorParser<ElementParser,Sizer>
+// senf::VectorParser<ElementParser,AuxPolicy>
-template <class ElementParser, class Sizer>
-prefix_ void senf::VectorParser<ElementParser,Sizer>::init()
+template <class ElementParser, class AuxPolicy>
+prefix_ void senf::VectorParser<ElementParser,AuxPolicy>::init()
const
{
- aux(i(), state()) = 0;
+ aux(0, i(), state());
iterator i (begin());
iterator const e (end());
for (; i!=e; ++i)
}
///////////////////////////////////////////////////////////////////////////
-// senf::VectorParser_Container<ElementParser,Sizer>
+// senf::VectorParser_Container<ElementParser,AuxPolicy>
-template <class ElementParser, class Sizer>
-prefix_ void senf::VectorParser_Container<ElementParser,Sizer>::init()
+template <class ElementParser, class AuxPolicy>
+prefix_ void senf::VectorParser_Container<ElementParser,AuxPolicy>::init()
const
{
iterator i (begin());
// Mutators
-template <class ElementParser, class Sizer>
-prefix_ typename senf::VectorParser_Container<ElementParser,Sizer>::iterator
-senf::VectorParser_Container<ElementParser,Sizer>::shift(iterator pos, size_type n)
+template <class ElementParser, class AuxPolicy>
+prefix_ typename senf::VectorParser_Container<ElementParser,AuxPolicy>::iterator
+senf::VectorParser_Container<ElementParser,AuxPolicy>::shift(iterator pos, size_type n)
{
size_type ix (std::distance(data().begin(),pos.raw()));
data().insert(pos.raw(),n*ElementParser::fixed_bytes,0);
return iterator(boost::next(data().begin(),ix),state());
}
-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,
size_type n,
Value const & t)
{
}
#ifndef DOXYGEN
-template <class ElementParser, class Sizer>
+template <class ElementParser, class AuxPolicy>
template <class ForwardIterator>
-prefix_ void senf::VectorParser_Container<ElementParser,Sizer>::
+prefix_ void senf::VectorParser_Container<ElementParser,AuxPolicy>::
insert(iterator pos, ForwardIterator f, ForwardIterator l,
typename boost::disable_if< boost::is_convertible<ForwardIterator,size_type> >::type *)
{
*j << *f;
}
#else
-template <class ElementParser, class Sizer>
+template <class ElementParser, class AuxPolicy>
template <class ForwardIterator>
-prefix_ void senf::VectorParser_Container<ElementParser,Sizer>::
+prefix_ void senf::VectorParser_Container<ElementParser,AuxPolicy>::
insert(iterator pos, ForwardIterator f, ForwardIterator l)
{}
#endif
-template <class ElementParser, class Sizer>
-prefix_ void senf::VectorParser_Container<ElementParser,Sizer>::resize(size_type n)
+template <class ElementParser, class AuxPolicy>
+prefix_ void senf::VectorParser_Container<ElementParser,AuxPolicy>::resize(size_type n)
{
if (size()>=n)
erase(boost::next(begin(),n),end());
push_back_space(n-size());
}
-template <class ElementParser, class Sizer>
+template <class ElementParser, class AuxPolicy>
template <class Value>
-prefix_ void senf::VectorParser_Container<ElementParser,Sizer>::resize(size_type n, Value value)
+prefix_ void senf::VectorParser_Container<ElementParser,AuxPolicy>::resize(size_type n,
+ Value value)
{
if (size()>=n)
erase(boost::next(begin(),n),end());
template <class ElementParser, class AuxPolicy>
prefix_ void senf::VectorParser_Container<ElementParser,AuxPolicy>::setSize(size_type value)
{
- aux(i(),state()).value(value);
+ aux(value, i(),state());
}
/////////////////////////////cti.e///////////////////////////////////////
namespace senf {
- template <class ElementParser, class Sizer> class VectorParser_Container;
+ template <class ElementParser, class AuxPolicy> class VectorParser_Container;
/** \brief Collection of fixed-size elements
> BOOST_PP_CAT(name, _vec_t); \
field( name, BOOST_PP_CAT(name, _vec_t) )
+ template <class ElementParser, class AuxPolicy, class AuxTag>
+ struct VectorParserPolicy
+ {};
+
+ template <class ElementParser, class AuxPolicy>
+ struct VectorParserPolicy<ElementParser, AuxPolicy, senf::detail::auxtag::none>
+ {
+ typedef AuxPolicy type;
+ };
+
+ template <class ElementParser, class AuxPolicy, class Transform>
+ struct VectorParserPolicy<ElementParser, AuxPolicy,
+ senf::detail::auxtag::transform<Transform> >
+ {
+ typedef senf::detail::TransformAuxParserPolicy<AuxPolicy, Transform> type;
+ };
+
+ template <unsigned fixedSize>
+ struct VectorParserBytesTransform
+ {
+ typedef PacketParserBase::size_type value_type;
+ static value_type get(value_type v) { return v/fixedSize; }
+ static value_type set(value_type v) { return v*fixedSize; }
+ };
+
+ template <class ElementParser, class AuxPolicy>
+ struct VectorParserPolicy<ElementParser, AuxPolicy, senf::detail::auxtag::bytes>
+ {
+ typedef senf::detail::TransformAuxParserPolicy<
+ AuxPolicy,
+ VectorParserBytesTransform<ElementParser::fixed_bytes> > type;
+ };
+
template <class ElementParser>
struct VectorParserTraits
{
template <class AuxPolicy, class AuxTag>
struct parser {
- typedef senf::VectorParser<ElementParser, AuxPolicy> type;
+ typedef senf::VectorParser<
+ ElementParser,
+ typename VectorParserPolicy<ElementParser, AuxPolicy, AuxTag>::type > type;
};
};
namespace {
+ struct TestTransform
+ {
+ typedef unsigned value_type;
+ static unsigned get(unsigned v) { return v-2; }
+ static unsigned set(unsigned v) { return v+2; }
+ };
+
struct TestVectorParser
: public senf::PacketParserBase
{
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_VECTOR ( vec1 , transform(TestTransform, size1) , senf::UInt16Parser );
+ SENF_PARSER_VECTOR ( vec2 , bytes(size2) , senf::UInt16Parser );
SENF_PARSER_FINALIZE( TestVectorParser );
};
BOOST_AUTO_UNIT_TEST(vectorMacro)
{
- unsigned char data[] = { 0x03, // size1
- 0x02, // size2
+ unsigned char data[] = { 0x05, // size1
+ 0x04, // size2
0x01, 0x02, 0x03, 0x04, // dummy
0x05, 0x06, // vec1[0]
0x07, 0x08, // vec1[1]