summaryrefslogtreecommitdiff
path: root/boost/spirit/home/x3/operator
diff options
context:
space:
mode:
Diffstat (limited to 'boost/spirit/home/x3/operator')
-rw-r--r--boost/spirit/home/x3/operator/alternative.hpp68
-rw-r--r--boost/spirit/home/x3/operator/and_predicate.hpp47
-rw-r--r--boost/spirit/home/x3/operator/detail/alternative.hpp317
-rw-r--r--boost/spirit/home/x3/operator/detail/sequence.hpp501
-rw-r--r--boost/spirit/home/x3/operator/difference.hpp75
-rw-r--r--boost/spirit/home/x3/operator/kleene.hpp59
-rw-r--r--boost/spirit/home/x3/operator/list.hpp73
-rw-r--r--boost/spirit/home/x3/operator/not_predicate.hpp47
-rw-r--r--boost/spirit/home/x3/operator/optional.hpp86
-rw-r--r--boost/spirit/home/x3/operator/plus.hpp63
-rw-r--r--boost/spirit/home/x3/operator/sequence.hpp79
11 files changed, 1415 insertions, 0 deletions
diff --git a/boost/spirit/home/x3/operator/alternative.hpp b/boost/spirit/home/x3/operator/alternative.hpp
new file mode 100644
index 0000000000..1566780bc6
--- /dev/null
+++ b/boost/spirit/home/x3/operator/alternative.hpp
@@ -0,0 +1,68 @@
+/*=============================================================================
+ Copyright (c) 2001-2014 Joel de Guzman
+
+ Distributed under the Boost Software License, Version 1.0. (See accompanying
+ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+=============================================================================*/
+#if !defined(SPIRIT_ALTERNATIVE_JAN_07_2013_1131AM)
+#define SPIRIT_ALTERNATIVE_JAN_07_2013_1131AM
+
+#if defined(_MSC_VER)
+#pragma once
+#endif
+
+#include <boost/spirit/home/x3/support/traits/attribute_of.hpp>
+#include <boost/spirit/home/x3/core/parser.hpp>
+#include <boost/spirit/home/x3/operator/detail/alternative.hpp>
+
+namespace boost { namespace spirit { namespace x3
+{
+ template <typename Left, typename Right>
+ struct alternative : binary_parser<Left, Right, alternative<Left, Right>>
+ {
+ typedef binary_parser<Left, Right, alternative<Left, Right>> base_type;
+
+ alternative(Left left, Right right)
+ : base_type(left, right) {}
+
+ template <typename Iterator, typename Context, typename RContext>
+ bool parse(
+ Iterator& first, Iterator const& last
+ , Context const& context, RContext& rcontext, unused_type) const
+ {
+ return this->left.parse(first, last, context, rcontext, unused)
+ || this->right.parse(first, last, context, rcontext, unused);
+ }
+
+ template <typename Iterator, typename Context
+ , typename RContext, typename Attribute>
+ bool parse(
+ Iterator& first, Iterator const& last
+ , Context const& context, RContext& rcontext, Attribute& attr) const
+ {
+ if (detail::parse_alternative(this->left, first, last, context, rcontext, attr))
+ return true;
+ if (detail::parse_alternative(this->right, first, last, context, rcontext, attr))
+ return true;
+ return false;
+ }
+ };
+
+ template <typename Left, typename Right>
+ inline alternative<
+ typename extension::as_parser<Left>::value_type
+ , typename extension::as_parser<Right>::value_type>
+ operator|(Left const& left, Right const& right)
+ {
+ return {as_parser(left), as_parser(right)};
+ }
+}}}
+
+namespace boost { namespace spirit { namespace x3 { namespace traits
+{
+ template <typename Left, typename Right, typename Context>
+ struct attribute_of<x3::alternative<Left, Right>, Context>
+ : x3::detail::attribute_of_alternative<Left, Right, Context> {};
+}}}}
+
+#endif
diff --git a/boost/spirit/home/x3/operator/and_predicate.hpp b/boost/spirit/home/x3/operator/and_predicate.hpp
new file mode 100644
index 0000000000..e0892cd8cf
--- /dev/null
+++ b/boost/spirit/home/x3/operator/and_predicate.hpp
@@ -0,0 +1,47 @@
+/*=============================================================================
+ Copyright (c) 2001-2014 Joel de Guzman
+
+ Distributed under the Boost Software License, Version 1.0. (See accompanying
+ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+=============================================================================*/
+#if !defined(SPIRIT_AND_PREDICATE_MARCH_23_2007_0617PM)
+#define SPIRIT_AND_PREDICATE_MARCH_23_2007_0617PM
+
+#if defined(_MSC_VER)
+#pragma once
+#endif
+
+#include <boost/spirit/home/x3/core/parser.hpp>
+
+namespace boost { namespace spirit { namespace x3
+{
+ template <typename Subject>
+ struct and_predicate : unary_parser<Subject, and_predicate<Subject>>
+ {
+ typedef unary_parser<Subject, and_predicate<Subject>> base_type;
+
+ typedef unused_type attribute_type;
+ static bool const has_attribute = false;
+
+ and_predicate(Subject const& subject)
+ : base_type(subject) {}
+
+ template <typename Iterator, typename Context
+ , typename RContext, typename Attribute>
+ bool parse(Iterator& first, Iterator const& last
+ , Context const& context, RContext& rcontext, Attribute& /*attr*/) const
+ {
+ Iterator i = first;
+ return this->subject.parse(i, last, context, rcontext, unused);
+ }
+ };
+
+ template <typename Subject>
+ inline and_predicate<typename extension::as_parser<Subject>::value_type>
+ operator&(Subject const& subject)
+ {
+ return {as_parser(subject)};
+ }
+}}}
+
+#endif
diff --git a/boost/spirit/home/x3/operator/detail/alternative.hpp b/boost/spirit/home/x3/operator/detail/alternative.hpp
new file mode 100644
index 0000000000..54f86e00df
--- /dev/null
+++ b/boost/spirit/home/x3/operator/detail/alternative.hpp
@@ -0,0 +1,317 @@
+/*=============================================================================
+ Copyright (c) 2001-2014 Joel de Guzman
+
+ Distributed under the Boost Software License, Version 1.0. (See accompanying
+ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+=============================================================================*/
+#if !defined(SPIRIT_ALTERNATIVE_DETAIL_JAN_07_2013_1245PM)
+#define SPIRIT_ALTERNATIVE_DETAIL_JAN_07_2013_1245PM
+
+#if defined(_MSC_VER)
+#pragma once
+#endif
+
+#include <boost/spirit/home/x3/support/traits/attribute_of.hpp>
+#include <boost/spirit/home/x3/support/traits/is_variant.hpp>
+#include <boost/spirit/home/x3/support/traits/tuple_traits.hpp>
+#include <boost/spirit/home/x3/support/traits/move_to.hpp>
+#include <boost/spirit/home/x3/support/traits/variant_has_substitute.hpp>
+#include <boost/spirit/home/x3/support/traits/variant_find_substitute.hpp>
+#include <boost/spirit/home/x3/core/detail/parse_into_container.hpp>
+#include <boost/variant/variant.hpp>
+
+#include <boost/mpl/copy_if.hpp>
+#include <boost/mpl/not.hpp>
+#include <boost/mpl/if.hpp>
+#include <boost/mpl/eval_if.hpp>
+#include <boost/mpl/vector.hpp>
+#include <boost/mpl/joint_view.hpp>
+
+#include <boost/fusion/include/front.hpp>
+
+#include <boost/type_traits/is_same.hpp>
+
+namespace boost { namespace spirit { namespace x3
+{
+ template <typename Left, typename Right>
+ struct alternative;
+}}}
+
+namespace boost { namespace spirit { namespace x3 { namespace detail
+{
+ struct pass_variant_unused
+ {
+ typedef unused_type type;
+
+ template <typename T>
+ static unused_type
+ call(T&)
+ {
+ return unused_type();
+ }
+ };
+
+ template <typename Attribute>
+ struct pass_variant_used
+ {
+ typedef Attribute& type;
+
+ static Attribute&
+ call(Attribute& v)
+ {
+ return v;
+ }
+ };
+
+ template <>
+ struct pass_variant_used<unused_type> : pass_variant_unused {};
+
+ template <typename Parser, typename Attribute, typename Context
+ , typename Enable = void>
+ struct pass_parser_attribute
+ {
+ typedef typename
+ traits::attribute_of<Parser, Context>::type
+ attribute_type;
+ typedef typename
+ traits::variant_find_substitute<Attribute, attribute_type>::type
+ substitute_type;
+
+ typedef typename
+ mpl::if_<
+ is_same<Attribute, substitute_type>
+ , Attribute&
+ , substitute_type
+ >::type
+ type;
+
+ template <typename Attribute_>
+ static Attribute_&
+ call(Attribute_& attr, mpl::true_)
+ {
+ return attr;
+ }
+
+ template <typename Attribute_>
+ static type
+ call(Attribute_&, mpl::false_)
+ {
+ return type();
+ }
+
+ template <typename Attribute_>
+ static type
+ call(Attribute_& attr)
+ {
+ return call(attr, is_same<Attribute_, typename remove_reference<type>::type>());
+ }
+ };
+
+ // Pass non-variant attributes as-is
+ template <typename Parser, typename Attribute, typename Context
+ , typename Enable = void>
+ struct pass_non_variant_attribute
+ {
+ typedef Attribute& type;
+
+ static Attribute&
+ call(Attribute& attr)
+ {
+ return attr;
+ }
+ };
+
+ // Unwrap single element sequences
+ template <typename Parser, typename Attribute, typename Context>
+ struct pass_non_variant_attribute<Parser, Attribute, Context,
+ typename enable_if<traits::is_size_one_sequence<Attribute>>::type>
+ {
+ typedef typename remove_reference<
+ typename fusion::result_of::front<Attribute>::type>::type
+ attr_type;
+
+ typedef pass_parser_attribute<Parser, attr_type, Context> pass;
+ typedef typename pass::type type;
+
+ template <typename Attribute_>
+ static type
+ call(Attribute_& attr)
+ {
+ return pass::call(fusion::front(attr));
+ }
+ };
+
+ template <typename Parser, typename Attribute, typename Context>
+ struct pass_parser_attribute<Parser, Attribute, Context,
+ typename enable_if_c<(!traits::is_variant<Attribute>::value)>::type>
+ : pass_non_variant_attribute<Parser, Attribute, Context>
+ {};
+
+ template <typename Parser, typename Context>
+ struct pass_parser_attribute<Parser, unused_type, Context>
+ : pass_variant_unused {};
+
+ template <typename Parser, typename Attribute, typename Context>
+ struct pass_variant_attribute :
+ mpl::if_c<traits::has_attribute<Parser, Context>::value
+ , pass_parser_attribute<Parser, Attribute, Context>
+ , pass_variant_unused>::type
+ {
+ typedef typename mpl::false_ is_alternative;
+ };
+
+ template <typename L, typename R, typename Attribute, typename Context>
+ struct pass_variant_attribute<alternative<L, R>, Attribute, Context> :
+ mpl::if_c<traits::has_attribute<alternative<L, R>, Context>::value
+ , pass_variant_used<Attribute>
+ , pass_variant_unused>::type
+ {
+ typedef typename mpl::true_ is_alternative;
+ };
+
+ template <typename L, typename R, typename C>
+ struct get_alternative_types
+ {
+ typedef
+ mpl::vector<
+ typename traits::attribute_of<L, C>::type
+ , typename traits::attribute_of<R, C>::type
+ >
+ type;
+ };
+
+ template <typename LL, typename LR, typename R, typename C>
+ struct get_alternative_types<alternative<LL, LR>, R, C>
+ {
+ typedef typename
+ mpl::push_back<
+ typename get_alternative_types<LL, LR, C>::type
+ , typename traits::attribute_of<R, C>::type
+ >::type
+ type;
+ };
+
+ template <typename L, typename RL, typename RR, typename C>
+ struct get_alternative_types<L, alternative<RL, RR>, C>
+ {
+ typedef typename
+ mpl::push_front<
+ typename get_alternative_types<RL, RR, C>::type
+ , typename traits::attribute_of<L, C>::type
+ >::type
+ type;
+ };
+
+ template <typename LL, typename LR, typename RL, typename RR, typename C>
+ struct get_alternative_types<alternative<LL, LR>, alternative<RL, RR>, C>
+ {
+ typedef
+ mpl::joint_view<
+ typename get_alternative_types<LL, LR, C>::type
+ , typename get_alternative_types<RL, RR, C>::type
+ >
+ type;
+ };
+
+ template <typename L, typename R, typename C>
+ struct attribute_of_alternative
+ {
+ // Get all alternative attribute types
+ typedef typename get_alternative_types<L, R, C>::type all_types;
+
+ // Filter all unused_types
+ typedef typename
+ mpl::copy_if<
+ all_types
+ , mpl::not_<is_same<mpl::_1, unused_type>>
+ , mpl::back_inserter<mpl::vector<>>
+ >::type
+ filtered_types;
+
+ // Build a variant if filtered_types is not empty,
+ // else just return unused_type
+ typedef typename
+ mpl::eval_if<
+ mpl::empty<filtered_types>
+ , mpl::identity<unused_type>
+ , make_variant_over<filtered_types>
+ >::type
+ type;
+ };
+
+ template <typename IsAlternative>
+ struct move_if_not_alternative
+ {
+ template<typename T1, typename T2>
+ static void call(T1& attr_, T2& attr) {}
+ };
+
+ template <>
+ struct move_if_not_alternative<mpl::false_ /*is alternative*/>
+ {
+ template<typename T1, typename T2>
+ static void call(T1& attr_, T2& attr)
+ {
+ traits::move_to(attr_, attr);
+ }
+ };
+
+ template <typename Parser, typename Iterator, typename Context
+ , typename RContext, typename Attribute>
+ bool parse_alternative(Parser const& p, Iterator& first, Iterator const& last
+ , Context const& context, RContext& rcontext, Attribute& attr)
+ {
+ typedef detail::pass_variant_attribute<Parser, Attribute, Context> pass;
+
+ typename pass::type attr_ = pass::call(attr);
+ if (p.parse(first, last, context, rcontext, attr_))
+ {
+ move_if_not_alternative<typename pass::is_alternative>::call(attr_, attr);
+ return true;
+ }
+ return false;
+ }
+
+
+ template <typename Left, typename Right, typename Context, typename RContext>
+ struct parse_into_container_impl<alternative<Left, Right>, Context, RContext>
+ {
+ typedef alternative<Left, Right> parser_type;
+
+ template <typename Iterator, typename Attribute>
+ static bool call(
+ parser_type const& parser
+ , Iterator& first, Iterator const& last
+ , Context const& context, RContext& rcontext, Attribute& attr, mpl::true_)
+ {
+ return parse_alternative(parser, first, last, context, rcontext, attr);
+ }
+
+ template <typename Iterator, typename Attribute>
+ static bool call(
+ parser_type const& parser
+ , Iterator& first, Iterator const& last
+ , Context const& context, RContext& rcontext, Attribute& attr, mpl::false_)
+ {
+ return parse_into_container_base_impl<parser_type>::call(
+ parser, first, last, context, rcontext, attr);
+ }
+
+ template <typename Iterator, typename Attribute>
+ static bool call(
+ parser_type const& parser
+ , Iterator& first, Iterator const& last
+ , Context const& context, RContext& rcontext, Attribute& attr)
+ {
+ typedef typename
+ traits::attribute_of<parser_type, Context>::type
+ attribute_type;
+
+ return call(parser, first, last, context, rcontext, attr
+ , traits::variant_has_substitute<attribute_type, Attribute>());
+ }
+ };
+
+}}}}
+
+#endif
diff --git a/boost/spirit/home/x3/operator/detail/sequence.hpp b/boost/spirit/home/x3/operator/detail/sequence.hpp
new file mode 100644
index 0000000000..1163707128
--- /dev/null
+++ b/boost/spirit/home/x3/operator/detail/sequence.hpp
@@ -0,0 +1,501 @@
+/*=============================================================================
+ Copyright (c) 2001-2014 Joel de Guzman
+
+ Distributed under the Boost Software License, Version 1.0. (See accompanying
+ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+=============================================================================*/
+#if !defined(SPIRIT_SEQUENCE_DETAIL_JAN_06_2013_1015AM)
+#define SPIRIT_SEQUENCE_DETAIL_JAN_06_2013_1015AM
+
+#if defined(_MSC_VER)
+#pragma once
+#endif
+
+#include <boost/spirit/home/x3/support/traits/attribute_of.hpp>
+#include <boost/spirit/home/x3/support/traits/attribute_category.hpp>
+#include <boost/spirit/home/x3/support/traits/make_attribute.hpp>
+#include <boost/spirit/home/x3/support/traits/has_attribute.hpp>
+#include <boost/spirit/home/x3/support/traits/is_substitute.hpp>
+#include <boost/spirit/home/x3/support/traits/container_traits.hpp>
+#include <boost/spirit/home/x3/core/detail/parse_into_container.hpp>
+
+#include <boost/fusion/include/begin.hpp>
+#include <boost/fusion/include/end.hpp>
+#include <boost/fusion/include/advance.hpp>
+#include <boost/fusion/include/empty.hpp>
+#include <boost/fusion/include/front.hpp>
+#include <boost/fusion/include/iterator_range.hpp>
+#include <boost/fusion/include/as_deque.hpp>
+#include <boost/fusion/include/mpl.hpp>
+
+#include <boost/mpl/copy_if.hpp>
+#include <boost/mpl/not.hpp>
+#include <boost/mpl/if.hpp>
+#include <boost/mpl/eval_if.hpp>
+#include <boost/mpl/vector.hpp>
+#include <boost/mpl/eval_if.hpp>
+#include <boost/mpl/identity.hpp>
+
+#include <boost/type_traits/add_reference.hpp>
+#include <boost/type_traits/is_same.hpp>
+
+namespace boost { namespace spirit { namespace x3
+{
+ template <typename Left, typename Right>
+ struct sequence;
+}}}
+
+namespace boost { namespace spirit { namespace x3 { namespace detail
+{
+ template <typename Parser, typename Context, typename Enable = void>
+ struct sequence_size
+ {
+ static int const value = traits::has_attribute<Parser, Context>::value;
+ };
+
+ template <typename Parser, typename Context>
+ struct sequence_size_subject
+ : sequence_size<typename Parser::subject_type, Context> {};
+
+ template <typename Parser, typename Context>
+ struct sequence_size<Parser, Context
+ , typename enable_if_c<(Parser::is_pass_through_unary)>::type>
+ : sequence_size_subject<Parser, Context> {};
+
+ template <typename L, typename R, typename Context>
+ struct sequence_size<sequence<L, R>, Context>
+ {
+ static int const value =
+ sequence_size<L, Context>::value +
+ sequence_size<R, Context>::value;
+ };
+
+ struct pass_sequence_attribute_unused
+ {
+ typedef unused_type type;
+
+ template <typename T>
+ static unused_type
+ call(T&)
+ {
+ return unused_type();
+ }
+ };
+
+ template <typename Attribute>
+ struct pass_sequence_attribute_front
+ {
+ typedef typename fusion::result_of::front<Attribute>::type type;
+
+ static typename add_reference<type>::type
+ call(Attribute& attr)
+ {
+ return fusion::front(attr);
+ }
+ };
+
+ template <typename Attribute>
+ struct pass_through_sequence_attribute
+ {
+ typedef Attribute& type;
+
+ template <typename Attribute_>
+ static Attribute_&
+ call(Attribute_& attr)
+ {
+ return attr;
+ }
+ };
+
+ template <typename Parser, typename Attribute>
+ struct pass_sequence_attribute_used :
+ mpl::if_<
+ traits::is_size_one_sequence<Attribute>
+ , pass_sequence_attribute_front<Attribute>
+ , pass_through_sequence_attribute<Attribute>>::type {};
+
+ template <typename Parser, typename Attribute, typename Enable = void>
+ struct pass_sequence_attribute :
+ mpl::if_<
+ fusion::result_of::empty<Attribute>
+ , pass_sequence_attribute_unused
+ , pass_sequence_attribute_used<Parser, Attribute>>::type {};
+
+ template <typename L, typename R, typename Attribute>
+ struct pass_sequence_attribute<sequence<L, R>, Attribute>
+ : pass_through_sequence_attribute<Attribute> {};
+
+ template <typename Parser, typename Attribute>
+ struct pass_sequence_attribute_subject :
+ pass_sequence_attribute<typename Parser::subject_type, Attribute> {};
+
+ template <typename Parser, typename Attribute>
+ struct pass_sequence_attribute<Parser, Attribute
+ , typename enable_if_c<(Parser::is_pass_through_unary)>::type>
+ : pass_sequence_attribute_subject<Parser, Attribute> {};
+
+ template <typename L, typename R, typename Attribute, typename Context
+ , typename Enable = void>
+ struct partition_attribute
+ {
+ static int const l_size = sequence_size<L, Context>::value;
+ static int const r_size = sequence_size<R, Context>::value;
+
+ // If you got an error here, then you are trying to pass
+ // a fusion sequence with the wrong number of elements
+ // as that expected by the (sequence) parser.
+ static_assert(
+ fusion::result_of::size<Attribute>::value == (l_size + r_size)
+ , "Attribute does not have the expected size."
+ );
+
+ typedef typename fusion::result_of::begin<Attribute>::type l_begin;
+ typedef typename fusion::result_of::advance_c<l_begin, l_size>::type l_end;
+ typedef typename fusion::result_of::end<Attribute>::type r_end;
+ typedef fusion::iterator_range<l_begin, l_end> l_part;
+ typedef fusion::iterator_range<l_end, r_end> r_part;
+ typedef pass_sequence_attribute<L, l_part> l_pass;
+ typedef pass_sequence_attribute<R, r_part> r_pass;
+
+ static l_part left(Attribute& s)
+ {
+ auto i = fusion::begin(s);
+ return l_part(i, fusion::advance_c<l_size>(i));
+ }
+
+ static r_part right(Attribute& s)
+ {
+ return r_part(
+ fusion::advance_c<l_size>(fusion::begin(s))
+ , fusion::end(s));
+ }
+ };
+
+ template <typename L, typename R, typename Attribute, typename Context>
+ struct partition_attribute<L, R, Attribute, Context,
+ typename enable_if_c<(!traits::has_attribute<L, Context>::value &&
+ traits::has_attribute<R, Context>::value)>::type>
+ {
+ typedef unused_type l_part;
+ typedef Attribute& r_part;
+ typedef pass_sequence_attribute_unused l_pass;
+ typedef pass_sequence_attribute<R, Attribute> r_pass;
+
+ static unused_type left(Attribute&)
+ {
+ return unused;
+ }
+
+ static Attribute& right(Attribute& s)
+ {
+ return s;
+ }
+ };
+
+ template <typename L, typename R, typename Attribute, typename Context>
+ struct partition_attribute<L, R, Attribute, Context,
+ typename enable_if_c<(traits::has_attribute<L, Context>::value &&
+ !traits::has_attribute<R, Context>::value)>::type>
+ {
+ typedef Attribute& l_part;
+ typedef unused_type r_part;
+ typedef pass_sequence_attribute<L, Attribute> l_pass;
+ typedef pass_sequence_attribute_unused r_pass;
+
+ static Attribute& left(Attribute& s)
+ {
+ return s;
+ }
+
+ static unused_type right(Attribute&)
+ {
+ return unused;
+ }
+ };
+
+ template <typename L, typename R, typename Attribute, typename Context>
+ struct partition_attribute<L, R, Attribute, Context,
+ typename enable_if_c<(!traits::has_attribute<L, Context>::value &&
+ !traits::has_attribute<R, Context>::value)>::type>
+ {
+ typedef unused_type l_part;
+ typedef unused_type r_part;
+ typedef pass_sequence_attribute_unused l_pass;
+ typedef pass_sequence_attribute_unused r_pass;
+
+ static unused_type left(Attribute&)
+ {
+ return unused;
+ }
+
+ static unused_type right(Attribute&)
+ {
+ return unused;
+ }
+ };
+
+ template <typename L, typename R, typename C>
+ struct get_sequence_types
+ {
+ typedef
+ mpl::vector<
+ typename traits::attribute_of<L, C>::type
+ , typename traits::attribute_of<R, C>::type
+ >
+ type;
+ };
+
+ template <typename LL, typename LR, typename R, typename C>
+ struct get_sequence_types<sequence<LL, LR>, R, C>
+ {
+ typedef typename
+ mpl::push_back<
+ typename get_sequence_types<LL, LR, C>::type
+ , typename traits::attribute_of<R, C>::type
+ >::type
+ type;
+ };
+
+ template <typename L, typename RL, typename RR, typename C>
+ struct get_sequence_types<L, sequence<RL, RR>, C>
+ {
+ typedef typename
+ mpl::push_front<
+ typename get_sequence_types<RL, RR, C>::type
+ , typename traits::attribute_of<L, C>::type
+ >::type
+ type;
+ };
+
+ template <typename LL, typename LR, typename RL, typename RR, typename C>
+ struct get_sequence_types<sequence<LL, LR>, sequence<RL, RR>, C>
+ {
+ typedef
+ mpl::joint_view<
+ typename get_sequence_types<LL, LR, C>::type
+ , typename get_sequence_types<RL, RR, C>::type
+ >
+ type;
+ };
+
+ template <typename L, typename R, typename C>
+ struct attribute_of_sequence
+ {
+ // Get all sequence attribute types
+ typedef typename get_sequence_types<L, R, C>::type all_types;
+
+ // Filter all unused_types
+ typedef typename
+ mpl::copy_if<
+ all_types
+ , mpl::not_<is_same<mpl::_1, unused_type>>
+ , mpl::back_inserter<mpl::vector<>>
+ >::type
+ filtered_types;
+
+ // Build a fusion::deque if filtered_types is not empty,
+ // else just return unused_type
+ typedef typename
+ mpl::eval_if<
+ mpl::empty<filtered_types>
+ , mpl::identity<unused_type>
+ , mpl::if_<mpl::equal_to<mpl::size<filtered_types>, mpl::int_<1> >,
+ typename mpl::front<filtered_types>::type
+ , typename fusion::result_of::as_deque<filtered_types>::type >
+ >::type
+ type;
+ };
+
+ template <typename Parser, typename Iterator, typename Context
+ , typename RContext, typename Attribute>
+ bool parse_sequence(
+ Parser const& parser, Iterator& first, Iterator const& last
+ , Context const& context, RContext& rcontext, Attribute& attr
+ , traits::tuple_attribute)
+ {
+ typedef typename Parser::left_type Left;
+ typedef typename Parser::right_type Right;
+ typedef partition_attribute<Left, Right, Attribute, Context> partition;
+ typedef typename partition::l_pass l_pass;
+ typedef typename partition::r_pass r_pass;
+
+ typename partition::l_part l_part = partition::left(attr);
+ typename partition::r_part r_part = partition::right(attr);
+ typename l_pass::type l_attr = l_pass::call(l_part);
+ typename r_pass::type r_attr = r_pass::call(r_part);
+
+ Iterator save = first;
+ if (parser.left.parse(first, last, context, rcontext, l_attr)
+ && parser.right.parse(first, last, context, rcontext, r_attr))
+ return true;
+ first = save;
+ return false;
+ }
+
+ template <typename Parser, typename Iterator, typename Context
+ , typename RContext, typename Attribute>
+ bool parse_sequence(
+ Parser const& parser , Iterator& first, Iterator const& last
+ , Context const& context, RContext& rcontext, Attribute& attr
+ , traits::plain_attribute)
+ {
+ typedef typename Parser::left_type Left;
+ typedef typename Parser::right_type Right;
+ typedef typename traits::attribute_of<Left, Context>::type l_attr_type;
+ typedef typename traits::attribute_of<Right, Context>::type r_attr_type;
+ typedef traits::make_attribute<l_attr_type, Attribute> l_make_attribute;
+ typedef traits::make_attribute<r_attr_type, Attribute> r_make_attribute;
+
+ typename l_make_attribute::type l_attr = l_make_attribute::call(attr);
+ typename r_make_attribute::type r_attr = r_make_attribute::call(attr);
+
+ Iterator save = first;
+ if (parser.left.parse(first, last, context, rcontext, l_attr)
+ && parser.right.parse(first, last, context, rcontext, r_attr))
+ return true;
+ first = save;
+ return false;
+ }
+
+ template <typename Left, typename Right, typename Iterator
+ , typename Context, typename RContext, typename Attribute>
+ bool parse_sequence(
+ Left const& left, Right const& right
+ , Iterator& first, Iterator const& last
+ , Context const& context, RContext& rcontext, Attribute& attr
+ , traits::container_attribute);
+
+ template <typename Parser, typename Iterator, typename Context
+ , typename RContext, typename Attribute>
+ bool parse_sequence(
+ Parser const& parser , Iterator& first, Iterator const& last
+ , Context const& context, RContext& rcontext, Attribute& attr
+ , traits::container_attribute)
+ {
+ Iterator save = first;
+ if (parse_into_container(parser.left, first, last, context, rcontext, attr)
+ && parse_into_container(parser.right, first, last, context, rcontext, attr))
+ return true;
+ first = save;
+ return false;
+ }
+
+ template <typename Parser, typename Iterator, typename Context
+ , typename RContext, typename Attribute>
+ bool parse_sequence_assoc(
+ Parser const& parser , Iterator& first, Iterator const& last
+ , Context const& context, RContext& rcontext, Attribute& attr, mpl::false_ /*should_split*/)
+ {
+ return parse_into_container(parser, first, last, context, rcontext, attr);
+ }
+
+ template <typename Parser, typename Iterator, typename Context
+ , typename RContext, typename Attribute>
+ bool parse_sequence_assoc(
+ Parser const& parser , Iterator& first, Iterator const& last
+ , Context const& context, RContext& rcontext, Attribute& attr, mpl::true_ /*should_split*/)
+ {
+ Iterator save = first;
+ if (parser.left.parse( first, last, context, rcontext, attr)
+ && parser.right.parse(first, last, context, rcontext, attr))
+ return true;
+ first = save;
+ return false;
+ }
+
+ template <typename Parser, typename Iterator, typename Context
+ , typename RContext, typename Attribute>
+ bool parse_sequence(
+ Parser const& parser, Iterator& first, Iterator const& last
+ , Context const& context, RContext& rcontext, Attribute& attr
+ , traits::associative_attribute)
+ {
+ // we can come here in 2 cases:
+ // - when sequence is key >> value and therefore must
+ // be parsed with tuple synthesized attribute and then
+ // that tuple is used to save into associative attribute provided here.
+ // Example: key >> value;
+ //
+ // - when either this->left or this->right provides full key-value
+ // pair (like in case 1) and another one provides nothing.
+ // Example: eps >> rule<class x; fusion::map<...> >
+ //
+ // first case must be parsed as whole, and second one should
+ // be parsed separately for left and right.
+
+ typedef typename traits::attribute_of<
+ decltype(parser.left), Context>::type l_attr_type;
+ typedef typename traits::attribute_of<
+ decltype(parser.right), Context>::type r_attr_type;
+
+ typedef typename
+ mpl::or_<
+ is_same<l_attr_type, unused_type>
+ , is_same<r_attr_type, unused_type> >
+ should_split;
+
+ return parse_sequence_assoc(parser, first, last, context, rcontext, attr
+ , should_split());
+ }
+
+ template <typename Left, typename Right, typename Context, typename RContext>
+ struct parse_into_container_impl<sequence<Left, Right>, Context, RContext>
+ {
+ typedef sequence<Left, Right> parser_type;
+
+ template <typename Iterator, typename Attribute>
+ static bool call(
+ parser_type const& parser
+ , Iterator& first, Iterator const& last
+ , Context const& context, RContext& rcontext, Attribute& attr, mpl::false_)
+ {
+ // inform user what went wrong if we jumped here in attempt to
+ // parse incompatible sequence into fusion::map
+ static_assert(!is_same< typename traits::attribute_category<Attribute>::type,
+ traits::associative_attribute>::value,
+ "To parse directly into fusion::map sequence must produce tuple attribute "
+ "where type of first element is existing key in fusion::map and second element "
+ "is value to be stored under that key");
+
+ Attribute attr_;
+ if (!parse_sequence(parser
+ , first, last, context, rcontext, attr_, traits::container_attribute()))
+ {
+ return false;
+ }
+ traits::append(attr, traits::begin(attr_), traits::end(attr_));
+ return true;
+ }
+
+ template <typename Iterator, typename Attribute>
+ static bool call(
+ parser_type const& parser
+ , Iterator& first, Iterator const& last
+ , Context const& context, RContext& rcontext, Attribute& attr, mpl::true_)
+ {
+ return parse_into_container_base_impl<parser_type>::call(
+ parser, first, last, context, rcontext, attr);
+ }
+
+ template <typename Iterator, typename Attribute>
+ static bool call(
+ parser_type const& parser
+ , Iterator& first, Iterator const& last
+ , Context const& context, RContext& rcontext, Attribute& attr)
+ {
+ typedef typename
+ traits::attribute_of<parser_type, Context>::type
+ attribute_type;
+
+ typedef typename
+ traits::container_value<Attribute>::type
+ value_type;
+
+ return call(parser, first, last, context, rcontext, attr
+ , typename traits::is_substitute<attribute_type, value_type>::type());
+ }
+ };
+
+}}}}
+
+#endif
diff --git a/boost/spirit/home/x3/operator/difference.hpp b/boost/spirit/home/x3/operator/difference.hpp
new file mode 100644
index 0000000000..13a9274de0
--- /dev/null
+++ b/boost/spirit/home/x3/operator/difference.hpp
@@ -0,0 +1,75 @@
+/*=============================================================================
+ Copyright (c) 2001-2014 Joel de Guzman
+
+ Distributed under the Boost Software License, Version 1.0. (See accompanying
+ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+=============================================================================*/
+#if !defined(SPIRIT_DIFFERENCE_FEBRUARY_11_2007_1250PM)
+#define SPIRIT_DIFFERENCE_FEBRUARY_11_2007_1250PM
+
+#if defined(_MSC_VER)
+#pragma once
+#endif
+
+#include <boost/spirit/home/x3/support/traits/attribute_of.hpp>
+#include <boost/spirit/home/x3/support/traits/has_attribute.hpp>
+#include <boost/spirit/home/x3/core/parser.hpp>
+
+namespace boost { namespace spirit { namespace x3
+{
+ template <typename Left, typename Right>
+ struct difference : binary_parser<Left, Right, difference<Left, Right>>
+ {
+ typedef binary_parser<Left, Right, difference<Left, Right>> base_type;
+ static bool const handles_container = Left::handles_container;
+
+ difference(Left const& left, Right const& right)
+ : base_type(left, right) {}
+
+ template <typename Iterator, typename Context
+ , typename RContext, typename Attribute>
+ bool parse(Iterator& first, Iterator const& last
+ , Context const& context, RContext& rcontext, Attribute& attr) const
+ {
+ // Try Right first
+ Iterator start = first;
+ if (this->right.parse(first, last, context, rcontext, unused))
+ {
+ // Right succeeds, we fail.
+ first = start;
+ return false;
+ }
+ // Right fails, now try Left
+ return this->left.parse(first, last, context, rcontext, attr);
+ }
+
+ template <typename Left_, typename Right_>
+ difference<Left_, Right_>
+ make(Left_ const& left, Right_ const& right) const
+ {
+ return difference<Left_, Right_>(left, right);
+ }
+ };
+
+ template <typename Left, typename Right>
+ inline difference<
+ typename extension::as_parser<Left>::value_type
+ , typename extension::as_parser<Right>::value_type>
+ operator-(Left const& left, Right const& right)
+ {
+ return {as_parser(left), as_parser(right)};
+ }
+}}}
+
+namespace boost { namespace spirit { namespace x3 { namespace traits
+{
+ template <typename Left, typename Right, typename Context>
+ struct attribute_of<x3::difference<Left, Right>, Context>
+ : attribute_of<Left, Context> {};
+
+ template <typename Left, typename Right, typename Context>
+ struct has_attribute<x3::difference<Left, Right>, Context>
+ : has_attribute<Left, Context> {};
+}}}}
+
+#endif
diff --git a/boost/spirit/home/x3/operator/kleene.hpp b/boost/spirit/home/x3/operator/kleene.hpp
new file mode 100644
index 0000000000..7e02bf4a02
--- /dev/null
+++ b/boost/spirit/home/x3/operator/kleene.hpp
@@ -0,0 +1,59 @@
+/*=============================================================================
+ Copyright (c) 2001-2014 Joel de Guzman
+ Copyright (c) 2001-2011 Hartmut Kaiser
+
+ Distributed under the Boost Software License, Version 1.0. (See accompanying
+ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+=============================================================================*/
+#if !defined(SPIRIT_KLEENE_JANUARY_07_2007_0818AM)
+#define SPIRIT_KLEENE_JANUARY_07_2007_0818AM
+
+#if defined(_MSC_VER)
+#pragma once
+#endif
+
+#include <boost/spirit/home/x3/core/parser.hpp>
+#include <boost/spirit/home/x3/support/traits/container_traits.hpp>
+#include <boost/spirit/home/x3/support/traits/attribute_of.hpp>
+#include <boost/spirit/home/x3/core/detail/parse_into_container.hpp>
+
+namespace boost { namespace spirit { namespace x3
+{
+ template <typename Subject>
+ struct kleene : unary_parser<Subject, kleene<Subject>>
+ {
+ typedef unary_parser<Subject, kleene<Subject>> base_type;
+ static bool const handles_container = true;
+
+ kleene(Subject const& subject)
+ : base_type(subject) {}
+
+ template <typename Iterator, typename Context
+ , typename RContext, typename Attribute>
+ bool parse(Iterator& first, Iterator const& last
+ , Context const& context, RContext& rcontext, Attribute& attr) const
+ {
+ while (detail::parse_into_container(
+ this->subject, first, last, context, rcontext, attr))
+ ;
+ return true;
+ }
+ };
+
+ template <typename Subject>
+ inline kleene<typename extension::as_parser<Subject>::value_type>
+ operator*(Subject const& subject)
+ {
+ return {as_parser(subject)};
+ }
+}}}
+
+namespace boost { namespace spirit { namespace x3 { namespace traits
+{
+ template <typename Subject, typename Context>
+ struct attribute_of<x3::kleene<Subject>, Context>
+ : build_container<
+ typename attribute_of<Subject, Context>::type> {};
+}}}}
+
+#endif
diff --git a/boost/spirit/home/x3/operator/list.hpp b/boost/spirit/home/x3/operator/list.hpp
new file mode 100644
index 0000000000..a463a7f9e0
--- /dev/null
+++ b/boost/spirit/home/x3/operator/list.hpp
@@ -0,0 +1,73 @@
+/*=============================================================================
+ Copyright (c) 2001-2014 Joel de Guzman
+ Copyright (c) 2001-2011 Hartmut Kaiser
+
+ Distributed under the Boost Software License, Version 1.0. (See accompanying
+ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+=============================================================================*/
+#if !defined(SPIRIT_LIST_MARCH_24_2007_1031AM)
+#define SPIRIT_LIST_MARCH_24_2007_1031AM
+
+#if defined(_MSC_VER)
+#pragma once
+#endif
+
+#include <boost/spirit/home/x3/core/parser.hpp>
+#include <boost/spirit/home/x3/support/traits/container_traits.hpp>
+#include <boost/spirit/home/x3/support/traits/attribute_of.hpp>
+#include <boost/spirit/home/x3/core/detail/parse_into_container.hpp>
+
+namespace boost { namespace spirit { namespace x3
+{
+ template <typename Left, typename Right>
+ struct list : binary_parser<Left, Right, list<Left, Right>>
+ {
+ typedef binary_parser<Left, Right, list<Left, Right>> base_type;
+ static bool const handles_container = true;
+ static bool const has_attribute = true;
+
+ list(Left const& left, Right const& right)
+ : base_type(left, right) {}
+
+ template <typename Iterator, typename Context
+ , typename RContext, typename Attribute>
+ bool parse(Iterator& first, Iterator const& last
+ , Context const& context, RContext& rcontext, Attribute& attr) const
+ {
+ // in order to succeed we need to match at least one element
+ if (!detail::parse_into_container(
+ this->left, first, last, context, rcontext, attr))
+ return false;
+
+ Iterator save = first;
+ while (this->right.parse(first, last, context, rcontext, unused)
+ && detail::parse_into_container(
+ this->left, first, last, context, rcontext, attr))
+ {
+ save = first;
+ }
+
+ first = save;
+ return true;
+ }
+ };
+
+ template <typename Left, typename Right>
+ inline list<
+ typename extension::as_parser<Left>::value_type
+ , typename extension::as_parser<Right>::value_type>
+ operator%(Left const& left, Right const& right)
+ {
+ return {as_parser(left), as_parser(right)};
+ }
+}}}
+
+namespace boost { namespace spirit { namespace x3 { namespace traits
+{
+ template <typename Left, typename Right, typename Context>
+ struct attribute_of<x3::list<Left, Right>, Context>
+ : traits::build_container<
+ typename attribute_of<Left, Context>::type> {};
+}}}}
+
+#endif
diff --git a/boost/spirit/home/x3/operator/not_predicate.hpp b/boost/spirit/home/x3/operator/not_predicate.hpp
new file mode 100644
index 0000000000..38b24bd2e2
--- /dev/null
+++ b/boost/spirit/home/x3/operator/not_predicate.hpp
@@ -0,0 +1,47 @@
+/*=============================================================================
+ Copyright (c) 2001-2014 Joel de Guzman
+
+ Distributed under the Boost Software License, Version 1.0. (See accompanying
+ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+=============================================================================*/
+#if !defined(SPIRIT_NOT_PREDICATE_MARCH_23_2007_0618PM)
+#define SPIRIT_NOT_PREDICATE_MARCH_23_2007_0618PM
+
+#if defined(_MSC_VER)
+#pragma once
+#endif
+
+#include <boost/spirit/home/x3/core/parser.hpp>
+
+namespace boost { namespace spirit { namespace x3
+{
+ template <typename Subject>
+ struct not_predicate : unary_parser<Subject, not_predicate<Subject>>
+ {
+ typedef unary_parser<Subject, not_predicate<Subject>> base_type;
+
+ typedef unused_type attribute_type;
+ static bool const has_attribute = false;
+
+ not_predicate(Subject const& subject)
+ : base_type(subject) {}
+
+ template <typename Iterator, typename Context
+ , typename RContext, typename Attribute>
+ bool parse(Iterator& first, Iterator const& last
+ , Context const& context, RContext& rcontext, Attribute& /*attr*/) const
+ {
+ Iterator i = first;
+ return !this->subject.parse(i, last, context, rcontext, unused);
+ }
+ };
+
+ template <typename Subject>
+ inline not_predicate<typename extension::as_parser<Subject>::value_type>
+ operator!(Subject const& subject)
+ {
+ return {as_parser(subject)};
+ }
+}}}
+
+#endif
diff --git a/boost/spirit/home/x3/operator/optional.hpp b/boost/spirit/home/x3/operator/optional.hpp
new file mode 100644
index 0000000000..16432f89d1
--- /dev/null
+++ b/boost/spirit/home/x3/operator/optional.hpp
@@ -0,0 +1,86 @@
+/*=============================================================================
+ Copyright (c) 2001-2014 Joel de Guzman
+ Copyright (c) 2001-2011 Hartmut Kaiser
+
+ Distributed under the Boost Software License, Version 1.0. (See accompanying
+ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+=============================================================================*/
+#if !defined(SPIRIT_OPTIONAL_MARCH_23_2007_1117PM)
+#define SPIRIT_OPTIONAL_MARCH_23_2007_1117PM
+
+#if defined(_MSC_VER)
+#pragma once
+#endif
+
+#include <boost/spirit/home/x3/core/proxy.hpp>
+#include <boost/spirit/home/x3/core/detail/parse_into_container.hpp>
+#include <boost/spirit/home/x3/support/traits/attribute_of.hpp>
+#include <boost/spirit/home/x3/support/traits/move_to.hpp>
+#include <boost/spirit/home/x3/support/traits/optional_traits.hpp>
+#include <boost/spirit/home/x3/support/traits/attribute_category.hpp>
+
+namespace boost { namespace spirit { namespace x3
+{
+ template <typename Subject>
+ struct optional : proxy<Subject, optional<Subject>>
+ {
+ typedef proxy<Subject, optional<Subject>> base_type;
+ static bool const handles_container = true;
+
+ optional(Subject const& subject)
+ : base_type(subject) {}
+
+ using base_type::parse_subject;
+
+ // Attribute is a container
+ template <typename Iterator, typename Context
+ , typename RContext, typename Attribute>
+ bool parse_subject(Iterator& first, Iterator const& last
+ , Context const& context, RContext& rcontext, Attribute& attr
+ , traits::container_attribute) const
+ {
+ detail::parse_into_container(
+ this->subject, first, last, context, rcontext, attr);
+ return true;
+ }
+
+ // Attribute is an optional
+ template <typename Iterator, typename Context
+ , typename RContext, typename Attribute>
+ bool parse_subject(Iterator& first, Iterator const& last
+ , Context const& context, RContext& rcontext, Attribute& attr
+ , traits::optional_attribute) const
+ {
+ typedef typename
+ x3::traits::optional_value<Attribute>::type
+ value_type;
+
+ // create a local value
+ value_type val = value_type();
+
+ if (this->subject.parse(first, last, context, rcontext, val))
+ {
+ // assign the parsed value into our attribute
+ x3::traits::move_to(val, attr);
+ }
+ return true;
+ }
+ };
+
+ template <typename Subject>
+ inline optional<typename extension::as_parser<Subject>::value_type>
+ operator-(Subject const& subject)
+ {
+ return {as_parser(subject)};
+ }
+}}}
+
+namespace boost { namespace spirit { namespace x3 { namespace traits
+{
+ template <typename Subject, typename Context>
+ struct attribute_of<x3::optional<Subject>, Context>
+ : build_optional<
+ typename attribute_of<Subject, Context>::type> {};
+}}}}
+
+#endif
diff --git a/boost/spirit/home/x3/operator/plus.hpp b/boost/spirit/home/x3/operator/plus.hpp
new file mode 100644
index 0000000000..32c7dbfffb
--- /dev/null
+++ b/boost/spirit/home/x3/operator/plus.hpp
@@ -0,0 +1,63 @@
+/*=============================================================================
+ Copyright (c) 2001-2014 Joel de Guzman
+ Copyright (c) 2001-2011 Hartmut Kaiser
+
+ Distributed under the Boost Software License, Version 1.0. (See accompanying
+ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+=============================================================================*/
+#if !defined(SPIRIT_PLUS_MARCH_13_2007_0127PM)
+#define SPIRIT_PLUS_MARCH_13_2007_0127PM
+
+#if defined(_MSC_VER)
+#pragma once
+#endif
+
+#include <boost/spirit/home/x3/core/parser.hpp>
+#include <boost/spirit/home/x3/support/traits/container_traits.hpp>
+#include <boost/spirit/home/x3/support/traits/attribute_of.hpp>
+#include <boost/spirit/home/x3/core/detail/parse_into_container.hpp>
+
+namespace boost { namespace spirit { namespace x3
+{
+ template <typename Subject>
+ struct plus : unary_parser<Subject, plus<Subject>>
+ {
+ typedef unary_parser<Subject, plus<Subject>> base_type;
+ static bool const handles_container = true;
+
+ plus(Subject const& subject)
+ : base_type(subject) {}
+
+ template <typename Iterator, typename Context
+ , typename RContext, typename Attribute>
+ bool parse(Iterator& first, Iterator const& last
+ , Context const& context, RContext& rcontext, Attribute& attr) const
+ {
+ if (!detail::parse_into_container(
+ this->subject, first, last, context, rcontext, attr))
+ return false;
+
+ while (detail::parse_into_container(
+ this->subject, first, last, context, rcontext, attr))
+ ;
+ return true;
+ }
+ };
+
+ template <typename Subject>
+ inline plus<typename extension::as_parser<Subject>::value_type>
+ operator+(Subject const& subject)
+ {
+ return {as_parser(subject)};
+ }
+}}}
+
+namespace boost { namespace spirit { namespace x3 { namespace traits
+{
+ template <typename Subject, typename Context>
+ struct attribute_of<x3::plus<Subject>, Context>
+ : build_container<
+ typename attribute_of<Subject, Context>::type> {};
+}}}}
+
+#endif
diff --git a/boost/spirit/home/x3/operator/sequence.hpp b/boost/spirit/home/x3/operator/sequence.hpp
new file mode 100644
index 0000000000..23d5e3d8d9
--- /dev/null
+++ b/boost/spirit/home/x3/operator/sequence.hpp
@@ -0,0 +1,79 @@
+/*=============================================================================
+ Copyright (c) 2001-2014 Joel de Guzman
+
+ Distributed under the Boost Software License, Version 1.0. (See accompanying
+ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+=============================================================================*/
+#if !defined(SPIRIT_SEQUENCE_JAN_06_2013_1015AM)
+#define SPIRIT_SEQUENCE_JAN_06_2013_1015AM
+
+#if defined(_MSC_VER)
+#pragma once
+#endif
+
+#include <boost/spirit/home/x3/support/traits/attribute_of.hpp>
+#include <boost/spirit/home/x3/core/parser.hpp>
+#include <boost/spirit/home/x3/operator/detail/sequence.hpp>
+#include <boost/spirit/home/x3/directive/expect.hpp>
+
+namespace boost { namespace spirit { namespace x3
+{
+ template <typename Left, typename Right>
+ struct sequence : binary_parser<Left, Right, sequence<Left, Right>>
+ {
+ typedef binary_parser<Left, Right, sequence<Left, Right>> base_type;
+
+ sequence(Left left, Right right)
+ : base_type(left, right) {}
+
+ template <typename Iterator, typename Context, typename RContext>
+ bool parse(
+ Iterator& first, Iterator const& last
+ , Context const& context, RContext& rcontext, unused_type) const
+ {
+ Iterator save = first;
+ if (this->left.parse(first, last, context, rcontext, unused)
+ && this->right.parse(first, last, context, rcontext, unused))
+ return true;
+ first = save;
+ return false;
+ }
+
+ template <typename Iterator, typename Context
+ , typename RContext, typename Attribute>
+ bool parse(
+ Iterator& first, Iterator const& last
+ , Context const& context, RContext& rcontext, Attribute& attr) const
+ {
+ return detail::parse_sequence(*this, first, last, context, rcontext, attr
+ , typename traits::attribute_category<Attribute>::type());
+ }
+ };
+
+ template <typename Left, typename Right>
+ inline sequence<
+ typename extension::as_parser<Left>::value_type
+ , typename extension::as_parser<Right>::value_type>
+ operator>>(Left const& left, Right const& right)
+ {
+ return {as_parser(left), as_parser(right)};
+ }
+
+ template <typename Left, typename Right>
+ inline sequence<
+ typename extension::as_parser<Left>::value_type
+ , expect_directive<typename extension::as_parser<Right>::value_type>>
+ operator>(Left const& left, Right const& right)
+ {
+ return {as_parser(left), as_parser(right)};
+ }
+}}}
+
+namespace boost { namespace spirit { namespace x3 { namespace traits
+{
+ template <typename Left, typename Right, typename Context>
+ struct attribute_of<x3::sequence<Left, Right>, Context>
+ : x3::detail::attribute_of_sequence<Left, Right, Context> {};
+}}}}
+
+#endif