diff options
Diffstat (limited to 'boost/spirit/home/x3/core/detail/parse_into_container.hpp')
-rw-r--r-- | boost/spirit/home/x3/core/detail/parse_into_container.hpp | 77 |
1 files changed, 61 insertions, 16 deletions
diff --git a/boost/spirit/home/x3/core/detail/parse_into_container.hpp b/boost/spirit/home/x3/core/detail/parse_into_container.hpp index 4b19115a67..96424a4278 100644 --- a/boost/spirit/home/x3/core/detail/parse_into_container.hpp +++ b/boost/spirit/home/x3/core/detail/parse_into_container.hpp @@ -7,10 +7,6 @@ #if !defined(SPIRIT_PARSE_INTO_CONTAINER_JAN_15_2013_0957PM) #define SPIRIT_PARSE_INTO_CONTAINER_JAN_15_2013_0957PM -#if defined(_MSC_VER) -#pragma once -#endif - #include <type_traits> #include <boost/spirit/home/x3/support/traits/container_traits.hpp> @@ -41,21 +37,24 @@ namespace boost { namespace spirit { namespace x3 { namespace detail } }; - +/* $$$ clang reports: warning: class template partial specialization contains + * a template parameter that can not be deduced; this partial specialization + * will never be used $$$ + * // save to associative fusion container where Key // is variant over possible keys template <typename ...T> struct save_to_assoc_attr<variant<T...> > { typedef variant<T...> variant_t; - + template <typename Value, typename Attribute> static void call(const variant_t key, Value& value, Attribute& attr) { apply_visitor(saver_visitor<Attribute, Value>(attr, value), key); } }; - +*/ template <typename Attribute, typename Value> struct saver_visitor : boost::static_visitor<void> { @@ -64,7 +63,7 @@ namespace boost { namespace spirit { namespace x3 { namespace detail Attribute& attr; Value& value; - + template <typename Key> void operator()(Key) const { @@ -72,6 +71,13 @@ namespace boost { namespace spirit { namespace x3 { namespace detail } }; + template <typename Parser, typename Container, typename Context> + struct parser_accepts_container + : traits::is_substitute< + typename traits::attribute_of<Parser, Context>::type + , Container + > + {}; template <typename Parser> struct parse_into_container_base_impl @@ -81,10 +87,10 @@ namespace boost { namespace spirit { namespace x3 { namespace detail // Parser has attribute (synthesize; Attribute is a container) template <typename Iterator, typename Context , typename RContext, typename Attribute> - static bool call_synthesize( + static bool call_synthesize_x( Parser const& parser , Iterator& first, Iterator const& last - , Context const& context, RContext& rcontext, Attribute& attr) + , Context const& context, RContext& rcontext, Attribute& attr, mpl::false_) { // synthesized attribute needs to be value initialized typedef typename @@ -100,6 +106,33 @@ namespace boost { namespace spirit { namespace x3 { namespace detail return true; } + // Parser has attribute (synthesize; Attribute is a container) + template <typename Iterator, typename Context + , typename RContext, typename Attribute> + static bool call_synthesize_x( + Parser const& parser + , Iterator& first, Iterator const& last + , Context const& context, RContext& rcontext, Attribute& attr, mpl::true_) + { + return parser.parse(first, last, context, rcontext, attr); + } + + // Parser has attribute (synthesize; Attribute is a container) + template <typename Iterator, typename Context + , typename RContext, typename Attribute> + static bool call_synthesize( + Parser const& parser + , Iterator& first, Iterator const& last + , Context const& context, RContext& rcontext, Attribute& attr) + { + typedef + parser_accepts_container<Parser, Attribute, Context> + parser_accepts_container; + + return call_synthesize_x(parser, first, last, context, rcontext, attr + , parser_accepts_container()); + } + // Parser has attribute (synthesize; Attribute is a single element fusion sequence) template <typename Iterator, typename Context , typename RContext, typename Attribute> @@ -173,7 +206,7 @@ namespace boost { namespace spirit { namespace x3 { namespace detail { return parser.parse(first, last, context, rcontext, unused); } - + public: @@ -190,7 +223,7 @@ namespace boost { namespace spirit { namespace x3 { namespace detail template <typename Parser, typename Context, typename RContext, typename Enable = void> struct parse_into_container_impl : parse_into_container_base_impl<Parser> {}; - template <typename Parser, typename Container, typename RContext, typename Context> + template <typename Parser, typename Container, typename Context> struct parser_attr_is_substitute_for_container_value : traits::is_substitute< typename traits::attribute_of<Parser, Context>::type @@ -206,7 +239,7 @@ namespace boost { namespace spirit { namespace x3 { namespace detail static bool call( Parser const& parser , Iterator& first, Iterator const& last - , Context const& context, RContext& rcontext, Attribute& attr, mpl::true_) + , Context const& context, RContext& rcontext, Attribute& attr, mpl::false_) { return parse_into_container_base_impl<Parser>::call( parser, first, last, context, rcontext, attr); @@ -216,7 +249,7 @@ namespace boost { namespace spirit { namespace x3 { namespace detail static bool call( Parser const& parser , Iterator& first, Iterator const& last - , Context const& context, RContext& rcontext, Attribute& attr, mpl::false_) + , Context const& context, RContext& rcontext, Attribute& attr, mpl::true_) { return parser.parse(first, last, context, rcontext, attr); } @@ -226,9 +259,21 @@ namespace boost { namespace spirit { namespace x3 { namespace detail , Iterator& first, Iterator const& last , Context const& context, RContext& rcontext, Attribute& attr) { + typedef parser_accepts_container< + Parser, Attribute, Context> + parser_accepts_container; + + typedef parser_attr_is_substitute_for_container_value< + Parser, Attribute, Context> + parser_attr_is_substitute_for_container_value; + + typedef mpl::or_< + parser_accepts_container + , mpl::not_<parser_attr_is_substitute_for_container_value>> + pass_attibute_as_is; + return call(parser, first, last, context, rcontext, attr, - parser_attr_is_substitute_for_container_value< - Parser, Attribute, Context, RContext>()); + pass_attibute_as_is()); } }; |