// Custom includes
#include "PacketParser.hh"
+#include <boost/preprocessor/cat.hpp>
+#include <boost/preprocessor/seq/enum.hpp>
///////////////////////////////ih.p////////////////////////////////////////
namespace senf {
namespace detail {
-# define SENF_PARSE_VARIANT_TPL_ARGS_DFL(n) \
- BOOST_PP_ENUM_PARAMS_WITH_A_DEFAULT( SENF_LIMIT_PARSE_VARIANT, \
- n, \
- boost::mpl::na )
-
-# define SENF_PARSE_VARIANT_TPL_ARGS(n) BOOST_PP_ENUM_PARAMS( SENF_LIMIT_PARSE_VARIANT, n )
-
-# ifndef DOXYGEN
+#ifndef DOXYGEN
template <class Variant, unsigned N>
struct VariantBytes {
static PacketParserBase::size_type bytes(Variant const & v, unsigned n);
};
-# endif
-
- /** \brief Internal: Variant Policy used by senf::DirectVariantParser */
- template <class ChooserType, unsigned Distance, class Translator>
- struct DirectVariantParser
+ template <class AuxPolicy, class AuxTag>
+ struct VariantParserPolicy {};
+
+ template <class AuxPolicy>
+ struct VariantParserPolicy<AuxPolicy, senf::detail::auxtag::none>
{
- typedef PacketParserBase::data_iterator data_iterator;
- typedef PacketParserBase::state_type state_type;
- typedef PacketParserBase::size_type size_type;
-
- static size_type const init_bytes = 0;
- size_type bytes(data_iterator i, state_type s) const { return 0; }
- data_iterator begin(data_iterator i, state_type s) const { return i; }
-
- ChooserType chooser(data_iterator i, state_type s) const {
- return ChooserType(boost::prior(i, Distance),s);
- }
-
- unsigned variant(data_iterator i, state_type s) const {
- return Translator::fromChooser(chooser(i,s).value());
- }
-
- void variant(unsigned v, data_iterator i, state_type s) {
- chooser(i,s).value(Translator::toChooser(v));
- }
+ typedef AuxPolicy type;
};
- /** \brief Internal: Identity chooser translator */
- struct VariantParser_IdentityTranslator {
- static unsigned fromChooser(unsigned value) { return value; }
- static unsigned toChooser(unsigned value) { return value; }
+
+ template <class AuxPolicy, class Transform>
+ struct VariantParserPolicy<AuxPolicy,
+ senf::detail::auxtag::transform<Transform,
+ senf::detail::auxtag::none> >
+ {
+ typedef TransformAuxParserPolicy<AuxPolicy, Transform> type;
};
-# define SENF_PARSER_VARIANT_(r, data, elem) ,elem
+ template <class Parsers>
+ struct VariantParserTraits
+ {
+ template <class AuxPolicy, class AuxTag>
+ struct parser {
+ typedef senf::VariantParser<
+ typename VariantParserPolicy<AuxPolicy, AuxTag>::type,
+ Parsers> type;
+ };
+ };
+
+# define SENF_PARSER_VARIANT_I(access, name, chooser, types) \
+ typedef boost::mpl::vector< BOOST_PP_SEQ_ENUM(types) > BOOST_PP_CAT(name, _parsers); \
+ SENF_PARSER_REQUIRE_VAR(variant) \
+ SENF_PARSER_COLLECTION_I( \
+ access, \
+ name, \
+ chooser, \
+ senf::detail::VariantParserTraits< BOOST_PP_CAT(name, _parsers) > )
-# define SENF_PARSER_VARIANT_I(field, name, chooser, translator, types) \
- typedef senf::DirectVariantParser< \
- BOOST_PP_CAT(chooser, _t), \
- SENF_PARSER_CURRENT_FIXED_OFFSET() - SENF_PARSER_FIXED_OFFSET(chooser), \
- translator \
- BOOST_PP_SEQ_FOR_EACH( SENF_PARSER_VARIANT_, _, types ) \
- >::parser BOOST_PP_CAT(name, _variant_t); \
- field( name, BOOST_PP_CAT(name, _variant_t) )
+#endif
}}