summaryrefslogtreecommitdiff
path: root/boost/spirit/home/x3
diff options
context:
space:
mode:
Diffstat (limited to 'boost/spirit/home/x3')
-rw-r--r--boost/spirit/home/x3/auxiliary.hpp24
-rw-r--r--boost/spirit/home/x3/auxiliary/any_parser.hpp155
-rw-r--r--boost/spirit/home/x3/auxiliary/attr.hpp135
-rw-r--r--boost/spirit/home/x3/auxiliary/eoi.hpp45
-rw-r--r--boost/spirit/home/x3/auxiliary/eol.hpp59
-rw-r--r--boost/spirit/home/x3/auxiliary/eps.hpp92
-rw-r--r--boost/spirit/home/x3/auxiliary/guard.hpp73
-rw-r--r--boost/spirit/home/x3/char.hpp23
-rw-r--r--boost/spirit/home/x3/char/any_char.hpp41
-rw-r--r--boost/spirit/home/x3/char/char.hpp88
-rw-r--r--boost/spirit/home/x3/char/char_class.hpp148
-rw-r--r--boost/spirit/home/x3/char/char_parser.hpp44
-rw-r--r--boost/spirit/home/x3/char/detail/cast_char.hpp58
-rw-r--r--boost/spirit/home/x3/char/literal_char.hpp54
-rw-r--r--boost/spirit/home/x3/char/negated_char_parser.hpp65
-rw-r--r--boost/spirit/home/x3/char/unicode.hpp617
-rw-r--r--boost/spirit/home/x3/core.hpp20
-rw-r--r--boost/spirit/home/x3/core/action.hpp120
-rw-r--r--boost/spirit/home/x3/core/call.hpp79
-rw-r--r--boost/spirit/home/x3/core/detail/parse_into_container.hpp248
-rw-r--r--boost/spirit/home/x3/core/parse.hpp190
-rw-r--r--boost/spirit/home/x3/core/parser.hpp239
-rw-r--r--boost/spirit/home/x3/core/proxy.hpp52
-rw-r--r--boost/spirit/home/x3/core/skip_over.hpp104
-rw-r--r--boost/spirit/home/x3/directive.hpp28
-rw-r--r--boost/spirit/home/x3/directive/expect.hpp80
-rw-r--r--boost/spirit/home/x3/directive/lexeme.hpp84
-rw-r--r--boost/spirit/home/x3/directive/no_skip.hpp82
-rw-r--r--boost/spirit/home/x3/directive/omit.hpp55
-rw-r--r--boost/spirit/home/x3/directive/raw.hpp70
-rw-r--r--boost/spirit/home/x3/directive/skip.hpp124
-rw-r--r--boost/spirit/home/x3/directive/with.hpp107
-rw-r--r--boost/spirit/home/x3/extensions.hpp18
-rw-r--r--boost/spirit/home/x3/extensions/seek.hpp70
-rw-r--r--boost/spirit/home/x3/nonterminal.hpp19
-rw-r--r--boost/spirit/home/x3/nonterminal/debug_handler_state.hpp24
-rw-r--r--boost/spirit/home/x3/nonterminal/detail/rule.hpp385
-rw-r--r--boost/spirit/home/x3/nonterminal/detail/transform_attribute.hpp108
-rw-r--r--boost/spirit/home/x3/nonterminal/rule.hpp186
-rw-r--r--boost/spirit/home/x3/nonterminal/simple_trace.hpp150
-rw-r--r--boost/spirit/home/x3/numeric.hpp19
-rw-r--r--boost/spirit/home/x3/numeric/bool.hpp106
-rw-r--r--boost/spirit/home/x3/numeric/bool_policies.hpp52
-rw-r--r--boost/spirit/home/x3/numeric/int.hpp66
-rw-r--r--boost/spirit/home/x3/numeric/real.hpp62
-rw-r--r--boost/spirit/home/x3/numeric/real_policies.hpp186
-rw-r--r--boost/spirit/home/x3/numeric/uint.hpp79
-rw-r--r--boost/spirit/home/x3/operator.hpp26
-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
-rw-r--r--boost/spirit/home/x3/string.hpp17
-rw-r--r--boost/spirit/home/x3/string/detail/string_parse.hpp89
-rw-r--r--boost/spirit/home/x3/string/detail/tst.hpp213
-rw-r--r--boost/spirit/home/x3/string/literal_string.hpp124
-rw-r--r--boost/spirit/home/x3/string/symbols.hpp358
-rw-r--r--boost/spirit/home/x3/string/tst.hpp137
-rw-r--r--boost/spirit/home/x3/string/tst_map.hpp216
-rw-r--r--boost/spirit/home/x3/support/ast/position_tagged.hpp96
-rw-r--r--boost/spirit/home/x3/support/ast/variant.hpp249
-rw-r--r--boost/spirit/home/x3/support/context.hpp135
-rw-r--r--boost/spirit/home/x3/support/numeric_utils/detail/extract_int.hpp512
-rw-r--r--boost/spirit/home/x3/support/numeric_utils/extract_int.hpp147
-rw-r--r--boost/spirit/home/x3/support/numeric_utils/extract_real.hpp271
-rw-r--r--boost/spirit/home/x3/support/numeric_utils/pow10.hpp116
-rw-r--r--boost/spirit/home/x3/support/numeric_utils/sign.hpp48
-rw-r--r--boost/spirit/home/x3/support/subcontext.hpp89
-rw-r--r--boost/spirit/home/x3/support/traits/attribute_category.hpp82
-rw-r--r--boost/spirit/home/x3/support/traits/attribute_of.hpp59
-rw-r--r--boost/spirit/home/x3/support/traits/attribute_type.hpp30
-rw-r--r--boost/spirit/home/x3/support/traits/container_traits.hpp333
-rw-r--r--boost/spirit/home/x3/support/traits/handles_container.hpp31
-rw-r--r--boost/spirit/home/x3/support/traits/has_attribute.hpp63
-rw-r--r--boost/spirit/home/x3/support/traits/is_parser.hpp37
-rw-r--r--boost/spirit/home/x3/support/traits/is_substitute.hpp164
-rw-r--r--boost/spirit/home/x3/support/traits/is_variant.hpp45
-rw-r--r--boost/spirit/home/x3/support/traits/make_attribute.hpp86
-rw-r--r--boost/spirit/home/x3/support/traits/move_to.hpp211
-rw-r--r--boost/spirit/home/x3/support/traits/numeric_traits.hpp128
-rw-r--r--boost/spirit/home/x3/support/traits/optional_traits.hpp78
-rw-r--r--boost/spirit/home/x3/support/traits/print_attribute.hpp150
-rw-r--r--boost/spirit/home/x3/support/traits/print_token.hpp79
-rw-r--r--boost/spirit/home/x3/support/traits/string_traits.hpp291
-rw-r--r--boost/spirit/home/x3/support/traits/transform_attribute.hpp48
-rw-r--r--boost/spirit/home/x3/support/traits/tuple_traits.hpp52
-rw-r--r--boost/spirit/home/x3/support/traits/value_traits.hpp30
-rw-r--r--boost/spirit/home/x3/support/traits/variant_find_substitute.hpp56
-rw-r--r--boost/spirit/home/x3/support/traits/variant_has_substitute.hpp56
-rw-r--r--boost/spirit/home/x3/support/unused.hpp93
-rw-r--r--boost/spirit/home/x3/support/utility/detail/testing.hpp16
-rw-r--r--boost/spirit/home/x3/support/utility/error_reporting.hpp241
-rw-r--r--boost/spirit/home/x3/support/utility/integer_sequence.hpp94
-rw-r--r--boost/spirit/home/x3/support/utility/is_callable.hpp45
-rw-r--r--boost/spirit/home/x3/support/utility/lambda_visitor.hpp49
-rw-r--r--boost/spirit/home/x3/support/utility/sfinae.hpp29
-rw-r--r--boost/spirit/home/x3/support/utility/testing.hpp69
-rw-r--r--boost/spirit/home/x3/support/utility/unrefcv.hpp29
-rw-r--r--boost/spirit/home/x3/support/utility/utf8.hpp72
106 files changed, 12037 insertions, 0 deletions
diff --git a/boost/spirit/home/x3/auxiliary.hpp b/boost/spirit/home/x3/auxiliary.hpp
new file mode 100644
index 0000000000..afa89b2883
--- /dev/null
+++ b/boost/spirit/home/x3/auxiliary.hpp
@@ -0,0 +1,24 @@
+/*=============================================================================
+ 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(BOOST_SPIRIT_X3_AUXILIARY_FEBRUARY_03_2007_0355PM)
+#define BOOST_SPIRIT_X3_AUXILIARY_FEBRUARY_03_2007_0355PM
+
+#if defined(_MSC_VER)
+#pragma once
+#endif
+
+#include <boost/spirit/home/x3/auxiliary/any_parser.hpp>
+#include <boost/spirit/home/x3/auxiliary/eps.hpp>
+#include <boost/spirit/home/x3/auxiliary/guard.hpp>
+//~ #include <boost/spirit/home/x3/auxiliary/lazy.hpp>
+#include <boost/spirit/home/x3/auxiliary/eol.hpp>
+#include <boost/spirit/home/x3/auxiliary/eoi.hpp>
+#include <boost/spirit/home/x3/auxiliary/attr.hpp>
+//~ #include <boost/spirit/home/x3/auxiliary/attr_cast.hpp>
+
+#endif
diff --git a/boost/spirit/home/x3/auxiliary/any_parser.hpp b/boost/spirit/home/x3/auxiliary/any_parser.hpp
new file mode 100644
index 0000000000..0e257c04b1
--- /dev/null
+++ b/boost/spirit/home/x3/auxiliary/any_parser.hpp
@@ -0,0 +1,155 @@
+/*=============================================================================
+ Copyright (c) 2001-2014 Joel de Guzman
+ Copyright (c) 2013-2014 Agustin Berge
+
+ 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(BOOST_SPIRIT_X3_AUXILIARY_ANY_PARSER_APR_09_2014_1145PM)
+#define BOOST_SPIRIT_X3_AUXILIARY_ANY_PARSER_APR_09_2014_1145PM
+
+#if defined(_MSC_VER)
+#pragma once
+#endif
+
+#include <boost/spirit/home/x3/core/parser.hpp>
+#include <boost/spirit/home/x3/support/context.hpp>
+#include <boost/spirit/home/x3/support/subcontext.hpp>
+#include <boost/spirit/home/x3/support/unused.hpp>
+#include <boost/spirit/home/x3/support/traits/container_traits.hpp>
+#include <boost/spirit/home/x3/support/traits/has_attribute.hpp>
+#include <boost/spirit/home/x3/support/traits/move_to.hpp>
+#include <boost/spirit/home/x3/support/traits/is_parser.hpp>
+#include <memory>
+#include <string>
+
+namespace boost { namespace spirit { namespace x3
+{
+ template <
+ typename Iterator
+ , typename Attribute = unused_type
+ , typename Context = subcontext<>>
+ struct any_parser : parser<any_parser<Iterator, Attribute, Context>>
+ {
+ typedef Attribute attribute_type;
+
+ static bool const has_attribute =
+ !is_same<unused_type, attribute_type>::value;
+ static bool const handles_container =
+ traits::is_container<Attribute>::value;
+
+ public:
+ any_parser()
+ : _content(nullptr) {}
+
+ template <typename Expr,
+ typename Enable = typename enable_if<traits::is_parser<Expr>>::type>
+ any_parser(Expr const& expr)
+ : _content(new holder<Expr>(expr)) {}
+
+ any_parser(any_parser const& other)
+ : _content(other._content ? other._content->clone() : nullptr) {}
+
+ any_parser(any_parser&& other) = default;
+
+ any_parser& operator=(any_parser const& other)
+ {
+ _content.reset(other._content ? other._content->clone() : nullptr);
+ return *this;
+ }
+
+ any_parser& operator=(any_parser&& other) = default;
+
+ template <typename Iterator_, typename Context_>
+ bool parse(Iterator_& first, Iterator_ const& last
+ , Context_ const& context, unused_type, Attribute& attr) const
+ {
+ BOOST_STATIC_ASSERT_MSG(
+ (is_same<Iterator, Iterator_>::value)
+ , "Incompatible iterator used"
+ );
+
+ BOOST_ASSERT_MSG(
+ (_content != nullptr)
+ , "Invalid use of uninitialized any_parser"
+ );
+
+ return _content->parse(first, last, context, attr);
+ }
+
+ template <typename Iterator_, typename Context_, typename Attribute_>
+ bool parse(Iterator_& first, Iterator_ const& last
+ , Context_ const& context, unused_type, Attribute_& attr_) const
+ {
+ Attribute attr;
+ if (parse(first, last, context, unused, attr))
+ {
+ traits::move_to(attr, attr_);
+ return true;
+ }
+ return false;
+ }
+
+ std::string get_info() const
+ {
+ return _content ? _content->get_info() : "";
+ }
+
+ private:
+
+ struct placeholder
+ {
+ virtual placeholder* clone() const = 0;
+
+ virtual bool parse(Iterator& first, Iterator const& last
+ , Context const& context, Attribute& attr) const = 0;
+
+ virtual std::string get_info() const = 0;
+
+ virtual ~placeholder() {}
+ };
+
+ template <typename Expr>
+ struct holder : placeholder
+ {
+ typedef typename extension::as_parser<Expr>::value_type parser_type;
+
+ explicit holder(Expr const& p)
+ : _parser(as_parser(p)) {}
+
+ holder* clone() const override
+ {
+ return new holder(*this);
+ }
+
+ bool parse(Iterator& first, Iterator const& last
+ , Context const& context, Attribute& attr) const override
+ {
+ return _parser.parse(first, last, context, unused, attr);
+ }
+
+ std::string get_info() const override
+ {
+ return x3::what(_parser);
+ }
+
+ parser_type _parser;
+ };
+
+ private:
+ std::unique_ptr<placeholder> _content;
+ };
+
+ template <typename Iterator, typename Attribute, typename Context>
+ struct get_info<any_parser<Iterator, Attribute, Context>>
+ {
+ typedef std::string result_type;
+ std::string operator()(
+ any_parser<Iterator, Attribute, Context> const& p) const
+ {
+ return p.get_info();
+ }
+ };
+}}}
+
+#endif
diff --git a/boost/spirit/home/x3/auxiliary/attr.hpp b/boost/spirit/home/x3/auxiliary/attr.hpp
new file mode 100644
index 0000000000..364cca0bee
--- /dev/null
+++ b/boost/spirit/home/x3/auxiliary/attr.hpp
@@ -0,0 +1,135 @@
+/*=============================================================================
+ Copyright (c) 2001-2011 Hartmut Kaiser
+ Copyright (c) 2001-2014 Joel de Guzman
+ Copyright (c) 2013 Agustin Berge
+
+ 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)
+==============================================================================*/
+#ifndef BOOST_SPIRIT_X3_ATTR_JUL_23_2008_0956AM
+#define BOOST_SPIRIT_X3_ATTR_JUL_23_2008_0956AM
+
+#if defined(_MSC_VER)
+#pragma once
+#endif
+
+#include <boost/spirit/home/x3/core/parser.hpp>
+#include <boost/spirit/home/x3/support/unused.hpp>
+#include <boost/spirit/home/x3/support/traits/container_traits.hpp>
+#include <boost/spirit/home/x3/support/traits/move_to.hpp>
+#include <boost/type_traits/is_same.hpp>
+#include <boost/type_traits/remove_cv.hpp>
+#include <boost/type_traits/remove_reference.hpp>
+#include <algorithm>
+#include <cstddef>
+#include <string>
+#include <utility>
+
+namespace boost { namespace spirit { namespace x3
+{
+ template <typename Value>
+ struct attr_parser : parser<attr_parser<Value>>
+ {
+ typedef Value attribute_type;
+
+ static bool const has_attribute =
+ !is_same<unused_type, attribute_type>::value;
+ static bool const handles_container =
+ traits::is_container<attribute_type>::value;
+
+ attr_parser(Value const& value)
+ : value_(value) {}
+ attr_parser(Value&& value)
+ : value_(std::move(value)) {}
+
+ template <typename Iterator, typename Context
+ , typename RuleContext, typename Attribute>
+ bool parse(Iterator& first, Iterator const& last
+ , Context const& context, RuleContext&, Attribute& attr_) const
+ {
+ // $$$ Change to copy_to once we have it $$$
+ traits::move_to(value_, attr_);
+ return true;
+ }
+
+ Value value_;
+
+ private:
+ // silence MSVC warning C4512: assignment operator could not be generated
+ attr_parser& operator= (attr_parser const&);
+ };
+
+ template <typename Value, std::size_t N>
+ struct attr_parser<Value[N]> : parser<attr_parser<Value[N]>>
+ {
+ typedef Value attribute_type[N];
+
+ static bool const has_attribute =
+ !is_same<unused_type, attribute_type>::value;
+ static bool const handles_container = true;
+
+ attr_parser(Value const (&value)[N])
+ {
+ std::copy(value + 0, value + N, value_ + 0);
+ }
+
+ attr_parser(Value (&&value)[N])
+ {
+ std::move(value + 0, value + N, value_ + 0);
+ }
+
+ template <typename Iterator, typename Context
+ , typename RuleContext, typename Attribute>
+ bool parse(Iterator& first, Iterator const& last
+ , Context const& context, RuleContext&, Attribute& attr_) const
+ {
+ // $$$ Change to copy_to once we have it $$$
+ traits::move_to(value_ + 0, value_ + N, attr_);
+ return true;
+ }
+
+ Value value_[N];
+
+ private:
+ // silence MSVC warning C4512: assignment operator could not be generated
+ attr_parser& operator= (attr_parser const&);
+ };
+
+ template <typename Value>
+ struct get_info<attr_parser<Value>>
+ {
+ typedef std::string result_type;
+ std::string operator()(attr_parser<Value> const& /*p*/) const
+ {
+ return "attr";
+ }
+ };
+
+ struct attr_gen
+ {
+ template <typename Value>
+ attr_parser<typename remove_cv<
+ typename remove_reference<Value>::type>::type>
+ operator()(Value&& value) const
+ {
+ return {std::forward<Value>(value)};
+ }
+
+ template <typename Value, std::size_t N>
+ attr_parser<typename remove_cv<Value>::type[N]>
+ operator()(Value (&value)[N]) const
+ {
+ return {value};
+ }
+ template <typename Value, std::size_t N>
+ attr_parser<typename remove_cv<Value>::type[N]>
+ operator()(Value (&&value)[N]) const
+ {
+ return {value};
+ }
+ };
+
+ attr_gen const attr = attr_gen();
+}}}
+
+#endif
diff --git a/boost/spirit/home/x3/auxiliary/eoi.hpp b/boost/spirit/home/x3/auxiliary/eoi.hpp
new file mode 100644
index 0000000000..55bd51cfc4
--- /dev/null
+++ b/boost/spirit/home/x3/auxiliary/eoi.hpp
@@ -0,0 +1,45 @@
+/*=============================================================================
+ 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(BOOST_SPIRIT_X3_EOI_MARCH_23_2007_0454PM)
+#define BOOST_SPIRIT_X3_EOI_MARCH_23_2007_0454PM
+
+#if defined(_MSC_VER)
+#pragma once
+#endif
+
+#include <boost/spirit/home/x3/core/skip_over.hpp>
+#include <boost/spirit/home/x3/core/parser.hpp>
+#include <boost/spirit/home/x3/support/unused.hpp>
+
+namespace boost { namespace spirit { namespace x3
+{
+ struct eoi_parser : parser<eoi_parser>
+ {
+ typedef unused_type attribute_type;
+ static bool const has_attribute = false;
+
+ template <typename Iterator, typename Context, typename Attribute>
+ bool parse(Iterator& first, Iterator const& last
+ , Context const& context, unused_type, Attribute&) const
+ {
+ x3::skip_over(first, last, context);
+ return first == last;
+ }
+ };
+
+ template<>
+ struct get_info<eoi_parser>
+ {
+ typedef std::string result_type;
+ result_type operator()(eoi_parser const &) const { return "eoi"; }
+ };
+
+ eoi_parser const eoi = eoi_parser();
+}}}
+
+#endif
diff --git a/boost/spirit/home/x3/auxiliary/eol.hpp b/boost/spirit/home/x3/auxiliary/eol.hpp
new file mode 100644
index 0000000000..3d191b4269
--- /dev/null
+++ b/boost/spirit/home/x3/auxiliary/eol.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(BOOST_SPIRIT_X3_EOL_MARCH_23_2007_0454PM)
+#define BOOST_SPIRIT_X3_EOL_MARCH_23_2007_0454PM
+
+#if defined(_MSC_VER)
+#pragma once
+#endif
+
+#include <boost/spirit/home/x3/core/skip_over.hpp>
+#include <boost/spirit/home/x3/core/parser.hpp>
+#include <boost/spirit/home/x3/support/unused.hpp>
+
+namespace boost { namespace spirit { namespace x3
+{
+ struct eol_parser : parser<eol_parser>
+ {
+ typedef unused_type attribute_type;
+ static bool const has_attribute = false;
+
+ template <typename Iterator, typename Context, typename Attribute>
+ bool parse(Iterator& first, Iterator const& last
+ , Context const& context, unused_type, Attribute& /*attr*/) const
+ {
+ x3::skip_over(first, last, context);
+ Iterator iter = first;
+ bool matched = false;
+ if (iter != last && *iter == '\r') // CR
+ {
+ matched = true;
+ ++iter;
+ }
+ if (iter != last && *iter == '\n') // LF
+ {
+ matched = true;
+ ++iter;
+ }
+
+ if (matched) first = iter;
+ return matched;
+ }
+ };
+
+ template<>
+ struct get_info<eol_parser>
+ {
+ typedef std::string result_type;
+ result_type operator()(eol_parser const &) const { return "eol"; }
+ };
+
+ eol_parser const eol = eol_parser();
+}}}
+
+#endif
diff --git a/boost/spirit/home/x3/auxiliary/eps.hpp b/boost/spirit/home/x3/auxiliary/eps.hpp
new file mode 100644
index 0000000000..ab4d307931
--- /dev/null
+++ b/boost/spirit/home/x3/auxiliary/eps.hpp
@@ -0,0 +1,92 @@
+/*=============================================================================
+ 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(BOOST_SPIRIT_X3_EPS_MARCH_23_2007_0454PM)
+#define BOOST_SPIRIT_X3_EPS_MARCH_23_2007_0454PM
+
+#if defined(_MSC_VER)
+#pragma once
+#endif
+
+#include <boost/spirit/home/x3/core/skip_over.hpp>
+#include <boost/spirit/home/x3/core/parser.hpp>
+#include <boost/spirit/home/x3/support/unused.hpp>
+
+namespace boost { namespace spirit { namespace x3
+{
+ struct rule_context_tag;
+
+ struct semantic_predicate : parser<semantic_predicate>
+ {
+ typedef unused_type attribute_type;
+ static bool const has_attribute = false;
+
+ semantic_predicate(bool predicate)
+ : predicate(predicate) {}
+
+ template <typename Iterator, typename Context, typename Attribute>
+ bool parse(Iterator& first, Iterator const& last
+ , Context const& context, unused_type, Attribute&) const
+ {
+ x3::skip_over(first, last, context);
+ return predicate;
+ }
+
+ bool predicate;
+ };
+
+ template <typename F>
+ struct lazy_semantic_predicate : parser<lazy_semantic_predicate<F>>
+ {
+ typedef unused_type attribute_type;
+ static bool const has_attribute = false;
+
+ lazy_semantic_predicate(F f)
+ : f(f) {}
+
+ template <typename Iterator, typename Context, typename Attribute>
+ bool parse(Iterator& first, Iterator const& last
+ , Context const& context, unused_type, Attribute& attr) const
+ {
+ x3::skip_over(first, last, context);
+ return f(x3::get<rule_context_tag>(context));
+ }
+
+ F f;
+ };
+
+ struct eps_parser : parser<eps_parser>
+ {
+ typedef unused_type attribute_type;
+ static bool const has_attribute = false;
+
+ template <typename Iterator, typename Context
+ , typename RuleContext, typename Attribute>
+ bool parse(Iterator& first, Iterator const& last
+ , Context const& context, RuleContext&, Attribute&) const
+ {
+ x3::skip_over(first, last, context);
+ return true;
+ }
+
+ semantic_predicate
+ operator()(bool predicate) const
+ {
+ return semantic_predicate(predicate);
+ }
+
+ template <typename F>
+ lazy_semantic_predicate<F>
+ operator()(F f) const
+ {
+ return lazy_semantic_predicate<F>(f);
+ }
+ };
+
+ eps_parser const eps = eps_parser();
+}}}
+
+#endif
diff --git a/boost/spirit/home/x3/auxiliary/guard.hpp b/boost/spirit/home/x3/auxiliary/guard.hpp
new file mode 100644
index 0000000000..6fd63c822c
--- /dev/null
+++ b/boost/spirit/home/x3/auxiliary/guard.hpp
@@ -0,0 +1,73 @@
+/*=============================================================================
+ 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(BOOST_SPIRIT_X3_GUARD_FERBRUARY_02_2013_0649PM)
+#define BOOST_SPIRIT_X3_GUARD_FERBRUARY_02_2013_0649PM
+
+#if defined(_MSC_VER)
+#pragma once
+#endif
+
+#include <boost/spirit/home/x3/support/context.hpp>
+#include <boost/spirit/home/x3/directive/expect.hpp>
+
+namespace boost { namespace spirit { namespace x3
+{
+ enum class error_handler_result
+ {
+ fail
+ , retry
+ , accept
+ , rethrow
+ };
+
+ template <typename Subject, typename Handler>
+ struct guard : unary_parser<Subject, guard<Subject, Handler>>
+ {
+ typedef unary_parser<Subject, guard<Subject, Handler>> base_type;
+ static bool const is_pass_through_unary = true;
+
+ guard(Subject const& subject, Handler handler)
+ : base_type(subject), handler(handler) {}
+
+ template <typename Iterator, typename Context
+ , typename RuleContext, typename Attribute>
+ bool parse(Iterator& first, Iterator const& last
+ , Context const& context, RuleContext& rcontext, Attribute& attr) const
+ {
+ for (;;)
+ {
+ try
+ {
+ Iterator i = first;
+ bool r = this->subject.parse(i, last, context, rcontext, attr);
+ if (r)
+ first = i;
+ return r;
+ }
+ catch (expectation_failure<Iterator> const& x)
+ {
+ switch (handler(first, last, x, context))
+ {
+ case error_handler_result::fail:
+ return false;
+ case error_handler_result::retry:
+ continue;
+ case error_handler_result::accept:
+ return true;
+ case error_handler_result::rethrow:
+ throw;
+ }
+ }
+ }
+ return false;
+ }
+
+ Handler handler;
+ };
+}}}
+
+#endif
diff --git a/boost/spirit/home/x3/char.hpp b/boost/spirit/home/x3/char.hpp
new file mode 100644
index 0000000000..19d26de3a2
--- /dev/null
+++ b/boost/spirit/home/x3/char.hpp
@@ -0,0 +1,23 @@
+/*=============================================================================
+ 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(BOOST_SPIRIT_X3_CHAR_FEBRUARY_02_2007_0921AM)
+#define BOOST_SPIRIT_X3_CHAR_FEBRUARY_02_2007_0921AM
+
+#if defined(_MSC_VER)
+#pragma once
+#endif
+
+#include <boost/spirit/home/x3/char/char_parser.hpp>
+#include <boost/spirit/home/x3/char/negated_char_parser.hpp>
+#include <boost/spirit/home/x3/char/char.hpp>
+#include <boost/spirit/home/x3/char/char_class.hpp>
+
+#if defined(BOOST_SPIRIT_X3_UNICODE)
+#include <boost/spirit/home/x3/char/unicode.hpp>
+#endif
+
+#endif
diff --git a/boost/spirit/home/x3/char/any_char.hpp b/boost/spirit/home/x3/char/any_char.hpp
new file mode 100644
index 0000000000..7ff769b8b2
--- /dev/null
+++ b/boost/spirit/home/x3/char/any_char.hpp
@@ -0,0 +1,41 @@
+/*=============================================================================
+ 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(BOOST_SPIRIT_X3_ANY_CHAR_APRIL_16_2006_1051AM)
+#define BOOST_SPIRIT_X3_ANY_CHAR_APRIL_16_2006_1051AM
+
+#if defined(_MSC_VER)
+#pragma once
+#endif
+
+#include <boost/spirit/home/x3/char/literal_char.hpp>
+
+namespace boost { namespace spirit { namespace x3
+{
+ template <typename Encoding>
+ struct any_char : char_parser<any_char<Encoding>>
+ {
+ typedef typename Encoding::char_type char_type;
+ typedef Encoding encoding;
+ typedef char_type attribute_type;
+ static bool const has_attribute = true;
+
+ template <typename Char, typename Context>
+ bool test(Char ch_, Context const&) const
+ {
+ return ((sizeof(Char) <= sizeof(char_type)) || encoding::ischar(ch_));
+ }
+
+ template <typename Char>
+ literal_char<Encoding>
+ operator()(Char ch) const
+ {
+ return literal_char<Encoding>(ch);
+ }
+ };
+}}}
+
+#endif
diff --git a/boost/spirit/home/x3/char/char.hpp b/boost/spirit/home/x3/char/char.hpp
new file mode 100644
index 0000000000..9452dcd86d
--- /dev/null
+++ b/boost/spirit/home/x3/char/char.hpp
@@ -0,0 +1,88 @@
+/*=============================================================================
+ 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(BOOST_SPIRIT_X3_CHAR_APRIL_16_2006_1051AM)
+#define BOOST_SPIRIT_X3_CHAR_APRIL_16_2006_1051AM
+
+#if defined(_MSC_VER)
+#pragma once
+#endif
+
+#include <boost/spirit/home/x3/char/any_char.hpp>
+#include <boost/spirit/home/support/char_encoding/ascii.hpp>
+#include <boost/spirit/home/support/char_encoding/standard.hpp>
+#include <boost/spirit/home/support/char_encoding/standard_wide.hpp>
+
+namespace boost { namespace spirit { namespace x3
+{
+ namespace standard
+ {
+ typedef any_char<char_encoding::standard> char_type;
+ char_type const char_ = char_type();
+ }
+
+ using standard::char_type;
+ using standard::char_;
+
+ namespace standard_wide
+ {
+ typedef any_char<char_encoding::standard_wide> char_type;
+ char_type const char_ = char_type();
+ }
+
+ namespace ascii
+ {
+ typedef any_char<char_encoding::ascii> char_type;
+ char_type const char_ = char_type();
+ }
+
+ namespace extension
+ {
+ template <>
+ struct as_parser<char>
+ {
+ typedef literal_char<
+ char_encoding::standard, unused_type>
+ type;
+
+ typedef type value_type;
+
+ static type call(char ch)
+ {
+ return type(ch);
+ }
+ };
+
+ template <>
+ struct as_parser<wchar_t>
+ {
+ typedef literal_char<
+ char_encoding::standard_wide, unused_type>
+ type;
+
+ typedef type value_type;
+
+ static type call(wchar_t ch)
+ {
+ return type(ch);
+ }
+ };
+ }
+
+ inline literal_char<char_encoding::standard, unused_type>
+ lit(char ch)
+ {
+ return literal_char<char_encoding::standard, unused_type>(ch);
+ }
+
+ inline literal_char<char_encoding::standard_wide, unused_type>
+ lit(wchar_t ch)
+ {
+ return literal_char<char_encoding::standard_wide, unused_type>(ch);
+ }
+}}}
+
+#endif
diff --git a/boost/spirit/home/x3/char/char_class.hpp b/boost/spirit/home/x3/char/char_class.hpp
new file mode 100644
index 0000000000..18b7131c0f
--- /dev/null
+++ b/boost/spirit/home/x3/char/char_class.hpp
@@ -0,0 +1,148 @@
+/*=============================================================================
+ 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(BOOST_SPIRIT_X3_CHAR_CLASS_APRIL_16_2006_1051AM)
+#define BOOST_SPIRIT_X3_CHAR_CLASS_APRIL_16_2006_1051AM
+
+#if defined(_MSC_VER)
+#pragma once
+#endif
+
+#include <boost/spirit/home/x3/char/char_parser.hpp>
+#include <boost/spirit/home/x3/char/detail/cast_char.hpp>
+#include <boost/spirit/home/support/char_encoding/standard.hpp>
+#include <boost/spirit/home/support/char_encoding/standard_wide.hpp>
+#include <boost/spirit/home/support/char_encoding/ascii.hpp>
+#include <boost/spirit/home/support/char_encoding/iso8859_1.hpp>
+
+namespace boost { namespace spirit { namespace x3
+{
+ ///////////////////////////////////////////////////////////////////////////
+ struct char_tag {};
+ struct alnum_tag {};
+ struct alpha_tag {};
+ struct blank_tag {};
+ struct cntrl_tag {};
+ struct digit_tag {};
+ struct graph_tag {};
+ struct print_tag {};
+ struct punct_tag {};
+ struct space_tag {};
+ struct xdigit_tag {};
+ struct lower_tag {};
+ struct upper_tag {};
+
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename Encoding>
+ struct char_class_base
+ {
+ typedef typename Encoding::char_type char_type;
+
+#define BOOST_SPIRIT_X3_CLASSIFY(name) \
+ template <typename Char> \
+ static bool \
+ is(name##_tag, Char ch) \
+ { \
+ return Encoding::is##name \
+ BOOST_PREVENT_MACRO_SUBSTITUTION \
+ (detail::cast_char<char_type>(ch)); \
+ } \
+ /***/
+
+ BOOST_SPIRIT_X3_CLASSIFY(char)
+ BOOST_SPIRIT_X3_CLASSIFY(alnum)
+ BOOST_SPIRIT_X3_CLASSIFY(alpha)
+ BOOST_SPIRIT_X3_CLASSIFY(digit)
+ BOOST_SPIRIT_X3_CLASSIFY(xdigit)
+ BOOST_SPIRIT_X3_CLASSIFY(cntrl)
+ BOOST_SPIRIT_X3_CLASSIFY(graph)
+ BOOST_SPIRIT_X3_CLASSIFY(lower)
+ BOOST_SPIRIT_X3_CLASSIFY(print)
+ BOOST_SPIRIT_X3_CLASSIFY(punct)
+ BOOST_SPIRIT_X3_CLASSIFY(space)
+ BOOST_SPIRIT_X3_CLASSIFY(blank)
+ BOOST_SPIRIT_X3_CLASSIFY(upper)
+
+#undef BOOST_SPIRIT_X3_CLASSIFY
+ };
+
+ template <typename Encoding, typename Tag>
+ struct char_class
+ : char_parser<char_class<Encoding, Tag>>
+ {
+ typedef Encoding encoding;
+ typedef Tag tag;
+ typedef typename Encoding::char_type char_type;
+ typedef char_type attribute_type;
+ static bool const has_attribute = true;
+
+ template <typename Char, typename Context>
+ bool test(Char ch, Context const&) const
+ {
+ return ((sizeof(Char) <= sizeof(char_type)) || encoding::ischar(ch))
+ && char_class_base<Encoding>::is(tag(), ch);
+ }
+ };
+
+#define BOOST_SPIRIT_X3_CHAR_CLASS(encoding, name) \
+ typedef char_class<char_encoding::encoding, name##_tag> name##_type; \
+ name##_type const name = name##_type(); \
+ /***/
+
+#define BOOST_SPIRIT_X3_CHAR_CLASSES(encoding) \
+ namespace encoding \
+ { \
+ BOOST_SPIRIT_X3_CHAR_CLASS(encoding, alnum) \
+ BOOST_SPIRIT_X3_CHAR_CLASS(encoding, alpha) \
+ BOOST_SPIRIT_X3_CHAR_CLASS(encoding, digit) \
+ BOOST_SPIRIT_X3_CHAR_CLASS(encoding, xdigit) \
+ BOOST_SPIRIT_X3_CHAR_CLASS(encoding, cntrl) \
+ BOOST_SPIRIT_X3_CHAR_CLASS(encoding, graph) \
+ BOOST_SPIRIT_X3_CHAR_CLASS(encoding, lower) \
+ BOOST_SPIRIT_X3_CHAR_CLASS(encoding, print) \
+ BOOST_SPIRIT_X3_CHAR_CLASS(encoding, punct) \
+ BOOST_SPIRIT_X3_CHAR_CLASS(encoding, space) \
+ BOOST_SPIRIT_X3_CHAR_CLASS(encoding, blank) \
+ BOOST_SPIRIT_X3_CHAR_CLASS(encoding, upper) \
+ } \
+ /***/
+
+ BOOST_SPIRIT_X3_CHAR_CLASSES(standard)
+ BOOST_SPIRIT_X3_CHAR_CLASSES(standard_wide)
+ BOOST_SPIRIT_X3_CHAR_CLASSES(ascii)
+ BOOST_SPIRIT_X3_CHAR_CLASSES(iso8859_1)
+
+#undef BOOST_SPIRIT_X3_CHAR_CLASS
+#undef BOOST_SPIRIT_X3_CHAR_CLASSES
+
+ using standard::alnum_type;
+ using standard::alpha_type;
+ using standard::digit_type;
+ using standard::xdigit_type;
+ using standard::cntrl_type;
+ using standard::graph_type;
+ using standard::lower_type;
+ using standard::print_type;
+ using standard::punct_type;
+ using standard::space_type;
+ using standard::blank_type;
+ using standard::upper_type;
+
+ using standard::alnum;
+ using standard::alpha;
+ using standard::digit;
+ using standard::xdigit;
+ using standard::cntrl;
+ using standard::graph;
+ using standard::lower;
+ using standard::print;
+ using standard::punct;
+ using standard::space;
+ using standard::blank;
+ using standard::upper;
+}}}
+
+#endif
diff --git a/boost/spirit/home/x3/char/char_parser.hpp b/boost/spirit/home/x3/char/char_parser.hpp
new file mode 100644
index 0000000000..6943804369
--- /dev/null
+++ b/boost/spirit/home/x3/char/char_parser.hpp
@@ -0,0 +1,44 @@
+/*=============================================================================
+ 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(BOOST_SPIRIT_X3_CHAR_PARSER_APR_16_2006_0906AM)
+#define BOOST_SPIRIT_X3_CHAR_PARSER_APR_16_2006_0906AM
+
+#if defined(_MSC_VER)
+#pragma once
+#endif
+
+#include <boost/spirit/home/x3/core/parser.hpp>
+#include <boost/spirit/home/x3/core/skip_over.hpp>
+#include <boost/spirit/home/x3/support/traits/move_to.hpp>
+
+namespace boost { namespace spirit { namespace x3
+{
+ ///////////////////////////////////////////////////////////////////////////
+ // The base char_parser
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename Derived>
+ struct char_parser : parser<Derived>
+ {
+ template <typename Iterator, typename Context, typename Attribute>
+ bool parse(
+ Iterator& first, Iterator const& last
+ , Context const& context, unused_type, Attribute& attr) const
+ {
+ x3::skip_over(first, last, context);
+
+ if (first != last && this->derived().test(*first, context))
+ {
+ x3::traits::move_to(*first, attr);
+ ++first;
+ return true;
+ }
+ return false;
+ }
+ };
+}}}
+
+#endif
diff --git a/boost/spirit/home/x3/char/detail/cast_char.hpp b/boost/spirit/home/x3/char/detail/cast_char.hpp
new file mode 100644
index 0000000000..03bda27a29
--- /dev/null
+++ b/boost/spirit/home/x3/char/detail/cast_char.hpp
@@ -0,0 +1,58 @@
+/*=============================================================================
+ 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(BOOST_SPIRIT_X3_CAST_CHAR_NOVEMBER_10_2006_0907AM)
+#define BOOST_SPIRIT_X3_CAST_CHAR_NOVEMBER_10_2006_0907AM
+
+#if defined(_MSC_VER)
+#pragma once
+#endif
+
+#include <boost/type_traits/is_signed.hpp>
+#include <boost/type_traits/make_unsigned.hpp>
+#include <boost/type_traits/make_signed.hpp>
+
+namespace boost { namespace spirit { namespace x3 { namespace detail
+{
+ // Here's the thing... typical encodings (except ASCII) deal with unsigned
+ // integers > 127 (ASCII uses only 127). Yet, most char and wchar_t are signed.
+ // Thus, a char with value > 127 is negative (e.g. char 233 is -23). When you
+ // cast this to an unsigned int with 32 bits, you get 4294967273!
+ //
+ // The trick is to cast to an unsigned version of the source char first
+ // before casting to the target. {P.S. Don't worry about the code, the
+ // optimizer will optimize the if-else branches}
+
+ template <typename TargetChar, typename SourceChar>
+ TargetChar cast_char(SourceChar ch)
+ {
+ if (is_signed<TargetChar>::value != is_signed<SourceChar>::value)
+ {
+ if (is_signed<SourceChar>::value)
+ {
+ // source is signed, target is unsigned
+ typedef typename make_unsigned<SourceChar>::type USourceChar;
+ return TargetChar(USourceChar(ch));
+ }
+ else
+ {
+ // source is unsigned, target is signed
+ typedef typename make_signed<SourceChar>::type SSourceChar;
+ return TargetChar(SSourceChar(ch));
+ }
+ }
+ else
+ {
+ // source and target has same signedness
+ return TargetChar(ch); // just cast
+ }
+ }
+}}}}
+
+#endif
+
+
diff --git a/boost/spirit/home/x3/char/literal_char.hpp b/boost/spirit/home/x3/char/literal_char.hpp
new file mode 100644
index 0000000000..94b2a239a6
--- /dev/null
+++ b/boost/spirit/home/x3/char/literal_char.hpp
@@ -0,0 +1,54 @@
+/*=============================================================================
+ 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(BOOST_SPIRIT_X3_LITERAL_CHAR_APRIL_16_2006_1051AM)
+#define BOOST_SPIRIT_X3_LITERAL_CHAR_APRIL_16_2006_1051AM
+
+#if defined(_MSC_VER)
+#pragma once
+#endif
+
+#include <boost/spirit/home/x3/char/char_parser.hpp>
+#include <boost/spirit/home/x3/support/utility/utf8.hpp>
+#include <boost/type_traits/is_same.hpp>
+
+namespace boost { namespace spirit { namespace x3
+{
+ template <typename Encoding, typename Attribute = typename Encoding::char_type>
+ struct literal_char : char_parser<literal_char<Encoding, Attribute>>
+ {
+ typedef typename Encoding::char_type char_type;
+ typedef Encoding encoding;
+ typedef Attribute attribute_type;
+ static bool const has_attribute =
+ !is_same<unused_type, attribute_type>::value;
+
+ template <typename Char>
+ literal_char(Char ch)
+ : ch(static_cast<char_type>(ch)) {}
+
+ template <typename Char, typename Context>
+ bool test(Char ch_, Context const&) const
+ {
+ return ((sizeof(Char) <= sizeof(char_type)) || encoding::ischar(ch_))
+ && ch == char_type(ch_);
+ }
+
+ char_type ch;
+ };
+
+ template <typename Encoding, typename Attribute>
+ struct get_info<literal_char<Encoding, Attribute>>
+ {
+ typedef std::string result_type;
+ std::string operator()(literal_char<Encoding, Attribute> const& p) const
+ {
+ return '\'' + to_utf8(Encoding::toucs4(p.ch)) + '\'';
+ }
+ };
+}}}
+
+#endif
diff --git a/boost/spirit/home/x3/char/negated_char_parser.hpp b/boost/spirit/home/x3/char/negated_char_parser.hpp
new file mode 100644
index 0000000000..392d712759
--- /dev/null
+++ b/boost/spirit/home/x3/char/negated_char_parser.hpp
@@ -0,0 +1,65 @@
+/*=============================================================================
+ 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(BOOST_SPIRIT_X3_NEGATED_CHAR_PARSER_APR_16_2006_0906AM)
+#define BOOST_SPIRIT_X3_NEGATED_CHAR_PARSER_APR_16_2006_0906AM
+
+#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/char/char_parser.hpp>
+
+namespace boost { namespace spirit { namespace x3
+{
+ ///////////////////////////////////////////////////////////////////////////
+ // negated_char_parser handles ~cp expressions (cp is a char_parser)
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename Positive>
+ struct negated_char_parser :
+ char_parser<negated_char_parser<Positive>>
+ {
+ negated_char_parser(Positive const& positive)
+ : positive(positive) {}
+
+ template <typename CharParam, typename Context>
+ bool test(CharParam ch, Context const& context) const
+ {
+ return !positive.test(ch, context);
+ }
+
+ Positive positive;
+ };
+
+ template <typename Positive>
+ inline negated_char_parser<Positive>
+ operator~(char_parser<Positive> const& cp)
+ {
+ return negated_char_parser<Positive>(cp.derived());
+ }
+
+ template <typename Positive>
+ inline Positive const&
+ operator~(negated_char_parser<Positive> const& cp)
+ {
+ return cp.positive;
+ }
+}}}
+
+namespace boost { namespace spirit { namespace x3 { namespace traits
+{
+ template <typename Positive, typename Context>
+ struct attribute_of<x3::negated_char_parser<Positive>, Context>
+ : attribute_of<Positive, Context> {};
+
+ template <typename Positive, typename Context>
+ struct has_attribute<x3::negated_char_parser<Positive>, Context>
+ : has_attribute<Positive, Context> {};
+}}}}
+
+#endif
diff --git a/boost/spirit/home/x3/char/unicode.hpp b/boost/spirit/home/x3/char/unicode.hpp
new file mode 100644
index 0000000000..6954c40e40
--- /dev/null
+++ b/boost/spirit/home/x3/char/unicode.hpp
@@ -0,0 +1,617 @@
+/*=============================================================================
+ 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(BOOST_SPIRIT_X3_UNICODE_JAN_20_2012_1218AM)
+#define BOOST_SPIRIT_X3_UNICODE_JAN_20_2012_1218AM
+
+#if defined(_MSC_VER)
+#pragma once
+#endif
+
+#include <boost/spirit/home/x3/char/char_parser.hpp>
+#include <boost/spirit/home/x3/char/char.hpp>
+#include <boost/spirit/home/x3/char/detail/cast_char.hpp>
+#include <boost/spirit/home/support/char_encoding/unicode.hpp>
+
+namespace boost { namespace spirit { namespace x3
+{
+ ///////////////////////////////////////////////////////////////////////////
+ // Unicode Major Categories
+ ///////////////////////////////////////////////////////////////////////////
+ struct char_tag;
+ struct alnum_tag;
+ struct alpha_tag;
+ struct blank_tag;
+ struct cntrl_tag;
+ struct digit_tag;
+ struct graph_tag;
+ struct print_tag;
+ struct punct_tag;
+ struct space_tag;
+ struct xdigit_tag;
+ struct lower_tag;
+ struct upper_tag;
+
+ ///////////////////////////////////////////////////////////////////////////
+ // Unicode Major Categories
+ ///////////////////////////////////////////////////////////////////////////
+ struct letter_tag {};
+ struct mark_tag {};
+ struct number_tag {};
+ struct separator_tag {};
+ struct other_tag {};
+ struct punctuation_tag {};
+ struct symbol_tag {};
+
+ ///////////////////////////////////////////////////////////////////////////
+ // Unicode General Categories
+ ///////////////////////////////////////////////////////////////////////////
+ struct uppercase_letter_tag {};
+ struct lowercase_letter_tag {};
+ struct titlecase_letter_tag {};
+ struct modifier_letter_tag {};
+ struct other_letter_tag {};
+
+ struct nonspacing_mark_tag {};
+ struct enclosing_mark_tag {};
+ struct spacing_mark_tag {};
+
+ struct decimal_number_tag {};
+ struct letter_number_tag {};
+ struct other_number_tag {};
+
+ struct space_separator_tag {};
+ struct line_separator_tag {};
+ struct paragraph_separator_tag {};
+
+ struct control_tag {};
+ struct format_tag {};
+ struct private_use_tag {};
+ struct surrogate_tag {};
+ struct unassigned_tag {};
+
+ struct dash_punctuation_tag {};
+ struct open_punctuation_tag {};
+ struct close_punctuation_tag {};
+ struct connector_punctuation_tag {};
+ struct other_punctuation_tag {};
+ struct initial_punctuation_tag {};
+ struct final_punctuation_tag {};
+
+ struct math_symbol_tag {};
+ struct currency_symbol_tag {};
+ struct modifier_symbol_tag {};
+ struct other_symbol_tag {};
+
+ ///////////////////////////////////////////////////////////////////////////
+ // Unicode Derived Categories
+ ///////////////////////////////////////////////////////////////////////////
+ struct alphabetic_tag {};
+ struct uppercase_tag {};
+ struct lowercase_tag {};
+ struct white_space_tag {};
+ struct hex_digit_tag {};
+ struct noncharacter_code_point_tag {};
+ struct default_ignorable_code_point_tag {};
+
+ ///////////////////////////////////////////////////////////////////////////
+ // Unicode Scripts
+ ///////////////////////////////////////////////////////////////////////////
+ struct arabic_tag {};
+ struct imperial_aramaic_tag {};
+ struct armenian_tag {};
+ struct avestan_tag {};
+ struct balinese_tag {};
+ struct bamum_tag {};
+ struct bengali_tag {};
+ struct bopomofo_tag {};
+ struct braille_tag {};
+ struct buginese_tag {};
+ struct buhid_tag {};
+ struct canadian_aboriginal_tag {};
+ struct carian_tag {};
+ struct cham_tag {};
+ struct cherokee_tag {};
+ struct coptic_tag {};
+ struct cypriot_tag {};
+ struct cyrillic_tag {};
+ struct devanagari_tag {};
+ struct deseret_tag {};
+ struct egyptian_hieroglyphs_tag {};
+ struct ethiopic_tag {};
+ struct georgian_tag {};
+ struct glagolitic_tag {};
+ struct gothic_tag {};
+ struct greek_tag {};
+ struct gujarati_tag {};
+ struct gurmukhi_tag {};
+ struct hangul_tag {};
+ struct han_tag {};
+ struct hanunoo_tag {};
+ struct hebrew_tag {};
+ struct hiragana_tag {};
+ struct katakana_or_hiragana_tag {};
+ struct old_italic_tag {};
+ struct javanese_tag {};
+ struct kayah_li_tag {};
+ struct katakana_tag {};
+ struct kharoshthi_tag {};
+ struct khmer_tag {};
+ struct kannada_tag {};
+ struct kaithi_tag {};
+ struct tai_tham_tag {};
+ struct lao_tag {};
+ struct latin_tag {};
+ struct lepcha_tag {};
+ struct limbu_tag {};
+ struct linear_b_tag {};
+ struct lisu_tag {};
+ struct lycian_tag {};
+ struct lydian_tag {};
+ struct malayalam_tag {};
+ struct mongolian_tag {};
+ struct meetei_mayek_tag {};
+ struct myanmar_tag {};
+ struct nko_tag {};
+ struct ogham_tag {};
+ struct ol_chiki_tag {};
+ struct old_turkic_tag {};
+ struct oriya_tag {};
+ struct osmanya_tag {};
+ struct phags_pa_tag {};
+ struct inscriptional_pahlavi_tag {};
+ struct phoenician_tag {};
+ struct inscriptional_parthian_tag {};
+ struct rejang_tag {};
+ struct runic_tag {};
+ struct samaritan_tag {};
+ struct old_south_arabian_tag {};
+ struct saurashtra_tag {};
+ struct shavian_tag {};
+ struct sinhala_tag {};
+ struct sundanese_tag {};
+ struct syloti_nagri_tag {};
+ struct syriac_tag {};
+ struct tagbanwa_tag {};
+ struct tai_le_tag {};
+ struct new_tai_lue_tag {};
+ struct tamil_tag {};
+ struct tai_viet_tag {};
+ struct telugu_tag {};
+ struct tifinagh_tag {};
+ struct tagalog_tag {};
+ struct thaana_tag {};
+ struct thai_tag {};
+ struct tibetan_tag {};
+ struct ugaritic_tag {};
+ struct vai_tag {};
+ struct old_persian_tag {};
+ struct cuneiform_tag {};
+ struct yi_tag {};
+ struct inherited_tag {};
+ struct common_tag {};
+ struct unknown_tag {};
+
+ ///////////////////////////////////////////////////////////////////////////
+ struct unicode_char_class_base
+ {
+ typedef char_encoding::unicode encoding;
+ typedef char_encoding::unicode::char_type char_type;
+
+#define BOOST_SPIRIT_X3_BASIC_CLASSIFY(name) \
+ template <typename Char> \
+ static bool \
+ is(name##_tag, Char ch) \
+ { \
+ return encoding::is ##name \
+ BOOST_PREVENT_MACRO_SUBSTITUTION \
+ (detail::cast_char<char_type>(ch)); \
+ } \
+ /***/
+
+#define BOOST_SPIRIT_X3_CLASSIFY(name) \
+ template <typename Char> \
+ static bool \
+ is(name##_tag, Char ch) \
+ { \
+ return encoding::is_##name \
+ BOOST_PREVENT_MACRO_SUBSTITUTION \
+ (detail::cast_char<char_type>(ch)); \
+ } \
+ /***/
+
+
+ ///////////////////////////////////////////////////////////////////////////
+ // Unicode Major Categories
+ ///////////////////////////////////////////////////////////////////////////
+ BOOST_SPIRIT_X3_BASIC_CLASSIFY(char)
+ BOOST_SPIRIT_X3_BASIC_CLASSIFY(alnum)
+ BOOST_SPIRIT_X3_BASIC_CLASSIFY(alpha)
+ BOOST_SPIRIT_X3_BASIC_CLASSIFY(digit)
+ BOOST_SPIRIT_X3_BASIC_CLASSIFY(xdigit)
+ BOOST_SPIRIT_X3_BASIC_CLASSIFY(cntrl)
+ BOOST_SPIRIT_X3_BASIC_CLASSIFY(graph)
+ BOOST_SPIRIT_X3_BASIC_CLASSIFY(lower)
+ BOOST_SPIRIT_X3_BASIC_CLASSIFY(print)
+ BOOST_SPIRIT_X3_BASIC_CLASSIFY(punct)
+ BOOST_SPIRIT_X3_BASIC_CLASSIFY(space)
+ BOOST_SPIRIT_X3_BASIC_CLASSIFY(blank)
+ BOOST_SPIRIT_X3_BASIC_CLASSIFY(upper)
+
+ ///////////////////////////////////////////////////////////////////////////
+ // Unicode Major Categories
+ ///////////////////////////////////////////////////////////////////////////
+ BOOST_SPIRIT_X3_CLASSIFY(letter)
+ BOOST_SPIRIT_X3_CLASSIFY(mark)
+ BOOST_SPIRIT_X3_CLASSIFY(number)
+ BOOST_SPIRIT_X3_CLASSIFY(separator)
+ BOOST_SPIRIT_X3_CLASSIFY(other)
+ BOOST_SPIRIT_X3_CLASSIFY(punctuation)
+ BOOST_SPIRIT_X3_CLASSIFY(symbol)
+
+ ///////////////////////////////////////////////////////////////////////////
+ // Unicode General Categories
+ ///////////////////////////////////////////////////////////////////////////
+ BOOST_SPIRIT_X3_CLASSIFY(uppercase_letter)
+ BOOST_SPIRIT_X3_CLASSIFY(lowercase_letter)
+ BOOST_SPIRIT_X3_CLASSIFY(titlecase_letter)
+ BOOST_SPIRIT_X3_CLASSIFY(modifier_letter)
+ BOOST_SPIRIT_X3_CLASSIFY(other_letter)
+
+ BOOST_SPIRIT_X3_CLASSIFY(nonspacing_mark)
+ BOOST_SPIRIT_X3_CLASSIFY(enclosing_mark)
+ BOOST_SPIRIT_X3_CLASSIFY(spacing_mark)
+
+ BOOST_SPIRIT_X3_CLASSIFY(decimal_number)
+ BOOST_SPIRIT_X3_CLASSIFY(letter_number)
+ BOOST_SPIRIT_X3_CLASSIFY(other_number)
+
+ BOOST_SPIRIT_X3_CLASSIFY(space_separator)
+ BOOST_SPIRIT_X3_CLASSIFY(line_separator)
+ BOOST_SPIRIT_X3_CLASSIFY(paragraph_separator)
+
+ BOOST_SPIRIT_X3_CLASSIFY(control)
+ BOOST_SPIRIT_X3_CLASSIFY(format)
+ BOOST_SPIRIT_X3_CLASSIFY(private_use)
+ BOOST_SPIRIT_X3_CLASSIFY(surrogate)
+ BOOST_SPIRIT_X3_CLASSIFY(unassigned)
+
+ BOOST_SPIRIT_X3_CLASSIFY(dash_punctuation)
+ BOOST_SPIRIT_X3_CLASSIFY(open_punctuation)
+ BOOST_SPIRIT_X3_CLASSIFY(close_punctuation)
+ BOOST_SPIRIT_X3_CLASSIFY(connector_punctuation)
+ BOOST_SPIRIT_X3_CLASSIFY(other_punctuation)
+ BOOST_SPIRIT_X3_CLASSIFY(initial_punctuation)
+ BOOST_SPIRIT_X3_CLASSIFY(final_punctuation)
+
+ BOOST_SPIRIT_X3_CLASSIFY(math_symbol)
+ BOOST_SPIRIT_X3_CLASSIFY(currency_symbol)
+ BOOST_SPIRIT_X3_CLASSIFY(modifier_symbol)
+ BOOST_SPIRIT_X3_CLASSIFY(other_symbol)
+
+ ///////////////////////////////////////////////////////////////////////////
+ // Unicode Derived Categories
+ ///////////////////////////////////////////////////////////////////////////
+ BOOST_SPIRIT_X3_CLASSIFY(alphabetic)
+ BOOST_SPIRIT_X3_CLASSIFY(uppercase)
+ BOOST_SPIRIT_X3_CLASSIFY(lowercase)
+ BOOST_SPIRIT_X3_CLASSIFY(white_space)
+ BOOST_SPIRIT_X3_CLASSIFY(hex_digit)
+ BOOST_SPIRIT_X3_CLASSIFY(noncharacter_code_point)
+ BOOST_SPIRIT_X3_CLASSIFY(default_ignorable_code_point)
+
+ ///////////////////////////////////////////////////////////////////////////
+ // Unicode Scripts
+ ///////////////////////////////////////////////////////////////////////////
+ BOOST_SPIRIT_X3_CLASSIFY(arabic)
+ BOOST_SPIRIT_X3_CLASSIFY(imperial_aramaic)
+ BOOST_SPIRIT_X3_CLASSIFY(armenian)
+ BOOST_SPIRIT_X3_CLASSIFY(avestan)
+ BOOST_SPIRIT_X3_CLASSIFY(balinese)
+ BOOST_SPIRIT_X3_CLASSIFY(bamum)
+ BOOST_SPIRIT_X3_CLASSIFY(bengali)
+ BOOST_SPIRIT_X3_CLASSIFY(bopomofo)
+ BOOST_SPIRIT_X3_CLASSIFY(braille)
+ BOOST_SPIRIT_X3_CLASSIFY(buginese)
+ BOOST_SPIRIT_X3_CLASSIFY(buhid)
+ BOOST_SPIRIT_X3_CLASSIFY(canadian_aboriginal)
+ BOOST_SPIRIT_X3_CLASSIFY(carian)
+ BOOST_SPIRIT_X3_CLASSIFY(cham)
+ BOOST_SPIRIT_X3_CLASSIFY(cherokee)
+ BOOST_SPIRIT_X3_CLASSIFY(coptic)
+ BOOST_SPIRIT_X3_CLASSIFY(cypriot)
+ BOOST_SPIRIT_X3_CLASSIFY(cyrillic)
+ BOOST_SPIRIT_X3_CLASSIFY(devanagari)
+ BOOST_SPIRIT_X3_CLASSIFY(deseret)
+ BOOST_SPIRIT_X3_CLASSIFY(egyptian_hieroglyphs)
+ BOOST_SPIRIT_X3_CLASSIFY(ethiopic)
+ BOOST_SPIRIT_X3_CLASSIFY(georgian)
+ BOOST_SPIRIT_X3_CLASSIFY(glagolitic)
+ BOOST_SPIRIT_X3_CLASSIFY(gothic)
+ BOOST_SPIRIT_X3_CLASSIFY(greek)
+ BOOST_SPIRIT_X3_CLASSIFY(gujarati)
+ BOOST_SPIRIT_X3_CLASSIFY(gurmukhi)
+ BOOST_SPIRIT_X3_CLASSIFY(hangul)
+ BOOST_SPIRIT_X3_CLASSIFY(han)
+ BOOST_SPIRIT_X3_CLASSIFY(hanunoo)
+ BOOST_SPIRIT_X3_CLASSIFY(hebrew)
+ BOOST_SPIRIT_X3_CLASSIFY(hiragana)
+ BOOST_SPIRIT_X3_CLASSIFY(katakana_or_hiragana)
+ BOOST_SPIRIT_X3_CLASSIFY(old_italic)
+ BOOST_SPIRIT_X3_CLASSIFY(javanese)
+ BOOST_SPIRIT_X3_CLASSIFY(kayah_li)
+ BOOST_SPIRIT_X3_CLASSIFY(katakana)
+ BOOST_SPIRIT_X3_CLASSIFY(kharoshthi)
+ BOOST_SPIRIT_X3_CLASSIFY(khmer)
+ BOOST_SPIRIT_X3_CLASSIFY(kannada)
+ BOOST_SPIRIT_X3_CLASSIFY(kaithi)
+ BOOST_SPIRIT_X3_CLASSIFY(tai_tham)
+ BOOST_SPIRIT_X3_CLASSIFY(lao)
+ BOOST_SPIRIT_X3_CLASSIFY(latin)
+ BOOST_SPIRIT_X3_CLASSIFY(lepcha)
+ BOOST_SPIRIT_X3_CLASSIFY(limbu)
+ BOOST_SPIRIT_X3_CLASSIFY(linear_b)
+ BOOST_SPIRIT_X3_CLASSIFY(lisu)
+ BOOST_SPIRIT_X3_CLASSIFY(lycian)
+ BOOST_SPIRIT_X3_CLASSIFY(lydian)
+ BOOST_SPIRIT_X3_CLASSIFY(malayalam)
+ BOOST_SPIRIT_X3_CLASSIFY(mongolian)
+ BOOST_SPIRIT_X3_CLASSIFY(meetei_mayek)
+ BOOST_SPIRIT_X3_CLASSIFY(myanmar)
+ BOOST_SPIRIT_X3_CLASSIFY(nko)
+ BOOST_SPIRIT_X3_CLASSIFY(ogham)
+ BOOST_SPIRIT_X3_CLASSIFY(ol_chiki)
+ BOOST_SPIRIT_X3_CLASSIFY(old_turkic)
+ BOOST_SPIRIT_X3_CLASSIFY(oriya)
+ BOOST_SPIRIT_X3_CLASSIFY(osmanya)
+ BOOST_SPIRIT_X3_CLASSIFY(phags_pa)
+ BOOST_SPIRIT_X3_CLASSIFY(inscriptional_pahlavi)
+ BOOST_SPIRIT_X3_CLASSIFY(phoenician)
+ BOOST_SPIRIT_X3_CLASSIFY(inscriptional_parthian)
+ BOOST_SPIRIT_X3_CLASSIFY(rejang)
+ BOOST_SPIRIT_X3_CLASSIFY(runic)
+ BOOST_SPIRIT_X3_CLASSIFY(samaritan)
+ BOOST_SPIRIT_X3_CLASSIFY(old_south_arabian)
+ BOOST_SPIRIT_X3_CLASSIFY(saurashtra)
+ BOOST_SPIRIT_X3_CLASSIFY(shavian)
+ BOOST_SPIRIT_X3_CLASSIFY(sinhala)
+ BOOST_SPIRIT_X3_CLASSIFY(sundanese)
+ BOOST_SPIRIT_X3_CLASSIFY(syloti_nagri)
+ BOOST_SPIRIT_X3_CLASSIFY(syriac)
+ BOOST_SPIRIT_X3_CLASSIFY(tagbanwa)
+ BOOST_SPIRIT_X3_CLASSIFY(tai_le)
+ BOOST_SPIRIT_X3_CLASSIFY(new_tai_lue)
+ BOOST_SPIRIT_X3_CLASSIFY(tamil)
+ BOOST_SPIRIT_X3_CLASSIFY(tai_viet)
+ BOOST_SPIRIT_X3_CLASSIFY(telugu)
+ BOOST_SPIRIT_X3_CLASSIFY(tifinagh)
+ BOOST_SPIRIT_X3_CLASSIFY(tagalog)
+ BOOST_SPIRIT_X3_CLASSIFY(thaana)
+ BOOST_SPIRIT_X3_CLASSIFY(thai)
+ BOOST_SPIRIT_X3_CLASSIFY(tibetan)
+ BOOST_SPIRIT_X3_CLASSIFY(ugaritic)
+ BOOST_SPIRIT_X3_CLASSIFY(vai)
+ BOOST_SPIRIT_X3_CLASSIFY(old_persian)
+ BOOST_SPIRIT_X3_CLASSIFY(cuneiform)
+ BOOST_SPIRIT_X3_CLASSIFY(yi)
+ BOOST_SPIRIT_X3_CLASSIFY(inherited)
+ BOOST_SPIRIT_X3_CLASSIFY(common)
+ BOOST_SPIRIT_X3_CLASSIFY(unknown)
+
+#undef BOOST_SPIRIT_X3_BASIC_CLASSIFY
+#undef BOOST_SPIRIT_X3_CLASSIFY
+ };
+
+ template <typename Tag>
+ struct unicode_char_class
+ : char_parser<unicode_char_class<Tag>>
+ {
+ typedef char_encoding::unicode encoding;
+ typedef Tag tag;
+ typedef typename encoding::char_type char_type;
+ typedef char_type attribute_type;
+ static bool const has_attribute = true;
+
+ template <typename Char, typename Context>
+ bool test(Char ch, Context const&) const
+ {
+ return ((sizeof(Char) <= sizeof(char_type)) || encoding::ischar(ch))
+ && unicode_char_class_base::is(tag(), ch);
+ }
+ };
+
+#define BOOST_SPIRIT_X3_CHAR_CLASS(name) \
+ typedef unicode_char_class<name##_tag> name##_type; \
+ name##_type const name = name##_type(); \
+ /***/
+
+ namespace unicode
+ {
+ typedef any_char<char_encoding::unicode> char_type;
+ char_type const char_ = char_type();
+
+ ///////////////////////////////////////////////////////////////////////////
+ // Unicode Major Categories
+ ///////////////////////////////////////////////////////////////////////////
+ BOOST_SPIRIT_X3_CHAR_CLASS(alnum)
+ BOOST_SPIRIT_X3_CHAR_CLASS(alpha)
+ BOOST_SPIRIT_X3_CHAR_CLASS(digit)
+ BOOST_SPIRIT_X3_CHAR_CLASS(xdigit)
+ BOOST_SPIRIT_X3_CHAR_CLASS(cntrl)
+ BOOST_SPIRIT_X3_CHAR_CLASS(graph)
+ BOOST_SPIRIT_X3_CHAR_CLASS(lower)
+ BOOST_SPIRIT_X3_CHAR_CLASS(print)
+ BOOST_SPIRIT_X3_CHAR_CLASS(punct)
+ BOOST_SPIRIT_X3_CHAR_CLASS(space)
+ BOOST_SPIRIT_X3_CHAR_CLASS(blank)
+ BOOST_SPIRIT_X3_CHAR_CLASS(upper)
+
+ ///////////////////////////////////////////////////////////////////////////
+ // Unicode Major Categories
+ ///////////////////////////////////////////////////////////////////////////
+ BOOST_SPIRIT_X3_CHAR_CLASS(letter)
+ BOOST_SPIRIT_X3_CHAR_CLASS(mark)
+ BOOST_SPIRIT_X3_CHAR_CLASS(number)
+ BOOST_SPIRIT_X3_CHAR_CLASS(separator)
+ BOOST_SPIRIT_X3_CHAR_CLASS(other)
+ BOOST_SPIRIT_X3_CHAR_CLASS(punctuation)
+ BOOST_SPIRIT_X3_CHAR_CLASS(symbol)
+
+ ///////////////////////////////////////////////////////////////////////////
+ // Unicode General Categories
+ ///////////////////////////////////////////////////////////////////////////
+ BOOST_SPIRIT_X3_CHAR_CLASS(uppercase_letter)
+ BOOST_SPIRIT_X3_CHAR_CLASS(lowercase_letter)
+ BOOST_SPIRIT_X3_CHAR_CLASS(titlecase_letter)
+ BOOST_SPIRIT_X3_CHAR_CLASS(modifier_letter)
+ BOOST_SPIRIT_X3_CHAR_CLASS(other_letter)
+
+ BOOST_SPIRIT_X3_CHAR_CLASS(nonspacing_mark)
+ BOOST_SPIRIT_X3_CHAR_CLASS(enclosing_mark)
+ BOOST_SPIRIT_X3_CHAR_CLASS(spacing_mark)
+
+ BOOST_SPIRIT_X3_CHAR_CLASS(decimal_number)
+ BOOST_SPIRIT_X3_CHAR_CLASS(letter_number)
+ BOOST_SPIRIT_X3_CHAR_CLASS(other_number)
+
+ BOOST_SPIRIT_X3_CHAR_CLASS(space_separator)
+ BOOST_SPIRIT_X3_CHAR_CLASS(line_separator)
+ BOOST_SPIRIT_X3_CHAR_CLASS(paragraph_separator)
+
+ BOOST_SPIRIT_X3_CHAR_CLASS(control)
+ BOOST_SPIRIT_X3_CHAR_CLASS(format)
+ BOOST_SPIRIT_X3_CHAR_CLASS(private_use)
+ BOOST_SPIRIT_X3_CHAR_CLASS(surrogate)
+ BOOST_SPIRIT_X3_CHAR_CLASS(unassigned)
+
+ BOOST_SPIRIT_X3_CHAR_CLASS(dash_punctuation)
+ BOOST_SPIRIT_X3_CHAR_CLASS(open_punctuation)
+ BOOST_SPIRIT_X3_CHAR_CLASS(close_punctuation)
+ BOOST_SPIRIT_X3_CHAR_CLASS(connector_punctuation)
+ BOOST_SPIRIT_X3_CHAR_CLASS(other_punctuation)
+ BOOST_SPIRIT_X3_CHAR_CLASS(initial_punctuation)
+ BOOST_SPIRIT_X3_CHAR_CLASS(final_punctuation)
+
+ BOOST_SPIRIT_X3_CHAR_CLASS(math_symbol)
+ BOOST_SPIRIT_X3_CHAR_CLASS(currency_symbol)
+ BOOST_SPIRIT_X3_CHAR_CLASS(modifier_symbol)
+ BOOST_SPIRIT_X3_CHAR_CLASS(other_symbol)
+
+ ///////////////////////////////////////////////////////////////////////////
+ // Unicode Derived Categories
+ ///////////////////////////////////////////////////////////////////////////
+ BOOST_SPIRIT_X3_CHAR_CLASS(alphabetic)
+ BOOST_SPIRIT_X3_CHAR_CLASS(uppercase)
+ BOOST_SPIRIT_X3_CHAR_CLASS(lowercase)
+ BOOST_SPIRIT_X3_CHAR_CLASS(white_space)
+ BOOST_SPIRIT_X3_CHAR_CLASS(hex_digit)
+ BOOST_SPIRIT_X3_CHAR_CLASS(noncharacter_code_point)
+ BOOST_SPIRIT_X3_CHAR_CLASS(default_ignorable_code_point)
+
+ ///////////////////////////////////////////////////////////////////////////
+ // Unicode Scripts
+ ///////////////////////////////////////////////////////////////////////////
+ BOOST_SPIRIT_X3_CHAR_CLASS(arabic)
+ BOOST_SPIRIT_X3_CHAR_CLASS(imperial_aramaic)
+ BOOST_SPIRIT_X3_CHAR_CLASS(armenian)
+ BOOST_SPIRIT_X3_CHAR_CLASS(avestan)
+ BOOST_SPIRIT_X3_CHAR_CLASS(balinese)
+ BOOST_SPIRIT_X3_CHAR_CLASS(bamum)
+ BOOST_SPIRIT_X3_CHAR_CLASS(bengali)
+ BOOST_SPIRIT_X3_CHAR_CLASS(bopomofo)
+ BOOST_SPIRIT_X3_CHAR_CLASS(braille)
+ BOOST_SPIRIT_X3_CHAR_CLASS(buginese)
+ BOOST_SPIRIT_X3_CHAR_CLASS(buhid)
+ BOOST_SPIRIT_X3_CHAR_CLASS(canadian_aboriginal)
+ BOOST_SPIRIT_X3_CHAR_CLASS(carian)
+ BOOST_SPIRIT_X3_CHAR_CLASS(cham)
+ BOOST_SPIRIT_X3_CHAR_CLASS(cherokee)
+ BOOST_SPIRIT_X3_CHAR_CLASS(coptic)
+ BOOST_SPIRIT_X3_CHAR_CLASS(cypriot)
+ BOOST_SPIRIT_X3_CHAR_CLASS(cyrillic)
+ BOOST_SPIRIT_X3_CHAR_CLASS(devanagari)
+ BOOST_SPIRIT_X3_CHAR_CLASS(deseret)
+ BOOST_SPIRIT_X3_CHAR_CLASS(egyptian_hieroglyphs)
+ BOOST_SPIRIT_X3_CHAR_CLASS(ethiopic)
+ BOOST_SPIRIT_X3_CHAR_CLASS(georgian)
+ BOOST_SPIRIT_X3_CHAR_CLASS(glagolitic)
+ BOOST_SPIRIT_X3_CHAR_CLASS(gothic)
+ BOOST_SPIRIT_X3_CHAR_CLASS(greek)
+ BOOST_SPIRIT_X3_CHAR_CLASS(gujarati)
+ BOOST_SPIRIT_X3_CHAR_CLASS(gurmukhi)
+ BOOST_SPIRIT_X3_CHAR_CLASS(hangul)
+ BOOST_SPIRIT_X3_CHAR_CLASS(han)
+ BOOST_SPIRIT_X3_CHAR_CLASS(hanunoo)
+ BOOST_SPIRIT_X3_CHAR_CLASS(hebrew)
+ BOOST_SPIRIT_X3_CHAR_CLASS(hiragana)
+ BOOST_SPIRIT_X3_CHAR_CLASS(katakana_or_hiragana)
+ BOOST_SPIRIT_X3_CHAR_CLASS(old_italic)
+ BOOST_SPIRIT_X3_CHAR_CLASS(javanese)
+ BOOST_SPIRIT_X3_CHAR_CLASS(kayah_li)
+ BOOST_SPIRIT_X3_CHAR_CLASS(katakana)
+ BOOST_SPIRIT_X3_CHAR_CLASS(kharoshthi)
+ BOOST_SPIRIT_X3_CHAR_CLASS(khmer)
+ BOOST_SPIRIT_X3_CHAR_CLASS(kannada)
+ BOOST_SPIRIT_X3_CHAR_CLASS(kaithi)
+ BOOST_SPIRIT_X3_CHAR_CLASS(tai_tham)
+ BOOST_SPIRIT_X3_CHAR_CLASS(lao)
+ BOOST_SPIRIT_X3_CHAR_CLASS(latin)
+ BOOST_SPIRIT_X3_CHAR_CLASS(lepcha)
+ BOOST_SPIRIT_X3_CHAR_CLASS(limbu)
+ BOOST_SPIRIT_X3_CHAR_CLASS(linear_b)
+ BOOST_SPIRIT_X3_CHAR_CLASS(lisu)
+ BOOST_SPIRIT_X3_CHAR_CLASS(lycian)
+ BOOST_SPIRIT_X3_CHAR_CLASS(lydian)
+ BOOST_SPIRIT_X3_CHAR_CLASS(malayalam)
+ BOOST_SPIRIT_X3_CHAR_CLASS(mongolian)
+ BOOST_SPIRIT_X3_CHAR_CLASS(meetei_mayek)
+ BOOST_SPIRIT_X3_CHAR_CLASS(myanmar)
+ BOOST_SPIRIT_X3_CHAR_CLASS(nko)
+ BOOST_SPIRIT_X3_CHAR_CLASS(ogham)
+ BOOST_SPIRIT_X3_CHAR_CLASS(ol_chiki)
+ BOOST_SPIRIT_X3_CHAR_CLASS(old_turkic)
+ BOOST_SPIRIT_X3_CHAR_CLASS(oriya)
+ BOOST_SPIRIT_X3_CHAR_CLASS(osmanya)
+ BOOST_SPIRIT_X3_CHAR_CLASS(phags_pa)
+ BOOST_SPIRIT_X3_CHAR_CLASS(inscriptional_pahlavi)
+ BOOST_SPIRIT_X3_CHAR_CLASS(phoenician)
+ BOOST_SPIRIT_X3_CHAR_CLASS(inscriptional_parthian)
+ BOOST_SPIRIT_X3_CHAR_CLASS(rejang)
+ BOOST_SPIRIT_X3_CHAR_CLASS(runic)
+ BOOST_SPIRIT_X3_CHAR_CLASS(samaritan)
+ BOOST_SPIRIT_X3_CHAR_CLASS(old_south_arabian)
+ BOOST_SPIRIT_X3_CHAR_CLASS(saurashtra)
+ BOOST_SPIRIT_X3_CHAR_CLASS(shavian)
+ BOOST_SPIRIT_X3_CHAR_CLASS(sinhala)
+ BOOST_SPIRIT_X3_CHAR_CLASS(sundanese)
+ BOOST_SPIRIT_X3_CHAR_CLASS(syloti_nagri)
+ BOOST_SPIRIT_X3_CHAR_CLASS(syriac)
+ BOOST_SPIRIT_X3_CHAR_CLASS(tagbanwa)
+ BOOST_SPIRIT_X3_CHAR_CLASS(tai_le)
+ BOOST_SPIRIT_X3_CHAR_CLASS(new_tai_lue)
+ BOOST_SPIRIT_X3_CHAR_CLASS(tamil)
+ BOOST_SPIRIT_X3_CHAR_CLASS(tai_viet)
+ BOOST_SPIRIT_X3_CHAR_CLASS(telugu)
+ BOOST_SPIRIT_X3_CHAR_CLASS(tifinagh)
+ BOOST_SPIRIT_X3_CHAR_CLASS(tagalog)
+ BOOST_SPIRIT_X3_CHAR_CLASS(thaana)
+ BOOST_SPIRIT_X3_CHAR_CLASS(thai)
+ BOOST_SPIRIT_X3_CHAR_CLASS(tibetan)
+ BOOST_SPIRIT_X3_CHAR_CLASS(ugaritic)
+ BOOST_SPIRIT_X3_CHAR_CLASS(vai)
+ BOOST_SPIRIT_X3_CHAR_CLASS(old_persian)
+ BOOST_SPIRIT_X3_CHAR_CLASS(cuneiform)
+ BOOST_SPIRIT_X3_CHAR_CLASS(yi)
+ BOOST_SPIRIT_X3_CHAR_CLASS(inherited)
+ BOOST_SPIRIT_X3_CHAR_CLASS(common)
+ BOOST_SPIRIT_X3_CHAR_CLASS(unknown)
+ }
+
+#undef BOOST_SPIRIT_X3_CHAR_CLASS
+
+}}}
+
+#endif
diff --git a/boost/spirit/home/x3/core.hpp b/boost/spirit/home/x3/core.hpp
new file mode 100644
index 0000000000..a4f875e38a
--- /dev/null
+++ b/boost/spirit/home/x3/core.hpp
@@ -0,0 +1,20 @@
+/*=============================================================================
+ 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(BOOST_SPIRIT_X3_CORE_APRIL_04_2012_0318PM)
+#define BOOST_SPIRIT_X3_CORE_APRIL_04_2012_0318PM
+
+#if defined(_MSC_VER)
+#pragma once
+#endif
+
+#include <boost/spirit/home/x3/core/parse.hpp>
+//~ #include <boost/spirit/home/x3/core/parse_attr.hpp>
+#include <boost/spirit/home/x3/core/parser.hpp>
+#include <boost/spirit/home/x3/core/skip_over.hpp>
+#include <boost/spirit/home/x3/core/action.hpp>
+
+#endif
diff --git a/boost/spirit/home/x3/core/action.hpp b/boost/spirit/home/x3/core/action.hpp
new file mode 100644
index 0000000000..890933fff1
--- /dev/null
+++ b/boost/spirit/home/x3/core/action.hpp
@@ -0,0 +1,120 @@
+/*=============================================================================
+ Copyright (arg) 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_ACTION_JANUARY_07_2007_1128AM)
+#define SPIRIT_ACTION_JANUARY_07_2007_1128AM
+
+#if defined(_MSC_VER)
+#pragma once
+#endif
+
+#include <boost/spirit/home/x3/support/context.hpp>
+#include <boost/spirit/home/x3/support/traits/attribute_of.hpp>
+#include <boost/spirit/home/x3/support/traits/make_attribute.hpp>
+#include <boost/spirit/home/x3/core/call.hpp>
+#include <boost/spirit/home/x3/nonterminal/detail/transform_attribute.hpp>
+#include <boost/range/iterator_range.hpp>
+
+namespace boost { namespace spirit { namespace x3
+{
+ struct raw_attribute_type;
+ struct parse_pass_context_tag;
+
+ template <typename Context>
+ inline bool& _pass(Context const& context)
+ {
+ return x3::get<parse_pass_context_tag>(context);
+ }
+
+ template <typename Subject, typename Action>
+ struct action : unary_parser<Subject, action<Subject, Action>>
+ {
+ typedef unary_parser<Subject, action<Subject, Action>> base_type;
+ static bool const is_pass_through_unary = true;
+ static bool const has_action = true;
+
+ action(Subject const& subject, Action f)
+ : base_type(subject), f(f) {}
+
+ template <typename Iterator, typename Context, typename RuleContext, typename Attribute>
+ bool call_action(
+ Iterator& first, Iterator const& last
+ , Context const& context, RuleContext& rcontext, Attribute& attr) const
+ {
+ bool pass = true;
+ auto action_context = make_context<parse_pass_context_tag>(pass, context);
+ call(f, first, last, action_context, rcontext, attr);
+ return pass;
+ }
+
+ template <typename Iterator, typename Context
+ , typename RuleContext, typename Attribute>
+ bool parse_main(Iterator& first, Iterator const& last
+ , Context const& context, RuleContext& rcontext, Attribute& attr) const
+ {
+ Iterator save = first;
+ if (this->subject.parse(first, last, context, rcontext, attr))
+ {
+ if (call_action(first, last, context, rcontext, attr))
+ return true;
+
+ // reset iterators if semantic action failed the match
+ // retrospectively
+ first = save;
+ }
+ return false;
+ }
+
+ // attr==raw_attribute_type, action wants iterator_range (see raw.hpp)
+ template <typename Iterator, typename Context, typename RuleContext>
+ bool parse_main(Iterator& first, Iterator const& last
+ , Context const& context, RuleContext& rcontext, raw_attribute_type&) const
+ {
+ boost::iterator_range<Iterator> rng;
+ // synthesize the attribute since one is not supplied
+ return parse_main(first, last, context, rcontext, rng);
+ }
+
+ // attr==unused, action wants attribute
+ template <typename Iterator, typename Context, typename RuleContext>
+ bool parse(Iterator& first, Iterator const& last
+ , Context const& context, RuleContext& rcontext, unused_type) const
+ {
+ typedef typename
+ traits::attribute_of<action<Subject, Action>, Context>::type
+ attribute_type;
+ typedef traits::make_attribute<attribute_type, unused_type> make_attribute;
+ typedef traits::transform_attribute<
+ typename make_attribute::type, attribute_type, parser_id>
+ transform;
+
+ // synthesize the attribute since one is not supplied
+ typename make_attribute::type made_attr = make_attribute::call(unused_type());
+ typename transform::type attr = transform::pre(made_attr);
+ return parse_main(first, last, context, rcontext, attr);
+ }
+
+ // main parse function
+ template <typename Iterator, typename Context
+ , typename RuleContext, typename Attribute>
+ bool parse(Iterator& first, Iterator const& last
+ , Context const& context, RuleContext& rcontext, Attribute& attr) const
+ {
+ return parse_main(first, last, context, rcontext, attr);
+ }
+
+ Action f;
+ };
+
+ template <typename P, typename Action>
+ inline action<typename extension::as_parser<P>::value_type, Action>
+ operator/(P const& p, Action f)
+ {
+ return {as_parser(p), f};
+ }
+}}}
+
+#endif
diff --git a/boost/spirit/home/x3/core/call.hpp b/boost/spirit/home/x3/core/call.hpp
new file mode 100644
index 0000000000..a4139751df
--- /dev/null
+++ b/boost/spirit/home/x3/core/call.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_CALL_CONTEXT_MAY_26_2014_0234PM)
+#define SPIRIT_CALL_CONTEXT_MAY_26_2014_0234PM
+
+#include <type_traits>
+
+#include <boost/spirit/home/x3/support/context.hpp>
+#include <boost/spirit/home/x3/support/utility/is_callable.hpp>
+#include <boost/range/iterator_range.hpp>
+
+namespace boost { namespace spirit { namespace x3
+{
+ ////////////////////////////////////////////////////////////////////////////
+ struct rule_val_context_tag;
+
+ template <typename Context>
+ inline auto _val(Context const& context)
+ -> decltype(x3::get<rule_val_context_tag>(context))
+ {
+ return x3::get<rule_val_context_tag>(context);
+ }
+
+ ////////////////////////////////////////////////////////////////////////////
+ struct where_context_tag;
+
+ template <typename Context>
+ inline auto _where(Context const& context)
+ -> decltype(x3::get<where_context_tag>(context))
+ {
+ return x3::get<where_context_tag>(context);
+ }
+
+ ////////////////////////////////////////////////////////////////////////////
+ struct attr_context_tag;
+
+ template <typename Context>
+ inline auto _attr(Context const& context)
+ -> decltype(x3::get<attr_context_tag>(context))
+ {
+ return x3::get<attr_context_tag>(context);
+ }
+
+ ////////////////////////////////////////////////////////////////////////////
+ namespace detail
+ {
+ template <typename F, typename Context>
+ auto call(F f, Context const& context, mpl::true_)
+ {
+ return f(context);
+ }
+
+ template <typename F, typename Context>
+ auto call(F f, Context const& context, mpl::false_)
+ {
+ return f();
+ }
+ }
+
+ template <
+ typename F, typename Iterator
+ , typename Context, typename RuleContext, typename Attribute>
+ auto call(
+ F f, Iterator& first, Iterator const& last
+ , Context const& context, RuleContext& rcontext, Attribute& attr)
+ {
+ boost::iterator_range<Iterator> rng(first, last);
+ auto val_context = make_context<rule_val_context_tag>(rcontext, context);
+ auto where_context = make_context<where_context_tag>(rng, val_context);
+ auto attr_context = make_context<attr_context_tag>(attr, where_context);
+ return detail::call(f, attr_context, is_callable<F(decltype(attr_context) const&)>());
+ }
+}}}
+
+#endif
diff --git a/boost/spirit/home/x3/core/detail/parse_into_container.hpp b/boost/spirit/home/x3/core/detail/parse_into_container.hpp
new file mode 100644
index 0000000000..4b19115a67
--- /dev/null
+++ b/boost/spirit/home/x3/core/detail/parse_into_container.hpp
@@ -0,0 +1,248 @@
+/*=============================================================================
+ 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_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>
+#include <boost/spirit/home/x3/support/traits/value_traits.hpp>
+#include <boost/spirit/home/x3/support/traits/attribute_of.hpp>
+#include <boost/spirit/home/x3/support/traits/handles_container.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/move_to.hpp>
+#include <boost/mpl/and.hpp>
+#include <boost/fusion/include/front.hpp>
+#include <boost/fusion/include/back.hpp>
+#include <boost/variant/apply_visitor.hpp>
+
+namespace boost { namespace spirit { namespace x3 { namespace detail
+{
+ template <typename Attribute, typename Value>
+ struct saver_visitor;
+
+ // save to associative fusion container where Key is simple type
+ template <typename Key, typename Enable = void>
+ struct save_to_assoc_attr
+ {
+ template <typename Value, typename Attribute>
+ static void call(const Key, Value& value, Attribute& attr)
+ {
+ traits::move_to(value, fusion::at_key<Key>(attr));
+ }
+ };
+
+
+ // 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>
+ {
+ saver_visitor(Attribute& attr, Value& value)
+ : attr(attr), value(value) {};
+
+ Attribute& attr;
+ Value& value;
+
+ template <typename Key>
+ void operator()(Key) const
+ {
+ save_to_assoc_attr<Key>::call(Key(), value,attr);
+ }
+ };
+
+
+ template <typename Parser>
+ struct parse_into_container_base_impl
+ {
+ private:
+
+ // 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)
+ {
+ // synthesized attribute needs to be value initialized
+ typedef typename
+ traits::container_value<Attribute>::type
+ value_type;
+ value_type val = traits::value_initialize<value_type>::call();
+
+ if (!parser.parse(first, last, context, rcontext, val))
+ return false;
+
+ // push the parsed value into our attribute
+ traits::push_back(attr, val);
+ return true;
+ }
+
+ // Parser has attribute (synthesize; Attribute is a single element fusion sequence)
+ template <typename Iterator, typename Context
+ , typename RContext, typename Attribute>
+ static bool call_synthesize_into_fusion_seq(Parser const& parser
+ , Iterator& first, Iterator const& last, Context const& context
+ , RContext& rcontext, Attribute& attr, mpl::false_ /* is_associative */)
+ {
+ static_assert(traits::has_size<Attribute, 1>::value,
+ "Expecting a single element fusion sequence");
+ return call_synthesize(parser, first, last, context, rcontext,
+ fusion::front(attr));
+ }
+
+ // Parser has attribute (synthesize; Attribute is fusion map sequence)
+ template <typename Iterator, typename Context, typename RContext, typename Attribute>
+ static bool call_synthesize_into_fusion_seq(
+ Parser const& parser
+ , Iterator& first, Iterator const& last, Context const& context
+ , RContext& rcontext, Attribute& attr, mpl::true_ /*is_associative*/)
+ {
+ using attribute_type = typename traits::attribute_of<Parser, Context>::type;
+ static_assert(traits::has_size<attribute_type, 2>::value,
+ "To parse directly into fusion map parser must produce 2 element attr");
+
+ // use type of first element of attribute as key
+ using key = typename std::remove_reference<
+ typename fusion::result_of::front<attribute_type>::type>::type;
+
+ attribute_type attr_;
+ if (!parser.parse(first, last, context, rcontext, attr_))
+ return false;
+
+ save_to_assoc_attr<key>::call(fusion::front(attr_), fusion::back(attr_), attr);
+ return true;
+ }
+
+ template <typename Iterator, typename Context, typename RContext, typename Attribute>
+ static bool call_synthesize_dispatch_by_seq(Parser const& parser
+ , Iterator& first, Iterator const& last, Context const& context
+ , RContext& rcontext, Attribute& attr, mpl::true_ /*is_sequence*/)
+ {
+ return call_synthesize_into_fusion_seq(
+ parser, first, last, context, rcontext, attr
+ , fusion::traits::is_associative<Attribute>());
+ }
+
+ template <typename Iterator, typename Context, typename RContext, typename Attribute>
+ static bool call_synthesize_dispatch_by_seq(Parser const& parser
+ , Iterator& first, Iterator const& last, Context const& context
+ , RContext& rcontext, Attribute& attr, mpl::false_ /*is_sequence*/)
+ {
+ return call_synthesize(parser, first, last, context, rcontext, attr);
+ }
+
+ // Parser has attribute (synthesize)
+ template <typename Iterator, typename Context, typename RContext, typename Attribute>
+ static bool call(Parser const& parser
+ , Iterator& first, Iterator const& last, Context const& context
+ , RContext& rcontext, Attribute& attr, mpl::true_)
+ {
+ return call_synthesize_dispatch_by_seq(parser, first, last, context, rcontext, attr
+ , fusion::traits::is_sequence<Attribute>());
+ }
+
+ // Parser has no attribute (pass unused)
+ template <typename Iterator, typename Context, typename RContext, typename Attribute>
+ static bool call(
+ Parser const& parser
+ , Iterator& first, Iterator const& last, Context const& context
+ , RContext& rcontext, Attribute& attr, mpl::false_)
+ {
+ return parser.parse(first, last, context, rcontext, unused);
+ }
+
+
+ public:
+
+ template <typename Iterator, typename Context, typename RContext, typename Attribute>
+ static bool call(Parser const& parser
+ , Iterator& first, Iterator const& last, Context const& context
+ , RContext& rcontext, Attribute& attr)
+ {
+ return call(parser, first, last, context, rcontext, attr
+ , mpl::bool_<traits::has_attribute<Parser, Context>::value>());
+ }
+ };
+
+ 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>
+ struct parser_attr_is_substitute_for_container_value
+ : traits::is_substitute<
+ typename traits::attribute_of<Parser, Context>::type
+ , typename traits::container_value<Container>::type
+ >
+ {};
+
+ template <typename Parser, typename Context, typename RContext>
+ struct parse_into_container_impl<Parser, Context, RContext,
+ typename enable_if<traits::handles_container<Parser, Context>>::type>
+ {
+ template <typename Iterator, typename Attribute>
+ static bool call(
+ Parser const& parser
+ , Iterator& first, Iterator const& last
+ , Context const& context, RContext& rcontext, Attribute& attr, mpl::true_)
+ {
+ return parse_into_container_base_impl<Parser>::call(
+ parser, first, last, context, rcontext, attr);
+ }
+
+ template <typename Iterator, typename Attribute>
+ static bool call(
+ Parser const& parser
+ , Iterator& first, Iterator const& last
+ , Context const& context, RContext& rcontext, Attribute& attr, mpl::false_)
+ {
+ return parser.parse(first, last, context, rcontext, attr);
+ }
+
+ template <typename Iterator, typename Attribute>
+ static bool call(Parser const& parser
+ , Iterator& first, Iterator const& last
+ , Context const& context, RContext& rcontext, Attribute& attr)
+ {
+ return call(parser, first, last, context, rcontext, attr,
+ parser_attr_is_substitute_for_container_value<
+ Parser, Attribute, Context, RContext>());
+ }
+ };
+
+ template <typename Parser, typename Iterator, typename Context
+ , typename RContext, typename Attribute>
+ bool parse_into_container(
+ Parser const& parser
+ , Iterator& first, Iterator const& last, Context const& context
+ , RContext& rcontext, Attribute& attr)
+ {
+ return parse_into_container_impl<Parser, Context, RContext>::call(
+ parser, first, last, context, rcontext, attr);
+ }
+
+}}}}
+
+#endif
diff --git a/boost/spirit/home/x3/core/parse.hpp b/boost/spirit/home/x3/core/parse.hpp
new file mode 100644
index 0000000000..ac36e3c7ea
--- /dev/null
+++ b/boost/spirit/home/x3/core/parse.hpp
@@ -0,0 +1,190 @@
+/*=============================================================================
+ 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(BOOST_SPIRIT_X3_PARSE_APRIL_16_2006_0442PM)
+#define BOOST_SPIRIT_X3_PARSE_APRIL_16_2006_0442PM
+
+#if defined(_MSC_VER)
+#pragma once
+#endif
+
+#include <boost/spirit/home/x3/support/context.hpp>
+#include <boost/spirit/home/x3/core/parser.hpp>
+#include <boost/spirit/home/x3/core/skip_over.hpp>
+#include <boost/concept_check.hpp>
+
+namespace boost { namespace spirit { namespace x3
+{
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename Iterator, typename Parser, typename Attribute>
+ inline bool
+ parse_main(
+ Iterator& first
+ , Iterator last
+ , Parser const& p
+ , Attribute& attr)
+ {
+ // Make sure the iterator is at least a forward_iterator. If you got a
+ // compilation error here, then you are using an input_iterator while
+ // calling this function. You need to supply at least a forward_iterator
+ // instead.
+ BOOST_CONCEPT_ASSERT((ForwardIterator<Iterator>));
+
+ // If you get an error no matching function for call to 'as_parser'
+ // here, then p is not a parser or there is no suitable conversion
+ // from p to a parser.
+ return as_parser(p).parse(first, last, unused, unused, attr);
+ }
+
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename Iterator, typename Parser, typename Attribute>
+ inline bool
+ parse(
+ Iterator& first
+ , Iterator last
+ , Parser const& p
+ , Attribute& attr)
+ {
+ return parse_main(first, last, p, attr);
+ }
+
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename Iterator, typename Parser, typename Attribute>
+ inline bool
+ parse(
+ Iterator const& first_
+ , Iterator last
+ , Parser const& p
+ , Attribute& attr)
+ {
+ Iterator first = first_;
+ return parse_main(first, last, p, attr);
+ }
+
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename Iterator, typename Parser>
+ inline bool
+ parse(
+ Iterator& first
+ , Iterator last
+ , Parser const& p)
+ {
+ return parse_main(first, last, p, unused);
+ }
+
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename Iterator, typename Parser>
+ inline bool
+ parse(
+ Iterator const& first_
+ , Iterator last
+ , Parser const& p)
+ {
+ Iterator first = first_;
+ return parse_main(first, last, p, unused);
+ }
+
+ ///////////////////////////////////////////////////////////////////////////
+ enum class skip_flag
+ {
+ post_skip, // force post-skipping in phrase_parse()
+ dont_post_skip // inhibit post-skipping in phrase_parse()
+ };
+
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename Iterator, typename Parser, typename Skipper, typename Attribute>
+ inline bool
+ phrase_parse_main(
+ Iterator& first
+ , Iterator last
+ , Parser const& p
+ , Skipper const& s
+ , Attribute& attr
+ , skip_flag post_skip = skip_flag::post_skip)
+ {
+ // Make sure the iterator is at least a forward_iterator. If you got a
+ // compilation error here, then you are using an input_iterator while
+ // calling this function. You need to supply at least a forward_iterator
+ // instead.
+ BOOST_CONCEPT_ASSERT((ForwardIterator<Iterator>));
+
+ // If you get an error no matching function for call to 'as_parser'
+ // here, for either p or s, then p or s is not a parser or there is
+ // no suitable conversion from p to a parser.
+ auto skipper_ctx = make_context<skipper_tag>(as_parser(s));
+ bool r = as_parser(p).parse(first, last, skipper_ctx, unused, attr);
+ if (post_skip == skip_flag::post_skip)
+ x3::skip_over(first, last, skipper_ctx);
+ return r;
+ }
+
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename Iterator, typename Parser, typename Skipper, typename Attribute>
+ inline bool
+ phrase_parse(
+ Iterator& first
+ , Iterator last
+ , Parser const& p
+ , Skipper const& s
+ , Attribute& attr
+ , skip_flag post_skip = skip_flag::post_skip)
+ {
+ return phrase_parse_main(first, last, p, s, attr, post_skip);
+ }
+
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename Iterator, typename Parser, typename Skipper, typename Attribute>
+ inline bool
+ phrase_parse(
+ Iterator const& first_
+ , Iterator last
+ , Parser const& p
+ , Skipper const& s
+ , Attribute& attr
+ , skip_flag post_skip = skip_flag::post_skip)
+ {
+ Iterator first = first_;
+ return phrase_parse_main(first, last, p, s, attr, post_skip);
+ }
+
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename Iterator, typename Parser, typename Skipper>
+ inline bool
+ phrase_parse(
+ Iterator& first
+ , Iterator last
+ , Parser const& p
+ , Skipper const& s
+ , skip_flag post_skip = skip_flag::post_skip)
+ {
+ return phrase_parse_main(first, last, p, s, unused, post_skip);
+ }
+
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename Iterator, typename Parser, typename Skipper>
+ inline bool
+ phrase_parse(
+ Iterator const& first_
+ , Iterator last
+ , Parser const& p
+ , Skipper const& s
+ , skip_flag post_skip = skip_flag::post_skip)
+ {
+ Iterator first = first_;
+ return phrase_parse_main(first, last, p, s, unused, post_skip);
+ }
+
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename Skipper>
+ struct phrase_parse_context
+ {
+ typedef decltype(
+ make_context<skipper_tag>(as_parser(std::declval<Skipper>())))
+ type;
+ };
+}}}
+
+#endif
diff --git a/boost/spirit/home/x3/core/parser.hpp b/boost/spirit/home/x3/core/parser.hpp
new file mode 100644
index 0000000000..bc63a7438b
--- /dev/null
+++ b/boost/spirit/home/x3/core/parser.hpp
@@ -0,0 +1,239 @@
+/*=============================================================================
+ Copyright (c) 2001-2014 Joel de Guzman
+ Copyright (c) 2013 Agustin Berge
+
+ 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(BOOST_SPIRIT_X3_PARSER_OCTOBER_16_2008_0254PM)
+#define BOOST_SPIRIT_X3_PARSER_OCTOBER_16_2008_0254PM
+
+#if defined(_MSC_VER)
+#pragma once
+#endif
+
+#include <boost/mpl/bool.hpp>
+#include <boost/type_traits/is_base_of.hpp>
+#include <boost/type_traits/remove_cv.hpp>
+#include <boost/type_traits/remove_reference.hpp>
+#include <boost/utility/declval.hpp>
+#include <boost/utility/enable_if.hpp>
+#include <boost/spirit/home/x3/support/unused.hpp>
+#include <boost/spirit/home/x3/support/context.hpp>
+#include <boost/spirit/home/x3/support/traits/has_attribute.hpp>
+#include <boost/spirit/home/x3/support/utility/sfinae.hpp>
+#include <string>
+
+#if !defined(BOOST_SPIRIT_X3_NO_RTTI)
+#include <typeinfo>
+#endif
+
+namespace boost { namespace spirit { namespace x3
+{
+ using x3::unused_type;
+ using x3::unused;
+ using x3::get;
+
+ template <typename Subject, typename Action>
+ struct action;
+
+ template <typename Subject, typename Handler>
+ struct guard;
+
+ struct parser_base {};
+ struct parser_id;
+
+ template <typename Derived>
+ struct parser : parser_base
+ {
+ typedef Derived derived_type;
+ static bool const handles_container = false;
+ static bool const is_pass_through_unary = false;
+ static bool const has_action = false;
+
+ Derived const& derived() const
+ {
+ return *static_cast<Derived const*>(this);
+ }
+
+ template <typename Action>
+ action<Derived, Action>
+ operator[](Action f) const
+ {
+ return action<Derived, Action>(this->derived(), f);
+ }
+
+ template <typename Handler>
+ guard<Derived, Handler>
+ on_error(Handler f) const
+ {
+ return guard<Derived, Handler>(this->derived(), f);
+ }
+ };
+
+ struct unary_category;
+ struct binary_category;
+
+ template <typename Subject, typename Derived>
+ struct unary_parser : parser<Derived>
+ {
+ typedef unary_category category;
+ typedef Subject subject_type;
+ static bool const has_action = Subject::has_action;
+
+ unary_parser(Subject subject)
+ : subject(subject) {}
+
+ unary_parser const& get_unary() const { return *this; }
+
+ Subject subject;
+ };
+
+ template <typename Left, typename Right, typename Derived>
+ struct binary_parser : parser<Derived>
+ {
+ typedef binary_category category;
+ typedef Left left_type;
+ typedef Right right_type;
+ static bool const has_action =
+ left_type::has_action || right_type::has_action;
+
+ binary_parser(Left left, Right right)
+ : left(left), right(right) {}
+
+ binary_parser const& get_binary() const { return *this; }
+
+ Left left;
+ Right right;
+ };
+
+ ///////////////////////////////////////////////////////////////////////////
+ // as_parser: convert a type, T, into a parser.
+ ///////////////////////////////////////////////////////////////////////////
+ namespace extension
+ {
+ namespace detail
+ {
+ namespace as_parser_guard
+ {
+ void as_spirit_parser(...);
+
+ template<typename T, typename R =
+ decltype(as_spirit_parser(boost::declval<T const&>()))>
+ struct deduce_as_parser
+ {
+ typedef R type;
+ typedef typename
+ boost::remove_cv<
+ typename boost::remove_reference<R>::type
+ >::type
+ value_type;
+
+ static type call(T const& v)
+ {
+ return as_spirit_parser(v);
+ }
+ };
+ template<typename T>
+ struct deduce_as_parser<T, void>
+ {};
+ }
+ using as_parser_guard::deduce_as_parser;
+ }
+
+ template <typename T, typename Enable = void>
+ struct as_parser : detail::deduce_as_parser<T> {};
+
+ template <>
+ struct as_parser<unused_type>
+ {
+ typedef unused_type type;
+ typedef unused_type value_type;
+ static type call(unused_type)
+ {
+ return unused;
+ }
+ };
+
+ template <typename Derived>
+ struct as_parser<Derived
+ , typename enable_if<is_base_of<parser_base, Derived>>::type>
+ {
+ typedef Derived const& type;
+ typedef Derived value_type;
+ static type call(Derived const& p)
+ {
+ return p;
+ }
+ };
+
+ template <typename Derived>
+ struct as_parser<parser<Derived>>
+ {
+ typedef Derived const& type;
+ typedef Derived value_type;
+ static type call(parser<Derived> const& p)
+ {
+ return p.derived();
+ }
+ };
+ }
+
+ template <typename T>
+ inline typename extension::as_parser<T>::type
+ as_parser(T const& x)
+ {
+ return extension::as_parser<T>::call(x);
+ }
+
+ template <typename Derived>
+ inline Derived const&
+ as_parser(parser<Derived> const& p)
+ {
+ return p.derived();
+ }
+
+ ///////////////////////////////////////////////////////////////////////////
+ // The main what function
+ //
+ // Note: unlike Spirit2, spirit parsers are no longer required to have a
+ // "what" member function. In X3, we specialize the get_info struct
+ // below where needed. If a specialization is not provided, the default
+ // below will be used. The default "what" result will be the typeid
+ // name of the parser if BOOST_SPIRIT_X3_NO_RTTI is not defined, otherwise
+ // "undefined"
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename Parser, typename Enable = void>
+ struct get_info
+ {
+ typedef std::string result_type;
+ std::string operator()(Parser const&) const
+ {
+#if !defined(BOOST_SPIRIT_X3_NO_RTTI)
+ return typeid(Parser).name();
+#else
+ return "undefined";
+#endif
+ }
+ };
+
+ template <typename Parser>
+ std::string what(Parser const& p)
+ {
+ return get_info<Parser>()(p);
+ }
+}}}
+
+namespace boost { namespace spirit { namespace x3 { namespace traits
+{
+ template <typename Subject, typename Derived, typename Context>
+ struct has_attribute<x3::unary_parser<Subject, Derived>, Context>
+ : has_attribute<Subject, Context> {};
+
+ template <typename Left, typename Right, typename Derived, typename Context>
+ struct has_attribute<x3::binary_parser<Left, Right, Derived>, Context>
+ : mpl::bool_<has_attribute<Left, Context>::value ||
+ has_attribute<Right, Context>::value> {};
+}}}}
+
+#endif
diff --git a/boost/spirit/home/x3/core/proxy.hpp b/boost/spirit/home/x3/core/proxy.hpp
new file mode 100644
index 0000000000..1a0ade59a8
--- /dev/null
+++ b/boost/spirit/home/x3/core/proxy.hpp
@@ -0,0 +1,52 @@
+/*=============================================================================
+ 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(BOOST_SPIRIT_X3_PROXY_FEBRUARY_1_2013_0211PM)
+#define BOOST_SPIRIT_X3_PROXY_FEBRUARY_1_2013_0211PM
+
+#if defined(_MSC_VER)
+#pragma once
+#endif
+
+#include <boost/spirit/home/x3/core/parser.hpp>
+#include <boost/spirit/home/x3/core/detail/parse_into_container.hpp>
+#include <boost/spirit/home/x3/support/traits/attribute_category.hpp>
+
+namespace boost { namespace spirit { namespace x3
+{
+ template <typename Subject, typename Derived>
+ struct proxy : unary_parser<Subject, Derived>
+ {
+ static bool const is_pass_through_unary = true;
+
+ proxy(Subject const& subject)
+ : unary_parser<Subject, Derived>(subject) {}
+
+ // Overload this when appropriate. The proxy parser will pick up
+ // the most derived overload.
+ template <typename Iterator, typename Context
+ , typename RuleContext, typename Attribute, typename Category>
+ bool parse_subject(Iterator& first, Iterator const& last
+ , Context const& context, RuleContext& rcontext, Attribute& attr, Category) const
+ {
+ this->subject.parse(first, last, context, rcontext, attr);
+ return true;
+ }
+
+ // Main entry point.
+ template <typename Iterator, typename Context
+ , typename RuleContext, typename Attribute>
+ bool parse(Iterator& first, Iterator const& last
+ , Context const& context, RuleContext& rcontext, Attribute& attr) const
+ {
+ return this->derived().parse_subject(first, last, context, rcontext, attr
+ , typename traits::attribute_category<Attribute>::type());
+ }
+ };
+
+}}}
+
+#endif
diff --git a/boost/spirit/home/x3/core/skip_over.hpp b/boost/spirit/home/x3/core/skip_over.hpp
new file mode 100644
index 0000000000..643ddb1f5b
--- /dev/null
+++ b/boost/spirit/home/x3/core/skip_over.hpp
@@ -0,0 +1,104 @@
+/*=============================================================================
+ 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(BOOST_SPIRIT_X3_SKIP_APRIL_16_2006_0625PM)
+#define BOOST_SPIRIT_X3_SKIP_APRIL_16_2006_0625PM
+
+#if defined(_MSC_VER)
+#pragma once
+#endif
+
+#include <boost/spirit/home/x3/support/unused.hpp>
+#include <boost/spirit/home/x3/support/context.hpp>
+#include <boost/spirit/home/x3/support/traits/attribute_category.hpp>
+#include <boost/mpl/bool.hpp>
+#include <boost/mpl/not.hpp>
+#include <boost/type_traits/remove_cv.hpp>
+#include <boost/type_traits/remove_reference.hpp>
+#include <boost/utility/declval.hpp>
+
+namespace boost { namespace spirit { namespace x3
+{
+ ///////////////////////////////////////////////////////////////////////////
+ // Move the /first/ iterator to the first non-matching position
+ // given a skip-parser. The function is a no-op if unused_type or
+ // unused_skipper is passed as the skip-parser.
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename Skipper>
+ struct unused_skipper : unused_type
+ {
+ unused_skipper(Skipper const& skipper)
+ : skipper(skipper) {}
+ Skipper const& skipper;
+ };
+
+ namespace detail
+ {
+ template <typename Skipper>
+ struct is_unused_skipper
+ : mpl::false_ {};
+
+ template <typename Skipper>
+ struct is_unused_skipper<unused_skipper<Skipper>>
+ : mpl::true_ {};
+
+ template <>
+ struct is_unused_skipper<unused_type>
+ : mpl::true_ {};
+
+ template <typename Skipper>
+ inline Skipper const&
+ get_unused_skipper(Skipper const& skipper)
+ {
+ return skipper;
+ }
+ template <typename Skipper>
+ inline Skipper const&
+ get_unused_skipper(unused_skipper<Skipper> const& unused_skipper)
+ {
+ return unused_skipper.skipper;
+ }
+
+ template <typename Iterator, typename Skipper>
+ inline void skip_over(
+ Iterator& first, Iterator const& last, Skipper const& skipper)
+ {
+ while (first != last && skipper.parse(first, last, unused, unused, unused))
+ /***/;
+ }
+
+ template <typename Iterator>
+ inline void skip_over(Iterator&, Iterator const&, unused_type)
+ {
+ }
+
+ template <typename Iterator, typename Skipper>
+ inline void skip_over(
+ Iterator&, Iterator const&, unused_skipper<Skipper> const&)
+ {
+ }
+ }
+
+ // this tag is used to find the skipper from the context
+ struct skipper_tag;
+
+ template <typename Context>
+ struct has_skipper
+ : mpl::not_<detail::is_unused_skipper<
+ typename remove_cv<typename remove_reference<
+ decltype(x3::get<skipper_tag>(boost::declval<Context>()))
+ >::type>::type
+ >> {};
+
+ template <typename Iterator, typename Context>
+ inline void skip_over(
+ Iterator& first, Iterator const& last, Context const& context)
+ {
+ detail::skip_over(first, last, x3::get<skipper_tag>(context));
+ }
+}}}
+
+#endif
diff --git a/boost/spirit/home/x3/directive.hpp b/boost/spirit/home/x3/directive.hpp
new file mode 100644
index 0000000000..81f7a8536a
--- /dev/null
+++ b/boost/spirit/home/x3/directive.hpp
@@ -0,0 +1,28 @@
+/*=============================================================================
+ 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(BOOST_SPIRIT_X3_DIRECTIVE_FEBRUARY_05_2007_0313PM)
+#define BOOST_SPIRIT_X3_DIRECTIVE_FEBRUARY_05_2007_0313PM
+
+#if defined(_MSC_VER)
+#pragma once
+#endif
+
+//~ #include <boost/spirit/home/x3/directive/as.hpp>
+//~ #include <boost/spirit/home/x3/directive/encoding.hpp>
+//~ #include <boost/spirit/home/x3/directive/hold.hpp>
+#include <boost/spirit/home/x3/directive/expect.hpp>
+#include <boost/spirit/home/x3/directive/lexeme.hpp>
+#include <boost/spirit/home/x3/directive/no_skip.hpp>
+//~ #include <boost/spirit/home/x3/directive/matches.hpp>
+//~ #include <boost/spirit/home/x3/directive/no_case.hpp>
+#include <boost/spirit/home/x3/directive/omit.hpp>
+#include <boost/spirit/home/x3/directive/raw.hpp>
+//~ #include <boost/spirit/home/x3/directive/repeat.hpp>
+#include <boost/spirit/home/x3/directive/skip.hpp>
+#include <boost/spirit/home/x3/directive/with.hpp>
+
+#endif
diff --git a/boost/spirit/home/x3/directive/expect.hpp b/boost/spirit/home/x3/directive/expect.hpp
new file mode 100644
index 0000000000..4e59ce5dca
--- /dev/null
+++ b/boost/spirit/home/x3/directive/expect.hpp
@@ -0,0 +1,80 @@
+/*=============================================================================
+ 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_EXPECT_MARCH_16_2012_1024PM)
+#define SPIRIT_EXPECT_MARCH_16_2012_1024PM
+
+#if defined(_MSC_VER)
+#pragma once
+#endif
+
+#include <boost/spirit/home/x3/support/context.hpp>
+#include <boost/spirit/home/x3/core/parser.hpp>
+#include <boost/throw_exception.hpp>
+#include <stdexcept>
+
+namespace boost { namespace spirit { namespace x3
+{
+ template <typename Iterator>
+ struct expectation_failure : std::runtime_error
+ {
+ public:
+
+ expectation_failure(Iterator where, std::string const& which)
+ : std::runtime_error("boost::spirit::x3::expectation_failure")
+ , where_(where), which_(which)
+ {}
+ ~expectation_failure() throw() {}
+
+ std::string which() const { return which_; }
+ Iterator const& where() const { return where_; }
+
+ private:
+
+ Iterator where_;
+ std::string which_;
+ };
+
+ template <typename Subject>
+ struct expect_directive : unary_parser<Subject, expect_directive<Subject>>
+ {
+ typedef unary_parser<Subject, expect_directive<Subject> > base_type;
+ static bool const is_pass_through_unary = true;
+
+ expect_directive(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
+ {
+ bool r = this->subject.parse(first, last, context, rcontext, attr);
+
+ if (!r)
+ {
+ boost::throw_exception(
+ expectation_failure<Iterator>(
+ first, what(this->subject)));
+ }
+ return r;
+ }
+ };
+
+ struct expect_gen
+ {
+ template <typename Subject>
+ expect_directive<typename extension::as_parser<Subject>::value_type>
+ operator[](Subject const& subject) const
+ {
+ return {as_parser(subject)};
+ }
+ };
+
+ expect_gen const expect = expect_gen();
+}}}
+
+#endif
diff --git a/boost/spirit/home/x3/directive/lexeme.hpp b/boost/spirit/home/x3/directive/lexeme.hpp
new file mode 100644
index 0000000000..e5104272f9
--- /dev/null
+++ b/boost/spirit/home/x3/directive/lexeme.hpp
@@ -0,0 +1,84 @@
+/*=============================================================================
+ 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_LEXEME_MARCH_24_2007_0802AM)
+#define SPIRIT_LEXEME_MARCH_24_2007_0802AM
+
+#if defined(_MSC_VER)
+#pragma once
+#endif
+
+#include <boost/spirit/home/x3/support/context.hpp>
+#include <boost/spirit/home/x3/support/unused.hpp>
+#include <boost/spirit/home/x3/core/skip_over.hpp>
+#include <boost/spirit/home/x3/core/parser.hpp>
+#include <boost/type_traits/remove_reference.hpp>
+#include <boost/utility/enable_if.hpp>
+
+namespace boost { namespace spirit { namespace x3
+{
+ template <typename Subject>
+ struct lexeme_directive : unary_parser<Subject, lexeme_directive<Subject>>
+ {
+ typedef unary_parser<Subject, lexeme_directive<Subject> > base_type;
+ static bool const is_pass_through_unary = true;
+ static bool const handles_container = Subject::handles_container;
+
+ lexeme_directive(Subject const& subject)
+ : base_type(subject) {}
+
+ template <typename Iterator, typename Context
+ , typename RContext, typename Attribute>
+ typename enable_if<has_skipper<Context>, bool>::type
+ parse(Iterator& first, Iterator const& last
+ , Context const& context, RContext& rcontext, Attribute& attr) const
+ {
+ x3::skip_over(first, last, context);
+ auto const& skipper = x3::get<skipper_tag>(context);
+
+ typedef unused_skipper<
+ typename remove_reference<decltype(skipper)>::type>
+ unused_skipper_type;
+ unused_skipper_type unused_skipper(skipper);
+
+ return this->subject.parse(
+ first, last
+ , make_context<skipper_tag>(unused_skipper, context)
+ , rcontext
+ , attr);
+ }
+
+ template <typename Iterator, typename Context
+ , typename RContext, typename Attribute>
+ typename disable_if<has_skipper<Context>, bool>::type
+ parse(Iterator& first, Iterator const& last
+ , Context const& context, RContext& rcontext, Attribute& attr) const
+ {
+ // no need to pre-skip if skipper is unused
+ //- x3::skip_over(first, last, context);
+
+ return this->subject.parse(
+ first, last
+ , context
+ , rcontext
+ , attr);
+ }
+ };
+
+ struct lexeme_gen
+ {
+ template <typename Subject>
+ lexeme_directive<typename extension::as_parser<Subject>::value_type>
+ operator[](Subject const& subject) const
+ {
+ return {as_parser(subject)};
+ }
+ };
+
+ lexeme_gen const lexeme = lexeme_gen();
+}}}
+
+#endif
diff --git a/boost/spirit/home/x3/directive/no_skip.hpp b/boost/spirit/home/x3/directive/no_skip.hpp
new file mode 100644
index 0000000000..14dee4d85c
--- /dev/null
+++ b/boost/spirit/home/x3/directive/no_skip.hpp
@@ -0,0 +1,82 @@
+/*=============================================================================
+ Copyright (c) 2001-2014 Joel de Guzman
+ Copyright (c) 2001-2011 Hartmut Kaiser
+ Copyright (c) 2013 Agustin Berge
+
+ 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_NO_SKIP_JAN_16_2010_0802PM)
+#define SPIRIT_NO_SKIP_JAN_16_2010_0802PM
+
+#if defined(_MSC_VER)
+#pragma once
+#endif
+
+#include <boost/spirit/home/x3/support/context.hpp>
+#include <boost/spirit/home/x3/support/unused.hpp>
+#include <boost/spirit/home/x3/core/skip_over.hpp>
+#include <boost/spirit/home/x3/core/parser.hpp>
+#include <boost/type_traits/remove_reference.hpp>
+#include <boost/utility/enable_if.hpp>
+
+namespace boost { namespace spirit { namespace x3
+{
+ // same as lexeme[], but does not pre-skip
+ template <typename Subject>
+ struct no_skip_directive : unary_parser<Subject, no_skip_directive<Subject>>
+ {
+ typedef unary_parser<Subject, no_skip_directive<Subject> > base_type;
+ static bool const is_pass_through_unary = true;
+ static bool const handles_container = Subject::handles_container;
+
+ no_skip_directive(Subject const& subject)
+ : base_type(subject) {}
+
+ template <typename Iterator, typename Context
+ , typename RContext, typename Attribute>
+ typename enable_if<has_skipper<Context>, bool>::type
+ parse(Iterator& first, Iterator const& last
+ , Context const& context, RContext& rcontext, Attribute& attr) const
+ {
+ auto const& skipper = x3::get<skipper_tag>(context);
+
+ typedef unused_skipper<
+ typename remove_reference<decltype(skipper)>::type>
+ unused_skipper_type;
+ unused_skipper_type unused_skipper(skipper);
+
+ return this->subject.parse(
+ first, last
+ , make_context<skipper_tag>(unused_skipper, context)
+ , rcontext
+ , attr);
+ }
+ template <typename Iterator, typename Context
+ , typename RContext, typename Attribute>
+ typename disable_if<has_skipper<Context>, bool>::type
+ parse(Iterator& first, Iterator const& last
+ , Context const& context, RContext& rcontext, Attribute& attr) const
+ {
+ return this->subject.parse(
+ first, last
+ , context
+ , rcontext
+ , attr);
+ }
+ };
+
+ struct no_skip_gen
+ {
+ template <typename Subject>
+ no_skip_directive<typename extension::as_parser<Subject>::value_type>
+ operator[](Subject const& subject) const
+ {
+ return {as_parser(subject)};
+ }
+ };
+
+ no_skip_gen const no_skip = no_skip_gen();
+}}}
+
+#endif
diff --git a/boost/spirit/home/x3/directive/omit.hpp b/boost/spirit/home/x3/directive/omit.hpp
new file mode 100644
index 0000000000..43ebd49aaf
--- /dev/null
+++ b/boost/spirit/home/x3/directive/omit.hpp
@@ -0,0 +1,55 @@
+/*=============================================================================
+ 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_OMIT_MARCH_24_2007_0802AM)
+#define SPIRIT_OMIT_MARCH_24_2007_0802AM
+
+#if defined(_MSC_VER)
+#pragma once
+#endif
+
+#include <boost/spirit/home/x3/support/unused.hpp>
+#include <boost/spirit/home/x3/core/parser.hpp>
+
+namespace boost { namespace spirit { namespace x3
+{
+ ///////////////////////////////////////////////////////////////////////////
+ // omit_directive forces the attribute of subject parser
+ // to be unused_type
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename Subject>
+ struct omit_directive : unary_parser<Subject, omit_directive<Subject>>
+ {
+ typedef unary_parser<Subject, omit_directive<Subject> > base_type;
+ typedef unused_type attribute_type;
+ static bool const has_attribute = false;
+
+ typedef Subject subject_type;
+ omit_directive(Subject const& subject)
+ : base_type(subject) {}
+
+ template <typename Iterator, typename Context, typename RContext>
+ bool parse(Iterator& first, Iterator const& last
+ , Context const& context, RContext& rcontext, unused_type) const
+ {
+ return this->subject.parse(first, last, context, rcontext, unused);
+ }
+ };
+
+ struct omit_gen
+ {
+ template <typename Subject>
+ omit_directive<typename extension::as_parser<Subject>::value_type>
+ operator[](Subject const& subject) const
+ {
+ return {as_parser(subject)};
+ }
+ };
+
+ omit_gen const omit = omit_gen();
+}}}
+
+#endif
diff --git a/boost/spirit/home/x3/directive/raw.hpp b/boost/spirit/home/x3/directive/raw.hpp
new file mode 100644
index 0000000000..e6bcd9a3a1
--- /dev/null
+++ b/boost/spirit/home/x3/directive/raw.hpp
@@ -0,0 +1,70 @@
+/*=============================================================================
+ Copyright (c) 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_X3_RAW_APRIL_9_2007_0912AM)
+#define SPIRIT_X3_RAW_APRIL_9_2007_0912AM
+
+#include <boost/spirit/home/x3/core/skip_over.hpp>
+#include <boost/spirit/home/x3/core/parser.hpp>
+#include <boost/spirit/home/x3/support/traits/move_to.hpp>
+#include <boost/range/iterator_range.hpp>
+
+namespace boost { namespace spirit { namespace x3
+{
+ // this is a pseudo attribute type indicating that the parser wants the
+ // iterator range pointing to the [first, last) matching characters from
+ // the input iterators.
+ struct raw_attribute_type {};
+
+ template <typename Subject>
+ struct raw_directive : unary_parser<Subject, raw_directive<Subject>>
+ {
+ typedef unary_parser<Subject, raw_directive<Subject> > base_type;
+ typedef raw_attribute_type attribute_type;
+ static bool const handles_container = Subject::handles_container;
+ typedef Subject subject_type;
+
+ raw_directive(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
+ {
+ x3::skip_over(first, last, context);
+ Iterator i = first;
+ if (this->subject.parse(i, last, context, rcontext, unused))
+ {
+ traits::move_to(first, i, attr);
+ first = i;
+ return true;
+ }
+ return false;
+ }
+
+ template <typename Iterator, typename Context, typename RContext>
+ bool parse(Iterator& first, Iterator const& last
+ , Context const& context, RContext& rcontext, unused_type) const
+ {
+ return this->subject.parse(first, last, context, rcontext, unused);
+ }
+ };
+
+ struct raw_gen
+ {
+ template <typename Subject>
+ raw_directive<typename extension::as_parser<Subject>::value_type>
+ operator[](Subject const& subject) const
+ {
+ return {as_parser(subject)};
+ }
+ };
+
+ raw_gen const raw = raw_gen();
+}}}
+
+#endif
diff --git a/boost/spirit/home/x3/directive/skip.hpp b/boost/spirit/home/x3/directive/skip.hpp
new file mode 100644
index 0000000000..c880720791
--- /dev/null
+++ b/boost/spirit/home/x3/directive/skip.hpp
@@ -0,0 +1,124 @@
+/*=============================================================================
+ Copyright (c) 2001-2014 Joel de Guzman
+ Copyright (c) 2013 Agustin Berge
+
+ 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_SKIP_JANUARY_26_2008_0422PM)
+#define SPIRIT_SKIP_JANUARY_26_2008_0422PM
+
+#if defined(_MSC_VER)
+#pragma once
+#endif
+
+#include <boost/spirit/home/x3/support/context.hpp>
+#include <boost/spirit/home/x3/support/unused.hpp>
+#include <boost/spirit/home/x3/core/skip_over.hpp>
+#include <boost/spirit/home/x3/core/parser.hpp>
+#include <boost/utility/enable_if.hpp>
+
+namespace boost { namespace spirit { namespace x3
+{
+ template <typename Subject>
+ struct reskip_directive : unary_parser<Subject, reskip_directive<Subject>>
+ {
+ typedef unary_parser<Subject, reskip_directive<Subject>> base_type;
+ static bool const is_pass_through_unary = true;
+ static bool const handles_container = Subject::handles_container;
+
+ reskip_directive(Subject const& subject)
+ : base_type(subject) {}
+
+ template <typename Iterator, typename Context
+ , typename RContext, typename Attribute>
+ typename disable_if<has_skipper<Context>, bool>::type
+ parse(Iterator& first, Iterator const& last
+ , Context const& context, RContext& rcontext, Attribute& attr) const
+ {
+ auto const& skipper =
+ detail::get_unused_skipper(x3::get<skipper_tag>(context));
+
+ return this->subject.parse(
+ first, last
+ , make_context<skipper_tag>(skipper, context)
+ , rcontext
+ , attr);
+ }
+ template <typename Iterator, typename Context
+ , typename RContext, typename Attribute>
+ typename enable_if<has_skipper<Context>, bool>::type
+ parse(Iterator& first, Iterator const& last
+ , Context const& context, RContext& rcontext, Attribute& attr) const
+ {
+ return this->subject.parse(
+ first, last
+ , context
+ , rcontext
+ , attr);
+ }
+ };
+
+ template <typename Subject, typename Skipper>
+ struct skip_directive : unary_parser<Subject, skip_directive<Subject, Skipper>>
+ {
+ typedef unary_parser<Subject, skip_directive<Subject, Skipper>> base_type;
+ static bool const is_pass_through_unary = true;
+ static bool const handles_container = Subject::handles_container;
+
+ skip_directive(Subject const& subject, Skipper const& skipper)
+ : base_type(subject)
+ , skipper(skipper)
+ {}
+
+ 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 this->subject.parse(
+ first, last
+ , make_context<skipper_tag>(skipper, context)
+ , rcontext
+ , attr);
+ }
+
+ Skipper const skipper;
+ };
+
+ struct reskip_gen
+ {
+ template <typename Skipper>
+ struct skip_gen
+ {
+ explicit skip_gen(Skipper const& skipper)
+ : skipper_(skipper) {}
+
+ template <typename Subject>
+ skip_directive<typename extension::as_parser<Subject>::value_type, Skipper>
+ operator[](Subject const& subject) const
+ {
+ return {as_parser(subject), skipper_};
+ }
+
+ Skipper skipper_;
+ };
+
+ template <typename Skipper>
+ skip_gen<Skipper> const operator()(Skipper const& skipper) const
+ {
+ return skip_gen<Skipper>(skipper);
+ }
+
+ template <typename Subject>
+ reskip_directive<typename extension::as_parser<Subject>::value_type>
+ operator[](Subject const& subject) const
+ {
+ return {as_parser(subject)};
+ }
+ };
+
+ reskip_gen const skip = reskip_gen();
+}}}
+
+#endif
diff --git a/boost/spirit/home/x3/directive/with.hpp b/boost/spirit/home/x3/directive/with.hpp
new file mode 100644
index 0000000000..cc6c442a34
--- /dev/null
+++ b/boost/spirit/home/x3/directive/with.hpp
@@ -0,0 +1,107 @@
+/*=============================================================================
+ Copyright (c) 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_X3_WITH_MAY_02_2014_0749AM)
+#define SPIRIT_X3_WITH_MAY_02_2014_0749AM
+
+#include <boost/spirit/home/x3/support/unused.hpp>
+#include <boost/spirit/home/x3/core/parser.hpp>
+
+namespace boost { namespace spirit { namespace x3
+{
+ ///////////////////////////////////////////////////////////////////////////
+ // with directive injects a value into the context prior to parsing.
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename Subject, typename Derived, typename T>
+ struct with_value_holder
+ : unary_parser<Subject, Derived>
+ {
+ typedef unary_parser<Subject, Derived> base_type;
+ mutable T val;
+ with_value_holder(Subject const& subject, T const& val)
+ : base_type(subject)
+ , val(val) {}
+ };
+
+ template <typename Subject, typename Derived, typename T>
+ struct with_value_holder<Subject, Derived, T const>
+ : unary_parser<Subject, Derived>
+ {
+ typedef unary_parser<Subject, Derived> base_type;
+ T val;
+ with_value_holder(Subject const& subject, T const& val)
+ : base_type(subject)
+ , val(val) {}
+ };
+
+ template <typename Subject, typename ID, typename T>
+ struct with_directive
+ : with_value_holder<Subject, with_directive<Subject, ID, T>, T>
+ {
+ typedef with_value_holder<Subject, with_directive<Subject, ID, T>, T> base_type;
+ static bool const is_pass_through_unary = true;
+ static bool const handles_container = Subject::handles_container;
+
+ typedef Subject subject_type;
+
+ with_directive(Subject const& subject, T const& val)
+ : base_type(subject, val) {}
+
+ 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 this->subject.parse(
+ first, last
+ , make_context<ID>(this->val, context)
+ , rcontext
+ , attr);
+ }
+ };
+
+ template <typename ID, typename T, typename NextContext = unused_type>
+ struct with_context
+ {
+ typedef context<ID, T, NextContext> type;
+ };
+
+ template <typename ID, typename T>
+ struct with_context<ID, T, unused_type>
+ {
+ typedef context<ID, T> const type;
+ };
+
+ template <typename ID, typename T>
+ struct with_gen
+ {
+ T& val;
+
+ with_gen(T& val)
+ : val(val) {}
+
+ template <typename Subject>
+ with_directive<typename extension::as_parser<Subject>::value_type, ID, T>
+ operator[](Subject const& subject) const
+ {
+ return {as_parser(subject), val};
+ }
+ };
+
+ template <typename ID, typename T>
+ inline with_gen<ID, T> with(T& val)
+ {
+ return with_gen<ID, T>{val};
+ }
+
+ template <typename ID, typename T>
+ inline with_gen<ID, T const> with(T const& val)
+ {
+ return with_gen<ID, T const>{val};
+ }
+}}}
+
+#endif
diff --git a/boost/spirit/home/x3/extensions.hpp b/boost/spirit/home/x3/extensions.hpp
new file mode 100644
index 0000000000..a40b719c35
--- /dev/null
+++ b/boost/spirit/home/x3/extensions.hpp
@@ -0,0 +1,18 @@
+/*=============================================================================
+ Copyright (c) 2001-2014 Joel de Guzman
+ Copyright (c) 2014 Thomas Bernard
+ Copyright (c) 2014 Lee Clagett
+
+ 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(BOOST_SPIRIT_X3_EXTENSIONS_APRIL_6_2014_1421PM)
+#define BOOST_SPIRIT_X3_EXTENSIONS_APRIL_6_2014_1421PM
+
+#if defined(_MSC_VER)
+#pragma once
+#endif
+
+#include <boost/spirit/home/x3/extensions/seek.hpp>
+
+#endif
diff --git a/boost/spirit/home/x3/extensions/seek.hpp b/boost/spirit/home/x3/extensions/seek.hpp
new file mode 100644
index 0000000000..bcd9544794
--- /dev/null
+++ b/boost/spirit/home/x3/extensions/seek.hpp
@@ -0,0 +1,70 @@
+/*=============================================================================
+ Copyright (c) 2011 Jamboree
+ Copyright (c) 2014 Lee Clagett
+
+ 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(BOOST_SPIRIT_X3_SEEK_APRIL_13_2014_1920PM)
+#define BOOST_SPIRIT_X3_SEEK_APRIL_13_2014_1920PM
+
+#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 seek_directive : unary_parser<Subject, seek_directive<Subject>>
+ {
+ typedef unary_parser<Subject, seek_directive<Subject>> base_type;
+ static bool const is_pass_through_unary = true;
+ static bool const handles_container = Subject::handles_container;
+
+ seek_directive(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 current(first);
+ for (/**/; current != last; ++current)
+ {
+ if (this->subject.parse(current, last, context, rcontext, attr))
+ {
+ first = current;
+ return true;
+ }
+ }
+
+ // Test for when subjects match on input empty. Example:
+ // comment = "//" >> seek[eol | eoi]
+ if (this->subject.parse(current, last, context, rcontext, attr))
+ {
+ first = current;
+ return true;
+ }
+
+ return false;
+ }
+ };
+
+ struct seek_gen
+ {
+ template<typename Subject>
+ seek_directive<typename extension::as_parser<Subject>::value_type>
+ operator[](Subject const& subject) const
+ {
+ return {as_parser(subject)};
+ }
+ };
+
+ seek_gen const seek = seek_gen();
+}}}
+
+#endif
diff --git a/boost/spirit/home/x3/nonterminal.hpp b/boost/spirit/home/x3/nonterminal.hpp
new file mode 100644
index 0000000000..1e589bd903
--- /dev/null
+++ b/boost/spirit/home/x3/nonterminal.hpp
@@ -0,0 +1,19 @@
+/*=============================================================================
+ 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(BOOST_SPIRIT_X3_NONTERMINAL_FEBRUARY_12_2007_1018AM)
+#define BOOST_SPIRIT_X3_NONTERMINAL_FEBRUARY_12_2007_1018AM
+
+#if defined(_MSC_VER)
+#pragma once
+#endif
+
+#include <boost/spirit/home/x3/nonterminal/rule.hpp>
+//~ #include <boost/spirit/home/x3/nonterminal/error_handler.hpp>
+//~ #include <boost/spirit/home/x3/nonterminal/debug_handler.hpp>
+//~ #include <boost/spirit/home/x3/nonterminal/success_handler.hpp>
+
+#endif
diff --git a/boost/spirit/home/x3/nonterminal/debug_handler_state.hpp b/boost/spirit/home/x3/nonterminal/debug_handler_state.hpp
new file mode 100644
index 0000000000..800023f013
--- /dev/null
+++ b/boost/spirit/home/x3/nonterminal/debug_handler_state.hpp
@@ -0,0 +1,24 @@
+/*=============================================================================
+ 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(BOOST_SPIRIT_X3_DEBUG_HANDLER_STATE_APR_21_2010_0733PM)
+#define BOOST_SPIRIT_X3_DEBUG_HANDLER_STATE_APR_21_2010_0733PM
+
+#if defined(_MSC_VER)
+#pragma once
+#endif
+
+namespace boost { namespace spirit { namespace x3
+{
+ enum debug_handler_state
+ {
+ pre_parse
+ , successful_parse
+ , failed_parse
+ };
+}}}
+
+#endif
diff --git a/boost/spirit/home/x3/nonterminal/detail/rule.hpp b/boost/spirit/home/x3/nonterminal/detail/rule.hpp
new file mode 100644
index 0000000000..54e2eef234
--- /dev/null
+++ b/boost/spirit/home/x3/nonterminal/detail/rule.hpp
@@ -0,0 +1,385 @@
+/*=============================================================================
+ 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(BOOST_SPIRIT_X3_DETAIL_RULE_JAN_08_2012_0326PM)
+#define BOOST_SPIRIT_X3_DETAIL_RULE_JAN_08_2012_0326PM
+
+#if defined(_MSC_VER)
+#pragma once
+#endif
+
+#include <boost/spirit/home/x3/core/parser.hpp>
+#include <boost/spirit/home/x3/support/traits/make_attribute.hpp>
+#include <boost/spirit/home/x3/support/utility/sfinae.hpp>
+#include <boost/spirit/home/x3/nonterminal/detail/transform_attribute.hpp>
+#include <boost/utility/addressof.hpp>
+
+#if defined(BOOST_SPIRIT_X3_DEBUG)
+#include <boost/spirit/home/x3/nonterminal/simple_trace.hpp>
+#endif
+
+namespace boost { namespace spirit { namespace x3
+{
+ template <typename ID>
+ struct identity;
+
+ template <typename ID, typename Attribute = unused_type>
+ struct rule;
+
+ struct parse_pass_context_tag;
+
+ namespace detail
+ {
+ // we use this so we can detect if the default parse_rule
+ // is the being called.
+ struct default_parse_rule_result
+ {
+ default_parse_rule_result(bool r)
+ : r(r) {}
+ operator bool() const { return r; }
+ bool r;
+ };
+ }
+
+ // default parse_rule implementation
+ template <typename ID, typename Attribute, typename Iterator
+ , typename Context, typename ActualAttribute>
+ inline detail::default_parse_rule_result
+ parse_rule(
+ rule<ID, Attribute> rule_
+ , Iterator& first, Iterator const& last
+ , Context const& context, ActualAttribute& attr);
+}}}
+
+namespace boost { namespace spirit { namespace x3 { namespace detail
+{
+#if defined(BOOST_SPIRIT_X3_DEBUG)
+ template <typename Iterator, typename Attribute>
+ struct context_debug
+ {
+ context_debug(
+ char const* rule_name
+ , Iterator const& first, Iterator const& last
+ , Attribute const& attr
+ , bool const& ok_parse //was parse successful?
+ )
+ : ok_parse(ok_parse), rule_name(rule_name)
+ , first(first), last(last)
+ , attr(attr)
+ , f(detail::get_simple_trace())
+ {
+ f(first, last, attr, pre_parse, rule_name);
+ }
+
+ ~context_debug()
+ {
+ auto status = ok_parse ? successful_parse : failed_parse ;
+ f(first, last, attr, status, rule_name);
+ }
+
+ bool const& ok_parse;
+ char const* rule_name;
+ Iterator const& first;
+ Iterator const& last;
+ Attribute const& attr;
+ detail::simple_trace_type& f;
+ };
+#endif
+
+ template <typename ID, typename Iterator, typename Context, typename Enable = void>
+ struct has_on_error : mpl::false_ {};
+
+ template <typename ID, typename Iterator, typename Context>
+ struct has_on_error<ID, Iterator, Context,
+ typename disable_if_substitution_failure<
+ decltype(
+ std::declval<ID>().on_error(
+ std::declval<Iterator&>()
+ , std::declval<Iterator>()
+ , std::declval<expectation_failure<Iterator>>()
+ , std::declval<Context>()
+ )
+ )>::type
+ >
+ : mpl::true_
+ {};
+
+ template <typename ID, typename Iterator, typename Attribute, typename Context, typename Enable = void>
+ struct has_on_success : mpl::false_ {};
+
+ template <typename ID, typename Iterator, typename Attribute, typename Context>
+ struct has_on_success<ID, Iterator, Context, Attribute,
+ typename disable_if_substitution_failure<
+ decltype(
+ std::declval<ID>().on_success(
+ std::declval<Iterator&>()
+ , std::declval<Iterator>()
+ , std::declval<Attribute&>()
+ , std::declval<Context>()
+ )
+ )>::type
+ >
+ : mpl::true_
+ {};
+
+ template <typename ID>
+ struct make_id
+ {
+ typedef identity<ID> type;
+ };
+
+ template <typename ID>
+ struct make_id<identity<ID>>
+ {
+ typedef identity<ID> type;
+ };
+
+ template <typename ID, typename RHS, typename Context>
+ Context const&
+ make_rule_context(RHS const& rhs, Context const& context
+ , mpl::false_ /* is_default_parse_rule */)
+ {
+ return context;
+ }
+
+ template <typename ID, typename RHS, typename Context>
+ auto make_rule_context(RHS const& rhs, Context const& context
+ , mpl::true_ /* is_default_parse_rule */ )
+ {
+ return make_unique_context<ID>(rhs, context);
+ }
+
+ template <typename Attribute, typename ID>
+ struct rule_parser
+ {
+ template <typename Iterator, typename Context, typename ActualAttribute>
+ static bool call_on_success(
+ Iterator& first, Iterator const& last
+ , Context const& context, ActualAttribute& attr
+ , mpl::false_ /* No on_success handler */ )
+ {
+ return true;
+ }
+
+ template <typename Iterator, typename Context, typename ActualAttribute>
+ static bool call_on_success(
+ Iterator& first, Iterator const& last
+ , Context const& context, ActualAttribute& attr
+ , mpl::true_ /* Has on_success handler */)
+ {
+ bool pass = true;
+ ID().on_success(
+ first
+ , last
+ , attr
+ , make_context<parse_pass_context_tag>(pass, context)
+ );
+ return pass;
+ }
+
+ template <typename RHS, typename Iterator, typename Context
+ , typename RContext, typename ActualAttribute>
+ static bool parse_rhs_main(
+ RHS const& rhs
+ , Iterator& first, Iterator const& last
+ , Context const& context, RContext& rcontext, ActualAttribute& attr
+ , mpl::false_)
+ {
+ // see if the user has a BOOST_SPIRIT_DEFINE for this rule
+ typedef
+ decltype(parse_rule(
+ rule<ID, Attribute>(), first, last
+ , make_unique_context<ID>(rhs, context), attr))
+ parse_rule_result;
+
+ // If there is no BOOST_SPIRIT_DEFINE for this rule,
+ // we'll make a context for this rule tagged by its ID
+ // so we can extract the rule later on in the default
+ // (generic) parse_rule function.
+ typedef
+ is_same<parse_rule_result, default_parse_rule_result>
+ is_default_parse_rule;
+
+ Iterator i = first;
+ bool r = rhs.parse(
+ i
+ , last
+ , make_rule_context<ID>(rhs, context, is_default_parse_rule())
+ , rcontext
+ , attr
+ );
+
+ if (r)
+ {
+ auto first_ = first;
+ x3::skip_over(first_, last, context);
+ r = call_on_success(first_, i, context, attr
+ , has_on_success<ID, Iterator, Context, ActualAttribute>());
+ }
+
+ if (r)
+ first = i;
+ return r;
+ }
+
+ template <typename RHS, typename Iterator, typename Context
+ , typename RContext, typename ActualAttribute>
+ static bool parse_rhs_main(
+ RHS const& rhs
+ , Iterator& first, Iterator const& last
+ , Context const& context, RContext& rcontext, ActualAttribute& attr
+ , mpl::true_ /* on_error is found */)
+ {
+ for (;;)
+ {
+ try
+ {
+ return parse_rhs_main(
+ rhs, first, last, context, rcontext, attr, mpl::false_());
+ }
+ catch (expectation_failure<Iterator> const& x)
+ {
+ switch (ID().on_error(first, last, x, context))
+ {
+ case error_handler_result::fail:
+ return false;
+ case error_handler_result::retry:
+ continue;
+ case error_handler_result::accept:
+ return true;
+ case error_handler_result::rethrow:
+ throw;
+ }
+ }
+ }
+ }
+
+ template <typename RHS, typename Iterator
+ , typename Context, typename RContext, typename ActualAttribute>
+ static bool parse_rhs_main(
+ RHS const& rhs
+ , Iterator& first, Iterator const& last
+ , Context const& context, RContext& rcontext, ActualAttribute& attr)
+ {
+ return parse_rhs_main(
+ rhs, first, last, context, rcontext, attr
+ , has_on_error<ID, Iterator, Context>()
+ );
+ }
+
+ template <typename RHS, typename Iterator
+ , typename Context, typename RContext, typename ActualAttribute>
+ static bool parse_rhs(
+ RHS const& rhs
+ , Iterator& first, Iterator const& last
+ , Context const& context, RContext& rcontext, ActualAttribute& attr
+ , mpl::false_)
+ {
+ return parse_rhs_main(rhs, first, last, context, rcontext, attr);
+ }
+
+ template <typename RHS, typename Iterator
+ , typename Context, typename RContext, typename ActualAttribute>
+ static bool parse_rhs(
+ RHS const& rhs
+ , Iterator& first, Iterator const& last
+ , Context const& context, RContext& rcontext, ActualAttribute& attr
+ , mpl::true_)
+ {
+ return parse_rhs_main(rhs, first, last, context, rcontext, unused);
+ }
+
+ template <typename RHS, typename Iterator, typename Context
+ , typename ActualAttribute, typename ExplicitAttrPropagation>
+ static bool call_rule_definition(
+ RHS const& rhs
+ , char const* rule_name
+ , Iterator& first, Iterator const& last
+ , Context const& context, ActualAttribute& attr
+ , ExplicitAttrPropagation)
+ {
+ typedef traits::make_attribute<Attribute, ActualAttribute> make_attribute;
+
+ // do down-stream transformation, provides attribute for
+ // rhs parser
+ typedef traits::transform_attribute<
+ typename make_attribute::type, Attribute, parser_id>
+ transform;
+
+ typedef typename make_attribute::value_type value_type;
+ typedef typename transform::type transform_attr;
+ value_type made_attr = make_attribute::call(attr);
+ transform_attr attr_ = transform::pre(made_attr);
+
+ bool ok_parse
+ //Creates a place to hold the result of parse_rhs
+ //called inside the following scope.
+ ;
+ {
+ //Create a scope to cause the dbg variable below (within
+ //the #if...#endif) to call it's DTOR before any
+ //modifications are made to the attribute, attr_ passed
+ //to parse_rhs (such as might be done in
+ //traits::post_transform when, for example,
+ //ActualAttribute is a recursive variant).
+#if defined(BOOST_SPIRIT_X3_DEBUG)
+ context_debug<Iterator, typename make_attribute::value_type>
+ dbg(rule_name, first, last, attr_, ok_parse);
+#endif
+ ok_parse=parse_rhs(rhs, first, last, context, attr_, attr_
+ , mpl::bool_
+ < ( RHS::has_action
+ && !ExplicitAttrPropagation::value
+ )
+ >()
+ );
+ }
+ if(ok_parse)
+ {
+ // do up-stream transformation, this integrates the results
+ // back into the original attribute value, if appropriate
+ traits::post_transform(attr, attr_);
+ }
+ return ok_parse;
+ }
+
+// template <typename RuleDef, typename Iterator, typename Context
+// , typename ActualAttribute, typename AttributeContext>
+// static bool call_from_rule(
+// RuleDef const& rule_def
+// , char const* rule_name
+// , Iterator& first, Iterator const& last
+// , Context const& context, ActualAttribute& attr, AttributeContext& attr_ctx)
+// {
+// // This is called when a rule-body has already been established.
+// // The rule body is already established by the rule_definition class,
+// // we will not do it again. We'll simply call the RHS by calling
+// // call_rule_definition.
+//
+// return call_rule_definition(
+// rule_def.rhs, rule_name, first, last
+// , context, attr, attr_ctx.attr_ptr
+// , mpl::bool_<(RuleDef::explicit_attribute_propagation)>());
+// }
+//
+// template <typename RuleDef, typename Iterator, typename Context
+// , typename ActualAttribute>
+// static bool call_from_rule(
+// RuleDef const& rule_def
+// , char const* rule_name
+// , Iterator& first, Iterator const& last
+// , Context const& context, ActualAttribute& attr, unused_type)
+// {
+// // This is called when a rule-body has *not yet* been established.
+// // The rule body is established by the rule_definition class, so
+// // we call it to parse and establish the rule-body.
+//
+// return rule_def.parse(first, last, context, unused, attr); // $$$ fix unused param $$$
+// }
+ };
+}}}}
+
+#endif
diff --git a/boost/spirit/home/x3/nonterminal/detail/transform_attribute.hpp b/boost/spirit/home/x3/nonterminal/detail/transform_attribute.hpp
new file mode 100644
index 0000000000..b1929f8993
--- /dev/null
+++ b/boost/spirit/home/x3/nonterminal/detail/transform_attribute.hpp
@@ -0,0 +1,108 @@
+/*=============================================================================
+ 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_X3_DETAIL_ATTRIBUTES_APR_18_2010_0458PM)
+#define SPIRIT_X3_DETAIL_ATTRIBUTES_APR_18_2010_0458PM
+
+#include <boost/spirit/home/x3/support/traits/transform_attribute.hpp>
+#include <boost/spirit/home/x3/support/traits/move_to.hpp>
+
+///////////////////////////////////////////////////////////////////////////////
+namespace boost { namespace spirit { namespace x3
+{
+ struct parser_id;
+
+ template <typename Exposed, typename Transformed>
+ struct default_transform_attribute
+ {
+ typedef Transformed type;
+
+ static Transformed pre(Exposed&) { return Transformed(); }
+
+ static void post(Exposed& val, Transformed& attr)
+ {
+ traits::move_to(attr, val);
+ }
+ };
+
+ // handle case where no transformation is required as the types are the same
+ template <typename Attribute>
+ struct default_transform_attribute<Attribute, Attribute>
+ {
+ typedef Attribute& type;
+ static Attribute& pre(Attribute& val) { return val; }
+ static void post(Attribute&, Attribute const&) {}
+ };
+
+ // main specialization for x3
+ template <typename Exposed, typename Transformed, typename Enable = void>
+ struct transform_attribute
+ : default_transform_attribute<Exposed, Transformed> {};
+
+ // reference types need special handling
+ template <typename Attribute>
+ struct transform_attribute<Attribute&, Attribute>
+ {
+ typedef Attribute& type;
+ static Attribute& pre(Attribute& val) { return val; }
+ static void post(Attribute&, Attribute const&) {}
+ };
+
+ // unused_type needs some special handling as well
+ template <>
+ struct transform_attribute<unused_type, unused_type>
+ {
+ typedef unused_type type;
+ static unused_type pre(unused_type) { return unused; }
+ static void post(unused_type, unused_type) {}
+ };
+
+ template <>
+ struct transform_attribute<unused_type const, unused_type>
+ : transform_attribute<unused_type, unused_type> {};
+
+ template <typename Attribute>
+ struct transform_attribute<unused_type, Attribute>
+ : transform_attribute<unused_type, unused_type> {};
+
+ template <typename Attribute>
+ struct transform_attribute<unused_type const, Attribute>
+ : transform_attribute<unused_type, unused_type> {};
+
+ template <typename Attribute>
+ struct transform_attribute<Attribute, unused_type>
+ : transform_attribute<unused_type, unused_type> {};
+
+ template <typename Attribute>
+ struct transform_attribute<Attribute const, unused_type>
+ : transform_attribute<unused_type, unused_type> {};
+}}}
+
+///////////////////////////////////////////////////////////////////////////////
+namespace boost { namespace spirit { namespace x3 { namespace traits
+{
+ template <typename Exposed, typename Transformed>
+ struct transform_attribute<Exposed, Transformed, x3::parser_id>
+ : x3::transform_attribute<Exposed, Transformed> {};
+
+ template <typename Exposed, typename Transformed>
+ struct transform_attribute<Exposed&, Transformed, x3::parser_id>
+ : transform_attribute<Exposed, Transformed, x3::parser_id> {};
+
+ template <typename Attribute>
+ struct transform_attribute<Attribute&, Attribute, x3::parser_id>
+ : x3::transform_attribute<Attribute&, Attribute> {};
+
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename Exposed, typename Transformed>
+ void post_transform(Exposed& dest, Transformed&& attr)
+ {
+ return transform_attribute<Exposed, Transformed, x3::parser_id>::post(dest, attr);
+ }
+}}}}
+
+#endif
diff --git a/boost/spirit/home/x3/nonterminal/rule.hpp b/boost/spirit/home/x3/nonterminal/rule.hpp
new file mode 100644
index 0000000000..049c6be57b
--- /dev/null
+++ b/boost/spirit/home/x3/nonterminal/rule.hpp
@@ -0,0 +1,186 @@
+/*=============================================================================
+ 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(BOOST_SPIRIT_X3_RULE_JAN_08_2012_0326PM)
+#define BOOST_SPIRIT_X3_RULE_JAN_08_2012_0326PM
+
+#if defined(_MSC_VER)
+#pragma once
+#endif
+
+#include <boost/spirit/home/x3/nonterminal/detail/rule.hpp>
+#include <boost/type_traits/is_same.hpp>
+#include <boost/spirit/home/x3/support/context.hpp>
+#include <boost/preprocessor/variadic/to_seq.hpp>
+#include <boost/preprocessor/variadic/elem.hpp>
+#include <boost/preprocessor/seq/for_each.hpp>
+
+#if !defined(BOOST_SPIRIT_X3_NO_RTTI)
+#include <typeinfo>
+#endif
+
+namespace boost { namespace spirit { namespace x3
+{
+ template <typename ID>
+ struct identity {};
+
+ // default parse_rule implementation
+ template <typename ID, typename Attribute, typename Iterator
+ , typename Context, typename ActualAttribute>
+ inline detail::default_parse_rule_result
+ parse_rule(
+ rule<ID, Attribute> rule_
+ , Iterator& first, Iterator const& last
+ , Context const& context, ActualAttribute& attr)
+ {
+ static_assert(!is_same<decltype(get<ID>(context)), unused_type>::value,
+ "BOOST_SPIRIT_DEFINE undefined for this rule.");
+ return get<ID>(context).parse(first, last, context, unused, attr);
+ }
+
+ template <typename ID, typename RHS, typename Attribute, bool force_attribute_>
+ struct rule_definition : parser<rule_definition<ID, RHS, Attribute, force_attribute_>>
+ {
+ typedef rule_definition<ID, RHS, Attribute, force_attribute_> this_type;
+ typedef ID id;
+ typedef RHS rhs_type;
+ typedef rule<ID, Attribute> lhs_type;
+ typedef Attribute attribute_type;
+
+ static bool const has_attribute =
+ !is_same<Attribute, unused_type>::value;
+ static bool const handles_container =
+ traits::is_container<Attribute>::value;
+ static bool const force_attribute =
+ force_attribute_;
+
+ rule_definition(RHS rhs, char const* name)
+ : rhs(rhs), name(name) {}
+
+ template <typename Iterator, typename Context, typename Attribute_>
+ bool parse(Iterator& first, Iterator const& last
+ , Context const& context, unused_type, Attribute_& attr) const
+ {
+ return detail::rule_parser<attribute_type, ID>
+ ::call_rule_definition(
+ rhs, name, first, last
+ , context
+ , attr
+ , mpl::bool_<force_attribute>());
+ }
+
+ RHS rhs;
+ char const* name;
+ };
+
+ template <typename ID, typename Attribute>
+ struct rule : parser<rule<ID, Attribute>>
+ {
+ typedef ID id;
+ typedef Attribute attribute_type;
+ static bool const has_attribute =
+ !is_same<Attribute, unused_type>::value;
+ static bool const handles_container =
+ traits::is_container<Attribute>::value;
+
+#if !defined(BOOST_SPIRIT_X3_NO_RTTI)
+ rule() : name(typeid(rule).name()) {}
+#else
+ rule() : name("unnamed") {}
+#endif
+
+ rule(char const* name)
+ : name(name) {}
+
+ template <typename RHS>
+ rule_definition<
+ ID, typename extension::as_parser<RHS>::value_type, Attribute, false>
+ operator=(RHS const& rhs) const
+ {
+ return {as_parser(rhs), name};
+ }
+
+ template <typename RHS>
+ rule_definition<
+ ID, typename extension::as_parser<RHS>::value_type, Attribute, true>
+ operator%=(RHS const& rhs) const
+ {
+ return {as_parser(rhs), name};
+ }
+
+
+ template <typename Iterator, typename Context, typename Attribute_>
+ bool parse(Iterator& first, Iterator const& last
+ , Context const& context, unused_type, Attribute_& attr) const
+ {
+ return parse_rule(*this, first, last, context, attr);
+ }
+
+ char const* name;
+ };
+
+ namespace traits
+ {
+ template <typename T, typename Enable = void>
+ struct is_rule : mpl::false_ {};
+
+ template <typename ID, typename Attribute>
+ struct is_rule<rule<ID, Attribute>> : mpl::true_ {};
+
+ template <typename ID, typename Attribute, typename RHS, bool force_attribute>
+ struct is_rule<rule_definition<ID, RHS, Attribute, force_attribute>> : mpl::true_ {};
+ }
+
+ template <typename T>
+ struct get_info<T, typename enable_if<traits::is_rule<T>>::type>
+ {
+ typedef std::string result_type;
+ std::string operator()(T const& r) const
+ {
+ return r.name;
+ }
+ };
+
+#define BOOST_SPIRIT_DECLARE_(r, data, rule_type) \
+ template <typename Iterator, typename Context, typename Attribute> \
+ bool parse_rule( \
+ rule_type rule_ \
+ , Iterator& first, Iterator const& last \
+ , Context const& context, Attribute& attr); \
+ /***/
+
+#define BOOST_SPIRIT_DECLARE(...) BOOST_PP_SEQ_FOR_EACH( \
+ BOOST_SPIRIT_DECLARE_, _, BOOST_PP_VARIADIC_TO_SEQ(__VA_ARGS__)) \
+ /***/
+
+#define BOOST_SPIRIT_DEFINE_(r, data, def) \
+ template <typename Iterator, typename Context, typename Attribute> \
+ inline bool parse_rule( \
+ decltype(def)::lhs_type rule_ \
+ , Iterator& first, Iterator const& last \
+ , Context const& context, Attribute& attr) \
+ { \
+ using boost::spirit::x3::unused; \
+ auto const& def_ = (def); \
+ return def_.parse(first, last, context, unused, attr); \
+ } \
+ /***/
+
+#define BOOST_SPIRIT_DEFINE(...) BOOST_PP_SEQ_FOR_EACH( \
+ BOOST_SPIRIT_DEFINE_, _, BOOST_PP_VARIADIC_TO_SEQ(__VA_ARGS__)) \
+ /***/
+
+#define BOOST_SPIRIT_INSTANTIATE(rule_type, Iterator, Context) \
+ template bool parse_rule<Iterator, Context, rule_type::attribute_type>( \
+ rule_type rule_ \
+ , Iterator& first, Iterator const& last \
+ , Context const& context, rule_type::attribute_type& attr); \
+ /***/
+
+
+}}}
+
+#endif
diff --git a/boost/spirit/home/x3/nonterminal/simple_trace.hpp b/boost/spirit/home/x3/nonterminal/simple_trace.hpp
new file mode 100644
index 0000000000..b049b4ec3c
--- /dev/null
+++ b/boost/spirit/home/x3/nonterminal/simple_trace.hpp
@@ -0,0 +1,150 @@
+/*=============================================================================
+ 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(BOOST_SPIRIT_X3_SIMPLE_TRACE_DECEMBER_06_2008_1102AM)
+#define BOOST_SPIRIT_X3_SIMPLE_TRACE_DECEMBER_06_2008_1102AM
+
+#if defined(_MSC_VER)
+#pragma once
+#endif
+
+#include <boost/spirit/home/x3/support/unused.hpp>
+#include <boost/spirit/home/x3/support/traits/print_token.hpp>
+#include <boost/spirit/home/x3/support/traits/print_attribute.hpp>
+#include <boost/spirit/home/x3/nonterminal/debug_handler_state.hpp>
+#include <boost/fusion/include/out.hpp>
+#include <boost/type_traits/is_same.hpp>
+#include <ostream>
+
+// The stream to use for debug output
+#if !defined(BOOST_SPIRIT_X3_DEBUG_OUT)
+#define BOOST_SPIRIT_X3_DEBUG_OUT std::cerr
+#endif
+
+// number of tokens to print while debugging
+#if !defined(BOOST_SPIRIT_X3_DEBUG_PRINT_SOME)
+#define BOOST_SPIRIT_X3_DEBUG_PRINT_SOME 20
+#endif
+
+// number of spaces to indent
+#if !defined(BOOST_SPIRIT_X3_DEBUG_INDENT)
+#define BOOST_SPIRIT_X3_DEBUG_INDENT 2
+#endif
+
+namespace boost { namespace spirit { namespace x3
+{
+ namespace detail
+ {
+ template <typename Char>
+ inline void token_printer(std::ostream& o, Char c)
+ {
+ // allow customization of the token printer routine
+ x3::traits::print_token(o, c);
+ }
+ }
+
+ template <int IndentSpaces = 2, int CharsToPrint = 20>
+ struct simple_trace
+ {
+ simple_trace(std::ostream& out)
+ : out(out), indent(0) {}
+
+ void print_indent(int n) const
+ {
+ n *= IndentSpaces;
+ for (int i = 0; i != n; ++i)
+ out << ' ';
+ }
+
+ template <typename Iterator>
+ void print_some(
+ char const* tag
+ , Iterator first, Iterator const& last) const
+ {
+ print_indent(indent);
+ out << '<' << tag << '>';
+ int const n = CharsToPrint;
+ for (int i = 0; first != last && i != n && *first; ++i, ++first)
+ detail::token_printer(out, *first);
+ out << "</" << tag << '>' << std::endl;
+
+ // $$$ FIXME convert invalid xml characters (e.g. '<') to valid
+ // character entities. $$$
+ }
+
+ template <typename Iterator, typename Attribute, typename State>
+ void operator()(
+ Iterator const& first
+ , Iterator const& last
+ , Attribute const& attr
+ , State state
+ , std::string const& rule_name) const
+ {
+ switch (state)
+ {
+ case pre_parse:
+ print_indent(indent++);
+ out
+ << '<' << rule_name << '>'
+ << std::endl;
+ print_some("try", first, last);
+ break;
+
+ case successful_parse:
+ print_some("success", first, last);
+ if (!is_same<Attribute, unused_type>::value)
+ {
+ print_indent(indent);
+ out
+ << "<attributes>";
+ traits::print_attribute(out, attr);
+ out
+ << "</attributes>";
+ out << std::endl;
+ }
+ //~ if (!fusion::empty(context.locals))
+ //~ out
+ //~ << "<locals>"
+ //~ << context.locals
+ //~ << "</locals>";
+ print_indent(--indent);
+ out
+ << "</" << rule_name << '>'
+ << std::endl;
+ break;
+
+ case failed_parse:
+ print_indent(indent);
+ out << "<fail/>" << std::endl;
+ print_indent(--indent);
+ out
+ << "</" << rule_name << '>'
+ << std::endl;
+ break;
+ }
+ }
+
+ std::ostream& out;
+ mutable int indent;
+ };
+
+ namespace detail
+ {
+ typedef simple_trace<
+ BOOST_SPIRIT_X3_DEBUG_INDENT, BOOST_SPIRIT_X3_DEBUG_PRINT_SOME>
+ simple_trace_type;
+
+ inline simple_trace_type&
+ get_simple_trace()
+ {
+ static simple_trace_type tracer(BOOST_SPIRIT_X3_DEBUG_OUT);
+ return tracer;
+ }
+ }
+}}}
+
+#endif
diff --git a/boost/spirit/home/x3/numeric.hpp b/boost/spirit/home/x3/numeric.hpp
new file mode 100644
index 0000000000..c44d668569
--- /dev/null
+++ b/boost/spirit/home/x3/numeric.hpp
@@ -0,0 +1,19 @@
+/*=============================================================================
+ 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(BOOST_SPIRIT_X3_NUMERIC_FEBRUARY_05_2007_1231PM)
+#define BOOST_SPIRIT_X3_NUMERIC_FEBRUARY_05_2007_1231PM
+
+#if defined(_MSC_VER)
+#pragma once
+#endif
+
+#include <boost/spirit/home/x3/numeric/bool.hpp>
+#include <boost/spirit/home/x3/numeric/int.hpp>
+#include <boost/spirit/home/x3/numeric/uint.hpp>
+#include <boost/spirit/home/x3/numeric/real.hpp>
+
+#endif
diff --git a/boost/spirit/home/x3/numeric/bool.hpp b/boost/spirit/home/x3/numeric/bool.hpp
new file mode 100644
index 0000000000..1fb21c16fe
--- /dev/null
+++ b/boost/spirit/home/x3/numeric/bool.hpp
@@ -0,0 +1,106 @@
+/*=============================================================================
+ Copyright (c) 2009 Hartmut Kaiser
+ Copyright (c) 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_X3_BOOL_SEP_29_2009_0709AM)
+#define SPIRIT_X3_BOOL_SEP_29_2009_0709AM
+
+#include <boost/spirit/home/x3/core/parser.hpp>
+#include <boost/spirit/home/x3/core/skip_over.hpp>
+#include <boost/spirit/home/x3/numeric/bool_policies.hpp>
+
+namespace boost { namespace spirit { namespace x3
+{
+ template <typename T, typename BoolPolicies = bool_policies<T>>
+ struct bool_parser : parser<bool_parser<T, BoolPolicies>>
+ {
+ typedef T attribute_type;
+ static bool const has_attribute = true;
+
+ bool_parser()
+ : policies() {}
+
+ bool_parser(BoolPolicies const& policies)
+ : policies(policies) {}
+
+ template <typename Iterator, typename Context>
+ bool parse(Iterator& first, Iterator const& last
+ , Context& context, unused_type, T& attr) const
+ {
+ x3::skip_over(first, last, context);
+ return policies.parse_true(first, last, attr)
+ || policies.parse_false(first, last, attr);
+ }
+
+ template <typename Iterator, typename Context, typename Attribute>
+ bool parse(Iterator& first, Iterator const& last
+ , Context& context, unused_type, Attribute& attr_param) const
+ {
+ // this case is called when Attribute is not T
+ T attr_;
+ if (parse(first, last, context, unused, attr_))
+ {
+ traits::move_to(attr_, attr_param);
+ return true;
+ }
+ return false;
+ }
+
+ BoolPolicies policies;
+ };
+
+ template <typename T, typename BoolPolicies = bool_policies<T>>
+ struct literal_bool_parser : parser<bool_parser<T, BoolPolicies>>
+ {
+ typedef T attribute_type;
+ static bool const has_attribute = true;
+
+ template <typename Value>
+ literal_bool_parser(Value const& n)
+ : policies(), n_(n) {}
+
+ template <typename Value>
+ literal_bool_parser(Value const& n, BoolPolicies const& policies)
+ : policies(policies), n_(n) {}
+
+ template <typename Iterator, typename Context>
+ bool parse(Iterator& first, Iterator const& last
+ , Context& context, unused_type, T& attr) const
+ {
+ x3::skip_over(first, last, context);
+ return (n_ && policies.parse_true(first, last, attr))
+ || (!n_ && policies.parse_false(first, last, attr));
+ }
+
+ template <typename Iterator, typename Context, typename Attribute>
+ bool parse(Iterator& first, Iterator const& last
+ , Context& context, unused_type, Attribute& attr_param) const
+ {
+ // this case is called when Attribute is not T
+ T attr_;
+ if (parse(first, last, context, unused, attr_))
+ {
+ traits::move_to(attr_, attr_param);
+ return true;
+ }
+ return false;
+ }
+
+ BoolPolicies policies;
+ T n_;
+ };
+
+ typedef bool_parser<bool> bool_type;
+ bool_type const bool_ = {};
+
+ typedef literal_bool_parser<bool> true_type;
+ true_type const true_ = { true };
+
+ typedef literal_bool_parser<bool> false_type;
+ false_type const false_ = { false };
+}}}
+
+#endif
diff --git a/boost/spirit/home/x3/numeric/bool_policies.hpp b/boost/spirit/home/x3/numeric/bool_policies.hpp
new file mode 100644
index 0000000000..bafc5b5294
--- /dev/null
+++ b/boost/spirit/home/x3/numeric/bool_policies.hpp
@@ -0,0 +1,52 @@
+/*=============================================================================
+ Copyright (c) 2009 Hartmut Kaiser
+ Copyright (c) 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_QI_BOOL_POLICIES_SEP_29_2009_0710AM)
+#define SPIRIT_QI_BOOL_POLICIES_SEP_29_2009_0710AM
+
+#if defined(_MSC_VER)
+#pragma once
+#endif
+
+#include <boost/spirit/home/x3/string/detail/string_parse.hpp>
+#include <boost/spirit/home/x3/support/traits/move_to.hpp>
+
+namespace boost { namespace spirit { namespace x3
+{
+ ///////////////////////////////////////////////////////////////////////////
+ // Default boolean policies
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename T = bool>
+ struct bool_policies
+ {
+ template <typename Iterator, typename Attribute>
+ static bool
+ parse_true(Iterator& first, Iterator const& last, Attribute& attr_)
+ {
+ if (detail::string_parse("true", first, last, unused))
+ {
+ traits::move_to(T(true), attr_); // result is true
+ return true;
+ }
+ return false;
+ }
+
+ template <typename Iterator, typename Attribute>
+ static bool
+ parse_false(Iterator& first, Iterator const& last, Attribute& attr_)
+ {
+ if (detail::string_parse("false", first, last, unused))
+ {
+ traits::move_to(T(false), attr_); // result is false
+ return true;
+ }
+ return false;
+ }
+ };
+}}}
+
+#endif
diff --git a/boost/spirit/home/x3/numeric/int.hpp b/boost/spirit/home/x3/numeric/int.hpp
new file mode 100644
index 0000000000..ba9ceb8243
--- /dev/null
+++ b/boost/spirit/home/x3/numeric/int.hpp
@@ -0,0 +1,66 @@
+/*=============================================================================
+ 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(BOOST_SPIRIT_X3_INT_APR_17_2006_0830AM)
+#define BOOST_SPIRIT_X3_INT_APR_17_2006_0830AM
+
+#if defined(_MSC_VER)
+#pragma once
+#endif
+
+#include <boost/spirit/home/x3/core/parser.hpp>
+#include <boost/spirit/home/x3/core/skip_over.hpp>
+#include <boost/spirit/home/x3/support/numeric_utils/extract_int.hpp>
+#include <cstdint>
+
+namespace boost { namespace spirit { namespace x3
+{
+ ///////////////////////////////////////////////////////////////////////////
+ template <
+ typename T
+ , unsigned Radix = 10
+ , unsigned MinDigits = 1
+ , int MaxDigits = -1>
+ struct int_parser : parser<int_parser<T, Radix, MinDigits, MaxDigits>>
+ {
+ // check template parameter 'Radix' for validity
+ static_assert(
+ (Radix == 2 || Radix == 8 || Radix == 10 || Radix == 16),
+ "Error Unsupported Radix");
+
+ typedef T attribute_type;
+ static bool const has_attribute = true;
+
+ template <typename Iterator, typename Context, typename Attribute>
+ bool parse(Iterator& first, Iterator const& last
+ , Context const& context, unused_type, Attribute& attr) const
+ {
+ typedef extract_int<T, Radix, MinDigits, MaxDigits> extract;
+ x3::skip_over(first, last, context);
+ return extract::call(first, last, attr);
+ }
+ };
+
+#define BOOST_SPIRIT_X3_INT_PARSER(int_type, name) \
+ typedef int_parser<int_type> name##type; \
+ name##type const name = {}; \
+ /***/
+
+ BOOST_SPIRIT_X3_INT_PARSER(long, long_)
+ BOOST_SPIRIT_X3_INT_PARSER(short, short_)
+ BOOST_SPIRIT_X3_INT_PARSER(int, int_)
+ BOOST_SPIRIT_X3_INT_PARSER(long long, long_long)
+
+ BOOST_SPIRIT_X3_INT_PARSER(int8_t, int8)
+ BOOST_SPIRIT_X3_INT_PARSER(int16_t, int16)
+ BOOST_SPIRIT_X3_INT_PARSER(int32_t, int32)
+ BOOST_SPIRIT_X3_INT_PARSER(int64_t, int64)
+
+#undef BOOST_SPIRIT_X3_INT_PARSER
+
+}}}
+
+#endif
diff --git a/boost/spirit/home/x3/numeric/real.hpp b/boost/spirit/home/x3/numeric/real.hpp
new file mode 100644
index 0000000000..91da536421
--- /dev/null
+++ b/boost/spirit/home/x3/numeric/real.hpp
@@ -0,0 +1,62 @@
+/*=============================================================================
+ 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(BOOST_SPIRIT_X3_REAL_APRIL_18_2006_0850AM)
+#define BOOST_SPIRIT_X3_REAL_APRIL_18_2006_0850AM
+
+#include <boost/spirit/home/x3/core/parser.hpp>
+#include <boost/spirit/home/x3/core/skip_over.hpp>
+#include <boost/spirit/home/x3/numeric/real_policies.hpp>
+#include <boost/spirit/home/x3/support/numeric_utils/extract_real.hpp>
+
+namespace boost { namespace spirit { namespace x3
+{
+ template <typename T, typename RealPolicies = real_policies<T> >
+ struct real_parser : parser<real_parser<T, RealPolicies> >
+ {
+ typedef T attribute_type;
+ static bool const has_attribute = true;
+
+ real_parser()
+ : policies() {}
+
+ real_parser(RealPolicies const& policies)
+ : policies(policies) {}
+
+ template <typename Iterator, typename Context>
+ bool parse(Iterator& first, Iterator const& last
+ , Context& context, unused_type, T& attr_) const
+ {
+ x3::skip_over(first, last, context);
+ return extract_real<T, RealPolicies>::parse(first, last, attr_, policies);
+ }
+
+ template <typename Iterator, typename Context, typename Attribute>
+ bool parse(Iterator& first, Iterator const& last
+ , Context& context, unused_type, Attribute& attr_param) const
+ {
+ // this case is called when Attribute is not T
+ T attr_;
+ if (parse(first, last, context, unused, attr_))
+ {
+ traits::move_to(attr_, attr_param);
+ return true;
+ }
+ return false;
+ }
+
+ RealPolicies policies;
+ };
+
+ typedef real_parser<float> float_type;
+ float_type const float_ = {};
+
+ typedef real_parser<double> double_type;
+ double_type const double_ = {};
+
+}}}
+
+#endif
diff --git a/boost/spirit/home/x3/numeric/real_policies.hpp b/boost/spirit/home/x3/numeric/real_policies.hpp
new file mode 100644
index 0000000000..4e02b266c5
--- /dev/null
+++ b/boost/spirit/home/x3/numeric/real_policies.hpp
@@ -0,0 +1,186 @@
+/*=============================================================================
+ 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_REAL_POLICIES_APRIL_17_2006_1158PM)
+#define SPIRIT_REAL_POLICIES_APRIL_17_2006_1158PM
+
+#if defined(_MSC_VER)
+#pragma once
+#endif
+
+#include <boost/spirit/home/x3/string/detail/string_parse.hpp>
+#include <boost/spirit/home/x3/support/numeric_utils/extract_int.hpp>
+
+namespace boost { namespace spirit { namespace x3
+{
+ ///////////////////////////////////////////////////////////////////////////
+ // Default (unsigned) real number policies
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename T>
+ struct ureal_policies
+ {
+ // trailing dot policy suggested by Gustavo Guerra
+ static bool const allow_leading_dot = true;
+ static bool const allow_trailing_dot = true;
+ static bool const expect_dot = false;
+
+ template <typename Iterator>
+ static bool
+ parse_sign(Iterator& /*first*/, Iterator const& /*last*/)
+ {
+ return false;
+ }
+
+ template <typename Iterator, typename Attribute>
+ static bool
+ parse_n(Iterator& first, Iterator const& last, Attribute& attr_)
+ {
+ return extract_uint<T, 10, 1, -1>::call(first, last, attr_);
+ }
+
+ template <typename Iterator>
+ static bool
+ parse_dot(Iterator& first, Iterator const& last)
+ {
+ if (first == last || *first != '.')
+ return false;
+ ++first;
+ return true;
+ }
+
+ template <typename Iterator, typename Attribute>
+ static bool
+ parse_frac_n(Iterator& first, Iterator const& last, Attribute& attr_)
+ {
+ return extract_uint<T, 10, 1, -1, true>::call(first, last, attr_);
+ }
+
+ template <typename Iterator>
+ static bool
+ parse_exp(Iterator& first, Iterator const& last)
+ {
+ if (first == last || (*first != 'e' && *first != 'E'))
+ return false;
+ ++first;
+ return true;
+ }
+
+ template <typename Iterator>
+ static bool
+ parse_exp_n(Iterator& first, Iterator const& last, int& attr_)
+ {
+ return extract_int<int, 10, 1, -1>::call(first, last, attr_);
+ }
+
+ ///////////////////////////////////////////////////////////////////////
+ // The parse_nan() and parse_inf() functions get called whenever:
+ //
+ // - a number to parse does not start with a digit (after having
+ // successfully parsed an optional sign)
+ //
+ // or
+ //
+ // - after a floating point number of the value 1 (having no
+ // exponential part and a fractional part value of 0) has been
+ // parsed.
+ //
+ // The first call allows to recognize representations of NaN or Inf
+ // starting with a non-digit character (such as NaN, Inf, QNaN etc.).
+ //
+ // The second call allows to recognize representation formats starting
+ // with a 1.0 (such as 1.0#NAN or 1.0#INF etc.).
+ //
+ // The functions should return true if a Nan or Inf has been found. In
+ // this case the attr should be set to the matched value (NaN or
+ // Inf). The optional sign will be automatically applied afterwards.
+ //
+ // The default implementation below recognizes representations of NaN
+ // and Inf as mandated by the C99 Standard and as proposed for
+ // inclusion into the C++0x Standard: nan, nan(...), inf and infinity
+ // (the matching is performed case-insensitively).
+ ///////////////////////////////////////////////////////////////////////
+ template <typename Iterator, typename Attribute>
+ static bool
+ parse_nan(Iterator& first, Iterator const& last, Attribute& attr_)
+ {
+ if (first == last)
+ return false; // end of input reached
+
+ if (*first != 'n' && *first != 'N')
+ return false; // not "nan"
+
+ // nan[(...)] ?
+ if (detail::string_parse("nan", "NAN", first, last, unused))
+ {
+ if (*first == '(')
+ {
+ // skip trailing (...) part
+ Iterator i = first;
+
+ while (++i != last && *i != ')')
+ ;
+ if (i == last)
+ return false; // no trailing ')' found, give up
+
+ first = ++i;
+ }
+ attr_ = std::numeric_limits<T>::quiet_NaN();
+ return true;
+ }
+ return false;
+ }
+
+ template <typename Iterator, typename Attribute>
+ static bool
+ parse_inf(Iterator& first, Iterator const& last, Attribute& attr_)
+ {
+ if (first == last)
+ return false; // end of input reached
+
+ if (*first != 'i' && *first != 'I')
+ return false; // not "inf"
+
+ // inf or infinity ?
+ if (detail::string_parse("inf", "INF", first, last, unused))
+ {
+ // skip allowed 'inity' part of infinity
+ detail::string_parse("inity", "INITY", first, last, unused);
+ attr_ = std::numeric_limits<T>::infinity();
+ return true;
+ }
+ return false;
+ }
+ };
+
+ ///////////////////////////////////////////////////////////////////////////
+ // Default (signed) real number policies
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename T>
+ struct real_policies : ureal_policies<T>
+ {
+ template <typename Iterator>
+ static bool
+ parse_sign(Iterator& first, Iterator const& last)
+ {
+ return extract_sign(first, last);
+ }
+ };
+
+ template <typename T>
+ struct strict_ureal_policies : ureal_policies<T>
+ {
+ static bool const expect_dot = true;
+ };
+
+ template <typename T>
+ struct strict_real_policies : real_policies<T>
+ {
+ static bool const expect_dot = true;
+ };
+}}}
+
+#endif
diff --git a/boost/spirit/home/x3/numeric/uint.hpp b/boost/spirit/home/x3/numeric/uint.hpp
new file mode 100644
index 0000000000..624bae52de
--- /dev/null
+++ b/boost/spirit/home/x3/numeric/uint.hpp
@@ -0,0 +1,79 @@
+/*=============================================================================
+ Copyright (c) 2001-2014 Joel de Guzman
+ Copyright (c) 2011 Jan Frederick Eick
+
+ 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(BOOST_SPIRIT_X3_UINT_APR_17_2006_0901AM)
+#define BOOST_SPIRIT_X3_UINT_APR_17_2006_0901AM
+
+#if defined(_MSC_VER)
+#pragma once
+#endif
+
+#include <boost/spirit/home/x3/core/parser.hpp>
+#include <boost/spirit/home/x3/core/skip_over.hpp>
+#include <boost/spirit/home/x3/support/numeric_utils/extract_int.hpp>
+#include <cstdint>
+
+namespace boost { namespace spirit { namespace x3
+{
+ ///////////////////////////////////////////////////////////////////////////
+ template <
+ typename T
+ , unsigned Radix = 10
+ , unsigned MinDigits = 1
+ , int MaxDigits = -1>
+ struct uint_parser : parser<uint_parser<T, Radix, MinDigits, MaxDigits>>
+ {
+ // check template parameter 'Radix' for validity
+ static_assert(
+ (Radix >= 2 && Radix <= 36),
+ "Error Unsupported Radix");
+
+ typedef T attribute_type;
+ static bool const has_attribute = true;
+
+ template <typename Iterator, typename Context, typename Attribute>
+ bool parse(Iterator& first, Iterator const& last
+ , Context const& context, unused_type, Attribute& attr) const
+ {
+ typedef extract_uint<T, Radix, MinDigits, MaxDigits> extract;
+ x3::skip_over(first, last, context);
+ return extract::call(first, last, attr);
+ }
+ };
+
+#define BOOST_SPIRIT_X3_UINT_PARSER(uint_type, name) \
+ typedef uint_parser<uint_type> name##type; \
+ name##type const name = {}; \
+ /***/
+
+ BOOST_SPIRIT_X3_UINT_PARSER(unsigned long, ulong_)
+ BOOST_SPIRIT_X3_UINT_PARSER(unsigned short, ushort_)
+ BOOST_SPIRIT_X3_UINT_PARSER(unsigned int, uint_)
+ BOOST_SPIRIT_X3_UINT_PARSER(unsigned long long, ulong_long)
+
+ BOOST_SPIRIT_X3_UINT_PARSER(uint8_t, uint8)
+ BOOST_SPIRIT_X3_UINT_PARSER(uint16_t, uint16)
+ BOOST_SPIRIT_X3_UINT_PARSER(uint32_t, uint32)
+ BOOST_SPIRIT_X3_UINT_PARSER(uint64_t, uint64)
+
+#undef BOOST_SPIRIT_X3_UINT_PARSER
+
+#define BOOST_SPIRIT_X3_UINT_PARSER(uint_type, radix, name) \
+ typedef uint_parser<uint_type, radix> name##type; \
+ name##type const name = name##type(); \
+ /***/
+
+ BOOST_SPIRIT_X3_UINT_PARSER(unsigned, 2, bin)
+ BOOST_SPIRIT_X3_UINT_PARSER(unsigned, 8, oct)
+ BOOST_SPIRIT_X3_UINT_PARSER(unsigned, 16, hex)
+
+#undef BOOST_SPIRIT_X3_UINT_PARSER
+
+
+}}}
+
+#endif
diff --git a/boost/spirit/home/x3/operator.hpp b/boost/spirit/home/x3/operator.hpp
new file mode 100644
index 0000000000..1244e2f04d
--- /dev/null
+++ b/boost/spirit/home/x3/operator.hpp
@@ -0,0 +1,26 @@
+/*=============================================================================
+ 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(BOOST_SPIRIT_X3_OPERATOR_FEBRUARY_02_2007_0558PM)
+#define BOOST_SPIRIT_X3_OPERATOR_FEBRUARY_02_2007_0558PM
+
+#if defined(_MSC_VER)
+#pragma once
+#endif
+
+#include <boost/spirit/home/x3/operator/sequence.hpp>
+#include <boost/spirit/home/x3/operator/alternative.hpp>
+//~ #include <boost/spirit/home/x3/operator/sequential_or.hpp>
+//~ #include <boost/spirit/home/x3/operator/permutation.hpp>
+#include <boost/spirit/home/x3/operator/difference.hpp>
+#include <boost/spirit/home/x3/operator/list.hpp>
+#include <boost/spirit/home/x3/operator/optional.hpp>
+#include <boost/spirit/home/x3/operator/kleene.hpp>
+#include <boost/spirit/home/x3/operator/plus.hpp>
+#include <boost/spirit/home/x3/operator/and_predicate.hpp>
+#include <boost/spirit/home/x3/operator/not_predicate.hpp>
+
+#endif
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
diff --git a/boost/spirit/home/x3/string.hpp b/boost/spirit/home/x3/string.hpp
new file mode 100644
index 0000000000..e0f5c6ebac
--- /dev/null
+++ b/boost/spirit/home/x3/string.hpp
@@ -0,0 +1,17 @@
+/*=============================================================================
+ 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(BOOST_SPIRIT_X3_STRING_FEBRUARY_03_2007_0355PM)
+#define BOOST_SPIRIT_X3_STRING_FEBRUARY_03_2007_0355PM
+
+#if defined(_MSC_VER)
+#pragma once
+#endif
+
+#include <boost/spirit/home/x3/string/literal_string.hpp>
+#include <boost/spirit/home/x3/string/symbols.hpp>
+
+#endif
diff --git a/boost/spirit/home/x3/string/detail/string_parse.hpp b/boost/spirit/home/x3/string/detail/string_parse.hpp
new file mode 100644
index 0000000000..f7a77df804
--- /dev/null
+++ b/boost/spirit/home/x3/string/detail/string_parse.hpp
@@ -0,0 +1,89 @@
+/*=============================================================================
+ 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(BOOST_SPIRIT_X3_STRING_PARSE_APR_18_2006_1125PM)
+#define BOOST_SPIRIT_X3_STRING_PARSE_APR_18_2006_1125PM
+
+#if defined(_MSC_VER)
+#pragma once
+#endif
+
+#include <boost/spirit/home/x3/support/traits/move_to.hpp>
+
+namespace boost { namespace spirit { namespace x3 { namespace detail
+{
+ template <typename Char, typename Iterator, typename Attribute>
+ inline bool string_parse(
+ Char const* str
+ , Iterator& first, Iterator const& last, Attribute& attr)
+ {
+ Iterator i = first;
+ Char ch = *str;
+
+ for (; !!ch; ++i)
+ {
+ if (i == last || (ch != *i))
+ return false;
+ ch = *++str;
+ }
+
+ x3::traits::move_to(first, i, attr);
+ first = i;
+ return true;
+ }
+
+ template <typename String, typename Iterator, typename Attribute>
+ inline bool string_parse(
+ String const& str
+ , Iterator& first, Iterator const& last, Attribute& attr)
+ {
+ Iterator i = first;
+ typename String::const_iterator stri = str.begin();
+ typename String::const_iterator str_last = str.end();
+
+ for (; stri != str_last; ++stri, ++i)
+ if (i == last || (*stri != *i))
+ return false;
+ x3::traits::move_to(first, i, attr);
+ first = i;
+ return true;
+ }
+
+ template <typename Char, typename Iterator, typename Attribute>
+ inline bool string_parse(
+ Char const* uc_i, Char const* lc_i
+ , Iterator& first, Iterator const& last, Attribute& attr)
+ {
+ Iterator i = first;
+
+ for (; *uc_i && *lc_i; ++uc_i, ++lc_i, ++i)
+ if (i == last || ((*uc_i != *i) && (*lc_i != *i)))
+ return false;
+ x3::traits::move_to(first, i, attr);
+ first = i;
+ return true;
+ }
+
+ template <typename String, typename Iterator, typename Attribute>
+ inline bool string_parse(
+ String const& ucstr, String const& lcstr
+ , Iterator& first, Iterator const& last, Attribute& attr)
+ {
+ typename String::const_iterator uc_i = ucstr.begin();
+ typename String::const_iterator uc_last = ucstr.end();
+ typename String::const_iterator lc_i = lcstr.begin();
+ Iterator i = first;
+
+ for (; uc_i != uc_last; ++uc_i, ++lc_i, ++i)
+ if (i == last || ((*uc_i != *i) && (*lc_i != *i)))
+ return false;
+ x3::traits::move_to(first, i, attr);
+ first = i;
+ return true;
+ }
+}}}}
+
+#endif
diff --git a/boost/spirit/home/x3/string/detail/tst.hpp b/boost/spirit/home/x3/string/detail/tst.hpp
new file mode 100644
index 0000000000..df61f4dec7
--- /dev/null
+++ b/boost/spirit/home/x3/string/detail/tst.hpp
@@ -0,0 +1,213 @@
+/*=============================================================================
+ 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(BOOST_SPIRIT_X3_TST_MARCH_09_2007_0905AM)
+#define BOOST_SPIRIT_X3_TST_MARCH_09_2007_0905AM
+
+#if defined(_MSC_VER)
+#pragma once
+#endif
+
+#include <boost/call_traits.hpp>
+#include <boost/detail/iterator.hpp>
+#include <boost/foreach.hpp>
+#include <boost/assert.hpp>
+
+namespace boost { namespace spirit { namespace x3 { namespace detail
+{
+ // This file contains low level TST routines, not for
+ // public consumption.
+
+ template <typename Char, typename T>
+ struct tst_node
+ {
+ tst_node(Char id)
+ : id(id), data(0), lt(0), eq(0), gt(0)
+ {
+ }
+
+ template <typename Alloc>
+ static void
+ destruct_node(tst_node* p, Alloc* alloc)
+ {
+ if (p)
+ {
+ if (p->data)
+ alloc->delete_data(p->data);
+ destruct_node(p->lt, alloc);
+ destruct_node(p->eq, alloc);
+ destruct_node(p->gt, alloc);
+ alloc->delete_node(p);
+ }
+ }
+
+ template <typename Alloc>
+ static tst_node*
+ clone_node(tst_node* p, Alloc* alloc)
+ {
+ if (p)
+ {
+ tst_node* clone = alloc->new_node(p->id);
+ if (p->data)
+ clone->data = alloc->new_data(*p->data);
+ clone->lt = clone_node(p->lt, alloc);
+ clone->eq = clone_node(p->eq, alloc);
+ clone->gt = clone_node(p->gt, alloc);
+ return clone;
+ }
+ return 0;
+ }
+
+ template <typename Iterator, typename Filter>
+ static T*
+ find(tst_node* start, Iterator& first, Iterator last, Filter filter)
+ {
+ if (first == last)
+ return 0;
+
+ Iterator i = first;
+ Iterator latest = first;
+ tst_node* p = start;
+ T* found = 0;
+
+ while (p && i != last)
+ {
+ typename
+ boost::detail::iterator_traits<Iterator>::value_type
+ c = filter(*i); // filter only the input
+
+ if (c == p->id)
+ {
+ if (p->data)
+ {
+ found = p->data;
+ latest = i;
+ }
+ p = p->eq;
+ i++;
+ }
+ else if (c < p->id)
+ {
+ p = p->lt;
+ }
+ else
+ {
+ p = p->gt;
+ }
+ }
+
+ if (found)
+ first = ++latest; // one past the last matching char
+ return found;
+ }
+
+ template <typename Iterator, typename Alloc>
+ static T*
+ add(
+ tst_node*& start
+ , Iterator first
+ , Iterator last
+ , typename boost::call_traits<T>::param_type val
+ , Alloc* alloc)
+ {
+ if (first == last)
+ return 0;
+
+ tst_node** pp = &start;
+ for(;;)
+ {
+ typename
+ boost::detail::iterator_traits<Iterator>::value_type
+ c = *first;
+
+ if (*pp == 0)
+ *pp = alloc->new_node(c);
+ tst_node* p = *pp;
+
+ if (c == p->id)
+ {
+ if (++first == last)
+ {
+ if (p->data == 0)
+ p->data = alloc->new_data(val);
+ return p->data;
+ }
+ pp = &p->eq;
+ }
+ else if (c < p->id)
+ {
+ pp = &p->lt;
+ }
+ else
+ {
+ pp = &p->gt;
+ }
+ }
+ }
+
+ template <typename Iterator, typename Alloc>
+ static void
+ remove(tst_node*& p, Iterator first, Iterator last, Alloc* alloc)
+ {
+ if (p == 0 || first == last)
+ return;
+
+ typename
+ boost::detail::iterator_traits<Iterator>::value_type
+ c = *first;
+
+ if (c == p->id)
+ {
+ if (++first == last)
+ {
+ if (p->data)
+ {
+ alloc->delete_data(p->data);
+ p->data = 0;
+ }
+ }
+ remove(p->eq, first, last, alloc);
+ }
+ else if (c < p->id)
+ {
+ remove(p->lt, first, last, alloc);
+ }
+ else
+ {
+ remove(p->gt, first, last, alloc);
+ }
+
+ if (p->data == 0 && p->lt == 0 && p->eq == 0 && p->gt == 0)
+ {
+ alloc->delete_node(p);
+ p = 0;
+ }
+ }
+
+ template <typename F>
+ static void
+ for_each(tst_node* p, std::basic_string<Char> prefix, F f)
+ {
+ if (p)
+ {
+ for_each(p->lt, prefix, f);
+ std::basic_string<Char> s = prefix + p->id;
+ for_each(p->eq, s, f);
+ if (p->data)
+ f(s, *p->data);
+ for_each(p->gt, prefix, f);
+ }
+ }
+
+ Char id; // the node's identity character
+ T* data; // optional data
+ tst_node* lt; // left pointer
+ tst_node* eq; // middle pointer
+ tst_node* gt; // right pointer
+ };
+}}}}
+
+#endif
diff --git a/boost/spirit/home/x3/string/literal_string.hpp b/boost/spirit/home/x3/string/literal_string.hpp
new file mode 100644
index 0000000000..bf05a9a08e
--- /dev/null
+++ b/boost/spirit/home/x3/string/literal_string.hpp
@@ -0,0 +1,124 @@
+/*=============================================================================
+ 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(BOOST_SPIRIT_X3_LITERAL_STRING_APR_18_2006_1125PM)
+#define BOOST_SPIRIT_X3_LITERAL_STRING_APR_18_2006_1125PM
+
+#if defined(_MSC_VER)
+#pragma once
+#endif
+
+#include <boost/spirit/home/x3/core/parser.hpp>
+#include <boost/spirit/home/x3/core/skip_over.hpp>
+#include <boost/spirit/home/x3/string/detail/string_parse.hpp>
+#include <boost/spirit/home/x3/support/utility/utf8.hpp>
+#include <boost/spirit/home/support/char_encoding/ascii.hpp>
+#include <boost/spirit/home/support/char_encoding/standard.hpp>
+#include <boost/spirit/home/support/char_encoding/standard_wide.hpp>
+
+#include <boost/type_traits/is_same.hpp>
+#include <boost/type_traits/add_reference.hpp>
+#include <string>
+
+namespace boost { namespace spirit { namespace x3
+{
+ template <typename String, typename Encoding,
+ typename Attribute = std::basic_string<typename Encoding::char_type>>
+ struct literal_string : parser<literal_string<String, Encoding, Attribute>>
+ {
+ typedef typename Encoding::char_type char_type;
+ typedef Encoding encoding;
+ typedef Attribute attribute_type;
+ static bool const has_attribute =
+ !is_same<unused_type, attribute_type>::value;
+ static bool const handles_container = has_attribute;
+
+ literal_string(typename add_reference<String>::type str)
+ : str(str)
+ {}
+
+ template <typename Iterator, typename Context, typename Attribute_>
+ bool parse(Iterator& first, Iterator const& last
+ , Context const& context, unused_type, Attribute_& attr) const
+ {
+ x3::skip_over(first, last, context);
+ return detail::string_parse(str, first, last, attr);
+ }
+
+ String str;
+ };
+
+ namespace standard
+ {
+ inline literal_string<char const*, char_encoding::standard>
+ string(char const* s)
+ {
+ return literal_string<char const*, char_encoding::standard>(s);
+ }
+ }
+ using standard::string;
+
+ namespace extension
+ {
+ template <int N>
+ struct as_parser<char[N]>
+ {
+ typedef
+ literal_string<
+ char const*, char_encoding::standard, unused_type>
+ type;
+
+ typedef type value_type;
+
+ static type call(char const* s)
+ {
+ return type(s);
+ }
+ };
+
+ template <int N>
+ struct as_parser<char const[N]> : as_parser<char[N]> {};
+
+ template <int N>
+ struct as_parser<wchar_t[N]>
+ {
+ typedef
+ literal_string<
+ wchar_t const*, char_encoding::standard_wide, unused_type>
+ type;
+
+ typedef type value_type;
+
+ static type call(wchar_t const* s)
+ {
+ return type(s);
+ }
+ };
+
+ template <int N>
+ struct as_parser<wchar_t const[N]> : as_parser<wchar_t[N]> {};
+ }
+
+ using standard::string;
+
+ inline literal_string<char const*, char_encoding::standard, unused_type>
+ lit(char const* s)
+ {
+ return literal_string<char const*, char_encoding::standard, unused_type>(s);
+ }
+
+ template <typename String, typename Encoding, typename Attribute>
+ struct get_info<literal_string<String, Encoding, Attribute>>
+ {
+ typedef std::string result_type;
+ std::string operator()(literal_string<String, Encoding, Attribute> const& p) const
+ {
+ return '"' + to_utf8(p.str) + '"';
+ }
+ };
+}}}
+
+#endif
diff --git a/boost/spirit/home/x3/string/symbols.hpp b/boost/spirit/home/x3/string/symbols.hpp
new file mode 100644
index 0000000000..b35a00a121
--- /dev/null
+++ b/boost/spirit/home/x3/string/symbols.hpp
@@ -0,0 +1,358 @@
+/*=============================================================================
+ Copyright (c) 2001-2014 Joel de Guzman
+ Copyright (c) 2013 Carl Barron
+
+ 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(BOOST_SPIRIT_X3_SYMBOLS_MARCH_11_2007_1055AM)
+#define BOOST_SPIRIT_X3_SYMBOLS_MARCH_11_2007_1055AM
+
+#if defined(_MSC_VER)
+#pragma once
+#endif
+
+#include <boost/spirit/home/x3/core/skip_over.hpp>
+#include <boost/spirit/home/x3/core/parser.hpp>
+#include <boost/spirit/home/x3/string/tst.hpp>
+#include <boost/spirit/home/x3/support/unused.hpp>
+#include <boost/spirit/home/x3/support/traits/string_traits.hpp>
+#include <boost/spirit/home/x3/support/traits/move_to.hpp>
+
+#include <boost/fusion/include/at.hpp>
+#include <boost/range.hpp>
+#include <boost/type_traits/add_reference.hpp>
+#include <boost/type_traits/is_same.hpp>
+#include <boost/shared_ptr.hpp>
+
+#include <initializer_list>
+
+#if defined(BOOST_MSVC)
+# pragma warning(push)
+# pragma warning(disable: 4355) // 'this' : used in base member initializer list warning
+#endif
+
+namespace boost { namespace spirit { namespace x3
+{
+ template <
+ typename Char = char
+ , typename T = unused_type
+ , typename Lookup = tst<Char, T>
+ , typename Filter = tst_pass_through>
+ struct symbols : parser<symbols<Char, T, Lookup, Filter>>
+ {
+ typedef Char char_type; // the character type
+ typedef T value_type; // the value associated with each entry
+ typedef symbols<Char, T, Lookup, Filter> this_type;
+ typedef value_type attribute_type;
+
+ static bool const has_attribute =
+ !is_same<unused_type, attribute_type>::value;
+ static bool const handles_container =
+ traits::is_container<attribute_type>::value;
+
+ symbols(std::string const& name = "symbols")
+ : add(*this)
+ , remove(*this)
+ , lookup(new Lookup())
+ , name_(name)
+ {
+ }
+
+ symbols(symbols const& syms)
+ : add(*this)
+ , remove(*this)
+ , lookup(syms.lookup)
+ , name_(syms.name_)
+ {
+ }
+
+ template <typename Filter_>
+ symbols(symbols<Char, T, Lookup, Filter_> const& syms)
+ : add(*this)
+ , remove(*this)
+ , lookup(syms.lookup)
+ , name_(syms.name_)
+ {
+ }
+
+ template <typename Symbols>
+ symbols(Symbols const& syms, std::string const& name = "symbols")
+ : add(*this)
+ , remove(*this)
+ , lookup(new Lookup())
+ , name_(name)
+ {
+ typename range_const_iterator<Symbols>::type si = boost::begin(syms);
+ while (si != boost::end(syms))
+ add(*si++);
+ }
+
+ template <typename Symbols, typename Data>
+ symbols(Symbols const& syms, Data const& data
+ , std::string const& name = "symbols")
+ : add(*this)
+ , remove(*this)
+ , lookup(new Lookup())
+ , name_(name)
+ {
+ typename range_const_iterator<Symbols>::type si = boost::begin(syms);
+ typename range_const_iterator<Data>::type di = boost::begin(data);
+ while (si != boost::end(syms))
+ add(*si++, *di++);
+ }
+
+ symbols(std::initializer_list<std::pair<Char const*, T>> syms
+ , std::string const & name="symbols")
+ : add(*this)
+ , remove(*this)
+ , lookup(new Lookup())
+ , name_(name)
+ {
+ typedef std::initializer_list<std::pair<Char const*, T>> symbols_t;
+ typename range_const_iterator<symbols_t>::type si = boost::begin(syms);
+ for (;si != boost::end(syms); ++si)
+ add(si->first, si->second);
+ }
+
+ symbols(std::initializer_list<Char const*> syms
+ , std::string const &name="symbols")
+ : add(*this)
+ , remove(*this)
+ , lookup(new Lookup())
+ , name_(name)
+ {
+ typedef std::initializer_list<Char const*> symbols_t;
+ typename range_const_iterator<symbols_t>::type si = boost::begin(syms);
+ while (si != boost::end(syms))
+ add(*si++);
+ }
+
+ symbols&
+ operator=(symbols const& rhs)
+ {
+ name_ = rhs.name_;
+ lookup = rhs.lookup;
+ return *this;
+ }
+
+ template <typename Filter_>
+ symbols&
+ operator=(symbols<Char, T, Lookup, Filter_> const& rhs)
+ {
+ name_ = rhs.name_;
+ lookup = rhs.lookup;
+ return *this;
+ }
+
+ void clear()
+ {
+ lookup->clear();
+ }
+
+ struct adder;
+ struct remover;
+
+ template <typename Str>
+ adder const&
+ operator=(Str const& str)
+ {
+ lookup->clear();
+ return add(str);
+ }
+
+ template <typename Str>
+ friend adder const&
+ operator+=(symbols& sym, Str const& str)
+ {
+ return sym.add(str);
+ }
+
+ template <typename Str>
+ friend remover const&
+ operator-=(symbols& sym, Str const& str)
+ {
+ return sym.remove(str);
+ }
+
+ template <typename F>
+ void for_each(F f) const
+ {
+ lookup->for_each(f);
+ }
+
+ template <typename Str>
+ value_type& at(Str const& str)
+ {
+ return *lookup->add(traits::get_string_begin<Char>(str)
+ , traits::get_string_end<Char>(str), T());
+ }
+
+ template <typename Iterator>
+ value_type* prefix_find(Iterator& first, Iterator const& last)
+ {
+ return lookup->find(first, last, Filter());
+ }
+
+ template <typename Iterator>
+ value_type const* prefix_find(Iterator& first, Iterator const& last) const
+ {
+ return lookup->find(first, last, Filter());
+ }
+
+ template <typename Str>
+ value_type* find(Str const& str)
+ {
+ return find_impl(traits::get_string_begin<Char>(str)
+ , traits::get_string_end<Char>(str));
+ }
+
+ template <typename Str>
+ value_type const* find(Str const& str) const
+ {
+ return find_impl(traits::get_string_begin<Char>(str)
+ , traits::get_string_end<Char>(str));
+ }
+
+ private:
+ template <typename Iterator>
+ value_type* find_impl(Iterator begin, Iterator end)
+ {
+ value_type* r = lookup->find(begin, end, Filter());
+ return begin == end ? r : 0;
+ }
+
+ template <typename Iterator>
+ value_type const* find_impl(Iterator begin, Iterator end) const
+ {
+ value_type const* r = lookup->find(begin, end, Filter());
+ return begin == end ? r : 0;
+ }
+
+ public:
+ template <typename Iterator, typename Context, typename Attribute>
+ bool parse(Iterator& first, Iterator const& last
+ , Context const& context, unused_type, Attribute& attr) const
+ {
+ x3::skip_over(first, last, context);
+
+ if (value_type* val_ptr
+ = lookup->find(first, last, Filter()))
+ {
+ x3::traits::move_to(*val_ptr, attr);
+ return true;
+ }
+ return false;
+ }
+
+ void name(std::string const &str)
+ {
+ name_ = str;
+ }
+ std::string const &name() const
+ {
+ return name_;
+ }
+
+ struct adder
+ {
+ template <typename, typename = unused_type, typename = unused_type>
+ struct result { typedef adder const& type; };
+
+ adder(symbols& sym)
+ : sym(sym)
+ {
+ }
+
+ template <typename Iterator>
+ adder const&
+ operator()(Iterator first, Iterator last, T const& val) const
+ {
+ sym.lookup->add(first, last, val);
+ return *this;
+ }
+
+ template <typename Str>
+ adder const&
+ operator()(Str const& s, T const& val = T()) const
+ {
+ sym.lookup->add(traits::get_string_begin<Char>(s)
+ , traits::get_string_end<Char>(s), val);
+ return *this;
+ }
+
+ template <typename Str>
+ adder const&
+ operator,(Str const& s) const
+ {
+ sym.lookup->add(traits::get_string_begin<Char>(s)
+ , traits::get_string_end<Char>(s), T());
+ return *this;
+ }
+
+ symbols& sym;
+ };
+
+ struct remover
+ {
+ template <typename, typename = unused_type, typename = unused_type>
+ struct result { typedef remover const& type; };
+
+ remover(symbols& sym)
+ : sym(sym)
+ {
+ }
+
+ template <typename Iterator>
+ remover const&
+ operator()(Iterator const& first, Iterator const& last) const
+ {
+ sym.lookup->remove(first, last);
+ return *this;
+ }
+
+ template <typename Str>
+ remover const&
+ operator()(Str const& s) const
+ {
+ sym.lookup->remove(traits::get_string_begin<Char>(s)
+ , traits::get_string_end<Char>(s));
+ return *this;
+ }
+
+ template <typename Str>
+ remover const&
+ operator,(Str const& s) const
+ {
+ sym.lookup->remove(traits::get_string_begin<Char>(s)
+ , traits::get_string_end<Char>(s));
+ return *this;
+ }
+
+ symbols& sym;
+ };
+
+ adder add;
+ remover remove;
+ shared_ptr<Lookup> lookup;
+ std::string name_;
+ };
+
+ template <typename Char, typename T, typename Lookup, typename Filter>
+ struct get_info<symbols<Char, T, Lookup, Filter>>
+ {
+ typedef std::string result_type;
+ result_type operator()(symbols< Char, T
+ , Lookup, Filter
+ > const& symbols) const
+ {
+ return symbols.name();
+ }
+ };
+}}}
+
+#if defined(BOOST_MSVC)
+# pragma warning(pop)
+#endif
+
+#endif
diff --git a/boost/spirit/home/x3/string/tst.hpp b/boost/spirit/home/x3/string/tst.hpp
new file mode 100644
index 0000000000..5379b032be
--- /dev/null
+++ b/boost/spirit/home/x3/string/tst.hpp
@@ -0,0 +1,137 @@
+/*=============================================================================
+ 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(BOOST_SPIRIT_X3_TST_JUNE_03_2007_1031AM)
+#define BOOST_SPIRIT_X3_TST_JUNE_03_2007_1031AM
+
+#if defined(_MSC_VER)
+#pragma once
+#endif
+
+#include <boost/spirit/home/x3/string/detail/tst.hpp>
+
+namespace boost { namespace spirit { namespace x3
+{
+ struct tst_pass_through
+ {
+ template <typename Char>
+ Char operator()(Char ch) const
+ {
+ return ch;
+ }
+ };
+
+ template <typename Char, typename T>
+ struct tst
+ {
+ typedef Char char_type; // the character type
+ typedef T value_type; // the value associated with each entry
+ typedef detail::tst_node<Char, T> node;
+
+ tst()
+ : root(0)
+ {
+ }
+
+ ~tst()
+ {
+ clear();
+ }
+
+ tst(tst const& rhs)
+ : root(0)
+ {
+ copy(rhs);
+ }
+
+ tst& operator=(tst const& rhs)
+ {
+ return assign(rhs);
+ }
+
+ template <typename Iterator, typename Filter>
+ T* find(Iterator& first, Iterator last, Filter filter) const
+ {
+ return node::find(root, first, last, filter);
+ }
+
+ template <typename Iterator>
+ T* find(Iterator& first, Iterator last) const
+ {
+ return find(first, last, tst_pass_through());
+ }
+
+ template <typename Iterator>
+ T* add(
+ Iterator first
+ , Iterator last
+ , typename boost::call_traits<T>::param_type val)
+ {
+ return node::add(root, first, last, val, this);
+ }
+
+ template <typename Iterator>
+ void remove(Iterator first, Iterator last)
+ {
+ node::remove(root, first, last, this);
+ }
+
+ void clear()
+ {
+ node::destruct_node(root, this);
+ root = 0;
+ }
+
+ template <typename F>
+ void for_each(F f) const
+ {
+ node::for_each(root, std::basic_string<Char>(), f);
+ }
+
+ private:
+
+ friend struct detail::tst_node<Char, T>;
+
+ void copy(tst const& rhs)
+ {
+ root = node::clone_node(rhs.root, this);
+ }
+
+ tst& assign(tst const& rhs)
+ {
+ if (this != &rhs)
+ {
+ clear();
+ copy(rhs);
+ }
+ return *this;
+ }
+
+ node* root;
+
+ node* new_node(Char id)
+ {
+ return new node(id);
+ }
+
+ T* new_data(typename boost::call_traits<T>::param_type val)
+ {
+ return new T(val);
+ }
+
+ void delete_node(node* p)
+ {
+ delete p;
+ }
+
+ void delete_data(T* p)
+ {
+ delete p;
+ }
+ };
+}}}
+
+#endif
diff --git a/boost/spirit/home/x3/string/tst_map.hpp b/boost/spirit/home/x3/string/tst_map.hpp
new file mode 100644
index 0000000000..2501324de6
--- /dev/null
+++ b/boost/spirit/home/x3/string/tst_map.hpp
@@ -0,0 +1,216 @@
+/*=============================================================================
+ 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(BOOST_SPIRIT_X3_TST_MAP_JUNE_03_2007_1143AM)
+#define BOOST_SPIRIT_X3_TST_MAP_JUNE_03_2007_1143AM
+
+#if defined(_MSC_VER)
+#pragma once
+#endif
+
+#include <boost/spirit/home/x3/string/detail/tst.hpp>
+#include <unordered_map>
+#include <boost/pool/object_pool.hpp>
+
+namespace boost { namespace spirit { namespace x3
+{
+ struct tst_pass_through; // declared in tst.hpp
+
+ template <typename Char, typename T>
+ struct tst_map
+ {
+ typedef Char char_type; // the character type
+ typedef T value_type; // the value associated with each entry
+ typedef detail::tst_node<Char, T> node;
+
+ tst_map()
+ {
+ }
+
+ ~tst_map()
+ {
+ // Nothing to do here.
+ // The pools do the right thing for us
+ }
+
+ tst_map(tst_map const& rhs)
+ {
+ copy(rhs);
+ }
+
+ tst_map& operator=(tst_map const& rhs)
+ {
+ return assign(rhs);
+ }
+
+ template <typename Iterator, typename Filter>
+ T* find(Iterator& first, Iterator last, Filter filter) const
+ {
+ if (first != last)
+ {
+ Iterator save = first;
+ typename map_type::const_iterator
+ i = map.find(filter(*first++));
+ if (i == map.end())
+ {
+ first = save;
+ return 0;
+ }
+ if (T* p = node::find(i->second.root, first, last, filter))
+ {
+ return p;
+ }
+ return i->second.data;
+ }
+ return 0;
+ }
+
+ template <typename Iterator>
+ T* find(Iterator& first, Iterator last) const
+ {
+ return find(first, last, tst_pass_through());
+ }
+
+ template <typename Iterator>
+ bool add(
+ Iterator first
+ , Iterator last
+ , typename boost::call_traits<T>::param_type val)
+ {
+ if (first != last)
+ {
+ map_data x = {0, 0};
+ std::pair<typename map_type::iterator, bool>
+ r = map.insert(std::pair<Char, map_data>(*first++, x));
+
+ if (first != last)
+ {
+ return node::add(r.first->second.root
+ , first, last, val, this) ? true : false;
+ }
+ else
+ {
+ if (r.first->second.data)
+ return false;
+ r.first->second.data = this->new_data(val);
+ }
+ return true;
+ }
+ return false;
+ }
+
+ template <typename Iterator>
+ void remove(Iterator first, Iterator last)
+ {
+ if (first != last)
+ {
+ typename map_type::iterator i = map.find(*first++);
+ if (i != map.end())
+ {
+ if (first != last)
+ {
+ node::remove(i->second.root, first, last, this);
+ }
+ else if (i->second.data)
+ {
+ this->delete_data(i->second.data);
+ i->second.data = 0;
+ }
+ if (i->second.data == 0 && i->second.root == 0)
+ {
+ map.erase(i);
+ }
+ }
+ }
+ }
+
+ void clear()
+ {
+ BOOST_FOREACH(typename map_type::value_type& x, map)
+ {
+ node::destruct_node(x.second.root, this);
+ if (x.second.data)
+ this->delete_data(x.second.data);
+ }
+ map.clear();
+ }
+
+ template <typename F>
+ void for_each(F f) const
+ {
+ BOOST_FOREACH(typename map_type::value_type const& x, map)
+ {
+ std::basic_string<Char> s(1, x.first);
+ node::for_each(x.second.root, s, f);
+ if (x.second.data)
+ f(s, *x.second.data);
+ }
+ }
+
+ private:
+
+ friend struct detail::tst_node<Char, T>;
+
+ struct map_data
+ {
+ node* root;
+ T* data;
+ };
+
+ typedef std::unordered_map<Char, map_data> map_type;
+
+ void copy(tst_map const& rhs)
+ {
+ BOOST_FOREACH(typename map_type::value_type const& x, rhs.map)
+ {
+ map_data xx = {node::clone_node(x.second.root, this), 0};
+ if (x.second.data)
+ xx.data = data_pool.construct(*x.second.data);
+ map[x.first] = xx;
+ }
+ }
+
+ tst_map& assign(tst_map const& rhs)
+ {
+ if (this != &rhs)
+ {
+ BOOST_FOREACH(typename map_type::value_type& x, map)
+ {
+ node::destruct_node(x.second.root, this);
+ }
+ map.clear();
+ copy(rhs);
+ }
+ return *this;
+ }
+
+ node* new_node(Char id)
+ {
+ return node_pool.construct(id);
+ }
+
+ T* new_data(typename boost::call_traits<T>::param_type val)
+ {
+ return data_pool.construct(val);
+ }
+
+ void delete_node(node* p)
+ {
+ node_pool.destroy(p);
+ }
+
+ void delete_data(T* p)
+ {
+ data_pool.destroy(p);
+ }
+
+ map_type map;
+ object_pool<node> node_pool;
+ object_pool<T> data_pool;
+ };
+}}}
+
+#endif
diff --git a/boost/spirit/home/x3/support/ast/position_tagged.hpp b/boost/spirit/home/x3/support/ast/position_tagged.hpp
new file mode 100644
index 0000000000..22cfd7588b
--- /dev/null
+++ b/boost/spirit/home/x3/support/ast/position_tagged.hpp
@@ -0,0 +1,96 @@
+/*=============================================================================
+ Copyright (c) 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(BOOST_SPIRIT_X3_POSITION_TAGGED_MAY_01_2014_0321PM)
+#define BOOST_SPIRIT_X3_POSITION_TAGGED_MAY_01_2014_0321PM
+
+#include <boost/range.hpp>
+#include <boost/type_traits/is_base_of.hpp>
+
+namespace boost { namespace spirit { namespace x3
+{
+ struct position_tagged
+ {
+ // Use this to annotate an AST with the iterator position.
+ // These ids are used as a key to the position_cache (below)
+ // and marks the start and end of an AST node.
+ int id_first = -1;
+ int id_last = -1;
+ };
+
+ template <typename Container>
+ class position_cache
+ {
+ public:
+
+ typedef typename Container::value_type iterator_type;
+
+ position_cache(
+ iterator_type first
+ , iterator_type last)
+ : first_(first), last_(last) {}
+
+ // This will catch all nodes inheriting from position_tagged
+ boost::iterator_range<iterator_type>
+ position_of(position_tagged const& ast) const
+ {
+ return
+ boost::iterator_range<iterator_type>(
+ positions.at(ast.id_first) // throws if out of range
+ , positions.at(ast.id_last) // throws if out of range
+ );
+ }
+
+ // This will catch all nodes except those inheriting from position_tagged
+ template <typename AST>
+ boost::iterator_range<iterator_type>
+ position_of(AST const& ast) const
+ {
+ // returns an empty position
+ return boost::iterator_range<iterator_type>();
+ }
+
+ // This will catch all nodes except those inheriting from position_tagged
+ template <typename AST>
+ void annotate(AST& ast, iterator_type first, iterator_type last, mpl::false_)
+ {
+ // (no-op) no need for tags
+ }
+
+ // This will catch all nodes inheriting from position_tagged
+ void annotate(position_tagged& ast, iterator_type first, iterator_type last, mpl::true_)
+ {
+ ast.id_first = int(positions.size());
+ positions.push_back(first);
+ ast.id_last = int(positions.size());
+ positions.push_back(last);
+ }
+
+ template <typename AST>
+ void annotate(AST& ast, iterator_type first, iterator_type last)
+ {
+ annotate(ast, first, last, is_base_of<position_tagged, AST>());
+ }
+
+ Container const&
+ get_positions() const
+ {
+ return positions;
+ }
+
+ iterator_type first() const { return first_; }
+ iterator_type last() const { return last_; }
+
+ private:
+
+ Container positions;
+ iterator_type first_;
+ iterator_type last_;
+ };
+
+}}}
+
+#endif
diff --git a/boost/spirit/home/x3/support/ast/variant.hpp b/boost/spirit/home/x3/support/ast/variant.hpp
new file mode 100644
index 0000000000..cf626e88be
--- /dev/null
+++ b/boost/spirit/home/x3/support/ast/variant.hpp
@@ -0,0 +1,249 @@
+/*=============================================================================
+ 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(BOOST_SPIRIT_X3_VARIANT_AUGUST_6_2011_0859AM)
+#define BOOST_SPIRIT_X3_VARIANT_AUGUST_6_2011_0859AM
+
+#if defined(_MSC_VER)
+#pragma once
+#endif
+
+#include <boost/variant.hpp>
+#include <boost/mpl/list.hpp>
+#include <boost/type_traits/is_base_of.hpp>
+
+///////////////////////////////////////////////////////////////////////////////
+namespace boost { namespace spirit { namespace x3
+{
+ template <typename T>
+ class forward_ast
+ {
+ public:
+
+ typedef T type;
+
+ public:
+
+ forward_ast() : p_(new T) {}
+
+ forward_ast(forward_ast const& operand)
+ : p_(new T(operand.get())) {}
+
+ forward_ast(forward_ast&& operand)
+ : p_(operand.p_)
+ {
+ operand.p_ = 0;
+ }
+
+ forward_ast(T const& operand)
+ : p_(new T(operand)) {}
+
+ forward_ast(T&& operand)
+ : p_(new T(std::move(operand))) {}
+
+ ~forward_ast()
+ {
+ boost::checked_delete(p_);
+ }
+
+ forward_ast& operator=(forward_ast const& rhs)
+ {
+ assign(rhs.get());
+ return *this;
+ }
+
+ void swap(forward_ast& operand) BOOST_NOEXCEPT
+ {
+ T* temp = operand.p_;
+ operand.p_ = p_;
+ p_ = temp;
+ }
+
+ forward_ast& operator=(T const& rhs)
+ {
+ assign(rhs);
+ return *this;
+ }
+
+ forward_ast& operator=(forward_ast&& rhs) BOOST_NOEXCEPT
+ {
+ swap(rhs);
+ return *this;
+ }
+
+ forward_ast& operator=(T&& rhs)
+ {
+ get() = std::move(rhs);
+ return *this;
+ }
+
+ T& get() { return *get_pointer(); }
+ const T& get() const { return *get_pointer(); }
+
+ T* get_pointer() { return p_; }
+ const T* get_pointer() const { return p_; }
+
+ operator T const&() const { return this->get(); }
+ operator T&() { return this->get(); }
+
+ private:
+
+ void assign(const T& rhs)
+ {
+ this->get() = rhs;
+ }
+
+ T* p_;
+ };
+
+ // function template swap
+ //
+ // Swaps two forward_ast<T> objects of the same type T.
+ //
+ template <typename T>
+ inline void swap(forward_ast<T>& lhs, forward_ast<T>& rhs) BOOST_NOEXCEPT
+ {
+ lhs.swap(rhs);
+ }
+
+ namespace detail
+ {
+ template <typename T>
+ struct remove_forward : mpl::identity<T>
+ {};
+
+ template <typename T>
+ struct remove_forward<forward_ast<T>> : mpl::identity<T>
+ {};
+ }
+
+ template <typename ...Types>
+ struct variant
+ {
+ // tell spirit that this is an adapted variant
+ struct adapted_variant_tag;
+
+ typedef boost::variant<Types...> variant_type;
+ typedef mpl::list<typename detail::remove_forward<Types>::type...> types;
+ typedef variant<Types...> base_type;
+
+ variant() : var() {}
+
+ template <typename T, typename disable_if<is_base_of<base_type, T>>::type>
+ explicit variant(T const& rhs)
+ : var(rhs) {}
+
+ template <typename T, typename disable_if<is_base_of<base_type, T>>::type>
+ explicit variant(T&& rhs)
+ : var(std::forward<T>(rhs)) {}
+
+ variant(variant const& rhs)
+ : var(rhs.var) {}
+
+ variant(variant& rhs)
+ : var(rhs.var) {}
+
+ variant(variant&& rhs)
+ : var(std::forward<variant_type>(rhs.var)) {}
+
+ variant& operator=(variant const& rhs)
+ {
+ var = rhs.get();
+ return *this;
+ }
+
+ variant& operator=(variant&& rhs)
+ {
+ var = std::forward<variant_type>(rhs.get());
+ return *this;
+ }
+
+ template <typename T>
+ //typename disable_if<is_base_of<base_type, T>, variant&>::type
+ variant& operator=(T const& rhs)
+ {
+ var = rhs;
+ return *this;
+ }
+
+ template <typename T>
+ //typename disable_if<is_base_of<base_type, T>, variant&>::type
+ variant& operator=(T&& rhs)
+ {
+ var = std::forward<T>(rhs);
+ return *this;
+ }
+
+ template <typename F>
+ typename F::result_type apply_visitor(F const& v)
+ {
+ return var.apply_visitor(v);
+ }
+
+ template <typename F>
+ typename F::result_type apply_visitor(F const& v) const
+ {
+ return var.apply_visitor(v);
+ }
+
+ template <typename F>
+ typename F::result_type apply_visitor(F& v)
+ {
+ return var.apply_visitor(v);
+ }
+
+ template <typename F>
+ typename F::result_type apply_visitor(F& v) const
+ {
+ return var.apply_visitor(v);
+ }
+
+ variant_type const& get() const
+ {
+ return var;
+ }
+
+ variant_type& get()
+ {
+ return var;
+ }
+
+ variant_type var;
+ };
+}}}
+
+namespace boost
+{
+ template <typename T, typename ...Types>
+ inline T const&
+ get(boost::spirit::x3::variant<Types...> const& x)
+ {
+ return boost::get<T>(x.get());
+ }
+
+ template <typename T, typename ...Types>
+ inline T&
+ get(boost::spirit::x3::variant<Types...>& x)
+ {
+ return boost::get<T>(x.get());
+ }
+
+ template <typename T, typename ...Types>
+ inline T const*
+ get(boost::spirit::x3::variant<Types...> const* x)
+ {
+ return boost::get<T>(&x->get());
+ }
+
+ template <typename T, typename ...Types>
+ inline T*
+ get(boost::spirit::x3::variant<Types...>* x)
+ {
+ return boost::get<T>(&x->get());
+ }
+}
+
+#endif
diff --git a/boost/spirit/home/x3/support/context.hpp b/boost/spirit/home/x3/support/context.hpp
new file mode 100644
index 0000000000..93bcb24070
--- /dev/null
+++ b/boost/spirit/home/x3/support/context.hpp
@@ -0,0 +1,135 @@
+/*=============================================================================
+ Copyright (c) 2001-2014 Joel de Guzman
+ http://spirit.sourceforge.net/
+
+ 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(BOOST_SPIRIT_X3_CONTEXT_JAN_4_2012_1215PM)
+#define BOOST_SPIRIT_X3_CONTEXT_JAN_4_2012_1215PM
+
+#if defined(_MSC_VER)
+#pragma once
+#endif
+
+#include <boost/spirit/home/x3/support/unused.hpp>
+#include <boost/mpl/identity.hpp>
+
+namespace boost { namespace spirit { namespace x3
+{
+ template <typename ID, typename T, typename Next = unused_type>
+ struct context
+ {
+ context(T& val, Next const& next)
+ : val(val), next(next) {}
+
+ template <typename ID_, typename Unused = void>
+ struct get_result
+ {
+ typedef typename Next::template get_result<ID_>::type type;
+ };
+
+ template <typename Unused>
+ struct get_result<mpl::identity<ID>, Unused>
+ {
+ typedef T& type;
+ };
+
+ T& get(mpl::identity<ID>) const
+ {
+ return val;
+ }
+
+ template <typename ID_>
+ typename Next::template get_result<ID_>::type
+ get(ID_ id) const
+ {
+ return next.get(id);
+ }
+
+ T& val;
+ Next const& next;
+ };
+
+ template <typename ID, typename T>
+ struct context<ID, T, unused_type>
+ {
+ context(T& val)
+ : val(val) {}
+
+ context(T& val, unused_type)
+ : val(val) {}
+
+ template <typename ID_, typename Unused = void>
+ struct get_result
+ {
+ typedef unused_type type;
+ };
+
+ template <typename Unused>
+ struct get_result<mpl::identity<ID>, Unused>
+ {
+ typedef T& type;
+ };
+
+ T& get(mpl::identity<ID>) const
+ {
+ return val;
+ }
+
+ template <typename ID_>
+ unused_type
+ get(ID_) const
+ {
+ return unused;
+ }
+
+ T& val;
+ };
+
+ template <typename Tag, typename Context>
+ inline auto
+ get(Context const& context)
+ -> decltype(context.get(mpl::identity<Tag>()))
+ {
+ return context.get(mpl::identity<Tag>());
+ }
+
+ template <typename ID, typename T, typename Next>
+ inline context<ID, T, Next> make_context(T& val, Next const& next)
+ {
+ return context<ID, T, Next>(val, next);
+ }
+
+ template <typename ID, typename T>
+ inline context<ID, T> make_context(T& val)
+ {
+ return context<ID, T>(val);
+ }
+
+ namespace detail
+ {
+ template <typename ID, typename T, typename Next, typename FoundVal>
+ inline Next const&
+ make_unique_context(T& val, Next const& next, FoundVal&)
+ {
+ return next;
+ }
+
+ template <typename ID, typename T, typename Next>
+ inline context<ID, T, Next>
+ make_unique_context(T& val, Next const& next, unused_type)
+ {
+ return context<ID, T, Next>(val, next);
+ }
+ }
+
+ template <typename ID, typename T, typename Next>
+ inline auto
+ make_unique_context(T& val, Next const& next)
+ {
+ return detail::make_unique_context<ID>(val, next, x3::get<ID>(next));
+ }
+}}}
+
+#endif
diff --git a/boost/spirit/home/x3/support/numeric_utils/detail/extract_int.hpp b/boost/spirit/home/x3/support/numeric_utils/detail/extract_int.hpp
new file mode 100644
index 0000000000..73770c87d0
--- /dev/null
+++ b/boost/spirit/home/x3/support/numeric_utils/detail/extract_int.hpp
@@ -0,0 +1,512 @@
+/*=============================================================================
+ Copyright (c) 2001-2014 Joel de Guzman
+ Copyright (c) 2001-2011 Hartmut Kaiser
+ Copyright (c) 2011 Jan Frederick Eick
+ Copyright (c) 2011 Christopher Jefferson
+ Copyright (c) 2006 Stephen Nutt
+
+ 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(BOOST_SPIRIT_X3_DETAIL_EXTRACT_INT_APRIL_17_2006_0816AM)
+#define BOOST_SPIRIT_X3_DETAIL_EXTRACT_INT_APRIL_17_2006_0816AM
+
+#if defined(_MSC_VER)
+#pragma once
+#endif
+
+#include <boost/spirit/home/x3/support/unused.hpp>
+#include <boost/spirit/home/x3/support/traits/attribute_type.hpp>
+#include <boost/spirit/home/x3/support/traits/move_to.hpp>
+#include <boost/spirit/home/x3/support/traits/numeric_traits.hpp>
+#include <boost/spirit/home/support/char_encoding/ascii.hpp>
+
+#include <boost/preprocessor/repetition/repeat.hpp>
+#include <boost/preprocessor/iteration/local.hpp>
+#include <boost/preprocessor/comparison/less.hpp>
+#include <boost/preprocessor/control/if.hpp>
+#include <boost/preprocessor/seq/elem.hpp>
+
+#include <boost/detail/iterator.hpp>
+#include <boost/utility/enable_if.hpp>
+
+#include <boost/type_traits/is_integral.hpp>
+#include <boost/type_traits/is_signed.hpp>
+#include <boost/type_traits/make_unsigned.hpp>
+
+#include <boost/mpl/bool.hpp>
+#include <boost/mpl/and.hpp>
+#include <boost/limits.hpp>
+
+#if !defined(SPIRIT_NUMERICS_LOOP_UNROLL)
+# define SPIRIT_NUMERICS_LOOP_UNROLL 3
+#endif
+
+namespace boost { namespace spirit { namespace x3 { namespace detail
+{
+ ///////////////////////////////////////////////////////////////////////////
+ //
+ // The maximum radix digits that can be represented without
+ // overflow:
+ //
+ // template<typename T, unsigned Radix>
+ // struct digits_traits::value;
+ //
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename T, unsigned Radix>
+ struct digits_traits;
+
+// lookup table for log2(x) : 2 <= x <= 36
+#define BOOST_SPIRIT_X3_LOG2 (#error)(#error) \
+ (1000000)(1584960)(2000000)(2321920)(2584960)(2807350) \
+ (3000000)(3169920)(3321920)(3459430)(3584960)(3700430) \
+ (3807350)(3906890)(4000000)(4087460)(4169920)(4247920) \
+ (4321920)(4392310)(4459430)(4523560)(4584960)(4643850) \
+ (4700430)(4754880)(4807350)(4857980)(4906890)(4954190) \
+ (5000000)(5044390)(5087460)(5129280)(5169925) \
+ /***/
+
+#define BOOST_PP_LOCAL_MACRO(Radix) \
+ template <typename T> struct digits_traits<T, Radix> \
+ { \
+ typedef std::numeric_limits<T> numeric_limits_type; \
+ BOOST_STATIC_CONSTANT(int, value = static_cast<int>( \
+ (numeric_limits_type::digits * 1000000) / \
+ BOOST_PP_SEQ_ELEM(Radix, BOOST_SPIRIT_X3_LOG2))); \
+ }; \
+ /***/
+
+#define BOOST_PP_LOCAL_LIMITS (2, 36)
+#include BOOST_PP_LOCAL_ITERATE()
+
+#undef BOOST_SPIRIT_X3_LOG2
+
+ ///////////////////////////////////////////////////////////////////////////
+ //
+ // Traits class for radix specific number conversion
+ //
+ // Test the validity of a single character:
+ //
+ // template<typename Char> static bool is_valid(Char ch);
+ //
+ // Convert a digit from character representation to binary
+ // representation:
+ //
+ // template<typename Char> static int digit(Char ch);
+ //
+ ///////////////////////////////////////////////////////////////////////////
+ template <unsigned Radix>
+ struct radix_traits
+ {
+ template <typename Char>
+ inline static bool is_valid(Char ch)
+ {
+ if (Radix <= 10)
+ return (ch >= '0' && ch <= static_cast<Char>('0' + Radix -1));
+ return (ch >= '0' && ch <= '9')
+ || (ch >= 'a' && ch <= static_cast<Char>('a' + Radix -10 -1))
+ || (ch >= 'A' && ch <= static_cast<Char>('A' + Radix -10 -1));
+ }
+
+ template <typename Char>
+ inline static unsigned digit(Char ch)
+ {
+ if (Radix <= 10 || (ch >= '0' && ch <= '9'))
+ return ch - '0';
+ return char_encoding::ascii::tolower(ch) - 'a' + 10;
+ }
+ };
+
+ ///////////////////////////////////////////////////////////////////////////
+ // positive_accumulator/negative_accumulator: Accumulator policies for
+ // extracting integers. Use positive_accumulator if number is positive.
+ // Use negative_accumulator if number is negative.
+ ///////////////////////////////////////////////////////////////////////////
+ template <unsigned Radix>
+ struct positive_accumulator
+ {
+ template <typename T, typename Char>
+ inline static void add(T& n, Char ch, mpl::false_) // unchecked add
+ {
+ const int digit = radix_traits<Radix>::digit(ch);
+ n = n * T(Radix) + T(digit);
+ }
+
+ template <typename T, typename Char>
+ inline static bool add(T& n, Char ch, mpl::true_) // checked add
+ {
+ // Ensure n *= Radix will not overflow
+ static T const max = (std::numeric_limits<T>::max)();
+ static T const val = max / Radix;
+ if (n > val)
+ return false;
+
+ n *= Radix;
+
+ // Ensure n += digit will not overflow
+ const int digit = radix_traits<Radix>::digit(ch);
+ if (n > max - digit)
+ return false;
+
+ n += static_cast<T>(digit);
+ return true;
+ }
+ };
+
+ template <unsigned Radix>
+ struct negative_accumulator
+ {
+ template <typename T, typename Char>
+ inline static void add(T& n, Char ch, mpl::false_) // unchecked subtract
+ {
+ const int digit = radix_traits<Radix>::digit(ch);
+ n = n * T(Radix) - T(digit);
+ }
+
+ template <typename T, typename Char>
+ inline static bool add(T& n, Char ch, mpl::true_) // checked subtract
+ {
+ // Ensure n *= Radix will not underflow
+ static T const min = (std::numeric_limits<T>::min)();
+ static T const val = (min + 1) / T(Radix);
+ if (n < val)
+ return false;
+
+ n *= Radix;
+
+ // Ensure n -= digit will not underflow
+ int const digit = radix_traits<Radix>::digit(ch);
+ if (n < min + digit)
+ return false;
+
+ n -= static_cast<T>(digit);
+ return true;
+ }
+ };
+
+ ///////////////////////////////////////////////////////////////////////////
+ // Common code for extract_int::parse specializations
+ ///////////////////////////////////////////////////////////////////////////
+ template <unsigned Radix, typename Accumulator, int MaxDigits>
+ struct int_extractor
+ {
+ template <typename Char, typename T>
+ inline static bool
+ call(Char ch, std::size_t count, T& n, mpl::true_)
+ {
+ static std::size_t const
+ overflow_free = digits_traits<T, Radix>::value - 1;
+
+ if (count < overflow_free)
+ {
+ Accumulator::add(n, ch, mpl::false_());
+ }
+ else
+ {
+ if (!Accumulator::add(n, ch, mpl::true_()))
+ return false; // over/underflow!
+ }
+ return true;
+ }
+
+ template <typename Char, typename T>
+ inline static bool
+ call(Char ch, std::size_t /*count*/, T& n, mpl::false_)
+ {
+ // no need to check for overflow
+ Accumulator::add(n, ch, mpl::false_());
+ return true;
+ }
+
+ template <typename Char>
+ inline static bool
+ call(Char /*ch*/, std::size_t /*count*/, unused_type, mpl::false_)
+ {
+ return true;
+ }
+
+ template <typename Char, typename T>
+ inline static bool
+ call(Char ch, std::size_t count, T& n)
+ {
+ return call(ch, count, n
+ , mpl::bool_<
+ ( (MaxDigits < 0)
+ || (MaxDigits > digits_traits<T, Radix>::value)
+ )
+ && traits::check_overflow<T>::value
+ >()
+ );
+ }
+ };
+
+ ///////////////////////////////////////////////////////////////////////////
+ // End of loop checking: check if the number of digits
+ // being parsed exceeds MaxDigits. Note: if MaxDigits == -1
+ // we don't do any checking.
+ ///////////////////////////////////////////////////////////////////////////
+ template <int MaxDigits>
+ struct check_max_digits
+ {
+ inline static bool
+ call(std::size_t count)
+ {
+ return count < MaxDigits; // bounded
+ }
+ };
+
+ template <>
+ struct check_max_digits<-1>
+ {
+ inline static bool
+ call(std::size_t /*count*/)
+ {
+ return true; // unbounded
+ }
+ };
+
+ ///////////////////////////////////////////////////////////////////////////
+ // extract_int: main code for extracting integers
+ ///////////////////////////////////////////////////////////////////////////
+#define SPIRIT_NUMERIC_INNER_LOOP(z, x, data) \
+ if (!check_max_digits<MaxDigits>::call(count + leading_zeros) \
+ || it == last) \
+ break; \
+ ch = *it; \
+ if (!radix_check::is_valid(ch) || !extractor::call(ch, count, val)) \
+ break; \
+ ++it; \
+ ++count; \
+ /**/
+
+ template <
+ typename T, unsigned Radix, unsigned MinDigits, int MaxDigits
+ , typename Accumulator = positive_accumulator<Radix>
+ , bool Accumulate = false
+ >
+ struct extract_int
+ {
+#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
+# pragma warning(push)
+# pragma warning(disable: 4127) // conditional expression is constant
+#endif
+ template <typename Iterator, typename Attribute>
+ inline static bool
+ parse_main(
+ Iterator& first
+ , Iterator const& last
+ , Attribute& attr)
+ {
+ typedef radix_traits<Radix> radix_check;
+ typedef int_extractor<Radix, Accumulator, MaxDigits> extractor;
+ typedef typename
+ boost::detail::iterator_traits<Iterator>::value_type
+ char_type;
+
+ Iterator it = first;
+ std::size_t leading_zeros = 0;
+ if (!Accumulate)
+ {
+ // skip leading zeros
+ while (it != last && *it == '0' && leading_zeros < MaxDigits)
+ {
+ ++it;
+ ++leading_zeros;
+ }
+ }
+
+ typedef typename
+ traits::attribute_type<Attribute>::type
+ attribute_type;
+
+ attribute_type val = Accumulate ? attr : attribute_type(0);
+ std::size_t count = 0;
+ char_type ch;
+
+ while (true)
+ {
+ BOOST_PP_REPEAT(
+ SPIRIT_NUMERICS_LOOP_UNROLL
+ , SPIRIT_NUMERIC_INNER_LOOP, _)
+ }
+
+ if (count + leading_zeros >= MinDigits)
+ {
+ traits::move_to(val, attr);
+ first = it;
+ return true;
+ }
+ return false;
+ }
+#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
+# pragma warning(pop)
+#endif
+
+ template <typename Iterator>
+ inline static bool
+ parse(
+ Iterator& first
+ , Iterator const& last
+ , unused_type)
+ {
+ T n = 0; // must calculate value to detect over/underflow
+ return parse_main(first, last, n);
+ }
+
+ template <typename Iterator, typename Attribute>
+ inline static bool
+ parse(
+ Iterator& first
+ , Iterator const& last
+ , Attribute& attr)
+ {
+ return parse_main(first, last, attr);
+ }
+ };
+#undef SPIRIT_NUMERIC_INNER_LOOP
+
+ ///////////////////////////////////////////////////////////////////////////
+ // extract_int: main code for extracting integers
+ // common case where MinDigits == 1 and MaxDigits = -1
+ ///////////////////////////////////////////////////////////////////////////
+#define SPIRIT_NUMERIC_INNER_LOOP(z, x, data) \
+ if (it == last) \
+ break; \
+ ch = *it; \
+ if (!radix_check::is_valid(ch)) \
+ break; \
+ if (!extractor::call(ch, count, val)) \
+ return false; \
+ ++it; \
+ ++count; \
+ /**/
+
+ template <typename T, unsigned Radix, typename Accumulator, bool Accumulate>
+ struct extract_int<T, Radix, 1, -1, Accumulator, Accumulate>
+ {
+#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
+# pragma warning(push)
+# pragma warning(disable: 4127) // conditional expression is constant
+#endif
+ template <typename Iterator, typename Attribute>
+ inline static bool
+ parse_main(
+ Iterator& first
+ , Iterator const& last
+ , Attribute& attr)
+ {
+ typedef radix_traits<Radix> radix_check;
+ typedef int_extractor<Radix, Accumulator, -1> extractor;
+ typedef typename
+ boost::detail::iterator_traits<Iterator>::value_type
+ char_type;
+
+ Iterator it = first;
+ std::size_t count = 0;
+ if (!Accumulate)
+ {
+ // skip leading zeros
+ while (it != last && *it == '0')
+ {
+ ++it;
+ ++count;
+ }
+
+ if (it == last)
+ {
+ if (count == 0) // must have at least one digit
+ return false;
+ attr = 0;
+ first = it;
+ return true;
+ }
+ }
+
+ typedef typename
+ traits::attribute_type<Attribute>::type
+ attribute_type;
+
+ attribute_type val = Accumulate ? attr : attribute_type(0);
+ char_type ch = *it;
+
+ if (!radix_check::is_valid(ch) || !extractor::call(ch, 0, val))
+ {
+ if (count == 0) // must have at least one digit
+ return false;
+ traits::move_to(val, attr);
+ first = it;
+ return true;
+ }
+
+ count = 0;
+ ++it;
+ while (true)
+ {
+ BOOST_PP_REPEAT(
+ SPIRIT_NUMERICS_LOOP_UNROLL
+ , SPIRIT_NUMERIC_INNER_LOOP, _)
+ }
+
+ traits::move_to(val, attr);
+ first = it;
+ return true;
+ }
+#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
+# pragma warning(pop)
+#endif
+
+ template <typename Iterator>
+ inline static bool
+ parse(
+ Iterator& first
+ , Iterator const& last
+ , unused_type)
+ {
+ T n = 0; // must calculate value to detect over/underflow
+ return parse_main(first, last, n);
+ }
+
+ template <typename Iterator, typename Attribute>
+ inline static bool
+ parse(
+ Iterator& first
+ , Iterator const& last
+ , Attribute& attr)
+ {
+ return parse_main(first, last, attr);
+ }
+ };
+
+#undef SPIRIT_NUMERIC_INNER_LOOP
+
+ ///////////////////////////////////////////////////////////////////////////
+ // Cast an signed integer to an unsigned integer
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename T,
+ bool force_unsigned
+ = mpl::and_<is_integral<T>, is_signed<T> >::value>
+ struct cast_unsigned;
+
+ template <typename T>
+ struct cast_unsigned<T, true>
+ {
+ typedef typename make_unsigned<T>::type unsigned_type;
+ typedef typename make_unsigned<T>::type& unsigned_type_ref;
+
+ inline static unsigned_type_ref call(T& n)
+ {
+ return unsigned_type_ref(n);
+ }
+ };
+
+ template <typename T>
+ struct cast_unsigned<T, false>
+ {
+ inline static T& call(T& n)
+ {
+ return n;
+ }
+ };
+}}}}
+
+#endif
diff --git a/boost/spirit/home/x3/support/numeric_utils/extract_int.hpp b/boost/spirit/home/x3/support/numeric_utils/extract_int.hpp
new file mode 100644
index 0000000000..aa80cdd6ea
--- /dev/null
+++ b/boost/spirit/home/x3/support/numeric_utils/extract_int.hpp
@@ -0,0 +1,147 @@
+/*=============================================================================
+ Copyright (c) 2001-2014 Joel de Guzman
+ Copyright (c) 2011 Jan Frederick Eick
+
+ 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(BOOST_SPIRIT_X3_EXTRACT_INT_APRIL_17_2006_0830AM)
+#define BOOST_SPIRIT_X3_EXTRACT_INT_APRIL_17_2006_0830AM
+
+#if defined(_MSC_VER)
+#pragma once
+#endif
+
+#include <boost/spirit/home/x3/support/traits/move_to.hpp>
+#include <boost/spirit/home/x3/support/numeric_utils/detail/extract_int.hpp>
+#include <boost/assert.hpp>
+
+namespace boost { namespace spirit { namespace x3
+{
+ ///////////////////////////////////////////////////////////////////////////
+ // Extract the prefix sign (- or +), return true if a '-' was found
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename Iterator>
+ inline bool
+ extract_sign(Iterator& first, Iterator const& last)
+ {
+ (void)last; // silence unused warnings
+ BOOST_ASSERT(first != last); // precondition
+
+ // Extract the sign
+ bool neg = *first == '-';
+ if (neg || (*first == '+'))
+ {
+ ++first;
+ return neg;
+ }
+ return false;
+ }
+
+ ///////////////////////////////////////////////////////////////////////////
+ // Low level unsigned integer parser
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename T, unsigned Radix, unsigned MinDigits, int MaxDigits
+ , bool Accumulate = false>
+ struct extract_uint
+ {
+ // check template parameter 'Radix' for validity
+ static_assert(
+ (Radix >= 2 && Radix <= 36),
+ "Error Unsupported Radix");
+
+ template <typename Iterator>
+ inline static bool call(Iterator& first, Iterator const& last, T& attr)
+ {
+ if (first == last)
+ return false;
+
+ typedef detail::extract_int<
+ T
+ , Radix
+ , MinDigits
+ , MaxDigits
+ , detail::positive_accumulator<Radix>
+ , Accumulate>
+ extract_type;
+
+ Iterator save = first;
+ if (!extract_type::parse(first, last,
+ detail::cast_unsigned<T>::call(attr)))
+ {
+ first = save;
+ return false;
+ }
+ return true;
+ }
+
+ template <typename Iterator, typename Attribute>
+ inline static bool call(Iterator& first, Iterator const& last, Attribute& attr_)
+ {
+ // this case is called when Attribute is not T
+ T attr;
+ if (call(first, last, attr))
+ {
+ traits::move_to(attr, attr_);
+ return true;
+ }
+ return false;
+ }
+ };
+
+ ///////////////////////////////////////////////////////////////////////////
+ // Low level signed integer parser
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename T, unsigned Radix, unsigned MinDigits, int MaxDigits>
+ struct extract_int
+ {
+ // check template parameter 'Radix' for validity
+ static_assert(
+ (Radix == 2 || Radix == 8 || Radix == 10 || Radix == 16),
+ "Error Unsupported Radix");
+
+ template <typename Iterator>
+ inline static bool call(Iterator& first, Iterator const& last, T& attr)
+ {
+ if (first == last)
+ return false;
+
+ typedef detail::extract_int<
+ T, Radix, MinDigits, MaxDigits>
+ extract_pos_type;
+
+ typedef detail::extract_int<
+ T, Radix, MinDigits, MaxDigits, detail::negative_accumulator<Radix> >
+ extract_neg_type;
+
+ Iterator save = first;
+ bool hit = extract_sign(first, last);
+ if (hit)
+ hit = extract_neg_type::parse(first, last, attr);
+ else
+ hit = extract_pos_type::parse(first, last, attr);
+
+ if (!hit)
+ {
+ first = save;
+ return false;
+ }
+ return true;
+ }
+
+ template <typename Iterator, typename Attribute>
+ inline static bool call(Iterator& first, Iterator const& last, Attribute& attr_)
+ {
+ // this case is called when Attribute is not T
+ T attr;
+ if (call(first, last, attr))
+ {
+ traits::move_to(attr, attr_);
+ return true;
+ }
+ return false;
+ }
+ };
+}}}
+
+#endif
diff --git a/boost/spirit/home/x3/support/numeric_utils/extract_real.hpp b/boost/spirit/home/x3/support/numeric_utils/extract_real.hpp
new file mode 100644
index 0000000000..fb30f02306
--- /dev/null
+++ b/boost/spirit/home/x3/support/numeric_utils/extract_real.hpp
@@ -0,0 +1,271 @@
+/*=============================================================================
+ Copyright (c) 2001-2014 Joel de Guzman
+ Copyright (c) 2001-2011 Hartmut Kaiser
+ http://spirit.sourceforge.net/
+
+ 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_EXTRACT_REAL_APRIL_18_2006_0901AM)
+#define SPIRIT_EXTRACT_REAL_APRIL_18_2006_0901AM
+
+#if defined(_MSC_VER)
+#pragma once
+#endif
+
+#include <cmath>
+#include <boost/limits.hpp>
+#include <boost/type_traits/is_same.hpp>
+#include <boost/spirit/home/x3/support/unused.hpp>
+#include <boost/spirit/home/x3/support/numeric_utils/pow10.hpp>
+#include <boost/spirit/home/x3/support/numeric_utils/sign.hpp>
+#include <boost/spirit/home/x3/support/traits/move_to.hpp>
+#include <boost/assert.hpp>
+
+#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
+# pragma warning(push)
+# pragma warning(disable: 4100) // 'p': unreferenced formal parameter
+# pragma warning(disable: 4127) // conditional expression is constant
+#endif
+
+namespace boost { namespace spirit { namespace x3 { namespace extension
+{
+ using x3::traits::pow10;
+
+ template <typename T>
+ inline void
+ scale(int exp, T& n)
+ {
+ if (exp >= 0)
+ {
+ // $$$ Why is this failing for boost.math.concepts ? $$$
+ //~ int nn = std::numeric_limits<T>::max_exponent10;
+ //~ BOOST_ASSERT(exp <= std::numeric_limits<T>::max_exponent10);
+ n *= pow10<T>(exp);
+ }
+ else
+ {
+ if (exp < std::numeric_limits<T>::min_exponent10)
+ {
+ n /= pow10<T>(-std::numeric_limits<T>::min_exponent10);
+ n /= pow10<T>(-exp + std::numeric_limits<T>::min_exponent10);
+ }
+ else
+ {
+ n /= pow10<T>(-exp);
+ }
+ }
+ }
+
+ inline void
+ scale(int /*exp*/, unused_type /*n*/)
+ {
+ // no-op for unused_type
+ }
+
+ template <typename T>
+ inline void
+ scale(int exp, int frac, T& n)
+ {
+ scale(exp - frac, n);
+ }
+
+ inline void
+ scale(int /*exp*/, int /*frac*/, unused_type /*n*/)
+ {
+ // no-op for unused_type
+ }
+
+ inline float
+ negate(bool neg, float n)
+ {
+ return neg ? x3::changesign(n) : n;
+ }
+
+ inline double
+ negate(bool neg, double n)
+ {
+ return neg ? x3::changesign(n) : n;
+ }
+
+ inline long double
+ negate(bool neg, long double n)
+ {
+ return neg ? x3::changesign(n) : n;
+ }
+
+ template <typename T>
+ inline T
+ negate(bool neg, T const& n)
+ {
+ return neg ? -n : n;
+ }
+
+ inline unused_type
+ negate(bool /*neg*/, unused_type n)
+ {
+ // no-op for unused_type
+ return n;
+ }
+
+ template <typename T>
+ inline bool
+ is_equal_to_one(T const& value)
+ {
+ return value == 1.0;
+ }
+
+ inline bool
+ is_equal_to_one(unused_type)
+ {
+ // no-op for unused_type
+ return false;
+ }
+}}}}
+
+namespace boost { namespace spirit { namespace x3
+{
+ template <typename T, typename RealPolicies>
+ struct extract_real
+ {
+ template <typename Iterator, typename Attribute>
+ static bool
+ parse(Iterator& first, Iterator const& last, Attribute& attr,
+ RealPolicies const& p)
+ {
+ if (first == last)
+ return false;
+ Iterator save = first;
+
+ // Start by parsing the sign. neg will be true if
+ // we got a "-" sign, false otherwise.
+ bool neg = p.parse_sign(first, last);
+
+ // Now attempt to parse an integer
+ T n = 0;
+ bool got_a_number = p.parse_n(first, last, n);
+
+ // If we did not get a number it might be a NaN, Inf or a leading
+ // dot.
+ if (!got_a_number)
+ {
+ // Check whether the number to parse is a NaN or Inf
+ if (p.parse_nan(first, last, n) ||
+ p.parse_inf(first, last, n))
+ {
+ // If we got a negative sign, negate the number
+ traits::move_to(extension::negate(neg, n), attr);
+ return true; // got a NaN or Inf, return early
+ }
+
+ // If we did not get a number and our policies do not
+ // allow a leading dot, fail and return early (no-match)
+ if (!p.allow_leading_dot)
+ {
+ first = save;
+ return false;
+ }
+ }
+
+ bool e_hit = false;
+ int frac_digits = 0;
+
+ // Try to parse the dot ('.' decimal point)
+ if (p.parse_dot(first, last))
+ {
+ // We got the decimal point. Now we will try to parse
+ // the fraction if it is there. If not, it defaults
+ // to zero (0) only if we already got a number.
+ Iterator savef = first;
+ if (p.parse_frac_n(first, last, n))
+ {
+ // Optimization note: don't compute frac_digits if T is
+ // an unused_type. This should be optimized away by the compiler.
+ if (!is_same<T, unused_type>::value)
+ frac_digits =
+ static_cast<int>(std::distance(savef, first));
+ }
+ else if (!got_a_number || !p.allow_trailing_dot)
+ {
+ // We did not get a fraction. If we still haven't got a
+ // number and our policies do not allow a trailing dot,
+ // return no-match.
+ first = save;
+ return false;
+ }
+
+ // Now, let's see if we can parse the exponent prefix
+ e_hit = p.parse_exp(first, last);
+ }
+ else
+ {
+ // No dot and no number! Return no-match.
+ if (!got_a_number)
+ {
+ first = save;
+ return false;
+ }
+
+ // If we must expect a dot and we didn't see an exponent
+ // prefix, return no-match.
+ e_hit = p.parse_exp(first, last);
+ if (p.expect_dot && !e_hit)
+ {
+ first = save;
+ return false;
+ }
+ }
+
+ if (e_hit)
+ {
+ // We got the exponent prefix. Now we will try to parse the
+ // actual exponent. It is an error if it is not there.
+ int exp = 0;
+ if (p.parse_exp_n(first, last, exp))
+ {
+ // Got the exponent value. Scale the number by
+ // exp-frac_digits.
+ extension::scale(exp, frac_digits, n);
+ }
+ else
+ {
+ // Oops, no exponent, return no-match.
+ first = save;
+ return false;
+ }
+ }
+ else if (frac_digits)
+ {
+ // No exponent found. Scale the number by -frac_digits.
+ extension::scale(-frac_digits, n);
+ }
+ else if (extension::is_equal_to_one(n))
+ {
+ // There is a chance of having to parse one of the 1.0#...
+ // styles some implementations use for representing NaN or Inf.
+
+ // Check whether the number to parse is a NaN or Inf
+ if (p.parse_nan(first, last, n) ||
+ p.parse_inf(first, last, n))
+ {
+ // If we got a negative sign, negate the number
+ traits::move_to(extension::negate(neg, n), attr);
+ return true; // got a NaN or Inf, return immediately
+ }
+ }
+
+ // If we got a negative sign, negate the number
+ traits::move_to(extension::negate(neg, n), attr);
+
+ // Success!!!
+ return true;
+ }
+ };
+
+#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
+# pragma warning(pop)
+#endif
+
+}}}
+
+#endif
diff --git a/boost/spirit/home/x3/support/numeric_utils/pow10.hpp b/boost/spirit/home/x3/support/numeric_utils/pow10.hpp
new file mode 100644
index 0000000000..f51d29fba8
--- /dev/null
+++ b/boost/spirit/home/x3/support/numeric_utils/pow10.hpp
@@ -0,0 +1,116 @@
+/*=============================================================================
+ Copyright (c) 2001-2014 Joel de Guzman
+ Copyright (c) 2001-2011 Hartmut Kaiser
+ http://spirit.sourceforge.net/
+
+ 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(BOOST_SPIRIT_X3_POW10_DECEMBER_26_2008_1118AM)
+#define BOOST_SPIRIT_X3_POW10_DECEMBER_26_2008_1118AM
+
+#if defined(_MSC_VER)
+#pragma once
+#endif
+
+#include <boost/config/no_tr1/cmath.hpp>
+#include <boost/limits.hpp>
+#include <boost/spirit/home/x3/support/unused.hpp>
+#include <boost/spirit/home/x3/support/traits/numeric_traits.hpp>
+
+#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
+# pragma warning(push)
+# pragma warning(disable: 4244) // conversion from 'double' to 'float', possible loss of data
+#endif
+
+namespace boost { namespace spirit { namespace x3 { namespace traits
+{
+ namespace detail
+ {
+ template <typename T, typename Enable = void>
+ struct pow10_helper
+ {
+ static T call(unsigned dim)
+ {
+ using namespace std; // allow for ADL to find the correct overload
+ return pow(T(10), T(dim));
+ }
+ };
+
+ template <>
+ struct pow10_helper<unused_type>
+ {
+ static unused_type call(unused_type)
+ {
+ return unused;
+ }
+ };
+
+#if (DBL_MAX_10_EXP == 308) // for IEEE-754
+ template <>
+ struct pow10_helper<double>
+ {
+ static double call(unsigned dim)
+ {
+ static double const exponents[] =
+ {
+ 1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9,
+ 1e10, 1e11, 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19,
+ 1e20, 1e21, 1e22, 1e23, 1e24, 1e25, 1e26, 1e27, 1e28, 1e29,
+ 1e30, 1e31, 1e32, 1e33, 1e34, 1e35, 1e36, 1e37, 1e38, 1e39,
+ 1e40, 1e41, 1e42, 1e43, 1e44, 1e45, 1e46, 1e47, 1e48, 1e49,
+ 1e50, 1e51, 1e52, 1e53, 1e54, 1e55, 1e56, 1e57, 1e58, 1e59,
+ 1e60, 1e61, 1e62, 1e63, 1e64, 1e65, 1e66, 1e67, 1e68, 1e69,
+ 1e70, 1e71, 1e72, 1e73, 1e74, 1e75, 1e76, 1e77, 1e78, 1e79,
+ 1e80, 1e81, 1e82, 1e83, 1e84, 1e85, 1e86, 1e87, 1e88, 1e89,
+ 1e90, 1e91, 1e92, 1e93, 1e94, 1e95, 1e96, 1e97, 1e98, 1e99,
+ 1e100, 1e101, 1e102, 1e103, 1e104, 1e105, 1e106, 1e107, 1e108, 1e109,
+ 1e110, 1e111, 1e112, 1e113, 1e114, 1e115, 1e116, 1e117, 1e118, 1e119,
+ 1e120, 1e121, 1e122, 1e123, 1e124, 1e125, 1e126, 1e127, 1e128, 1e129,
+ 1e130, 1e131, 1e132, 1e133, 1e134, 1e135, 1e136, 1e137, 1e138, 1e139,
+ 1e140, 1e141, 1e142, 1e143, 1e144, 1e145, 1e146, 1e147, 1e148, 1e149,
+ 1e150, 1e151, 1e152, 1e153, 1e154, 1e155, 1e156, 1e157, 1e158, 1e159,
+ 1e160, 1e161, 1e162, 1e163, 1e164, 1e165, 1e166, 1e167, 1e168, 1e169,
+ 1e170, 1e171, 1e172, 1e173, 1e174, 1e175, 1e176, 1e177, 1e178, 1e179,
+ 1e180, 1e181, 1e182, 1e183, 1e184, 1e185, 1e186, 1e187, 1e188, 1e189,
+ 1e190, 1e191, 1e192, 1e193, 1e194, 1e195, 1e196, 1e197, 1e198, 1e199,
+ 1e200, 1e201, 1e202, 1e203, 1e204, 1e205, 1e206, 1e207, 1e208, 1e209,
+ 1e210, 1e211, 1e212, 1e213, 1e214, 1e215, 1e216, 1e217, 1e218, 1e219,
+ 1e220, 1e221, 1e222, 1e223, 1e224, 1e225, 1e226, 1e227, 1e228, 1e229,
+ 1e230, 1e231, 1e232, 1e233, 1e234, 1e235, 1e236, 1e237, 1e238, 1e239,
+ 1e240, 1e241, 1e242, 1e243, 1e244, 1e245, 1e246, 1e247, 1e248, 1e249,
+ 1e250, 1e251, 1e252, 1e253, 1e254, 1e255, 1e256, 1e257, 1e258, 1e259,
+ 1e260, 1e261, 1e262, 1e263, 1e264, 1e265, 1e266, 1e267, 1e268, 1e269,
+ 1e270, 1e271, 1e272, 1e273, 1e274, 1e275, 1e276, 1e277, 1e278, 1e279,
+ 1e280, 1e281, 1e282, 1e283, 1e284, 1e285, 1e286, 1e287, 1e288, 1e289,
+ 1e290, 1e291, 1e292, 1e293, 1e294, 1e295, 1e296, 1e297, 1e298, 1e299,
+ 1e300, 1e301, 1e302, 1e303, 1e304, 1e305, 1e306, 1e307, 1e308,
+ };
+ BOOST_ASSERT(dim < sizeof(exponents)/sizeof(double));
+ return exponents[dim];
+ }
+ };
+
+ template <>
+ struct pow10_helper<float>
+ {
+ static float call(unsigned dim)
+ {
+ return pow10_helper<double>::call(dim);
+ }
+ };
+#endif // for IEEE-754
+ }
+
+ template <typename T>
+ inline T pow10(unsigned dim)
+ {
+ return detail::pow10_helper<T>::call(dim);
+ }
+}}}}
+
+#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
+# pragma warning(pop)
+#endif
+
+#endif
diff --git a/boost/spirit/home/x3/support/numeric_utils/sign.hpp b/boost/spirit/home/x3/support/numeric_utils/sign.hpp
new file mode 100644
index 0000000000..fe2feceeed
--- /dev/null
+++ b/boost/spirit/home/x3/support/numeric_utils/sign.hpp
@@ -0,0 +1,48 @@
+/*=============================================================================
+ Copyright (c) 2001-2014 Joel de Guzman
+ Copyright (c) 2001-2011 Hartmut Kaiser
+ http://spirit.sourceforge.net/
+
+ 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_SIGN_MAR_11_2009_0734PM)
+#define SPIRIT_SIGN_MAR_11_2009_0734PM
+
+#if defined(_MSC_VER)
+#pragma once
+#endif
+
+#include <boost/config/no_tr1/cmath.hpp>
+#include <boost/math/special_functions/fpclassify.hpp>
+#include <boost/math/special_functions/sign.hpp>
+
+namespace boost { namespace spirit { namespace x3
+{
+ template<typename T>
+ inline bool (signbit)(T x)
+ {
+ return (boost::math::signbit)(x) ? true : false;
+ }
+
+ // This routine has been taken and adapted from Johan Rade's fp_traits
+ // library
+ template<typename T>
+ inline T (changesign)(T x)
+ {
+#if defined(BOOST_MATH_USE_STD_FPCLASSIFY) && !defined(BOOST_MATH_DISABLE_STD_FPCLASSIFY)
+ return -x;
+#else
+ typedef typename math::detail::fp_traits<T>::type traits_type;
+
+ typename traits_type::bits a;
+ traits_type::get_bits(x, a);
+ a ^= traits_type::sign;
+ traits_type::set_bits(x, a);
+ return x;
+#endif
+ }
+
+}}}
+
+#endif
diff --git a/boost/spirit/home/x3/support/subcontext.hpp b/boost/spirit/home/x3/support/subcontext.hpp
new file mode 100644
index 0000000000..7614fcbcae
--- /dev/null
+++ b/boost/spirit/home/x3/support/subcontext.hpp
@@ -0,0 +1,89 @@
+/*=============================================================================
+ Copyright (c) 2001-2014 Joel de Guzman
+ Copyright (c) 2013 Agustín Bergé
+ http://spirit.sourceforge.net/
+
+ 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(BOOST_SPIRIT_X3_SUBCONTEXT_APR_15_2013_0840AM)
+#define BOOST_SPIRIT_X3_SUBCONTEXT_APR_15_2013_0840AM
+
+#if defined(_MSC_VER)
+#pragma once
+#endif
+
+#include <boost/fusion/support/pair.hpp>
+#include <boost/spirit/home/x3/support/context.hpp>
+#include <boost/spirit/home/x3/support/unused.hpp>
+
+namespace boost { namespace spirit { namespace x3
+{
+ template <typename... T>
+ struct subcontext;
+
+ template <>
+ struct subcontext<>
+ {
+ template <typename Context>
+ subcontext(Context const& /*context*/)
+ {}
+
+ template <typename ID_, typename Unused = void>
+ struct get_result
+ {
+ typedef unused_type type;
+ };
+
+ template <typename ID_>
+ unused_type
+ get(ID_) const
+ {
+ return unused;
+ }
+ };
+
+ template <typename T>
+ struct subcontext<T>
+ : context<typename T::first_type, typename T::second_type>
+ {
+ typedef context<
+ typename T::first_type, typename T::second_type
+ > context_type;
+
+ template <typename Context>
+ subcontext(Context const& context)
+ : context_type(x3::get<typename T::first_type>(context))
+ {}
+
+ using context_type::get;
+ };
+
+ template <typename T, typename... Tail>
+ struct subcontext<T, Tail...>
+ : subcontext<Tail...>
+ , context<
+ typename T::first_type, typename T::second_type
+ , subcontext<Tail...>
+ >
+ {
+ typedef subcontext<Tail...> base_type;
+ typedef context<
+ typename T::first_type, typename T::second_type
+ , base_type
+ > context_type;
+
+ template <typename Context>
+ subcontext(Context const& context)
+ : base_type(context)
+ , context_type(
+ x3::get<typename T::first_type>(context)
+ , *static_cast<base_type*>(this))
+ {}
+
+ using context_type::get;
+ };
+
+}}}
+
+#endif
diff --git a/boost/spirit/home/x3/support/traits/attribute_category.hpp b/boost/spirit/home/x3/support/traits/attribute_category.hpp
new file mode 100644
index 0000000000..a003327de2
--- /dev/null
+++ b/boost/spirit/home/x3/support/traits/attribute_category.hpp
@@ -0,0 +1,82 @@
+/*=============================================================================
+ Copyright (c) 2001-2014 Joel de Guzman
+ http://spirit.sourceforge.net/
+
+ 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(BOOST_SPIRIT_X3_ATTRIBUTE_CATEGORY_JAN_4_2012_1150AM)
+#define BOOST_SPIRIT_X3_ATTRIBUTE_CATEGORY_JAN_4_2012_1150AM
+
+#if defined(_MSC_VER)
+#pragma once
+#endif
+
+#include <boost/mpl/identity.hpp>
+#include <boost/mpl/logical.hpp>
+#include <boost/mpl/eval_if.hpp>
+#include <boost/fusion/include/copy.hpp>
+#include <boost/fusion/include/is_sequence.hpp>
+#include <boost/fusion/support/category_of.hpp>
+#include <boost/spirit/home/x3/support/traits/is_variant.hpp>
+#include <boost/spirit/home/x3/support/traits/container_traits.hpp>
+
+namespace boost { namespace spirit { namespace x3
+{
+ struct unused_type;
+}}}
+
+namespace boost { namespace spirit { namespace x3 { namespace traits
+{
+ struct unused_attribute {};
+ struct plain_attribute {};
+ struct container_attribute {};
+ struct tuple_attribute {};
+ struct associative_attribute {};
+ struct variant_attribute {};
+ struct optional_attribute {};
+
+ template <typename T, typename Enable = void>
+ struct attribute_category
+ : mpl::identity<plain_attribute> {};
+
+ template <>
+ struct attribute_category<unused_type>
+ : mpl::identity<unused_attribute> {};
+
+ template <>
+ struct attribute_category<unused_type const>
+ : mpl::identity<unused_attribute> {};
+
+ template <typename T>
+ struct attribute_category< T
+ , typename enable_if<
+ typename mpl::eval_if<
+ fusion::traits::is_sequence<T>
+ , fusion::traits::is_associative<T>
+ , mpl::false_
+ >::type >::type >
+ : mpl::identity<associative_attribute> {};
+
+ template <typename T>
+ struct attribute_category< T
+ , typename enable_if<
+ mpl::and_<
+ fusion::traits::is_sequence<T>
+ , mpl::not_<fusion::traits::is_associative<T> >
+ > >::type >
+ : mpl::identity<tuple_attribute> {};
+
+ template <typename T>
+ struct attribute_category<T,
+ typename enable_if<traits::is_variant<T>>::type>
+ : mpl::identity<variant_attribute> {};
+
+ template <typename T>
+ struct attribute_category<T,
+ typename enable_if<traits::is_container<T>>::type>
+ : mpl::identity<container_attribute> {};
+
+}}}}
+
+#endif
diff --git a/boost/spirit/home/x3/support/traits/attribute_of.hpp b/boost/spirit/home/x3/support/traits/attribute_of.hpp
new file mode 100644
index 0000000000..71f70b0273
--- /dev/null
+++ b/boost/spirit/home/x3/support/traits/attribute_of.hpp
@@ -0,0 +1,59 @@
+/*=============================================================================
+ Copyright (c) 2001-2014 Joel de Guzman
+ Copyright (c) 2013 Agustin Berge
+ http://spirit.sourceforge.net/
+
+ 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(BOOST_SPIRIT_X3_ATTRIBUTE_OF_JAN_7_2012_0914AM)
+#define BOOST_SPIRIT_X3_ATTRIBUTE_OF_JAN_7_2012_0914AM
+
+#if defined(_MSC_VER)
+#pragma once
+#endif
+
+#include <boost/spirit/home/x3/support/utility/sfinae.hpp>
+#include <boost/mpl/identity.hpp>
+#include <boost/utility/enable_if.hpp>
+
+namespace boost { namespace spirit { namespace x3 { namespace traits
+{
+ ///////////////////////////////////////////////////////////////////////////
+ // Get the attribute type of a component. By default, this gets the
+ // Component's attribute_type typedef or instantiates a nested attribute
+ // metafunction. Components may specialize this if such an attribute_type
+ // is not readily available (e.g. expensive to compute at compile time).
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename Component, typename Context, typename Enable = void>
+ struct attribute_of;
+
+ namespace detail
+ {
+ template <typename Component, typename Context, typename Enable = void>
+ struct default_attribute_of;
+
+ template <typename Component, typename Context>
+ struct default_attribute_of<Component, Context,
+ typename disable_if_substitution_failure<
+ typename Component::attribute_type>::type>
+ : mpl::identity<typename Component::attribute_type> {};
+
+ template <typename Component, typename Context>
+ struct default_attribute_of<Component, Context,
+ typename disable_if_substitution_failure<
+ typename Component::template attribute<Context>::type>::type>
+ : Component::template attribute<Context> {};
+
+ template <typename Component, typename Context>
+ struct default_attribute_of<Component, Context,
+ typename enable_if_c<Component::is_pass_through_unary>::type>
+ : attribute_of<typename Component::subject_type, Context>{};
+ }
+
+ template <typename Component, typename Context, typename Enable>
+ struct attribute_of : detail::default_attribute_of<Component, Context> {};
+
+}}}}
+
+#endif
diff --git a/boost/spirit/home/x3/support/traits/attribute_type.hpp b/boost/spirit/home/x3/support/traits/attribute_type.hpp
new file mode 100644
index 0000000000..55e788b41c
--- /dev/null
+++ b/boost/spirit/home/x3/support/traits/attribute_type.hpp
@@ -0,0 +1,30 @@
+/*=============================================================================
+ Copyright (c) 2001-2014 Joel de Guzman
+ http://spirit.sourceforge.net/
+
+ 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(BOOST_SPIRIT_X3_ATTRIBUTE_TYPE_JAN_5_2012_0358PM)
+#define BOOST_SPIRIT_X3_ATTRIBUTE_TYPE_JAN_5_2012_0358PM
+
+#if defined(_MSC_VER)
+#pragma once
+#endif
+
+#include <boost/mpl/identity.hpp>
+
+namespace boost { namespace spirit { namespace x3 { namespace traits
+{
+ ///////////////////////////////////////////////////////////////////////////
+ // Retrieve the attribute type to use from the given type
+ //
+ // This is needed to extract the correct attribute type from proxy classes
+ // as utilized in FUSION_ADAPT_ADT et. al.
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename Attribute, typename Enable = void>
+ struct attribute_type : mpl::identity<Attribute> {};
+
+}}}}
+
+#endif
diff --git a/boost/spirit/home/x3/support/traits/container_traits.hpp b/boost/spirit/home/x3/support/traits/container_traits.hpp
new file mode 100644
index 0000000000..c382b7bfaa
--- /dev/null
+++ b/boost/spirit/home/x3/support/traits/container_traits.hpp
@@ -0,0 +1,333 @@
+/*=============================================================================
+ Copyright (c) 2001-2014 Joel de Guzman
+ Copyright (c) 2001-2011 Hartmut Kaiser
+ http://spirit.sourceforge.net/
+
+ 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(BOOST_SPIRIT_X3_CONTAINER_FEBRUARY_06_2007_1001AM)
+#define BOOST_SPIRIT_X3_CONTAINER_FEBRUARY_06_2007_1001AM
+
+#if defined(_MSC_VER)
+#pragma once
+#endif
+
+#include <boost/fusion/support/category_of.hpp>
+#include <boost/spirit/home/x3/support/unused.hpp>
+#include <boost/detail/iterator.hpp>
+#include <boost/fusion/include/deque.hpp>
+#include <boost/mpl/has_xxx.hpp>
+#include <boost/mpl/bool.hpp>
+#include <boost/mpl/identity.hpp>
+#include <vector>
+#include <string>
+
+namespace boost { namespace spirit { namespace x3 { namespace traits
+{
+ ///////////////////////////////////////////////////////////////////////////
+ // This file contains some container utils for stl containers.
+ ///////////////////////////////////////////////////////////////////////////
+
+ namespace detail
+ {
+ BOOST_MPL_HAS_XXX_TRAIT_DEF(value_type)
+ BOOST_MPL_HAS_XXX_TRAIT_DEF(iterator)
+ BOOST_MPL_HAS_XXX_TRAIT_DEF(size_type)
+ BOOST_MPL_HAS_XXX_TRAIT_DEF(reference)
+ }
+
+ template <typename T, typename Enable = void>
+ struct is_container
+ : mpl::bool_<
+ detail::has_value_type<T>::value &&
+ detail::has_iterator<T>::value &&
+ detail::has_size_type<T>::value &&
+ detail::has_reference<T>::value>
+ {};
+
+ ///////////////////////////////////////////////////////////////////////////
+ namespace detail
+ {
+ template <typename T>
+ struct remove_value_const : mpl::identity<T> {};
+
+ template <typename T>
+ struct remove_value_const<T const> : remove_value_const<T> {};
+
+ template <typename F, typename S>
+ struct remove_value_const<std::pair<F, S>>
+ {
+ typedef typename remove_value_const<F>::type first_type;
+ typedef typename remove_value_const<S>::type second_type;
+ typedef std::pair<first_type, second_type> type;
+ };
+ }
+
+ ///////////////////////////////////////////////////////////////////////
+ template <typename Container, typename Enable = void>
+ struct container_value
+ : detail::remove_value_const<typename Container::value_type>
+ {};
+
+ template <typename Container>
+ struct container_value<Container const> : container_value<Container> {};
+
+ // There is no single container value for fusion maps, but because output
+ // of this metafunc is used to check wheter parser's attribute can be
+ // saved to container, we simply return whole fusion::map as is
+ // so that check can be done in traits::is_substitute specialisation
+ template <typename T>
+ struct container_value<T
+ , typename enable_if<typename mpl::eval_if <
+ fusion::traits::is_sequence<T>
+ , fusion::traits::is_associative<T>
+ , mpl::false_ >::type >::type>
+ : mpl::identity<T> {};
+
+ template <>
+ struct container_value<unused_type> : mpl::identity<unused_type> {};
+
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename Container, typename Enable = void>
+ struct container_iterator
+ : mpl::identity<typename Container::iterator> {};
+
+ template <typename Container>
+ struct container_iterator<Container const>
+ : mpl::identity<typename Container::const_iterator> {};
+
+ template <>
+ struct container_iterator<unused_type>
+ : mpl::identity<unused_type const*> {};
+
+ template <>
+ struct container_iterator<unused_type const>
+ : mpl::identity<unused_type const*> {};
+
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename Container, typename T>
+ bool push_back(Container& c, T&& val);
+
+ template <typename Container, typename Enable = void>
+ struct push_back_container
+ {
+ template <typename T>
+ static bool call(Container& c, T&& val)
+ {
+ c.insert(c.end(), std::move(val));
+ return true;
+ }
+ };
+
+ template <typename Container, typename T>
+ inline bool push_back(Container& c, T&& val)
+ {
+ return push_back_container<Container>::call(c, std::move(val));
+ }
+
+ template <typename Container>
+ inline bool push_back(Container&, unused_type)
+ {
+ return true;
+ }
+
+ template <typename T>
+ inline bool push_back(unused_type, T const&)
+ {
+ return true;
+ }
+
+ inline bool push_back(unused_type, unused_type)
+ {
+ return true;
+ }
+
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename Container, typename Iterator>
+ bool append(Container& c, Iterator first, Iterator last);
+
+ template <typename Container, typename Enable = void>
+ struct append_container
+ {
+ // Not all containers have "reserve"
+ template <typename Container_>
+ static void reserve(Container_& c, std::size_t size) {}
+
+ template <typename T>
+ static void reserve(std::vector<T>& c, std::size_t size)
+ {
+ c.reserve(size);
+ }
+
+ template <typename Iterator>
+ static bool call(Container& c, Iterator first, Iterator last)
+ {
+ reserve(c, c.size() + std::distance(first, last));
+ c.insert(c.end(), first, last);
+ return true;
+ }
+ };
+
+ template <typename Container, typename Iterator>
+ inline bool append(Container& c, Iterator first, Iterator last)
+ {
+ return append_container<Container>::call(c, first, last);
+ }
+
+ template <typename Iterator>
+ inline bool append(unused_type, Iterator first, Iterator last)
+ {
+ return true;
+ }
+
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename Container, typename Enable = void>
+ struct is_empty_container
+ {
+ static bool call(Container const& c)
+ {
+ return c.empty();
+ }
+ };
+
+ template <typename Container>
+ inline bool is_empty(Container const& c)
+ {
+ return is_empty_container<Container>::call(c);
+ }
+
+ inline bool is_empty(unused_type)
+ {
+ return true;
+ }
+
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename Container, typename Enable = void>
+ struct begin_container
+ {
+ static typename container_iterator<Container>::type call(Container& c)
+ {
+ return c.begin();
+ }
+ };
+
+ template <typename Container>
+ inline typename container_iterator<Container>::type
+ begin(Container& c)
+ {
+ return begin_container<Container>::call(c);
+ }
+
+ inline unused_type const*
+ begin(unused_type)
+ {
+ return &unused;
+ }
+
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename Container, typename Enable = void>
+ struct end_container
+ {
+ static typename container_iterator<Container>::type call(Container& c)
+ {
+ return c.end();
+ }
+ };
+
+ template <typename Container>
+ inline typename container_iterator<Container>::type
+ end(Container& c)
+ {
+ return end_container<Container>::call(c);
+ }
+
+ inline unused_type const*
+ end(unused_type)
+ {
+ return &unused;
+ }
+
+
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename Iterator, typename Enable = void>
+ struct deref_iterator
+ {
+ typedef typename boost::detail::iterator_traits<Iterator>::reference type;
+ static type call(Iterator& it)
+ {
+ return *it;
+ }
+ };
+
+ template <typename Iterator>
+ typename deref_iterator<Iterator>::type
+ deref(Iterator& it)
+ {
+ return deref_iterator<Iterator>::call(it);
+ }
+
+ inline unused_type
+ deref(unused_type const*)
+ {
+ return unused;
+ }
+
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename Iterator, typename Enable = void>
+ struct next_iterator
+ {
+ static void call(Iterator& it)
+ {
+ ++it;
+ }
+ };
+
+ template <typename Iterator>
+ void next(Iterator& it)
+ {
+ next_iterator<Iterator>::call(it);
+ }
+
+ inline void next(unused_type const*)
+ {
+ // do nothing
+ }
+
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename Iterator, typename Enable = void>
+ struct compare_iterators
+ {
+ static bool call(Iterator const& it1, Iterator const& it2)
+ {
+ return it1 == it2;
+ }
+ };
+
+ template <typename Iterator>
+ bool compare(Iterator& it1, Iterator& it2)
+ {
+ return compare_iterators<Iterator>::call(it1, it2);
+ }
+
+ inline bool compare(unused_type const*, unused_type const*)
+ {
+ return false;
+ }
+
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename T>
+ struct build_container : mpl::identity<std::vector<T>> {};
+
+ template <typename T>
+ struct build_container<boost::fusion::deque<T> > : build_container<T> {};
+
+ template <>
+ struct build_container<unused_type> : mpl::identity<unused_type> {};
+
+ template <>
+ struct build_container<char> : mpl::identity<std::string> {};
+
+}}}}
+
+#endif
diff --git a/boost/spirit/home/x3/support/traits/handles_container.hpp b/boost/spirit/home/x3/support/traits/handles_container.hpp
new file mode 100644
index 0000000000..3fe05aef87
--- /dev/null
+++ b/boost/spirit/home/x3/support/traits/handles_container.hpp
@@ -0,0 +1,31 @@
+/*=============================================================================
+ Copyright (c) 2001-2011 Hartmut Kaiser
+ Copyright (c) 2013 Agustin Berge
+
+ 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(BOOST_SPIRIT_X3_HANDLES_CONTAINER_DEC_18_2010_0920AM)
+#define BOOST_SPIRIT_X3_HANDLES_CONTAINER_DEC_18_2010_0920AM
+
+#if defined(_MSC_VER)
+#pragma once
+#endif
+
+#include <boost/mpl/bool.hpp>
+
+namespace boost { namespace spirit { namespace x3 { namespace traits
+{
+ ///////////////////////////////////////////////////////////////////////////
+ // Whether a component handles container attributes intrinsically
+ // (or whether container attributes need to be split up separately).
+ // By default, this gets the Component's handles_container nested value.
+ // Components may specialize this if such a handles_container is not
+ // readily available (e.g. expensive to compute at compile time).
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename Component, typename Context, typename Enable = void>
+ struct handles_container : mpl::bool_<Component::handles_container> {};
+
+}}}}
+
+#endif
diff --git a/boost/spirit/home/x3/support/traits/has_attribute.hpp b/boost/spirit/home/x3/support/traits/has_attribute.hpp
new file mode 100644
index 0000000000..c8b1f8a347
--- /dev/null
+++ b/boost/spirit/home/x3/support/traits/has_attribute.hpp
@@ -0,0 +1,63 @@
+/*=============================================================================
+ Copyright (c) 2001-2014 Joel de Guzman
+ Copyright (c) 2013 Agustin Berge
+ http://spirit.sourceforge.net/
+
+ 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(BOOST_SPIRIT_X3_HAS_ATTRIBUTE_JUN_6_2012_1714PM)
+#define BOOST_SPIRIT_X3_HAS_ATTRIBUTE_JUN_6_2012_1714PM
+
+#if defined(_MSC_VER)
+#pragma once
+#endif
+
+#include <boost/spirit/home/x3/support/traits/attribute_of.hpp>
+#include <boost/spirit/home/x3/support/utility/sfinae.hpp>
+#include <boost/mpl/bool.hpp>
+#include <boost/mpl/not.hpp>
+#include <boost/type_traits/is_same.hpp>
+#include <boost/utility/enable_if.hpp>
+
+namespace boost { namespace spirit { namespace x3
+{
+ struct unused_type;
+}}}
+
+namespace boost { namespace spirit { namespace x3 { namespace traits
+{
+ ///////////////////////////////////////////////////////////////////////////
+ // Whether a component has an attribute. By default, this compares the
+ // component attribute against unused_type. If the component provides a
+ // nested constant expression has_attribute as a hint, that value is used
+ // instead. Components may specialize this.
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename Component, typename Context, typename Enable = void>
+ struct has_attribute;
+
+ namespace detail
+ {
+ template <typename Component, typename Context, typename Enable = void>
+ struct default_has_attribute
+ : mpl::not_<is_same<unused_type,
+ typename attribute_of<Component, Context>::type>> {};
+
+ template <typename Component, typename Context>
+ struct default_has_attribute<Component, Context,
+ typename disable_if_substitution_failure<
+ mpl::bool_<Component::has_attribute>>::type>
+ : mpl::bool_<Component::has_attribute> {};
+
+ template <typename Component, typename Context>
+ struct default_has_attribute<Component, Context,
+ typename enable_if_c<Component::is_pass_through_unary>::type>
+ : has_attribute<typename Component::subject_type, Context> {};
+ }
+
+ template <typename Component, typename Context, typename Enable>
+ struct has_attribute : detail::default_has_attribute<Component, Context> {};
+
+}}}}
+
+#endif
diff --git a/boost/spirit/home/x3/support/traits/is_parser.hpp b/boost/spirit/home/x3/support/traits/is_parser.hpp
new file mode 100644
index 0000000000..cfbe8f74b4
--- /dev/null
+++ b/boost/spirit/home/x3/support/traits/is_parser.hpp
@@ -0,0 +1,37 @@
+/*=============================================================================
+ Copyright (c) 2001-2014 Joel de Guzman
+ Copyright (c) 2014 Agustin Berge
+
+ 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(BOOST_SPIRIT_X3_IS_PARSER_MAY_20_2013_0235PM)
+#define BOOST_SPIRIT_X3_IS_PARSER_MAY_20_2013_0235PM
+
+#if defined(_MSC_VER)
+#pragma once
+#endif
+
+#include <boost/mpl/bool.hpp>
+#include <boost/spirit/home/x3/core/parser.hpp>
+#include <boost/spirit/home/x3/support/utility/sfinae.hpp>
+
+namespace boost { namespace spirit { namespace x3 { namespace traits
+{
+ ///////////////////////////////////////////////////////////////////////////
+ // is_parser<T>: metafunction that evaluates to mpl::true_ if a type T
+ // can be used as a parser, mpl::false_ otherwise
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename T, typename Enable = void>
+ struct is_parser
+ : mpl::false_
+ {};
+
+ template <typename T>
+ struct is_parser<T, typename disable_if_substitution_failure<
+ typename extension::as_parser<T>::type>::type>
+ : mpl::true_
+ {};
+}}}}
+
+#endif
diff --git a/boost/spirit/home/x3/support/traits/is_substitute.hpp b/boost/spirit/home/x3/support/traits/is_substitute.hpp
new file mode 100644
index 0000000000..9e023371ce
--- /dev/null
+++ b/boost/spirit/home/x3/support/traits/is_substitute.hpp
@@ -0,0 +1,164 @@
+/*=============================================================================
+ Copyright (c) 2001-2014 Joel de Guzman
+ http://spirit.sourceforge.net/
+
+ 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(BOOST_SPIRIT_X3_IS_SUBSTITUTE_JAN_9_2012_1049PM)
+#define BOOST_SPIRIT_X3_IS_SUBSTITUTE_JAN_9_2012_1049PM
+
+#if defined(_MSC_VER)
+#pragma once
+#endif
+
+#include <boost/spirit/home/x3/support/traits/container_traits.hpp>
+#include <boost/fusion/include/is_sequence.hpp>
+#include <boost/fusion/include/map.hpp>
+#include <boost/fusion/include/value_at_key.hpp>
+#include <boost/fusion/adapted/mpl.hpp>
+#include <boost/mpl/placeholders.hpp>
+#include <boost/mpl/equal.hpp>
+#include <boost/mpl/apply.hpp>
+#include <boost/mpl/filter_view.hpp>
+#include <boost/mpl/size.hpp>
+#include <boost/mpl/logical.hpp>
+#include <boost/mpl/at.hpp>
+#include <boost/mpl/count_if.hpp>
+#include <boost/utility/enable_if.hpp>
+#include <boost/optional/optional.hpp>
+#include <boost/type_traits/is_same.hpp>
+
+namespace boost { namespace spirit { namespace x3 { namespace traits
+{
+ ///////////////////////////////////////////////////////////////////////////
+ // Find out if T can be a (strong) substitute for Attribute
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename T, typename Attribute, typename Enable = void>
+ struct is_substitute;
+
+ template <typename Variant, typename Attribute>
+ struct variant_has_substitute;
+
+ namespace detail
+ {
+ template <typename T, typename Attribute>
+ struct value_type_is_substitute
+ : is_substitute<
+ typename container_value<T>::type
+ , typename container_value<Attribute>::type>
+ {};
+
+ template <typename T, typename Attribute, typename Enable = void>
+ struct is_substitute_impl : is_same<T, Attribute> {};
+
+ template <typename T, typename Attribute>
+ struct is_substitute_impl<T, Attribute,
+ typename enable_if<
+ mpl::and_<
+ fusion::traits::is_sequence<T>,
+ fusion::traits::is_sequence<Attribute>,
+ mpl::equal<T, Attribute, is_substitute<mpl::_1, mpl::_2>>
+ >
+ >::type>
+ : mpl::true_ {};
+
+ template <typename T, typename Attribute>
+ struct is_substitute_impl<T, Attribute,
+ typename enable_if<
+ mpl::and_<
+ is_container<T>,
+ is_container<Attribute>,
+ value_type_is_substitute<T, Attribute>
+ >
+ >::type>
+ : mpl::true_ {};
+
+ template <typename T, typename Attribute>
+ struct is_substitute_impl<T, Attribute,
+ typename enable_if<
+ is_variant<Attribute>
+ >::type>
+ : mpl::or_<
+ is_same<T, Attribute>
+ , variant_has_substitute<Attribute, T>
+ >
+ {};
+ }
+
+ template <typename T, typename Attribute, typename Enable /*= void*/>
+ struct is_substitute
+ : detail::is_substitute_impl<T, Attribute> {};
+
+ // for reference T
+ template <typename T, typename Attribute, typename Enable>
+ struct is_substitute<T&, Attribute, Enable>
+ : is_substitute<T, Attribute, Enable> {};
+
+ // for reference Attribute
+ template <typename T, typename Attribute, typename Enable>
+ struct is_substitute<T, Attribute&, Enable>
+ : is_substitute<T, Attribute, Enable> {};
+
+ // 2 element mpl tuple is compatible with fusion::map if:
+ // - it's first element type is existing key in map
+ // - it second element type is compatible to type stored at the key in map
+ template <typename T, typename Attribute>
+ struct is_substitute<T, Attribute
+ , typename enable_if<
+ typename mpl::eval_if<
+ mpl::and_<fusion::traits::is_sequence<T>
+ , fusion::traits::is_sequence<Attribute>>
+ , mpl::and_<traits::has_size<T, 2>
+ , fusion::traits::is_associative<Attribute>>
+ , mpl::false_>::type>::type>
+
+ {
+ // checking that "p_key >> p_value" parser can
+ // store it's result in fusion::map attribute
+ typedef typename mpl::at_c<T, 0>::type p_key;
+ typedef typename mpl::at_c<T, 1>::type p_value;
+
+ // for simple p_key type we just check that
+ // such key can be found in attr and that value under that key
+ // matches p_value
+ template <typename Key, typename Value, typename Map>
+ struct has_kv_in_map
+ : mpl::eval_if<
+ fusion::result_of::has_key<Map, Key>
+ , mpl::apply<
+ is_substitute<
+ fusion::result_of::value_at_key<mpl::_1, Key>
+ , Value>
+ , Map>
+ , mpl::false_>
+ {};
+
+ // if p_key is variant over multiple types (as a result of
+ // "(key1|key2|key3) >> p_value" parser) check that all
+ // keys are found in fusion::map attribute and that values
+ // under these keys match p_value
+ template <typename Variant>
+ struct variant_kv
+ : mpl::equal_to<
+ mpl::size< typename Variant::types>
+ , mpl::size< mpl::filter_view<typename Variant::types
+ , has_kv_in_map<mpl::_1, p_value, Attribute>>>
+ >
+ {};
+
+ typedef typename
+ mpl::eval_if<
+ is_variant<p_key>
+ , variant_kv<p_key>
+ , has_kv_in_map<p_key, p_value, Attribute>
+ >::type
+ type;
+ };
+
+ template <typename T, typename Attribute>
+ struct is_substitute<optional<T>, optional<Attribute>>
+ : is_substitute<T, Attribute> {};
+}}}}
+
+#endif
diff --git a/boost/spirit/home/x3/support/traits/is_variant.hpp b/boost/spirit/home/x3/support/traits/is_variant.hpp
new file mode 100644
index 0000000000..829a673c3f
--- /dev/null
+++ b/boost/spirit/home/x3/support/traits/is_variant.hpp
@@ -0,0 +1,45 @@
+/*=============================================================================
+ Copyright (c) 2001-2014 Joel de Guzman
+ http://spirit.sourceforge.net/
+
+ 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(BOOST_SPIRIT_X3_IS_VARIANT_JAN_10_2012_0823AM)
+#define BOOST_SPIRIT_X3_IS_VARIANT_JAN_10_2012_0823AM
+
+#if defined(_MSC_VER)
+#pragma once
+#endif
+
+#include <boost/variant.hpp>
+#include <boost/mpl/has_xxx.hpp>
+#include <boost/mpl/bool.hpp>
+
+namespace boost { namespace spirit { namespace x3 { namespace traits
+{
+ namespace detail
+ {
+ // By declaring a nested struct in your class/struct, you tell
+ // spirit that it is regarded as a variant type. The minimum
+ // required interface for such a variant is that it has constructors
+ // for various types supported by your variant and a typedef 'types'
+ // which is an mpl sequence of the contained types.
+ //
+ // This is an intrusive interface. For a non-intrusive interface,
+ // use the is_variant trait.
+ BOOST_MPL_HAS_XXX_TRAIT_DEF(adapted_variant_tag)
+ }
+
+ template <typename T, typename Enable = void>
+ struct is_variant
+ : detail::has_adapted_variant_tag<T>
+ {};
+
+ template <BOOST_VARIANT_ENUM_PARAMS(typename T)>
+ struct is_variant<boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)>>
+ : mpl::true_
+ {};
+}}}}
+
+#endif
diff --git a/boost/spirit/home/x3/support/traits/make_attribute.hpp b/boost/spirit/home/x3/support/traits/make_attribute.hpp
new file mode 100644
index 0000000000..cf3baeedaf
--- /dev/null
+++ b/boost/spirit/home/x3/support/traits/make_attribute.hpp
@@ -0,0 +1,86 @@
+/*=============================================================================
+ Copyright (c) 2001-2014 Joel de Guzman
+ Copyright (c) 2001-2012 Hartmut Kaiser
+ http://spirit.sourceforge.net/
+
+ 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(BOOST_SPIRIT_X3_MAKE_ATTRIBUTE_JAN_8_2012_0721PM)
+#define BOOST_SPIRIT_X3_MAKE_ATTRIBUTE_JAN_8_2012_0721PM
+
+#if defined(_MSC_VER)
+#pragma once
+#endif
+
+#include <boost/mpl/if.hpp>
+#include <boost/type_traits/remove_const.hpp>
+#include <boost/type_traits/add_reference.hpp>
+#include <boost/spirit/home/x3/support/unused.hpp>
+
+namespace boost { namespace spirit { namespace x3 { namespace traits
+{
+ template <typename Attribute>
+ struct make_attribute_base
+ {
+ static Attribute call(unused_type)
+ {
+ // synthesize the attribute/parameter
+ return Attribute();
+ }
+
+ template <typename T>
+ static T& call(T& value)
+ {
+ return value; // just pass the one provided
+ }
+ };
+
+ template <typename Attribute, typename ActualAttribute>
+ struct make_attribute : make_attribute_base<Attribute>
+ {
+ typedef ActualAttribute& type;
+ typedef ActualAttribute value_type;
+ };
+
+ template <typename Attribute>
+ struct make_attribute<Attribute, unused_type>
+ : make_attribute_base<Attribute>
+ {
+ typedef typename remove_const<Attribute>::type attribute_type;
+ typedef attribute_type type;
+ typedef attribute_type value_type;
+ };
+
+ template <typename Attribute, typename ActualAttribute>
+ struct make_attribute<Attribute&, ActualAttribute>
+ : make_attribute<Attribute, ActualAttribute> {};
+
+ template <typename Attribute, typename ActualAttribute>
+ struct make_attribute<Attribute const&, ActualAttribute>
+ : make_attribute<Attribute const, ActualAttribute> {};
+
+ template <typename ActualAttribute>
+ struct make_attribute<unused_type, ActualAttribute>
+ {
+ typedef unused_type type;
+ typedef unused_type value_type;
+ static unused_type call(unused_type)
+ {
+ return unused;
+ }
+ };
+
+ template <>
+ struct make_attribute<unused_type, unused_type>
+ {
+ typedef unused_type type;
+ typedef unused_type value_type;
+ static unused_type call(unused_type)
+ {
+ return unused;
+ }
+ };
+}}}}
+
+#endif
diff --git a/boost/spirit/home/x3/support/traits/move_to.hpp b/boost/spirit/home/x3/support/traits/move_to.hpp
new file mode 100644
index 0000000000..ecd7c6f202
--- /dev/null
+++ b/boost/spirit/home/x3/support/traits/move_to.hpp
@@ -0,0 +1,211 @@
+/*=============================================================================
+ Copyright (c) 2001-2014 Joel de Guzman
+ Copyright (c) 2013 Agustin Berge
+ http://spirit.sourceforge.net/
+
+ 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(BOOST_SPIRIT_X3_MOVE_TO_JAN_17_2013_0859PM)
+#define BOOST_SPIRIT_X3_MOVE_TO_JAN_17_2013_0859PM
+
+#if defined(_MSC_VER)
+#pragma once
+#endif
+
+#include <boost/spirit/home/x3/support/traits/attribute_category.hpp>
+#include <boost/spirit/home/x3/support/traits/tuple_traits.hpp>
+#include <boost/spirit/home/x3/support/traits/variant_has_substitute.hpp>
+#include <boost/fusion/include/is_sequence.hpp>
+#include <boost/fusion/include/front.hpp>
+#include <boost/fusion/include/size.hpp>
+#include <boost/fusion/include/move.hpp>
+#include <boost/fusion/include/is_sequence.hpp>
+#include <boost/range/iterator_range.hpp>
+#include <utility>
+
+namespace boost { namespace spirit { namespace x3 { namespace traits
+{
+ template <typename Source, typename Dest>
+ void move_to(Source&& src, Dest& dest);
+
+ template <typename Dest>
+ inline void move_to(unused_type, Dest&) {}
+
+ template <typename Source>
+ inline void move_to(Source&, unused_type) {}
+
+ inline void move_to(unused_type, unused_type) {}
+
+ template <typename Iterator, typename Dest>
+ void
+ move_to(Iterator first, Iterator last, Dest& dest);
+
+ template <typename Iterator>
+ inline void
+ move_to(Iterator, Iterator, unused_type) {}
+
+ namespace detail
+ {
+ template <typename Source, typename Dest>
+ inline void
+ move_to(Source&&, Dest&, unused_attribute) {}
+
+ template <typename Source, typename Dest>
+ inline void
+ move_to_plain(Source&& src, Dest& dest, mpl::false_) // src is not a single-element tuple
+ {
+ dest = std::move(src);
+ }
+
+ template <typename Source, typename Dest>
+ inline void
+ move_to_plain(Source&& src, Dest& dest, mpl::true_) // src is a single-element tuple
+ {
+ dest = std::move(fusion::front(src));
+ }
+
+ template <typename Source, typename Dest>
+ inline void
+ move_to(Source&& src, Dest& dest, plain_attribute)
+ {
+ typename mpl::and_<
+ fusion::traits::is_sequence<Source>,
+ is_size_one_sequence<Source> >
+ is_single_element_sequence;
+
+ move_to_plain(std::move(src), dest, is_single_element_sequence);
+ }
+
+ template <typename Source, typename Dest>
+ inline typename enable_if<is_container<Source>>::type
+ move_to(Source&& src, Dest& dest, container_attribute)
+ {
+ traits::move_to(src.begin(), src.end(), dest);
+ }
+
+ template <typename Source, typename Dest>
+ inline typename enable_if<
+ mpl::and_<
+ is_same_size_sequence<Dest, Source>,
+ mpl::not_<is_size_one_sequence<Dest> > >
+ >::type
+ move_to(Source&& src, Dest& dest, tuple_attribute)
+ {
+ fusion::move(std::move(src), dest);
+ }
+
+ template <typename Source, typename Dest>
+ inline typename enable_if<
+ is_size_one_sequence<Dest>
+ >::type
+ move_to(Source&& src, Dest& dest, tuple_attribute)
+ {
+ traits::move_to(src, fusion::front(dest));
+ }
+
+ template <typename Source, typename Dest>
+ inline void
+ move_to(Source&& src, Dest& dest, variant_attribute, mpl::false_)
+ {
+ dest = std::move(src);
+ }
+
+ template <typename Source, typename Dest>
+ inline void
+ move_to_variant_from_single_element_sequence(Source&& src, Dest& dest, mpl::false_)
+ {
+ // dest is a variant, src is a single element fusion sequence that the variant
+ // cannot directly hold. We'll try to unwrap the single element fusion sequence.
+
+ // Make sure that the Dest variant can really hold Source
+ static_assert(variant_has_substitute<Dest, typename fusion::result_of::front<Source>::type>::value,
+ "Error! The destination variant (Dest) cannot hold the source type (Source)");
+
+ dest = std::move(fusion::front(src));
+ }
+
+ template <typename Source, typename Dest>
+ inline void
+ move_to_variant_from_single_element_sequence(Source&& src, Dest& dest, mpl::true_)
+ {
+ // dest is a variant, src is a single element fusion sequence that the variant
+ // *can* directly hold.
+ dest = std::move(src);
+ }
+
+ template <typename Source, typename Dest>
+ inline void
+ move_to(Source&& src, Dest& dest, variant_attribute, mpl::true_)
+ {
+ move_to_variant_from_single_element_sequence(src, dest, variant_has_substitute<Dest, Source>());
+ }
+
+ template <typename Source, typename Dest>
+ inline void
+ move_to(Source&& src, Dest& dest, variant_attribute tag)
+ {
+ move_to(src, dest, tag, is_size_one_sequence<Source>());
+ }
+
+ template <typename Iterator>
+ inline void
+ move_to(Iterator, Iterator, unused_type, unused_attribute) {}
+
+ template <typename Iterator, typename Dest>
+ inline void
+ move_to(Iterator first, Iterator last, Dest& dest, container_attribute)
+ {
+ if (is_empty(dest))
+ dest = Dest(first, last);
+ else
+ append(dest, first, last);
+ }
+
+ template <typename Iterator>
+ inline void
+ move_to(Iterator first, Iterator last, boost::iterator_range<Iterator>& rng, container_attribute)
+ {
+ rng = {first, last};
+ }
+ }
+
+ template <typename Source, typename Dest>
+ inline void
+ move_to(Source&& src, Dest& dest)
+ {
+ detail::move_to(std::move(src), dest
+ , typename attribute_category<Dest>::type());
+ }
+
+ template <typename T>
+ inline void move_to(T& src, T& dest)
+ {
+ if (&src != &dest)
+ dest = std::move(src);
+ }
+
+ template <typename T>
+ inline void move_to(T const& src, T& dest)
+ {
+ if (&src != &dest)
+ dest = std::move(src);
+ }
+
+ template <typename T>
+ inline void move_to(T&& src, T& dest)
+ {
+ if (&src != &dest)
+ dest = std::move(src);
+ }
+
+ template <typename Iterator, typename Dest>
+ inline void
+ move_to(Iterator first, Iterator last, Dest& dest)
+ {
+ // $$$ Use std::move_iterator when iterator is not a const-iterator $$$
+ detail::move_to(first, last, dest, typename attribute_category<Dest>::type());
+ }
+}}}}
+
+#endif
diff --git a/boost/spirit/home/x3/support/traits/numeric_traits.hpp b/boost/spirit/home/x3/support/traits/numeric_traits.hpp
new file mode 100644
index 0000000000..3cdbdaec63
--- /dev/null
+++ b/boost/spirit/home/x3/support/traits/numeric_traits.hpp
@@ -0,0 +1,128 @@
+/*=============================================================================
+ 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(BOOST_SPIRIT_X3_NUMERIC_TRAITS_JAN_07_2011_0722AM)
+#define BOOST_SPIRIT_X3_NUMERIC_TRAITS_JAN_07_2011_0722AM
+
+#if defined(_MSC_VER)
+#pragma once
+#endif
+
+#include <boost/config.hpp>
+#include <boost/integer_traits.hpp>
+#include <boost/mpl/bool.hpp>
+#include <boost/utility/enable_if.hpp>
+
+namespace boost { namespace spirit { namespace x3 { namespace traits
+{
+ ///////////////////////////////////////////////////////////////////////////
+ // Determine if T is a boolean type
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename T>
+ struct is_bool : mpl::false_ {};
+
+ template <typename T>
+ struct is_bool<T const> : is_bool<T> {};
+
+ template <>
+ struct is_bool<bool> : mpl::true_ {};
+
+ ///////////////////////////////////////////////////////////////////////////
+ // Determine if T is a signed integer type
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename T>
+ struct is_int : mpl::false_ {};
+
+ template <typename T>
+ struct is_int<T const> : is_int<T> {};
+
+ template <>
+ struct is_int<short> : mpl::true_ {};
+
+ template <>
+ struct is_int<int> : mpl::true_ {};
+
+ template <>
+ struct is_int<long> : mpl::true_ {};
+
+#ifdef BOOST_HAS_LONG_LONG
+ template <>
+ struct is_int<boost::long_long_type> : mpl::true_ {};
+#endif
+
+ ///////////////////////////////////////////////////////////////////////////
+ // Determine if T is an unsigned integer type
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename T>
+ struct is_uint : mpl::false_ {};
+
+ template <typename T>
+ struct is_uint<T const> : is_uint<T> {};
+
+#if !defined(BOOST_NO_INTRINSIC_WCHAR_T)
+ template <>
+ struct is_uint<unsigned short> : mpl::true_ {};
+#endif
+
+ template <>
+ struct is_uint<unsigned int> : mpl::true_ {};
+
+ template <>
+ struct is_uint<unsigned long> : mpl::true_ {};
+
+#ifdef BOOST_HAS_LONG_LONG
+ template <>
+ struct is_uint<boost::ulong_long_type> : mpl::true_ {};
+#endif
+
+ ///////////////////////////////////////////////////////////////////////////
+ // Determine if T is a floating point type
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename T>
+ struct is_real : mpl::false_ {};
+
+ template <typename T>
+ struct is_real<T const> : is_uint<T> {};
+
+ template <>
+ struct is_real<float> : mpl::true_ {};
+
+ template <>
+ struct is_real<double> : mpl::true_ {};
+
+ template <>
+ struct is_real<long double> : mpl::true_ {};
+
+ ///////////////////////////////////////////////////////////////////////////
+ // customization points for numeric operations
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename T, typename Enable = void>
+ struct absolute_value;
+
+ template <typename T, typename Enable = void>
+ struct is_negative;
+
+ template <typename T, typename Enable = void>
+ struct is_zero;
+
+ template <typename T, typename Enable = void>
+ struct pow10_helper;
+
+ template <typename T, typename Enable = void>
+ struct is_nan;
+
+ template <typename T, typename Enable = void>
+ struct is_infinite;
+
+ template <typename T, typename Enable = void>
+ struct check_overflow : mpl::false_ {};
+
+ template <typename T>
+ struct check_overflow<T, typename enable_if_c<integer_traits<T>::is_integral>::type>
+ : mpl::true_ {};
+}}}}
+
+#endif
diff --git a/boost/spirit/home/x3/support/traits/optional_traits.hpp b/boost/spirit/home/x3/support/traits/optional_traits.hpp
new file mode 100644
index 0000000000..65568b0265
--- /dev/null
+++ b/boost/spirit/home/x3/support/traits/optional_traits.hpp
@@ -0,0 +1,78 @@
+/*=============================================================================
+ Copyright (c) 2001-2014 Joel de Guzman
+ Copyright (c) 2001-2011 Hartmut Kaiser
+ http://spirit.sourceforge.net/
+
+ 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(BOOST_SPIRIT_X3_OPTIONAL_TRAITS_FEBRUARY_06_2007_1001AM)
+#define BOOST_SPIRIT_X3_OPTIONAL_TRAITS_FEBRUARY_06_2007_1001AM
+
+#if defined(_MSC_VER)
+#pragma once
+#endif
+
+#include <boost/spirit/home/x3/support/unused.hpp>
+#include <boost/optional/optional.hpp>
+#include <boost/mpl/identity.hpp>
+
+namespace boost { namespace spirit { namespace x3 { namespace traits
+{
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename T, typename Enable = void>
+ struct is_optional
+ : mpl::false_
+ {};
+
+ template <typename T>
+ struct is_optional<boost::optional<T>>
+ : mpl::true_
+ {};
+
+ ///////////////////////////////////////////////////////////////////////////
+ // build_optional
+ //
+ // Build a boost::optional from T. Return unused_type if T is unused_type.
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename T>
+ struct build_optional
+ {
+ typedef boost::optional<T> type;
+ };
+
+ template <typename T>
+ struct build_optional<boost::optional<T> >
+ {
+ typedef boost::optional<T> type;
+ };
+
+ template <>
+ struct build_optional<unused_type>
+ {
+ typedef unused_type type;
+ };
+
+ ///////////////////////////////////////////////////////////////////////////
+ // optional_value
+ //
+ // Get the optional's value_type. Handles unused_type as well.
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename T>
+ struct optional_value : mpl::identity<T> {};
+
+ template <typename T>
+ struct optional_value<boost::optional<T> >
+ : mpl::identity<T> {};
+
+ template <>
+ struct optional_value<unused_type>
+ : mpl::identity<unused_type> {};
+
+ template <>
+ struct optional_value<unused_type const>
+ : mpl::identity<unused_type> {};
+
+}}}}
+
+#endif
diff --git a/boost/spirit/home/x3/support/traits/print_attribute.hpp b/boost/spirit/home/x3/support/traits/print_attribute.hpp
new file mode 100644
index 0000000000..47bffce1a1
--- /dev/null
+++ b/boost/spirit/home/x3/support/traits/print_attribute.hpp
@@ -0,0 +1,150 @@
+/*=============================================================================
+ 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(BOOST_SPIRIT_X3_PRINT_ATTRIBUTE_JANUARY_20_2013_0814AM)
+#define BOOST_SPIRIT_X3_PRINT_ATTRIBUTE_JANUARY_20_2013_0814AM
+
+#if defined(_MSC_VER)
+#pragma once
+#endif
+
+#include <boost/variant.hpp>
+#include <boost/optional/optional.hpp>
+#include <boost/fusion/include/is_sequence.hpp>
+#include <boost/fusion/include/for_each.hpp>
+#include <boost/spirit/home/x3/support/traits/attribute_category.hpp>
+#include <boost/spirit/home/x3/support/traits/is_variant.hpp>
+
+namespace boost { namespace spirit { namespace x3 { namespace traits
+{
+ template <typename Out, typename T>
+ void print_attribute(Out& out, T const& val);
+
+ template <typename Out>
+ inline void print_attribute(Out&, unused_type) {}
+
+ ///////////////////////////////////////////////////////////////////////////
+ namespace detail
+ {
+ template <typename Out>
+ struct print_fusion_sequence
+ {
+ print_fusion_sequence(Out& out)
+ : out(out), is_first(true) {}
+
+ typedef void result_type;
+
+ template <typename T>
+ void operator()(T const& val) const
+ {
+ if (is_first)
+ is_first = false;
+ else
+ out << ", ";
+ x3::traits::print_attribute(out, val);
+ }
+
+ Out& out;
+ mutable bool is_first;
+ };
+
+ // print elements in a variant
+ template <typename Out>
+ struct print_visitor : static_visitor<>
+ {
+ print_visitor(Out& out) : out(out) {}
+
+ template <typename T>
+ void operator()(T const& val) const
+ {
+ x3::traits::print_attribute(out, val);
+ }
+
+ Out& out;
+ };
+ }
+
+ template <typename Out, typename T, typename Enable = void>
+ struct print_attribute_debug
+ {
+ // for plain data types
+ template <typename T_>
+ static void call(Out& out, T_ const& val, unused_attribute)
+ {
+ out << "unused";
+ }
+
+ // for plain data types
+ template <typename T_>
+ static void call(Out& out, T_ const& val, plain_attribute)
+ {
+ out << val;
+ }
+
+ // for fusion data types
+ template <typename T_>
+ static void call(Out& out, T_ const& val, tuple_attribute)
+ {
+ out << '[';
+ fusion::for_each(val, detail::print_fusion_sequence<Out>(out));
+ out << ']';
+ }
+
+ // stl container
+ template <typename T_>
+ static void call(Out& out, T_ const& val, container_attribute)
+ {
+ out << '[';
+ if (!traits::is_empty(val))
+ {
+ bool first = true;
+ typename container_iterator<T_ const>::type iend = traits::end(val);
+ for (typename container_iterator<T_ const>::type i = traits::begin(val);
+ !traits::compare(i, iend); traits::next(i))
+ {
+ if (!first)
+ out << ", ";
+ first = false;
+ x3::traits::print_attribute(out, traits::deref(i));
+ }
+ }
+ out << ']';
+ }
+
+ // for variant types
+ template <typename T_>
+ static void call(Out& out, T_ const& val, variant_attribute)
+ {
+ apply_visitor(detail::print_visitor<Out>(out), val);
+ }
+
+ // for optional types
+ template <typename T_>
+ static void call(Out& out, T_ const& val, optional_attribute)
+ {
+ if (val)
+ x3::traits::print_attribute(out, *val);
+ else
+ out << "[empty]";
+ }
+
+ // main entry point
+ static void call(Out& out, T const& val)
+ {
+ call(out, val, typename attribute_category<T>::type());
+ }
+ };
+
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename Out, typename T>
+ inline void print_attribute(Out& out, T const& val)
+ {
+ print_attribute_debug<Out, T>::call(out, val);
+ }
+}}}}
+
+#endif
diff --git a/boost/spirit/home/x3/support/traits/print_token.hpp b/boost/spirit/home/x3/support/traits/print_token.hpp
new file mode 100644
index 0000000000..f1429f4776
--- /dev/null
+++ b/boost/spirit/home/x3/support/traits/print_token.hpp
@@ -0,0 +1,79 @@
+/*=============================================================================
+ 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(BOOST_SPIRIT_X3_PRINT_TOKEN_JANUARY_20_2013_0814AM)
+#define BOOST_SPIRIT_X3_PRINT_TOKEN_JANUARY_20_2013_0814AM
+
+#if defined(_MSC_VER)
+#pragma once
+#endif
+
+#include <boost/mpl/if.hpp>
+#include <boost/mpl/and.hpp>
+#include <boost/type_traits/is_convertible.hpp>
+#include <cctype>
+
+namespace boost { namespace spirit { namespace x3 { namespace traits
+{
+ ///////////////////////////////////////////////////////////////////////////
+ // generate debug output for lookahead token (character) stream
+ namespace detail
+ {
+ struct token_printer_debug_for_chars
+ {
+ template<typename Out, typename Char>
+ static void print(Out& o, Char c)
+ {
+ using namespace std; // allow for ADL to find the proper iscntrl
+
+ switch (c)
+ {
+ case '\a': o << "\\a"; break;
+ case '\b': o << "\\b"; break;
+ case '\f': o << "\\f"; break;
+ case '\n': o << "\\n"; break;
+ case '\r': o << "\\r"; break;
+ case '\t': o << "\\t"; break;
+ case '\v': o << "\\v"; break;
+ default:
+ if (c >= 0 && c < 127 && iscntrl(c))
+ o << "\\" << std::oct << int(c);
+ else
+ o << Char(c);
+ }
+ }
+ };
+
+ // for token types where the comparison with char constants wouldn't work
+ struct token_printer_debug
+ {
+ template<typename Out, typename T>
+ static void print(Out& o, T const& val)
+ {
+ o << val;
+ }
+ };
+ }
+
+ template <typename T, typename Enable = void>
+ struct token_printer_debug
+ : mpl::if_<
+ mpl::and_<
+ is_convertible<T, char>, is_convertible<char, T> >
+ , detail::token_printer_debug_for_chars
+ , detail::token_printer_debug>::type
+ {};
+
+ template <typename Out, typename T>
+ inline void print_token(Out& out, T const& val)
+ {
+ // allow to customize the token printer routine
+ token_printer_debug<T>::print(out, val);
+ }
+}}}}
+
+#endif
diff --git a/boost/spirit/home/x3/support/traits/string_traits.hpp b/boost/spirit/home/x3/support/traits/string_traits.hpp
new file mode 100644
index 0000000000..46ee356cdc
--- /dev/null
+++ b/boost/spirit/home/x3/support/traits/string_traits.hpp
@@ -0,0 +1,291 @@
+/*=============================================================================
+ Copyright (c) 2001-2014 Joel de Guzman
+ Copyright (c) 2001-2011 Hartmut Kaiser
+ Copyright (c) 2010 Bryce Lelbach
+
+ 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(BOOST_SPIRIT_X3_STRING_TRAITS_OCTOBER_2008_1252PM)
+#define BOOST_SPIRIT_X3_STRING_TRAITS_OCTOBER_2008_1252PM
+
+#if defined(_MSC_VER)
+#pragma once
+#endif
+
+#include <string>
+#include <boost/mpl/bool.hpp>
+#include <boost/mpl/identity.hpp>
+
+namespace boost { namespace spirit { namespace x3 { namespace traits
+{
+ ///////////////////////////////////////////////////////////////////////////
+ // Determine if T is a character type
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename T>
+ struct is_char : mpl::false_ {};
+
+ template <typename T>
+ struct is_char<T const> : is_char<T> {};
+
+ template <>
+ struct is_char<char> : mpl::true_ {};
+
+ template <>
+ struct is_char<wchar_t> : mpl::true_ {};
+
+ ///////////////////////////////////////////////////////////////////////////
+ // Determine if T is a string
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename T>
+ struct is_string : mpl::false_ {};
+
+ template <typename T>
+ struct is_string<T const> : is_string<T> {};
+
+ template <>
+ struct is_string<char const*> : mpl::true_ {};
+
+ template <>
+ struct is_string<wchar_t const*> : mpl::true_ {};
+
+ template <>
+ struct is_string<char*> : mpl::true_ {};
+
+ template <>
+ struct is_string<wchar_t*> : mpl::true_ {};
+
+ template <std::size_t N>
+ struct is_string<char[N]> : mpl::true_ {};
+
+ template <std::size_t N>
+ struct is_string<wchar_t[N]> : mpl::true_ {};
+
+ template <std::size_t N>
+ struct is_string<char const[N]> : mpl::true_ {};
+
+ template <std::size_t N>
+ struct is_string<wchar_t const[N]> : mpl::true_ {};
+
+ template <std::size_t N>
+ struct is_string<char(&)[N]> : mpl::true_ {};
+
+ template <std::size_t N>
+ struct is_string<wchar_t(&)[N]> : mpl::true_ {};
+
+ template <std::size_t N>
+ struct is_string<char const(&)[N]> : mpl::true_ {};
+
+ template <std::size_t N>
+ struct is_string<wchar_t const(&)[N]> : mpl::true_ {};
+
+ template <typename T, typename Traits, typename Allocator>
+ struct is_string<std::basic_string<T, Traits, Allocator> > : mpl::true_ {};
+
+ ///////////////////////////////////////////////////////////////////////////
+ // Get the underlying char type of a string
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename T>
+ struct char_type_of;
+
+ template <typename T>
+ struct char_type_of<T const> : char_type_of<T> {};
+
+ template <>
+ struct char_type_of<char> : mpl::identity<char> {};
+
+ template <>
+ struct char_type_of<wchar_t> : mpl::identity<wchar_t> {};
+
+ template <>
+ struct char_type_of<char const*> : mpl::identity<char const> {};
+
+ template <>
+ struct char_type_of<wchar_t const*> : mpl::identity<wchar_t const> {};
+
+ template <>
+ struct char_type_of<char*> : mpl::identity<char> {};
+
+ template <>
+ struct char_type_of<wchar_t*> : mpl::identity<wchar_t> {};
+
+ template <std::size_t N>
+ struct char_type_of<char[N]> : mpl::identity<char> {};
+
+ template <std::size_t N>
+ struct char_type_of<wchar_t[N]> : mpl::identity<wchar_t> {};
+
+ template <std::size_t N>
+ struct char_type_of<char const[N]> : mpl::identity<char const> {};
+
+ template <std::size_t N>
+ struct char_type_of<wchar_t const[N]> : mpl::identity<wchar_t const> {};
+
+ template <std::size_t N>
+ struct char_type_of<char(&)[N]> : mpl::identity<char> {};
+
+ template <std::size_t N>
+ struct char_type_of<wchar_t(&)[N]> : mpl::identity<wchar_t> {};
+
+ template <std::size_t N>
+ struct char_type_of<char const(&)[N]> : mpl::identity<char const> {};
+
+ template <std::size_t N>
+ struct char_type_of<wchar_t const(&)[N]> : mpl::identity<wchar_t const> {};
+
+ template <typename T, typename Traits, typename Allocator>
+ struct char_type_of<std::basic_string<T, Traits, Allocator> >
+ : mpl::identity<T> {};
+
+ ///////////////////////////////////////////////////////////////////////////
+ // Get the C string from a string
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename String>
+ struct extract_c_string;
+
+ template <typename String>
+ struct extract_c_string
+ {
+ typedef typename char_type_of<String>::type char_type;
+
+ template <typename T>
+ static T const* call (T* str)
+ {
+ return (T const*)str;
+ }
+
+ template <typename T>
+ static T const* call (T const* str)
+ {
+ return str;
+ }
+ };
+
+ // Forwarder that strips const
+ template <typename T>
+ struct extract_c_string<T const>
+ {
+ typedef typename extract_c_string<T>::char_type char_type;
+
+ static typename extract_c_string<T>::char_type const* call (T const str)
+ {
+ return extract_c_string<T>::call(str);
+ }
+ };
+
+ // Forwarder that strips references
+ template <typename T>
+ struct extract_c_string<T&>
+ {
+ typedef typename extract_c_string<T>::char_type char_type;
+
+ static typename extract_c_string<T>::char_type const* call (T& str)
+ {
+ return extract_c_string<T>::call(str);
+ }
+ };
+
+ // Forwarder that strips const references
+ template <typename T>
+ struct extract_c_string<T const&>
+ {
+ typedef typename extract_c_string<T>::char_type char_type;
+
+ static typename extract_c_string<T>::char_type const* call (T const& str)
+ {
+ return extract_c_string<T>::call(str);
+ }
+ };
+
+ template <typename T, typename Traits, typename Allocator>
+ struct extract_c_string<std::basic_string<T, Traits, Allocator> >
+ {
+ typedef T char_type;
+
+ typedef std::basic_string<T, Traits, Allocator> string;
+
+ static T const* call (string const& str)
+ {
+ return str.c_str();
+ }
+ };
+
+ template <typename T>
+ typename extract_c_string<T*>::char_type const*
+ get_c_string(T* str)
+ {
+ return extract_c_string<T*>::call(str);
+ }
+
+ template <typename T>
+ typename extract_c_string<T const*>::char_type const*
+ get_c_string(T const* str)
+ {
+ return extract_c_string<T const*>::call(str);
+ }
+
+ template <typename String>
+ typename extract_c_string<String>::char_type const*
+ get_c_string(String& str)
+ {
+ return extract_c_string<String>::call(str);
+ }
+
+ template <typename String>
+ typename extract_c_string<String>::char_type const*
+ get_c_string(String const& str)
+ {
+ return extract_c_string<String>::call(str);
+ }
+
+ ///////////////////////////////////////////////////////////////////////////
+ // Get the begin/end iterators from a string
+ ///////////////////////////////////////////////////////////////////////////
+
+ // Implementation for C-style strings.
+
+ template <typename T>
+ inline T const* get_string_begin(T const* str) { return str; }
+
+ template <typename T>
+ inline T* get_string_begin(T* str) { return str; }
+
+ template <typename T>
+ inline T const* get_string_end(T const* str)
+ {
+ T const* last = str;
+ while (*last)
+ last++;
+ return last;
+ }
+
+ template <typename T>
+ inline T* get_string_end(T* str)
+ {
+ T* last = str;
+ while (*last)
+ last++;
+ return last;
+ }
+
+ // Implementation for containers (includes basic_string).
+ template <typename T, typename Str>
+ inline typename Str::const_iterator get_string_begin(Str const& str)
+ { return str.begin(); }
+
+ template <typename T, typename Str>
+ inline typename Str::iterator
+ get_string_begin(Str& str)
+ { return str.begin(); }
+
+ template <typename T, typename Str>
+ inline typename Str::const_iterator get_string_end(Str const& str)
+ { return str.end(); }
+
+ template <typename T, typename Str>
+ inline typename Str::iterator
+ get_string_end(Str& str)
+ { return str.end(); }
+}}}}
+
+#endif
diff --git a/boost/spirit/home/x3/support/traits/transform_attribute.hpp b/boost/spirit/home/x3/support/traits/transform_attribute.hpp
new file mode 100644
index 0000000000..24268520d7
--- /dev/null
+++ b/boost/spirit/home/x3/support/traits/transform_attribute.hpp
@@ -0,0 +1,48 @@
+/*=============================================================================
+ Copyright (c) 2001-2014 Joel de Guzman
+ Copyright (c) 2001-2012 Hartmut Kaiser
+ http://spirit.sourceforge.net/
+
+ 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(BOOST_SPIRIT_X3_ATTRIBUTE_TRANSFORM_JAN_8_2012_0721PM)
+#define BOOST_SPIRIT_X3_ATTRIBUTE_TRANSFORM_JAN_8_2012_0721PM
+
+#if defined(_MSC_VER)
+#pragma once
+#endif
+
+#include <boost/mpl/identity.hpp>
+
+namespace boost { namespace spirit { namespace x3 { namespace traits
+{
+ ///////////////////////////////////////////////////////////////////////////
+ // transform_attribute
+ //
+ // Sometimes the user needs to transform the attribute types for certain
+ // attributes. This template can be used as a customization point, where
+ // the user is able specify specific transformation rules for any attribute
+ // type.
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename Exposed, typename Transformed, typename Tag
+ , typename Enable = void>
+ struct transform_attribute;
+
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename Tag, typename Transformed, typename Exposed>
+ typename transform_attribute<Exposed, Transformed, Tag>::type
+ pre_transform(Exposed& attr)
+ {
+ return transform_attribute<Exposed, Transformed, Tag>::pre(attr);
+ }
+
+ template <typename Tag, typename Transformed, typename Exposed>
+ typename transform_attribute<Exposed, Transformed, Tag>::type
+ pre_transform(Exposed const& attr)
+ {
+ return transform_attribute<Exposed const, Transformed, Tag>::pre(attr);
+ }
+}}}}
+
+#endif
diff --git a/boost/spirit/home/x3/support/traits/tuple_traits.hpp b/boost/spirit/home/x3/support/traits/tuple_traits.hpp
new file mode 100644
index 0000000000..17bfd4e1cb
--- /dev/null
+++ b/boost/spirit/home/x3/support/traits/tuple_traits.hpp
@@ -0,0 +1,52 @@
+/*=============================================================================
+ 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(BOOST_SPIRIT_X3_TUPLE_TRAITS_JANUARY_2012_1132PM)
+#define BOOST_SPIRIT_X3_TUPLE_TRAITS_JANUARY_2012_1132PM
+
+#if defined(_MSC_VER)
+#pragma once
+#endif
+
+#include <boost/fusion/include/is_sequence.hpp>
+#include <boost/fusion/include/size.hpp>
+#include <boost/mpl/bool.hpp>
+#include <boost/mpl/and.hpp>
+
+namespace boost { namespace spirit { namespace x3 { namespace traits
+{
+ template <typename A, typename B>
+ struct has_same_size
+ : mpl::bool_<(
+ fusion::result_of::size<A>::value ==
+ fusion::result_of::size<B>::value
+ )>
+ {};
+
+ template <typename T, std::size_t N>
+ struct has_size
+ : mpl::bool_<(fusion::result_of::size<T>::value == N)>
+ {};
+
+ template <typename A, typename B>
+ struct is_same_size_sequence
+ : mpl::and_<
+ fusion::traits::is_sequence<A>
+ , fusion::traits::is_sequence<B>
+ , has_same_size<A, B>
+ >
+ {};
+
+ template <typename Seq>
+ struct is_size_one_sequence
+ : mpl::and_<
+ fusion::traits::is_sequence<Seq>
+ , has_size<Seq, 1>
+ >
+ {};
+}}}}
+
+#endif
diff --git a/boost/spirit/home/x3/support/traits/value_traits.hpp b/boost/spirit/home/x3/support/traits/value_traits.hpp
new file mode 100644
index 0000000000..5f004c957c
--- /dev/null
+++ b/boost/spirit/home/x3/support/traits/value_traits.hpp
@@ -0,0 +1,30 @@
+/*=============================================================================
+ Copyright (c) 2001-2014 Joel de Guzman
+ Copyright (c) 2001-2011 Hartmut Kaiser
+ http://spirit.sourceforge.net/
+
+ 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(BOOST_SPIRIT_X3_VALUE_TRAITS_MAY_07_2013_0203PM)
+#define BOOST_SPIRIT_X3_VALUE_TRAITS_MAY_07_2013_0203PM
+
+#if defined(_MSC_VER)
+#pragma once
+#endif
+
+#include <boost/utility/value_init.hpp>
+
+namespace boost { namespace spirit { namespace x3 { namespace traits
+{
+ template <typename T, typename Enable = void>
+ struct value_initialize
+ {
+ static T call()
+ {
+ return boost::value_initialized<T>();
+ }
+ };
+}}}}
+
+#endif
diff --git a/boost/spirit/home/x3/support/traits/variant_find_substitute.hpp b/boost/spirit/home/x3/support/traits/variant_find_substitute.hpp
new file mode 100644
index 0000000000..4de7b7d5e3
--- /dev/null
+++ b/boost/spirit/home/x3/support/traits/variant_find_substitute.hpp
@@ -0,0 +1,56 @@
+/*=============================================================================
+ Copyright (c) 2001-2014 Joel de Guzman
+ http://spirit.sourceforge.net/
+
+ 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(BOOST_SPIRIT_X3_VARIANT_FIND_SUBSTITUTE_APR_18_2014_930AM)
+#define BOOST_SPIRIT_X3_VARIANT_FIND_SUBSTITUTE_APR_18_2014_930AM
+
+#if defined(_MSC_VER)
+#pragma once
+#endif
+
+#include <boost/spirit/home/x3/support/traits/is_substitute.hpp>
+
+namespace boost { namespace spirit { namespace x3 { namespace traits
+{
+ template <typename Variant, typename Attribute>
+ struct variant_find_substitute
+ {
+ // Get the type from the variant that can be a substitute for Attribute.
+ // If none is found, just return Attribute
+
+ typedef Variant variant_type;
+ typedef typename variant_type::types types;
+ typedef typename mpl::end<types>::type end;
+
+ typedef typename
+ mpl::find_if<types, is_same<mpl::_1, Attribute> >::type
+ iter_1;
+
+ typedef typename
+ mpl::eval_if<
+ is_same<iter_1, end>,
+ mpl::find_if<types, traits::is_substitute<mpl::_1, Attribute> >,
+ mpl::identity<iter_1>
+ >::type
+ iter;
+
+ typedef typename
+ mpl::eval_if<
+ is_same<iter, end>,
+ mpl::identity<Attribute>,
+ mpl::deref<iter>
+ >::type
+ type;
+ };
+
+ template <typename Variant>
+ struct variant_find_substitute<Variant, Variant>
+ : mpl::identity<Variant> {};
+
+}}}}
+
+#endif
diff --git a/boost/spirit/home/x3/support/traits/variant_has_substitute.hpp b/boost/spirit/home/x3/support/traits/variant_has_substitute.hpp
new file mode 100644
index 0000000000..d0dfb49b8d
--- /dev/null
+++ b/boost/spirit/home/x3/support/traits/variant_has_substitute.hpp
@@ -0,0 +1,56 @@
+/*=============================================================================
+ Copyright (c) 2001-2014 Joel de Guzman
+ http://spirit.sourceforge.net/
+
+ 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(BOOST_SPIRIT_X3_VARIANT_HAS_SUBSTITUTE_APR_18_2014_925AM)
+#define BOOST_SPIRIT_X3_VARIANT_HAS_SUBSTITUTE_APR_18_2014_925AM
+
+#if defined(_MSC_VER)
+#pragma once
+#endif
+
+#include <boost/spirit/home/x3/support/traits/is_substitute.hpp>
+
+namespace boost { namespace spirit { namespace x3 { namespace traits
+{
+ template <typename Variant, typename Attribute>
+ struct variant_has_substitute_impl
+ {
+ // Find a type from the variant that can be a substitute for Attribute.
+ // return true_ if one is found, else false_
+
+ typedef Variant variant_type;
+ typedef typename variant_type::types types;
+ typedef typename mpl::end<types>::type end;
+
+ typedef typename
+ mpl::find_if<types, is_same<mpl::_1, Attribute>>::type
+ iter_1;
+
+ typedef typename
+ mpl::eval_if<
+ is_same<iter_1, end>,
+ mpl::find_if<types, traits::is_substitute<mpl::_1, Attribute>>,
+ mpl::identity<iter_1>
+ >::type
+ iter;
+
+ typedef mpl::not_<is_same<iter, end>> type;
+ };
+
+ template <typename Variant, typename Attribute>
+ struct variant_has_substitute
+ : variant_has_substitute_impl<Variant, Attribute>::type {};
+
+ template <typename Attribute>
+ struct variant_has_substitute<unused_type, Attribute> : mpl::true_ {};
+
+ template <typename Attribute>
+ struct variant_has_substitute<unused_type const, Attribute> : mpl::true_ {};
+
+}}}}
+
+#endif
diff --git a/boost/spirit/home/x3/support/unused.hpp b/boost/spirit/home/x3/support/unused.hpp
new file mode 100644
index 0000000000..cf42d13098
--- /dev/null
+++ b/boost/spirit/home/x3/support/unused.hpp
@@ -0,0 +1,93 @@
+/*=============================================================================
+ 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(BOOST_SPIRIT_X3_UNUSED_APRIL_16_2006_0616PM)
+#define BOOST_SPIRIT_X3_UNUSED_APRIL_16_2006_0616PM
+
+#if defined(_MSC_VER)
+#pragma once
+#endif
+
+#include <ostream>
+#include <istream>
+#include <boost/mpl/identity.hpp>
+
+#if defined(BOOST_MSVC)
+# pragma warning(push)
+# pragma warning(disable: 4522) // multiple assignment operators specified warning
+#endif
+
+///////////////////////////////////////////////////////////////////////////////
+namespace boost { namespace spirit { namespace x3
+{
+ struct unused_type
+ {
+ unused_type()
+ {
+ }
+
+ template <typename T>
+ unused_type(T const&)
+ {
+ }
+
+ template <typename T>
+ unused_type const&
+ operator=(T const&) const
+ {
+ return *this;
+ }
+
+ template <typename T>
+ unused_type&
+ operator=(T const&)
+ {
+ return *this;
+ }
+
+ unused_type const&
+ operator=(unused_type const&) const
+ {
+ return *this;
+ }
+
+ unused_type&
+ operator=(unused_type const&)
+ {
+ return *this;
+ }
+
+ // unused_type can also masquerade as an empty context (see context.hpp)
+
+ template <typename ID>
+ struct get_result : mpl::identity<unused_type> {};
+
+ template <typename ID>
+ unused_type get(ID) const
+ {
+ return unused_type();
+ }
+ };
+
+ unused_type const unused = unused_type();
+
+ inline std::ostream& operator<<(std::ostream& out, unused_type const&)
+ {
+ return out;
+ }
+
+ inline std::istream& operator>>(std::istream& in, unused_type&)
+ {
+ return in;
+ }
+}}}
+
+#if defined(BOOST_MSVC)
+# pragma warning(pop)
+#endif
+
+#endif
diff --git a/boost/spirit/home/x3/support/utility/detail/testing.hpp b/boost/spirit/home/x3/support/utility/detail/testing.hpp
new file mode 100644
index 0000000000..1423d9fc7b
--- /dev/null
+++ b/boost/spirit/home/x3/support/utility/detail/testing.hpp
@@ -0,0 +1,16 @@
+/*=============================================================================
+ Copyright (c) 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(BOOST_SPIRIT_X3_DETAIL_TESTING_JUNE_05_2014_00422PM)
+#define BOOST_SPIRIT_X3_DETAIL_TESTING_JUNE_05_2014_00422PM
+
+namespace boost { namespace spirit { namespace x3 { namespace testing
+{
+
+
+}}}}
+
+#endif
diff --git a/boost/spirit/home/x3/support/utility/error_reporting.hpp b/boost/spirit/home/x3/support/utility/error_reporting.hpp
new file mode 100644
index 0000000000..9e65f2149b
--- /dev/null
+++ b/boost/spirit/home/x3/support/utility/error_reporting.hpp
@@ -0,0 +1,241 @@
+/*=============================================================================
+ Copyright (c) 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(BOOST_SPIRIT_X3_ERROR_REPORTING_MAY_19_2014_00405PM)
+#define BOOST_SPIRIT_X3_ERROR_REPORTING_MAY_19_2014_00405PM
+
+#include <boost/filesystem/path.hpp>
+#include <boost/spirit/home/x3/support/ast/position_tagged.hpp>
+#include <ostream>
+
+// Clang-style error handling utilities
+
+namespace boost { namespace spirit { namespace x3
+{
+ template <typename Iterator>
+ class error_handler
+ {
+ public:
+
+ typedef Iterator iterator_type;
+
+ error_handler(
+ Iterator first, Iterator last, std::ostream& err_out
+ , std::string file = "", int tabs = 4)
+ : err_out(err_out)
+ , file(file)
+ , tabs(tabs)
+ , pos_cache(first, last) {}
+
+ typedef void result_type;
+
+ void operator()(Iterator err_pos, std::string const& error_message) const;
+ void operator()(Iterator err_first, Iterator err_last, std::string const& error_message) const;
+ void operator()(position_tagged pos, std::string const& message) const
+ {
+ auto where = pos_cache.position_of(pos);
+ (*this)(
+ where.begin()
+ , where.end()
+ , message
+ );
+ }
+
+ template <typename AST>
+ void tag(AST& ast, Iterator first, Iterator last)
+ {
+ return pos_cache.annotate(ast, first, last);
+ }
+//
+// void operator()(
+// Iterator first
+// , Iterator last
+// , Iterator err_op
+// , Iterator err_first
+// , Iterator err_last
+// , std::string const& error_message
+// ) const;
+
+ private:
+
+ void print_file_line(std::size_t line) const;
+ void print_line(Iterator& line_start, Iterator last) const;
+ void print_indicator(Iterator& line_start, Iterator last, char ind) const;
+ void skip_whitespace(Iterator& err_pos, Iterator last) const;
+ void skip_non_whitespace(Iterator& err_pos, Iterator last) const;
+ Iterator get_line_start(Iterator first, Iterator pos) const;
+ std::size_t position(Iterator i) const;
+
+ std::ostream& err_out;
+ std::string file;
+ int tabs;
+ position_cache<std::vector<Iterator>> pos_cache;
+ };
+
+ template <typename Iterator>
+ void error_handler<Iterator>::print_file_line(std::size_t line) const
+ {
+ namespace fs = boost::filesystem;
+
+ if (file != "")
+ err_out << "In file " << fs::path(file).generic_string() << ", ";
+ else
+ err_out << "In ";
+
+ err_out << "line " << line << ':' << std::endl;
+ }
+
+ template <typename Iterator>
+ void error_handler<Iterator>::print_line(Iterator& start, Iterator last) const
+ {
+ for (; start != last; ++start)
+ {
+ auto c = *start;
+ if (c == '\r' || c == '\n')
+ break;
+ else
+ err_out << c;
+ }
+ err_out << std::endl;
+ }
+
+ template <typename Iterator>
+ void error_handler<Iterator>::print_indicator(Iterator& start, Iterator last, char ind) const
+ {
+ for (; start != last; ++start)
+ {
+ auto c = *start;
+ if (c == '\r' || c == '\n')
+ break;
+ else if (c == '\t')
+ for (int i = 0; i < tabs; ++i)
+ err_out << ind;
+ else
+ err_out << ind;
+ }
+ }
+
+ template <typename Iterator>
+ void error_handler<Iterator>::skip_whitespace(Iterator& err_pos, Iterator last) const
+ {
+ // make sure err_pos does not point to white space
+ while (err_pos != last)
+ {
+ char c = *err_pos;
+ if (std::isspace(c))
+ ++err_pos;
+ else
+ break;
+ }
+ }
+
+ template <typename Iterator>
+ void error_handler<Iterator>::skip_non_whitespace(Iterator& err_pos, Iterator last) const
+ {
+ // make sure err_pos does not point to white space
+ while (err_pos != last)
+ {
+ char c = *err_pos;
+ if (std::isspace(c))
+ break;
+ else
+ ++err_pos;
+ }
+ }
+
+ template <class Iterator>
+ inline Iterator error_handler<Iterator>::get_line_start(Iterator first, Iterator pos) const
+ {
+ Iterator latest = first;
+ for (Iterator i = first; i != pos; ++i)
+ if (*i == '\r' || *i == '\n')
+ latest = i;
+ return latest;
+ }
+
+ template <typename Iterator>
+ std::size_t error_handler<Iterator>::position(Iterator i) const
+ {
+ // $$$ asumes iterator is similar to line_pos_iterator $$$
+ return i.position();
+ }
+
+ template <typename Iterator>
+ void error_handler<Iterator>::operator()(
+ Iterator err_pos, std::string const& error_message) const
+ {
+ Iterator first = pos_cache.first();
+ Iterator last = pos_cache.last();
+
+ // make sure err_pos does not point to white space
+ skip_whitespace(err_pos, last);
+
+ print_file_line(position(err_pos));
+ err_out << error_message << std::endl;
+
+ Iterator start = get_line_start(first, err_pos);
+ if (start != first)
+ ++start;
+ Iterator i = start;
+ print_line(i, last);
+ print_indicator(start, err_pos, '_');
+ err_out << "^_" << std::endl;
+ }
+
+ template <typename Iterator>
+ void error_handler<Iterator>::operator()(
+ Iterator err_first, Iterator err_last, std::string const& error_message) const
+ {
+ Iterator first = pos_cache.first();
+ Iterator last = pos_cache.last();
+
+ // make sure err_pos does not point to white space
+ skip_whitespace(err_first, last);
+
+ print_file_line(position(err_first));
+ err_out << error_message << std::endl;
+
+ Iterator start = get_line_start(first, err_first);
+ if (start != first)
+ ++start;
+ Iterator i = start;
+ print_line(i, last);
+ print_indicator(start, err_first, ' ');
+ print_indicator(start, err_last, '~');
+ err_out << " <<-- Here" << std::endl;
+ }
+//
+// template <typename Iterator>
+// void error_handler<Iterator>::operator()(
+// Iterator first
+// , Iterator last
+// , Iterator err_op
+// , Iterator err_first
+// , Iterator err_last
+// , std::string const& error_message
+// ) const
+// {
+// // make sure err_pos does not point to white space
+// skip_whitespace(err_first, last);
+//
+// print_file_line(position(err_pos));
+// err_out << error_message << std::endl;
+//
+// Iterator start = get_line_start(first, err_first);
+// if (start != first)
+// ++start;
+// Iterator i = start;
+// print_line(i, last);
+// print_indicator(start, err_first, ' ');
+// print_indicator(start, err_op, '~');
+// err_out << '^';
+// print_indicator(++start, err_last, '~');
+// err_out << " <<-- Here" << std::endl;
+// }
+
+}}}
+
+#endif
diff --git a/boost/spirit/home/x3/support/utility/integer_sequence.hpp b/boost/spirit/home/x3/support/utility/integer_sequence.hpp
new file mode 100644
index 0000000000..1f0bace72b
--- /dev/null
+++ b/boost/spirit/home/x3/support/utility/integer_sequence.hpp
@@ -0,0 +1,94 @@
+/*//////////////////////////////////////////////////////////////////////////////
+ Copyright (c) 2014 Jamboree
+
+ 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)
+//////////////////////////////////////////////////////////////////////////////*/
+#ifndef BOOST_SPIRIT_X3_INTEGER_SEQUENCE_HPP_INCLUDED
+#define BOOST_SPIRIT_X3_INTEGER_SEQUENCE_HPP_INCLUDED
+
+#if defined(_MSC_VER)
+#pragma once
+#endif
+
+#include <cstddef>
+#include <boost/type_traits/integral_constant.hpp>
+
+// This is a standard (c++1y) compatible integer_sequence implementation,
+// it's needed for now, and it could be replaced with std::integer_sequence
+// once the new standard is available everywhere.
+
+namespace boost { namespace spirit { namespace x3
+{
+ template <typename T, T... Ns>
+ struct integer_sequence
+ {
+ typedef T value_type;
+
+ static constexpr std::size_t size() noexcept
+ {
+ return sizeof...(Ns);
+ }
+ };
+}}}
+
+namespace boost { namespace spirit { namespace x3 { namespace detail
+{
+ template <typename T, typename S1, typename S2, T N>
+ struct accum_integer_sequence;
+
+ template <typename T, T... N1, T... N2, T N>
+ struct accum_integer_sequence<T, integer_sequence<T, N1...>, integer_sequence<T, N2...>, N>
+ {
+ typedef integer_sequence<T, N1..., (N + N2)...> type;
+ };
+
+ template <typename N>
+ struct make_integer_sequence_impl
+ {
+ typedef typename N::value_type T;
+ static T const n = N::value;
+ static T const m = n / 2;
+ typedef typename
+ make_integer_sequence_impl<integral_constant<T, m>>::type
+ part1;
+ typedef typename
+ make_integer_sequence_impl<integral_constant<T, n - m>>::type
+ part2;
+ typedef typename
+ accum_integer_sequence<T, part1, part2, m>::type
+ type;
+ };
+
+ template <typename T>
+ struct make_integer_sequence_impl<integral_constant<T, 0>>
+ {
+ typedef integer_sequence<T> type;
+ };
+
+ template <typename T>
+ struct make_integer_sequence_impl<integral_constant<T, 1>>
+ {
+ typedef integer_sequence<T, 0> type;
+ };
+}}}}
+
+namespace boost { namespace spirit { namespace x3
+{
+ template <std::size_t... Ns>
+ using index_sequence = integer_sequence<std::size_t, Ns...>;
+
+ template <typename T, T N>
+ using make_integer_sequence = typename detail::make_integer_sequence_impl<
+ integral_constant<T, N>>::type;
+
+ template <std::size_t N>
+ using make_index_sequence = make_integer_sequence<std::size_t, N>;
+
+ template <typename... T>
+ using index_sequence_for = make_index_sequence<sizeof...(T)>;
+}}}
+
+
+#endif
+
diff --git a/boost/spirit/home/x3/support/utility/is_callable.hpp b/boost/spirit/home/x3/support/utility/is_callable.hpp
new file mode 100644
index 0000000000..17f86822b8
--- /dev/null
+++ b/boost/spirit/home/x3/support/utility/is_callable.hpp
@@ -0,0 +1,45 @@
+/*//////////////////////////////////////////////////////////////////////////////
+ Copyright (c) 2014 Jamboree
+
+ 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)
+//////////////////////////////////////////////////////////////////////////////*/
+#ifndef BOOST_SPIRIT_X3_IS_CALLABLE_HPP_INCLUDED
+#define BOOST_SPIRIT_X3_IS_CALLABLE_HPP_INCLUDED
+
+#if defined(_MSC_VER)
+#pragma once
+#endif
+
+#include <boost/utility/result_of.hpp>
+#include <boost/mpl/bool.hpp>
+#include <boost/spirit/home/x3/support/utility/sfinae.hpp>
+
+
+namespace boost { namespace spirit { namespace x3 { namespace detail
+{
+ template <typename Sig, typename Enable = void>
+ struct is_callable_impl
+ : mpl::false_
+ {};
+
+ template <typename F, typename... A>
+ struct is_callable_impl<F(A...), typename disable_if_substitution_failure<
+ typename result_of<F(A...)>::type>::type>
+ : mpl::true_
+ {};
+}}}}
+
+namespace boost { namespace spirit { namespace x3
+{
+ template <typename Sig>
+ struct is_callable;
+
+ template <typename F, typename... A>
+ struct is_callable<F(A...)>
+ : detail::is_callable_impl<F(A...)>
+ {};
+}}}
+
+
+#endif
diff --git a/boost/spirit/home/x3/support/utility/lambda_visitor.hpp b/boost/spirit/home/x3/support/utility/lambda_visitor.hpp
new file mode 100644
index 0000000000..83e1d2f046
--- /dev/null
+++ b/boost/spirit/home/x3/support/utility/lambda_visitor.hpp
@@ -0,0 +1,49 @@
+/*=============================================================================
+ Copyright (c) 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(BOOST_SPIRIT_X3_LAMBDA_VISITOR_MAY_19_2014_1116AM)
+#define BOOST_SPIRIT_X3_LAMBDA_VISITOR_MAY_19_2014_1116AM
+
+namespace boost { namespace spirit { namespace x3
+{
+ template <typename RT, typename... Lambdas>
+ struct lambda_visitor;
+
+ template <typename RT, typename F, typename... Lambdas>
+ struct lambda_visitor<RT, F, Lambdas...> : F, lambda_visitor<RT, Lambdas...>
+ {
+ typedef lambda_visitor<RT , Lambdas...> base_type;
+ using F::operator();
+ using base_type::operator();
+ lambda_visitor(F f, Lambdas... lambdas)
+ : F(f), base_type(lambdas...)
+ {}
+ };
+
+ template <typename RT, typename F>
+ struct lambda_visitor<RT, F> : F
+ {
+ typedef RT result_type;
+ using F::operator();
+ lambda_visitor(F f)
+ : F(f)
+ {}
+ };
+
+ template <typename RT>
+ struct lambda_visitor<RT>
+ {
+ typedef RT result_type;
+ };
+
+ template <typename RT, typename... Lambdas>
+ lambda_visitor<RT, Lambdas...> make_lambda_visitor(Lambdas... lambdas)
+ {
+ return { lambdas... };
+ }
+}}}
+
+#endif
diff --git a/boost/spirit/home/x3/support/utility/sfinae.hpp b/boost/spirit/home/x3/support/utility/sfinae.hpp
new file mode 100644
index 0000000000..6cefa95961
--- /dev/null
+++ b/boost/spirit/home/x3/support/utility/sfinae.hpp
@@ -0,0 +1,29 @@
+/*=============================================================================
+ Copyright (c) 2001-2014 Joel de Guzman
+ Copyright (c) 2013 Agustin Berge
+
+ 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(BOOST_SPIRIT_X3_SFINAE_MAY_20_2013_0840AM)
+#define BOOST_SPIRIT_X3_SFINAE_MAY_20_2013_0840AM
+
+#if defined(_MSC_VER)
+#pragma once
+#endif
+
+namespace boost { namespace spirit { namespace x3
+{
+ template <typename Expr, typename T = void>
+ struct disable_if_substitution_failure
+ {
+ typedef T type;
+ };
+ template <typename Expr, typename T>
+ struct lazy_disable_if_substitution_failure
+ {
+ typedef typename T::type type;
+ };
+}}}
+
+#endif
diff --git a/boost/spirit/home/x3/support/utility/testing.hpp b/boost/spirit/home/x3/support/utility/testing.hpp
new file mode 100644
index 0000000000..fced46bef8
--- /dev/null
+++ b/boost/spirit/home/x3/support/utility/testing.hpp
@@ -0,0 +1,69 @@
+/*=============================================================================
+ Copyright (c) 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(BOOST_SPIRIT_X3_TESTING_JUNE_05_2014_00422PM)
+#define BOOST_SPIRIT_X3_TESTING_JUNE_05_2014_00422PM
+
+namespace boost { namespace spirit { namespace x3 { namespace testing
+{
+ ////////////////////////////////////////////////////////////////////////////
+ //
+ // Test utility
+ //
+ // The test function accepts a file loaded in memory. The 'test_file'
+ // range param points to the data contained in the file. This file
+ // contains two parts.
+ //
+ // 1) The source input for testing
+ // 2) The expected result.
+ //
+ // The first part of the file is sent to the generator function
+ // 'gen' which returns a string. This generated string is then compared
+ // to the contents of the second (expected result) part.
+ //
+ // The second part is demarcated by the string parameter 'demarcation'
+ // which defaults to "<**expected**>". The expected template may include
+ // embedded regular expressions marked-up within re_prefix and re_suffix
+ // parameter tags. For example, given the default RE markup ("<%" and
+ // "%>"), this template:
+ //
+ // <%[0-9]+%>
+ //
+ // will match any integer in the source input being tested. The function
+ // will return the first non-matching position. The flag full_match
+ // indicates a full match. It is possible for returned pos to be
+ // at the end of in (in.end()) while still returning full_match ==
+ // false. In that case, we have a partial match.
+ //
+ // Here's an example of a test file:
+ //
+ // Hello World, I am Joel. This is a test.
+ //
+ // <**expected**>
+ // Hello World, I am <%[a-zA-Z]+%>. This is a test.
+ //
+ ////////////////////////////////////////////////////////////////////////////
+
+ template <typename Iterator>
+ struct test_result
+ {
+ Iterator pos;
+ bool full_match;
+ };
+
+ template <typename Range, typename F>
+ test_result<typename Range::const_iterator>
+ test(
+ Range test_file
+ , F gen
+ , char const* demarcation = "<**expected**>"
+ , char const* re_prefix = "<%"
+ , char const* re_suffix = "%>"
+ );
+
+}}}}
+
+#endif
diff --git a/boost/spirit/home/x3/support/utility/unrefcv.hpp b/boost/spirit/home/x3/support/utility/unrefcv.hpp
new file mode 100644
index 0000000000..fa4d448178
--- /dev/null
+++ b/boost/spirit/home/x3/support/utility/unrefcv.hpp
@@ -0,0 +1,29 @@
+/*//////////////////////////////////////////////////////////////////////////////
+ Copyright (c) 2014 Jamboree
+
+ 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)
+//////////////////////////////////////////////////////////////////////////////*/
+#ifndef BOOST_SPIRIT_X3_UNREFCV_HPP_INCLUDED
+#define BOOST_SPIRIT_X3_UNREFCV_HPP_INCLUDED
+
+#if defined(_MSC_VER)
+#pragma once
+#endif
+
+#include <boost/type_traits/remove_cv.hpp>
+#include <boost/type_traits/remove_reference.hpp>
+
+
+namespace boost { namespace spirit { namespace x3
+{
+ template <typename T>
+ struct unrefcv : remove_cv<typename remove_reference<T>::type> {};
+
+ template <typename T>
+ using unrefcv_t = typename unrefcv<T>::type;
+}}}
+
+
+#endif
+
diff --git a/boost/spirit/home/x3/support/utility/utf8.hpp b/boost/spirit/home/x3/support/utility/utf8.hpp
new file mode 100644
index 0000000000..93b5a22077
--- /dev/null
+++ b/boost/spirit/home/x3/support/utility/utf8.hpp
@@ -0,0 +1,72 @@
+/*=============================================================================
+ 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(BOOST_SPIRIT_X3_UC_TYPES_NOVEMBER_23_2008_0840PM)
+#define BOOST_SPIRIT_X3_UC_TYPES_NOVEMBER_23_2008_0840PM
+
+#if defined(_MSC_VER)
+#pragma once
+#endif
+
+#include <boost/cstdint.hpp>
+#include <boost/foreach.hpp>
+#include <boost/regex/pending/unicode_iterator.hpp>
+#include <boost/type_traits/make_unsigned.hpp>
+#include <string>
+
+namespace boost { namespace spirit { namespace x3
+{
+ typedef ::boost::uint32_t ucs4_char;
+ typedef char utf8_char;
+ typedef std::basic_string<ucs4_char> ucs4_string;
+ typedef std::basic_string<utf8_char> utf8_string;
+
+ template <typename Char>
+ inline utf8_string to_utf8(Char value)
+ {
+ // always store as UTF8
+ utf8_string result;
+ typedef std::back_insert_iterator<utf8_string> insert_iter;
+ insert_iter out_iter(result);
+ utf8_output_iterator<insert_iter> utf8_iter(out_iter);
+ typedef typename make_unsigned<Char>::type UChar;
+ *utf8_iter = (UChar)value;
+ return result;
+ }
+
+ template <typename Char>
+ inline utf8_string to_utf8(Char const* str)
+ {
+ // always store as UTF8
+ utf8_string result;
+ typedef std::back_insert_iterator<utf8_string> insert_iter;
+ insert_iter out_iter(result);
+ utf8_output_iterator<insert_iter> utf8_iter(out_iter);
+ typedef typename make_unsigned<Char>::type UChar;
+ while (*str)
+ *utf8_iter++ = (UChar)*str++;
+ return result;
+ }
+
+ template <typename Char, typename Traits, typename Allocator>
+ inline utf8_string
+ to_utf8(std::basic_string<Char, Traits, Allocator> const& str)
+ {
+ // always store as UTF8
+ utf8_string result;
+ typedef std::back_insert_iterator<utf8_string> insert_iter;
+ insert_iter out_iter(result);
+ utf8_output_iterator<insert_iter> utf8_iter(out_iter);
+ typedef typename make_unsigned<Char>::type UChar;
+ BOOST_FOREACH(Char ch, str)
+ {
+ *utf8_iter++ = (UChar)ch;
+ }
+ return result;
+ }
+}}}
+
+#endif