summaryrefslogtreecommitdiffstats
path: root/src/boost/libs/spirit/test/x3
diff options
context:
space:
mode:
Diffstat (limited to 'src/boost/libs/spirit/test/x3')
-rw-r--r--src/boost/libs/spirit/test/x3/Jamfile134
-rw-r--r--src/boost/libs/spirit/test/x3/actions.cpp108
-rw-r--r--src/boost/libs/spirit/test/x3/alternative.cpp253
-rw-r--r--src/boost/libs/spirit/test/x3/and_predicate.cpp25
-rw-r--r--src/boost/libs/spirit/test/x3/any_parser.cpp159
-rw-r--r--src/boost/libs/spirit/test/x3/attr.cpp53
-rw-r--r--src/boost/libs/spirit/test/x3/attribute_type_check.cpp113
-rw-r--r--src/boost/libs/spirit/test/x3/binary.cpp155
-rw-r--r--src/boost/libs/spirit/test/x3/bool.cpp83
-rw-r--r--src/boost/libs/spirit/test/x3/bool.hpp41
-rw-r--r--src/boost/libs/spirit/test/x3/char1.cpp198
-rw-r--r--src/boost/libs/spirit/test/x3/char_class.cpp248
-rw-r--r--src/boost/libs/spirit/test/x3/confix.cpp84
-rw-r--r--src/boost/libs/spirit/test/x3/container_support.cpp248
-rw-r--r--src/boost/libs/spirit/test/x3/debug.cpp144
-rw-r--r--src/boost/libs/spirit/test/x3/difference.cpp66
-rw-r--r--src/boost/libs/spirit/test/x3/eoi.cpp29
-rw-r--r--src/boost/libs/spirit/test/x3/eol.cpp32
-rw-r--r--src/boost/libs/spirit/test/x3/eps.cpp44
-rw-r--r--src/boost/libs/spirit/test/x3/error_handler.cpp57
-rw-r--r--src/boost/libs/spirit/test/x3/expect.cpp147
-rw-r--r--src/boost/libs/spirit/test/x3/extract_int.cpp162
-rw-r--r--src/boost/libs/spirit/test/x3/fusion_map.cpp138
-rw-r--r--src/boost/libs/spirit/test/x3/grammar.cpp6
-rw-r--r--src/boost/libs/spirit/test/x3/grammar.hpp7
-rw-r--r--src/boost/libs/spirit/test/x3/grammar_linker.cpp24
-rw-r--r--src/boost/libs/spirit/test/x3/int.hpp61
-rw-r--r--src/boost/libs/spirit/test/x3/int1.cpp186
-rw-r--r--src/boost/libs/spirit/test/x3/iterator_check.cpp49
-rw-r--r--src/boost/libs/spirit/test/x3/kleene.cpp126
-rw-r--r--src/boost/libs/spirit/test/x3/lexeme.cpp42
-rw-r--r--src/boost/libs/spirit/test/x3/list.cpp109
-rw-r--r--src/boost/libs/spirit/test/x3/lit.cpp53
-rw-r--r--src/boost/libs/spirit/test/x3/lit1.cpp85
-rw-r--r--src/boost/libs/spirit/test/x3/lit2.cpp52
-rw-r--r--src/boost/libs/spirit/test/x3/matches.cpp37
-rw-r--r--src/boost/libs/spirit/test/x3/no_case.cpp148
-rw-r--r--src/boost/libs/spirit/test/x3/no_skip.cpp50
-rw-r--r--src/boost/libs/spirit/test/x3/not_predicate.cpp26
-rw-r--r--src/boost/libs/spirit/test/x3/omit.cpp114
-rw-r--r--src/boost/libs/spirit/test/x3/optional.cpp113
-rw-r--r--src/boost/libs/spirit/test/x3/optional_ast_node.cpp66
-rw-r--r--src/boost/libs/spirit/test/x3/plus.cpp140
-rw-r--r--src/boost/libs/spirit/test/x3/raw.cpp97
-rw-r--r--src/boost/libs/spirit/test/x3/real.hpp122
-rw-r--r--src/boost/libs/spirit/test/x3/real1.cpp119
-rw-r--r--src/boost/libs/spirit/test/x3/real2.cpp132
-rw-r--r--src/boost/libs/spirit/test/x3/real3.cpp85
-rw-r--r--src/boost/libs/spirit/test/x3/real4.cpp73
-rw-r--r--src/boost/libs/spirit/test/x3/repeat.cpp152
-rw-r--r--src/boost/libs/spirit/test/x3/rule1.cpp129
-rw-r--r--src/boost/libs/spirit/test/x3/rule2.cpp108
-rw-r--r--src/boost/libs/spirit/test/x3/rule3.cpp109
-rw-r--r--src/boost/libs/spirit/test/x3/rule4.cpp164
-rw-r--r--src/boost/libs/spirit/test/x3/rule_separate_tu.cpp71
-rw-r--r--src/boost/libs/spirit/test/x3/rule_separate_tu_grammar.cpp42
-rw-r--r--src/boost/libs/spirit/test/x3/rule_separate_tu_grammar.hpp49
-rw-r--r--src/boost/libs/spirit/test/x3/seek.cpp95
-rw-r--r--src/boost/libs/spirit/test/x3/sequence.cpp503
-rw-r--r--src/boost/libs/spirit/test/x3/skip.cpp48
-rw-r--r--src/boost/libs/spirit/test/x3/symbols1.cpp187
-rw-r--r--src/boost/libs/spirit/test/x3/symbols2.cpp202
-rw-r--r--src/boost/libs/spirit/test/x3/symbols3.cpp86
-rw-r--r--src/boost/libs/spirit/test/x3/test.hpp125
-rw-r--r--src/boost/libs/spirit/test/x3/to_utf8.cpp28
-rw-r--r--src/boost/libs/spirit/test/x3/tst.cpp337
-rw-r--r--src/boost/libs/spirit/test/x3/uint.hpp59
-rw-r--r--src/boost/libs/spirit/test/x3/uint1.cpp211
-rw-r--r--src/boost/libs/spirit/test/x3/uint_radix.cpp740
-rw-r--r--src/boost/libs/spirit/test/x3/uint_radix.hpp142
-rw-r--r--src/boost/libs/spirit/test/x3/unused_type.cpp34
-rw-r--r--src/boost/libs/spirit/test/x3/utils.hpp48
-rw-r--r--src/boost/libs/spirit/test/x3/with.cpp114
-rw-r--r--src/boost/libs/spirit/test/x3/x3_variant.cpp57
74 files changed, 8683 insertions, 0 deletions
diff --git a/src/boost/libs/spirit/test/x3/Jamfile b/src/boost/libs/spirit/test/x3/Jamfile
new file mode 100644
index 00000000..875c06a3
--- /dev/null
+++ b/src/boost/libs/spirit/test/x3/Jamfile
@@ -0,0 +1,134 @@
+#==============================================================================
+# Copyright (c) 2001-2013 Joel de Guzman
+# Copyright (c) 2001-2012 Hartmut Kaiser
+# Copyright (c) 2011 Bryce Lelbach
+#
+# Use, modification and distribution is subject to 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)
+#==============================================================================
+
+import config : requires ;
+import modules ;
+import feature ;
+import testing ;
+
+###############################################################################
+
+project spirit-x3
+ : requirements
+ <include>.
+ <c++-template-depth>512
+ [ requires
+ # Assume all the cxx11 checks succeed if any of cxx14 does.
+ #cxx14_binary_literals # grep -Er "[0-9]+b[0-9]+" *
+ #cxx14_constexpr
+ cxx14_decltype_auto # grep -r "decltype(auto)" *
+ #cxx14_digit_separators # grep -Er "[0-9]+'[0-9]+" *
+ cxx14_generic_lambdas # grep -Er "]\s*\\([^\\)]*auto" *
+ #cxx14_hdr_shared_mutex # grep -r "shared_mutex" *
+ #cxx14_initialized_lambda_captures # grep -Er "\\[[^=\\]]+=" *
+ #cxx14_aggregate_nsdmi
+ cxx14_return_type_deduction # grep -Er "auto[^\\(=\\)]+\(" *
+ #cxx14_std_exchange # grep -r "exchange" *
+ cxx14_variable_templates
+ ]
+ ;
+
+###############################################################################
+
+local subproject-name = x3 ;
+
+rule run ( sources + : args * : input-files *
+ : requirements * : target-name ? : default-build * )
+{
+ target-name ?= $(subproject-name)_$(sources[1]:D=:S=) ;
+ return [ testing.run $(sources) : $(args) : $(input-files)
+ : $(requirements) : $(target-name) : $(default-build) ] ;
+}
+
+rule compile ( sources + : requirements * : target-name ? )
+{
+ target-name ?= $(subproject-name)_$(sources[1]:D=:S=) ;
+ return [ testing.compile $(sources)
+ : $(requirements) : $(target-name) ] ;
+}
+
+rule compile-fail ( sources + : requirements * : target-name ? )
+{
+ target-name ?= $(subproject-name)_$(sources[1]:D=:S=) ;
+ return [ testing.compile-fail $(sources)
+ : $(requirements) : $(target-name) ] ;
+}
+
+###############################################################################
+
+run actions.cpp ;
+run alternative.cpp ;
+run and_predicate.cpp ;
+run any_parser.cpp ;
+run attr.cpp ;
+run binary.cpp ;
+run bool.cpp ;
+run char1.cpp ;
+run char_class.cpp ;
+run container_support.cpp ;
+run debug.cpp ;
+run difference.cpp ;
+run eoi.cpp ;
+run eol.cpp ;
+run eps.cpp ;
+run expect.cpp ;
+run extract_int.cpp ;
+run int1.cpp ;
+run kleene.cpp ;
+run lexeme.cpp ;
+run lit1.cpp ;
+run lit2.cpp ;
+run list.cpp ;
+run matches.cpp ;
+run no_case.cpp ;
+run no_skip.cpp ;
+run not_predicate.cpp ;
+run omit.cpp ;
+run optional.cpp ;
+run plus.cpp ;
+run with.cpp ;
+
+run raw.cpp ;
+run real1.cpp ;
+run real2.cpp ;
+run real3.cpp ;
+run real4.cpp ;
+run rule1.cpp ;
+run rule2.cpp ;
+run rule3.cpp ;
+run rule4.cpp ;
+run sequence.cpp ;
+run skip.cpp ;
+run symbols1.cpp ;
+run symbols2.cpp ;
+run symbols3.cpp ;
+run tst.cpp ;
+
+run uint1.cpp ;
+run uint_radix.cpp ;
+
+run confix.cpp ;
+run repeat.cpp ;
+run seek.cpp ;
+
+run unused_type.cpp ;
+run attribute_type_check.cpp ;
+run fusion_map.cpp ;
+run x3_variant.cpp ;
+run error_handler.cpp /boost//filesystem ;
+run iterator_check.cpp ;
+
+run to_utf8.cpp ;
+
+obj rule_separate_tu_grammar : rule_separate_tu_grammar.cpp ;
+run rule_separate_tu.cpp rule_separate_tu_grammar ;
+
+obj grammar_linker : grammar.cpp ;
+run grammar_linker.cpp grammar_linker ;
diff --git a/src/boost/libs/spirit/test/x3/actions.cpp b/src/boost/libs/spirit/test/x3/actions.cpp
new file mode 100644
index 00000000..f033e27e
--- /dev/null
+++ b/src/boost/libs/spirit/test/x3/actions.cpp
@@ -0,0 +1,108 @@
+/*=============================================================================
+ Copyright (c) 2001-2015 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)
+=============================================================================*/
+#include <boost/detail/lightweight_test.hpp>
+#include <boost/spirit/home/x3.hpp>
+#include <cstring>
+#include <functional>
+
+#include "test.hpp"
+
+
+namespace x3 = boost::spirit::x3;
+
+int x = 0;
+
+auto fun1 =
+ [](auto& ctx)
+ {
+ x += x3::_attr(ctx);
+ }
+;
+
+struct fun_action
+{
+ template <typename Context>
+ void operator()(Context const& ctx) const
+ {
+ x += x3::_attr(ctx);
+ }
+};
+
+auto fail =
+ [](auto& ctx)
+ {
+ x3::_pass(ctx) = false;
+ }
+;
+
+struct setnext
+{
+ setnext(char& next) : next(next) {}
+
+ template <typename Context>
+ void operator()(Context const& ctx) const
+ {
+ next = x3::_attr(ctx);
+ }
+
+ char& next;
+};
+
+
+struct stationary : boost::noncopyable
+{
+ explicit stationary(int i) : val{i} {}
+ stationary& operator=(int i) { val = i; return *this; }
+
+ int val;
+};
+
+
+int main()
+{
+ using spirit_test::test;
+ using spirit_test::test_attr;
+
+ using x3::int_;
+
+ {
+ char const *s1 = "{42}", *e1 = s1 + std::strlen(s1);
+ x3::parse(s1, e1, '{' >> int_[fun1] >> '}');
+ }
+
+
+ {
+ char const *s1 = "{42}", *e1 = s1 + std::strlen(s1);
+ x3::parse(s1, e1, '{' >> int_[fun_action()] >> '}');
+ }
+
+ {
+ using namespace std::placeholders;
+ char const *s1 = "{42}", *e1 = s1 + std::strlen(s1);
+ x3::parse(s1, e1, '{' >> int_[std::bind(fun_action(), _1)] >> '}');
+ }
+
+ BOOST_TEST(x == (42*3));
+
+ {
+ std::string input("1234 6543");
+ char next = '\0';
+ BOOST_TEST(x3::phrase_parse(input.begin(), input.end(),
+ x3::int_[fail] | x3::digit[setnext(next)], x3::space));
+ BOOST_TEST(next == '1');
+ }
+
+ { // ensure no unneded synthesization, copying and moving occured
+ auto p = '{' >> int_ >> '}';
+
+ stationary st { 0 };
+ BOOST_TEST(test_attr("{42}", p[([]{})], st));
+ BOOST_TEST_EQ(st.val, 42);
+ }
+
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/spirit/test/x3/alternative.cpp b/src/boost/libs/spirit/test/x3/alternative.cpp
new file mode 100644
index 00000000..9162e943
--- /dev/null
+++ b/src/boost/libs/spirit/test/x3/alternative.cpp
@@ -0,0 +1,253 @@
+/*=============================================================================
+ Copyright (c) 2001-2015 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)
+=============================================================================*/
+#include <boost/detail/lightweight_test.hpp>
+#include <boost/spirit/home/x3.hpp>
+#include <boost/fusion/include/adapt_struct.hpp>
+#include <boost/variant.hpp>
+#include <boost/fusion/include/vector.hpp>
+#include <boost/fusion/include/at.hpp>
+
+#include <string>
+#include <iostream>
+#include <vector>
+#include "test.hpp"
+
+struct di_ignore
+{
+ std::string text;
+};
+
+struct di_include
+{
+ std::string FileName;
+};
+
+BOOST_FUSION_ADAPT_STRUCT(di_ignore,
+ text
+)
+
+BOOST_FUSION_ADAPT_STRUCT(di_include,
+ FileName
+)
+
+struct undefined {};
+
+
+struct stationary : boost::noncopyable
+{
+ explicit stationary(int i) : val{i} {}
+ // TODO: fix unneeded self move in alternative
+ stationary& operator=(stationary&&) { std::abort(); }
+ stationary& operator=(int i) { val = i; return *this; }
+
+ int val;
+};
+
+
+int
+main()
+{
+ using spirit_test::test;
+ using spirit_test::test_attr;
+
+ using boost::spirit::x3::attr;
+ using boost::spirit::x3::char_;
+ using boost::spirit::x3::int_;
+ using boost::spirit::x3::lit;
+ using boost::spirit::x3::unused_type;
+ using boost::spirit::x3::unused;
+ using boost::spirit::x3::omit;
+ using boost::spirit::x3::eps;
+
+
+ {
+ BOOST_TEST((test("a", char_ | char_)));
+ BOOST_TEST((test("x", lit('x') | lit('i'))));
+ BOOST_TEST((test("i", lit('x') | lit('i'))));
+ BOOST_TEST((!test("z", lit('x') | lit('o'))));
+ BOOST_TEST((test("rock", lit("rock") | lit("roll"))));
+ BOOST_TEST((test("roll", lit("rock") | lit("roll"))));
+ BOOST_TEST((test("rock", lit("rock") | int_)));
+ BOOST_TEST((test("12345", lit("rock") | int_)));
+ }
+
+ {
+ typedef boost::variant<undefined, int, char> attr_type;
+ attr_type v;
+
+ BOOST_TEST((test_attr("12345", int_ | char_, v)));
+ BOOST_TEST(boost::get<int>(v) == 12345);
+
+ BOOST_TEST((test_attr("12345", lit("rock") | int_ | char_, v)));
+ BOOST_TEST(boost::get<int>(v) == 12345);
+
+ v = attr_type();
+ BOOST_TEST((test_attr("rock", lit("rock") | int_ | char_, v)));
+ BOOST_TEST(v.which() == 0);
+
+ BOOST_TEST((test_attr("x", lit("rock") | int_ | char_, v)));
+ BOOST_TEST(boost::get<char>(v) == 'x');
+ }
+
+ { // Make sure that we are using the actual supplied attribute types
+ // from the variant and not the expected type.
+ boost::variant<int, std::string> v;
+ BOOST_TEST((test_attr("12345", int_ | +char_, v)));
+ BOOST_TEST(boost::get<int>(v) == 12345);
+
+ BOOST_TEST((test_attr("abc", int_ | +char_, v)));
+ BOOST_TEST(boost::get<std::string>(v) == "abc");
+
+ BOOST_TEST((test_attr("12345", +char_ | int_, v)));
+ BOOST_TEST(boost::get<std::string>(v) == "12345");
+ }
+
+ {
+ unused_type x;
+ BOOST_TEST((test_attr("rock", lit("rock") | lit('x'), x)));
+ }
+
+ {
+ // test if alternatives with all components having unused
+ // attributes have an unused attribute
+
+ using boost::fusion::vector;
+ using boost::fusion::at_c;
+
+ vector<char, char> v;
+ BOOST_TEST((test_attr("abc",
+ char_ >> (omit[char_] | omit[char_]) >> char_, v)));
+ BOOST_TEST((at_c<0>(v) == 'a'));
+ BOOST_TEST((at_c<1>(v) == 'c'));
+ }
+
+ {
+ // Test that we can still pass a "compatible" attribute to
+ // an alternate even if its "expected" attribute is unused type.
+
+ std::string s;
+ BOOST_TEST((test_attr("...", *(char_('.') | char_(',')), s)));
+ BOOST_TEST(s == "...");
+ }
+
+ { // make sure collapsing eps works as expected
+ // (compile check only)
+
+ using boost::spirit::x3::rule;
+ using boost::spirit::x3::eps;
+ using boost::spirit::x3::_attr;
+ using boost::spirit::x3::_val;
+
+ rule<class r1, wchar_t> r1;
+ rule<class r2, wchar_t> r2;
+ rule<class r3, wchar_t> r3;
+
+ auto f = [&](auto& ctx){ _val(ctx) = _attr(ctx); };
+
+ r3 = ((eps >> r1))[f];
+ r3 = ((r1) | r2)[f];
+ r3 = ((eps >> r1) | r2);
+ }
+
+ {
+ std::string s;
+ using boost::spirit::x3::eps;
+
+ // test having a variant<container, ...>
+ BOOST_TEST( (test_attr("a,b", (char_ % ',') | eps, s )) );
+ BOOST_TEST(s == "ab");
+ }
+
+ {
+ using boost::spirit::x3::eps;
+
+ // testing a sequence taking a container as attribute
+ std::string s;
+ BOOST_TEST( (test_attr("abc,a,b,c",
+ char_ >> char_ >> (char_ % ','), s )) );
+ BOOST_TEST(s == "abcabc");
+
+ // test having an optional<container> inside a sequence
+ s.erase();
+ BOOST_TEST( (test_attr("ab",
+ char_ >> char_ >> -(char_ % ','), s )) );
+ BOOST_TEST(s == "ab");
+
+ // test having a variant<container, ...> inside a sequence
+ s.erase();
+ BOOST_TEST( (test_attr("ab",
+ char_ >> char_ >> ((char_ % ',') | eps), s )) );
+ BOOST_TEST(s == "ab");
+ s.erase();
+ BOOST_TEST( (test_attr("abc",
+ char_ >> char_ >> ((char_ % ',') | eps), s )) );
+ BOOST_TEST(s == "abc");
+ }
+
+ {
+ //compile test only (bug_march_10_2011_8_35_am)
+ typedef boost::variant<double, std::string> value_type;
+
+ using boost::spirit::x3::rule;
+ using boost::spirit::x3::eps;
+
+ rule<class r1, value_type> r1;
+ auto r1_ = r1 = r1 | eps; // left recursive!
+
+ unused = r1_; // silence unused local warning
+ }
+
+ {
+ using boost::spirit::x3::rule;
+ typedef boost::variant<di_ignore, di_include> d_line;
+
+ rule<class ignore, di_ignore> ignore;
+ rule<class include, di_include> include;
+ rule<class line, d_line> line;
+
+ auto start =
+ line = include | ignore;
+
+ unused = start; // silence unused local warning
+ }
+
+ // single-element fusion vector tests
+ {
+ boost::fusion::vector<boost::variant<int, std::string>> fv;
+ BOOST_TEST((test_attr("12345", int_ | +char_, fv)));
+ BOOST_TEST(boost::get<int>(boost::fusion::at_c<0>(fv)) == 12345);
+
+ boost::fusion::vector<boost::variant<int, std::string>> fvi;
+ BOOST_TEST((test_attr("12345", int_ | int_, fvi)));
+ BOOST_TEST(boost::get<int>(boost::fusion::at_c<0>(fvi)) == 12345);
+ }
+
+ // alternative over single element sequences as part of another sequence
+ {
+ auto key1 = lit("long") >> attr(long());
+ auto key2 = lit("char") >> attr(char());
+ auto keys = key1 | key2;
+ auto pair = keys >> lit("=") >> +char_;
+
+ boost::fusion::deque<boost::variant<long, char>, std::string> attr_;
+
+ BOOST_TEST(test_attr("long=ABC", pair, attr_));
+ BOOST_TEST(boost::get<long>(&boost::fusion::front(attr_)) != nullptr);
+ BOOST_TEST(boost::get<char>(&boost::fusion::front(attr_)) == nullptr);
+ }
+
+ { // ensure no unneded synthesization, copying and moving occured
+ auto p = '{' >> int_ >> '}';
+
+ stationary st { 0 };
+ BOOST_TEST(test_attr("{42}", p | eps | p, st));
+ BOOST_TEST_EQ(st.val, 42);
+ }
+
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/spirit/test/x3/and_predicate.cpp b/src/boost/libs/spirit/test/x3/and_predicate.cpp
new file mode 100644
index 00000000..b2a44d10
--- /dev/null
+++ b/src/boost/libs/spirit/test/x3/and_predicate.cpp
@@ -0,0 +1,25 @@
+/*=============================================================================
+ Copyright (c) 2001-2015 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)
+=============================================================================*/
+#include <boost/detail/lightweight_test.hpp>
+#include <boost/spirit/home/x3.hpp>
+
+#include <iostream>
+#include "test.hpp"
+
+int
+main()
+{
+ using spirit_test::test;
+ using boost::spirit::x3::int_;
+
+ {
+ BOOST_TEST((test("1234", &int_, false)));
+ BOOST_TEST((!test("abcd", &int_)));
+ }
+
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/spirit/test/x3/any_parser.cpp b/src/boost/libs/spirit/test/x3/any_parser.cpp
new file mode 100644
index 00000000..9f46492f
--- /dev/null
+++ b/src/boost/libs/spirit/test/x3/any_parser.cpp
@@ -0,0 +1,159 @@
+/*=============================================================================
+ Copyright (c) 2001-2015 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)
+==============================================================================*/
+
+#include <boost/detail/lightweight_test.hpp>
+#include <boost/spirit/home/x3.hpp>
+
+#include <string>
+#include <cstring>
+#include <iostream>
+#include "test.hpp"
+
+int
+main()
+{
+ using spirit_test::test_attr;
+ using spirit_test::test;
+
+ using namespace boost::spirit::x3::ascii;
+ using boost::spirit::x3::any_parser;
+ using boost::spirit::x3::make_context;
+ using boost::spirit::x3::lit;
+ using boost::spirit::x3::unused_type;
+ using boost::spirit::x3::phrase_parse;
+ using boost::spirit::x3::skip_flag;
+ using boost::spirit::x3::skipper_tag;
+ using boost::spirit::x3::_attr;
+
+ typedef char const* iterator_type;
+ typedef decltype(make_context<skipper_tag>(space)) context_type;
+ { // basic tests
+
+ auto a = lit('a');
+ auto b = lit('b');
+ auto c = lit('c');
+
+ {
+ any_parser<iterator_type> start =
+ *(a | b | c);
+
+ BOOST_TEST(test("abcabcacb", start));
+ }
+ }
+
+ { // basic tests w/ skipper
+
+ auto a = lit('a');
+ auto b = lit('b');
+ auto c = lit('c');
+
+ {
+ any_parser<iterator_type, unused_type, context_type> start =
+ *(a | b | c);
+
+ BOOST_TEST(test(" a b c a b c a c b ", start, space));
+ }
+ }
+
+ { // basic tests w/ skipper but no final post-skip
+
+ any_parser<iterator_type, unused_type, context_type> a = lit('a');
+ any_parser<iterator_type, unused_type, context_type> b = lit('b');
+ any_parser<iterator_type, unused_type, context_type> c = lit('c');
+
+ {
+ any_parser<iterator_type, unused_type, context_type> start = *(a | b) >> c;
+
+ char const *s1 = " a b a a b b a c ... "
+ , *const e1 = s1 + std::strlen(s1);
+ BOOST_TEST(phrase_parse(s1, e1, start, space, skip_flag::dont_post_skip)
+ && s1 == e1 - 5);
+ }
+ }
+
+ { // context tests
+
+ char ch;
+ any_parser<iterator_type, char> a = alpha;
+
+ // this semantic action requires both the context and attribute
+ //!!auto f = [&](auto&, char attr){ ch = attr; };
+ //!!BOOST_TEST(test("x", a[f]));
+ //!!BOOST_TEST(ch == 'x');
+
+ // the semantic action may have the context passed
+ auto f2 = [&](auto&){ ch = 'y'; };
+ BOOST_TEST(test("x", a[f2]));
+ BOOST_TEST(ch == 'y');
+
+ // the semantic action may optionally not have any arguments at all
+ auto f3 = [&]{ ch = 'z'; };
+ BOOST_TEST(test("x", a[f3]));
+ BOOST_TEST(ch == 'z');
+
+ BOOST_TEST(test_attr("z", a, ch)); // attribute is given.
+ BOOST_TEST(ch == 'z');
+ }
+
+ { // auto rules tests
+
+ char ch = '\0';
+ any_parser<iterator_type, char> a = alpha;
+ auto f = [&](auto& ctx){ ch = _attr(ctx); };
+
+ BOOST_TEST(test("x", a[f]));
+ BOOST_TEST(ch == 'x');
+ ch = '\0';
+ BOOST_TEST(test_attr("z", a, ch)); // attribute is given.
+ BOOST_TEST(ch == 'z');
+
+ ch = '\0';
+ BOOST_TEST(test("x", a[f]));
+ BOOST_TEST(ch == 'x');
+ ch = '\0';
+ BOOST_TEST(test_attr("z", a, ch)); // attribute is given.
+ BOOST_TEST(ch == 'z');
+ }
+
+ { // auto rules tests: allow stl containers as attributes to
+ // sequences (in cases where attributes of the elements
+ // are convertible to the value_type of the container or if
+ // the element itself is an stl container with value_type
+ // that is convertible to the value_type of the attribute).
+
+ std::string s;
+ auto f = [&](auto& ctx){ s = _attr(ctx); };
+
+ {
+ any_parser<iterator_type, std::string> r
+ = char_ >> *(',' >> char_)
+ ;
+
+ BOOST_TEST(test("a,b,c,d,e,f", r[f]));
+ BOOST_TEST(s == "abcdef");
+ }
+
+ {
+ any_parser<iterator_type, std::string> r
+ = char_ >> *(',' >> char_);
+ s.clear();
+ BOOST_TEST(test("a,b,c,d,e,f", r[f]));
+ BOOST_TEST(s == "abcdef");
+ }
+
+ {
+ any_parser<iterator_type, std::string> r
+ = char_ >> char_ >> char_ >> char_ >> char_ >> char_;
+ s.clear();
+ BOOST_TEST(test("abcdef", r[f]));
+ BOOST_TEST(s == "abcdef");
+ }
+ }
+
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/spirit/test/x3/attr.cpp b/src/boost/libs/spirit/test/x3/attr.cpp
new file mode 100644
index 00000000..ead8d49f
--- /dev/null
+++ b/src/boost/libs/spirit/test/x3/attr.cpp
@@ -0,0 +1,53 @@
+/*=============================================================================
+ Copyright (c) 2001-2015 Joel de Guzman
+
+ Distributed under the Boost Software License, Version 1. (See accompanying
+ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+=============================================================================*/
+#include <boost/detail/lightweight_test.hpp>
+#include <boost/spirit/home/x3.hpp>
+
+#include <boost/fusion/include/std_pair.hpp>
+#include <vector>
+
+#include "test.hpp"
+
+int main()
+{
+ using spirit_test::test_attr;
+ using boost::spirit::x3::attr;
+ using boost::spirit::x3::int_;
+
+ {
+ int d = 0;
+ BOOST_TEST(test_attr("", attr(1), d) && d == 1);
+
+ int d1 = 1;
+ BOOST_TEST(test_attr("", attr(d1), d) && d == 1);
+
+ std::pair<int, int> p;
+ BOOST_TEST(test_attr("1", int_ >> attr(1), p) &&
+ p.first == 1 && p.second == 1);
+
+ char c = '\0';
+ BOOST_TEST(test_attr("", attr('a'), c) && c == 'a');
+
+ // $$$ Needs some special is_convertible support, or
+ // str ends up with an explicit null-terminator... $$$
+ //~ std::string str;
+ //~ BOOST_TEST(test_attr("", attr("test"), str) && str == "test");
+
+ int array[] = {0, 1, 2};
+ std::vector<int> vec;
+ BOOST_TEST(test_attr("", attr(array), vec) && vec.size() == 3 &&
+ vec[0] == 0 && vec[1] == 1 && vec[2] == 2);
+ }
+
+ {
+ std::string s;
+ BOOST_TEST(test_attr("s", "s" >> attr(std::string("123")), s) &&
+ s == "123");
+ }
+
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/spirit/test/x3/attribute_type_check.cpp b/src/boost/libs/spirit/test/x3/attribute_type_check.cpp
new file mode 100644
index 00000000..26f028a3
--- /dev/null
+++ b/src/boost/libs/spirit/test/x3/attribute_type_check.cpp
@@ -0,0 +1,113 @@
+#include <boost/detail/lightweight_test.hpp>
+#include <boost/spirit/home/x3.hpp>
+#include <boost/fusion/include/vector.hpp>
+#include <boost/fusion/include/make_vector.hpp>
+#include <boost/fusion/include/equal_to.hpp>
+#include <boost/type_traits/is_same.hpp>
+#include <boost/optional.hpp>
+#include <string>
+
+namespace x3 = boost::spirit::x3;
+
+// just an `attr` with added type checker
+template <typename Value, typename Expected>
+struct checked_attr_parser : x3::attr_parser<Value>
+{
+ using base_t = x3::attr_parser<Value>;
+
+ checked_attr_parser(Value const& value) : base_t(value) {}
+ checked_attr_parser(Value&& value) : base_t(std::move(value)) {}
+
+ template <typename Iterator, typename Context
+ , typename RuleContext, typename Attribute>
+ bool parse(Iterator& first, Iterator const& last
+ , Context const& ctx, RuleContext& rctx, Attribute& attr_) const
+ {
+ static_assert(boost::is_same<Expected, Attribute>::value,
+ "attribute type check failed");
+ return base_t::parse(first, last, ctx, rctx, attr_);
+ }
+};
+
+template <typename Expected, typename Value>
+static inline checked_attr_parser<boost::decay_t<Value>, Expected>
+checked_attr(Value&& value) { return { std::forward<Value>(value) }; }
+
+// instantiate our type checker
+// (checks attribute value just to be sure we are ok)
+template <typename Value, typename Expr>
+static void test_expr(Value const& v, Expr&& expr)
+{
+ char const* it = "";
+ Value r;
+ BOOST_TEST((x3::parse(it, it, std::forward<Expr>(expr), r)));
+ BOOST_TEST((r == v));
+}
+
+template <typename Expr, typename Attribute>
+static void gen_sequence(Attribute const& attribute, Expr&& expr)
+{
+ test_expr(attribute, expr);
+ test_expr(attribute, expr >> x3::eps);
+}
+
+template <typename Expected, typename... ExpectedTail, typename Attribute, typename Expr, typename Value, typename... Tail>
+static void gen_sequence(Attribute const& attribute, Expr&& expr, Value const& v, Tail const&... tail)
+{
+ gen_sequence<ExpectedTail...>(attribute, expr >> checked_attr<Expected>(v), tail...);
+ gen_sequence<ExpectedTail...>(attribute, expr >> x3::eps >> checked_attr<Expected>(v), tail...);
+ gen_sequence<ExpectedTail...>(attribute, expr >> (x3::eps >> checked_attr<Expected>(v)), tail...);
+}
+
+template <typename Expected, typename... ExpectedTail, typename Attribute, typename Value, typename... Tail>
+static void gen_sequence_tests(Attribute const& attribute, Value const& v, Tail const&... tail)
+{
+ gen_sequence<ExpectedTail...>(attribute, checked_attr<Expected>(v), tail...);
+ gen_sequence<ExpectedTail...>(attribute, x3::eps >> checked_attr<Expected>(v), tail...);
+}
+
+template <typename Expected, typename Value>
+static void gen_single_item_tests(Value const& v)
+{
+ Expected attribute(v);
+ gen_sequence(attribute, checked_attr<Expected>(v));
+ gen_sequence(attribute, x3::eps >> checked_attr<Expected>(v));
+}
+
+template <typename Expected, typename... ExpectedTail, typename Value, typename... Tail>
+static void gen_single_item_tests(Value const& v, Tail const&... tail)
+{
+ gen_single_item_tests<Expected>(v);
+ gen_single_item_tests<ExpectedTail...>(tail...);
+}
+
+template <typename... Expected, typename... Values>
+static void gen_tests(Values const&... values)
+{
+ gen_single_item_tests<Expected...>(values...);
+
+ boost::fusion::vector<Expected...> attribute = boost::fusion::make_vector(values...);
+ gen_sequence_tests<Expected...>(attribute, values...);
+}
+
+template <typename... Attributes>
+void make_test(Attributes const&... attrs)
+{
+ // I would like to place all of this in a single call
+ // but it requires tremendous amount of heap to compile
+ gen_tests<Attributes...>(attrs...);
+ gen_tests<
+ boost::optional<Attributes>...
+ , boost::fusion::vector<Attributes>...
+ >(attrs..., attrs...);
+ gen_tests<
+ boost::optional<boost::fusion::vector<Attributes>>...
+ , boost::fusion::vector<boost::optional<Attributes>>...
+ >(boost::fusion::vector<Attributes>(attrs)..., attrs...);
+}
+
+int main()
+{
+ make_test<int, std::string>(123, "hello");
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/spirit/test/x3/binary.cpp b/src/boost/libs/spirit/test/x3/binary.cpp
new file mode 100644
index 00000000..12878429
--- /dev/null
+++ b/src/boost/libs/spirit/test/x3/binary.cpp
@@ -0,0 +1,155 @@
+/*=============================================================================
+ 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)
+==============================================================================*/
+#include <boost/detail/lightweight_test.hpp>
+
+#include <boost/spirit/home/x3/binary.hpp>
+#include <boost/cstdint.hpp>
+#include <boost/predef/other/endian.h>
+#include "test.hpp"
+
+///////////////////////////////////////////////////////////////////////////////
+int main()
+{
+ using spirit_test::test_attr;
+ using spirit_test::test;
+ using spirit_test::binary_test;
+ using spirit_test::binary_test_attr;
+
+ using boost::spirit::x3::byte_;
+ using boost::spirit::x3::word;
+ using boost::spirit::x3::dword;
+ using boost::spirit::x3::big_word;
+ using boost::spirit::x3::big_dword;
+ using boost::spirit::x3::little_word;
+ using boost::spirit::x3::little_dword;
+#ifdef BOOST_HAS_LONG_LONG
+ using boost::spirit::x3::qword;
+ using boost::spirit::x3::big_qword;
+ using boost::spirit::x3::little_qword;
+#endif
+// using boost::spirit::x3::bin_float;
+// using boost::spirit::x3::big_bin_float;
+// using boost::spirit::x3::little_bin_float;
+// using boost::spirit::x3::bin_double;
+// using boost::spirit::x3::big_bin_double;
+// using boost::spirit::x3::little_bin_double;
+
+ boost::uint8_t uc;
+ boost::uint16_t us;
+ boost::uint32_t ui;
+#ifdef BOOST_HAS_LONG_LONG
+ boost::uint64_t ul;
+#endif
+// float f;
+// double d;
+
+ { // test native endian binaries
+#if BOOST_ENDIAN_LITTLE_BYTE
+ BOOST_TEST(test_attr("\x01", byte_, uc) && uc == 0x01);
+ BOOST_TEST(test_attr("\x01\x02", word, us) && us == 0x0201);
+ BOOST_TEST(test_attr("\x01\x02\x03\x04", dword, ui) && ui == 0x04030201);
+#ifdef BOOST_HAS_LONG_LONG
+ BOOST_TEST(test_attr("\x01\x02\x03\x04\x05\x06\x07\x08", qword, ul) &&
+ ul == 0x0807060504030201LL);
+#endif
+// BOOST_TEST(binary_test_attr("\x00\x00\x80\x3f", 4, bin_float, f) &&
+// f == 1.0f);
+// BOOST_TEST(binary_test_attr("\x00\x00\x00\x00\x00\x00\xf0\x3f",
+// 8, bin_double, d) && f == 1.0);
+#else
+ BOOST_TEST(test_attr("\x01", byte_, uc) && uc == 0x01);
+ BOOST_TEST(test_attr("\x01\x02", word, us) && us == 0x0102);
+ BOOST_TEST(test_attr("\x01\x02\x03\x04", dword, ui) && ui == 0x01020304);
+#ifdef BOOST_HAS_LONG_LONG
+ BOOST_TEST(test_attr("\x01\x02\x03\x04\x05\x06\x07\x08", qword, ul) &&
+ ul == 0x0102030405060708LL);
+#endif
+// BOOST_TEST(binary_test_attr("\x3f\x80\x00\x00", 4, bin_float, f) &&
+// f == 1.0f);
+// BOOST_TEST(binary_test_attr("\x3f\xf0\x00\x00\x00\x00\x00\x00",
+// 8, bin_double, d) && f == 1.0);
+#endif
+ }
+
+ { // test native endian binaries
+#if BOOST_ENDIAN_LITTLE_BYTE
+ BOOST_TEST(test("\x01", byte_(0x01)));
+ BOOST_TEST(test("\x01\x02", word(0x0201)));
+ BOOST_TEST(test("\x01\x02\x03\x04", dword(0x04030201)));
+#ifdef BOOST_HAS_LONG_LONG
+ BOOST_TEST(test("\x01\x02\x03\x04\x05\x06\x07\x08",
+ qword(0x0807060504030201LL)));
+#endif
+// BOOST_TEST(binary_test("\x00\x00\x80\x3f", 4, bin_float(1.0f)));
+// BOOST_TEST(binary_test("\x00\x00\x00\x00\x00\x00\xf0\x3f", 8,
+// bin_double(1.0)));
+#else
+ BOOST_TEST(test("\x01", byte_(0x01)));
+ BOOST_TEST(test("\x01\x02", word(0x0102)));
+ BOOST_TEST(test("\x01\x02\x03\x04", dword(0x01020304)));
+#ifdef BOOST_HAS_LONG_LONG
+ BOOST_TEST(test("\x01\x02\x03\x04\x05\x06\x07\x08",
+ qword(0x0102030405060708LL)));
+#endif
+// BOOST_TEST(binary_test("\x3f\x80\x00\x00", 4, bin_float(1.0f)));
+// BOOST_TEST(binary_test("\x3f\x80\x00\x00\x00\x00\x00\x00", 8,
+// bin_double(1.0)));
+#endif
+ }
+
+ { // test big endian binaries
+ BOOST_TEST(test_attr("\x01\x02", big_word, us) && us == 0x0102);
+ BOOST_TEST(test_attr("\x01\x02\x03\x04", big_dword, ui) && ui == 0x01020304);
+#ifdef BOOST_HAS_LONG_LONG
+ BOOST_TEST(test_attr("\x01\x02\x03\x04\x05\x06\x07\x08", big_qword, ul)
+ && ul == 0x0102030405060708LL);
+#endif
+// BOOST_TEST(binary_test_attr("\x3f\x80\x00\x00", 4, big_bin_float, f) &&
+// f == 1.0f);
+// BOOST_TEST(binary_test_attr("\x3f\xf0\x00\x00\x00\x00\x00\x00",
+// 8, big_bin_double, d) && f == 1.0);
+ }
+
+ {
+ BOOST_TEST(test("\x01\x02", big_word(0x0102)));
+ BOOST_TEST(test("\x01\x02\x03\x04", big_dword(0x01020304)));
+#ifdef BOOST_HAS_LONG_LONG
+ BOOST_TEST(test("\x01\x02\x03\x04\x05\x06\x07\x08",
+ big_qword(0x0102030405060708LL)));
+#endif
+// BOOST_TEST(binary_test("\x3f\x80\x00\x00", 4, big_bin_float(1.0f)));
+// BOOST_TEST(binary_test("\x3f\xf0\x00\x00\x00\x00\x00\x00", 8,
+// big_bin_double(1.0)));
+ }
+
+ { // test little endian binaries
+ BOOST_TEST(test_attr("\x01\x02", little_word, us) && us == 0x0201);
+ BOOST_TEST(test_attr("\x01\x02\x03\x04", little_dword, ui) && ui == 0x04030201);
+#ifdef BOOST_HAS_LONG_LONG
+ BOOST_TEST(test_attr("\x01\x02\x03\x04\x05\x06\x07\x08", little_qword, ul)
+ && ul == 0x0807060504030201LL);
+#endif
+// BOOST_TEST(binary_test_attr("\x00\x00\x80\x3f", 4,
+// little_bin_float, f) && f == 1.0f);
+// BOOST_TEST(binary_test_attr("\x00\x00\x00\x00\x00\x00\xf0\x3f",
+// 8, little_bin_double, d) && f == 1.0);
+ }
+
+ {
+ BOOST_TEST(test("\x01\x02", little_word(0x0201)));
+ BOOST_TEST(test("\x01\x02\x03\x04", little_dword(0x04030201)));
+#ifdef BOOST_HAS_LONG_LONG
+ BOOST_TEST(test("\x01\x02\x03\x04\x05\x06\x07\x08",
+ little_qword(0x0807060504030201LL)));
+#endif
+// BOOST_TEST(binary_test("\x00\x00\x80\x3f", 4, little_bin_float(1.0f)));
+// BOOST_TEST(binary_test("\x00\x00\x00\x00\x00\x00\xf0\x3f", 8,
+// little_bin_double(1.0)));
+ }
+
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/spirit/test/x3/bool.cpp b/src/boost/libs/spirit/test/x3/bool.cpp
new file mode 100644
index 00000000..61c357f8
--- /dev/null
+++ b/src/boost/libs/spirit/test/x3/bool.cpp
@@ -0,0 +1,83 @@
+/*=============================================================================
+ Copyright (c) 2001-2011 Hartmut Kaiser
+ Copyright (c) 2011 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)
+==============================================================================*/
+#include "bool.hpp"
+
+int main()
+{
+ using spirit_test::test_attr;
+ using spirit_test::test;
+ using boost::spirit::x3::bool_;
+
+ {
+ BOOST_TEST(test("true", bool_));
+ BOOST_TEST(test("false", bool_));
+ BOOST_TEST(!test("fasle", bool_));
+ }
+
+ {
+ using boost::spirit::x3::true_;
+ using boost::spirit::x3::false_;
+
+ BOOST_TEST(test("true", true_));
+ BOOST_TEST(!test("true", false_));
+ BOOST_TEST(test("false", false_));
+ BOOST_TEST(!test("false", true_));
+ }
+
+ {
+ using boost::spirit::x3::true_;
+ using boost::spirit::x3::false_;
+ using boost::spirit::x3::no_case;
+
+ BOOST_TEST(test("True", no_case[bool_]));
+ BOOST_TEST(test("False", no_case[bool_]));
+ BOOST_TEST(test("True", no_case[true_]));
+ BOOST_TEST(test("False", no_case[false_]));
+ }
+
+ {
+ bool b = false;
+ BOOST_TEST(test_attr("true", bool_, b) && b);
+ BOOST_TEST(test_attr("false", bool_, b) && !b);
+ BOOST_TEST(!test_attr("fasle", bool_, b));
+ }
+
+ {
+ typedef boost::spirit::x3::bool_parser<bool, boost::spirit::char_encoding::standard, backwards_bool_policies>
+ backwards_bool_type;
+ backwards_bool_type const backwards_bool = backwards_bool_type();
+
+ BOOST_TEST(test("true", backwards_bool));
+ BOOST_TEST(test("eurt", backwards_bool));
+ BOOST_TEST(!test("false", backwards_bool));
+ BOOST_TEST(!test("fasle", backwards_bool));
+
+ bool b = false;
+ BOOST_TEST(test_attr("true", backwards_bool, b) && b);
+ BOOST_TEST(test_attr("eurt", backwards_bool, b) && !b);
+ BOOST_TEST(!test_attr("false", backwards_bool, b));
+ BOOST_TEST(!test_attr("fasle", backwards_bool, b));
+ }
+
+ {
+ typedef boost::spirit::x3::bool_parser<test_bool_type, boost::spirit::char_encoding::standard>
+ bool_test_type;
+ bool_test_type const test_bool = bool_test_type();
+
+ BOOST_TEST(test("true", test_bool));
+ BOOST_TEST(test("false", test_bool));
+ BOOST_TEST(!test("fasle", test_bool));
+
+ test_bool_type b = false;
+ BOOST_TEST(test_attr("true", test_bool, b) && b.b);
+ BOOST_TEST(test_attr("false", test_bool, b) && !b.b);
+ BOOST_TEST(!test_attr("fasle", test_bool, b));
+ }
+
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/spirit/test/x3/bool.hpp b/src/boost/libs/spirit/test/x3/bool.hpp
new file mode 100644
index 00000000..f06b884c
--- /dev/null
+++ b/src/boost/libs/spirit/test/x3/bool.hpp
@@ -0,0 +1,41 @@
+/*=============================================================================
+ Copyright (c) 2001-2011 Hartmut Kaiser
+ Copyright (c) 2011 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_TEST_QI_BOOL)
+#define BOOST_SPIRIT_TEST_QI_BOOL
+
+#include <boost/detail/lightweight_test.hpp>
+#include <boost/spirit/home/x3.hpp>
+#include "test.hpp"
+
+///////////////////////////////////////////////////////////////////////////////
+struct backwards_bool_policies : boost::spirit::x3::bool_policies<>
+{
+ // we want to interpret a 'true' spelled backwards as 'false'
+ template <typename Iterator, typename Attribute, typename CaseCompare>
+ static bool
+ parse_false(Iterator& first, Iterator const& last, Attribute& attr, CaseCompare const& case_compare)
+ {
+ namespace spirit = boost::spirit;
+ namespace x3 = boost::spirit::x3;
+ if (x3::detail::string_parse("eurt", first, last, x3::unused, case_compare))
+ {
+ x3::traits::move_to(false, attr); // result is false
+ return true;
+ }
+ return false;
+ }
+};
+
+///////////////////////////////////////////////////////////////////////////////
+struct test_bool_type
+{
+ test_bool_type(bool b = false) : b(b) {} // provide conversion
+ bool b;
+};
+
+#endif
diff --git a/src/boost/libs/spirit/test/x3/char1.cpp b/src/boost/libs/spirit/test/x3/char1.cpp
new file mode 100644
index 00000000..b835e48d
--- /dev/null
+++ b/src/boost/libs/spirit/test/x3/char1.cpp
@@ -0,0 +1,198 @@
+/*=============================================================================
+ Copyright (c) 2001-2015 Joel de Guzman
+ Copyright (c) 2001-2011 Hartmut Kaiser
+ Copyright (c) 2019 Christian Mazakas
+
+ 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)
+=============================================================================*/
+
+#define BOOST_SPIRIT_X3_UNICODE
+
+#include <boost/detail/lightweight_test.hpp>
+#include <boost/spirit/home/x3.hpp>
+
+#include <boost/utility/string_view.hpp>
+
+#include <iostream>
+#include <vector>
+#include <algorithm>
+
+#include "test.hpp"
+
+int
+main()
+{
+ using spirit_test::test;
+
+ {
+ using namespace boost::spirit::x3::ascii;
+
+ BOOST_TEST(test("x", 'x'));
+ BOOST_TEST(test(L"x", L'x'));
+ BOOST_TEST(!test("y", 'x'));
+ BOOST_TEST(!test(L"y", L'x'));
+
+ BOOST_TEST(test("x", char_));
+ BOOST_TEST(test("x", char_('x')));
+ BOOST_TEST(!test("x", char_('y')));
+ BOOST_TEST(test("x", char_('a', 'z')));
+ BOOST_TEST(!test("x", char_('0', '9')));
+
+ BOOST_TEST(test("0", char_('0', '9')));
+ BOOST_TEST(test("9", char_('0', '9')));
+ BOOST_TEST(!test("0", ~char_('0', '9')));
+ BOOST_TEST(!test("9", ~char_('0', '9')));
+
+ BOOST_TEST(!test("x", ~char_));
+ BOOST_TEST(!test("x", ~char_('x')));
+ BOOST_TEST(test(" ", ~char_('x')));
+ BOOST_TEST(test("X", ~char_('x')));
+ BOOST_TEST(!test("x", ~char_('b', 'y')));
+ BOOST_TEST(test("a", ~char_('b', 'y')));
+ BOOST_TEST(test("z", ~char_('b', 'y')));
+
+ BOOST_TEST(test("x", ~~char_));
+ BOOST_TEST(test("x", ~~char_('x')));
+ BOOST_TEST(!test(" ", ~~char_('x')));
+ BOOST_TEST(!test("X", ~~char_('x')));
+ BOOST_TEST(test("x", ~~char_('b', 'y')));
+ BOOST_TEST(!test("a", ~~char_('b', 'y')));
+ BOOST_TEST(!test("z", ~~char_('b', 'y')));
+ }
+
+ {
+ using namespace boost::spirit::x3::ascii;
+
+ BOOST_TEST(test(" x", 'x', space));
+ BOOST_TEST(test(L" x", L'x', space));
+
+ BOOST_TEST(test(" x", char_, space));
+ BOOST_TEST(test(" x", char_('x'), space));
+ BOOST_TEST(!test(" x", char_('y'), space));
+ BOOST_TEST(test(" x", char_('a', 'z'), space));
+ BOOST_TEST(!test(" x", char_('0', '9'), space));
+ }
+
+ {
+ using namespace boost::spirit::x3::standard_wide;
+
+ BOOST_TEST(test(L"x", char_));
+ BOOST_TEST(test(L"x", char_(L'x')));
+ BOOST_TEST(!test(L"x", char_(L'y')));
+ BOOST_TEST(test(L"x", char_(L'a', L'z')));
+ BOOST_TEST(!test(L"x", char_(L'0', L'9')));
+
+ BOOST_TEST(!test(L"x", ~char_));
+ BOOST_TEST(!test(L"x", ~char_(L'x')));
+ BOOST_TEST(test(L" ", ~char_(L'x')));
+ BOOST_TEST(test(L"X", ~char_(L'x')));
+ BOOST_TEST(!test(L"x", ~char_(L'b', L'y')));
+ BOOST_TEST(test(L"a", ~char_(L'b', L'y')));
+ BOOST_TEST(test(L"z", ~char_(L'b', L'y')));
+
+ BOOST_TEST(test(L"x", ~~char_));
+ BOOST_TEST(test(L"x", ~~char_(L'x')));
+ BOOST_TEST(!test(L" ", ~~char_(L'x')));
+ BOOST_TEST(!test(L"X", ~~char_(L'x')));
+ BOOST_TEST(test(L"x", ~~char_(L'b', L'y')));
+ BOOST_TEST(!test(L"a", ~~char_(L'b', L'y')));
+ BOOST_TEST(!test(L"z", ~~char_(L'b', L'y')));
+ }
+
+ // unicode (normal ASCII)
+ {
+ using namespace boost::spirit::x3::unicode;
+
+ BOOST_TEST(test(U"abcd", +char_(U"abcd")));
+ BOOST_TEST(!test(U"abcd", +char_(U"qwer")));
+
+ auto const sub_delims = char_(U"!$&'()*+,;=");
+
+ auto const delims =
+ std::vector<boost::u32string_view>{U"!", U"$", U"&", U"'", U"(", U")", U"*", U"+",
+ U",", U";", U"="};
+
+ auto const matched_all_sub_delims =
+ std::all_of(delims.begin(), delims.end(), [&](auto const delim) -> bool {
+ return test(delim, sub_delims);
+ });
+
+ BOOST_TEST(matched_all_sub_delims);
+ }
+
+ // unicode (escaped Unicode char literals)
+ {
+ using namespace boost::spirit::x3::unicode;
+
+ auto const chars = char_(U"\u0024\u00a2\u0939\u20ac\U00010348");
+
+ auto const test_strings =
+ std::vector<boost::u32string_view>{U"\u0024", U"\u00a2", U"\u0939", U"\u20ac",
+ U"\U00010348"};
+
+ auto const bad_test_strings = std::vector<boost::u32string_view>{U"a", U"B", U"c", U"\u0409"};
+
+ auto const all_matched =
+ std::all_of(test_strings.begin(), test_strings.end(), [&](auto const test_str) -> bool {
+ return test(test_str, chars);
+ });
+
+ auto const none_matched =
+ std::all_of(bad_test_strings.begin(), bad_test_strings.end(), [&](auto const bad_test_str) -> bool {
+ return !test(bad_test_str, chars);
+ });
+
+ BOOST_TEST(all_matched);
+ BOOST_TEST(none_matched);
+ }
+
+
+ { // single char strings!
+ namespace ascii = boost::spirit::x3::ascii;
+ namespace wide = boost::spirit::x3::standard_wide;
+
+ BOOST_TEST(test("x", "x"));
+ BOOST_TEST(test(L"x", L"x"));
+ BOOST_TEST(test("x", ascii::char_("x")));
+ BOOST_TEST(test(L"x", wide::char_(L"x")));
+
+ BOOST_TEST(test("x", ascii::char_("a", "z")));
+ BOOST_TEST(test(L"x", wide::char_(L"a", L"z")));
+ }
+
+ {
+ // chsets
+ namespace ascii = boost::spirit::x3::ascii;
+ namespace wide = boost::spirit::x3::standard_wide;
+
+ BOOST_TEST(test("x", ascii::char_("a-z")));
+ BOOST_TEST(!test("1", ascii::char_("a-z")));
+ BOOST_TEST(test("1", ascii::char_("a-z0-9")));
+
+ BOOST_TEST(test("x", wide::char_(L"a-z")));
+ BOOST_TEST(!test("1", wide::char_(L"a-z")));
+ BOOST_TEST(test("1", wide::char_(L"a-z0-9")));
+
+ std::string set = "a-z0-9";
+ BOOST_TEST(test("x", ascii::char_(set)));
+
+#ifdef SPIRIT_NO_COMPILE_CHECK
+ test("", ascii::char_(L"a-z0-9"));
+#endif
+ }
+
+ {
+ namespace ascii = boost::spirit::x3::ascii;
+ char const* input = "\x80";
+
+ // ascii > 7 bits (this should fail, not assert!)
+ BOOST_TEST(!test(input, ascii::char_));
+ BOOST_TEST(!test(input, ascii::char_('a')));
+ BOOST_TEST(!test(input, ascii::alnum));
+ BOOST_TEST(!test(input, ascii::char_("a-z")));
+ BOOST_TEST(!test(input, ascii::char_('0', '9')));
+ }
+
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/spirit/test/x3/char_class.cpp b/src/boost/libs/spirit/test/x3/char_class.cpp
new file mode 100644
index 00000000..a151d5c8
--- /dev/null
+++ b/src/boost/libs/spirit/test/x3/char_class.cpp
@@ -0,0 +1,248 @@
+/*=============================================================================
+ Copyright (c) 2001-2015 Joel de Guzman
+ Copyright (c) 2001-2010 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)
+=============================================================================*/
+
+#define BOOST_SPIRIT_X3_UNICODE
+
+#include <boost/detail/lightweight_test.hpp>
+#include <boost/spirit/home/x3.hpp>
+#include <boost/type_traits/is_same.hpp>
+
+#include <iostream>
+#include "test.hpp"
+
+int
+main()
+{
+ using spirit_test::test;
+ using spirit_test::test_failure;
+ using spirit_test::test_attr;
+
+ using boost::spirit::x3::unused_type;
+
+ {
+ using namespace boost::spirit::x3::ascii;
+ BOOST_TEST(test("1", alnum));
+ BOOST_TEST(!test(" ", alnum));
+ BOOST_TEST(!test("1", alpha));
+ BOOST_TEST(test("x", alpha));
+ BOOST_TEST(test(" ", blank));
+ BOOST_TEST(!test("x", blank));
+ BOOST_TEST(test("1", digit));
+ BOOST_TEST(!test("x", digit));
+ BOOST_TEST(test("a", lower));
+ BOOST_TEST(!test("A", lower));
+ BOOST_TEST(test("!", punct));
+ BOOST_TEST(!test("x", punct));
+ BOOST_TEST(test(" ", space));
+ BOOST_TEST(test("\n", space));
+ BOOST_TEST(test("\r", space));
+ BOOST_TEST(test("\t", space));
+ BOOST_TEST(test("A", upper));
+ BOOST_TEST(!test("a", upper));
+ BOOST_TEST(test("A", xdigit));
+ BOOST_TEST(test("0", xdigit));
+ BOOST_TEST(test("f", xdigit));
+ BOOST_TEST(!test("g", xdigit));
+ }
+
+ {
+ using namespace boost::spirit::x3::ascii;
+ BOOST_TEST(!test("1", ~alnum));
+ BOOST_TEST(test(" ", ~alnum));
+ BOOST_TEST(test("1", ~alpha));
+ BOOST_TEST(!test("x", ~alpha));
+ BOOST_TEST(!test(" ", ~blank));
+ BOOST_TEST(test("x", ~blank));
+ BOOST_TEST(!test("1", ~digit));
+ BOOST_TEST(test("x", ~digit));
+ BOOST_TEST(!test("a", ~lower));
+ BOOST_TEST(test("A", ~lower));
+ BOOST_TEST(!test("!", ~punct));
+ BOOST_TEST(test("x", ~punct));
+ BOOST_TEST(!test(" ", ~space));
+ BOOST_TEST(!test("\n", ~space));
+ BOOST_TEST(!test("\r", ~space));
+ BOOST_TEST(!test("\t", ~space));
+ BOOST_TEST(!test("A", ~upper));
+ BOOST_TEST(test("a", ~upper));
+ BOOST_TEST(!test("A", ~xdigit));
+ BOOST_TEST(!test("0", ~xdigit));
+ BOOST_TEST(!test("f", ~xdigit));
+ BOOST_TEST(test("g", ~xdigit));
+ }
+
+ {
+ using namespace boost::spirit::x3::iso8859_1;
+ BOOST_TEST(test("1", alnum));
+ BOOST_TEST(!test(" ", alnum));
+ BOOST_TEST(!test("1", alpha));
+ BOOST_TEST(test("x", alpha));
+ BOOST_TEST(test(" ", blank));
+ BOOST_TEST(!test("x", blank));
+ BOOST_TEST(test("1", digit));
+ BOOST_TEST(!test("x", digit));
+ BOOST_TEST(test("a", lower));
+ BOOST_TEST(!test("A", lower));
+ BOOST_TEST(test("!", punct));
+ BOOST_TEST(!test("x", punct));
+ BOOST_TEST(test(" ", space));
+ BOOST_TEST(test("\n", space));
+ BOOST_TEST(test("\r", space));
+ BOOST_TEST(test("\t", space));
+ BOOST_TEST(test("A", upper));
+ BOOST_TEST(!test("a", upper));
+ BOOST_TEST(test("A", xdigit));
+ BOOST_TEST(test("0", xdigit));
+ BOOST_TEST(test("f", xdigit));
+ BOOST_TEST(!test("g", xdigit));
+
+ // test extended ASCII characters
+ BOOST_TEST(test("\xE9", alpha));
+ BOOST_TEST(test("\xE9", lower));
+ BOOST_TEST(!test("\xE9", upper));
+ }
+
+ {
+ using namespace boost::spirit::x3::standard;
+ BOOST_TEST(test("1", alnum));
+ BOOST_TEST(!test(" ", alnum));
+ BOOST_TEST(!test("1", alpha));
+ BOOST_TEST(test("x", alpha));
+ BOOST_TEST(test(" ", blank));
+ BOOST_TEST(!test("x", blank));
+ BOOST_TEST(test("1", digit));
+ BOOST_TEST(!test("x", digit));
+ BOOST_TEST(test("a", lower));
+ BOOST_TEST(!test("A", lower));
+ BOOST_TEST(test("!", punct));
+ BOOST_TEST(!test("x", punct));
+ BOOST_TEST(test(" ", space));
+ BOOST_TEST(test("\n", space));
+ BOOST_TEST(test("\r", space));
+ BOOST_TEST(test("\t", space));
+ BOOST_TEST(test("A", upper));
+ BOOST_TEST(!test("a", upper));
+ BOOST_TEST(test("A", xdigit));
+ BOOST_TEST(test("0", xdigit));
+ BOOST_TEST(test("f", xdigit));
+ BOOST_TEST(!test("g", xdigit));
+ }
+
+ {
+ using namespace boost::spirit::x3::standard_wide;
+ BOOST_TEST(test(L"1", alnum));
+ BOOST_TEST(!test(L" ", alnum));
+ BOOST_TEST(!test(L"1", alpha));
+ BOOST_TEST(test(L"x", alpha));
+ BOOST_TEST(test(L" ", blank));
+ BOOST_TEST(!test(L"x", blank));
+ BOOST_TEST(test(L"1", digit));
+ BOOST_TEST(!test(L"x", digit));
+ BOOST_TEST(test(L"a", lower));
+ BOOST_TEST(!test(L"A", lower));
+ BOOST_TEST(test(L"!", punct));
+ BOOST_TEST(!test(L"x", punct));
+ BOOST_TEST(test(L" ", space));
+ BOOST_TEST(test(L"\n", space));
+ BOOST_TEST(test(L"\r", space));
+ BOOST_TEST(test(L"\t", space));
+ BOOST_TEST(test(L"A", upper));
+ BOOST_TEST(!test(L"a", upper));
+ BOOST_TEST(test(L"A", xdigit));
+ BOOST_TEST(test(L"0", xdigit));
+ BOOST_TEST(test(L"f", xdigit));
+ BOOST_TEST(!test(L"g", xdigit));
+ }
+
+ {
+ using namespace boost::spirit::x3::unicode;
+ BOOST_TEST(test(L"1", alnum));
+ BOOST_TEST(!test(L" ", alnum));
+ BOOST_TEST(!test(L"1", alpha));
+ BOOST_TEST(test(L"x", alpha));
+ BOOST_TEST(test(L" ", blank));
+ BOOST_TEST(!test(L"x", blank));
+ BOOST_TEST(test(L"1", digit));
+ BOOST_TEST(!test(L"x", digit));
+ BOOST_TEST(test(L"a", lower));
+ BOOST_TEST(!test(L"A", lower));
+ BOOST_TEST(test(L"!", punct));
+ BOOST_TEST(!test(L"x", punct));
+ BOOST_TEST(test(L" ", space));
+ BOOST_TEST(test(L"\n", space));
+ BOOST_TEST(test(L"\r", space));
+ BOOST_TEST(test(L"\t", space));
+ BOOST_TEST(test(L"A", upper));
+ BOOST_TEST(!test(L"a", upper));
+ BOOST_TEST(test(L"A", xdigit));
+ BOOST_TEST(test(L"0", xdigit));
+ BOOST_TEST(test(L"f", xdigit));
+ BOOST_TEST(!test(L"g", xdigit));
+
+ BOOST_TEST(test(L"A", alphabetic));
+ BOOST_TEST(test(L"9", decimal_number));
+ BOOST_TEST(test(L"\u2800", braille));
+ BOOST_TEST(!test(L" ", braille));
+ BOOST_TEST(test(L" ", ~braille));
+ // $$$ TODO $$$ Add more unicode tests
+ }
+
+ { // test invalid unicode literals
+ using namespace boost::spirit::x3::unicode;
+
+ auto const invalid_unicode = char32_t{0x7FFFFFFF};
+ auto const input = boost::u32string_view(&invalid_unicode, 1);
+
+ BOOST_TEST(test_failure(input, char_));
+
+ // force unicode category lookup
+ // related issue: https://github.com/boostorg/spirit/issues/524
+ BOOST_TEST(test_failure(input, alpha));
+ BOOST_TEST(test_failure(input, upper));
+ BOOST_TEST(test_failure(input, lower));
+ }
+
+ { // test attribute extraction
+ using boost::spirit::x3::traits::attribute_of;
+ using boost::spirit::x3::iso8859_1::alpha;
+ using boost::spirit::x3::iso8859_1::alpha_type;
+
+ static_assert(
+ boost::is_same<
+ attribute_of<alpha_type, unused_type>::type
+ , unsigned char>::value
+ , "Wrong attribute type!"
+ );
+
+ int attr = 0;
+ BOOST_TEST(test_attr("a", alpha, attr));
+ BOOST_TEST(attr == 'a');
+ }
+
+ { // test attribute extraction
+ using boost::spirit::x3::iso8859_1::alpha;
+ using boost::spirit::x3::iso8859_1::space;
+ char attr = 0;
+ BOOST_TEST(test_attr(" a", alpha, attr, space));
+ BOOST_TEST(attr == 'a');
+ }
+
+ { // test action
+ using namespace boost::spirit::x3::ascii;
+ using boost::spirit::x3::_attr;
+ char ch;
+ auto f = [&](auto& ctx){ ch = _attr(ctx); };
+
+ BOOST_TEST(test("x", alnum[f]));
+ BOOST_TEST(ch == 'x');
+ BOOST_TEST(test(" A", alnum[f], space));
+ BOOST_TEST(ch == 'A');
+ }
+
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/spirit/test/x3/confix.cpp b/src/boost/libs/spirit/test/x3/confix.cpp
new file mode 100644
index 00000000..40bce11b
--- /dev/null
+++ b/src/boost/libs/spirit/test/x3/confix.cpp
@@ -0,0 +1,84 @@
+/*=============================================================================
+ Copyright (c) 2009 Chris Hoeppler
+ 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)
+=============================================================================*/
+#include <boost/detail/lightweight_test.hpp>
+
+#include <boost/spirit/home/x3/char.hpp>
+#include <boost/spirit/home/x3/core.hpp>
+#include <boost/spirit/home/x3/numeric.hpp>
+#include <boost/spirit/home/x3/operator.hpp>
+#include <boost/spirit/home/x3/string.hpp>
+#include <boost/spirit/home/x3/directive/confix.hpp>
+
+#include "test.hpp"
+
+int main()
+{
+ namespace x3 = boost::spirit::x3;
+ using namespace spirit_test;
+
+ {
+ const auto comment = x3::confix("/*", "*/");
+
+ BOOST_TEST(test_failure("/abcdef*/", comment["abcdef"]));
+ BOOST_TEST(test_failure("/* abcdef*/", comment["abcdef"]));
+ BOOST_TEST(test_failure("/*abcdef */", comment["abcdef"]));
+ BOOST_TEST(test("/*abcdef*/", comment["abcdef"]));
+
+ {
+ unsigned value = 0;
+ BOOST_TEST(
+ test_attr(" /* 123 */ ", comment[x3::uint_], value, x3::space));
+ BOOST_TEST(value == 123);
+
+ using x3::_attr;
+ value = 0;
+ const auto lambda = [&value](auto& ctx ){ value = _attr(ctx) + 1; };
+ BOOST_TEST(test_attr("/*123*/", comment[x3::uint_][lambda], value));
+ BOOST_TEST(value == 124);
+ }
+ }
+ {
+ const auto array = x3::confix('[', ']');
+
+ {
+ std::vector<unsigned> values;
+
+ BOOST_TEST(test("[0,2,4,6,8]", array[x3::uint_ % ',']));
+ BOOST_TEST(test_attr("[0,2,4,6,8]", array[x3::uint_ % ','], values));
+ BOOST_TEST(
+ values.size() == 5 &&
+ values[0] == 0 &&
+ values[1] == 2 &&
+ values[2] == 4 &&
+ values[3] == 6 &&
+ values[4] == 8);
+ }
+ {
+ std::vector<std::vector<unsigned>> values;
+ BOOST_TEST(
+ test("[[1,3,5],[0,2,4]]", array[array[x3::uint_ % ','] % ',']));
+ BOOST_TEST(
+ test_attr(
+ "[[1,3,5],[0,2,4]]",
+ array[array[x3::uint_ % ','] % ','],
+ values));
+ BOOST_TEST(
+ values.size() == 2 &&
+ values[0].size() == 3 &&
+ values[0][0] == 1 &&
+ values[0][1] == 3 &&
+ values[0][2] == 5 &&
+ values[1].size() == 3 &&
+ values[1][0] == 0 &&
+ values[1][1] == 2 &&
+ values[1][2] == 4);
+ }
+ }
+
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/spirit/test/x3/container_support.cpp b/src/boost/libs/spirit/test/x3/container_support.cpp
new file mode 100644
index 00000000..f8c79f1d
--- /dev/null
+++ b/src/boost/libs/spirit/test/x3/container_support.cpp
@@ -0,0 +1,248 @@
+/*=============================================================================
+ Copyright (c) 2001-2015 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)
+=============================================================================*/
+#include <boost/detail/lightweight_test.hpp>
+#include <boost/spirit/home/x3.hpp>
+#include <boost/fusion/include/std_pair.hpp>
+
+#include <iostream>
+#include <map>
+#include <unordered_map>
+#include <boost/unordered_map.hpp>
+#include <vector>
+#include <list>
+#include <deque>
+#include <set>
+#include <unordered_set>
+#include <boost/unordered_set.hpp>
+#include <string>
+#include "test.hpp"
+
+namespace x3 = boost::spirit::x3;
+
+x3::rule<class pair_rule, std::pair<std::string,std::string>> const pair_rule("pair");
+x3::rule<class string_rule, std::string> const string_rule("string");
+
+auto const pair_rule_def = string_rule > x3::lit('=') > string_rule;
+auto const string_rule_def = x3::lexeme[*x3::alnum];
+
+BOOST_SPIRIT_DEFINE(pair_rule, string_rule)
+
+template <typename Container>
+void test_map_support()
+{
+ using spirit_test::test_attr;
+
+ Container container;
+ Container const compare {{"k1", "v1"}, {"k2", "v2"}};
+ auto const rule = pair_rule % x3::lit(',');
+
+ BOOST_TEST(test_attr("k1=v1,k2=v2,k2=v3", rule, container));
+ BOOST_TEST(container.size() == 2);
+ BOOST_TEST(container == compare);
+
+ // test sequences parsing into containers
+ auto const seq_rule = pair_rule >> ',' >> pair_rule >> ',' >> pair_rule;
+ container.clear();
+ BOOST_TEST(test_attr("k1=v1,k2=v2,k2=v3", seq_rule, container));
+
+ // test parsing container into container
+ auto const cic_rule = pair_rule >> +(',' >> pair_rule);
+ container.clear();
+ BOOST_TEST(test_attr("k1=v1,k2=v2,k2=v3", cic_rule, container));
+}
+
+template <typename Container>
+void test_multimap_support()
+{
+ using spirit_test::test_attr;
+
+ Container container;
+ Container const compare {{"k1", "v1"}, {"k2", "v2"}, {"k2", "v3"}};
+ auto const rule = pair_rule % x3::lit(',');
+
+ BOOST_TEST(test_attr("k1=v1,k2=v2,k2=v3", rule, container));
+ BOOST_TEST(container.size() == 3);
+ BOOST_TEST(container == compare);
+
+ // test sequences parsing into containers
+ auto const seq_rule = pair_rule >> ',' >> pair_rule >> ',' >> pair_rule;
+ container.clear();
+ BOOST_TEST(test_attr("k1=v1,k2=v2,k2=v3", seq_rule, container));
+
+ // test parsing container into container
+ auto const cic_rule = pair_rule >> +(',' >> pair_rule);
+ container.clear();
+ BOOST_TEST(test_attr("k1=v1,k2=v2,k2=v3", cic_rule, container));
+}
+
+template <typename Container>
+void test_sequence_support()
+{
+ using spirit_test::test_attr;
+
+ Container container;
+ Container const compare {"e1", "e2", "e2"};
+ auto const rule = string_rule % x3::lit(',');
+
+ BOOST_TEST(test_attr("e1,e2,e2", rule, container));
+ BOOST_TEST(container.size() == 3);
+ BOOST_TEST(container == compare);
+
+ // test sequences parsing into containers
+ auto const seq_rule = string_rule >> ',' >> string_rule >> ',' >> string_rule;
+ container.clear();
+ BOOST_TEST(test_attr("e1,e2,e2", seq_rule, container));
+
+ // test parsing container into container
+ auto const cic_rule = string_rule >> +(',' >> string_rule);
+ container.clear();
+ BOOST_TEST(test_attr("e1,e2,e2", cic_rule, container));
+}
+
+template <typename Container>
+void test_set_support()
+{
+ using spirit_test::test_attr;
+
+ Container container;
+ Container const compare {"e1", "e2"};
+ auto const rule = string_rule % x3::lit(',');
+
+ BOOST_TEST(test_attr("e1,e2,e2", rule, container));
+ BOOST_TEST(container.size() == 2);
+ BOOST_TEST(container == compare);
+
+ // test sequences parsing into containers
+ auto const seq_rule = string_rule >> ',' >> string_rule >> ',' >> string_rule;
+ container.clear();
+ BOOST_TEST(test_attr("e1,e2,e2", seq_rule, container));
+
+ // test parsing container into container
+ auto const cic_rule = string_rule >> +(',' >> string_rule);
+ container.clear();
+ BOOST_TEST(test_attr("e1,e2,e2", cic_rule, container));
+}
+
+template <typename Container>
+void test_multiset_support()
+{
+ using spirit_test::test_attr;
+
+ Container container;
+ Container const compare {"e1", "e2", "e2"};
+ auto const rule = string_rule % x3::lit(',');
+
+ BOOST_TEST(test_attr("e1,e2,e2", rule, container));
+ BOOST_TEST(container.size() == 3);
+ BOOST_TEST(container == compare);
+
+ // test sequences parsing into containers
+ auto const seq_rule = string_rule >> ',' >> string_rule >> ',' >> string_rule;
+ container.clear();
+ BOOST_TEST(test_attr("e1,e2,e2", seq_rule, container));
+
+ // test parsing container into container
+ auto const cic_rule = string_rule >> +(',' >> string_rule);
+ container.clear();
+ BOOST_TEST(test_attr("e1,e2,e2", cic_rule, container));
+}
+
+template <typename Container>
+void test_string_support()
+{
+ using spirit_test::test_attr;
+
+ Container container;
+ Container const compare {"e1e2e2"};
+ auto const rule = string_rule % x3::lit(',');
+
+ BOOST_TEST(test_attr("e1,e2,e2", rule, container));
+ BOOST_TEST(container.size() == 6);
+ BOOST_TEST(container == compare);
+
+ // test sequences parsing into containers
+ auto const seq_rule = string_rule >> ',' >> string_rule >> ',' >> string_rule;
+ container.clear();
+ BOOST_TEST(test_attr("e1,e2,e2", seq_rule, container));
+
+ // test parsing container into container
+ auto const cic_rule = string_rule >> +(',' >> string_rule);
+ container.clear();
+ BOOST_TEST(test_attr("e1,e2,e2", cic_rule, container));
+}
+
+int
+main()
+{
+ using x3::traits::is_associative;
+ using x3::traits::is_reservable;
+
+ static_assert(is_reservable<std::vector<int>>::value, "is_reservable problem");
+ static_assert(is_reservable<std::string>::value, "is_reservable problem");
+ static_assert(is_reservable<std::unordered_set<int>>::value, "is_reservable problem");
+ static_assert(is_reservable<boost::unordered_set<int>>::value, "is_reservable problem");
+ static_assert(is_reservable<std::unordered_multiset<int>>::value, "is_reservable problem");
+ static_assert(is_reservable<boost::unordered_multiset<int>>::value, "is_reservable problem");
+ static_assert(is_reservable<std::unordered_map<int,int>>::value, "is_reservable problem");
+ static_assert(is_reservable<boost::unordered_map<int,int>>::value, "is_reservable problem");
+ static_assert(is_reservable<std::unordered_multimap<int,int>>::value, "is_reservable problem");
+ static_assert(is_reservable<boost::unordered_multimap<int,int>>::value, "is_reservable problem");
+
+ static_assert(!is_reservable<std::deque<int>>::value, "is_reservable problem");
+ static_assert(!is_reservable<std::list<int>>::value, "is_reservable problem");
+ static_assert(!is_reservable<std::set<int>>::value, "is_reservable problem");
+ static_assert(!is_reservable<std::multiset<int>>::value, "is_reservable problem");
+ static_assert(!is_reservable<std::map<int,int>>::value, "is_reservable problem");
+ static_assert(!is_reservable<std::multimap<int,int>>::value, "is_reservable problem");
+
+ // ------------------------------------------------------------------
+
+ static_assert(is_associative<std::set<int>>::value, "is_associative problem");
+ static_assert(is_associative<std::unordered_set<int>>::value, "is_associative problem");
+ static_assert(is_associative<boost::unordered_set<int>>::value, "is_associative problem");
+ static_assert(is_associative<std::multiset<int>>::value, "is_associative problem");
+ static_assert(is_associative<std::unordered_multiset<int>>::value, "is_associative problem");
+ static_assert(is_associative<boost::unordered_multiset<int>>::value, "is_associative problem");
+ static_assert(is_associative<std::map<int,int>>::value, "is_associative problem");
+ static_assert(is_associative<std::unordered_map<int,int>>::value, "is_associative problem");
+ static_assert(is_associative<boost::unordered_map<int,int>>::value, "is_associative problem");
+ static_assert(is_associative<std::multimap<int,int>>::value, "is_associative problem");
+ static_assert(is_associative<std::unordered_multimap<int,int>>::value, "is_associative problem");
+ static_assert(is_associative<boost::unordered_multimap<int,int>>::value, "is_associative problem");
+
+ static_assert(!is_associative<std::vector<int>>::value, "is_associative problem");
+ static_assert(!is_associative<std::string>::value, "is_associative problem");
+ static_assert(!is_associative<std::deque<int>>::value, "is_associative problem");
+ static_assert(!is_associative<std::list<int>>::value, "is_associative problem");
+
+ // ------------------------------------------------------------------
+
+ test_string_support<std::string>();
+
+ test_sequence_support<std::vector<std::string>>();
+ test_sequence_support<std::list<std::string>>();
+ test_sequence_support<std::deque<std::string>>();
+
+ test_set_support<std::set<std::string>>();
+ test_set_support<std::unordered_set<std::string>>();
+ test_set_support<boost::unordered_set<std::string>>();
+
+ test_multiset_support<std::multiset<std::string>>();
+ test_multiset_support<std::unordered_multiset<std::string>>();
+ test_multiset_support<boost::unordered_multiset<std::string>>();
+
+ test_map_support<std::map<std::string,std::string>>();
+ test_map_support<std::unordered_map<std::string,std::string>>();
+ test_map_support<boost::unordered_map<std::string,std::string>>();
+
+ test_multimap_support<std::multimap<std::string,std::string>>();
+ test_multimap_support<std::unordered_multimap<std::string,std::string>>();
+ test_multimap_support<boost::unordered_multimap<std::string,std::string>>();
+
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/spirit/test/x3/debug.cpp b/src/boost/libs/spirit/test/x3/debug.cpp
new file mode 100644
index 00000000..5d3508ac
--- /dev/null
+++ b/src/boost/libs/spirit/test/x3/debug.cpp
@@ -0,0 +1,144 @@
+/*=============================================================================
+ Copyright (c) 2001-2015 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)
+=============================================================================*/
+#define BOOST_SPIRIT_X3_DEBUG
+
+#include <boost/detail/lightweight_test.hpp>
+#include <boost/spirit/home/x3.hpp>
+#include <boost/fusion/include/std_pair.hpp>
+#include <boost/fusion/include/vector.hpp>
+
+#include <vector>
+#include <string>
+#include <cstring>
+#include <iostream>
+#include "test.hpp"
+
+struct my_error_handler
+{
+ template <typename Iterator, typename Exception, typename Context>
+ boost::spirit::x3::error_handler_result
+ operator()(Iterator&, Iterator const& last, Exception const& x, Context const&) const
+ {
+ std::cout
+ << "Error! Expecting: "
+ << x.which()
+ << ", got: \""
+ << std::string(x.where(), last)
+ << "\""
+ << std::endl;
+ return boost::spirit::x3::error_handler_result::fail;
+ }
+};
+
+struct my_attribute
+{
+ bool alive = true;
+
+ void access() const
+ {
+ BOOST_TEST(alive);
+ }
+ ~my_attribute()
+ {
+ alive = false;
+ }
+
+ friend std::ostream & operator << (std::ostream & os, my_attribute const & attr)
+ {
+ attr.access();
+ return os << "my_attribute";
+ }
+};
+
+int
+main()
+{
+ using spirit_test::test_attr;
+ using spirit_test::test;
+
+ using namespace boost::spirit::x3::ascii;
+ using boost::spirit::x3::rule;
+ using boost::spirit::x3::symbols;
+ using boost::spirit::x3::int_;
+ using boost::spirit::x3::alpha;
+
+ { // basic tests
+
+ auto a = rule<class a>("a") = 'a';
+ auto b = rule<class b>("b") = 'b';
+ auto c = rule<class c>("c") = 'c';
+
+ {
+ auto start = *(a | b | c);
+ BOOST_TEST(test("abcabcacb", start));
+ }
+
+ {
+ rule<class start> start("start");
+ auto start_def =
+ start = (a | b) >> (start | b);
+
+ BOOST_TEST(test("aaaabababaaabbb", start_def));
+ BOOST_TEST(test("aaaabababaaabba", start_def, false));
+ }
+ }
+
+ { // basic tests w/ skipper
+
+ auto a = rule<class a>("a") = 'a';
+ auto b = rule<class b>("b") = 'b';
+ auto c = rule<class c>("c") = 'c';
+
+ {
+ auto start = *(a | b | c);
+ BOOST_TEST(test(" a b c a b c a c b ", start, space));
+ }
+
+ {
+ rule<class start> start("start");
+ auto start_def =
+ start = (a | b) >> (start | b);
+
+ BOOST_TEST(test(" a a a a b a b a b a a a b b b ", start_def, space));
+ BOOST_TEST(test(" a a a a b a b a b a a a b b a ", start_def, space, false));
+ }
+ }
+
+ { // std::container attributes
+
+ typedef boost::fusion::vector<int, char> fs;
+ rule<class start, std::vector<fs>> start("start");
+ auto start_def =
+ start = *(int_ >> alpha);
+
+ BOOST_TEST(test("1 a 2 b 3 c", start_def, space));
+ }
+
+ { // error handling
+
+ auto r_def = '(' > int_ > ',' > int_ > ')';
+ auto r = r_def.on_error(my_error_handler());
+
+ BOOST_TEST(test("(123,456)", r));
+ BOOST_TEST(!test("(abc,def)", r));
+ BOOST_TEST(!test("(123,456]", r));
+ BOOST_TEST(!test("(123;456)", r));
+ BOOST_TEST(!test("[123,456]", r));
+ }
+
+ {
+ symbols<my_attribute> a{{{ "a", my_attribute{} }}};
+
+ auto b = rule<struct b, my_attribute>("b") = a;
+
+ my_attribute attr;
+
+ BOOST_TEST(test_attr("a", b, attr));
+ }
+
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/spirit/test/x3/difference.cpp b/src/boost/libs/spirit/test/x3/difference.cpp
new file mode 100644
index 00000000..5581cdea
--- /dev/null
+++ b/src/boost/libs/spirit/test/x3/difference.cpp
@@ -0,0 +1,66 @@
+/*=============================================================================
+ Copyright (c) 2001-2015 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)
+=============================================================================*/
+#include <boost/detail/lightweight_test.hpp>
+#include <boost/spirit/home/x3.hpp>
+
+#include <string>
+#include <iostream>
+#include "test.hpp"
+
+int
+main()
+{
+ using boost::spirit::x3::ascii::char_;
+ using boost::spirit::x3::ascii::space;
+ using boost::spirit::x3::lit;
+ using spirit_test::test;
+ using spirit_test::test_attr;
+
+ // Basic tests
+ {
+ BOOST_TEST(test("b", char_ - 'a'));
+ BOOST_TEST(!test("a", char_ - 'a'));
+ BOOST_TEST(test("/* abcdefghijk */", "/*" >> *(char_ - "*/") >> "*/"));
+ BOOST_TEST(!test("switch", lit("switch") - "switch"));
+ }
+
+ // Test attributes
+ {
+ char attr;
+ BOOST_TEST(test_attr("xg", (char_ - 'g') >> 'g', attr));
+ BOOST_TEST(attr == 'x');
+ }
+
+ // Test handling of container attributes
+ {
+ std::string attr;
+ BOOST_TEST(test_attr("abcdefg", *(char_ - 'g') >> 'g', attr));
+ BOOST_TEST(attr == "abcdef");
+ }
+
+ {
+ using boost::spirit::x3::_attr;
+
+ std::string s;
+
+ BOOST_TEST(test(
+ "/*abcdefghijk*/"
+ , "/*" >> *(char_ - "*/")[([&](auto& ctx){ s += _attr(ctx); })] >> "*/"
+ ));
+ BOOST_TEST(s == "abcdefghijk");
+ s.clear();
+
+ BOOST_TEST(test(
+ " /*abcdefghijk*/"
+ , "/*" >> *(char_ - "*/")[([&](auto& ctx){ s += _attr(ctx); })] >> "*/"
+ , space
+ ));
+ BOOST_TEST(s == "abcdefghijk");
+ }
+
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/spirit/test/x3/eoi.cpp b/src/boost/libs/spirit/test/x3/eoi.cpp
new file mode 100644
index 00000000..41de6d04
--- /dev/null
+++ b/src/boost/libs/spirit/test/x3/eoi.cpp
@@ -0,0 +1,29 @@
+/*=============================================================================
+ Copyright (c) 2001-2015 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)
+=============================================================================*/
+#include <boost/detail/lightweight_test.hpp>
+#include <boost/spirit/home/x3.hpp>
+
+#include <iostream>
+#include "test.hpp"
+
+int
+main()
+{
+ using spirit_test::test;
+ using boost::spirit::x3::eoi;
+
+ {
+ BOOST_TEST((test("", eoi)));
+ BOOST_TEST(!(test("x", eoi)));
+ }
+
+ {
+ BOOST_TEST(what(eoi) == "eoi");
+ }
+
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/spirit/test/x3/eol.cpp b/src/boost/libs/spirit/test/x3/eol.cpp
new file mode 100644
index 00000000..d363a621
--- /dev/null
+++ b/src/boost/libs/spirit/test/x3/eol.cpp
@@ -0,0 +1,32 @@
+/*=============================================================================
+ Copyright (c) 2001-2015 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)
+=============================================================================*/
+#include <boost/detail/lightweight_test.hpp>
+#include <boost/spirit/home/x3.hpp>
+
+#include <iostream>
+#include "test.hpp"
+
+int
+main()
+{
+ using spirit_test::test;
+ using boost::spirit::x3::eol;
+
+ {
+ BOOST_TEST((test("\r\n", eol)));
+ BOOST_TEST((test("\r", eol)));
+ BOOST_TEST((test("\n", eol)));
+ BOOST_TEST((!test("\n\r", eol)));
+ BOOST_TEST((!test("", eol)));
+ }
+
+ {
+ BOOST_TEST(what(eol) == "eol");
+ }
+
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/spirit/test/x3/eps.cpp b/src/boost/libs/spirit/test/x3/eps.cpp
new file mode 100644
index 00000000..d4bfac28
--- /dev/null
+++ b/src/boost/libs/spirit/test/x3/eps.cpp
@@ -0,0 +1,44 @@
+/*=============================================================================
+ Copyright (c) 2001-2015 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)
+=============================================================================*/
+#include <boost/detail/lightweight_test.hpp>
+#include <boost/spirit/home/x3.hpp>
+
+#include <iostream>
+#include "test.hpp"
+
+int
+main()
+{
+ using spirit_test::test;
+ using boost::spirit::x3::eps;
+ using boost::spirit::x3::unused_type;
+
+ {
+ BOOST_TEST((test("", eps)));
+ BOOST_TEST((test("xxx", eps, false)));
+ //~ BOOST_TEST((!test("", !eps))); // not predicate $$$ Implement me! $$$
+ }
+
+ { // test non-lazy semantic predicate
+
+ BOOST_TEST((test("", eps(true))));
+ BOOST_TEST((!test("", eps(false))));
+ BOOST_TEST((test("", !eps(false))));
+ }
+
+ { // test lazy semantic predicate
+
+ auto true_ = [](unused_type) { return true; };
+ auto false_ = [](unused_type) { return false; };
+
+ BOOST_TEST((test("", eps(true_))));
+ BOOST_TEST((!test("", eps(false_))));
+ BOOST_TEST((test("", !eps(false_))));
+ }
+
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/spirit/test/x3/error_handler.cpp b/src/boost/libs/spirit/test/x3/error_handler.cpp
new file mode 100644
index 00000000..d22949fd
--- /dev/null
+++ b/src/boost/libs/spirit/test/x3/error_handler.cpp
@@ -0,0 +1,57 @@
+/*=============================================================================
+ Copyright (c) 2001-2015 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)
+=============================================================================*/
+
+#include <boost/detail/lightweight_test.hpp>
+#include <boost/spirit/home/x3.hpp>
+#include <boost/spirit/home/x3/support/utility/annotate_on_success.hpp>
+#include <string>
+#include <sstream>
+
+namespace x3 = boost::spirit::x3;
+
+struct error_handler_base
+{
+ template <typename Iterator, typename Exception, typename Context>
+ x3::error_handler_result on_error(
+ Iterator&, Iterator const&
+ , Exception const& x, Context const& context) const
+ {
+ std::string message = "Error! Expecting: " + x.which() + " here:";
+ auto& error_handler = x3::get<x3::error_handler_tag>(context).get();
+ error_handler(x.where(), message);
+ return x3::error_handler_result::fail;
+ }
+};
+
+struct test_rule_class : x3::annotate_on_success, error_handler_base {};
+
+x3::rule<test_rule_class> const test_rule;
+auto const test_rule_def = x3::lit("foo") > x3::lit("bar") > x3::lit("git");
+
+BOOST_SPIRIT_DEFINE(test_rule)
+
+void test(std::string const& line_break) {
+ std::string const input("foo" + line_break + " foo" + line_break + "git");
+ auto const begin = std::begin(input);
+ auto const end = std::end(input);
+
+ std::stringstream stream;
+ x3::error_handler<std::string::const_iterator> error_handler{begin, end, stream};
+
+ auto const parser = x3::with<x3::error_handler_tag>(std::ref(error_handler))[test_rule];
+ x3::phrase_parse(begin, end, parser, x3::space);
+
+ BOOST_TEST_EQ(stream.str(), "In line 2:\nError! Expecting: \"bar\" here:\n foo\n__^_\n");
+}
+
+int main() {
+ test("\n");
+ test("\r");
+ test("\r\n");
+
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/spirit/test/x3/expect.cpp b/src/boost/libs/spirit/test/x3/expect.cpp
new file mode 100644
index 00000000..82422a3b
--- /dev/null
+++ b/src/boost/libs/spirit/test/x3/expect.cpp
@@ -0,0 +1,147 @@
+/*=============================================================================
+ Copyright (c) 2001-2013 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)
+=============================================================================*/
+#include <boost/detail/lightweight_test.hpp>
+#include <boost/spirit/home/x3.hpp>
+#include <boost/fusion/include/vector.hpp>
+#include <boost/fusion/include/at.hpp>
+
+#include <string>
+#include <iostream>
+#include "test.hpp"
+
+int
+main()
+{
+ using namespace boost::spirit;
+ using namespace boost::spirit::x3::ascii;
+ using boost::spirit::x3::lit;
+ using boost::spirit::x3::expect;
+ using spirit_test::test;
+ using spirit_test::test_attr;
+ using boost::spirit::x3::expectation_failure;
+
+ {
+ try
+ {
+ BOOST_TEST((test("aa", char_ >> expect[char_])));
+ BOOST_TEST((test("aaa", char_ >> expect[char_ >> char_('a')])));
+ BOOST_TEST((test("xi", char_('x') >> expect[char_('i')])));
+ BOOST_TEST((!test("xi", char_('y') >> expect[char_('o')]))); // should not throw!
+ BOOST_TEST((test("xin", char_('x') >> expect[char_('i') >> char_('n')])));
+ BOOST_TEST((!test("xi", char_('x') >> expect[char_('o')])));
+ }
+ catch (expectation_failure<char const*> const& x)
+ {
+ std::cout << "expected: " << x.which();
+ std::cout << " got: \"" << x.where() << '"' << std::endl;
+ }
+ }
+
+ {
+ try
+ {
+ BOOST_TEST((test("aa", char_ > char_)));
+ BOOST_TEST((test("aaa", char_ > char_ > char_('a'))));
+ BOOST_TEST((test("xi", char_('x') > char_('i'))));
+ BOOST_TEST((!test("xi", char_('y') > char_('o')))); // should not throw!
+ BOOST_TEST((test("xin", char_('x') > char_('i') > char_('n'))));
+ BOOST_TEST((!test("xi", char_('x') > char_('o'))));
+ }
+ catch (expectation_failure<char const*> const& x)
+ {
+ std::cout << "expected: " << x.which();
+ std::cout << " got: \"" << x.where() << '"' << std::endl;
+ }
+ }
+
+ {
+ try
+ {
+ BOOST_TEST((!test("ay:a", char_ > char_('x') >> ':' > 'a')));
+ }
+ catch (expectation_failure<char const*> const& x)
+ {
+ std::cout << "expected: " << x.which();
+ std::cout << " got: \"" << x.where() << '"' << std::endl;
+ }
+ }
+
+#if defined(BOOST_CLANG)
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Woverloaded-shift-op-parentheses"
+#endif
+ { // Test that attributes with > (sequences) work just like >> (sequences)
+
+ using boost::fusion::vector;
+ using boost::fusion::at_c;
+
+ {
+ vector<char, char, char> attr;
+ BOOST_TEST((test_attr(" a\n b\n c",
+ char_ > char_ > char_, attr, space)));
+ BOOST_TEST((at_c<0>(attr) == 'a'));
+ BOOST_TEST((at_c<1>(attr) == 'b'));
+ BOOST_TEST((at_c<2>(attr) == 'c'));
+ }
+
+ {
+ vector<char, char, char> attr;
+ BOOST_TEST((test_attr(" a\n b\n c",
+ char_ > char_ >> char_, attr, space)));
+ BOOST_TEST((at_c<0>(attr) == 'a'));
+ BOOST_TEST((at_c<1>(attr) == 'b'));
+ BOOST_TEST((at_c<2>(attr) == 'c'));
+ }
+
+ {
+ vector<char, char, char> attr;
+ BOOST_TEST((test_attr(" a, b, c",
+ char_ >> ',' > char_ >> ',' > char_, attr, space)));
+ BOOST_TEST((at_c<0>(attr) == 'a'));
+ BOOST_TEST((at_c<1>(attr) == 'b'));
+ BOOST_TEST((at_c<2>(attr) == 'c'));
+ }
+
+ {
+ std::string attr;
+ BOOST_TEST((test_attr("'azaaz'",
+ "'" > *(char_("a") | char_("z")) > "'", attr, space)));
+ BOOST_TEST(attr == "azaaz");
+ }
+ }
+#if defined(BOOST_CLANG)
+#pragma clang diagnostic pop
+#endif
+
+ {
+ try
+ {
+ BOOST_TEST((test(" a a", char_ > char_, space)));
+ BOOST_TEST((test(" x i", char_('x') > char_('i'), space)));
+ BOOST_TEST((!test(" x i", char_('x') > char_('o'), space)));
+ }
+ catch (expectation_failure<char const*> const& x)
+ {
+ std::cout << "expected: " << x.which();
+ std::cout << " got: \"" << x.where() << '"' << std::endl;
+ }
+ }
+
+ {
+ try
+ {
+ BOOST_TEST((test("bar", expect[lit("foo")])));
+ }
+ catch (expectation_failure<char const*> const& x)
+ {
+ std::cout << "expected: " << x.which();
+ std::cout << " got: \"" << x.where() << '"' << std::endl;
+ }
+ }
+
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/spirit/test/x3/extract_int.cpp b/src/boost/libs/spirit/test/x3/extract_int.cpp
new file mode 100644
index 00000000..f7b97cde
--- /dev/null
+++ b/src/boost/libs/spirit/test/x3/extract_int.cpp
@@ -0,0 +1,162 @@
+/*=============================================================================
+ Copyright (c) 2018 Nikita Kniazev
+
+ 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)
+=============================================================================*/
+
+#include <boost/detail/lightweight_test.hpp>
+#include <boost/spirit/home/x3/support/numeric_utils/extract_int.hpp>
+#include <cmath> // for std::pow
+#include <cstdio>
+#include <iosfwd>
+#include <limits>
+
+#ifdef _MSC_VER
+# pragma warning(disable: 4127) // conditional expression is constant
+#endif
+
+template <int Min, int Max>
+struct custom_int
+{
+ custom_int() = default;
+ constexpr custom_int(int value) : value_{value} {}
+
+ custom_int operator+(custom_int x) const { return value_ + x.value_; }
+ custom_int operator-(custom_int x) const { return value_ - x.value_; }
+ custom_int operator*(custom_int x) const { return value_ * x.value_; }
+ custom_int operator/(custom_int x) const { return value_ / x.value_; }
+
+ custom_int& operator+=(custom_int x) { value_ += x.value_; return *this; }
+ custom_int& operator-=(custom_int x) { value_ -= x.value_; return *this; }
+ custom_int& operator*=(custom_int x) { value_ *= x.value_; return *this; }
+ custom_int& operator/=(custom_int x) { value_ /= x.value_; return *this; }
+ custom_int& operator++() { ++value_; return *this; }
+ custom_int& operator--() { --value_; return *this; }
+ custom_int operator++(int) { return value_++; }
+ custom_int operator--(int) { return value_--; }
+
+ custom_int operator+() { return +value_; }
+ custom_int operator-() { return -value_; }
+
+ bool operator< (custom_int x) const { return value_ < x.value_; }
+ bool operator> (custom_int x) const { return value_ > x.value_; }
+ bool operator<=(custom_int x) const { return value_ <= x.value_; }
+ bool operator>=(custom_int x) const { return value_ >= x.value_; }
+ bool operator==(custom_int x) const { return value_ == x.value_; }
+ bool operator!=(custom_int x) const { return value_ != x.value_; }
+
+ template <typename Char, typename Traits>
+ friend std::basic_ostream<Char, Traits>&
+ operator<<(std::basic_ostream<Char, Traits>& os, custom_int x) {
+ return os << x.value_;
+ }
+
+ static constexpr int max = Max;
+ static constexpr int min = Min;
+
+private:
+ int value_;
+};
+
+namespace utils {
+
+template <int Min, int Max> struct digits;
+template <> struct digits<-9, 9> { static constexpr int r2 = 3, r10 = 1; };
+template <> struct digits<-10, 10> { static constexpr int r2 = 3, r10 = 1; };
+template <> struct digits<-15, 15> { static constexpr int r2 = 3, r10 = 1; };
+
+}
+
+namespace std {
+
+template <int Min, int Max>
+class numeric_limits<custom_int<Min, Max>> : public numeric_limits<int>
+{
+public:
+ static constexpr custom_int<Min, Max> max() noexcept { return Max; }
+ static constexpr custom_int<Min, Max> min() noexcept { return Min; }
+ static constexpr custom_int<Min, Max> lowest() noexcept { return min(); }
+ static_assert(numeric_limits<int>::radix == 2, "hardcoded for digits of radix 2");
+ static constexpr int digits = utils::digits<Min, Max>::r2;
+ static constexpr int digits10 = utils::digits<Min, Max>::r10;
+};
+
+}
+
+namespace x3 = boost::spirit::x3;
+
+template <typename T, int Base, int MaxDigits>
+void test_overflow_handling(char const* begin, char const* end, int i)
+{
+ // Check that parser fails on overflow
+ static_assert(std::numeric_limits<T>::is_bounded, "tests prerequest");
+ BOOST_ASSERT_MSG(MaxDigits == -1 || static_cast<int>(std::pow(float(Base), MaxDigits)) > T::max,
+ "test prerequest");
+ int initial = Base - i % Base; // just a 'random' non-equal to i number
+ T x { initial };
+ char const* it = begin;
+ bool r = x3::extract_int<T, Base, 1, MaxDigits>::call(it, end, x);
+ if (T::min <= i && i <= T::max) {
+ BOOST_TEST(r);
+ BOOST_TEST(it == end);
+ BOOST_TEST_EQ(x, i);
+ }
+ else
+ if (MaxDigits == -1) // TODO: Looks like a regression. See #430
+ {
+ BOOST_TEST(!r);
+ BOOST_TEST(it == begin);
+ }
+}
+
+template <typename T, int Base>
+void test_unparsed_digits_are_not_consumed(char const* it, char const* end, int i)
+{
+ // Check that unparsed digits are not consumed
+ static_assert(T::min <= -Base+1, "test prerequest");
+ static_assert(T::max >= Base-1, "test prerequest");
+ bool has_sign = *it == '+' || *it == '-';
+ auto len = end - it;
+ int initial = Base - i % Base; // just a 'random' non-equal to i number
+ T x { initial };
+ bool r = x3::extract_int<T, Base, 1, 1>::call(it, end, x);
+ BOOST_TEST(r);
+ if (-Base < i && i < Base) {
+ BOOST_TEST(it == end);
+ BOOST_TEST_EQ(x, i);
+ }
+ else {
+ BOOST_TEST_EQ(end - it, len - 1 - has_sign);
+ BOOST_TEST_EQ(x, i / Base);
+ }
+}
+
+template <typename T, int Base>
+void run_tests(char const* begin, char const* end, int i)
+{
+ // Check that parser fails on overflow
+ test_overflow_handling<T, Base, -1>(begin, end, i);
+ // Check that MaxDigits > digits10 behave like MaxDigits=-1
+ test_overflow_handling<T, Base, 2>(begin, end, i);
+ // Check that unparsed digits are not consumed
+ test_unparsed_digits_are_not_consumed<T, Base>(begin, end, i);
+}
+
+int main()
+{
+ for (int i = -30; i <= 30; ++i) {
+ char s[4];
+ std::snprintf(s, 4, "%d", i);
+ auto begin = &s[0], end = begin + std::strlen(begin);
+
+ // log(Base, abs(MinOrMax) + 1) == digits
+ run_tests<custom_int<-9, 9>, 10>(begin, end, i);
+ // (MinOrMax % Base) == 0
+ run_tests<custom_int<-10, 10>, 10>(begin, end, i);
+ // (MinOrMax % Base) != 0
+ run_tests<custom_int<-15, 15>, 10>(begin, end, i);
+ }
+
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/spirit/test/x3/fusion_map.cpp b/src/boost/libs/spirit/test/x3/fusion_map.cpp
new file mode 100644
index 00000000..719b5e30
--- /dev/null
+++ b/src/boost/libs/spirit/test/x3/fusion_map.cpp
@@ -0,0 +1,138 @@
+/*=============================================================================
+ Copyright (c) 2001-2015 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)
+ =============================================================================*/
+#include <boost/detail/lightweight_test.hpp>
+#include <boost/spirit/home/x3.hpp>
+#include <boost/fusion/include/at_key.hpp>
+#include <boost/fusion/include/make_map.hpp>
+#include <boost/fusion/adapted/struct.hpp>
+
+#include <string>
+#include <iostream>
+#include "test.hpp"
+
+struct AdaptedStruct {
+ std::string key1;
+ std::string key2;
+};
+
+class key1_attr {};
+class key2_attr {};
+
+BOOST_FUSION_ADAPT_ASSOC_STRUCT(
+ AdaptedStruct,
+ (std::string, key1, class key1_attr)
+ (std::string, key2, class key2_attr)
+ )
+
+template <class Parser, class Attribute>
+bool test_attr(const std::string in,Parser const& p, Attribute& attr) {
+ auto it = in.begin();
+ return boost::spirit::x3::parse(it,in.end(), p, attr);
+}
+
+int
+main()
+{
+ using spirit_test::test;
+ using boost::spirit::x3::lit;
+ using boost::spirit::x3::attr;
+ using boost::spirit::x3::char_;
+ using boost::spirit::x3::eps;
+ namespace fusion = boost::fusion;
+
+ { // parsing sequence directly into fusion map
+
+ auto const key1 = lit("key1") >> attr(key1_attr());
+ auto const kv1 = key1 >> lit("=") >> +char_;
+
+ {
+ auto attr_ = fusion::make_map<key1_attr>(std::string());
+ BOOST_TEST(test_attr("key1=ABC", kv1, attr_));
+ BOOST_TEST(fusion::at_key<key1_attr>(attr_) == "ABC");
+ }
+ {
+ AdaptedStruct attr_;
+ BOOST_TEST(test_attr("key1=ABC", kv1, attr_));
+ BOOST_TEST(attr_.key1 == "ABC");
+ BOOST_TEST(attr_.key2 == "");
+ }
+ }
+ { // case when parser handling fusion assoc sequence
+ // is on one side of another sequence
+ auto const key1 = lit("key1") >> attr(key1_attr());
+ auto const kv1 = key1 >> lit("=") >> +~char_(';');
+
+ AdaptedStruct attr_;
+ BOOST_TEST(test_attr("key1=ABC", eps >> (kv1 % ';') , attr_));
+ BOOST_TEST(attr_.key1 == "ABC");
+ BOOST_TEST(attr_.key2 == "");
+ }
+ { // parsing repeated sequence directly into fusion map (overwrite)
+ auto const key1 = lit("key1") >> attr(key1_attr());
+ auto const kv1 = key1 >> lit("=") >> +~char_(';');
+
+ {
+ auto attr_ = fusion::make_map<key1_attr>(std::string());
+ BOOST_TEST(test_attr("key1=ABC;key1=XYZ", kv1 % ';', attr_));
+ BOOST_TEST(fusion::at_key<key1_attr>(attr_) == "XYZ");
+ }
+ {
+ AdaptedStruct attr_;
+ BOOST_TEST(test_attr("key1=ABC;key1=XYZ", kv1 % ';', attr_));
+ BOOST_TEST(attr_.key1 == "XYZ");
+ }
+ }
+
+ { // parsing repeated sequence directly into fusion map (append)
+
+ /* NOT IMPLEMENTED
+ auto const key1 = lit("key1") >> attr(key1_attr());
+ auto const kv1 = key1 >> lit("=") >> +char_;
+ auto attr_ = fusion::make_map<key1_attr>(std::vector<std::string>());
+
+ BOOST_TEST(test_attr("key1=ABC;key1=XYZ", kv1 % ";", attr_));
+ BOOST_TEST(fusion::at_key<key1_attr>(attr_) == {"ABC","XYZ"});
+ */
+ }
+
+ { // alternative over key-value pairs
+
+ auto const key1 = lit("key1") >> attr(key1_attr());
+ auto const key2 = lit("key2") >> attr(key2_attr());
+ auto const kv1 = key1 >> lit("=") >> +~char_(';');
+ auto const kv2 = key2 >> lit("=") >> +~char_(';');
+
+ auto attr_ = fusion::make_map<key1_attr, key2_attr>(std::string(),std::string());
+ BOOST_TEST(test_attr("key2=XYZ;key1=ABC", (kv1|kv2) % ';', attr_));
+ BOOST_TEST(fusion::at_key<key1_attr>(attr_) == "ABC");
+ BOOST_TEST(fusion::at_key<key2_attr>(attr_) == "XYZ");
+ }
+
+ { // parsing sequence where key is a variant
+
+ namespace x3 = boost::spirit::x3;
+ auto key1 = lit("key1") >> attr(key1_attr());
+ auto key2 = lit("key2") >> attr(key2_attr());
+ auto keys = key1 | key2;
+ auto pair = keys >> lit("=") >> +~char_(';');
+
+ {
+ auto attr_ = fusion::make_map<key1_attr,key2_attr>(std::string(),std::string());
+ BOOST_TEST(test_attr("key1=ABC;key2=XYZ", pair % ';', attr_));
+ BOOST_TEST(fusion::at_key<key1_attr>(attr_) == "ABC");
+ BOOST_TEST(fusion::at_key<key2_attr>(attr_) == "XYZ");
+ }
+ {
+ AdaptedStruct attr_;
+ BOOST_TEST(test_attr("key1=ABC;key2=XYZ", pair % ';', attr_));
+ BOOST_TEST(fusion::at_key<key1_attr>(attr_) == "ABC");
+ BOOST_TEST(fusion::at_key<key2_attr>(attr_) == "XYZ");
+ }
+ }
+
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/spirit/test/x3/grammar.cpp b/src/boost/libs/spirit/test/x3/grammar.cpp
new file mode 100644
index 00000000..519e15cc
--- /dev/null
+++ b/src/boost/libs/spirit/test/x3/grammar.cpp
@@ -0,0 +1,6 @@
+#include "grammar.hpp"
+
+auto const grammar_def = x3::int_;
+
+BOOST_SPIRIT_DEFINE(grammar)
+BOOST_SPIRIT_INSTANTIATE(grammar_type, char const*, x3::unused_type)
diff --git a/src/boost/libs/spirit/test/x3/grammar.hpp b/src/boost/libs/spirit/test/x3/grammar.hpp
new file mode 100644
index 00000000..14b9402a
--- /dev/null
+++ b/src/boost/libs/spirit/test/x3/grammar.hpp
@@ -0,0 +1,7 @@
+#include <boost/spirit/home/x3.hpp>
+
+namespace x3 = boost::spirit::x3;
+
+x3::rule<struct grammar_r, int> const grammar;
+using grammar_type = decltype(grammar);
+BOOST_SPIRIT_DECLARE(grammar_type)
diff --git a/src/boost/libs/spirit/test/x3/grammar_linker.cpp b/src/boost/libs/spirit/test/x3/grammar_linker.cpp
new file mode 100644
index 00000000..00a6fcf1
--- /dev/null
+++ b/src/boost/libs/spirit/test/x3/grammar_linker.cpp
@@ -0,0 +1,24 @@
+/*=============================================================================
+ Copyright (c) 2019 Nikita Kniazev
+ Copyright (c) 2019 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)
+=============================================================================*/
+#include "grammar.hpp"
+#include <boost/detail/lightweight_test.hpp>
+
+int main()
+{
+ char const* s = "123", * e = s + std::strlen(s);
+#if 1
+ auto r = parse(s, e, grammar);
+#else
+ int i = 0;
+ auto r = parse(s, e, grammar, i);
+#endif
+
+ BOOST_TEST(r);
+ return boost::report_errors();
+}
+
diff --git a/src/boost/libs/spirit/test/x3/int.hpp b/src/boost/libs/spirit/test/x3/int.hpp
new file mode 100644
index 00000000..21c92504
--- /dev/null
+++ b/src/boost/libs/spirit/test/x3/int.hpp
@@ -0,0 +1,61 @@
+/*=============================================================================
+ Copyright (c) 2001-2012 Joel de Guzman
+ Copyright (c) 2001-2011 Hartmut Kaiser
+ Copyright (c) 2011 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_TEST_X3_INT_HPP)
+#define BOOST_SPIRIT_TEST_X3_INT_HPP
+
+#include <climits>
+#include <boost/detail/lightweight_test.hpp>
+#include <boost/spirit/home/x3/numeric/int.hpp>
+#include "test.hpp"
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// *** BEWARE PLATFORM DEPENDENT!!! ***
+// *** The following assumes 32 bit or 64 bit integers and 64 bit long longs.
+// *** Modify these constant strings when appropriate.
+//
+///////////////////////////////////////////////////////////////////////////////
+
+ static_assert(sizeof(long long) == 8, "unexpected long long size");
+
+#if INT_MAX != LLONG_MAX
+ static_assert(sizeof(int) == 4, "unexpected int size");
+ char const* max_int = "2147483647";
+ char const* int_overflow = "2147483648";
+ char const* min_int = "-2147483648";
+ char const* int_underflow = "-2147483649";
+#else
+ static_assert(sizeof(int) == 8, "unexpected int size");
+ char const* max_int = "9223372036854775807";
+ char const* int_overflow = "9223372036854775808";
+ char const* min_int = "-9223372036854775808";
+ char const* int_underflow = "-9223372036854775809";
+#endif
+
+ char const* max_long_long = "9223372036854775807";
+ char const* long_long_overflow = "9223372036854775808";
+ char const* min_long_long = "-9223372036854775808";
+ char const* long_long_underflow = "-9223372036854775809";
+
+///////////////////////////////////////////////////////////////////////////////
+// A custom int type
+struct custom_int
+{
+ int n;
+ custom_int() : n(0) {}
+ explicit custom_int(int n_) : n(n_) {}
+ custom_int& operator=(int n_) { n = n_; return *this; }
+ friend bool operator==(custom_int a, custom_int b) { return a.n == b.n; }
+ friend bool operator==(custom_int a, int b) { return a.n == b; }
+ friend custom_int operator*(custom_int a, custom_int b) { return custom_int(a.n * b.n); }
+ friend custom_int operator+(custom_int a, custom_int b) { return custom_int(a.n + b.n); }
+ friend custom_int operator-(custom_int a, custom_int b) { return custom_int(a.n - b.n); }
+};
+
+#endif
diff --git a/src/boost/libs/spirit/test/x3/int1.cpp b/src/boost/libs/spirit/test/x3/int1.cpp
new file mode 100644
index 00000000..cf42d511
--- /dev/null
+++ b/src/boost/libs/spirit/test/x3/int1.cpp
@@ -0,0 +1,186 @@
+/*=============================================================================
+ Copyright (c) 2001-2015 Joel de Guzman
+ Copyright (c) 2001-2011 Hartmut Kaiser
+ Copyright (c) 2011 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)
+=============================================================================*/
+#include "int.hpp"
+#include <boost/spirit/home/x3.hpp>
+#include <boost/fusion/include/vector.hpp>
+#include <boost/fusion/include/at.hpp>
+
+int
+main()
+{
+ using spirit_test::test;
+ using spirit_test::test_attr;
+
+ ///////////////////////////////////////////////////////////////////////////
+ // signed integer tests
+ ///////////////////////////////////////////////////////////////////////////
+ {
+ using boost::spirit::x3::int_;
+ int i;
+
+ BOOST_TEST(test("123456", int_));
+ BOOST_TEST(test_attr("123456", int_, i));
+ BOOST_TEST(i == 123456);
+
+ BOOST_TEST(test("+123456", int_));
+ BOOST_TEST(test_attr("+123456", int_, i));
+ BOOST_TEST(i == 123456);
+
+ BOOST_TEST(test("-123456", int_));
+ BOOST_TEST(test_attr("-123456", int_, i));
+ BOOST_TEST(i == -123456);
+
+ BOOST_TEST(test(max_int, int_));
+ BOOST_TEST(test_attr(max_int, int_, i));
+ BOOST_TEST(i == INT_MAX);
+
+ BOOST_TEST(test(min_int, int_));
+ BOOST_TEST(test_attr(min_int, int_, i));
+ BOOST_TEST(i == INT_MIN);
+
+ BOOST_TEST(!test(int_overflow, int_));
+ BOOST_TEST(!test_attr(int_overflow, int_, i));
+ BOOST_TEST(!test(int_underflow, int_));
+ BOOST_TEST(!test_attr(int_underflow, int_, i));
+
+ BOOST_TEST(!test("-", int_));
+ BOOST_TEST(!test_attr("-", int_, i));
+
+ BOOST_TEST(!test("+", int_));
+ BOOST_TEST(!test_attr("+", int_, i));
+
+ // Bug report from Steve Nutt
+ BOOST_TEST(!test_attr("5368709120", int_, i));
+
+ // with leading zeros
+ BOOST_TEST(test("0000000000123456", int_));
+ BOOST_TEST(test_attr("0000000000123456", int_, i));
+ BOOST_TEST(i == 123456);
+ }
+
+ ///////////////////////////////////////////////////////////////////////////
+ // long long tests
+ ///////////////////////////////////////////////////////////////////////////
+ {
+ using boost::spirit::x3::long_long;
+ boost::long_long_type ll;
+
+ BOOST_TEST(test("1234567890123456789", long_long));
+ BOOST_TEST(test_attr("1234567890123456789", long_long, ll));
+ BOOST_TEST(ll == 1234567890123456789LL);
+
+ BOOST_TEST(test("-1234567890123456789", long_long));
+ BOOST_TEST(test_attr("-1234567890123456789", long_long, ll));
+ BOOST_TEST(ll == -1234567890123456789LL);
+
+ BOOST_TEST(test(max_long_long, long_long));
+ BOOST_TEST(test_attr(max_long_long, long_long, ll));
+ BOOST_TEST(ll == LLONG_MAX);
+
+ BOOST_TEST(test(min_long_long, long_long));
+ BOOST_TEST(test_attr(min_long_long, long_long, ll));
+ BOOST_TEST(ll == LLONG_MIN);
+
+ BOOST_TEST(!test(long_long_overflow, long_long));
+ BOOST_TEST(!test_attr(long_long_overflow, long_long, ll));
+ BOOST_TEST(!test(long_long_underflow, long_long));
+ BOOST_TEST(!test_attr(long_long_underflow, long_long, ll));
+ }
+
+ ///////////////////////////////////////////////////////////////////////////
+ // short_ and long_ tests
+ ///////////////////////////////////////////////////////////////////////////
+ {
+ using boost::spirit::x3::short_;
+ using boost::spirit::x3::long_;
+ int i;
+
+ BOOST_TEST(test("12345", short_));
+ BOOST_TEST(test_attr("12345", short_, i));
+ BOOST_TEST(i == 12345);
+
+ BOOST_TEST(test("1234567890", long_));
+ BOOST_TEST(test_attr("1234567890", long_, i));
+ BOOST_TEST(i == 1234567890);
+ }
+
+ ///////////////////////////////////////////////////////////////////////////
+ // Check overflow is parse error
+ ///////////////////////////////////////////////////////////////////////////
+ {
+ boost::spirit::x3::int_parser<boost::int8_t> int8_;
+ char c;
+
+ BOOST_TEST(!test_attr("999", int8_, c));
+
+ int i;
+ using boost::spirit::x3::short_;
+ BOOST_TEST(!test_attr("32769", short_, i, false));
+ BOOST_TEST(!test_attr("41234", short_, i, false));
+ }
+
+ ///////////////////////////////////////////////////////////////////////////
+ // int_parser<unused_type> tests
+ ///////////////////////////////////////////////////////////////////////////
+ {
+ using boost::spirit::x3::int_parser;
+ using boost::spirit::x3::unused_type;
+ int_parser<unused_type> any_int;
+
+ BOOST_TEST(test("123456", any_int));
+ BOOST_TEST(test("-123456", any_int));
+ BOOST_TEST(test("-1234567890123456789", any_int));
+ }
+
+ ///////////////////////////////////////////////////////////////////////////
+ // action tests
+ ///////////////////////////////////////////////////////////////////////////
+ {
+ using boost::spirit::x3::_attr;
+ using boost::spirit::x3::ascii::space;
+ using boost::spirit::x3::int_;
+ int n = 0, m = 0;
+
+ auto f = [&](auto& ctx){ n = _attr(ctx); };
+
+ BOOST_TEST(test("123", int_[f]));
+ BOOST_TEST(n == 123);
+ BOOST_TEST(test_attr("789", int_[f], m));
+ BOOST_TEST(n == 789 && m == 789);
+ BOOST_TEST(test(" 456", int_[f], space));
+ BOOST_TEST(n == 456);
+ }
+
+ ///////////////////////////////////////////////////////////////////////////
+ // custom int tests
+ ///////////////////////////////////////////////////////////////////////////
+ {
+ using boost::spirit::x3::int_;
+ using boost::spirit::x3::int_parser;
+ custom_int i;
+
+ BOOST_TEST(test_attr("-123456", int_, i));
+ int_parser<custom_int, 10, 1, 2> int2;
+ BOOST_TEST(test_attr("-12", int2, i));
+ }
+
+ ///////////////////////////////////////////////////////////////////////////
+ // single-element fusion vector tests
+ ///////////////////////////////////////////////////////////////////////////
+ {
+ using boost::spirit::x3::int_;
+ using boost::spirit::x3::int_parser;
+ boost::fusion::vector<int> i;
+
+ BOOST_TEST(test_attr("-123456", int_, i));
+ BOOST_TEST(boost::fusion::at_c<0>(i) == -123456);
+ }
+
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/spirit/test/x3/iterator_check.cpp b/src/boost/libs/spirit/test/x3/iterator_check.cpp
new file mode 100644
index 00000000..70a8a176
--- /dev/null
+++ b/src/boost/libs/spirit/test/x3/iterator_check.cpp
@@ -0,0 +1,49 @@
+/*=============================================================================
+ Copyright (c) 2001-2017 Joel de Guzman
+ Copyright (c) 2017 think-cell GmbH
+
+ 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)
+=============================================================================*/
+#include <boost/detail/lightweight_test.hpp>
+#include <boost/spirit/home/x3.hpp>
+#include <boost/range/adaptor/transformed.hpp>
+
+#include <iostream>
+#include <string>
+#include <functional>
+
+int main()
+{
+ using boost::adaptors::transform;
+ using boost::spirit::x3::raw;
+ using boost::spirit::x3::eps;
+ using boost::spirit::x3::eoi;
+ using boost::spirit::x3::upper;
+ using boost::spirit::x3::repeat;
+ using boost::spirit::x3::parse;
+
+ std::string input = "abcde";
+ std::function<char(char)> func = [](char c) {
+ return c < 'a' || 'z' < c ? c : static_cast<char>(c - 'a' + 'A');
+ };
+ auto const rng = transform(input, func);
+
+ {
+ std::string str;
+ BOOST_TEST((parse(boost::begin(rng), boost::end(rng), +upper >> eoi, str)));
+ BOOST_TEST(("ABCDE"==str));
+ }
+
+ {
+ boost::iterator_range<decltype(boost::begin(rng))> str;
+ BOOST_TEST((parse(boost::begin(rng), boost::end(rng), raw[+upper >> eoi], str)));
+ BOOST_TEST((boost::equal(std::string("ABCDE"), str)));
+ }
+
+ {
+ BOOST_TEST((parse(boost::begin(rng), boost::end(rng), (repeat(6)[upper] | repeat(5)[upper]) >> eoi)));
+ }
+
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/spirit/test/x3/kleene.cpp b/src/boost/libs/spirit/test/x3/kleene.cpp
new file mode 100644
index 00000000..67f59d28
--- /dev/null
+++ b/src/boost/libs/spirit/test/x3/kleene.cpp
@@ -0,0 +1,126 @@
+/*=============================================================================
+ Copyright (c) 2001-2015 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)
+=============================================================================*/
+#include <string>
+#include <vector>
+
+#include <boost/detail/lightweight_test.hpp>
+#include <boost/spirit/home/x3.hpp>
+
+#include <string>
+#include <iostream>
+#include "test.hpp"
+#include "utils.hpp"
+
+struct x_attr
+{
+};
+
+namespace boost { namespace spirit { namespace x3 { namespace traits
+{
+ template <>
+ struct container_value<x_attr>
+ {
+ typedef char type; // value type of container
+ };
+
+ template <>
+ struct push_back_container<x_attr>
+ {
+ static bool call(x_attr& /*c*/, char /*val*/)
+ {
+ // push back value type into container
+ return true;
+ }
+ };
+}}}}
+
+int
+main()
+{
+ using spirit_test::test;
+ using spirit_test::test_attr;
+ using boost::spirit::x3::char_;
+ using boost::spirit::x3::alpha;
+ using boost::spirit::x3::upper;
+ using boost::spirit::x3::space;
+ using boost::spirit::x3::digit;
+ using boost::spirit::x3::int_;
+ using boost::spirit::x3::lexeme;
+
+ {
+ BOOST_TEST(test("aaaaaaaa", *char_));
+ BOOST_TEST(test("a", *char_));
+ BOOST_TEST(test("", *char_));
+ BOOST_TEST(test("aaaaaaaa", *alpha));
+ BOOST_TEST(!test("aaaaaaaa", *upper));
+ }
+
+ {
+ BOOST_TEST(test(" a a aaa aa", *char_, space));
+ BOOST_TEST(test("12345 678 9", *digit, space));
+ }
+
+ {
+ std::string s;
+ BOOST_TEST(test_attr("bbbb", *char_, s) && 4 == s.size() && s == "bbbb");
+
+ s.clear();
+ BOOST_TEST(test_attr("b b b b ", *char_, s, space) && s == "bbbb");
+ }
+
+ {
+ std::vector<int> v;
+ BOOST_TEST(test_attr("123 456 789 10", *int_, v, space) && 4 == v.size() &&
+ v[0] == 123 && v[1] == 456 && v[2] == 789 && v[3] == 10);
+ }
+
+ {
+ std::vector<std::string> v;
+ BOOST_TEST(test_attr("a b c d", *lexeme[+alpha], v, space) && 4 == v.size() &&
+ v[0] == "a" && v[1] == "b" && v[2] == "c" && v[3] == "d");
+ }
+
+ {
+ std::vector<int> v;
+ BOOST_TEST(test_attr("123 456 789", *int_, v, space) && 3 == v.size() &&
+ v[0] == 123 && v[1] == 456 && v[2] == 789);
+ }
+
+ { // actions
+ using boost::spirit::x3::_attr;
+
+ std::string v;
+ auto f = [&](auto& ctx){ v = _attr(ctx); };
+
+ BOOST_TEST(test("bbbb", (*char_)[f]) && 4 == v.size() &&
+ v[0] == 'b' && v[1] == 'b' && v[2] == 'b' && v[3] == 'b');
+ }
+
+ { // more actions
+ using boost::spirit::x3::_attr;
+
+ std::vector<int> v;
+ auto f = [&](auto& ctx){ v = _attr(ctx); };
+
+ BOOST_TEST(test("123 456 789", (*int_)[f], space) && 3 == v.size() &&
+ v[0] == 123 && v[1] == 456 && v[2] == 789);
+ }
+
+ { // attribute customization
+
+ x_attr x;
+ test_attr("abcde", *char_, x);
+ }
+
+ { // test move only types
+ std::vector<move_only> v;
+ BOOST_TEST(test_attr("sss", *synth_move_only, v));
+ BOOST_TEST_EQ(v.size(), 3);
+ }
+
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/spirit/test/x3/lexeme.cpp b/src/boost/libs/spirit/test/x3/lexeme.cpp
new file mode 100644
index 00000000..f8962e52
--- /dev/null
+++ b/src/boost/libs/spirit/test/x3/lexeme.cpp
@@ -0,0 +1,42 @@
+/*=============================================================================
+ Copyright (c) 2001-2015 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)
+=============================================================================*/
+#include <boost/detail/lightweight_test.hpp>
+#include <boost/spirit/home/x3.hpp>
+
+#include <iostream>
+#include "test.hpp"
+
+int
+main()
+{
+ using spirit_test::test;
+ using boost::spirit::x3::ascii::space;
+ using boost::spirit::x3::ascii::space_type;
+ using boost::spirit::x3::ascii::digit;
+ using boost::spirit::x3::lexeme;
+ using boost::spirit::x3::rule;
+
+ {
+ BOOST_TEST((test(" 1 2 3 4 5", +digit, space)));
+ BOOST_TEST((!test(" 1 2 3 4 5", lexeme[+digit], space)));
+ BOOST_TEST((test(" 12345", lexeme[+digit], space)));
+ BOOST_TEST((test(" 12345 ", lexeme[+digit], space, false)));
+
+ // lexeme collapsing
+ BOOST_TEST((!test(" 1 2 3 4 5", lexeme[lexeme[+digit]], space)));
+ BOOST_TEST((test(" 12345", lexeme[lexeme[+digit]], space)));
+ BOOST_TEST((test(" 12345 ", lexeme[lexeme[+digit]], space, false)));
+
+ auto r = +digit;
+ auto rr = lexeme[r];
+
+ BOOST_TEST((!test(" 1 2 3 4 5", rr, space)));
+ BOOST_TEST((test(" 12345", rr, space)));
+ }
+
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/spirit/test/x3/list.cpp b/src/boost/libs/spirit/test/x3/list.cpp
new file mode 100644
index 00000000..ff41de0e
--- /dev/null
+++ b/src/boost/libs/spirit/test/x3/list.cpp
@@ -0,0 +1,109 @@
+/*=============================================================================
+ Copyright (c) 2001-2013 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)
+=============================================================================*/
+#include <string>
+#include <vector>
+#include <set>
+#include <map>
+
+#include <boost/detail/lightweight_test.hpp>
+#include <boost/spirit/home/x3.hpp>
+
+#include <string>
+#include <iostream>
+#include "test.hpp"
+#include "utils.hpp"
+
+using namespace spirit_test;
+
+int
+main()
+{
+ using namespace boost::spirit::x3::ascii;
+
+ {
+ BOOST_TEST(test("a,b,c,d,e,f,g,h", char_ % ','));
+ BOOST_TEST(test("a,b,c,d,e,f,g,h,", char_ % ',', false));
+ }
+
+ {
+ BOOST_TEST(test("a, b, c, d, e, f, g, h", char_ % ',', space));
+ BOOST_TEST(test("a, b, c, d, e, f, g, h,", char_ % ',', space, false));
+ }
+
+ {
+ std::string s;
+ BOOST_TEST(test_attr("a,b,c,d,e,f,g,h", char_ % ',', s));
+ BOOST_TEST(s == "abcdefgh");
+
+ BOOST_TEST(!test("a,b,c,d,e,f,g,h,", char_ % ','));
+ }
+
+ {
+ std::string s;
+ BOOST_TEST(test_attr("ab,cd,ef,gh", (char_ >> char_) % ',', s));
+ BOOST_TEST(s == "abcdefgh");
+
+ BOOST_TEST(!test("ab,cd,ef,gh,", (char_ >> char_) % ','));
+ BOOST_TEST(!test("ab,cd,ef,g", (char_ >> char_) % ','));
+
+ s.clear();
+ BOOST_TEST(test_attr("ab,cd,efg", (char_ >> char_) % ',' >> char_, s));
+ BOOST_TEST(s == "abcdefg");
+ }
+
+ {
+ using boost::spirit::x3::int_;
+
+ std::vector<int> v;
+ BOOST_TEST(test_attr("1,2", int_ % ',', v));
+ BOOST_TEST(2 == v.size() && 1 == v[0] && 2 == v[1]);
+ }
+
+ {
+ using boost::spirit::x3::int_;
+
+ std::vector<int> v;
+ BOOST_TEST(test_attr("(1,2)", '(' >> int_ % ',' >> ')', v));
+ BOOST_TEST(2 == v.size() && 1 == v[0] && 2 == v[1]);
+ }
+
+ {
+ std::vector<std::string> v;
+ BOOST_TEST(test_attr("a,b,c,d", +alpha % ',', v));
+ BOOST_TEST(4 == v.size() && "a" == v[0] && "b" == v[1]
+ && "c" == v[2] && "d" == v[3]);
+ }
+
+ {
+ std::vector<boost::optional<char> > v;
+ BOOST_TEST(test_attr("#a,#", ('#' >> -alpha) % ',', v));
+ BOOST_TEST(2 == v.size() &&
+ !!v[0] && 'a' == boost::get<char>(v[0]) && !v[1]);
+
+ std::vector<char> v2;
+ BOOST_TEST(test_attr("#a,#", ('#' >> -alpha) % ',', v2));
+ BOOST_TEST(1 == v2.size() && 'a' == v2[0]);
+ }
+
+ { // actions
+ using boost::spirit::x3::_attr;
+
+ std::string s;
+ auto f = [&](auto& ctx){ s = std::string(_attr(ctx).begin(), _attr(ctx).end()); };
+
+ BOOST_TEST(test("a,b,c,d,e,f,g,h", (char_ % ',')[f]));
+ BOOST_TEST(s == "abcdefgh");
+ }
+
+ { // test move only types
+ std::vector<move_only> v;
+ BOOST_TEST(test_attr("s.s.s.s", synth_move_only % '.', v));
+ BOOST_TEST_EQ(v.size(), 4);
+ }
+
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/spirit/test/x3/lit.cpp b/src/boost/libs/spirit/test/x3/lit.cpp
new file mode 100644
index 00000000..2a9abc98
--- /dev/null
+++ b/src/boost/libs/spirit/test/x3/lit.cpp
@@ -0,0 +1,53 @@
+/*=============================================================================
+ Copyright (c) 2001-2015 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)
+=============================================================================*/
+#include <boost/detail/lightweight_test.hpp>
+#include <boost/spirit/home/x3.hpp>
+
+#include <string>
+
+#include "test.hpp"
+
+int
+main()
+{
+ using spirit_test::test_attr;
+ using boost::spirit::x3::lit;
+ using boost::spirit::x3::char_;
+
+ {
+ std::string attr;
+ auto p = char_ >> lit("\n");
+ BOOST_TEST(test_attr("A\n", p, attr));
+ BOOST_TEST(attr == "A");
+ }
+
+ {
+ using namespace boost::spirit::x3::ascii;
+ std::string attr;
+ auto p = char_ >> lit("\n");
+ BOOST_TEST(test_attr("A\n", p, attr));
+ BOOST_TEST(attr == "A");
+ }
+
+ {
+ using namespace boost::spirit::x3::iso8859_1;
+ std::string attr;
+ auto p = char_ >> lit("\n");
+ BOOST_TEST(test_attr("É\n", p, attr));
+ BOOST_TEST(attr == "É");
+ }
+
+ {
+ using namespace boost::spirit::x3::standard_wide;
+ std::wstring attr;
+ auto p = char_ >> lit("\n");
+ BOOST_TEST(test_attr(l"É\n", p, attr));
+ BOOST_TEST(attr == "A");
+ }
+
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/spirit/test/x3/lit1.cpp b/src/boost/libs/spirit/test/x3/lit1.cpp
new file mode 100644
index 00000000..7eefba6c
--- /dev/null
+++ b/src/boost/libs/spirit/test/x3/lit1.cpp
@@ -0,0 +1,85 @@
+/*=============================================================================
+ Copyright (c) 2001-2015 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)
+=============================================================================*/
+#include <boost/detail/lightweight_test.hpp>
+#include <boost/spirit/home/x3.hpp>
+#include <boost/fusion/include/vector.hpp>
+
+#include <string>
+#include "test.hpp"
+
+int
+main()
+{
+ using spirit_test::test;
+ using spirit_test::test_attr;
+ using boost::spirit::x3::string;
+
+ {
+ BOOST_TEST((test("kimpo", "kimpo")));
+ BOOST_TEST((test("kimpo", string("kimpo"))));
+
+ BOOST_TEST((test("x", string("x"))));
+ BOOST_TEST((test(L"x", string(L"x"))));
+
+ std::basic_string<char> s("kimpo");
+ std::basic_string<wchar_t> ws(L"kimpo");
+ BOOST_TEST((test("kimpo", s)));
+ BOOST_TEST((test(L"kimpo", ws)));
+ BOOST_TEST((test("kimpo", string(s))));
+ BOOST_TEST((test(L"kimpo", string(ws))));
+ }
+
+ {
+ BOOST_TEST((test(L"kimpo", L"kimpo")));
+ BOOST_TEST((test(L"kimpo", string(L"kimpo"))));
+ BOOST_TEST((test(L"x", string(L"x"))));
+ }
+
+ {
+ std::basic_string<char> s("kimpo");
+ BOOST_TEST((test("kimpo", string(s))));
+
+ std::basic_string<wchar_t> ws(L"kimpo");
+ BOOST_TEST((test(L"kimpo", string(ws))));
+ }
+
+ {
+ using namespace boost::spirit::x3::ascii;
+ BOOST_TEST((test(" kimpo", string("kimpo"), space)));
+ BOOST_TEST((test(L" kimpo", string(L"kimpo"), space)));
+ BOOST_TEST((test(" x", string("x"), space)));
+ }
+
+ {
+ using namespace boost::spirit::x3::ascii;
+ BOOST_TEST((test(" kimpo", string("kimpo"), space)));
+ BOOST_TEST((test(L" kimpo", string(L"kimpo"), space)));
+ BOOST_TEST((test(" x", string("x"), space)));
+ }
+
+ {
+ using namespace boost::spirit::x3::ascii;
+ std::string s;
+ BOOST_TEST((test_attr("kimpo", string("kimpo"), s)));
+ BOOST_TEST(s == "kimpo");
+ s.clear();
+ BOOST_TEST((test_attr(L"kimpo", string(L"kimpo"), s)));
+ BOOST_TEST(s == "kimpo");
+ s.clear();
+ BOOST_TEST((test_attr("x", string("x"), s)));
+ BOOST_TEST(s == "x");
+ }
+
+ { // single-element fusion vector tests
+ boost::fusion::vector<std::string> s;
+ BOOST_TEST(test_attr("kimpo", string("kimpo"), s));
+ BOOST_TEST(boost::fusion::at_c<0>(s) == "kimpo");
+ }
+
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/spirit/test/x3/lit2.cpp b/src/boost/libs/spirit/test/x3/lit2.cpp
new file mode 100644
index 00000000..947837f9
--- /dev/null
+++ b/src/boost/libs/spirit/test/x3/lit2.cpp
@@ -0,0 +1,52 @@
+/*=============================================================================
+ Copyright (c) 2001-2015 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)
+=============================================================================*/
+#include <boost/detail/lightweight_test.hpp>
+#include <boost/spirit/home/x3.hpp>
+
+#include <iostream>
+#include "test.hpp"
+
+int
+main()
+{
+ using spirit_test::test;
+ using spirit_test::test_attr;
+ using boost::spirit::x3::lit;
+
+ {
+ BOOST_TEST((test("kimpo", lit("kimpo"))));
+
+ std::basic_string<char> s("kimpo");
+ std::basic_string<wchar_t> ws(L"kimpo");
+ BOOST_TEST((test("kimpo", lit(s))));
+ BOOST_TEST((test(L"kimpo", lit(ws))));
+ }
+
+ {
+ std::basic_string<char> s("kimpo");
+ BOOST_TEST((test("kimpo", lit(s))));
+
+ std::basic_string<wchar_t> ws(L"kimpo");
+ BOOST_TEST((test(L"kimpo", lit(ws))));
+ }
+
+ {
+ using namespace boost::spirit::x3::ascii;
+ BOOST_TEST((test(" kimpo", lit("kimpo"), space)));
+ BOOST_TEST((test(L" kimpo", lit(L"kimpo"), space)));
+ }
+
+ {
+ using namespace boost::spirit::x3::iso8859_1;
+ BOOST_TEST((test(" kimpo", lit("kimpo"), space)));
+ BOOST_TEST((test(L" kimpo", lit(L"kimpo"), space)));
+ }
+
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/spirit/test/x3/matches.cpp b/src/boost/libs/spirit/test/x3/matches.cpp
new file mode 100644
index 00000000..58923b72
--- /dev/null
+++ b/src/boost/libs/spirit/test/x3/matches.cpp
@@ -0,0 +1,37 @@
+/*=============================================================================
+ Copyright (c) 2001-2015 Joel de Guzman
+ Copyright (c) 2001-2010 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)
+=============================================================================*/
+#include <boost/detail/lightweight_test.hpp>
+#include <boost/spirit/home/x3.hpp>
+#include <iostream>
+#include "test.hpp"
+
+int
+main()
+{
+ using spirit_test::test;
+ using spirit_test::test_attr;
+ using boost::spirit::x3::matches;
+ using boost::spirit::x3::char_;
+
+ {
+ BOOST_TEST(test("x", matches[char_]));
+ bool result = false;
+ BOOST_TEST(test_attr("x", matches[char_], result) && result);
+ }
+
+ {
+ BOOST_TEST(!test("y", matches[char_('x')]));
+ BOOST_TEST(!test("y", matches['x']));
+ bool result = true;
+ BOOST_TEST(test_attr("y", matches[char_('x')], result, false) && !result);
+ result = true;
+ BOOST_TEST(test_attr("y", matches['x'], result, false) && !result);
+ }
+
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/spirit/test/x3/no_case.cpp b/src/boost/libs/spirit/test/x3/no_case.cpp
new file mode 100644
index 00000000..cbf6c9dd
--- /dev/null
+++ b/src/boost/libs/spirit/test/x3/no_case.cpp
@@ -0,0 +1,148 @@
+/*=============================================================================
+ Copyright (c) 2001-2015 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)
+=============================================================================*/
+
+#include <boost/detail/lightweight_test.hpp>
+#include <boost/spirit/home/x3.hpp>
+
+#include <iostream>
+#include "test.hpp"
+
+int
+main()
+{
+ using spirit_test::test;
+ using spirit_test::test_attr;
+ using boost::spirit::x3::no_case;
+
+ {
+ using namespace boost::spirit::x3::ascii;
+ BOOST_TEST(test("x", no_case[char_]));
+ BOOST_TEST(test("X", no_case[char_('x')]));
+ BOOST_TEST(test("X", no_case[char_('X')]));
+ BOOST_TEST(test("x", no_case[char_('X')]));
+ BOOST_TEST(test("x", no_case[char_('x')]));
+ BOOST_TEST(!test("z", no_case[char_('X')]));
+ BOOST_TEST(!test("z", no_case[char_('x')]));
+ BOOST_TEST(test("x", no_case[char_('a', 'z')]));
+ BOOST_TEST(test("X", no_case[char_('a', 'z')]));
+ BOOST_TEST(!test("a", no_case[char_('b', 'z')]));
+ BOOST_TEST(!test("z", no_case[char_('a', 'y')]));
+ }
+ {
+ using namespace boost::spirit::x3::ascii;
+ BOOST_TEST(test("X", no_case['x']));
+ BOOST_TEST(test("X", no_case['X']));
+ BOOST_TEST(test("x", no_case['X']));
+ BOOST_TEST(test("x", no_case['x']));
+ BOOST_TEST(!test("z", no_case['X']));
+ BOOST_TEST(!test("z", no_case['x']));
+ }
+
+ {
+ using namespace boost::spirit::x3::iso8859_1;
+ BOOST_TEST(test("X", no_case[char_("a-z")]));
+ BOOST_TEST(!test("1", no_case[char_("a-z")]));
+ }
+
+ { // test extended ASCII characters
+ using namespace boost::spirit::x3::iso8859_1;
+ BOOST_TEST(test("\xC1", no_case[char_('\xE1')]));
+
+ BOOST_TEST(test("\xC9", no_case[char_("\xE5-\xEF")]));
+ BOOST_TEST(!test("\xFF", no_case[char_("\xE5-\xEF")]));
+
+ BOOST_TEST(test("\xC1\xE1", no_case[lit("\xE1\xC1")]));
+ BOOST_TEST(test("\xE1\xE1", no_case[no_case[lit("\xE1\xC1")]]));
+ }
+
+ {
+ using namespace boost::spirit::x3::ascii;
+ BOOST_TEST(test("Bochi Bochi", no_case[lit("bochi bochi")]));
+ BOOST_TEST(test("BOCHI BOCHI", no_case[lit("bochi bochi")]));
+ BOOST_TEST(!test("Vavoo", no_case[lit("bochi bochi")]));
+ }
+
+ {
+ // should work!
+ using namespace boost::spirit::x3::ascii;
+ BOOST_TEST(test("x", no_case[no_case[char_]]));
+ BOOST_TEST(test("x", no_case[no_case[char_('x')]]));
+ BOOST_TEST(test("yabadabadoo", no_case[no_case[lit("Yabadabadoo")]]));
+ }
+
+ {
+ using namespace boost::spirit::x3::ascii;
+ BOOST_TEST(test("X", no_case[alnum]));
+ BOOST_TEST(test("6", no_case[alnum]));
+ BOOST_TEST(!test(":", no_case[alnum]));
+
+ BOOST_TEST(test("X", no_case[lower]));
+ BOOST_TEST(test("x", no_case[lower]));
+ BOOST_TEST(test("X", no_case[upper]));
+ BOOST_TEST(test("x", no_case[upper]));
+ BOOST_TEST(!test(":", no_case[lower]));
+ BOOST_TEST(!test(":", no_case[upper]));
+ }
+
+ {
+ using namespace boost::spirit::x3::iso8859_1;
+ BOOST_TEST(test("X", no_case[alnum]));
+ BOOST_TEST(test("6", no_case[alnum]));
+ BOOST_TEST(!test(":", no_case[alnum]));
+
+ BOOST_TEST(test("X", no_case[lower]));
+ BOOST_TEST(test("x", no_case[lower]));
+ BOOST_TEST(test("X", no_case[upper]));
+ BOOST_TEST(test("x", no_case[upper]));
+ BOOST_TEST(!test(":", no_case[lower]));
+ BOOST_TEST(!test(":", no_case[upper]));
+ }
+
+ {
+ using namespace boost::spirit::x3::standard;
+ BOOST_TEST(test("X", no_case[alnum]));
+ BOOST_TEST(test("6", no_case[alnum]));
+ BOOST_TEST(!test(":", no_case[alnum]));
+
+ BOOST_TEST(test("X", no_case[lower]));
+ BOOST_TEST(test("x", no_case[lower]));
+ BOOST_TEST(test("X", no_case[upper]));
+ BOOST_TEST(test("x", no_case[upper]));
+ BOOST_TEST(!test(":", no_case[lower]));
+ BOOST_TEST(!test(":", no_case[upper]));
+ }
+
+ {
+ // chsets
+ namespace standard = boost::spirit::x3::standard;
+ namespace standard_wide = boost::spirit::x3::standard_wide;
+
+ BOOST_TEST(test("x", no_case[standard::char_("a-z")]));
+ BOOST_TEST(test("X", no_case[standard::char_("a-z")]));
+ BOOST_TEST(test(L"X", no_case[standard_wide::char_(L"a-z")]));
+ BOOST_TEST(test(L"X", no_case[standard_wide::char_(L"X")]));
+ }
+
+ {
+ using namespace boost::spirit::x3::standard;
+ std::string s("bochi bochi");
+ BOOST_TEST(test("Bochi Bochi", no_case[lit(s.c_str())]));
+ BOOST_TEST(test("Bochi Bochi", no_case[lit(s)]));
+ BOOST_TEST(test("Bochi Bochi", no_case[s.c_str()]));
+ BOOST_TEST(test("Bochi Bochi", no_case[s]));
+ }
+
+ {
+ {
+ using namespace boost::spirit::x3::standard;
+ BOOST_TEST(!test("Ä…", no_case['a']));
+ }
+ }
+
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/spirit/test/x3/no_skip.cpp b/src/boost/libs/spirit/test/x3/no_skip.cpp
new file mode 100644
index 00000000..b64a4a6e
--- /dev/null
+++ b/src/boost/libs/spirit/test/x3/no_skip.cpp
@@ -0,0 +1,50 @@
+/*=============================================================================
+ Copyright (c) 2001-2015 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)
+=============================================================================*/
+#include <boost/detail/lightweight_test.hpp>
+#include <boost/spirit/home/x3.hpp>
+
+#include <iostream>
+#include "test.hpp"
+
+int
+main()
+{
+ using spirit_test::test;
+ using spirit_test::test_attr;
+ using boost::spirit::x3::ascii::space;
+ using boost::spirit::x3::ascii::space_type;
+ using boost::spirit::x3::ascii::char_;
+ using boost::spirit::x3::lexeme;
+ using boost::spirit::x3::no_skip;
+
+ // without skipping no_skip is equivalent to lexeme
+ {
+ std::string str;
+ BOOST_TEST((test_attr("' abc '", '\'' >> no_skip[+~char_('\'')] >> '\'', str)));
+ BOOST_TEST(str == " abc ");
+ }
+ {
+ std::string str;
+ BOOST_TEST((test_attr("' abc '", '\'' >> lexeme[+~char_('\'')] >> '\'', str)));
+ BOOST_TEST(str == " abc ");
+ }
+
+ // with skipping, no_skip allows to match a leading skipper
+ {
+ std::string str;
+ BOOST_TEST((test_attr("' abc '", '\'' >> no_skip[+~char_('\'')] >> '\'', str, space)));
+ BOOST_TEST(str == " abc ");
+ }
+ {
+ std::string str;
+ BOOST_TEST((test_attr("' abc '", '\'' >> lexeme[+~char_('\'')] >> '\'', str, space)));
+ BOOST_TEST(str == "abc ");
+ }
+
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/spirit/test/x3/not_predicate.cpp b/src/boost/libs/spirit/test/x3/not_predicate.cpp
new file mode 100644
index 00000000..d5b962a4
--- /dev/null
+++ b/src/boost/libs/spirit/test/x3/not_predicate.cpp
@@ -0,0 +1,26 @@
+/*=============================================================================
+ Copyright (c) 2001-2015 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)
+=============================================================================*/
+#include <boost/detail/lightweight_test.hpp>
+#include <boost/spirit/home/x3.hpp>
+
+#include <iostream>
+#include "test.hpp"
+
+int
+main()
+{
+ using spirit_test::test;
+ using boost::spirit::x3::int_;
+
+ {
+ BOOST_TEST((!test("1234", !int_)));
+ BOOST_TEST((test("abcd", !int_, false)));
+ BOOST_TEST((!test("abcd", !!int_, false)));
+ }
+
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/spirit/test/x3/omit.cpp b/src/boost/libs/spirit/test/x3/omit.cpp
new file mode 100644
index 00000000..f89a4851
--- /dev/null
+++ b/src/boost/libs/spirit/test/x3/omit.cpp
@@ -0,0 +1,114 @@
+/*=============================================================================
+ Copyright (c) 2001-2015 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)
+=============================================================================*/
+#include <boost/detail/lightweight_test.hpp>
+#include <boost/spirit/home/x3.hpp>
+#include <boost/fusion/include/vector.hpp>
+#include <boost/fusion/include/at.hpp>
+
+#include <string>
+#include <iostream>
+#include "test.hpp"
+
+int
+main()
+{
+ using namespace boost::spirit::x3::ascii;
+ using boost::spirit::x3::omit;
+ using boost::spirit::x3::unused_type;
+ using boost::spirit::x3::unused;
+ using boost::spirit::x3::int_;
+
+ using boost::fusion::vector;
+ using boost::fusion::at_c;
+
+ using spirit_test::test;
+ using spirit_test::test_attr;
+
+ {
+ BOOST_TEST(test("a", omit['a']));
+ }
+
+ {
+ // omit[] means we don't receive the attribute
+ char attr;
+ BOOST_TEST((test_attr("abc", omit[char_] >> omit['b'] >> char_, attr)));
+ BOOST_TEST((attr == 'c'));
+ }
+
+ {
+ // If all elements except 1 is omitted, the attribute is
+ // a single-element sequence. For this case alone, we allow
+ // naked attributes (unwrapped in a fusion sequence).
+ char attr;
+ BOOST_TEST((test_attr("abc", omit[char_] >> 'b' >> char_, attr)));
+ BOOST_TEST((attr == 'c'));
+ }
+
+ {
+ // omit[] means we don't receive the attribute
+ vector<> attr;
+ BOOST_TEST((test_attr("abc", omit[char_] >> omit['b'] >> omit[char_], attr)));
+ }
+
+ {
+ // omit[] means we don't receive the attribute
+ // this test is merely a compile test, because using a unused as the
+ // explicit attribute doesn't make any sense
+ unused_type attr;
+ BOOST_TEST((test_attr("abc", omit[char_ >> 'b' >> char_], attr)));
+ }
+
+ {
+ // omit[] means we don't receive the attribute, if all elements of a
+ // sequence have unused attributes, the whole sequence has an unused
+ // attribute as well
+ vector<char, char> attr;
+ BOOST_TEST((test_attr("abcde",
+ char_ >> (omit[char_] >> omit['c'] >> omit[char_]) >> char_, attr)));
+ BOOST_TEST((at_c<0>(attr) == 'a'));
+ BOOST_TEST((at_c<1>(attr) == 'e'));
+ }
+
+ {
+ // "hello" has an unused_type. unused attrubutes are not part of the sequence
+ vector<char, char> attr;
+ BOOST_TEST((test_attr("a hello c", char_ >> "hello" >> char_, attr, space)));
+ BOOST_TEST((at_c<0>(attr) == 'a'));
+ BOOST_TEST((at_c<1>(attr) == 'c'));
+ }
+
+ {
+ // if only one node in a sequence is left (all the others are omitted),
+ // then we need "naked" attributes (not wraped in a tuple)
+ int attr;
+ BOOST_TEST((test_attr("a 123 c", omit['a'] >> int_ >> omit['c'], attr, space)));
+ BOOST_TEST((attr == 123));
+ }
+
+ {
+ // unused means we don't care about the attribute
+ BOOST_TEST((test_attr("abc", char_ >> 'b' >> char_, unused)));
+ }
+
+ { // test action with omitted attribute
+ char c = 0;
+ auto f = [&](auto& ctx){ c = _attr(ctx); };
+
+ BOOST_TEST(test("x123\"a string\"", (char_ >> omit[int_] >> "\"a string\"")[f]));
+ BOOST_TEST(c == 'x');
+ }
+
+ { // test action with omitted attribute
+ int n = 0;
+ auto f = [&](auto& ctx){ n = _attr(ctx); };
+
+ BOOST_TEST(test("x 123 \"a string\"", (omit[char_] >> int_ >> "\"a string\"")[f], space));
+ BOOST_TEST(n == 123);
+ }
+
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/spirit/test/x3/optional.cpp b/src/boost/libs/spirit/test/x3/optional.cpp
new file mode 100644
index 00000000..cd7f6d32
--- /dev/null
+++ b/src/boost/libs/spirit/test/x3/optional.cpp
@@ -0,0 +1,113 @@
+/*=============================================================================
+ Copyright (c) 2001-2015 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)
+=============================================================================*/
+#include <boost/detail/lightweight_test.hpp>
+#include <boost/spirit/home/x3.hpp>
+#include <boost/fusion/adapted/struct.hpp>
+#include <boost/fusion/include/vector.hpp>
+
+#include <iostream>
+#include "test.hpp"
+#include "utils.hpp"
+
+struct adata
+{
+ int a;
+ boost::optional<int> b;
+};
+
+BOOST_FUSION_ADAPT_STRUCT(adata,
+ a, b
+)
+
+struct test_attribute_type
+{
+ template <typename Context>
+ void operator()(Context& ctx) const
+ {
+ BOOST_TEST(typeid(decltype(_attr(ctx))).name() == typeid(boost::optional<int>).name());
+ }
+};
+
+int
+main()
+{
+ using boost::spirit::x3::traits::is_optional;
+
+ static_assert(is_optional<boost::optional<int>>(), "is_optional problem");
+
+ using spirit_test::test;
+ using spirit_test::test_attr;
+
+ using boost::spirit::x3::int_;
+ using boost::spirit::x3::omit;
+ using boost::spirit::x3::ascii::char_;
+
+ {
+ BOOST_TEST((test("1234", -int_)));
+ BOOST_TEST((test("abcd", -int_, false)));
+ }
+
+ { // test propagation of unused
+ using boost::fusion::at_c;
+ using boost::fusion::vector;
+
+ vector<char, char> v;
+ BOOST_TEST((test_attr("a1234c", char_ >> -omit[int_] >> char_, v)));
+ BOOST_TEST((at_c<0>(v) == 'a'));
+ BOOST_TEST((at_c<1>(v) == 'c'));
+
+ v = boost::fusion::vector<char, char>();
+ BOOST_TEST((test_attr("a1234c", char_ >> omit[-int_] >> char_, v)));
+ BOOST_TEST((at_c<0>(v) == 'a'));
+ BOOST_TEST((at_c<1>(v) == 'c'));
+
+ char ch;
+ BOOST_TEST((test_attr(",c", -(',' >> char_), ch)));
+ BOOST_TEST((ch == 'c'));
+ }
+
+ { // test action
+ boost::optional<int> n = 0;
+ BOOST_TEST((test_attr("1234", (-int_)[test_attribute_type()], n)));
+ BOOST_TEST((n.get() == 1234));
+ }
+
+ {
+ std::string s;
+ BOOST_TEST((test_attr("abc", char_ >> -(char_ >> char_), s)));
+ BOOST_TEST(s == "abc");
+ }
+
+ {
+ boost::optional<int> n = 0;
+ auto f = [&](auto& ctx){ n = _attr(ctx); };
+
+ BOOST_TEST((test("1234", (-int_)[f])));
+ BOOST_TEST(n.get() == 1234);
+
+ n = boost::optional<int>();
+ BOOST_TEST((test("abcd", (-int_)[f], false)));
+ BOOST_TEST(!n);
+ }
+
+ {
+ std::vector<adata> v;
+ BOOST_TEST((test_attr("a 1 2 a 2", *('a' >> int_ >> -int_), v
+ , char_(' '))));
+ BOOST_TEST(2 == v.size() &&
+ 1 == v[0].a && v[0].b && 2 == *(v[0].b) &&
+ 2 == v[1].a && !v[1].b);
+ }
+
+ { // test move only types
+ boost::optional<move_only> o;
+ BOOST_TEST(test_attr("s", -synth_move_only, o));
+ BOOST_TEST(o);
+ }
+
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/spirit/test/x3/optional_ast_node.cpp b/src/boost/libs/spirit/test/x3/optional_ast_node.cpp
new file mode 100644
index 00000000..036d6de4
--- /dev/null
+++ b/src/boost/libs/spirit/test/x3/optional_ast_node.cpp
@@ -0,0 +1,66 @@
+/*=============================================================================
+ Copyright (c) 2001-2015 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)
+
+ Duzy Chan:
+ This test addresses the usage of boost::optional<foo> as an ast node.
+=============================================================================*/
+#include <boost/detail/lightweight_test.hpp>
+#include <boost/spirit/home/x3.hpp>
+#include <boost/fusion/adapted/struct.hpp>
+#include <boost/fusion/include/vector.hpp>
+
+#include <iostream>
+#include "test.hpp"
+#include "utils.hpp"
+
+struct twoints
+{
+ int a;
+ int b;
+};
+
+struct adata
+{
+ twoints a;
+ boost::optional<twoints> b;
+ twoints c;
+};
+
+BOOST_FUSION_ADAPT_STRUCT(twoints, a, b)
+BOOST_FUSION_ADAPT_STRUCT(adata, a, b, c)
+
+int
+main()
+{
+ {
+ // Duzy Chan: This case addresses the usage of boost::optional<foo>
+ // as an ast node. Which should actually test the ability of
+ // boost::spirit::x3::traits::move_to to handle with optional source
+ // value.
+ boost::spirit::x3::rule<class twoints, adata> top = "top";
+ boost::spirit::x3::rule<class twoints, boost::optional<twoints>>
+ twoints = "twoints";
+
+ using boost::spirit::x3::int_;
+ auto const top_def = twoints >> ',' >> -twoints >> ',' >> twoints;
+ auto const twoints_def = int_ >> int_;
+
+ BOOST_SPIRIT_DEFINE(top, twoints);
+
+ twoints a, b;
+ BOOST_TEST((test_attr("1 2,3 4,5 6", top, a)));
+ BOOST_TEST((a.a.a == 1 && a.a.b == 2));
+ BOOST_TEST((a.b && a.b->a == 3 && a.b->b == 4));
+ BOOST_TEST((a.c.a == 5 && a.c.b == 6));
+
+ BOOST_TEST((test_attr("1 2,,5 6", top), b));
+ BOOST_TEST((b.a.a == 1 && b.a.b == 2));
+ BOOST_TEST((!a.b));
+ BOOST_TEST((b.c.a == 5 && b.c.b == 6));
+ }
+
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/spirit/test/x3/plus.cpp b/src/boost/libs/spirit/test/x3/plus.cpp
new file mode 100644
index 00000000..7e27c84b
--- /dev/null
+++ b/src/boost/libs/spirit/test/x3/plus.cpp
@@ -0,0 +1,140 @@
+/*=============================================================================
+ Copyright (c) 2001-2015 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)
+=============================================================================*/
+#include <string>
+#include <vector>
+
+#include <boost/detail/lightweight_test.hpp>
+#include <boost/spirit/home/x3.hpp>
+#include <boost/fusion/include/vector.hpp>
+
+#include <string>
+#include <iostream>
+#include "test.hpp"
+#include "utils.hpp"
+
+struct x_attr
+{
+};
+
+namespace boost { namespace spirit { namespace x3 { namespace traits
+{
+ template <>
+ struct container_value<x_attr>
+ {
+ typedef char type; // value type of container
+ };
+
+ template <>
+ struct push_back_container<x_attr>
+ {
+ static bool call(x_attr& /*c*/, char /*val*/)
+ {
+ // push back value type into container
+ return true;
+ }
+ };
+}}}}
+
+int
+main()
+{
+ using spirit_test::test;
+ using spirit_test::test_attr;
+ using boost::spirit::x3::char_;
+ using boost::spirit::x3::alpha;
+ using boost::spirit::x3::upper;
+ using boost::spirit::x3::space;
+ using boost::spirit::x3::digit;
+ //~ using boost::spirit::x3::no_case;
+ using boost::spirit::x3::int_;
+ using boost::spirit::x3::omit;
+ using boost::spirit::x3::lit;
+ //~ using boost::spirit::x3::_1;
+ using boost::spirit::x3::lexeme;
+
+ {
+ BOOST_TEST(test("aaaaaaaa", +char_));
+ BOOST_TEST(test("a", +char_));
+ BOOST_TEST(!test("", +char_));
+ BOOST_TEST(test("aaaaaaaa", +alpha));
+ BOOST_TEST(!test("aaaaaaaa", +upper));
+ }
+
+ {
+ BOOST_TEST(test(" a a aaa aa", +char_, space));
+ BOOST_TEST(test("12345 678 9 ", +digit, space));
+ }
+
+ //~ {
+ //~ BOOST_TEST(test("aBcdeFGH", no_case[+char_]));
+ //~ BOOST_TEST(test("a B cde FGH ", no_case[+char_], space));
+ //~ }
+
+ {
+ std::vector<int> v;
+ BOOST_TEST(test_attr("123 456 789 10", +int_, v, space) && 4 == v.size() &&
+ v[0] == 123 && v[1] == 456 && v[2] == 789 && v[3] == 10);
+ }
+
+ {
+ std::vector<std::string> v;
+ BOOST_TEST(test_attr("a b c d", +lexeme[+alpha], v, space) && 4 == v.size() &&
+ v[0] == "a" && v[1] == "b" && v[2] == "c" && v[3] == "d");
+ }
+
+ {
+ BOOST_TEST(test("Kim Kim Kim", +lit("Kim"), space));
+ }
+
+ // $$$ Fixme $$$
+ /*{
+ // The following 2 tests show that omit does not inhibit explicit attributes
+
+ std::string s;
+ BOOST_TEST(test_attr("bbbb", omit[+char_('b')], s) && s == "bbbb");
+
+ s.clear();
+ BOOST_TEST(test_attr("b b b b ", omit[+char_('b')], s, space) && s == "bbbb");
+ }*/
+
+ { // actions
+ std::string v;
+ auto f = [&](auto& ctx){ v = _attr(ctx); };
+
+ BOOST_TEST(test("bbbb", (+char_)[f]) && 4 == v.size() &&
+ v[0] == 'b' && v[1] == 'b' && v[2] == 'b' && v[3] == 'b');
+ }
+
+ { // more actions
+ std::vector<int> v;
+ auto f = [&](auto& ctx){ v = _attr(ctx); };
+
+ BOOST_TEST(test("1 2 3", (+int_)[f], space) && 3 == v.size() &&
+ v[0] == 1 && v[1] == 2 && v[2] == 3);
+ }
+
+ { // attribute customization
+
+ x_attr x;
+ test_attr("abcde", +char_, x);
+ }
+
+ // single-element fusion vector tests
+ {
+ boost::fusion::vector<std::string> fs;
+ BOOST_TEST((test_attr("12345", +char_, fs))); // ok
+ BOOST_TEST(boost::fusion::at_c<0>(fs) == "12345");
+ }
+
+ { // test move only types
+ std::vector<move_only> v;
+ BOOST_TEST(test_attr("sss", +synth_move_only, v));
+ BOOST_TEST_EQ(v.size(), 3);
+ }
+
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/spirit/test/x3/raw.cpp b/src/boost/libs/spirit/test/x3/raw.cpp
new file mode 100644
index 00000000..78f025dd
--- /dev/null
+++ b/src/boost/libs/spirit/test/x3/raw.cpp
@@ -0,0 +1,97 @@
+/*=============================================================================
+ 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)
+=============================================================================*/
+#include <boost/detail/lightweight_test.hpp>
+#include <boost/spirit/home/x3.hpp>
+#include <boost/fusion/include/std_pair.hpp>
+
+#include <iostream>
+#include <string>
+#include "test.hpp"
+
+int main()
+{
+ using spirit_test::test;
+ using spirit_test::test_attr;
+ using namespace boost::spirit::x3::ascii;
+ using boost::spirit::x3::raw;
+ using boost::spirit::x3::eps;
+ using boost::spirit::x3::lit;
+ using boost::spirit::x3::_attr;
+ using boost::spirit::x3::parse;
+ using boost::spirit::x3::int_;
+ using boost::spirit::x3::char_;
+
+ {
+ boost::iterator_range<char const*> range;
+ std::string str;
+ BOOST_TEST((test_attr("spirit_test_123", raw[alpha >> *(alnum | '_')], range)));
+ BOOST_TEST((std::string(range.begin(), range.end()) == "spirit_test_123"));
+ BOOST_TEST((test_attr(" spirit", raw[*alpha], range, space)));
+ BOOST_TEST((range.size() == 6));
+ }
+
+ {
+ std::string str;
+ BOOST_TEST((test_attr("spirit_test_123", raw[alpha >> *(alnum | '_')], str)));
+ BOOST_TEST((str == "spirit_test_123"));
+ }
+
+ {
+ boost::iterator_range<char const*> range;
+ BOOST_TEST((test("x", raw[alpha])));
+ BOOST_TEST((test_attr("x", raw[alpha], range)));
+ }
+
+ {
+ boost::iterator_range<char const*> range;
+ BOOST_TEST((test("x", raw[alpha][ ([&](auto& ctx){ range = _attr(ctx); }) ])));
+ BOOST_TEST(range.size() == 1 && *range.begin() == 'x');
+ }
+
+ {
+ boost::iterator_range<char const*> range;
+ BOOST_TEST((test("x123x", lit('x') >> raw[+digit] >> lit('x'))));
+ BOOST_TEST((test_attr("x123x", lit('x') >> raw[+digit] >> lit('x'), range)));
+ BOOST_TEST((std::string(range.begin(), range.end()) == "123"));
+ }
+
+ {
+ using range = boost::iterator_range<std::string::iterator>;
+ boost::variant<int, range> attr;
+
+ std::string str("test");
+ parse(str.begin(), str.end(), (int_ | raw[*char_]), attr);
+
+ auto rng = boost::get<range>(attr);
+ BOOST_TEST(std::string(rng.begin(), rng.end()) == "test");
+ }
+
+ {
+ std::vector<boost::iterator_range<std::string::iterator>> attr;
+ std::string str("123abcd");
+ parse(str.begin(), str.end()
+ , (raw[int_] >> raw[*char_])
+ , attr
+ );
+ BOOST_TEST(attr.size() == 2);
+ BOOST_TEST(std::string(attr[0].begin(), attr[0].end()) == "123");
+ BOOST_TEST(std::string(attr[1].begin(), attr[1].end()) == "abcd");
+ }
+
+ {
+ std::pair<int, boost::iterator_range<std::string::iterator>> attr;
+ std::string str("123abcd");
+ parse(str.begin(), str.end()
+ , (int_ >> raw[*char_])
+ , attr
+ );
+ BOOST_TEST(attr.first == 123);
+ BOOST_TEST(std::string(attr.second.begin(), attr.second.end()) == "abcd");
+ }
+
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/spirit/test/x3/real.hpp b/src/boost/libs/spirit/test/x3/real.hpp
new file mode 100644
index 00000000..7a680f73
--- /dev/null
+++ b/src/boost/libs/spirit/test/x3/real.hpp
@@ -0,0 +1,122 @@
+/*=============================================================================
+ Copyright (c) 2001-2010 Joel de Guzman
+ Copyright (c) 2001-2010 Hartmut Kaiser
+
+ Use, modification and distribution is subject to 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_TEST_X3_REAL_HPP)
+#define BOOST_SPIRIT_TEST_X3_REAL_HPP
+
+#include <climits>
+#include <boost/math/concepts/real_concept.hpp>
+#include <boost/detail/lightweight_test.hpp>
+#include <boost/spirit/home/x3/char.hpp>
+#include <boost/spirit/home/x3/numeric.hpp>
+#include <boost/spirit/home/x3/operator.hpp>
+#include <boost/math/special_functions/fpclassify.hpp>
+#include <boost/math/special_functions/sign.hpp>
+
+#include "test.hpp"
+
+///////////////////////////////////////////////////////////////////////////////
+// These policies can be used to parse thousand separated
+// numbers with at most 2 decimal digits after the decimal
+// point. e.g. 123,456,789.01
+///////////////////////////////////////////////////////////////////////////////
+template <typename T>
+struct ts_real_policies : boost::spirit::x3::ureal_policies<T>
+{
+ // 2 decimal places Max
+ template <typename Iterator, typename Attribute>
+ static bool
+ parse_frac_n(Iterator& first, Iterator const& last, Attribute& attr)
+ {
+ namespace x3 = boost::spirit::x3;
+ return boost::spirit::x3::extract_uint<T, 10, 1, 2, true>::call(first, last, attr);
+ }
+
+ // No exponent
+ template <typename Iterator>
+ static bool
+ parse_exp(Iterator&, Iterator const&)
+ {
+ return false;
+ }
+
+ // No exponent
+ template <typename Iterator, typename Attribute>
+ static bool
+ parse_exp_n(Iterator&, Iterator const&, Attribute&)
+ {
+ return false;
+ }
+
+ // Thousands separated numbers
+ template <typename Iterator, typename Accumulator>
+ static bool
+ parse_n(Iterator& first, Iterator const& last, Accumulator& result)
+ {
+ using boost::spirit::x3::uint_parser;
+ namespace x3 = boost::spirit::x3;
+
+ uint_parser<unsigned, 10, 1, 3> uint3;
+ uint_parser<unsigned, 10, 3, 3> uint3_3;
+
+ if (parse(first, last, uint3, result))
+ {
+ Accumulator n;
+ Iterator iter = first;
+
+ while (x3::parse(iter, last, ',') && x3::parse(iter, last, uint3_3, n))
+ {
+ result = result * 1000 + n;
+ first = iter;
+ }
+
+ return true;
+ }
+ return false;
+ }
+};
+
+template <typename T>
+struct no_trailing_dot_policy : boost::spirit::x3::real_policies<T>
+{
+ static bool const allow_trailing_dot = false;
+};
+
+template <typename T>
+struct no_leading_dot_policy : boost::spirit::x3::real_policies<T>
+{
+ static bool const allow_leading_dot = false;
+};
+
+template <typename T, typename T2>
+bool
+compare(T n, T2 expected)
+{
+ T const eps = std::pow(10.0, -std::numeric_limits<T>::digits10);
+ T delta = n - expected;
+ return (delta >= -eps) && (delta <= eps);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// A custom real type
+struct custom_real
+{
+ double n;
+ custom_real() : n(0) {}
+ custom_real(double n_) : n(n_) {}
+ friend bool operator==(custom_real a, custom_real b)
+ { return a.n == b.n; }
+ friend custom_real operator*(custom_real a, custom_real b)
+ { return custom_real(a.n * b.n); }
+ friend custom_real operator+(custom_real a, custom_real b)
+ { return custom_real(a.n + b.n); }
+ friend custom_real operator-(custom_real a, custom_real b)
+ { return custom_real(a.n - b.n); }
+};
+
+#endif
diff --git a/src/boost/libs/spirit/test/x3/real1.cpp b/src/boost/libs/spirit/test/x3/real1.cpp
new file mode 100644
index 00000000..f550a606
--- /dev/null
+++ b/src/boost/libs/spirit/test/x3/real1.cpp
@@ -0,0 +1,119 @@
+/*=============================================================================
+ Copyright (c) 2001-2015 Joel de Guzman
+ Copyright (c) 2001-2011 Hartmut Kaiser
+ Copyright (c) 2011 Bryce Lelbach
+
+ Use, modification and distribution is subject to 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)
+=============================================================================*/
+
+#include "real.hpp"
+
+int
+main()
+{
+ using spirit_test::test;
+ using spirit_test::test_attr;
+
+ ///////////////////////////////////////////////////////////////////////////
+ // thousand separated numbers
+ ///////////////////////////////////////////////////////////////////////////
+ {
+ using boost::spirit::x3::uint_parser;
+ using boost::spirit::x3::parse;
+
+ uint_parser<unsigned, 10, 1, 3> uint3;
+ uint_parser<unsigned, 10, 3, 3> uint3_3;
+
+ #define r (uint3 >> *(',' >> uint3_3))
+
+ BOOST_TEST(test("1,234,567,890", r));
+ BOOST_TEST(test("12,345,678,900", r));
+ BOOST_TEST(test("123,456,789,000", r));
+ BOOST_TEST(!test("1000,234,567,890", r));
+ BOOST_TEST(!test("1,234,56,890", r));
+ BOOST_TEST(!test("1,66", r));
+ }
+
+ ///////////////////////////////////////////////////////////////////////////
+ // unsigned real number tests
+ ///////////////////////////////////////////////////////////////////////////
+ {
+ using boost::spirit::x3::real_parser;
+ using boost::spirit::x3::parse;
+ using boost::spirit::x3::ureal_policies;
+
+ real_parser<double, ureal_policies<double> > udouble;
+ double d;
+
+ BOOST_TEST(test("1234", udouble));
+ BOOST_TEST(test_attr("1234", udouble, d) && compare(d, 1234));
+
+ BOOST_TEST(test("1.2e3", udouble));
+ BOOST_TEST(test_attr("1.2e3", udouble, d) && compare(d, 1.2e3));
+
+ BOOST_TEST(test("1.2e-3", udouble));
+ BOOST_TEST(test_attr("1.2e-3", udouble, d) && compare(d, 1.2e-3));
+
+ BOOST_TEST(test("1.e2", udouble));
+ BOOST_TEST(test_attr("1.e2", udouble, d) && compare(d, 1.e2));
+
+ BOOST_TEST(test("1.", udouble));
+ BOOST_TEST(test_attr("1.", udouble, d) && compare(d, 1.));
+
+ BOOST_TEST(test(".2e3", udouble));
+ BOOST_TEST(test_attr(".2e3", udouble, d) && compare(d, .2e3));
+
+ BOOST_TEST(test("2e3", udouble));
+ BOOST_TEST(test_attr("2e3", udouble, d) && compare(d, 2e3));
+
+ BOOST_TEST(test("2", udouble));
+ BOOST_TEST(test_attr("2", udouble, d) && compare(d, 2));
+
+ using boost::math::fpclassify;
+ BOOST_TEST(test("inf", udouble));
+ BOOST_TEST(test("infinity", udouble));
+ BOOST_TEST(test("INF", udouble));
+ BOOST_TEST(test("INFINITY", udouble));
+
+ BOOST_TEST(test_attr("inf", udouble, d)
+ && FP_INFINITE == fpclassify(d));
+ BOOST_TEST(test_attr("INF", udouble, d)
+ && FP_INFINITE == fpclassify(d));
+ BOOST_TEST(test_attr("infinity", udouble, d)
+ && FP_INFINITE == fpclassify(d));
+ BOOST_TEST(test_attr("INFINITY", udouble, d)
+ && FP_INFINITE == fpclassify(d));
+
+ BOOST_TEST(test("nan", udouble));
+ BOOST_TEST(test_attr("nan", udouble, d)
+ && FP_NAN == fpclassify(d));
+ BOOST_TEST(test("NAN", udouble));
+ BOOST_TEST(test_attr("NAN", udouble, d)
+ && FP_NAN == fpclassify(d));
+ BOOST_TEST(test("nan(...)", udouble));
+ BOOST_TEST(test_attr("nan(...)", udouble, d)
+ && FP_NAN == fpclassify(d));
+ BOOST_TEST(test("NAN(...)", udouble));
+ BOOST_TEST(test_attr("NAN(...)", udouble, d)
+ && FP_NAN == fpclassify(d));
+
+ BOOST_TEST(!test("e3", udouble));
+ BOOST_TEST(!test_attr("e3", udouble, d));
+
+ BOOST_TEST(!test("-1.2e3", udouble));
+ BOOST_TEST(!test_attr("-1.2e3", udouble, d));
+
+ BOOST_TEST(!test("+1.2e3", udouble));
+ BOOST_TEST(!test_attr("+1.2e3", udouble, d));
+
+ BOOST_TEST(!test("1.2e", udouble));
+ BOOST_TEST(!test_attr("1.2e", udouble, d));
+
+ BOOST_TEST(!test("-.3", udouble));
+ BOOST_TEST(!test_attr("-.3", udouble, d));
+ }
+
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/spirit/test/x3/real2.cpp b/src/boost/libs/spirit/test/x3/real2.cpp
new file mode 100644
index 00000000..dc003f0d
--- /dev/null
+++ b/src/boost/libs/spirit/test/x3/real2.cpp
@@ -0,0 +1,132 @@
+/*=============================================================================
+ Copyright (c) 2001-2015 Joel de Guzman
+ Copyright (c) 2001-2011 Hartmut Kaiser
+ Copyright (c) 2011 Bryce Lelbach
+
+ Use, modification and distribution is subject to 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)
+=============================================================================*/
+
+#include "real.hpp"
+
+template <typename T, typename P>
+void basic_real_parser_test(P parser)
+{
+ using spirit_test::test;
+ using spirit_test::test_attr;
+
+ T attr;
+
+ BOOST_TEST(test("-1234", parser));
+ BOOST_TEST(test_attr("-1234", parser, attr) && compare(attr, T(-1234l)));
+
+ BOOST_TEST(test("-1.2e3", parser));
+ BOOST_TEST(test_attr("-1.2e3", parser, attr) && compare(attr, T(-1.2e3l)));
+
+ BOOST_TEST(test("+1.2e3", parser));
+ BOOST_TEST(test_attr("+1.2e3", parser, attr) && compare(attr, T(1.2e3l)));
+
+ BOOST_TEST(test("-0.1", parser));
+ BOOST_TEST(test_attr("-0.1", parser, attr) && compare(attr, T(-0.1l)));
+
+ BOOST_TEST(test("-1.2e-3", parser));
+ BOOST_TEST(test_attr("-1.2e-3", parser, attr) && compare(attr, T(-1.2e-3l)));
+
+ BOOST_TEST(test("-1.e2", parser));
+ BOOST_TEST(test_attr("-1.e2", parser, attr) && compare(attr, T(-1.e2l)));
+
+ BOOST_TEST(test("-.2e3", parser));
+ BOOST_TEST(test_attr("-.2e3", parser, attr) && compare(attr, T(-.2e3l)));
+
+ BOOST_TEST(test("-2e3", parser));
+ BOOST_TEST(test_attr("-2e3", parser, attr) && compare(attr, T(-2e3l)));
+
+ BOOST_TEST(!test("-e3", parser));
+ BOOST_TEST(!test_attr("-e3", parser, attr));
+
+ BOOST_TEST(!test("-1.2e", parser));
+ BOOST_TEST(!test_attr("-1.2e", parser, attr));
+}
+
+int
+main()
+{
+ using spirit_test::test;
+ using spirit_test::test_attr;
+ ///////////////////////////////////////////////////////////////////////////
+ // signed real number tests
+ ///////////////////////////////////////////////////////////////////////////
+ {
+ basic_real_parser_test<float>(boost::spirit::x3::float_);
+ basic_real_parser_test<double>(boost::spirit::x3::double_);
+ basic_real_parser_test<long double>(boost::spirit::x3::long_double);
+ }
+
+ {
+ using boost::spirit::x3::double_;
+ double d;
+
+#if defined(BOOST_SPIRIT_TEST_REAL_PRECISION)
+ BOOST_TEST(test_attr("-5.7222349715140557e+307", double_, d));
+ BOOST_TEST(d == -5.7222349715140557e+307); // exact!
+
+ BOOST_TEST(test_attr("2.0332938517515416e-308", double_, d));
+ BOOST_TEST(d == 2.0332938517515416e-308); // exact!
+
+ BOOST_TEST(test_attr("20332938517515416e291", double_, d));
+ BOOST_TEST(d == 20332938517515416e291); // exact!
+
+ BOOST_TEST(test_attr("2.0332938517515416e307", double_, d));
+ BOOST_TEST(d == 2.0332938517515416e307); // exact!
+#endif
+
+ using boost::math::fpclassify;
+ using boost::spirit::x3::signbit; // Boost version is broken
+
+ BOOST_TEST(test("-inf", double_));
+ BOOST_TEST(test("-infinity", double_));
+ BOOST_TEST(test_attr("-inf", double_, d) &&
+ FP_INFINITE == fpclassify(d) && signbit(d));
+ BOOST_TEST(test_attr("-infinity", double_, d) &&
+ FP_INFINITE == fpclassify(d) && signbit(d));
+ BOOST_TEST(test("-INF", double_));
+ BOOST_TEST(test("-INFINITY", double_));
+ BOOST_TEST(test_attr("-INF", double_, d) &&
+ FP_INFINITE == fpclassify(d) && signbit(d));
+ BOOST_TEST(test_attr("-INFINITY", double_, d) &&
+ FP_INFINITE == fpclassify(d) && signbit(d));
+
+ BOOST_TEST(test("-nan", double_));
+ BOOST_TEST(test_attr("-nan", double_, d) &&
+ FP_NAN == fpclassify(d) && signbit(d));
+ BOOST_TEST(test("-NAN", double_));
+ BOOST_TEST(test_attr("-NAN", double_, d) &&
+ FP_NAN == fpclassify(d) && signbit(d));
+
+ BOOST_TEST(test("-nan(...)", double_));
+ BOOST_TEST(test_attr("-nan(...)", double_, d) &&
+ FP_NAN == fpclassify(d) && signbit(d));
+ BOOST_TEST(test("-NAN(...)", double_));
+ BOOST_TEST(test_attr("-NAN(...)", double_, d) &&
+ FP_NAN == fpclassify(d) && signbit(d));
+
+ BOOST_TEST(!test("1e999", double_));
+ BOOST_TEST(!test("1e-999", double_));
+ BOOST_TEST(test_attr("2.1111111e-303", double_, d) &&
+ compare(d, 2.1111111e-303));
+ BOOST_TEST(!test_attr("1.1234e", double_, d) && compare(d, 1.1234));
+
+ // https://svn.boost.org/trac10/ticket/11608
+ BOOST_TEST(test_attr("1267650600228229401496703205376", double_, d) &&
+ compare(d, 1.2676506002282291E+30)); // Note Qi has better precision
+
+ BOOST_TEST(test_attr("12676506.00228229401496703205376", double_, d) &&
+ compare(d, 1.2676506002282292E7)); // Note Qi has better precision
+
+ BOOST_TEST(test_attr("12676506.00228229401496703205376E6", double_, d) &&
+ compare(d, 1.2676506002282291016E13)); // Note Qi has better precision
+ }
+
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/spirit/test/x3/real3.cpp b/src/boost/libs/spirit/test/x3/real3.cpp
new file mode 100644
index 00000000..09e11ad9
--- /dev/null
+++ b/src/boost/libs/spirit/test/x3/real3.cpp
@@ -0,0 +1,85 @@
+/*=============================================================================
+ Copyright (c) 2001-2015 Joel de Guzman
+ Copyright (c) 2001-2010 Hartmut Kaiser
+
+ Use, modification and distribution is subject to 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)
+=============================================================================*/
+
+#include "real.hpp"
+
+int
+main()
+{
+ using spirit_test::test;
+ using spirit_test::test_attr;
+
+ ///////////////////////////////////////////////////////////////////////////
+ // strict real number tests
+ ///////////////////////////////////////////////////////////////////////////
+ {
+ using boost::spirit::x3::real_parser;
+ using boost::spirit::x3::parse;
+ using boost::spirit::x3::strict_ureal_policies;
+ using boost::spirit::x3::strict_real_policies;
+
+ real_parser<double, strict_ureal_policies<double> > strict_udouble;
+ real_parser<double, strict_real_policies<double> > strict_double;
+ double d;
+
+ BOOST_TEST(!test("1234", strict_udouble));
+ BOOST_TEST(!test_attr("1234", strict_udouble, d));
+
+ BOOST_TEST(test("1.2", strict_udouble));
+ BOOST_TEST(test_attr("1.2", strict_udouble, d) && compare(d, 1.2));
+
+ BOOST_TEST(!test("-1234", strict_double));
+ BOOST_TEST(!test_attr("-1234", strict_double, d));
+
+ BOOST_TEST(test("123.", strict_double));
+ BOOST_TEST(test_attr("123.", strict_double, d) && compare(d, 123));
+
+ BOOST_TEST(test("3.E6", strict_double));
+ BOOST_TEST(test_attr("3.E6", strict_double, d) && compare(d, 3e6));
+
+ real_parser<double, no_trailing_dot_policy<double> > notrdot_real;
+ real_parser<double, no_leading_dot_policy<double> > nolddot_real;
+
+ BOOST_TEST(!test("1234.", notrdot_real)); // Bad trailing dot
+ BOOST_TEST(!test(".1234", nolddot_real)); // Bad leading dot
+ }
+
+ ///////////////////////////////////////////////////////////////////////////
+ // Special thousands separated numbers
+ ///////////////////////////////////////////////////////////////////////////
+ {
+ using boost::spirit::x3::real_parser;
+ using boost::spirit::x3::parse;
+ real_parser<double, ts_real_policies<double> > ts_real;
+ double d;
+
+ BOOST_TEST(test("123.01", ts_real));
+ BOOST_TEST(test_attr("123.01", ts_real, d)
+ && compare(d, 123.01));
+
+ BOOST_TEST(test("123,456,789.01", ts_real));
+ BOOST_TEST(test_attr("123,456,789.01", ts_real, d)
+ && compare(d, 123456789.01));
+
+ BOOST_TEST(test("12,345,678.90", ts_real));
+ BOOST_TEST(test_attr("12,345,678.90", ts_real, d)
+ && compare(d, 12345678.90));
+
+ BOOST_TEST(test("1,234,567.89", ts_real));
+ BOOST_TEST(test_attr("1,234,567.89", ts_real, d)
+ && compare(d, 1234567.89));
+
+ BOOST_TEST(!test("1234,567,890", ts_real));
+ BOOST_TEST(!test("1,234,5678,9", ts_real));
+ BOOST_TEST(!test("1,234,567.89e6", ts_real));
+ BOOST_TEST(!test("1,66", ts_real));
+ }
+
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/spirit/test/x3/real4.cpp b/src/boost/libs/spirit/test/x3/real4.cpp
new file mode 100644
index 00000000..0b668c75
--- /dev/null
+++ b/src/boost/libs/spirit/test/x3/real4.cpp
@@ -0,0 +1,73 @@
+/*=============================================================================
+ Copyright (c) 2001-2015 Joel de Guzman
+ Copyright (c) 2001-2011 Hartmut Kaiser
+ Copyright (c) 2011 Bryce Lelbach
+
+ Use, modification and distribution is subject to 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)
+=============================================================================*/
+
+#include "real.hpp"
+
+int
+main()
+{
+ using spirit_test::test;
+ using spirit_test::test_attr;
+
+ ///////////////////////////////////////////////////////////////////////////
+ // Custom data type
+ ///////////////////////////////////////////////////////////////////////////
+ {
+ using boost::math::concepts::real_concept;
+ using boost::spirit::x3::real_parser;
+ using boost::spirit::x3::real_policies;
+ using boost::spirit::x3::parse;
+
+ real_parser<real_concept, real_policies<real_concept> > custom_real;
+ real_concept d;
+
+ BOOST_TEST(test("-1234", custom_real));
+ BOOST_TEST(test_attr("-1234", custom_real, d) && compare(d, -1234));
+
+ BOOST_TEST(test("-1.2e3", custom_real));
+ BOOST_TEST(test_attr("-1.2e3", custom_real, d) && compare(d, -1.2e3));
+
+ BOOST_TEST(test("+1.2e3", custom_real));
+ BOOST_TEST(test_attr("+1.2e3", custom_real, d) && compare(d, 1.2e3));
+
+ BOOST_TEST(test("-0.1", custom_real));
+ BOOST_TEST(test_attr("-0.1", custom_real, d) && compare(d, -0.1));
+
+ BOOST_TEST(test("-1.2e-3", custom_real));
+ BOOST_TEST(test_attr("-1.2e-3", custom_real, d) && compare(d, -1.2e-3));
+
+ BOOST_TEST(test("-1.e2", custom_real));
+ BOOST_TEST(test_attr("-1.e2", custom_real, d) && compare(d, -1.e2));
+
+ BOOST_TEST(test("-.2e3", custom_real));
+ BOOST_TEST(test_attr("-.2e3", custom_real, d) && compare(d, -.2e3));
+
+ BOOST_TEST(test("-2e3", custom_real));
+ BOOST_TEST(test_attr("-2e3", custom_real, d) && compare(d, -2e3));
+
+ BOOST_TEST(!test("-e3", custom_real));
+ BOOST_TEST(!test_attr("-e3", custom_real, d));
+
+ BOOST_TEST(!test("-1.2e", custom_real));
+ BOOST_TEST(!test_attr("-1.2e", custom_real, d));
+ }
+
+ ///////////////////////////////////////////////////////////////////////////
+ // custom real tests
+ ///////////////////////////////////////////////////////////////////////////
+ {
+ using boost::spirit::x3::double_;
+ custom_real n;
+
+ BOOST_TEST(test_attr("-123456e6", double_, n));
+ }
+
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/spirit/test/x3/repeat.cpp b/src/boost/libs/spirit/test/x3/repeat.cpp
new file mode 100644
index 00000000..99c080fe
--- /dev/null
+++ b/src/boost/libs/spirit/test/x3/repeat.cpp
@@ -0,0 +1,152 @@
+/*=============================================================================
+ Copyright (c) 2001-2011 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)
+=============================================================================*/
+#include <string>
+#include <vector>
+
+#include <boost/detail/lightweight_test.hpp>
+#include <boost/utility/enable_if.hpp>
+
+#include <boost/spirit/home/x3.hpp>
+#include <string>
+#include <iostream>
+#include "test.hpp"
+#include "utils.hpp"
+
+int
+main()
+{
+ using spirit_test::test_attr;
+ using spirit_test::test;
+
+ using namespace boost::spirit::x3::ascii;
+ using boost::spirit::x3::repeat;
+ using boost::spirit::x3::inf;
+ using boost::spirit::x3::omit;
+ using boost::spirit::x3::int_;
+ using boost::spirit::x3::lexeme;
+ using boost::spirit::x3::char_;
+ {
+ BOOST_TEST(test("aaaaaaaa", repeat[char_])); // kleene synonym
+ BOOST_TEST(test("aaaaaaaa", repeat(8)[char_]));
+ BOOST_TEST(!test("aa", repeat(3)[char_]));
+ BOOST_TEST(test("aaa", repeat(3, 5)[char_]));
+ BOOST_TEST(test("aaaaa", repeat(3, 5)[char_]));
+ BOOST_TEST(!test("aaaaaa", repeat(3, 5)[char_]));
+ BOOST_TEST(!test("aa", repeat(3, 5)[char_]));
+
+ BOOST_TEST(test("aaa", repeat(3, inf)[char_]));
+ BOOST_TEST(test("aaaaa", repeat(3, inf)[char_]));
+ BOOST_TEST(test("aaaaaa", repeat(3, inf)[char_]));
+ BOOST_TEST(!test("aa", repeat(3, inf)[char_]));
+ }
+ {
+ std::string s;
+ BOOST_TEST(test_attr("aaaaaaaa", repeat[char_ >> char_], s)); // kleene synonym
+ BOOST_TEST(s == "aaaaaaaa");
+
+ s.clear();
+ BOOST_TEST(test_attr("aaaaaaaa", repeat(4)[char_ >> char_], s));
+ BOOST_TEST(s == "aaaaaaaa");
+
+ BOOST_TEST(!test("aa", repeat(3)[char_ >> char_]));
+ BOOST_TEST(!test("a", repeat(1)[char_ >> char_]));
+
+ s.clear();
+ BOOST_TEST(test_attr("aa", repeat(1, 3)[char_ >> char_], s));
+ BOOST_TEST(s == "aa");
+
+ s.clear();
+ BOOST_TEST(test_attr("aaaaaa", repeat(1, 3)[char_ >> char_], s));
+ BOOST_TEST(s == "aaaaaa");
+
+ BOOST_TEST(!test("aaaaaaa", repeat(1, 3)[char_ >> char_]));
+ BOOST_TEST(!test("a", repeat(1, 3)[char_ >> char_]));
+
+ s.clear();
+ BOOST_TEST(test_attr("aaaa", repeat(2, inf)[char_ >> char_], s));
+ BOOST_TEST(s == "aaaa");
+
+ s.clear();
+ BOOST_TEST(test_attr("aaaaaa", repeat(2, inf)[char_ >> char_], s));
+ BOOST_TEST(s == "aaaaaa");
+
+ BOOST_TEST(!test("aa", repeat(2, inf)[char_ >> char_]));
+ }
+
+ { // from classic spirit tests
+ BOOST_TEST(test("", repeat(0, inf)['x']));
+
+ // repeat exact 8
+ #define rep8 repeat(8)[alpha] >> 'X'
+ BOOST_TEST(!test("abcdefgX", rep8, false));
+ BOOST_TEST(test("abcdefghX", rep8));
+ BOOST_TEST(!test("abcdefghiX", rep8, false));
+ BOOST_TEST(!test("abcdefgX", rep8, false));
+ BOOST_TEST(!test("aX", rep8, false));
+
+ // repeat 2 to 8
+ #define rep28 repeat(2, 8)[alpha] >> '*'
+ BOOST_TEST(test("abcdefg*", rep28));
+ BOOST_TEST(test("abcdefgh*", rep28));
+ BOOST_TEST(!test("abcdefghi*", rep28, false));
+ BOOST_TEST(!test("a*", rep28, false));
+
+ // repeat 2 or more
+ #define rep2_ repeat(2, inf)[alpha] >> '+'
+ BOOST_TEST(test("abcdefg+", rep2_));
+ BOOST_TEST(test("abcdefgh+", rep2_));
+ BOOST_TEST(test("abcdefghi+", rep2_));
+ BOOST_TEST(test("abcdefg+", rep2_));
+ BOOST_TEST(!test("a+", rep2_, false));
+
+ // repeat 0
+ #define rep0 repeat(0)[alpha] >> '/'
+ BOOST_TEST(test("/", rep0));
+ BOOST_TEST(!test("a/", rep0, false));
+
+ // repeat 0 or 1
+ #define rep01 repeat(0, 1)[alpha >> digit] >> '?'
+ BOOST_TEST(!test("abcdefg?", rep01, false));
+ BOOST_TEST(!test("a?", rep01, false));
+ BOOST_TEST(!test("1?", rep01, false));
+ BOOST_TEST(!test("11?", rep01, false));
+ BOOST_TEST(!test("aa?", rep01, false));
+ BOOST_TEST(test("?", rep01));
+ BOOST_TEST(test("a1?", rep01));
+ }
+
+ {
+ BOOST_TEST(test(" a a aaa aa", repeat(7)[char_], space));
+ BOOST_TEST(test("12345 678 9", repeat(9)[digit], space));
+ }
+
+ {
+ std::vector<std::string> v;
+ BOOST_TEST(test_attr("a b c d", repeat(4)[lexeme[+alpha]], v, space) && 4 == v.size() &&
+ v[0] == "a" && v[1] == "b" && v[2] == "c" && v[3] == "d");
+ }
+ {
+ BOOST_TEST(test("1 2 3", int_ >> repeat(2)[int_], space));
+ BOOST_TEST(!test("1 2", int_ >> repeat(2)[int_], space));
+ }
+
+ {
+ std::vector<char> v;
+ BOOST_TEST(test_attr("1 2 3", int_ >> repeat(2)[int_], v, space));
+ BOOST_TEST(v.size() == 3 && v[0] == 1 && v[1] == 2 && v[2] == 3);
+
+ BOOST_TEST(!test("1 2", int_ >> repeat(2)[int_], space));
+ }
+
+ { // test move only types
+ std::vector<move_only> v;
+ BOOST_TEST(test_attr("sss", repeat(3)[synth_move_only], v));
+ BOOST_TEST_EQ(v.size(), 3);
+ }
+
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/spirit/test/x3/rule1.cpp b/src/boost/libs/spirit/test/x3/rule1.cpp
new file mode 100644
index 00000000..09941dec
--- /dev/null
+++ b/src/boost/libs/spirit/test/x3/rule1.cpp
@@ -0,0 +1,129 @@
+/*=============================================================================
+ Copyright (c) 2001-2015 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)
+=============================================================================*/
+
+#include <boost/detail/lightweight_test.hpp>
+#include <boost/spirit/home/x3.hpp>
+
+#include <string>
+#include <cstring>
+#include <iostream>
+#include "test.hpp"
+
+int
+main()
+{
+ using spirit_test::test_attr;
+ using spirit_test::test;
+
+ using namespace boost::spirit::x3::ascii;
+ using boost::spirit::x3::rule;
+ using boost::spirit::x3::lit;
+ using boost::spirit::x3::int_;
+ using boost::spirit::x3::unused_type;
+ using boost::spirit::x3::phrase_parse;
+ using boost::spirit::x3::skip_flag;
+ using boost::spirit::x3::traits::has_attribute;
+
+ // check attribute advertising
+ static_assert( has_attribute<rule<class r, int>, /*Context=*/unused_type>::value, "");
+ static_assert(!has_attribute<rule<class r >, /*Context=*/unused_type>::value, "");
+ static_assert( has_attribute<decltype(rule<class r, int>{} = int_), /*Context=*/unused_type>::value, "");
+ static_assert(!has_attribute<decltype(rule<class r >{} = int_), /*Context=*/unused_type>::value, "");
+
+
+ { // basic tests
+
+ auto a = lit('a');
+ auto b = lit('b');
+ auto c = lit('c');
+ rule<class r> r;
+
+ {
+ auto start =
+ r = *(a | b | c);
+
+ BOOST_TEST(test("abcabcacb", start));
+ }
+
+ {
+ auto start =
+ r = (a | b) >> (r | b);
+
+ BOOST_TEST(test("aaaabababaaabbb", start));
+ BOOST_TEST(test("aaaabababaaabba", start, false));
+
+ // ignore the skipper!
+ BOOST_TEST(test("aaaabababaaabba", start, space, false));
+ }
+ }
+
+ { // basic tests w/ skipper
+
+ auto a = lit('a');
+ auto b = lit('b');
+ auto c = lit('c');
+ rule<class r> r;
+
+ {
+ auto start =
+ r = *(a | b | c);
+
+ BOOST_TEST(test(" a b c a b c a c b ", start, space));
+ }
+
+ {
+ auto start =
+ r = (a | b) >> (r | b);
+
+ BOOST_TEST(test(" a a a a b a b a b a a a b b b ", start, space));
+ BOOST_TEST(test(" a a a a b a b a b a a a b b a ", start, space, false));
+ }
+ }
+
+ { // basic tests w/ skipper but no final post-skip
+
+ auto a = rule<class a>()
+ = lit('a');
+
+ auto b = rule<class b>()
+ = lit('b');
+
+ auto c = rule<class c>()
+ = lit('c');
+
+ {
+ auto start = rule<class start>() = *(a | b) >> c;
+
+ char const *s1 = " a b a a b b a c ... "
+ , *const e1 = s1 + std::strlen(s1);
+ BOOST_TEST(phrase_parse(s1, e1, start, space, skip_flag::dont_post_skip)
+ && s1 == e1 - 5);
+
+ }
+
+ {
+ rule<class start> start;
+
+ auto p =
+ start = (a | b) >> (start | c);
+ {
+ char const *s1 = " a a a a b a b a b a a a b b b c "
+ , *const e1 = s1 + std::strlen(s1);
+ BOOST_TEST(phrase_parse(s1, e1, p, space, skip_flag::post_skip)
+ && s1 == e1);
+ }
+ {
+ char const *s1 = " a a a a b a b a b a a a b b b c "
+ , *const e1 = s1 + std::strlen(s1);
+ BOOST_TEST(phrase_parse(s1, e1, p, space, skip_flag::dont_post_skip)
+ && s1 == e1 - 1);
+ }
+ }
+ }
+
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/spirit/test/x3/rule2.cpp b/src/boost/libs/spirit/test/x3/rule2.cpp
new file mode 100644
index 00000000..fd6c07fa
--- /dev/null
+++ b/src/boost/libs/spirit/test/x3/rule2.cpp
@@ -0,0 +1,108 @@
+/*=============================================================================
+ Copyright (c) 2001-2015 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)
+=============================================================================*/
+
+#include <boost/detail/lightweight_test.hpp>
+#include <boost/spirit/home/x3.hpp>
+
+#include <string>
+#include <cstring>
+#include <iostream>
+#include "test.hpp"
+
+int
+main()
+{
+ using spirit_test::test_attr;
+ using spirit_test::test;
+
+ using namespace boost::spirit::x3::ascii;
+ using boost::spirit::x3::rule;
+ using boost::spirit::x3::lit;
+ using boost::spirit::x3::unused_type;
+ using boost::spirit::x3::_attr;
+
+ { // context tests
+
+ char ch;
+ auto a = rule<class a, char>() = alpha;
+
+ // this semantic action requires the context
+ auto f = [&](auto& ctx){ ch = _attr(ctx); };
+ BOOST_TEST(test("x", a[f]));
+ BOOST_TEST(ch == 'x');
+
+ // this semantic action requires the (unused) context
+ auto f2 = [&](auto&){ ch = 'y'; };
+ BOOST_TEST(test("x", a[f2]));
+ BOOST_TEST(ch == 'y');
+
+ // the semantic action may optionally not have any arguments at all
+ auto f3 = [&]{ ch = 'z'; };
+ BOOST_TEST(test("x", a[f3]));
+ BOOST_TEST(ch == 'z');
+
+ BOOST_TEST(test_attr("z", a, ch)); // attribute is given.
+ BOOST_TEST(ch == 'z');
+ }
+
+ { // auto rules tests
+
+ char ch = '\0';
+ auto a = rule<class a, char>() = alpha;
+ auto f = [&](auto& ctx){ ch = _attr(ctx); };
+
+ BOOST_TEST(test("x", a[f]));
+ BOOST_TEST(ch == 'x');
+ ch = '\0';
+ BOOST_TEST(test_attr("z", a, ch)); // attribute is given.
+ BOOST_TEST(ch == 'z');
+
+ ch = '\0';
+ BOOST_TEST(test("x", a[f]));
+ BOOST_TEST(ch == 'x');
+ ch = '\0';
+ BOOST_TEST(test_attr("z", a, ch)); // attribute is given.
+ BOOST_TEST(ch == 'z');
+ }
+
+ { // auto rules tests: allow stl containers as attributes to
+ // sequences (in cases where attributes of the elements
+ // are convertible to the value_type of the container or if
+ // the element itself is an stl container with value_type
+ // that is convertible to the value_type of the attribute).
+
+ std::string s;
+ auto f = [&](auto& ctx){ s = _attr(ctx); };
+
+ {
+ auto r = rule<class r, std::string>()
+ = char_ >> *(',' >> char_)
+ ;
+
+ BOOST_TEST(test("a,b,c,d,e,f", r[f]));
+ BOOST_TEST(s == "abcdef");
+ }
+
+ {
+ auto r = rule<class r, std::string>()
+ = char_ >> *(',' >> char_);
+ s.clear();
+ BOOST_TEST(test("a,b,c,d,e,f", r[f]));
+ BOOST_TEST(s == "abcdef");
+ }
+
+ {
+ auto r = rule<class r, std::string>()
+ = char_ >> char_ >> char_ >> char_ >> char_ >> char_;
+ s.clear();
+ BOOST_TEST(test("abcdef", r[f]));
+ BOOST_TEST(s == "abcdef");
+ }
+ }
+
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/spirit/test/x3/rule3.cpp b/src/boost/libs/spirit/test/x3/rule3.cpp
new file mode 100644
index 00000000..420146c0
--- /dev/null
+++ b/src/boost/libs/spirit/test/x3/rule3.cpp
@@ -0,0 +1,109 @@
+/*=============================================================================
+ Copyright (c) 2001-2012 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)
+=============================================================================*/
+
+#include <boost/detail/lightweight_test.hpp>
+#include <boost/spirit/home/x3.hpp>
+#include <boost/fusion/include/std_pair.hpp>
+
+#include <string>
+#include <cstring>
+#include <iostream>
+#include "test.hpp"
+
+using boost::spirit::x3::_val;
+
+struct f
+{
+ template <typename Context>
+ void operator()(Context const& ctx) const
+ {
+ _val(ctx) += _attr(ctx);
+ }
+};
+
+
+struct stationary : boost::noncopyable
+{
+ explicit stationary(int i) : val{i} {}
+ stationary& operator=(int i) { val = i; return *this; }
+
+ int val;
+};
+
+
+namespace check_stationary {
+
+boost::spirit::x3::rule<class a_r, stationary> const a;
+boost::spirit::x3::rule<class b_r, stationary> const b;
+
+auto const a_def = '{' >> boost::spirit::x3::int_ >> '}';
+auto const b_def = a;
+
+BOOST_SPIRIT_DEFINE(a, b)
+
+}
+
+
+int main()
+{
+ using spirit_test::test_attr;
+ using spirit_test::test;
+
+ using namespace boost::spirit::x3::ascii;
+ using boost::spirit::x3::rule;
+ using boost::spirit::x3::lit;
+ using boost::spirit::x3::eps;
+ using boost::spirit::x3::unused_type;
+
+
+ { // synth attribute value-init
+
+ std::string s;
+ typedef rule<class r, std::string> rule_type;
+
+ auto rdef = rule_type()
+ = alpha [f()]
+ ;
+
+ BOOST_TEST(test_attr("abcdef", +rdef, s));
+ BOOST_TEST(s == "abcdef");
+ }
+
+ { // synth attribute value-init
+
+ std::string s;
+ typedef rule<class r, std::string> rule_type;
+
+ auto rdef = rule_type() =
+ alpha /
+ [](auto& ctx)
+ {
+ _val(ctx) += _attr(ctx);
+ }
+ ;
+
+ BOOST_TEST(test_attr("abcdef", +rdef, s));
+ BOOST_TEST(s == "abcdef");
+ }
+
+ {
+ auto r = rule<class r, int>{} = eps[([] (auto& ctx) {
+ using boost::spirit::x3::_val;
+ static_assert(std::is_same<std::decay_t<decltype(_val(ctx))>, unused_type>::value,
+ "Attribute must not be synthesized");
+ })];
+ BOOST_TEST(test("", r));
+ }
+
+ { // ensure no unneded synthesization, copying and moving occured
+ stationary st { 0 };
+ BOOST_TEST(test_attr("{42}", check_stationary::b, st));
+ BOOST_TEST_EQ(st.val, 42);
+ }
+
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/spirit/test/x3/rule4.cpp b/src/boost/libs/spirit/test/x3/rule4.cpp
new file mode 100644
index 00000000..3e3a647d
--- /dev/null
+++ b/src/boost/libs/spirit/test/x3/rule4.cpp
@@ -0,0 +1,164 @@
+/*=============================================================================
+ Copyright (c) 2001-2015 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)
+=============================================================================*/
+
+#include <boost/detail/lightweight_test.hpp>
+#include <boost/spirit/home/x3.hpp>
+#include <boost/fusion/include/vector.hpp>
+#include <boost/fusion/include/at.hpp>
+
+#include <string>
+#include <cstring>
+#include <iostream>
+#include "test.hpp"
+
+namespace x3 = boost::spirit::x3;
+
+int got_it = 0;
+
+struct my_rule_class
+{
+ template <typename Iterator, typename Exception, typename Context>
+ x3::error_handler_result
+ on_error(Iterator&, Iterator const& last, Exception const& x, Context const&)
+ {
+ std::cout
+ << "Error! Expecting: "
+ << x.which()
+ << ", got: \""
+ << std::string(x.where(), last)
+ << "\""
+ << std::endl
+ ;
+ return x3::error_handler_result::fail;
+ }
+
+ template <typename Iterator, typename Attribute, typename Context>
+ inline void
+ on_success(Iterator const&, Iterator const&, Attribute&, Context const&)
+ {
+ ++got_it;
+ }
+};
+
+int
+main()
+{
+ using spirit_test::test_attr;
+ using spirit_test::test;
+
+ using namespace boost::spirit::x3::ascii;
+ using boost::spirit::x3::rule;
+ using boost::spirit::x3::int_;
+ using boost::spirit::x3::lit;
+
+ { // show that ra = rb and ra %= rb works as expected
+ rule<class a, int> ra;
+ rule<class b, int> rb;
+ int attr;
+
+ auto ra_def = (ra %= int_);
+ BOOST_TEST(test_attr("123", ra_def, attr));
+ BOOST_TEST(attr == 123);
+
+ auto rb_def = (rb %= ra_def);
+ BOOST_TEST(test_attr("123", rb_def, attr));
+ BOOST_TEST(attr == 123);
+
+ auto rb_def2 = (rb = ra_def);
+ BOOST_TEST(test_attr("123", rb_def2, attr));
+ BOOST_TEST(attr == 123);
+ }
+
+ { // show that ra %= rb works as expected with semantic actions
+ rule<class a, int> ra;
+ rule<class b, int> rb;
+ int attr;
+
+ auto f = [](auto&){};
+ auto ra_def = (ra %= int_[f]);
+ BOOST_TEST(test_attr("123", ra_def, attr));
+ BOOST_TEST(attr == 123);
+
+ auto ra_def2 = (rb = (ra %= int_[f]));
+ BOOST_TEST(test_attr("123", ra_def2, attr));
+ BOOST_TEST(attr == 123);
+ }
+
+
+ { // std::string as container attribute with auto rules
+
+ std::string attr;
+
+ // test deduced auto rule behavior
+
+ auto text = rule<class text, std::string>()
+ = +(!char_(')') >> !char_('>') >> char_);
+
+ attr.clear();
+ BOOST_TEST(test_attr("x", text, attr));
+ BOOST_TEST(attr == "x");
+ }
+
+ { // error handling
+
+ auto r = rule<my_rule_class, char const*>()
+ = '(' > int_ > ',' > int_ > ')';
+
+ BOOST_TEST(test("(123,456)", r));
+ BOOST_TEST(!test("(abc,def)", r));
+ BOOST_TEST(!test("(123,456]", r));
+ BOOST_TEST(!test("(123;456)", r));
+ BOOST_TEST(!test("[123,456]", r));
+
+ BOOST_TEST(got_it == 1);
+ }
+
+ {
+ typedef boost::variant<double, int> v_type;
+ auto r1 = rule<class r1, v_type>()
+ = int_;
+ v_type v;
+ BOOST_TEST(test_attr("1", r1, v) && v.which() == 1 &&
+ boost::get<int>(v) == 1);
+
+ typedef boost::optional<int> ov_type;
+ auto r2 = rule<class r2, ov_type>()
+ = int_;
+ ov_type ov;
+ BOOST_TEST(test_attr("1", r2, ov) && ov && boost::get<int>(ov) == 1);
+ }
+
+ // test handling of single element fusion sequences
+ {
+ using boost::fusion::vector;
+ using boost::fusion::at_c;
+ auto r = rule<class r, vector<int>>()
+ = int_;
+
+ vector<int> v(0);
+ BOOST_TEST(test_attr("1", r, v) && at_c<0>(v) == 1);
+ }
+
+ { // attribute compatibility test
+ using boost::spirit::x3::rule;
+ using boost::spirit::x3::int_;
+
+ auto const expr = int_;
+
+ short i;
+ BOOST_TEST(test_attr("1", expr, i) && i == 1); // ok
+
+ const rule< class int_rule, int > int_rule( "int_rule" );
+ auto const int_rule_def = int_;
+ auto const start = int_rule = int_rule_def;
+
+ short j;
+ BOOST_TEST(test_attr("1", start, j) && j == 1); // error
+ }
+
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/spirit/test/x3/rule_separate_tu.cpp b/src/boost/libs/spirit/test/x3/rule_separate_tu.cpp
new file mode 100644
index 00000000..c3fcb29e
--- /dev/null
+++ b/src/boost/libs/spirit/test/x3/rule_separate_tu.cpp
@@ -0,0 +1,71 @@
+/*=============================================================================
+ Copyright (c) 2019 Nikita Kniazev
+
+ Use, modification and distribution is subject to 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)
+=============================================================================*/
+
+#include "rule_separate_tu_grammar.hpp"
+
+#include <boost/core/lightweight_test.hpp>
+
+#include "test.hpp"
+
+namespace sem_act {
+
+namespace x3 = boost::spirit::x3;
+
+auto nop = [](auto const&){};
+
+x3::rule<class used_attr1_r, int> used_attr1;
+auto const used_attr1_def = used_attr::grammar[nop];
+BOOST_SPIRIT_DEFINE(used_attr1);
+
+x3::rule<class used_attr2_r, int> used_attr2;
+auto const used_attr2_def = unused_attr::grammar[nop];
+BOOST_SPIRIT_DEFINE(used_attr2);
+
+x3::rule<class unused_attr1_r> unused_attr1;
+auto const unused_attr1_def = used_attr::grammar[nop];
+BOOST_SPIRIT_DEFINE(unused_attr1);
+
+x3::rule<class unused_attr2_r> unused_attr2;
+auto const unused_attr2_def = unused_attr::grammar[nop];
+BOOST_SPIRIT_DEFINE(unused_attr2);
+
+}
+
+int main()
+{
+ using spirit_test::test;
+ using spirit_test::test_attr;
+
+ {
+ BOOST_TEST(test("*", unused_attr::skipper));
+ BOOST_TEST(test("#", unused_attr::skipper2));
+ BOOST_TEST(test("==", unused_attr::grammar));
+ BOOST_TEST(test("*=*=", unused_attr::grammar, unused_attr::skipper));
+ BOOST_TEST(test("#=#=", unused_attr::grammar, unused_attr::skipper2));
+ }
+
+ {
+ long i;
+ static_assert(!std::is_same<decltype(i), used_attr::grammar_type::attribute_type>::value,
+ "ensure we have instantiated the rule with a different attribute type");
+ BOOST_TEST(test_attr("123", used_attr::grammar, i));
+ BOOST_TEST_EQ(i, 123);
+ BOOST_TEST(test_attr(" 42", used_attr::grammar, i, used_attr::skipper));
+ BOOST_TEST_EQ(i, 42);
+ }
+
+ {
+ long i;
+ BOOST_TEST(test_attr("123", sem_act::used_attr1, i));
+ BOOST_TEST(test_attr("===", sem_act::used_attr2, i));
+ BOOST_TEST(test("123", sem_act::unused_attr1));
+ BOOST_TEST(test("===", sem_act::unused_attr2));
+ }
+
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/spirit/test/x3/rule_separate_tu_grammar.cpp b/src/boost/libs/spirit/test/x3/rule_separate_tu_grammar.cpp
new file mode 100644
index 00000000..cf29fd75
--- /dev/null
+++ b/src/boost/libs/spirit/test/x3/rule_separate_tu_grammar.cpp
@@ -0,0 +1,42 @@
+/*=============================================================================
+ Copyright (c) 2019 Nikita Kniazev
+
+ Use, modification and distribution is subject to 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)
+=============================================================================*/
+
+#include "rule_separate_tu_grammar.hpp"
+
+#include <boost/spirit/home/x3.hpp>
+
+namespace unused_attr {
+
+const auto skipper_def = x3::lit('*');
+BOOST_SPIRIT_DEFINE(skipper)
+BOOST_SPIRIT_INSTANTIATE(skipper_type, char const*, x3::unused_type)
+
+const auto skipper2_def = x3::lit('#');
+BOOST_SPIRIT_DEFINE(skipper2)
+BOOST_SPIRIT_INSTANTIATE(skipper2_type, char const*, x3::unused_type)
+
+const auto grammar_def = *x3::lit('=');
+BOOST_SPIRIT_DEFINE(grammar)
+BOOST_SPIRIT_INSTANTIATE(grammar_type, char const*, x3::unused_type)
+BOOST_SPIRIT_INSTANTIATE(grammar_type, char const*, x3::phrase_parse_context<skipper_type>::type)
+BOOST_SPIRIT_INSTANTIATE(grammar_type, char const*, x3::phrase_parse_context<skipper2_type>::type)
+
+}
+
+namespace used_attr {
+
+const auto skipper_def = x3::space;
+BOOST_SPIRIT_DEFINE(skipper)
+BOOST_SPIRIT_INSTANTIATE(skipper_type, char const*, x3::unused_type)
+
+const auto grammar_def = x3::int_;
+BOOST_SPIRIT_DEFINE(grammar)
+BOOST_SPIRIT_INSTANTIATE(grammar_type, char const*, x3::unused_type)
+BOOST_SPIRIT_INSTANTIATE(grammar_type, char const*, x3::phrase_parse_context<skipper_type>::type)
+
+}
diff --git a/src/boost/libs/spirit/test/x3/rule_separate_tu_grammar.hpp b/src/boost/libs/spirit/test/x3/rule_separate_tu_grammar.hpp
new file mode 100644
index 00000000..7187a36a
--- /dev/null
+++ b/src/boost/libs/spirit/test/x3/rule_separate_tu_grammar.hpp
@@ -0,0 +1,49 @@
+/*=============================================================================
+ Copyright (c) 2019 Nikita Kniazev
+
+ Use, modification and distribution is subject to 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)
+=============================================================================*/
+
+#include <boost/spirit/home/x3.hpp>
+
+// Check that `BOOST_SPIRIT_INSTANTIATE` instantiates `parse_rule` with proper
+// types when a rule has no attribute.
+
+namespace unused_attr {
+
+namespace x3 = boost::spirit::x3;
+
+// skipper must has no attribute, checks `parse` and `skip_over`
+using skipper_type = x3::rule<class skipper_r>;
+const skipper_type skipper;
+BOOST_SPIRIT_DECLARE(skipper_type)
+
+// the `unused_type const` must have the same effect as no attribute
+using skipper2_type = x3::rule<class skipper2_r, x3::unused_type const>;
+const skipper2_type skipper2;
+BOOST_SPIRIT_DECLARE(skipper2_type)
+
+// grammar must has no attribute, checks `parse` and `phrase_parse`
+using grammar_type = x3::rule<class grammar_r>;
+const grammar_type grammar;
+BOOST_SPIRIT_DECLARE(grammar_type)
+
+}
+
+// Check instantiation when rule has an attribute.
+
+namespace used_attr {
+
+namespace x3 = boost::spirit::x3;
+
+using skipper_type = x3::rule<class skipper_r>;
+const skipper_type skipper;
+BOOST_SPIRIT_DECLARE(skipper_type)
+
+using grammar_type = x3::rule<class grammar_r, int>;
+const grammar_type grammar;
+BOOST_SPIRIT_DECLARE(grammar_type)
+
+}
diff --git a/src/boost/libs/spirit/test/x3/seek.cpp b/src/boost/libs/spirit/test/x3/seek.cpp
new file mode 100644
index 00000000..2986a55e
--- /dev/null
+++ b/src/boost/libs/spirit/test/x3/seek.cpp
@@ -0,0 +1,95 @@
+/*//////////////////////////////////////////////////////////////////////////////
+ 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)
+//////////////////////////////////////////////////////////////////////////////*/
+#include <vector>
+
+#include <boost/detail/lightweight_test.hpp>
+#include <boost/spirit/home/x3/auxiliary/eoi.hpp>
+#include <boost/spirit/home/x3/core.hpp>
+#include <boost/spirit/home/x3/char.hpp>
+#include <boost/spirit/home/x3/string.hpp>
+#include <boost/spirit/home/x3/numeric.hpp>
+#include <boost/spirit/home/x3/operator/plus.hpp>
+#include <boost/spirit/home/x3/operator/sequence.hpp>
+
+#include <boost/spirit/home/x3/directive/seek.hpp>
+
+#include "test.hpp"
+
+
+///////////////////////////////////////////////////////////////////////////////
+int main()
+{
+ using namespace spirit_test;
+ namespace x3 = boost::spirit::x3;
+
+ // test eoi
+ {
+ BOOST_TEST(test("", x3::seek[x3::eoi]));
+ BOOST_TEST(test(" ", x3::seek[x3::eoi], x3::space));
+ BOOST_TEST(test("a", x3::seek[x3::eoi]));
+ BOOST_TEST(test(" a", x3::seek[x3::eoi], x3::space));
+ }
+
+ // test literal finding
+ {
+ int i = 0;
+
+ BOOST_TEST(
+ test_attr("!@#$%^&*KEY:123", x3::seek["KEY:"] >> x3::int_, i)
+ && i == 123
+ );
+ }
+ // test sequence finding
+ {
+ int i = 0;
+
+ BOOST_TEST(
+ test_attr("!@#$%^&* KEY : 123", x3::seek[x3::lit("KEY") >> ':'] >> x3::int_, i, x3::space)
+ && i == 123
+ );
+ }
+
+ // test attr finding
+ {
+ std::vector<int> v;
+
+ BOOST_TEST( // expect partial match
+ test_attr("a06b78c3d", +x3::seek[x3::int_], v, false)
+ && v.size() == 3 && v[0] == 6 && v[1] == 78 && v[2] == 3
+ );
+ }
+
+ // test action
+ {
+
+ bool b = false;
+ auto const action = [&b]() { b = true; };
+
+ BOOST_TEST( // expect partial match
+ test("abcdefg", x3::seek["def"][action], false)
+ && b
+ );
+ }
+
+ // test container
+ {
+ std::vector<int> v;
+
+ BOOST_TEST(
+ test_attr("abcInt:100Int:95Int:44", x3::seek[+("Int:" >> x3::int_)], v)
+ && v.size() == 3 && v[0] == 100 && v[1] == 95 && v[2] == 44
+ );
+ }
+
+ // test failure rollback
+ {
+ BOOST_TEST(test_failure("abcdefg", x3::seek[x3::int_]));
+ }
+
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/spirit/test/x3/sequence.cpp b/src/boost/libs/spirit/test/x3/sequence.cpp
new file mode 100644
index 00000000..f6559078
--- /dev/null
+++ b/src/boost/libs/spirit/test/x3/sequence.cpp
@@ -0,0 +1,503 @@
+/*=============================================================================
+ Copyright (c) 2001-2015 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)
+=============================================================================*/
+#include <boost/detail/lightweight_test.hpp>
+#include <boost/spirit/home/x3.hpp>
+#include <boost/fusion/include/vector.hpp>
+#include <boost/fusion/include/deque.hpp>
+#include <boost/fusion/include/at.hpp>
+#include <boost/fusion/include/comparison.hpp>
+
+#include <string>
+#include <iostream>
+#include "test.hpp"
+#include "utils.hpp"
+
+int
+main()
+{
+ using boost::spirit::x3::unused_type;
+
+ using boost::spirit::x3::char_;
+ using boost::spirit::x3::space;
+ using boost::spirit::x3::string;
+ using boost::spirit::x3::attr;
+ using boost::spirit::x3::omit;
+ using boost::spirit::x3::lit;
+ using boost::spirit::x3::unused;
+ using boost::spirit::x3::int_;
+ using boost::spirit::x3::float_;
+ using boost::spirit::x3::no_case;
+ using boost::spirit::x3::rule;
+ using boost::spirit::x3::alnum;
+
+ using boost::spirit::x3::traits::attribute_of;
+
+ using boost::fusion::vector;
+ using boost::fusion::deque;
+ using boost::fusion::at_c;
+
+ using spirit_test::test;
+ using spirit_test::test_attr;
+
+ {
+ BOOST_TEST((test("aa", char_ >> char_)));
+ BOOST_TEST((test("aa", char_ >> 'a')));
+ BOOST_TEST((test("aaa", char_ >> char_ >> char_('a'))));
+ BOOST_TEST((test("xi", char_('x') >> char_('i'))));
+ BOOST_TEST((!test("xi", char_('x') >> char_('o'))));
+ BOOST_TEST((test("xin", char_('x') >> char_('i') >> char_('n'))));
+ }
+
+#ifdef BOOST_SPIRIT_COMPILE_ERROR_CHECK
+ {
+ // Compile check only
+ struct x {};
+ char_ >> x(); // this should give a reasonable error message
+ }
+#endif
+
+ {
+ BOOST_TEST((test(" a a", char_ >> char_, space)));
+ BOOST_TEST((test(" x i", char_('x') >> char_('i'), space)));
+ BOOST_TEST((!test(" x i", char_('x') >> char_('o'), space)));
+ }
+
+
+ {
+ BOOST_TEST((test(" Hello, World", lit("Hello") >> ',' >> "World", space)));
+ }
+
+
+ {
+ vector<char, char> attr;
+ BOOST_TEST((test_attr("ab", char_ >> char_, attr)));
+ BOOST_TEST((at_c<0>(attr) == 'a'));
+ BOOST_TEST((at_c<1>(attr) == 'b'));
+ }
+
+#ifdef BOOST_SPIRIT_COMPILE_ERROR_CHECK
+ {
+ // Compile check only
+ vector<char, char> attr;
+
+ // error: attr does not have enough elements
+ test_attr("abc", char_ >> char_ >> char_, attr);
+ }
+#endif
+
+ {
+ vector<char, char, char> attr;
+ BOOST_TEST((test_attr(" a\n b\n c", char_ >> char_ >> char_, attr, space)));
+ BOOST_TEST((at_c<0>(attr) == 'a'));
+ BOOST_TEST((at_c<1>(attr) == 'b'));
+ BOOST_TEST((at_c<2>(attr) == 'c'));
+ }
+
+ {
+ // 'b' has an unused_type. unused attributes are not part of the sequence
+ vector<char, char> attr;
+ BOOST_TEST((test_attr("abc", char_ >> 'b' >> char_, attr)));
+ BOOST_TEST((at_c<0>(attr) == 'a'));
+ BOOST_TEST((at_c<1>(attr) == 'c'));
+ }
+
+ {
+ // 'b' has an unused_type. unused attributes are not part of the sequence
+ vector<char, char> attr;
+ BOOST_TEST((test_attr("acb", char_ >> char_ >> 'b', attr)));
+ BOOST_TEST((at_c<0>(attr) == 'a'));
+ BOOST_TEST((at_c<1>(attr) == 'c'));
+ }
+
+ {
+ // "hello" has an unused_type. unused attributes are not part of the sequence
+ vector<char, char> attr;
+ BOOST_TEST((test_attr("a hello c", char_ >> "hello" >> char_, attr, space)));
+ BOOST_TEST((at_c<0>(attr) == 'a'));
+ BOOST_TEST((at_c<1>(attr) == 'c'));
+ }
+
+ {
+ // a single element
+ char attr;
+ BOOST_TEST((test_attr("ab", char_ >> 'b', attr)));
+ BOOST_TEST((attr == 'a'));
+ }
+
+ {
+ // a single element fusion sequence
+ vector<char> attr;
+ BOOST_TEST((test_attr("ab", char_ >> 'b', attr)));
+ BOOST_TEST((at_c<0>(attr) == 'a'));
+ }
+
+ {
+ // make sure single element tuples get passed through if the rhs
+ // has a single element tuple as its attribute. Edit JDG 2014:
+ // actually he issue here is that if the rhs in this case a rule
+ // (r), it should get it (i.e. the sequence parser should not
+ // unwrap it). It's odd that the RHS (r) does not really have a
+ // single element tuple (it's a deque<char, int>), so the original
+ // comment is not accurate.
+
+ typedef deque<char, int> attr_type;
+ attr_type fv;
+
+ auto r = rule<class r, attr_type>()
+ = char_ >> ',' >> int_;
+
+ BOOST_TEST((test_attr("test:x,1", "test:" >> r, fv) &&
+ fv == attr_type('x', 1)));
+ }
+
+ {
+ // make sure single element tuples get passed through if the rhs
+ // has a single element tuple as its attribute. This is a correction
+ // of the test above.
+
+ typedef deque<int> attr_type;
+ attr_type fv;
+
+ auto r = rule<class r, attr_type>()
+ = int_;
+
+ BOOST_TEST((test_attr("test:1", "test:" >> r, fv) &&
+ fv == attr_type(1)));
+ }
+
+ {
+ // unused means we don't care about the attribute
+ BOOST_TEST((test_attr("abc", char_ >> 'b' >> char_, unused)));
+ }
+
+ {
+ BOOST_TEST((test("aA", no_case[char_('a') >> 'a'])));
+ BOOST_TEST((test("BEGIN END", no_case[lit("begin") >> "end"], space)));
+ BOOST_TEST((!test("BEGIN END", no_case[lit("begin") >> "nend"], space)));
+ }
+
+ { // check attribute is passed through unary to another sequence
+ using boost::spirit::x3::eps;
+ std::string s;
+ BOOST_TEST(test_attr("ab", eps >> no_case[char_ >> char_], s));
+ BOOST_TEST("ab" == s);
+ s.clear();
+ BOOST_TEST(test_attr("ab", no_case[char_ >> char_] >> eps, s));
+ BOOST_TEST("ab" == s);
+ s.clear();
+ BOOST_TEST(test_attr("abc", char_ >> no_case[char_ >> char_], s));
+ BOOST_TEST("abc" == s);
+ s.clear();
+ BOOST_TEST(test_attr("abc", no_case[char_ >> char_] >> char_, s));
+ BOOST_TEST("abc" == s);
+ }
+
+ {
+#ifdef SPIRIT_NO_COMPILE_CHECK
+ char_ >> char_ = char_ >> char_; // disallow this!
+#endif
+ }
+
+ { // alternative forms of attributes. Allow sequences to take in
+ // stl containers.
+
+ std::vector<char> v;
+ BOOST_TEST(test_attr("abc", char_ >> char_ >> char_, v));
+ BOOST_TEST(v.size() == 3);
+ BOOST_TEST(v[0] == 'a');
+ BOOST_TEST(v[1] == 'b');
+ BOOST_TEST(v[2] == 'c');
+ }
+
+ { // alternative forms of attributes. Allow sequences to take in
+ // stl containers.
+
+ std::vector<char> v;
+ BOOST_TEST(test_attr("a,b,c", char_ >> *(',' >> char_), v));
+ BOOST_TEST(v.size() == 3);
+ BOOST_TEST(v[0] == 'a');
+ BOOST_TEST(v[1] == 'b');
+ BOOST_TEST(v[2] == 'c');
+ }
+
+ { // alternative forms of attributes. Allow sequences to take in
+ // stl containers.
+
+ std::vector<char> v;
+ BOOST_TEST(test_attr("abc", char_ >> *char_, v));
+ BOOST_TEST(v.size() == 3);
+ BOOST_TEST(v[0] == 'a');
+ BOOST_TEST(v[1] == 'b');
+ BOOST_TEST(v[2] == 'c');
+ }
+
+ { // alternative forms of attributes. Allow sequences to take in
+ // stl containers.
+ //~ using boost::spirit::x3::hold;
+
+ std::vector<char> v;
+ BOOST_TEST(test_attr("abc", char_ >> *(char_ >> char_), v));
+ BOOST_TEST(v.size() == 3);
+ BOOST_TEST(v[0] == 'a');
+ BOOST_TEST(v[1] == 'b');
+ BOOST_TEST(v[2] == 'c');
+
+ v.clear();
+ BOOST_TEST(!test_attr("abcd", char_ >> *(char_ >> char_), v));
+
+ // $$$ hold not yet implementd $$$
+ //~ v.clear();
+ //~ BOOST_TEST(test_attr("abcdef", char_ >> *hold[char_ >> char_] >> char_, v));
+ //~ BOOST_TEST(v.size() == 6);
+ //~ BOOST_TEST(v[0] == 'a');
+ //~ BOOST_TEST(v[1] == 'b');
+ //~ BOOST_TEST(v[2] == 'c');
+ //~ BOOST_TEST(v[3] == 'd');
+ //~ BOOST_TEST(v[4] == 'e');
+ //~ BOOST_TEST(v[5] == 'f');
+
+ v.clear();
+ BOOST_TEST(test_attr("abc", char_ >> +(char_ >> char_), v));
+ BOOST_TEST(v.size() == 3);
+ BOOST_TEST(v[0] == 'a');
+ BOOST_TEST(v[1] == 'b');
+ BOOST_TEST(v[2] == 'c');
+ }
+
+ { // alternative forms of attributes. Allow sequences to take in
+ // stl containers.
+
+ std::vector<char> v;
+ BOOST_TEST(test_attr("abc", char_ >> -(+char_), v));
+ BOOST_TEST(v.size() == 3);
+ BOOST_TEST(v[0] == 'a');
+ BOOST_TEST(v[1] == 'b');
+ BOOST_TEST(v[2] == 'c');
+ }
+
+ { // alternative forms of attributes. Allow sequences to take in
+ // stl containers.
+
+ std::string s;
+ BOOST_TEST(test_attr("foobar", string("foo") >> string("bar"), s));
+ BOOST_TEST(s == "foobar");
+
+ s.clear();
+
+ // $$$ hold not yet implemented $$$
+ //~ using boost::spirit::x3::hold;
+
+ //~ rule<char const*, std::string()> word = +char_("abc");
+ //~ BOOST_TEST(test_attr("ab.bc.ca", *hold[word >> string(".")] >> word, s));
+ //~ BOOST_TEST(s == "ab.bc.ca");
+ }
+
+ // Make sure get_sequence_types works for sequences of sequences.
+ {
+ std::vector<char> v;
+ BOOST_TEST(test_attr(" a b", (' ' >> char_) >> (' ' >> char_), v));
+ BOOST_TEST(v.size() == 2);
+ BOOST_TEST(v[0] == 'a');
+ BOOST_TEST(v[1] == 'b');
+ }
+
+ // alternative forms of attributes. Allow sequences to take in
+ // stl containers of stl containers.
+ {
+ std::vector<std::string> v;
+ BOOST_TEST(test_attr("abc1,abc2",
+ *~char_(',') >> *(',' >> *~char_(',')), v));
+ BOOST_TEST(v.size() == 2 && v[0] == "abc1" && v[1] == "abc2");
+ }
+
+ {
+ std::vector<std::string> v;
+
+ auto e = rule<class e, std::string>()
+ = *~char_(',');
+
+ auto l = rule<class l, std::vector<std::string>>()
+ = e >> *(',' >> e);
+
+ BOOST_TEST(test_attr("abc1,abc2,abc3", l, v));
+ BOOST_TEST(v.size() == 3);
+ BOOST_TEST(v[0] == "abc1");
+ BOOST_TEST(v[1] == "abc2");
+ BOOST_TEST(v[2] == "abc3");
+ }
+
+ // do the same with a plain string object
+ {
+ std::string s;
+ BOOST_TEST(test_attr("abc1,abc2",
+ *~char_(',') >> *(',' >> *~char_(',')), s));
+ BOOST_TEST(s == "abc1abc2");
+ }
+
+ {
+ std::string s;
+ auto e = rule<class e, std::string>()
+ = *~char_(',');
+
+ auto l = rule<class l, std::string>()
+ = e >> *(',' >> e);
+
+ BOOST_TEST(test_attr("abc1,abc2,abc3", l, s));
+ BOOST_TEST(s == "abc1abc2abc3");
+ }
+
+ {
+ std::vector<char> v;
+ BOOST_TEST(test_attr("ab", char_ >> -char_, v));
+ BOOST_TEST(v.size() == 2 && v[0] == 'a' && v[1] == 'b');
+
+ v.clear();
+ BOOST_TEST(test_attr("a", char_ >> -char_, v));
+ BOOST_TEST(v.size() == 1 && v[0] == 'a');
+
+ // $$$ should this be allowed? I don't think so... $$$
+ //~ v.clear();
+ //~ BOOST_TEST(test_attr("a", char_, v));
+ //~ BOOST_TEST(v.size() == 1 && v[0] == 'a');
+ }
+
+ {
+ std::vector<boost::optional<char>> v;
+ BOOST_TEST(test_attr("ab", char_ >> -char_, v));
+ BOOST_TEST(v.size() == 2 && v[0] == 'a' && v[1] == 'b');
+
+ v.clear();
+ BOOST_TEST(test_attr("a", char_ >> -char_, v));
+ BOOST_TEST(v.size() == 2 && v[0] == 'a' && !v[1]);
+
+ // $$$ should this be allowed? I don't think so... $$$
+ //~ v.clear();
+ //~ BOOST_TEST(test_attr("a", char_, v));
+ //~ BOOST_TEST(v.size() == 1 && v[0] == 'a');
+ }
+
+ // test from spirit mailing list
+ // "Optional operator causes string attribute concatenation"
+ {
+ typedef vector<char, char, int> attr_type;
+ attr_type attr;
+
+ auto node = alnum >> -('[' >> alnum >> '=' >> int_ >> ']');
+
+ BOOST_TEST(test_attr("x[y=123]", node, attr));
+ BOOST_TEST(attr == attr_type('x', 'y', 123));
+ }
+
+ // test from spirit mailing list (variation of above)
+ // "Optional operator causes string attribute concatenation"
+ {
+ typedef vector<std::string, std::string, int> attr_type;
+ attr_type attr;
+
+ auto node = +alnum >> -('[' >> +alnum >> '=' >> int_ >> ']');
+
+ BOOST_TEST(test_attr("xxx[yyy=123]", node, attr));
+ BOOST_TEST(attr == attr_type("xxx", "yyy", 123));
+ }
+
+ // test from spirit mailing list
+ // "Error with container within sequence"
+ {
+ typedef vector<std::string> attr_type;
+ attr_type attr;
+
+ auto r = *alnum;
+
+ BOOST_TEST(test_attr("abcdef", r, attr));
+ BOOST_TEST(at_c<0>(attr) == "abcdef");
+ }
+
+ // test from spirit mailing list (variation of above)
+ // "Error with container within sequence"
+ {
+ typedef vector<std::vector<int>> attr_type;
+ attr_type attr;
+
+ auto r = *int_;
+
+ BOOST_TEST(test_attr("123 456", r, attr, space));
+ BOOST_TEST(at_c<0>(attr).size() == 2);
+ BOOST_TEST(at_c<0>(attr)[0] == 123);
+ BOOST_TEST(at_c<0>(attr)[1] == 456);
+ }
+
+ {
+ using Attr = boost::variant<int, float>;
+ Attr attr;
+ auto const term = rule<class term, Attr>("term") = int_ | float_;
+ auto const expr = rule<class expr, Attr>("expr") = term | ('(' > term > ')');
+ BOOST_TEST((test_attr("(1)", expr, attr, space)));
+ }
+
+ // test that failing sequence leaves attribute consistent
+ {
+ std::string attr;
+ //no need to use omit[], but lit() is buggy ATM
+ BOOST_TEST(test_attr("A\nB\nC", *(char_ >> omit[lit("\n")]), attr, false));
+ BOOST_TEST(attr == "AB");
+ }
+
+ // test that sequence with only one parser producing attribute
+ // makes it unwrapped
+ {
+ BOOST_TEST((boost::is_same<
+ typename attribute_of<decltype(lit("abc") >> attr(long())), unused_type>::type,
+ long>() ));
+ }
+
+ { // test action
+ using boost::fusion::at_c;
+
+ char c = 0;
+ int n = 0;
+ auto f = [&](auto& ctx)
+ {
+ c = at_c<0>(_attr(ctx));
+ n = at_c<1>(_attr(ctx));
+ };
+
+ BOOST_TEST(test("x123\"a string\"", (char_ >> int_ >> "\"a string\"")[f]));
+ BOOST_TEST(c == 'x');
+ BOOST_TEST(n == 123);
+ }
+
+ { // test action
+ char c = 0;
+ int n = 0;
+ auto f = [&](auto& ctx)
+ {
+ c = at_c<0>(_attr(ctx));
+ n = at_c<1>(_attr(ctx));
+ };
+
+ BOOST_TEST(test("x 123 \"a string\"", (char_ >> int_ >> "\"a string\"")[f], space));
+ BOOST_TEST(c == 'x');
+ BOOST_TEST(n == 123);
+ }
+
+ {
+#ifdef SPIRIT_NO_COMPILE_CHECK
+ char const* const s = "";
+ int i;
+ parse(s, s, int_ >> int_, i);
+#endif
+ }
+
+ { // test move only types
+ using boost::spirit::x3::eps;
+ std::vector<move_only> v;
+ BOOST_TEST(test_attr("ssszs", *synth_move_only >> 'z' >> synth_move_only, v));
+ BOOST_TEST_EQ(v.size(), 4);
+ }
+
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/spirit/test/x3/skip.cpp b/src/boost/libs/spirit/test/x3/skip.cpp
new file mode 100644
index 00000000..3a201408
--- /dev/null
+++ b/src/boost/libs/spirit/test/x3/skip.cpp
@@ -0,0 +1,48 @@
+/*=============================================================================
+ Copyright (c) 2001-2015 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)
+=============================================================================*/
+#include <boost/detail/lightweight_test.hpp>
+#include <boost/spirit/home/x3.hpp>
+
+#include <iostream>
+#include "test.hpp"
+
+int
+main()
+{
+ using spirit_test::test;
+ using spirit_test::test_attr;
+ using boost::spirit::x3::ascii::space;
+ using boost::spirit::x3::ascii::space_type;
+ using boost::spirit::x3::ascii::char_;
+ using boost::spirit::x3::ascii::alpha;
+ using boost::spirit::x3::lexeme;
+ using boost::spirit::x3::skip;
+ using boost::spirit::x3::lit;
+
+ {
+ BOOST_TEST((test("a b c d", skip(space)[*char_])));
+ }
+
+ { // test attribute
+ std::string s;
+ BOOST_TEST((test_attr("a b c d", skip(space)[*char_], s)));
+ BOOST_TEST(s == "abcd");
+ }
+
+ { // reskip
+ BOOST_TEST((test("ab c d", lexeme[lit('a') >> 'b' >> skip[lit('c') >> 'd']], space)));
+ BOOST_TEST((test("abcd", lexeme[lit('a') >> 'b' >> skip[lit('c') >> 'd']], space)));
+ BOOST_TEST(!(test("a bcd", lexeme[lit('a') >> 'b' >> skip[lit('c') >> 'd']], space)));
+
+ BOOST_TEST((test("ab c d", lexeme[lexeme[lit('a') >> 'b' >> skip[lit('c') >> 'd']]], space)));
+ BOOST_TEST((test("abcd", lexeme[lexeme[lit('a') >> 'b' >> skip[lit('c') >> 'd']]], space)));
+ BOOST_TEST(!(test("a bcd", lexeme[lexeme[lit('a') >> 'b' >> skip[lit('c') >> 'd']]], space)));
+ }
+
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/spirit/test/x3/symbols1.cpp b/src/boost/libs/spirit/test/x3/symbols1.cpp
new file mode 100644
index 00000000..38771e45
--- /dev/null
+++ b/src/boost/libs/spirit/test/x3/symbols1.cpp
@@ -0,0 +1,187 @@
+/*=============================================================================
+ Copyright (c) 2001-2015 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)
+=============================================================================*/
+#include <boost/detail/lightweight_test.hpp>
+#include <boost/spirit/home/x3.hpp>
+
+#include <iostream>
+#include "test.hpp"
+
+// Custom string type with a C-style string conversion.
+struct custom_string_c
+{
+ custom_string_c(char c) { str[0] = c; str[1] = '\0'; }
+
+ operator char*() { return str; }
+ operator char const*() const { return str; }
+
+private:
+ char str[2];
+};
+
+int
+main()
+{
+ using spirit_test::test;
+ using spirit_test::test_attr;
+ using boost::spirit::x3::symbols;
+ using boost::spirit::x3::no_case;
+
+ { // basics
+ symbols<int> sym;
+
+ sym.add
+ ("Joel")
+ ("Ruby")
+ ("Tenji")
+ ("Tutit")
+ ("Kim")
+ ("Joey")
+ ("Joeyboy")
+ ;
+
+ BOOST_TEST((test("Joel", sym)));
+ BOOST_TEST((test("Ruby", sym)));
+ BOOST_TEST((test("Tenji", sym)));
+ BOOST_TEST((test("Tutit", sym)));
+ BOOST_TEST((test("Kim", sym)));
+ BOOST_TEST((test("Joey", sym)));
+ BOOST_TEST((test("Joeyboy", sym)));
+ BOOST_TEST((!test("XXX", sym)));
+
+ // test copy
+ symbols<int> sym2;
+ sym2 = sym;
+ BOOST_TEST((test("Joel", sym2)));
+ BOOST_TEST((test("Ruby", sym2)));
+ BOOST_TEST((test("Tenji", sym2)));
+ BOOST_TEST((test("Tutit", sym2)));
+ BOOST_TEST((test("Kim", sym2)));
+ BOOST_TEST((test("Joey", sym2)));
+ BOOST_TEST((!test("XXX", sym2)));
+
+ // make sure it plays well with other parsers
+ BOOST_TEST((test("Joelyo", sym >> "yo")));
+
+ sym.remove
+ ("Joel")
+ ("Ruby")
+ ;
+
+ BOOST_TEST((!test("Joel", sym)));
+ BOOST_TEST((!test("Ruby", sym)));
+ }
+
+ { // comma syntax
+ symbols<int> sym;
+ sym += "Joel", "Ruby", "Tenji", "Tutit", "Kim", "Joey";
+
+ BOOST_TEST((test("Joel", sym)));
+ BOOST_TEST((test("Ruby", sym)));
+ BOOST_TEST((test("Tenji", sym)));
+ BOOST_TEST((test("Tutit", sym)));
+ BOOST_TEST((test("Kim", sym)));
+ BOOST_TEST((test("Joey", sym)));
+ BOOST_TEST((!test("XXX", sym)));
+
+ sym -= "Joel", "Ruby";
+
+ BOOST_TEST((!test("Joel", sym)));
+ BOOST_TEST((!test("Ruby", sym)));
+ }
+
+ { // no-case handling
+ using namespace boost::spirit::x3::ascii;
+
+ symbols<int> sym;
+ // NOTE: make sure all entries are in lower-case!!!
+ sym = "joel", "ruby", "tenji", "tutit", "kim", "joey";
+
+ BOOST_TEST((test("joel", no_case[sym])));
+ BOOST_TEST((test("ruby", no_case[sym])));
+ BOOST_TEST((test("tenji", no_case[sym])));
+ BOOST_TEST((test("tutit", no_case[sym])));
+ BOOST_TEST((test("kim", no_case[sym])));
+ BOOST_TEST((test("joey", no_case[sym])));
+
+ BOOST_TEST((test("JOEL", no_case[sym])));
+ BOOST_TEST((test("RUBY", no_case[sym])));
+ BOOST_TEST((test("TENJI", no_case[sym])));
+ BOOST_TEST((test("TUTIT", no_case[sym])));
+ BOOST_TEST((test("KIM", no_case[sym])));
+ BOOST_TEST((test("JOEY", no_case[sym])));
+
+ // make sure it plays well with other parsers
+ BOOST_TEST((test("Joelyo", no_case[sym] >> "yo")));
+ }
+
+ { // attributes
+ symbols<int> sym;
+
+ sym.add
+ ("Joel", 1)
+ ("Ruby", 2)
+ ("Tenji", 3)
+ ("Tutit", 4)
+ ("Kim", 5)
+ ("Joey", 6)
+ ;
+
+ int i;
+ BOOST_TEST((test_attr("Joel", sym, i)));
+ BOOST_TEST(i == 1);
+ BOOST_TEST((test_attr("Ruby", sym, i)));
+ BOOST_TEST(i == 2);
+ BOOST_TEST((test_attr("Tenji", sym, i)));
+ BOOST_TEST(i == 3);
+ BOOST_TEST((test_attr("Tutit", sym, i)));
+ BOOST_TEST(i == 4);
+ BOOST_TEST((test_attr("Kim", sym, i)));
+ BOOST_TEST(i == 5);
+ BOOST_TEST((test_attr("Joey", sym, i)));
+ BOOST_TEST(i == 6);
+ BOOST_TEST((!test_attr("XXX", sym, i)));
+
+ // double add:
+
+ sym.add("Joel", 265);
+ BOOST_TEST((test_attr("Joel", sym, i)));
+ BOOST_TEST(i == 1);
+ }
+
+ { // actions
+ using boost::spirit::x3::_attr;
+
+ symbols<int> sym;
+ sym.add
+ ("Joel", 1)
+ ("Ruby", 2)
+ ("Tenji", 3)
+ ("Tutit", 4)
+ ("Kim", 5)
+ ("Joey", 6)
+ ;
+
+ int i;
+ auto f = [&](auto& ctx){ i = _attr(ctx); };
+
+ BOOST_TEST((test("Joel", sym[f])));
+ BOOST_TEST(i == 1);
+ BOOST_TEST((test("Ruby", sym[f])));
+ BOOST_TEST(i == 2);
+ BOOST_TEST((test("Tenji", sym[f])));
+ BOOST_TEST(i == 3);
+ BOOST_TEST((test("Tutit", sym[f])));
+ BOOST_TEST(i == 4);
+ BOOST_TEST((test("Kim", sym[f])));
+ BOOST_TEST(i == 5);
+ BOOST_TEST((test("Joey", sym[f])));
+ BOOST_TEST(i == 6);
+ BOOST_TEST((!test("XXX", sym[f])));
+ }
+
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/spirit/test/x3/symbols2.cpp b/src/boost/libs/spirit/test/x3/symbols2.cpp
new file mode 100644
index 00000000..f401dc14
--- /dev/null
+++ b/src/boost/libs/spirit/test/x3/symbols2.cpp
@@ -0,0 +1,202 @@
+/*=============================================================================
+ Copyright (c) 2001-2015 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)
+=============================================================================*/
+#include <boost/detail/lightweight_test.hpp>
+#include <boost/spirit/home/x3.hpp>
+
+#include <iostream>
+#include "test.hpp"
+
+// Custom string type with a C-style string conversion.
+struct custom_string_c
+{
+ custom_string_c(char c) { str[0] = c; str[1] = '\0'; }
+
+ operator char*() { return str; }
+ operator char const*() const { return str; }
+
+private:
+ char str[2];
+};
+
+std::string get_str(char const* str)
+{
+ return std::string(str);
+}
+
+int
+main()
+{
+ using spirit_test::test;
+ using spirit_test::test_attr;
+ using boost::spirit::x3::symbols;
+ using boost::spirit::x3::rule;
+
+ { // construction from symbol array
+ char const* syms[] = {"Joel","Ruby","Tenji","Tutit","Kim","Joey"};
+ symbols<int> sym(syms);
+
+ BOOST_TEST((test("Joel", sym)));
+ BOOST_TEST((test("Ruby", sym)));
+ BOOST_TEST((test("Tenji", sym)));
+ BOOST_TEST((test("Tutit", sym)));
+ BOOST_TEST((test("Kim", sym)));
+ BOOST_TEST((test("Joey", sym)));
+ BOOST_TEST((!test("XXX", sym)));
+ }
+
+ { // construction from 2 arrays
+
+ char const* syms[] = {"Joel","Ruby","Tenji","Tutit","Kim","Joey"};
+ int data[] = {1,2,3,4,5,6};
+ symbols<int> sym(syms, data);
+
+ int i;
+ BOOST_TEST((test_attr("Joel", sym, i)));
+ BOOST_TEST(i == 1);
+ BOOST_TEST((test_attr("Ruby", sym, i)));
+ BOOST_TEST(i == 2);
+ BOOST_TEST((test_attr("Tenji", sym, i)));
+ BOOST_TEST(i == 3);
+ BOOST_TEST((test_attr("Tutit", sym, i)));
+ BOOST_TEST(i == 4);
+ BOOST_TEST((test_attr("Kim", sym, i)));
+ BOOST_TEST(i == 5);
+ BOOST_TEST((test_attr("Joey", sym, i)));
+ BOOST_TEST(i == 6);
+ BOOST_TEST((!test_attr("XXX", sym, i)));
+ }
+
+ { // allow std::string and other string types
+ symbols<> sym;
+
+ // const and non-const std::string
+ std::string a("abc");
+ std::string const b("def");
+ sym += a;
+ sym += b;
+ BOOST_TEST((test("abc", sym)));
+ BOOST_TEST((test("def", sym)));
+ sym = a;
+ BOOST_TEST((test("abc", sym)));
+ BOOST_TEST((!test("def", sym)));
+
+ // non-const C-style string
+ char arr[2]; arr[0] = 'a'; arr[1] = '\0';
+ sym = arr;
+ BOOST_TEST((test("a", sym)));
+ BOOST_TEST((!test("b", sym)));
+
+ // const and non-const custom string type
+ custom_string_c c('x');
+ custom_string_c const cc('y');
+ sym = c, cc;
+ BOOST_TEST((test("x", sym)));
+ BOOST_TEST((test("y", sym)));
+ BOOST_TEST((!test("z", sym)));
+ }
+
+ { // find
+
+ symbols<int> sym;
+ sym.add("a", 1)("b", 2);
+
+ BOOST_TEST(!sym.find("c"));
+
+ BOOST_TEST(sym.find("a") && *sym.find("a") == 1);
+ BOOST_TEST(sym.find("b") && *sym.find("b") == 2);
+
+ BOOST_TEST(sym.at("a") == 1);
+ BOOST_TEST(sym.at("b") == 2);
+ BOOST_TEST(sym.at("c") == 0);
+
+ BOOST_TEST(sym.find("a") && *sym.find("a") == 1);
+ BOOST_TEST(sym.find("b") && *sym.find("b") == 2);
+ BOOST_TEST(sym.find("c") && *sym.find("c") == 0);
+
+ symbols<int> const_sym(sym);
+
+ BOOST_TEST(const_sym.find("a") && *const_sym.find("a") == 1);
+ BOOST_TEST(const_sym.find("b") && *const_sym.find("b") == 2);
+ BOOST_TEST(const_sym.find("c") && *const_sym.find("c") == 0);
+ BOOST_TEST(!const_sym.find("d"));
+
+ char const *str1 = "all";
+ char const *first = str1, *last = str1 + 3;
+ BOOST_TEST(*sym.prefix_find(first, last) == 1 && first == str1 + 1);
+
+ char const *str2 = "dart";
+ first = str2; last = str2 + 4;
+ BOOST_TEST(!sym.prefix_find(first, last) && first == str2);
+ }
+
+ { // name
+ symbols <int> sym,sym2;
+ sym.name("test");
+ BOOST_TEST(sym.name()=="test");
+ sym2 = sym;
+ BOOST_TEST(sym2.name()=="test");
+
+ symbols <int> sym3(sym);
+ BOOST_TEST(sym3.name()=="test");
+ }
+
+ { // Substrings
+
+ symbols<int> sym;
+ BOOST_TEST(sym.at("foo") == 0);
+ sym.at("foo") = 1;
+ BOOST_TEST(sym.at("foo") == 1);
+ BOOST_TEST(sym.at("fool") == 0);
+ sym.at("fool") = 2;
+ BOOST_TEST(sym.find("foo") && *sym.find("foo") == 1);
+ BOOST_TEST(sym.find("fool") && *sym.find("fool") == 2);
+ BOOST_TEST(!sym.find("foolish"));
+ BOOST_TEST(!sym.find("foot"));
+ BOOST_TEST(!sym.find("afoot"));
+
+ char const *str, *first, *last;
+ str = "foolish"; first = str; last = str + 7;
+ BOOST_TEST(*sym.prefix_find(first, last) == 2 && first == str + 4);
+
+ first = str; last = str + 4;
+ BOOST_TEST(*sym.prefix_find(first, last) == 2 && first == str + 4);
+
+ str = "food"; first = str; last = str + 4;
+ BOOST_TEST(*sym.prefix_find(first, last) == 1 && first == str + 3);
+
+ first = str; last = str + 3;
+ BOOST_TEST(*sym.prefix_find(first, last) == 1 && first == str + 3);
+
+ first = str; last = str + 2;
+ BOOST_TEST(!sym.prefix_find(first, last) && first == str);
+ }
+
+ {
+ // remove bug
+
+ std::string s;
+ symbols<double> vars;
+
+ vars.add("l1", 12.0);
+ vars.add("l2", 0.0);
+ vars.remove("l2");
+ vars.find("l1");
+ double* d = vars.find("l1");
+ BOOST_TEST(d != 0);
+ }
+
+ { // test for proto problem with rvalue references (10-11-2011)
+ symbols<int> sym;
+ sym += get_str("Joel");
+ sym += get_str("Ruby");
+
+ BOOST_TEST((test("Joel", sym)));
+ BOOST_TEST((test("Ruby", sym)));
+ }
+
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/spirit/test/x3/symbols3.cpp b/src/boost/libs/spirit/test/x3/symbols3.cpp
new file mode 100644
index 00000000..d732ca3d
--- /dev/null
+++ b/src/boost/libs/spirit/test/x3/symbols3.cpp
@@ -0,0 +1,86 @@
+/*=============================================================================
+ Copyright (c) 2013 Carl Barron
+ Copyright (c) 2015 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)
+=============================================================================*/
+
+#include <boost/detail/lightweight_test.hpp>
+#include <boost/spirit/home/x3.hpp>
+#include <boost/fusion/include/at.hpp>
+#include <boost/fusion/include/vector.hpp>
+#include <boost/fusion/include/adapt_struct.hpp>
+#include <boost/mpl/int.hpp>
+#include <boost/optional.hpp>
+
+#include <iostream>
+#include <numeric>
+#include <vector>
+#include "test.hpp"
+
+struct roman
+{
+ boost::optional<int> a;
+ boost::optional<int> b;
+ boost::optional<int> c;
+};
+
+BOOST_FUSION_ADAPT_STRUCT(roman,
+ a, b, c
+)
+
+int eval(roman const & c)
+{
+ return c.a.get_value_or(0) + c.b.get_value_or(0) + c.c.get_value_or(0);
+}
+
+int
+main()
+{
+ using spirit_test::test;
+ using spirit_test::test_attr;
+ using boost::spirit::x3::symbols;
+
+ { // construction from initializer-list
+ symbols<int> const ones =
+ {
+ {"I", 1}, {"II", 2}, {"III", 3}, {"IV", 4},
+ {"V", 5}, {"VI", 6}, {"VII", 7}, {"VIII", 8},
+ {"IX", 9}
+ };
+ symbols<int> const tens =
+ {
+ {"X", 10}, {"XX", 20}, {"XXX", 30}, {"XL", 40},
+ {"L", 50}, {"LX", 60}, {"LXX", 70}, {"LXXX", 80},
+ {"XC", 90}
+ };
+ symbols<int> const hundreds
+ {
+ {"C", 100}, {"CC", 200}, {"CCC", 300}, {"CD", 400},
+ {"D", 500}, {"DC", 600}, {"DCC", 700}, {"DCCC", 800},
+ {"CM", 900}
+ };
+
+ auto number = -hundreds >> -tens >> -ones;
+
+ roman r;
+ BOOST_TEST((test_attr("CDXLII", number, r)));
+ BOOST_TEST(eval(r) == 442);
+ }
+
+ { // construction from initializer-list without attribute
+ symbols<> foo = {"a1", "a2", "a3"};
+
+ BOOST_TEST((test("a3", foo)));
+ }
+
+ { // assignment from initializer-list
+ symbols<> foo;
+ foo = {"a1", "a2", "a3"};
+
+ BOOST_TEST((test("a3", foo)));
+ }
+
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/spirit/test/x3/test.hpp b/src/boost/libs/spirit/test/x3/test.hpp
new file mode 100644
index 00000000..af1c22ee
--- /dev/null
+++ b/src/boost/libs/spirit/test/x3/test.hpp
@@ -0,0 +1,125 @@
+/*=============================================================================
+ Copyright (c) 2001-2013 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_TEST_FEBRUARY_01_2007_0605PM)
+#define BOOST_SPIRIT_TEST_FEBRUARY_01_2007_0605PM
+
+#include <boost/spirit/home/x3/core/parse.hpp>
+#include <boost/utility/string_view.hpp>
+#include <iostream>
+
+namespace spirit_test
+{
+ template <typename Char, typename Parser>
+ bool test(Char const* in, Parser const& p, bool full_match = true)
+ {
+ Char const* last = in;
+ while (*last)
+ last++;
+ return boost::spirit::x3::parse(in, last, p)
+ && (!full_match || (in == last));
+ }
+
+ template <typename Char, typename Parser>
+ bool test(boost::basic_string_view<Char, std::char_traits<Char>> in,
+ Parser const& p, bool full_match = true)
+ {
+ auto const last = in.end();
+ auto pos = in.begin();
+
+ return boost::spirit::x3::parse(pos, last, p) && (!full_match || (pos == last));
+ }
+
+ template <typename Char, typename Parser, typename Skipper>
+ bool test(Char const* in, Parser const& p
+ , Skipper const& s, bool full_match = true)
+ {
+ Char const* last = in;
+ while (*last)
+ last++;
+ return boost::spirit::x3::phrase_parse(in, last, p, s)
+ && (!full_match || (in == last));
+ }
+
+ template <typename Char, typename Parser>
+ bool test_failure(Char const* in, Parser const& p)
+ {
+ Char const * const start = in;
+ Char const* last = in;
+ while (*last)
+ last++;
+
+ return !boost::spirit::x3::parse(in, last, p) && (in == start);
+ }
+
+ template <typename Char, typename Parser>
+ bool test_failure(boost::basic_string_view<Char, std::char_traits<Char>> const in,
+ Parser const& p)
+ {
+ auto pos = in.begin();
+ return !boost::spirit::x3::parse(pos, in.end(), p) && (pos == in.begin());
+ }
+
+ template <typename Char, typename Parser, typename Attr>
+ bool test_attr(Char const* in, Parser const& p
+ , Attr& attr, bool full_match = true)
+ {
+ Char const* last = in;
+ while (*last)
+ last++;
+ return boost::spirit::x3::parse(in, last, p, attr)
+ && (!full_match || (in == last));
+ }
+
+ template <typename Char, typename Parser, typename Attr, typename Skipper>
+ bool test_attr(Char const* in, Parser const& p
+ , Attr& attr, Skipper const& s, bool full_match = true)
+ {
+ Char const* last = in;
+ while (*last)
+ last++;
+ return boost::spirit::x3::phrase_parse(in, last, p, s, attr)
+ && (!full_match || (in == last));
+ }
+
+ template <typename Char, typename Parser>
+ bool binary_test(Char const* in, std::size_t size, Parser const& p,
+ bool full_match = true)
+ {
+ Char const* last = in + size;
+ return boost::spirit::x3::parse(in, last, p)
+ && (!full_match || (in == last));
+ }
+
+ template <typename Char, typename Parser, typename Skipper>
+ bool binary_test(Char const* in, std::size_t size, Parser const& p,
+ Skipper const& s, bool full_match = true)
+ {
+ Char const* last = in + size;
+ return boost::spirit::x3::phrase_parse(in, last, p, s)
+ && (!full_match || (in == last));
+ }
+
+ template <typename Char, typename Parser, typename Attr>
+ bool binary_test_attr(Char const* in, std::size_t size, Parser const& p,
+ Attr& attr, bool full_match = true)
+ {
+ Char const* last = in + size;
+ return boost::spirit::x3::parse(in, last, p, attr)
+ && (!full_match || (in == last));
+ }
+
+ template <typename Char, typename Parser, typename Attr, typename Skipper>
+ bool binary_test_attr(Char const* in, std::size_t size, Parser const& p,
+ Attr& attr, Skipper const& s, bool full_match = true)
+ {
+ Char const* last = in + size;
+ return boost::spirit::x3::phrase_parse(in, last, p, s, attr)
+ && (!full_match || (in == last));
+ }
+}
+
+#endif
diff --git a/src/boost/libs/spirit/test/x3/to_utf8.cpp b/src/boost/libs/spirit/test/x3/to_utf8.cpp
new file mode 100644
index 00000000..9974e8b2
--- /dev/null
+++ b/src/boost/libs/spirit/test/x3/to_utf8.cpp
@@ -0,0 +1,28 @@
+/*=============================================================================
+ Copyright (c) 2018 Nikita Kniazev
+
+ 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)
+=============================================================================*/
+#include <boost/core/lightweight_test.hpp>
+#include <boost/spirit/home/x3/support/utility/utf8.hpp>
+
+int main()
+{
+ using boost::spirit::x3::to_utf8;
+
+ // Assume wchar_t is 16-bit on Windows and 32-bit on Unix
+#if defined(_WIN32) || defined(__CYGWIN__)
+ BOOST_TEST_CSTR_EQ("\xEF\xBF\xA1", to_utf8(L'\uFFE1').c_str());
+#else
+ BOOST_TEST_CSTR_EQ("\xF0\x9F\xA7\x90", to_utf8(L'\U0001F9D0').c_str());
+#endif
+
+ BOOST_TEST_CSTR_EQ("\xF0\x9F\xA7\x90\xF0\x9F\xA7\xA0",
+ to_utf8(L"\U0001F9D0\U0001F9E0").c_str());
+
+ BOOST_TEST_CSTR_EQ("\xF0\x9F\xA7\x90\xF0\x9F\xA7\xA0",
+ to_utf8(std::wstring(L"\U0001F9D0\U0001F9E0")).c_str());
+
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/spirit/test/x3/tst.cpp b/src/boost/libs/spirit/test/x3/tst.cpp
new file mode 100644
index 00000000..abe19a59
--- /dev/null
+++ b/src/boost/libs/spirit/test/x3/tst.cpp
@@ -0,0 +1,337 @@
+/*=============================================================================
+ Copyright (c) 2001-2015 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)
+=============================================================================*/
+#include <boost/detail/lightweight_test.hpp>
+#include <boost/spirit/home/x3/string/tst.hpp>
+#include <boost/spirit/home/x3/string/tst_map.hpp>
+#include <boost/spirit/home/x3/support/no_case.hpp>
+#include <boost/spirit/home/support/char_encoding/standard.hpp>
+#include <boost/spirit/home/support/char_encoding/standard_wide.hpp>
+#include <string>
+#include <cctype>
+#include <iostream>
+
+namespace
+{
+ template <typename TST, typename Char>
+ void add(TST& tst, Char const* s, int data)
+ {
+ Char const* last = s;
+ while (*last)
+ last++;
+ tst.add(s, last, data);
+ }
+
+ template <typename TST, typename Char>
+ void remove(TST& tst, Char const* s)
+ {
+ Char const* last = s;
+ while (*last)
+ last++;
+ tst.remove(s, last);
+ }
+
+ template <typename TST, typename Char, typename CaseCompare>
+ void docheck(TST const& tst, CaseCompare const& comp, Char const* s, bool expected, int N = 0, int val = -1)
+ {
+ Char const* first = s;
+ Char const* last = s;
+ while (*last)
+ last++;
+ int* r = tst.find(s, last,comp);
+ BOOST_TEST((r != 0) == expected);
+ if (r != 0)
+ BOOST_TEST((s-first) == N);
+ if (r)
+ BOOST_TEST(*r == val);
+ }
+
+ struct printer
+ {
+ template <typename String, typename Data>
+ void operator()(String const& s, Data const& data)
+ {
+ std::cout << " " << s << ": " << data << std::endl;
+ }
+ };
+
+ template <typename TST>
+ void print(TST const& tst)
+ {
+ std::cout << '[' << std::endl;
+ tst.for_each(printer());
+ std::cout << ']' << std::endl;
+ }
+
+}
+
+boost::spirit::x3::case_compare<boost::spirit::char_encoding::standard> ncomp;
+boost::spirit::x3::case_compare<boost::spirit::char_encoding::standard_wide> wcomp;
+boost::spirit::x3::no_case_compare<boost::spirit::char_encoding::standard> nc_ncomp;
+boost::spirit::x3::no_case_compare<boost::spirit::char_encoding::standard_wide> nc_wcomp;
+
+template <typename Lookup, typename WideLookup>
+void tests()
+{
+ { // basic tests
+ Lookup lookup;
+
+ docheck(lookup, ncomp, "not-yet-there", false);
+ docheck(lookup, ncomp, "", false);
+
+ add(lookup, "apple", 123);
+ docheck(lookup, ncomp, "apple", true, 5, 123); // full match
+ docheck(lookup, ncomp, "banana", false); // no-match
+ docheck(lookup, ncomp, "applexxx", true, 5, 123); // partial match
+
+ add(lookup, "applepie", 456);
+ docheck(lookup, ncomp, "applepie", true, 8, 456); // full match
+ docheck(lookup, ncomp, "banana", false); // no-match
+ docheck(lookup, ncomp, "applepiexxx", true, 8, 456); // partial match
+ docheck(lookup, ncomp, "apple", true, 5, 123); // full match
+ docheck(lookup, ncomp, "applexxx", true, 5, 123); // partial match
+ }
+
+ { // variation of above
+ Lookup lookup;
+
+ add(lookup, "applepie", 456);
+ add(lookup, "apple", 123);
+
+ docheck(lookup, ncomp, "applepie", true, 8, 456); // full match
+ docheck(lookup, ncomp, "banana", false); // no-match
+ docheck(lookup, ncomp, "applepiexxx", true, 8, 456); // partial match
+ docheck(lookup, ncomp, "apple", true, 5, 123); // full match
+ docheck(lookup, ncomp, "applexxx", true, 5, 123); // partial match
+ }
+ { // variation of above
+ Lookup lookup;
+
+ add(lookup, "applepie", 456);
+ add(lookup, "apple", 123);
+
+ docheck(lookup, ncomp, "applepie", true, 8, 456); // full match
+ docheck(lookup, ncomp, "banana", false); // no-match
+ docheck(lookup, ncomp, "applepiexxx", true, 8, 456); // partial match
+ docheck(lookup, ncomp, "apple", true, 5, 123); // full match
+ docheck(lookup, ncomp, "applexxx", true, 5, 123); // partial match
+ }
+
+ { // narrow char tests
+ Lookup lookup;
+ add(lookup, "pineapple", 1);
+ add(lookup, "orange", 2);
+ add(lookup, "banana", 3);
+ add(lookup, "applepie", 4);
+ add(lookup, "apple", 5);
+
+ docheck(lookup, ncomp, "pineapple", true, 9, 1);
+ docheck(lookup, ncomp, "orange", true, 6, 2);
+ docheck(lookup, ncomp, "banana", true, 6, 3);
+ docheck(lookup, ncomp, "apple", true, 5, 5);
+ docheck(lookup, ncomp, "pizza", false);
+ docheck(lookup, ncomp, "steak", false);
+ docheck(lookup, ncomp, "applepie", true, 8, 4);
+ docheck(lookup, ncomp, "bananarama", true, 6, 3);
+ docheck(lookup, ncomp, "applet", true, 5, 5);
+ docheck(lookup, ncomp, "applepi", true, 5, 5);
+ docheck(lookup, ncomp, "appl", false);
+
+ docheck(lookup, ncomp, "pineapplez", true, 9, 1);
+ docheck(lookup, ncomp, "orangez", true, 6, 2);
+ docheck(lookup, ncomp, "bananaz", true, 6, 3);
+ docheck(lookup, ncomp, "applez", true, 5, 5);
+ docheck(lookup, ncomp, "pizzaz", false);
+ docheck(lookup, ncomp, "steakz", false);
+ docheck(lookup, ncomp, "applepiez", true, 8, 4);
+ docheck(lookup, ncomp, "bananaramaz", true, 6, 3);
+ docheck(lookup, ncomp, "appletz", true, 5, 5);
+ docheck(lookup, ncomp, "applepix", true, 5, 5);
+ }
+
+ { // wide char tests
+ WideLookup lookup;
+ add(lookup, L"pineapple", 1);
+ add(lookup, L"orange", 2);
+ add(lookup, L"banana", 3);
+ add(lookup, L"applepie", 4);
+ add(lookup, L"apple", 5);
+
+ docheck(lookup, wcomp, L"pineapple", true, 9, 1);
+ docheck(lookup, wcomp, L"orange", true, 6, 2);
+ docheck(lookup, wcomp, L"banana", true, 6, 3);
+ docheck(lookup, wcomp, L"apple", true, 5, 5);
+ docheck(lookup, wcomp, L"pizza", false);
+ docheck(lookup, wcomp, L"steak", false);
+ docheck(lookup, wcomp, L"applepie", true, 8, 4);
+ docheck(lookup, wcomp, L"bananarama", true, 6, 3);
+ docheck(lookup, wcomp, L"applet", true, 5, 5);
+ docheck(lookup, wcomp, L"applepi", true, 5, 5);
+ docheck(lookup, wcomp, L"appl", false);
+
+ docheck(lookup, wcomp, L"pineapplez", true, 9, 1);
+ docheck(lookup, wcomp, L"orangez", true, 6, 2);
+ docheck(lookup, wcomp, L"bananaz", true, 6, 3);
+ docheck(lookup, wcomp, L"applez", true, 5, 5);
+ docheck(lookup, wcomp, L"pizzaz", false);
+ docheck(lookup, wcomp, L"steakz", false);
+ docheck(lookup, wcomp, L"applepiez", true, 8, 4);
+ docheck(lookup, wcomp, L"bananaramaz", true, 6, 3);
+ docheck(lookup, wcomp, L"appletz", true, 5, 5);
+ docheck(lookup, wcomp, L"applepix", true, 5, 5);
+ }
+
+ { // test remove
+ Lookup lookup;
+ add(lookup, "pineapple", 1);
+ add(lookup, "orange", 2);
+ add(lookup, "banana", 3);
+ add(lookup, "applepie", 4);
+ add(lookup, "apple", 5);
+
+ docheck(lookup, ncomp, "pineapple", true, 9, 1);
+ docheck(lookup, ncomp, "orange", true, 6, 2);
+ docheck(lookup, ncomp, "banana", true, 6, 3);
+ docheck(lookup, ncomp, "apple", true, 5, 5);
+ docheck(lookup, ncomp, "applepie", true, 8, 4);
+ docheck(lookup, ncomp, "bananarama", true, 6, 3);
+ docheck(lookup, ncomp, "applet", true, 5, 5);
+ docheck(lookup, ncomp, "applepi", true, 5, 5);
+ docheck(lookup, ncomp, "appl", false);
+
+ remove(lookup, "banana");
+ docheck(lookup, ncomp, "pineapple", true, 9, 1);
+ docheck(lookup, ncomp, "orange", true, 6, 2);
+ docheck(lookup, ncomp, "banana", false);
+ docheck(lookup, ncomp, "apple", true, 5, 5);
+ docheck(lookup, ncomp, "applepie", true, 8, 4);
+ docheck(lookup, ncomp, "bananarama", false);
+ docheck(lookup, ncomp, "applet", true, 5, 5);
+ docheck(lookup, ncomp, "applepi", true, 5, 5);
+ docheck(lookup, ncomp, "appl", false);
+
+ remove(lookup, "apple");
+ docheck(lookup, ncomp, "pineapple", true, 9, 1);
+ docheck(lookup, ncomp, "orange", true, 6, 2);
+ docheck(lookup, ncomp, "apple", false);
+ docheck(lookup, ncomp, "applepie", true, 8, 4);
+ docheck(lookup, ncomp, "applet", false);
+ docheck(lookup, ncomp, "applepi", false);
+ docheck(lookup, ncomp, "appl", false);
+
+ remove(lookup, "orange");
+ docheck(lookup, ncomp, "pineapple", true, 9, 1);
+ docheck(lookup, ncomp, "orange", false);
+ docheck(lookup, ncomp, "applepie", true, 8, 4);
+
+ remove(lookup, "pineapple");
+ docheck(lookup, ncomp, "pineapple", false);
+ docheck(lookup, ncomp, "orange", false);
+ docheck(lookup, ncomp, "applepie", true, 8, 4);
+
+ remove(lookup, "applepie");
+ docheck(lookup, ncomp, "applepie", false);
+ }
+
+ { // copy/assign/clear test
+ Lookup lookupa;
+ add(lookupa, "pineapple", 1);
+ add(lookupa, "orange", 2);
+ add(lookupa, "banana", 3);
+ add(lookupa, "applepie", 4);
+ add(lookupa, "apple", 5);
+
+ Lookup lookupb(lookupa); // copy ctor
+ docheck(lookupb, ncomp, "pineapple", true, 9, 1);
+ docheck(lookupb, ncomp, "orange", true, 6, 2);
+ docheck(lookupb, ncomp, "banana", true, 6, 3);
+ docheck(lookupb, ncomp, "apple", true, 5, 5);
+ docheck(lookupb, ncomp, "pizza", false);
+ docheck(lookupb, ncomp, "steak", false);
+ docheck(lookupb, ncomp, "applepie", true, 8, 4);
+ docheck(lookupb, ncomp, "bananarama", true, 6, 3);
+ docheck(lookupb, ncomp, "applet", true, 5, 5);
+ docheck(lookupb, ncomp, "applepi", true, 5, 5);
+ docheck(lookupb, ncomp, "appl", false);
+
+ lookupb.clear(); // clear
+ docheck(lookupb, ncomp, "pineapple", false);
+ docheck(lookupb, ncomp, "orange", false);
+ docheck(lookupb, ncomp, "banana", false);
+ docheck(lookupb, ncomp, "apple", false);
+ docheck(lookupb, ncomp, "applepie", false);
+ docheck(lookupb, ncomp, "bananarama", false);
+ docheck(lookupb, ncomp, "applet", false);
+ docheck(lookupb, ncomp, "applepi", false);
+ docheck(lookupb, ncomp, "appl", false);
+
+ lookupb = lookupa; // assign
+ docheck(lookupb, ncomp, "pineapple", true, 9, 1);
+ docheck(lookupb, ncomp, "orange", true, 6, 2);
+ docheck(lookupb, ncomp, "banana", true, 6, 3);
+ docheck(lookupb, ncomp, "apple", true, 5, 5);
+ docheck(lookupb, ncomp, "pizza", false);
+ docheck(lookupb, ncomp, "steak", false);
+ docheck(lookupb, ncomp, "applepie", true, 8, 4);
+ docheck(lookupb, ncomp, "bananarama", true, 6, 3);
+ docheck(lookupb, ncomp, "applet", true, 5, 5);
+ docheck(lookupb, ncomp, "applepi", true, 5, 5);
+ docheck(lookupb, ncomp, "appl", false);
+ }
+
+ { // test for_each
+ Lookup lookup;
+ add(lookup, "pineapple", 1);
+ add(lookup, "orange", 2);
+ add(lookup, "banana", 3);
+ add(lookup, "applepie", 4);
+ add(lookup, "apple", 5);
+
+ print(lookup);
+ }
+
+ { // case insensitive tests
+ Lookup lookup;
+
+ // NOTE: make sure all entries are in lower-case!!!
+ add(lookup, "pineapple", 1);
+ add(lookup, "orange", 2);
+ add(lookup, "banana", 3);
+ add(lookup, "applepie", 4);
+ add(lookup, "apple", 5);
+
+ docheck(lookup, nc_ncomp, "pineapple", true, 9, 1);
+ docheck(lookup, nc_ncomp, "orange", true, 6, 2);
+ docheck(lookup, nc_ncomp, "banana", true, 6, 3);
+ docheck(lookup, nc_ncomp, "apple", true, 5, 5);
+ docheck(lookup, nc_ncomp, "applepie", true, 8, 4);
+
+ docheck(lookup, nc_ncomp, "PINEAPPLE", true, 9, 1);
+ docheck(lookup, nc_ncomp, "ORANGE", true, 6, 2);
+ docheck(lookup, nc_ncomp, "BANANA", true, 6, 3);
+ docheck(lookup, nc_ncomp, "APPLE", true, 5, 5);
+ docheck(lookup, nc_ncomp, "APPLEPIE", true, 8, 4);
+
+ docheck(lookup, nc_ncomp, "pineApple", true, 9, 1);
+ docheck(lookup, nc_ncomp, "orangE", true, 6, 2);
+ docheck(lookup, nc_ncomp, "Banana", true, 6, 3);
+ docheck(lookup, nc_ncomp, "aPPLe", true, 5, 5);
+ docheck(lookup, nc_ncomp, "ApplePie", true, 8, 4);
+
+ print(lookup);
+ }
+}
+
+int main()
+{
+ using boost::spirit::x3::tst;
+ using boost::spirit::x3::tst_map;
+
+ tests<tst<char, int>, tst<wchar_t, int> >();
+//~ tests<tst_map<char, int>, tst_map<wchar_t, int> >();
+
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/spirit/test/x3/uint.hpp b/src/boost/libs/spirit/test/x3/uint.hpp
new file mode 100644
index 00000000..b7d4fb7d
--- /dev/null
+++ b/src/boost/libs/spirit/test/x3/uint.hpp
@@ -0,0 +1,59 @@
+/*=============================================================================
+ Copyright (c) 2001-2012 Joel de Guzman
+ Copyright (c) 2001-2011 Hartmut Kaiser
+ Copyright (c) 2011 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_TEST_QI_UINT_HPP)
+#define BOOST_SPIRIT_TEST_QI_UINT_HPP
+
+#include <climits>
+#include <boost/detail/lightweight_test.hpp>
+#include <boost/spirit/home/x3.hpp>
+
+#include "test.hpp"
+#include <cstring>
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// *** BEWARE PLATFORM DEPENDENT!!! ***
+// *** The following assumes 32 bit integers and 64 bit long longs.
+// *** Modify these constant strings when appropriate.
+//
+///////////////////////////////////////////////////////////////////////////////
+
+ char const* max_unsigned = "4294967295";
+ char const* unsigned_overflow = "4294967296";
+ char const* max_int = "2147483647";
+ char const* int_overflow = "2147483648";
+ char const* min_int = "-2147483648";
+ char const* int_underflow = "-2147483649";
+ char const* max_binary = "11111111111111111111111111111111";
+ char const* binary_overflow = "100000000000000000000000000000000";
+ char const* max_octal = "37777777777";
+ char const* octal_overflow = "100000000000";
+ char const* max_hex = "FFFFFFFF";
+ char const* hex_overflow = "100000000";
+
+///////////////////////////////////////////////////////////////////////////////
+// A custom int type
+struct custom_uint
+{
+ unsigned n;
+ custom_uint() : n(0) {}
+ explicit custom_uint(unsigned n_) : n(n_) {}
+ custom_uint& operator=(unsigned n_) { n = n_; return *this; }
+ friend bool operator==(custom_uint a, custom_uint b)
+ { return a.n == b.n; }
+ friend bool operator==(custom_uint a, unsigned b)
+ { return a.n == b; }
+ friend custom_uint operator*(custom_uint a, custom_uint b)
+ { return custom_uint(a.n * b.n); }
+ friend custom_uint operator+(custom_uint a, custom_uint b)
+ { return custom_uint(a.n + b.n); }
+};
+
+#endif
+
diff --git a/src/boost/libs/spirit/test/x3/uint1.cpp b/src/boost/libs/spirit/test/x3/uint1.cpp
new file mode 100644
index 00000000..7778ef0b
--- /dev/null
+++ b/src/boost/libs/spirit/test/x3/uint1.cpp
@@ -0,0 +1,211 @@
+/*=============================================================================
+ Copyright (c) 2001-2015 Joel de Guzman
+ Copyright (c) 2001-2011 Hartmut Kaiser
+ Copyright (c) 2011 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)
+=============================================================================*/
+#include "uint.hpp"
+#include <boost/spirit/home/x3.hpp>
+
+int
+main()
+{
+ using spirit_test::test;
+ using spirit_test::test_attr;
+ ///////////////////////////////////////////////////////////////////////////
+ // unsigned tests
+ ///////////////////////////////////////////////////////////////////////////
+ {
+ using boost::spirit::x3::uint_;
+ unsigned u;
+
+ BOOST_TEST(test("123456", uint_));
+ BOOST_TEST(test_attr("123456", uint_, u));
+ BOOST_TEST(u == 123456);
+
+ BOOST_TEST(test(max_unsigned, uint_));
+ BOOST_TEST(test_attr(max_unsigned, uint_, u));
+ BOOST_TEST(u == UINT_MAX);
+
+ BOOST_TEST(!test(unsigned_overflow, uint_));
+ BOOST_TEST(!test_attr(unsigned_overflow, uint_, u));
+ }
+
+ ///////////////////////////////////////////////////////////////////////////
+ // binary tests
+ ///////////////////////////////////////////////////////////////////////////
+ {
+ using boost::spirit::x3::bin;
+ unsigned u;
+
+ BOOST_TEST(test("11111110", bin));
+ BOOST_TEST(test_attr("11111110", bin, u));
+ BOOST_TEST(u == 0xFE);
+
+ BOOST_TEST(test(max_binary, bin));
+ BOOST_TEST(test_attr(max_binary, bin, u));
+ BOOST_TEST(u == UINT_MAX);
+
+ BOOST_TEST(!test(binary_overflow, bin));
+ BOOST_TEST(!test_attr(binary_overflow, bin, u));
+ }
+
+ ///////////////////////////////////////////////////////////////////////////
+ // octal tests
+ ///////////////////////////////////////////////////////////////////////////
+ {
+ using boost::spirit::x3::oct;
+ unsigned u;
+
+ BOOST_TEST(test("12545674515", oct));
+ BOOST_TEST(test_attr("12545674515", oct, u));
+ BOOST_TEST(u == 012545674515);
+
+ BOOST_TEST(test(max_octal, oct));
+ BOOST_TEST(test_attr(max_octal, oct, u));
+ BOOST_TEST(u == UINT_MAX);
+
+ BOOST_TEST(!test(octal_overflow, oct));
+ BOOST_TEST(!test_attr(octal_overflow, oct, u));
+ }
+
+ ///////////////////////////////////////////////////////////////////////////
+ // hex tests
+ ///////////////////////////////////////////////////////////////////////////
+ {
+ using boost::spirit::x3::hex;
+ unsigned u;
+
+ BOOST_TEST(test("95BC8DF", hex));
+ BOOST_TEST(test_attr("95BC8DF", hex, u));
+ BOOST_TEST(u == 0x95BC8DF);
+
+ BOOST_TEST(test("abcdef12", hex));
+ BOOST_TEST(test_attr("abcdef12", hex, u));
+ BOOST_TEST(u == 0xabcdef12);
+
+ BOOST_TEST(test(max_hex, hex));
+ BOOST_TEST(test_attr(max_hex, hex, u));
+ BOOST_TEST(u == UINT_MAX);
+
+ BOOST_TEST(!test(hex_overflow, hex));
+ BOOST_TEST(!test_attr(hex_overflow, hex, u));
+ }
+
+ ///////////////////////////////////////////////////////////////////////////
+ // limited fieldwidth
+ ///////////////////////////////////////////////////////////////////////////
+ {
+ unsigned u;
+ using boost::spirit::x3::uint_parser;
+
+ uint_parser<unsigned, 10, 1, 3> uint3;
+ BOOST_TEST(test("123456", uint3, false));
+ BOOST_TEST(test_attr("123456", uint3, u, false));
+ BOOST_TEST(u == 123);
+
+ uint_parser<unsigned, 10, 2, 4> uint4;
+ BOOST_TEST(test("123456", uint4, false));
+ BOOST_TEST(test_attr("123456", uint4, u, false));
+ BOOST_TEST(u == 1234);
+
+ char const * first = "0000000";
+ char const * last = first + std::strlen(first);
+ uint_parser<unsigned, 10, 4, 4> uint_exact4;
+ BOOST_TEST(boost::spirit::x3::parse(first, last, uint_exact4, u)
+ && first != last && (last-first == 3) && u == 0);
+
+ first = "0001400";
+ last = first + std::strlen(first);
+ BOOST_TEST(boost::spirit::x3::parse(first, last, uint_exact4, u)
+ && first != last && (last-first == 3) && u == 1);
+
+ BOOST_TEST(!test("1", uint4));
+ BOOST_TEST(!test_attr("1", uint4, u));
+ BOOST_TEST(test_attr("014567", uint4, u, false) && u == 145);
+ }
+
+ ///////////////////////////////////////////////////////////////////////////
+ // action tests
+ ///////////////////////////////////////////////////////////////////////////
+ {
+ using boost::spirit::x3::_attr;
+ using boost::spirit::x3::uint_;
+ using boost::spirit::x3::ascii::space;
+ int n;
+
+ auto f = [&](auto& ctx){ n = _attr(ctx); };
+
+ BOOST_TEST(test("123", uint_[f]));
+ BOOST_TEST(n == 123);
+ BOOST_TEST(test(" 456", uint_[f], space));
+ BOOST_TEST(n == 456);
+ }
+
+ ///////////////////////////////////////////////////////////////////////////
+ // Check overflow is parse error
+ ///////////////////////////////////////////////////////////////////////////
+ {
+ boost::spirit::x3::uint_parser<boost::uint8_t> uint8_;
+ boost::uint8_t u8;
+
+ BOOST_TEST(!test_attr("999", uint8_, u8));
+ BOOST_TEST(!test_attr("256", uint8_, u8));
+ BOOST_TEST(test_attr("255", uint8_, u8));
+
+ boost::spirit::x3::uint_parser<boost::uint16_t> uint16_;
+ boost::uint16_t u16;
+
+ BOOST_TEST(!test_attr("99999", uint16_, u16));
+ BOOST_TEST(!test_attr("65536", uint16_, u16));
+ BOOST_TEST(test_attr("65535", uint16_, u16));
+
+ boost::spirit::x3::uint_parser<boost::uint32_t> uint32_;
+ boost::uint32_t u32;
+
+ BOOST_TEST(!test_attr("9999999999", uint32_, u32));
+ BOOST_TEST(!test_attr("4294967296", uint32_, u32));
+ BOOST_TEST(test_attr("4294967295", uint32_, u32));
+
+ boost::spirit::x3::uint_parser<boost::int8_t> u_int8_;
+
+ BOOST_TEST(!test_attr("999", u_int8_, u8));
+ BOOST_TEST(!test_attr("-1", u_int8_, u8));
+ BOOST_TEST(!test_attr("128", u_int8_, u8));
+ BOOST_TEST(test_attr("127", u_int8_, u8));
+ BOOST_TEST(test_attr("0", u_int8_, u8));
+
+ boost::spirit::x3::uint_parser<boost::int16_t> u_int16_;
+
+ BOOST_TEST(!test_attr("99999", u_int16_, u16));
+ BOOST_TEST(!test_attr("-1", u_int16_, u16));
+ BOOST_TEST(!test_attr("32768", u_int16_, u16));
+ BOOST_TEST(test_attr("32767", u_int16_, u16));
+ BOOST_TEST(test_attr("0", u_int16_, u16));
+
+ boost::spirit::x3::uint_parser<boost::int32_t> u_int32_;
+
+ BOOST_TEST(!test_attr("9999999999", u_int32_, u32));
+ BOOST_TEST(!test_attr("-1", u_int32_, u32));
+ BOOST_TEST(!test_attr("2147483648", u_int32_, u32));
+ BOOST_TEST(test_attr("2147483647", u_int32_, u32));
+ BOOST_TEST(test_attr("0", u_int32_, u32));
+ }
+
+ ///////////////////////////////////////////////////////////////////////////
+ // custom uint tests
+ ///////////////////////////////////////////////////////////////////////////
+ {
+ using boost::spirit::x3::uint_;
+ using boost::spirit::x3::uint_parser;
+ custom_uint u;
+
+ BOOST_TEST(test_attr("123456", uint_, u));
+ uint_parser<custom_uint, 10, 1, 2> uint2;
+ BOOST_TEST(test_attr("12", uint2, u));
+ }
+
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/spirit/test/x3/uint_radix.cpp b/src/boost/libs/spirit/test/x3/uint_radix.cpp
new file mode 100644
index 00000000..4ae4fb0f
--- /dev/null
+++ b/src/boost/libs/spirit/test/x3/uint_radix.cpp
@@ -0,0 +1,740 @@
+/*=============================================================================
+ 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)
+=============================================================================*/
+
+#include <boost/config/warning_disable.hpp>
+#include <boost/detail/lightweight_test.hpp>
+#include <boost/spirit/home/x3.hpp>
+
+#include <climits>
+#include <cstring>
+#include "test.hpp"
+
+#include "uint_radix.hpp"
+
+int
+main()
+{
+ using spirit_test::test;
+ using spirit_test::test_attr;
+
+ using boost::spirit::x3::uint_parser;
+
+ ///////////////////////////////////////////////////////////////////////////
+ // arbitrary radix test (base 3)
+ ///////////////////////////////////////////////////////////////////////////
+ {
+ unsigned int u;
+ uint_parser<unsigned int, 3, 1, -1> base3_parser;
+
+ BOOST_TEST(test("210112221200", base3_parser));
+ BOOST_TEST(test_attr("210112221200", base3_parser, u));
+ BOOST_TEST(424242 == u);
+
+ BOOST_TEST(!test("1231", base3_parser));
+ BOOST_TEST(!test_attr("1231", base3_parser, u));
+
+ BOOST_TEST(test(max_unsigned_base3, base3_parser));
+ BOOST_TEST(test_attr(max_unsigned_base3, base3_parser, u));
+
+ BOOST_TEST(!test(unsigned_overflow_base3, base3_parser));
+ BOOST_TEST(!test_attr(unsigned_overflow_base3, base3_parser, u));
+ BOOST_TEST(!test(digit_overflow_base3, base3_parser));
+ BOOST_TEST(!test_attr(digit_overflow_base3, base3_parser, u));
+ }
+
+ ///////////////////////////////////////////////////////////////////////////
+ // arbitrary radix test (base 4)
+ ///////////////////////////////////////////////////////////////////////////
+ {
+ unsigned int u;
+
+ uint_parser<unsigned int, 4, 1, -1> base4_parser;
+
+ BOOST_TEST(test("1213210302", base4_parser));
+ BOOST_TEST(test_attr("1213210302", base4_parser, u));
+ BOOST_TEST(424242 == u);
+
+ BOOST_TEST(!test("1234", base4_parser));
+ BOOST_TEST(!test_attr("1234", base4_parser, u));
+
+ BOOST_TEST(test(max_unsigned_base4, base4_parser));
+ BOOST_TEST(test_attr(max_unsigned_base4, base4_parser, u));
+ BOOST_TEST(!test(digit_overflow_base4, base4_parser));
+ BOOST_TEST(!test_attr(digit_overflow_base4, base4_parser, u));
+ }
+
+ ///////////////////////////////////////////////////////////////////////////
+ // arbitrary radix test (base 5)
+ ///////////////////////////////////////////////////////////////////////////
+ {
+ unsigned int u;
+
+ uint_parser<unsigned int, 5, 1, -1> base5_parser;
+
+ BOOST_TEST(test("102033432", base5_parser));
+ BOOST_TEST(test_attr("102033432", base5_parser, u));
+ BOOST_TEST(424242 == u);
+
+ BOOST_TEST(!test("2345", base5_parser));
+ BOOST_TEST(!test_attr("2345", base5_parser, u));
+
+ BOOST_TEST(test(max_unsigned_base5, base5_parser));
+ BOOST_TEST(test_attr(max_unsigned_base5, base5_parser, u));
+
+ BOOST_TEST(!test(unsigned_overflow_base5, base5_parser));
+ BOOST_TEST(!test_attr(unsigned_overflow_base5, base5_parser, u));
+ BOOST_TEST(!test(digit_overflow_base5, base5_parser));
+ BOOST_TEST(!test_attr(digit_overflow_base5, base5_parser, u));
+ }
+
+ ///////////////////////////////////////////////////////////////////////////
+ // arbitrary radix test (base 6)
+ ///////////////////////////////////////////////////////////////////////////
+ {
+ unsigned int u;
+
+ uint_parser<unsigned int, 6, 1, -1> base6_parser;
+
+ BOOST_TEST(test("13032030", base6_parser));
+ BOOST_TEST(test_attr("13032030", base6_parser, u));
+ BOOST_TEST(424242 == u);
+
+ BOOST_TEST(!test("3456", base6_parser));
+ BOOST_TEST(!test_attr("3456", base6_parser, u));
+
+ BOOST_TEST(test(max_unsigned_base6, base6_parser));
+ BOOST_TEST(test_attr(max_unsigned_base6, base6_parser, u));
+
+ BOOST_TEST(!test(unsigned_overflow_base6, base6_parser));
+ BOOST_TEST(!test_attr(unsigned_overflow_base6, base6_parser, u));
+ BOOST_TEST(!test(digit_overflow_base6, base6_parser));
+ BOOST_TEST(!test_attr(digit_overflow_base6, base6_parser, u));
+ }
+
+ ///////////////////////////////////////////////////////////////////////////
+ // arbitrary radix test (base 7)
+ ///////////////////////////////////////////////////////////////////////////
+ {
+ unsigned int u;
+
+ uint_parser<unsigned int, 7, 1, -1> base7_parser;
+
+ BOOST_TEST(test("3414600", base7_parser));
+ BOOST_TEST(test_attr("3414600", base7_parser, u));
+ BOOST_TEST(424242 == u);
+
+ BOOST_TEST(!test("4567", base7_parser));
+ BOOST_TEST(!test_attr("4567", base7_parser, u));
+
+ BOOST_TEST(test(max_unsigned_base7, base7_parser));
+ BOOST_TEST(test_attr(max_unsigned_base7, base7_parser, u));
+
+ BOOST_TEST(!test(unsigned_overflow_base7, base7_parser));
+ BOOST_TEST(!test_attr(unsigned_overflow_base7, base7_parser, u));
+ BOOST_TEST(!test(digit_overflow_base7, base7_parser));
+ BOOST_TEST(!test_attr(digit_overflow_base7, base7_parser, u));
+ }
+
+ ///////////////////////////////////////////////////////////////////////////
+ // arbitrary radix test (base 9)
+ ///////////////////////////////////////////////////////////////////////////
+ {
+ unsigned int u;
+
+ uint_parser<unsigned int, 9, 1, -1> base9_parser;
+
+ BOOST_TEST(test("715850", base9_parser));
+ BOOST_TEST(test_attr("715850", base9_parser, u));
+ BOOST_TEST(424242 == u);
+
+ BOOST_TEST(!test("6789", base9_parser));
+ BOOST_TEST(!test_attr("6789", base9_parser, u));
+
+ BOOST_TEST(test(max_unsigned_base9, base9_parser));
+ BOOST_TEST(test_attr(max_unsigned_base9, base9_parser, u));
+
+ BOOST_TEST(!test(unsigned_overflow_base9, base9_parser));
+ BOOST_TEST(!test_attr(unsigned_overflow_base9, base9_parser, u));
+ BOOST_TEST(!test(digit_overflow_base9, base9_parser));
+ BOOST_TEST(!test_attr(digit_overflow_base9, base9_parser, u));
+ }
+
+ ///////////////////////////////////////////////////////////////////////////
+ // arbitrary radix test (base 11)
+ ///////////////////////////////////////////////////////////////////////////
+ {
+ unsigned int u;
+
+ uint_parser<unsigned int, 11, 1, -1> base11_parser;
+
+ BOOST_TEST(test("26a815", base11_parser));
+ BOOST_TEST(test_attr("26a815", base11_parser, u));
+ BOOST_TEST(424242 == u);
+
+ BOOST_TEST(!test("90ab", base11_parser));
+ BOOST_TEST(!test_attr("90AB", base11_parser, u));
+
+ BOOST_TEST(test(max_unsigned_base11, base11_parser));
+ BOOST_TEST(test_attr(max_unsigned_base11, base11_parser, u));
+
+ BOOST_TEST(!test(unsigned_overflow_base11, base11_parser));
+ BOOST_TEST(!test_attr(unsigned_overflow_base11, base11_parser, u));
+ BOOST_TEST(!test(digit_overflow_base11, base11_parser));
+ BOOST_TEST(!test_attr(digit_overflow_base11, base11_parser, u));
+ }
+
+ ///////////////////////////////////////////////////////////////////////////
+ // arbitrary radix test (base 12)
+ ///////////////////////////////////////////////////////////////////////////
+ {
+ unsigned int u;
+ uint_parser<unsigned int, 12, 1, -1> base12_parser;
+
+ BOOST_TEST(test("185616", base12_parser));
+ BOOST_TEST(test_attr("185616", base12_parser, u));
+ BOOST_TEST(424242 == u);
+
+ BOOST_TEST(!test("9abc", base12_parser));
+ BOOST_TEST(!test_attr("9ABC", base12_parser, u));
+
+ BOOST_TEST(test(max_unsigned_base12, base12_parser));
+ BOOST_TEST(test_attr(max_unsigned_base12, base12_parser, u));
+
+ BOOST_TEST(!test(unsigned_overflow_base12, base12_parser));
+ BOOST_TEST(!test_attr(unsigned_overflow_base12, base12_parser, u));
+ BOOST_TEST(!test(digit_overflow_base12, base12_parser));
+ BOOST_TEST(!test_attr(digit_overflow_base12, base12_parser, u));
+ }
+
+ ///////////////////////////////////////////////////////////////////////////
+ // arbitrary radix test (base 13)
+ ///////////////////////////////////////////////////////////////////////////
+ {
+ unsigned int u;
+ uint_parser<unsigned int, 13, 1, -1> base13_parser;
+
+ BOOST_TEST(test("11b140", base13_parser));
+ BOOST_TEST(test_attr("11b140", base13_parser, u));
+ BOOST_TEST(424242 == u);
+
+ BOOST_TEST(!test("abcd", base13_parser));
+ BOOST_TEST(!test_attr("ABCD", base13_parser, u));
+
+ BOOST_TEST(test(max_unsigned_base13, base13_parser));
+ BOOST_TEST(test_attr(max_unsigned_base13, base13_parser, u));
+
+ BOOST_TEST(!test(unsigned_overflow_base13, base13_parser));
+ BOOST_TEST(!test_attr(unsigned_overflow_base13, base13_parser, u));
+ BOOST_TEST(!test(digit_overflow_base13, base13_parser));
+ BOOST_TEST(!test_attr(digit_overflow_base13, base13_parser, u));
+ }
+
+ ///////////////////////////////////////////////////////////////////////////
+ // arbitrary radix test (base 14)
+ ///////////////////////////////////////////////////////////////////////////
+ {
+ unsigned int u;
+ uint_parser<unsigned int, 14, 1, -1> base14_parser;
+
+ BOOST_TEST(test("b0870", base14_parser));
+ BOOST_TEST(test_attr("b0870", base14_parser, u));
+ BOOST_TEST(424242 == u);
+
+ BOOST_TEST(!test("bcde", base14_parser));
+ BOOST_TEST(!test_attr("BCDE", base14_parser, u));
+
+ BOOST_TEST(test(max_unsigned_base14, base14_parser));
+ BOOST_TEST(test_attr(max_unsigned_base14, base14_parser, u));
+
+ BOOST_TEST(!test(unsigned_overflow_base14, base14_parser));
+ BOOST_TEST(!test_attr(unsigned_overflow_base14, base14_parser, u));
+ BOOST_TEST(!test(digit_overflow_base14, base14_parser));
+ BOOST_TEST(!test_attr(digit_overflow_base14, base14_parser, u));
+ }
+
+ ///////////////////////////////////////////////////////////////////////////
+ // arbitrary radix test (base 15)
+ ///////////////////////////////////////////////////////////////////////////
+ {
+ unsigned int u;
+ uint_parser<unsigned int, 15, 1, -1> base15_parser;
+
+ BOOST_TEST(test("85a7c", base15_parser));
+ BOOST_TEST(test_attr("85a7c", base15_parser, u));
+ BOOST_TEST(424242 == u);
+
+ BOOST_TEST(!test("cdef", base15_parser));
+ BOOST_TEST(!test_attr("CDEF", base15_parser, u));
+
+ BOOST_TEST(test(max_unsigned_base15, base15_parser));
+ BOOST_TEST(test_attr(max_unsigned_base15, base15_parser, u));
+
+ BOOST_TEST(!test(unsigned_overflow_base15, base15_parser));
+ BOOST_TEST(!test_attr(unsigned_overflow_base15, base15_parser, u));
+ BOOST_TEST(!test(digit_overflow_base15, base15_parser));
+ BOOST_TEST(!test_attr(digit_overflow_base15, base15_parser, u));
+ }
+
+ ///////////////////////////////////////////////////////////////////////////
+ // arbitrary radix test (base 17)
+ ///////////////////////////////////////////////////////////////////////////
+ {
+ unsigned int u;
+ uint_parser<unsigned int, 17, 1, -1> base17_parser;
+
+ BOOST_TEST(test("515g7", base17_parser));
+ BOOST_TEST(test_attr("515g7", base17_parser, u));
+ BOOST_TEST(424242 == u);
+
+ BOOST_TEST(!test("efgh", base17_parser));
+ BOOST_TEST(!test_attr("EFGH", base17_parser, u));
+
+ BOOST_TEST(test(max_unsigned_base17, base17_parser));
+ BOOST_TEST(test_attr(max_unsigned_base17, base17_parser, u));
+
+ BOOST_TEST(!test(unsigned_overflow_base17, base17_parser));
+ BOOST_TEST(!test_attr(unsigned_overflow_base17, base17_parser, u));
+ BOOST_TEST(!test(digit_overflow_base17, base17_parser));
+ BOOST_TEST(!test_attr(digit_overflow_base17, base17_parser, u));
+ }
+
+ ///////////////////////////////////////////////////////////////////////////
+ // arbitrary radix test (base 18)
+ ///////////////////////////////////////////////////////////////////////////
+ {
+ unsigned int u;
+ uint_parser<unsigned int, 18, 1, -1> base18_parser;
+
+ BOOST_TEST(test("40d70", base18_parser));
+ BOOST_TEST(test_attr("40d70", base18_parser, u));
+ BOOST_TEST(424242 == u);
+
+ BOOST_TEST(!test("fghi", base18_parser));
+ BOOST_TEST(!test_attr("FGHI", base18_parser, u));
+
+ BOOST_TEST(test(max_unsigned_base18, base18_parser));
+ BOOST_TEST(test_attr(max_unsigned_base18, base18_parser, u));
+
+ BOOST_TEST(!test(unsigned_overflow_base18, base18_parser));
+ BOOST_TEST(!test_attr(unsigned_overflow_base18, base18_parser, u));
+ BOOST_TEST(!test(digit_overflow_base18, base18_parser));
+ BOOST_TEST(!test_attr(digit_overflow_base18, base18_parser, u));
+ }
+
+ ///////////////////////////////////////////////////////////////////////////
+ // arbitrary radix test (base 19)
+ ///////////////////////////////////////////////////////////////////////////
+ {
+ unsigned int u;
+ uint_parser<unsigned int, 19, 1, -1> base19_parser;
+
+ BOOST_TEST(test("34g3a", base19_parser));
+ BOOST_TEST(test_attr("34g3a", base19_parser, u));
+ BOOST_TEST(424242 == u);
+
+ BOOST_TEST(!test("ghij", base19_parser));
+ BOOST_TEST(!test_attr("GHIJ", base19_parser, u));
+
+ BOOST_TEST(test(max_unsigned_base19, base19_parser));
+ BOOST_TEST(test_attr(max_unsigned_base19, base19_parser, u));
+
+ BOOST_TEST(!test(unsigned_overflow_base19, base19_parser));
+ BOOST_TEST(!test_attr(unsigned_overflow_base19, base19_parser, u));
+ BOOST_TEST(!test(digit_overflow_base19, base19_parser));
+ BOOST_TEST(!test_attr(digit_overflow_base19, base19_parser, u));
+ }
+
+ ///////////////////////////////////////////////////////////////////////////
+ // arbitrary radix test (base 20)
+ ///////////////////////////////////////////////////////////////////////////
+ {
+ unsigned int u;
+ uint_parser<unsigned int, 20, 1, -1> base20_parser;
+
+ BOOST_TEST(test("2d0c2", base20_parser));
+ BOOST_TEST(test_attr("2d0c2", base20_parser, u));
+ BOOST_TEST(424242 == u);
+
+ BOOST_TEST(!test("hijk", base20_parser));
+ BOOST_TEST(!test_attr("HIJK", base20_parser, u));
+
+ BOOST_TEST(test(max_unsigned_base20, base20_parser));
+ BOOST_TEST(test_attr(max_unsigned_base20, base20_parser, u));
+
+ BOOST_TEST(!test(unsigned_overflow_base20, base20_parser));
+ BOOST_TEST(!test_attr(unsigned_overflow_base20, base20_parser, u));
+ BOOST_TEST(!test(digit_overflow_base20, base20_parser));
+ BOOST_TEST(!test_attr(digit_overflow_base20, base20_parser, u));
+ }
+
+ ///////////////////////////////////////////////////////////////////////////
+ // arbitrary radix test (base 21)
+ ///////////////////////////////////////////////////////////////////////////
+ {
+ unsigned int u;
+ uint_parser<unsigned int, 21, 1, -1> base21_parser;
+
+ BOOST_TEST(test("23h00", base21_parser));
+ BOOST_TEST(test_attr("23h00", base21_parser, u));
+ BOOST_TEST(424242 == u);
+
+ BOOST_TEST(!test("ijkl", base21_parser));
+ BOOST_TEST(!test_attr("IJKL", base21_parser, u));
+
+ BOOST_TEST(test(max_unsigned_base21, base21_parser));
+ BOOST_TEST(test_attr(max_unsigned_base21, base21_parser, u));
+
+ BOOST_TEST(!test(unsigned_overflow_base21, base21_parser));
+ BOOST_TEST(!test_attr(unsigned_overflow_base21, base21_parser, u));
+ BOOST_TEST(!test(digit_overflow_base21, base21_parser));
+ BOOST_TEST(!test_attr(digit_overflow_base21, base21_parser, u));
+ }
+
+ ///////////////////////////////////////////////////////////////////////////
+ // arbitrary radix test (base 22)
+ ///////////////////////////////////////////////////////////////////////////
+ {
+ unsigned int u;
+ uint_parser<unsigned int, 22, 1, -1> base22_parser;
+
+ BOOST_TEST(test("1hibg", base22_parser));
+ BOOST_TEST(test_attr("1hibg", base22_parser, u));
+ BOOST_TEST(424242 == u);
+
+ BOOST_TEST(!test("jklm", base22_parser));
+ BOOST_TEST(!test_attr("JKLM", base22_parser, u));
+
+ BOOST_TEST(test(max_unsigned_base22, base22_parser));
+ BOOST_TEST(test_attr(max_unsigned_base22, base22_parser, u));
+
+ BOOST_TEST(!test(unsigned_overflow_base22, base22_parser));
+ BOOST_TEST(!test_attr(unsigned_overflow_base22, base22_parser, u));
+ BOOST_TEST(!test(digit_overflow_base22, base22_parser));
+ BOOST_TEST(!test_attr(digit_overflow_base22, base22_parser, u));
+ }
+
+ ///////////////////////////////////////////////////////////////////////////
+ // arbitrary radix test (base 23)
+ ///////////////////////////////////////////////////////////////////////////
+ {
+ unsigned int u;
+ uint_parser<unsigned int, 23, 1, -1> base23_parser;
+
+ BOOST_TEST(test("1bjm7", base23_parser));
+ BOOST_TEST(test_attr("1bjm7", base23_parser, u));
+ BOOST_TEST(424242 == u);
+
+ BOOST_TEST(!test("klmn", base23_parser));
+ BOOST_TEST(!test_attr("KLMN", base23_parser, u));
+
+ BOOST_TEST(test(max_unsigned_base23, base23_parser));
+ BOOST_TEST(test_attr(max_unsigned_base23, base23_parser, u));
+
+ BOOST_TEST(!test(unsigned_overflow_base23, base23_parser));
+ BOOST_TEST(!test_attr(unsigned_overflow_base23, base23_parser, u));
+ BOOST_TEST(!test(digit_overflow_base23, base23_parser));
+ BOOST_TEST(!test_attr(digit_overflow_base23, base23_parser, u));
+ }
+
+ ///////////////////////////////////////////////////////////////////////////
+ // arbitrary radix test (base 24)
+ ///////////////////////////////////////////////////////////////////////////
+ {
+ unsigned int u;
+ uint_parser<unsigned int, 24, 1, -1> base24_parser;
+
+ BOOST_TEST(test("16gci", base24_parser));
+ BOOST_TEST(test_attr("16gci", base24_parser, u));
+ BOOST_TEST(424242 == u);
+
+ BOOST_TEST(!test("lmno", base24_parser));
+ BOOST_TEST(!test_attr("LMNO", base24_parser, u));
+
+ BOOST_TEST(test(max_unsigned_base24, base24_parser));
+ BOOST_TEST(test_attr(max_unsigned_base24, base24_parser, u));
+
+ BOOST_TEST(!test(unsigned_overflow_base24, base24_parser));
+ BOOST_TEST(!test_attr(unsigned_overflow_base24, base24_parser, u));
+ BOOST_TEST(!test(digit_overflow_base24, base24_parser));
+ BOOST_TEST(!test_attr(digit_overflow_base24, base24_parser, u));
+ }
+
+ ///////////////////////////////////////////////////////////////////////////
+ // arbitrary radix test (base 25)
+ ///////////////////////////////////////////////////////////////////////////
+ {
+ unsigned int u;
+ uint_parser<unsigned int, 25, 1, -1> base25_parser;
+
+ BOOST_TEST(test("123jh", base25_parser));
+ BOOST_TEST(test_attr("123jh", base25_parser, u));
+ BOOST_TEST(424242 == u);
+
+ BOOST_TEST(!test("mnop", base25_parser));
+ BOOST_TEST(!test_attr("MNOP", base25_parser, u));
+
+ BOOST_TEST(test(max_unsigned_base25, base25_parser));
+ BOOST_TEST(test_attr(max_unsigned_base25, base25_parser, u));
+
+ BOOST_TEST(!test(unsigned_overflow_base25, base25_parser));
+ BOOST_TEST(!test_attr(unsigned_overflow_base25, base25_parser, u));
+ BOOST_TEST(!test(digit_overflow_base25, base25_parser));
+ BOOST_TEST(!test_attr(digit_overflow_base25, base25_parser, u));
+ }
+
+ ///////////////////////////////////////////////////////////////////////////
+ // arbitrary radix test (base 26)
+ ///////////////////////////////////////////////////////////////////////////
+ {
+ unsigned int u;
+ uint_parser<unsigned int, 26, 1, -1> base26_parser;
+
+ BOOST_TEST(test("o3f0", base26_parser));
+ BOOST_TEST(test_attr("o3f0", base26_parser, u));
+ BOOST_TEST(424242 == u);
+
+ BOOST_TEST(!test("nopq", base26_parser));
+ BOOST_TEST(!test_attr("NOPQ", base26_parser, u));
+
+ BOOST_TEST(test(max_unsigned_base26, base26_parser));
+ BOOST_TEST(test_attr(max_unsigned_base26, base26_parser, u));
+
+ BOOST_TEST(!test(unsigned_overflow_base26, base26_parser));
+ BOOST_TEST(!test_attr(unsigned_overflow_base26, base26_parser, u));
+ BOOST_TEST(!test(digit_overflow_base26, base26_parser));
+ BOOST_TEST(!test_attr(digit_overflow_base26, base26_parser, u));
+ }
+
+ ///////////////////////////////////////////////////////////////////////////
+ // arbitrary radix test (base 27)
+ ///////////////////////////////////////////////////////////////////////////
+ {
+ unsigned int u;
+ uint_parser<unsigned int, 27, 1, -1> base27_parser;
+
+ BOOST_TEST(test("lepi", base27_parser));
+ BOOST_TEST(test_attr("lepi", base27_parser, u));
+ BOOST_TEST(424242 == u);
+
+ BOOST_TEST(!test("opqr", base27_parser));
+ BOOST_TEST(!test_attr("OPQR", base27_parser, u));
+
+ BOOST_TEST(test(max_unsigned_base27, base27_parser));
+ BOOST_TEST(test_attr(max_unsigned_base27, base27_parser, u));
+
+ BOOST_TEST(!test(unsigned_overflow_base27, base27_parser));
+ BOOST_TEST(!test_attr(unsigned_overflow_base27, base27_parser, u));
+ BOOST_TEST(!test(digit_overflow_base27, base27_parser));
+ BOOST_TEST(!test_attr(digit_overflow_base27, base27_parser, u));
+ }
+
+ ///////////////////////////////////////////////////////////////////////////
+ // arbitrary radix test (base 28)
+ ///////////////////////////////////////////////////////////////////////////
+ {
+ unsigned int u;
+ uint_parser<unsigned int, 28, 1, -1> base28_parser;
+
+ BOOST_TEST(test("j93e", base28_parser));
+ BOOST_TEST(test_attr("j93e", base28_parser, u));
+ BOOST_TEST(424242 == u);
+
+ BOOST_TEST(!test("pqrs", base28_parser));
+ BOOST_TEST(!test_attr("PQRS", base28_parser, u));
+
+ BOOST_TEST(test(max_unsigned_base28, base28_parser));
+ BOOST_TEST(test_attr(max_unsigned_base28, base28_parser, u));
+
+ BOOST_TEST(!test(unsigned_overflow_base28, base28_parser));
+ BOOST_TEST(!test_attr(unsigned_overflow_base28, base28_parser, u));
+ BOOST_TEST(!test(digit_overflow_base28, base28_parser));
+ BOOST_TEST(!test_attr(digit_overflow_base28, base28_parser, u));
+ }
+
+ ///////////////////////////////////////////////////////////////////////////
+ // arbitrary radix test (base 29)
+ ///////////////////////////////////////////////////////////////////////////
+ {
+ unsigned int u;
+ uint_parser<unsigned int, 29, 1, -1> base29_parser;
+
+ BOOST_TEST(test("hbd1", base29_parser));
+ BOOST_TEST(test_attr("hbd1", base29_parser, u));
+ BOOST_TEST(424242 == u);
+
+ BOOST_TEST(!test("qrst", base29_parser));
+ BOOST_TEST(!test_attr("QRST", base29_parser, u));
+
+ BOOST_TEST(test(max_unsigned_base29, base29_parser));
+ BOOST_TEST(test_attr(max_unsigned_base29, base29_parser, u));
+
+ BOOST_TEST(!test(unsigned_overflow_base29, base29_parser));
+ BOOST_TEST(!test_attr(unsigned_overflow_base29, base29_parser, u));
+ BOOST_TEST(!test(digit_overflow_base29, base29_parser));
+ BOOST_TEST(!test_attr(digit_overflow_base29, base29_parser, u));
+ }
+
+ ///////////////////////////////////////////////////////////////////////////
+ // arbitrary radix test (base 30)
+ ///////////////////////////////////////////////////////////////////////////
+ {
+ unsigned int u;
+ uint_parser<unsigned int, 30, 1, -1> base30_parser;
+
+ BOOST_TEST(test("flbc", base30_parser));
+ BOOST_TEST(test_attr("flbc", base30_parser, u));
+ BOOST_TEST(424242 == u);
+
+ BOOST_TEST(!test("rstu", base30_parser));
+ BOOST_TEST(!test_attr("RSTU", base30_parser, u));
+
+ BOOST_TEST(test(max_unsigned_base30, base30_parser));
+ BOOST_TEST(test_attr(max_unsigned_base30, base30_parser, u));
+
+ BOOST_TEST(!test(unsigned_overflow_base30, base30_parser));
+ BOOST_TEST(!test_attr(unsigned_overflow_base30, base30_parser, u));
+ BOOST_TEST(!test(digit_overflow_base30, base30_parser));
+ BOOST_TEST(!test_attr(digit_overflow_base30, base30_parser, u));
+ }
+
+ ///////////////////////////////////////////////////////////////////////////
+ // arbitrary radix test (base 31)
+ ///////////////////////////////////////////////////////////////////////////
+ {
+ unsigned int u;
+ uint_parser<unsigned int, 31, 1, -1> base31_parser;
+
+ BOOST_TEST(test("e7e7", base31_parser));
+ BOOST_TEST(test_attr("e7e7", base31_parser, u));
+ BOOST_TEST(424242 == u);
+
+ BOOST_TEST(!test("stuv", base31_parser));
+ BOOST_TEST(!test_attr("STUV", base31_parser, u));
+
+ BOOST_TEST(test(max_unsigned_base31, base31_parser));
+ BOOST_TEST(test_attr(max_unsigned_base31, base31_parser, u));
+
+ BOOST_TEST(!test(unsigned_overflow_base31, base31_parser));
+ BOOST_TEST(!test_attr(unsigned_overflow_base31, base31_parser, u));
+ BOOST_TEST(!test(digit_overflow_base31, base31_parser));
+ BOOST_TEST(!test_attr(digit_overflow_base31, base31_parser, u));
+ }
+
+ ///////////////////////////////////////////////////////////////////////////
+ // arbitrary radix test (base 32)
+ ///////////////////////////////////////////////////////////////////////////
+ {
+ unsigned int u;
+ uint_parser<unsigned int, 32, 1, -1> base32_parser;
+
+ BOOST_TEST(test("cu9i", base32_parser));
+ BOOST_TEST(test_attr("cu9i", base32_parser, u));
+ BOOST_TEST(424242 == u);
+
+ BOOST_TEST(!test("tuvw", base32_parser));
+ BOOST_TEST(!test_attr("TUVW", base32_parser, u));
+
+ BOOST_TEST(test(max_unsigned_base32, base32_parser));
+ BOOST_TEST(test_attr(max_unsigned_base32, base32_parser, u));
+
+ BOOST_TEST(!test(unsigned_overflow_base32, base32_parser));
+ BOOST_TEST(!test_attr(unsigned_overflow_base32, base32_parser, u));
+ BOOST_TEST(!test(digit_overflow_base32, base32_parser));
+ BOOST_TEST(!test_attr(digit_overflow_base32, base32_parser, u));
+ }
+
+ ///////////////////////////////////////////////////////////////////////////
+ // arbitrary radix test (base 33)
+ ///////////////////////////////////////////////////////////////////////////
+ {
+ unsigned int u;
+ uint_parser<unsigned int, 33, 1, -1> base33_parser;
+
+ BOOST_TEST(test("bqir", base33_parser));
+ BOOST_TEST(test_attr("bqir", base33_parser, u));
+ BOOST_TEST(424242 == u);
+
+ BOOST_TEST(!test("uvwx", base33_parser));
+ BOOST_TEST(!test_attr("UVWX", base33_parser, u));
+
+ BOOST_TEST(test(max_unsigned_base33, base33_parser));
+ BOOST_TEST(test_attr(max_unsigned_base33, base33_parser, u));
+
+ BOOST_TEST(!test(unsigned_overflow_base33, base33_parser));
+ BOOST_TEST(!test_attr(unsigned_overflow_base33, base33_parser, u));
+ BOOST_TEST(!test(digit_overflow_base33, base33_parser));
+ BOOST_TEST(!test_attr(digit_overflow_base33, base33_parser, u));
+ }
+
+ ///////////////////////////////////////////////////////////////////////////
+ // arbitrary radix test (base 34)
+ ///////////////////////////////////////////////////////////////////////////
+ {
+ unsigned int u;
+ uint_parser<unsigned int, 34, 1, -1> base34_parser;
+
+ BOOST_TEST(test("aqxo", base34_parser));
+ BOOST_TEST(test_attr("aqxo", base34_parser, u));
+ BOOST_TEST(424242 == u);
+
+ BOOST_TEST(!test("vwxy", base34_parser));
+ BOOST_TEST(!test_attr("VWXY", base34_parser, u));
+
+ BOOST_TEST(test(max_unsigned_base34, base34_parser));
+ BOOST_TEST(test_attr(max_unsigned_base34, base34_parser, u));
+
+ BOOST_TEST(!test(unsigned_overflow_base34, base34_parser));
+ BOOST_TEST(!test_attr(unsigned_overflow_base34, base34_parser, u));
+ BOOST_TEST(!test(digit_overflow_base34, base34_parser));
+ BOOST_TEST(!test_attr(digit_overflow_base34, base34_parser, u));
+ }
+
+ ///////////////////////////////////////////////////////////////////////////
+ // arbitrary radix test (base 35)
+ ///////////////////////////////////////////////////////////////////////////
+ {
+ unsigned int u;
+ uint_parser<unsigned int, 35, 1, -1> base35_parser;
+
+ BOOST_TEST(test("9vb7", base35_parser));
+ BOOST_TEST(test_attr("9vb7", base35_parser, u));
+ BOOST_TEST(424242 == u);
+
+ BOOST_TEST(!test("wxyz", base35_parser));
+ BOOST_TEST(!test_attr("WXYZ", base35_parser, u));
+
+ BOOST_TEST(test(max_unsigned_base35, base35_parser));
+ BOOST_TEST(test_attr(max_unsigned_base35, base35_parser, u));
+
+ BOOST_TEST(!test(unsigned_overflow_base35, base35_parser));
+ BOOST_TEST(!test_attr(unsigned_overflow_base35, base35_parser, u));
+ BOOST_TEST(!test(digit_overflow_base35, base35_parser));
+ BOOST_TEST(!test_attr(digit_overflow_base35, base35_parser, u));
+ }
+
+ ///////////////////////////////////////////////////////////////////////////
+ // arbitrary radix test (base 36)
+ ///////////////////////////////////////////////////////////////////////////
+ {
+ unsigned int u;
+ uint_parser<unsigned int, 36, 1, -1> base36_parser;
+
+ BOOST_TEST(test("93ci", base36_parser));
+ BOOST_TEST(test_attr("93ci", base36_parser, u));
+ BOOST_TEST(424242 == u);
+
+ BOOST_TEST(test(max_unsigned_base36, base36_parser));
+ BOOST_TEST(test_attr(max_unsigned_base36, base36_parser, u));
+
+ BOOST_TEST(!test(unsigned_overflow_base36, base36_parser));
+ BOOST_TEST(!test_attr(unsigned_overflow_base36, base36_parser, u));
+ BOOST_TEST(!test(digit_overflow_base36, base36_parser));
+ BOOST_TEST(!test_attr(digit_overflow_base36, base36_parser, u));
+ }
+
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/spirit/test/x3/uint_radix.hpp b/src/boost/libs/spirit/test/x3/uint_radix.hpp
new file mode 100644
index 00000000..07b5638f
--- /dev/null
+++ b/src/boost/libs/spirit/test/x3/uint_radix.hpp
@@ -0,0 +1,142 @@
+/*=============================================================================
+ 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_TEST_X3_UINT4_HPP)
+#define BOOST_SPIRIT_TEST_X3_UINT4_HPP
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// *** BEWARE PLATFORM DEPENDENT!!! ***
+// *** The following assumes 32 bit integers and 64 bit long longs.
+// *** Modify these constant strings when appropriate.
+//
+///////////////////////////////////////////////////////////////////////////////
+
+char const* max_unsigned_base3 = "102002022201221111210";
+char const* unsigned_overflow_base3 = "102002022201221111211";
+char const* digit_overflow_base3 = "1020020222012211112100";
+
+char const* max_unsigned_base4 = "3333333333333333";
+char const* digit_overflow_base4 = "33333333333333330";
+
+char const* max_unsigned_base5 = "32244002423140";
+char const* unsigned_overflow_base5 = "32244002423141";
+char const* digit_overflow_base5 = "322440024231400";
+
+char const* max_unsigned_base6 = "1550104015503";
+char const* unsigned_overflow_base6 = "1550104015504";
+char const* digit_overflow_base6 = "15501040155030";
+
+char const* max_unsigned_base7 = "211301422353";
+char const* unsigned_overflow_base7 = "211301422354";
+char const* digit_overflow_base7 = "2113014223530";
+
+char const* max_unsigned_base9 = "12068657453";
+char const* unsigned_overflow_base9 = "12068657454";
+char const* digit_overflow_base9 = "120686574530";
+
+char const* max_unsigned_base11 = "1904440553";
+char const* unsigned_overflow_base11 = "1904440554";
+char const* digit_overflow_base11 = "19044405530";
+
+char const* max_unsigned_base12 = "9BA461593";
+char const* unsigned_overflow_base12 = "9BA461594";
+char const* digit_overflow_base12 = "9BA4615930";
+
+char const* max_unsigned_base13 = "535A79888";
+char const* unsigned_overflow_base13 = "535A79889";
+char const* digit_overflow_base13 = "535A798880";
+
+char const* max_unsigned_base14 = "2CA5B7463";
+char const* unsigned_overflow_base14 = "2CA5B7464";
+char const* digit_overflow_base14 = "2CA5B74630";
+
+char const* max_unsigned_base15 = "1A20DCD80";
+char const* unsigned_overflow_base15 = "1A20DCD81";
+char const* digit_overflow_base15 = "1A20DCD800";
+
+char const* max_unsigned_base17 = "A7FFDA90";
+char const* unsigned_overflow_base17 = "A7FFDA91";
+char const* digit_overflow_base17 = "A7FFDA900";
+
+char const* max_unsigned_base18 = "704HE7G3";
+char const* unsigned_overflow_base18 = "704HE7G4";
+char const* digit_overflow_base18 = "704HE7G30";
+
+char const* max_unsigned_base19 = "4F5AFF65";
+char const* unsigned_overflow_base19 = "4F5AFF66";
+char const* digit_overflow_base19 = "4F5AFF650";
+
+char const* max_unsigned_base20 = "3723AI4F";
+char const* unsigned_overflow_base20 = "3723AI4G";
+char const* digit_overflow_base20 = "3723AI4G0";
+
+char const* max_unsigned_base21 = "281D55I3";
+char const* unsigned_overflow_base21 = "281D55I4";
+char const* digit_overflow_base21 = "281D55I30";
+
+char const* max_unsigned_base22 = "1FJ8B183";
+char const* unsigned_overflow_base22 = "1FJ8B184";
+char const* digit_overflow_base22 = "1FJ8B1830";
+
+char const* max_unsigned_base23 = "1606K7IB";
+char const* unsigned_overflow_base23 = "1606K7IC";
+char const* digit_overflow_base23 = "1606K7IB0";
+
+char const* max_unsigned_base24 = "MB994AF";
+char const* unsigned_overflow_base24 = "MB994AG";
+char const* digit_overflow_base24 = "MB994AF0";
+
+char const* max_unsigned_base25 = "HEK2MGK";
+char const* unsigned_overflow_base25 = "HEK2MGL";
+char const* digit_overflow_base25 = "HEK2MGK0";
+
+char const* max_unsigned_base26 = "DNCHBNL";
+char const* unsigned_overflow_base26 = "DNCHBNM";
+char const* digit_overflow_base26 = "DNCHBNL0";
+
+char const* max_unsigned_base27 = "B28JPDL";
+char const* unsigned_overflow_base27 = "B28JPDM";
+char const* digit_overflow_base27 = "B28JPDL0";
+
+char const* max_unsigned_base28 = "8PFGIH3";
+char const* unsigned_overflow_base28 = "8PFGIH4";
+char const* digit_overflow_base28 = "8PFGIH30";
+
+char const* max_unsigned_base29 = "76BEIGF";
+char const* unsigned_overflow_base29 = "76BEIGH";
+char const* digit_overflow_base29 = "76BEIGF0";
+
+char const* max_unsigned_base30 = "5QMCPQF";
+char const* unsigned_overflow_base30 = "5QMCPQG";
+char const* digit_overflow_base30 = "5QMCPQF0";
+
+char const* max_unsigned_base31 = "4Q0JTO3";
+char const* unsigned_overflow_base31 = "4Q0JTO4";
+char const* digit_overflow_base31 = "4Q0JTO30";
+
+char const* max_unsigned_base32 = "3VVVVVV";
+char const* unsigned_overflow_base32 = "3VVVVVW";
+char const* digit_overflow_base32 = "3VVVVVV0";
+
+char const* max_unsigned_base33 = "3AOKQ93";
+char const* unsigned_overflow_base33 = "3AOKQ94";
+char const* digit_overflow_base33 = "3AOKQ930";
+
+char const* max_unsigned_base34 = "2QHXJLH";
+char const* unsigned_overflow_base34 = "2QHXJLI";
+char const* digit_overflow_base34 = "2QHXJLH0";
+
+char const* max_unsigned_base35 = "2BR45QA";
+char const* unsigned_overflow_base35 = "2BR45QB";
+char const* digit_overflow_base35 = "2BR45QA0";
+
+char const* max_unsigned_base36 = "1Z141Z3";
+char const* unsigned_overflow_base36 = "1Z141Z4";
+char const* digit_overflow_base36 = "1Z141Z30";
+
+#endif \ No newline at end of file
diff --git a/src/boost/libs/spirit/test/x3/unused_type.cpp b/src/boost/libs/spirit/test/x3/unused_type.cpp
new file mode 100644
index 00000000..6a660590
--- /dev/null
+++ b/src/boost/libs/spirit/test/x3/unused_type.cpp
@@ -0,0 +1,34 @@
+/*=============================================================================
+ Copyright (c) 2019 Nikita Kniazev
+
+ Use, modification and distribution is subject to 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)
+=============================================================================*/
+
+#include <boost/spirit/home/x3/support/unused.hpp>
+#include <type_traits>
+
+void test_use(boost::spirit::x3::unused_type) {}
+
+int main()
+{
+ using boost::spirit::x3::unused;
+ using boost::spirit::x3::unused_type;
+
+ static_assert(std::is_trivial<unused_type>::value, "");
+
+ unused_type unused_mut;
+ static_assert(std::is_same<decltype((unused)), unused_type const&>::value, "");
+ static_assert(std::is_same<decltype((unused_mut)), unused_type&>::value, "");
+ static_assert(std::is_same<decltype(unused = 123), unused_type const&>::value, "");
+ static_assert(std::is_same<decltype(unused = unused), unused_type const&>::value, "");
+ static_assert(std::is_same<decltype(unused = unused_mut), unused_type const&>::value, "");
+ static_assert(std::is_same<decltype(unused_mut = 123), unused_type&>::value, "");
+ static_assert(std::is_same<decltype(unused_mut = unused), unused_type&>::value, "");
+ static_assert(std::is_same<decltype(unused_mut = unused_mut), unused_type&>::value, "");
+
+ test_use(0);
+ test_use(unused);
+ test_use(unused_mut);
+}
diff --git a/src/boost/libs/spirit/test/x3/utils.hpp b/src/boost/libs/spirit/test/x3/utils.hpp
new file mode 100644
index 00000000..588f60de
--- /dev/null
+++ b/src/boost/libs/spirit/test/x3/utils.hpp
@@ -0,0 +1,48 @@
+/*=============================================================================
+ Copyright (c) 2019 Nikita Kniazev
+
+ Use, modification and distribution is subject to 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_TEST_X3_UTILS_HPP)
+#define BOOST_SPIRIT_TEST_X3_UTILS_HPP
+
+#include <boost/spirit/home/x3/core/parser.hpp>
+
+struct move_only
+{
+ move_only() = default;
+ move_only(move_only&&) = default;
+ move_only& operator=(move_only&&) = default;
+};
+
+
+template <typename T>
+struct synth_parser : boost::spirit::x3::parser<synth_parser<T>>
+{
+ typedef T attribute_type;
+
+ static bool const has_attribute = true;
+ static bool const handles_container = false;
+
+ template <typename Iterator, typename Context,
+ typename RuleContext, typename Attribute>
+ bool parse(Iterator& iter, Iterator const& last, Context const&,
+ RuleContext&, Attribute& attr) const
+ {
+ if (iter != last && *iter == 's') {
+ ++iter;
+ boost::spirit::x3::traits::move_to(attribute_type{}, attr);
+ return true;
+ }
+ return false;
+ }
+};
+
+template <typename T>
+synth_parser<T> synth{};
+
+synth_parser<move_only> const synth_move_only{};
+
+#endif
diff --git a/src/boost/libs/spirit/test/x3/with.cpp b/src/boost/libs/spirit/test/x3/with.cpp
new file mode 100644
index 00000000..8160b80e
--- /dev/null
+++ b/src/boost/libs/spirit/test/x3/with.cpp
@@ -0,0 +1,114 @@
+/*=============================================================================
+ Copyright (c) 2015 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)
+=============================================================================*/
+#include <boost/detail/lightweight_test.hpp>
+#include <boost/spirit/home/x3.hpp>
+#include "test.hpp"
+
+namespace x3 = boost::spirit::x3;
+
+struct my_tag;
+
+struct my_rule_class
+{
+ template <typename Iterator, typename Exception, typename Context>
+ x3::error_handler_result
+ on_error(Iterator&, Iterator const&, Exception const&, Context const& context)
+ {
+ x3::get<my_tag>(context)++;
+ return x3::error_handler_result::fail;
+ }
+
+ template <typename Iterator, typename Attribute, typename Context>
+ inline void
+ on_success(Iterator const&, Iterator const&, Attribute&, Context const& context)
+ {
+ x3::get<my_tag>(context)++;
+ }
+};
+
+int
+main()
+{
+ using spirit_test::test_attr;
+ using spirit_test::test;
+
+ using boost::spirit::x3::rule;
+ using boost::spirit::x3::int_;
+ using boost::spirit::x3::with;
+
+ { // injecting data into the context in the grammar
+
+ int val = 0;
+ auto r = rule<my_rule_class, char const*>() =
+ '(' > int_ > ',' > int_ > ')'
+ ;
+
+ auto start =
+ with<my_tag>(std::ref(val)) [ r ]
+ ;
+
+ BOOST_TEST(test("(123,456)", start));
+ BOOST_TEST(!test("(abc,def)", start));
+ BOOST_TEST(val == 2);
+ }
+
+ { // injecting non-const lvalue into the context
+ int val = 0;
+ auto const r = int_[([](auto& ctx){
+ x3::get<my_tag>(ctx) += x3::_attr(ctx);
+ })];
+ BOOST_TEST(test("123,456", with<my_tag>(val)[r % ',']));
+ BOOST_TEST(579 == val);
+ }
+
+ { // injecting rvalue into the context
+ auto const r1 = int_[([](auto& ctx){
+ x3::get<my_tag>(ctx) += x3::_attr(ctx);
+ })];
+ auto const r2 = rule<struct my_rvalue_rule_class, int>() =
+ x3::lit('(') >> (r1 % ',') >> x3::lit(')')[([](auto& ctx){
+ x3::_val(ctx) = x3::get<my_tag>(ctx);
+ })];
+ int attr = 0;
+ BOOST_TEST(test_attr("(1,2,3)", with<my_tag>(100)[r2], attr));
+ BOOST_TEST(106 == attr);
+ }
+
+ { // injecting const/non-const lvalue and rvalue into the context
+ struct functor {
+ int operator()(int& val) {
+ return val * 10; // non-const ref returns 10 * injected val
+ }
+ int operator()(int const& val) {
+ return val; // const ref returns injected val
+ }
+ };
+
+ auto f = [](auto& ctx){
+ x3::_val(ctx) = x3::_attr(ctx) + functor()(x3::get<my_tag>(ctx));
+ };
+ auto const r = rule<struct my_rule_class2, int>() = int_[f];
+
+ int attr = 0;
+ int const cval = 10;
+ BOOST_TEST(test_attr("5", with<my_tag>(cval)[r], attr));
+ BOOST_TEST(15 == attr); // x3::get returns const ref to cval
+
+ attr = 0;
+ int val = 10;
+ BOOST_TEST(test_attr("5", with<my_tag>(val)[r], attr));
+ BOOST_TEST(105 == attr); // x3::get returns ref to val
+
+ attr = 0;
+
+ BOOST_TEST(test_attr("5", with<my_tag>(10)[r], attr));
+ // x3::get returns ref to member variable of with_directive
+ BOOST_TEST(105 == attr);
+ }
+
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/spirit/test/x3/x3_variant.cpp b/src/boost/libs/spirit/test/x3/x3_variant.cpp
new file mode 100644
index 00000000..5a3f510c
--- /dev/null
+++ b/src/boost/libs/spirit/test/x3/x3_variant.cpp
@@ -0,0 +1,57 @@
+/*=============================================================================
+ Copyright (c) 2001-2016 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)
+=============================================================================*/
+#include <boost/detail/lightweight_test.hpp>
+#include <boost/spirit/home/x3.hpp>
+#include <boost/spirit/home/x3/support/ast/variant.hpp>
+
+#include <string>
+#include <iostream>
+#include "test.hpp"
+
+namespace x3 = boost::spirit::x3;
+
+struct none {};
+
+using variant = x3::variant<
+ none
+ , bool
+ , std::string
+ , int
+ , double
+ >;
+
+struct ast : variant
+{
+ using variant::variant;
+ using variant::operator=;
+
+ ast(char const* s)
+ : variant(std::string{s})
+ {}
+
+ ast& operator=(char const* s)
+ {
+ variant::operator=(std::string{s});
+ return *this;
+ }
+};
+
+int
+main()
+{
+ {
+ ast v{123};
+ BOOST_TEST(boost::get<int>(v) == 123);
+
+ v = "test";
+ BOOST_TEST(boost::get<std::string>(v) == "test");
+
+ v = true;
+ BOOST_TEST(boost::get<bool>(v) == true);
+ }
+ return boost::report_errors();
+}