diff options
Diffstat (limited to 'src/boost/libs/spirit/test/qi')
108 files changed, 13328 insertions, 0 deletions
diff --git a/src/boost/libs/spirit/test/qi/Jamfile b/src/boost/libs/spirit/test/qi/Jamfile new file mode 100644 index 00000000..6c2b4e8a --- /dev/null +++ b/src/boost/libs/spirit/test/qi/Jamfile @@ -0,0 +1,155 @@ +#============================================================================== +# Copyright (c) 2001-2011 Joel de Guzman +# Copyright (c) 2001-2012 Hartmut Kaiser +# Copyright (c) 2011 Bryce Lelbach +# Copyright (c) 2016-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) +#============================================================================== + +import testing ; + +############################################################################### + +project spirit-qi + : requirements + <include>. + <c++-template-depth>512 + ; + +############################################################################### + +cpp-pch pch : pch.hpp : : : <include>. <toolset>msvc:<cxxflags>"/FIpch.hpp" ; + +explicit pch ; + +############################################################################### + +local subproject-name = qi ; + +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) <pch>on-spirit:<source>pch : $(target-name) : $(default-build) ] ; +} + +rule compile ( sources + : requirements * : target-name ? ) +{ + target-name ?= $(subproject-name)_$(sources[1]:D=:S=) ; + return [ testing.compile $(sources) + : $(requirements) <pch>on-spirit:<source>pch : $(target-name) ] ; +} + +rule compile-fail ( sources + : requirements * : target-name ? ) +{ + target-name ?= $(subproject-name)_$(sources[1]:D=:S=) ; + return [ testing.compile-fail $(sources) + : $(requirements) <pch>on-spirit:<source>pch : $(target-name) ] ; +} + +############################################################################### + +compile-fail grammar_fail.cpp ; +compile-fail rule_fail.cpp ; +run actions.cpp : : : <pch>off ; # Enable PCH when boostorg/proto#13 is merged. +run actions2.cpp : : : <pch>off ; +run alternative.cpp ; +run attr.cpp ; +run attribute1.cpp ; +run attribute2.cpp ; +run and_predicate.cpp ; +run auto.cpp ; +run binary.cpp ; +run bool1.cpp ; +run bool2.cpp ; +run char1.cpp : : : <pch>off ; # Enable PCH after fixing interference from including auto. +run char2.cpp ; +run char_class.cpp : : : <pch>off ; +run debug.cpp : : : <pch>off ; +run difference.cpp ; +run encoding.cpp ; +run end.cpp ; +run eps.cpp ; +run expect.cpp ; +run expectd.cpp ; +run extract_int.cpp ; +run grammar.cpp ; +run int1.cpp ; +run int2.cpp ; +run int3.cpp ; +run kleene.cpp ; +run lazy.cpp ; +run lexeme.cpp ; +run lit1.cpp ; +run lit2.cpp ; +run list.cpp ; +run hold.cpp ; +run match_manip1.cpp ; +run match_manip2.cpp ; +run match_manip3.cpp ; +run match_manip_attr.cpp ; +run matches.cpp ; +run no_case.cpp ; +run no_skip.cpp ; +run not_predicate.cpp ; +run omit.cpp ; +run optional.cpp ; +run parse_attr.cpp ; +run pass_container1.cpp ; +run pass_container2.cpp ; +run permutation.cpp ; +run plus.cpp ; +run range_run.cpp ; +run raw.cpp ; +run real1.cpp ; +run real2.cpp ; +run real3.cpp ; +run real4.cpp ; +run real5.cpp ; +run repeat.cpp ; +run rule1.cpp ; +run rule2.cpp ; +run rule3.cpp ; +run rule4.cpp ; +run sequence.cpp ; +run sequential_or.cpp ; +run skip.cpp ; +run stream.cpp ; +run symbols1.cpp ; +run symbols2.cpp ; +run terminal_ex.cpp ; +run tst.cpp ; +run uint1.cpp ; +run uint2.cpp ; +run uint3.cpp ; +run uint_radix.cpp ; +run utree1.cpp ; +run utree2.cpp ; +run utree3.cpp ; +run utree4.cpp ; +run iterator_check.cpp ; + +compile pass_container3.cpp ; +compile regression_attr_with_action.cpp ; +compile regression_container_attribute.cpp ; +compile regression_debug_optional.cpp : <pch>off ; +compile regression_fusion_proto_spirit.cpp ; +compile regression_one_element_fusion_sequence.cpp ; +compile regression_one_element_sequence_attribute.cpp ; + +run regression_adapt_adt.cpp ; +run regression_clear.cpp ; +#run regression_float_fraction.cpp ; +run regression_lazy_repeat.cpp ; +run regression_numeric_alternatives.cpp ; +run regression_reorder.cpp ; +run regression_repeat.cpp ; +run regression_transform_assignment.cpp ; +run regression_binary_action.cpp ; +run regression_stream_eof.cpp ; + +run to_utf8.cpp : : : <pch>off ; diff --git a/src/boost/libs/spirit/test/qi/actions.cpp b/src/boost/libs/spirit/test/qi/actions.cpp new file mode 100644 index 00000000..9bd4184d --- /dev/null +++ b/src/boost/libs/spirit/test/qi/actions.cpp @@ -0,0 +1,116 @@ +/*============================================================================= + 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) +=============================================================================*/ + +#if defined(_MSC_VER) +# pragma warning(disable: 4180) // qualifier applied to function type + // has no meaning; ignored +#endif + +#include <boost/detail/lightweight_test.hpp> +#include <boost/detail/workaround.hpp> +#include <boost/spirit/include/qi_operator.hpp> +#include <boost/spirit/include/qi_numeric.hpp> +#include <boost/spirit/include/qi_char.hpp> +#include <boost/spirit/include/qi_parse.hpp> +#include <boost/spirit/include/qi_action.hpp> +#include <boost/lambda/lambda.hpp> +#include <boost/bind.hpp> +#include <cstring> + +int x = 0; + +void fun1(int const& i) +{ + x += i; +} + +void fun2(int i) +{ + x += i; +} +using boost::spirit::unused_type; + +struct fun_action +{ + void operator()(int const& i, unused_type, unused_type) const + { + x += i; + } +}; + +void fail (int, boost::spirit::unused_type, bool& pass) +{ + pass = false; +} + +struct setnext +{ + setnext(char& next) : next(next) {} + + void operator()(char c, unused_type, unused_type) const + { + next = c; + } + + char& next; +}; + +int main() +{ + namespace qi = boost::spirit::qi; + using boost::spirit::int_; + + { + char const *s1 = "{42}", *e1 = s1 + std::strlen(s1); + qi::parse(s1, e1, '{' >> int_[&fun1] >> '}'); + } + + { + char const *s1 = "{42}", *e1 = s1 + std::strlen(s1); + qi::parse(s1, e1, '{' >> int_[&fun2] >> '}'); + } + +#if !BOOST_WORKAROUND(BOOST_MSVC, <= 1400) + { + char const *s1 = "{42}", *e1 = s1 + std::strlen(s1); + qi::parse(s1, e1, '{' >> int_[fun2] >> '}'); + } +#else + x += 42; // compensate for missing test case +#endif + + { + char const *s1 = "{42}", *e1 = s1 + std::strlen(s1); + qi::parse(s1, e1, '{' >> int_[fun_action()] >> '}'); + } + + { + char const *s1 = "{42}", *e1 = s1 + std::strlen(s1); + qi::parse(s1, e1, '{' >> int_[boost::bind(&fun1, _1)] >> '}'); + } + + { + namespace lambda = boost::lambda; + char const *s1 = "{42}", *e1 = s1 + std::strlen(s1); + qi::parse(s1, e1, '{' >> int_[lambda::var(x) += lambda::_1] >> '}'); + } + BOOST_TEST(x == (42*6)); + + { + std::string input("1234 6543"); + char next = '\0'; + BOOST_TEST(qi::phrase_parse(input.begin(), input.end(), + qi::int_[fail] | qi::digit[setnext(next)] , qi::space)); + BOOST_TEST(next == '1'); + } + + return boost::report_errors(); +} + + + + diff --git a/src/boost/libs/spirit/test/qi/actions2.cpp b/src/boost/libs/spirit/test/qi/actions2.cpp new file mode 100644 index 00000000..16b42a74 --- /dev/null +++ b/src/boost/libs/spirit/test/qi/actions2.cpp @@ -0,0 +1,65 @@ +/*============================================================================= + 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) +=============================================================================*/ + +#if defined(_MSC_VER) +# pragma warning(disable: 4180) // qualifier applied to function type + // has no meaning; ignored +#endif + +// This tests the new behavior allowing attribute compatibility +// to semantic actions + +#define BOOST_SPIRIT_ACTIONS_ALLOW_ATTR_COMPAT + +#include <boost/detail/lightweight_test.hpp> +#include <boost/detail/workaround.hpp> +#include <boost/spirit/include/qi.hpp> +#include <boost/spirit/include/phoenix_bind.hpp> +#include <string> +#include "test.hpp" + +void f(std::string const& s) +{ + std::cout << "parsing got: " << s << std::endl; +} + +std::string s; +void b(char c) +{ + s += c; +} + +int main() +{ + namespace qi = boost::spirit::qi; + namespace phoenix = boost::phoenix; + using spirit_test::test_attr; + using spirit_test::test; + + { + qi::rule<char const*, std::string()> r; + r %= (+qi::char_)[phoenix::bind(&f, qi::_1)]; + + std::string attr; + BOOST_TEST(test_attr("abcdef", r, attr)); + BOOST_TEST(attr == "abcdef"); + } + + { // chaining + using namespace boost::spirit::ascii; + + s = ""; + BOOST_TEST(test("a", char_[b][b])); + BOOST_TEST(s == "aa"); + } + + return boost::report_errors(); +} + + + + diff --git a/src/boost/libs/spirit/test/qi/alternative.cpp b/src/boost/libs/spirit/test/qi/alternative.cpp new file mode 100644 index 00000000..4f7aa677 --- /dev/null +++ b/src/boost/libs/spirit/test/qi/alternative.cpp @@ -0,0 +1,265 @@ +/*============================================================================= + Copyright (c) 2001-2011 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/mpl/print.hpp> +#include <boost/spirit/include/qi_operator.hpp> +#include <boost/spirit/include/qi_char.hpp> +#include <boost/spirit/include/qi_string.hpp> +#include <boost/spirit/include/qi_numeric.hpp> +#include <boost/spirit/include/qi_directive.hpp> +#include <boost/spirit/include/qi_action.hpp> +#include <boost/spirit/include/qi_nonterminal.hpp> +#include <boost/spirit/include/qi_auxiliary.hpp> +#include <boost/spirit/include/qi_rule.hpp> +#include <boost/spirit/include/support_argument.hpp> +#include <boost/spirit/include/phoenix_core.hpp> +#include <boost/spirit/include/phoenix_operator.hpp> +#include <boost/fusion/include/adapt_struct.hpp> +#include <boost/variant.hpp> +#include <boost/assert.hpp> + +#include <string> +#include <iostream> +#include <vector> +#include "test.hpp" + +struct test_action +{ + test_action(char last) + : last_(last) {} + + template<typename Context> + void operator()(std::vector<char> const& v, Context const&, bool&) const + { + BOOST_TEST(v.size() == 4 && + v[0] == 'a' && v[1] == 'b' && v[2] == '1' && v[3] == last_); + } + + char last_; +}; + +struct test_action_2 +{ + typedef std::vector<boost::optional<char> > result_type; + + template<typename Context> + void operator()(result_type const& v, Context const&, bool&) const + { + BOOST_TEST(v.size() == 5 && + !v[0] && v[1] == 'a' && v[2] == 'b' && v[3] == '1' && v[4] == '2'); + } +}; + +struct DIgnore +{ + std::string text; +}; + +struct DInclude +{ + std::string FileName; +}; + +BOOST_FUSION_ADAPT_STRUCT( + DIgnore, + (std::string, text) +) + +BOOST_FUSION_ADAPT_STRUCT( + DInclude, + (std::string, FileName) +) + +int +main() +{ + using spirit_test::test; + using spirit_test::test_attr; + + using boost::spirit::ascii::char_; + using boost::spirit::qi::int_; + using boost::spirit::qi::lit; + using boost::spirit::qi::unused_type; + using boost::spirit::qi::_1; + using boost::spirit::qi::omit; + + { + 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_))); + } + + { + boost::variant<unused_type, int, char> v; + + BOOST_TEST((test_attr("12345", lit("rock") | int_ | char_, v))); + BOOST_TEST(boost::get<int>(v) == 12345); + + BOOST_TEST((test_attr("rock", lit("rock") | int_ | char_, v))); + BOOST_TEST(v.which() == 1); + + 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. + // $$$ Fixed: <2/19/2011> JDG $$$ + 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"); + } + + { // test action + + namespace phx = boost::phoenix; + boost::optional<boost::variant<int, char> > v; + + BOOST_TEST((test("12345", (lit("rock") | int_ | char_)[phx::ref(v) = _1]))); + BOOST_TEST(boost::get<int>(boost::get(v)) == 12345); + BOOST_TEST((test("rock", (lit("rock") | int_ | char_)[phx::ref(v) = _1]))); + BOOST_TEST(!v); + } + + { + 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::qi::rule; + using boost::spirit::qi::_val; + using boost::spirit::qi::_1; + using boost::spirit::eps; + rule<const wchar_t*, wchar_t()> r1, r2, r3; + + r3 = ((eps >> r1))[_val += _1]; + r3 = ((r1 ) | r2)[_val += _1]; + + r3 %= ((eps >> r1) | r2); + r3 = ((eps >> r1) | r2)[_val += _1]; + } + + // make sure the attribute of an alternative gets properly collapsed + { + using boost::spirit::qi::lexeme; + using boost::spirit::ascii::alnum; + using boost::spirit::ascii::alpha; + using boost::spirit::ascii::digit; + using boost::spirit::ascii::string; + namespace phx = boost::phoenix; + + + BOOST_TEST( (test("ab1_", (*(alnum | char_('_')))[test_action('_')])) ); + BOOST_TEST( (test("ab12", (*(alpha | digit))[test_action('2')])) ); + + BOOST_TEST( (test("abcab12", (*("abc" | alnum))[test_action_2()])) ); + + std::vector<boost::optional<char> > v; + BOOST_TEST( (test("x,y,z", (*(',' | char_))[phx::ref(v) = _1])) ); + BOOST_ASSERT(v[0] == 'x'); + BOOST_ASSERT(!v[1]); + BOOST_ASSERT(v[2] == 'y'); + BOOST_ASSERT(!v[3]); + BOOST_ASSERT(v[4] == 'z'); + } + + { + using boost::spirit::qi::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"); + } + + { + using boost::spirit::qi::int_; + + int i = 0; + BOOST_TEST( (test_attr("10", int_(5) | int_(10), i)) ); + BOOST_TEST(i == 10); + } + + { +#ifdef SPIRIT_NO_COMPILE_CHECK + //compile test only (bug_march_10_2011_8_35_am) + // TODO: does not work as intended with std <= c++03 + typedef boost::variant<double, std::string> value_type; + + using boost::spirit::qi::rule; + using boost::spirit::qi::eps; + rule<std::string::const_iterator, value_type()> r1 = r1 | eps; +#endif + } + + { + using boost::spirit::qi::rule; + typedef boost::variant<DIgnore, DInclude> DLine; + + rule<char*, DIgnore()> ignore; + rule<char*, DInclude()> include; + rule<char*, DLine()> line = include | ignore; + } + + return boost::report_errors(); +} + diff --git a/src/boost/libs/spirit/test/qi/and_predicate.cpp b/src/boost/libs/spirit/test/qi/and_predicate.cpp new file mode 100644 index 00000000..d3210ecb --- /dev/null +++ b/src/boost/libs/spirit/test/qi/and_predicate.cpp @@ -0,0 +1,27 @@ +/*============================================================================= + Copyright (c) 2001-2010 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/include/qi_operator.hpp> +#include <boost/spirit/include/qi_numeric.hpp> +#include <boost/spirit/include/phoenix_core.hpp> + +#include <iostream> +#include "test.hpp" + +int +main() +{ + using spirit_test::test; + using boost::spirit::int_; + + { + BOOST_TEST((test("1234", &int_, false))); + BOOST_TEST((!test("abcd", &int_))); + } + + return boost::report_errors(); +} diff --git a/src/boost/libs/spirit/test/qi/attr.cpp b/src/boost/libs/spirit/test/qi/attr.cpp new file mode 100644 index 00000000..319c9a70 --- /dev/null +++ b/src/boost/libs/spirit/test/qi/attr.cpp @@ -0,0 +1,65 @@ +/*============================================================================= + Copyright (c) 2001-2011 Hartmut Kaiser + 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 <boost/detail/lightweight_test.hpp> +#include <boost/spirit/include/qi_char.hpp> +#include <boost/spirit/include/qi_auxiliary.hpp> +#include <boost/spirit/include/qi_numeric.hpp> +#include <boost/spirit/include/qi_operator.hpp> +#include <boost/spirit/include/support_argument.hpp> +#include <boost/spirit/include/phoenix_core.hpp> +#include <boost/spirit/include/phoenix_operator.hpp> +#include <boost/fusion/include/std_pair.hpp> + +#include <iostream> +#include "test.hpp" + +int +main() +{ + using spirit_test::test_attr; + namespace qi = boost::spirit::qi; + + using qi::attr; + using qi::double_; + + { + double d = 0.0; + BOOST_TEST(test_attr("", attr(1.0), d) && d == 1.0); + + double d1 = 1.0; + BOOST_TEST(test_attr("", attr(d1), d) && d == 1.0); + + std::pair<double, double> p; + BOOST_TEST(test_attr("1.0", double_ >> attr(1.0), p) && + p.first == 1.0 && p.second == 1.0); + + char c = '\0'; + BOOST_TEST(test_attr("", attr('a'), c) && c == 'a'); + std::string str; + BOOST_TEST(test_attr("", attr("test"), str) && str == "test"); + } + + { // testing lazy constructs + using boost::phoenix::val; + using boost::phoenix::ref; + + double d = 0.0; + BOOST_TEST(test_attr("", attr(val(1.0)), d) && d == 1.0); + + double d1 = 2.0; + BOOST_TEST(test_attr("", attr(ref(d1)), d) && d == 2.0); + } + + { + std::string s; + BOOST_TEST(test_attr("s", "s" >> qi::attr(std::string("123")), s) && + s == "123"); + } + + return boost::report_errors(); +} diff --git a/src/boost/libs/spirit/test/qi/attribute1.cpp b/src/boost/libs/spirit/test/qi/attribute1.cpp new file mode 100644 index 00000000..9593b8fd --- /dev/null +++ b/src/boost/libs/spirit/test/qi/attribute1.cpp @@ -0,0 +1,177 @@ +/*============================================================================= + Copyright (c) 2001-2011 Hartmut Kaiser + 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 <boost/config/warning_disable.hpp> +#include <boost/detail/lightweight_test.hpp> + +#include <boost/spirit/include/phoenix_limits.hpp> + +#include <boost/fusion/include/struct.hpp> +#include <boost/fusion/include/nview.hpp> + +#include <boost/spirit/include/qi_char.hpp> +#include <boost/spirit/include/qi_string.hpp> +#include <boost/spirit/include/qi_numeric.hpp> +#include <boost/spirit/include/qi_operator.hpp> +#include <boost/spirit/include/qi_nonterminal.hpp> +#include <boost/spirit/include/qi_auxiliary.hpp> + +#include <iostream> +#include <vector> +#include <string> +#include "test.hpp" + +/////////////////////////////////////////////////////////////////////////////// +struct test_data +{ + std::string s1; + std::string s2; + int i1; + double d1; + std::string s3; +}; + +BOOST_FUSION_ADAPT_STRUCT( + test_data, + (int, i1) + (std::string, s1) + (std::string, s2) + (std::string, s3) + (double, d1) +) + +/////////////////////////////////////////////////////////////////////////////// +struct test_int_data1 +{ + int i; +}; + +// we provide a custom attribute transformation taking copy of the actual +// attribute value, simulating more complex type transformations +namespace boost { namespace spirit { namespace traits +{ + template <> + struct transform_attribute<test_int_data1, int, qi::domain> + { + typedef int type; + static int pre(test_int_data1& d) { return d.i; } + static void post(test_int_data1& d, int i) { d.i = i; } + static void fail(test_int_data1&) {} + }; +}}} + +/////////////////////////////////////////////////////////////////////////////// +struct test_int_data2 +{ + int i; +}; + +// we provide a simple custom attribute transformation utilizing passing the +// actual attribute by reference +namespace boost { namespace spirit { namespace traits +{ + template <> + struct transform_attribute<test_int_data2, int, qi::domain> + { + typedef int& type; + static int& pre(test_int_data2& d) { return d.i; } + static void post(test_int_data2&, int const&) {} + static void fail(test_int_data2&) {} + }; +}}} + +/////////////////////////////////////////////////////////////////////////////// +int +main() +{ + using spirit_test::test_attr; + namespace qi = boost::spirit::qi; + namespace fusion = boost::fusion; + + // testing attribute reordering in a fusion sequence as explicit attribute + { + typedef fusion::result_of::as_nview<test_data, 1, 0, 4>::type + test_view; + + test_data d1 = { "", "", 0, 0.0, "" }; + test_view v1 = fusion::as_nview<1, 0, 4>(d1); + BOOST_TEST(test_attr("s1,2,1.5", + *(qi::char_ - ',') >> ',' >> qi::int_ >> ',' >> qi::double_, v1)); + BOOST_TEST(d1.i1 == 2 && d1.s1 == "s1" && d1.d1 == 1.5); + + test_data d2 = { "", "", 0, 0.0, "" }; + test_view v2 = fusion::as_nview<1, 0, 4>(d2); + BOOST_TEST(test_attr("s1, 2, 1.5 ", + *(qi::char_ - ',') >> ',' >> qi::int_ >> ',' >> qi::double_, + v2, qi::space)); + BOOST_TEST(d2.i1 == 2 && d2.s1 == "s1" && d2.d1 == 1.5); + } + + { + // this won't work without the second template argument as *digit + // exposes a vector<char> as its attribute + std::string str; + BOOST_TEST(test_attr("123" + , qi::attr_cast<std::string, std::string>(*qi::digit), str)); + BOOST_TEST(str == "123"); + } + + // testing attribute reordering in a fusion sequence involving a rule + { + typedef fusion::result_of::as_nview<test_data, 1, 0, 4>::type + test_view; + std::vector<test_data> v; + + qi::rule<char const*, test_view()> r1 = + *(qi::char_ - ',') >> ',' >> qi::int_ >> ',' >> qi::double_; + + BOOST_TEST(test_attr("s1,2,1.5\ns2,4,3.5", r1 % qi::eol, v)); + BOOST_TEST(v.size() == 2 && + v[0].i1 == 2 && v[0].s1 == "s1" && v[0].d1 == 1.5 && + v[1].i1 == 4 && v[1].s1 == "s2" && v[1].d1 == 3.5); + + qi::rule<char const*, test_view(), qi::blank_type> r2 = + *(qi::char_ - ',') >> ',' >> qi::int_ >> ',' >> qi::double_; + + v.clear(); + BOOST_TEST(test_attr("s1, 2, 1.5 \n s2, 4, 3.5", r2 % qi::eol, v, qi::blank)); + BOOST_TEST(v.size() == 2 && + v[0].i1 == 2 && v[0].s1 == "s1" && v[0].d1 == 1.5 && + v[1].i1 == 4 && v[1].s1 == "s2" && v[1].d1 == 3.5); + } + + // testing explicit transformation if attribute needs to be copied + { + test_int_data1 d = { 0 }; + BOOST_TEST(test_attr("1", qi::attr_cast(qi::int_), d)); + BOOST_TEST(d.i == 1); + BOOST_TEST(test_attr("2", qi::attr_cast<test_int_data1>(qi::int_), d)); + BOOST_TEST(d.i == 2); + BOOST_TEST(test_attr("3", qi::attr_cast<test_int_data1, int>(qi::int_), d)); + BOOST_TEST(d.i == 3); + } + + { + std::vector<test_int_data1> v; + + BOOST_TEST(test_attr("1,2", qi::attr_cast(qi::int_) % ',', v)); + BOOST_TEST(v.size() == 2 && v[0].i == 1 && v[1].i == 2); + + v.clear(); + BOOST_TEST(test_attr("1,2" + , qi::attr_cast<test_int_data1>(qi::int_) % ',', v)); + BOOST_TEST(v.size() == 2 && v[0].i == 1 && v[1].i == 2); + + v.clear(); + BOOST_TEST(test_attr("1,2" + , qi::attr_cast<test_int_data1, int>(qi::int_) % ',', v)); + BOOST_TEST(v.size() == 2 && v[0].i == 1 && v[1].i == 2); + } + + return boost::report_errors(); +} diff --git a/src/boost/libs/spirit/test/qi/attribute2.cpp b/src/boost/libs/spirit/test/qi/attribute2.cpp new file mode 100644 index 00000000..d8167d89 --- /dev/null +++ b/src/boost/libs/spirit/test/qi/attribute2.cpp @@ -0,0 +1,189 @@ +/*============================================================================= + Copyright (c) 2001-2011 Hartmut Kaiser + 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 <boost/config/warning_disable.hpp> +#include <boost/detail/lightweight_test.hpp> + +#include <boost/spirit/include/phoenix_limits.hpp> + +#include <boost/fusion/include/struct.hpp> +#include <boost/fusion/include/nview.hpp> + +#include <boost/spirit/include/qi_char.hpp> +#include <boost/spirit/include/qi_string.hpp> +#include <boost/spirit/include/qi_numeric.hpp> +#include <boost/spirit/include/qi_operator.hpp> +#include <boost/spirit/include/qi_nonterminal.hpp> +#include <boost/spirit/include/qi_auxiliary.hpp> + +#include <iostream> +#include <vector> +#include <string> +#include "test.hpp" + +/////////////////////////////////////////////////////////////////////////////// +struct test_data +{ + std::string s1; + std::string s2; + int i1; + double d1; + std::string s3; +}; + +BOOST_FUSION_ADAPT_STRUCT( + test_data, + (int, i1) + (std::string, s1) + (std::string, s2) + (std::string, s3) + (double, d1) +) + +/////////////////////////////////////////////////////////////////////////////// +struct test_int_data1 +{ + int i; +}; + +// we provide a custom attribute transformation taking copy of the actual +// attribute value, simulating more complex type transformations +namespace boost { namespace spirit { namespace traits +{ + template <> + struct transform_attribute<test_int_data1, int, qi::domain> + { + typedef int type; + static int pre(test_int_data1& d) { return d.i; } + static void post(test_int_data1& d, int i) { d.i = i; } + static void fail(test_int_data1&) {} + }; +}}} + +/////////////////////////////////////////////////////////////////////////////// +struct test_int_data2 +{ + int i; +}; + +// we provide a simple custom attribute transformation utilizing passing the +// actual attribute by reference +namespace boost { namespace spirit { namespace traits +{ + template <> + struct transform_attribute<test_int_data2, int, qi::domain> + { + typedef int& type; + static int& pre(test_int_data2& d) { return d.i; } + static void post(test_int_data2&, int const&) {} + static void fail(test_int_data2&) {} + }; +}}} + +/////////////////////////////////////////////////////////////////////////////// +int +main() +{ + using spirit_test::test_attr; + namespace qi = boost::spirit::qi; + namespace fusion = boost::fusion; + + { + std::vector<test_int_data1> v; + qi::rule<char const*, int()> r = qi::int_; + + BOOST_TEST(test_attr("1,2", r % ',', v)); + BOOST_TEST(v.size() == 2 && v[0].i == 1 && v[1].i == 2); + } + + { + std::vector<double> v; + qi::rule<char const*, int()> r = qi::int_; + + BOOST_TEST(test_attr("1,2", r % ',', v)); + BOOST_TEST(v.size() == 2 && v[0] == 1.0 && v[1] == 2.0); + } + + { + std::vector<test_int_data1> v; + +// this won't compile as there is no defined transformation for +// test_int_data1 and double +// BOOST_TEST(test_attr("1.0,2.2", qi::attr_cast(qi::double_) % ',', v)); +// BOOST_TEST(test_attr("1.0,2.2" +// , qi::attr_cast<test_int_data1>(qi::double_) % ',', v)); + + BOOST_TEST(test_attr("1.0,2.2" + , qi::attr_cast<test_int_data1, int>(qi::double_) % ',', v)); + BOOST_TEST(v.size() == 2 && v[0].i == 1 && v[1].i == 2); + + qi::rule<char const*, int()> r = qi::double_; + + v.clear(); + BOOST_TEST(test_attr("1.0,2.0", r % ',', v)); + BOOST_TEST(v.size() == 2 && v[0].i == 1 && v[1].i == 2); + } + + // testing explicit transformation if attribute is taken by reference + { + test_int_data2 d = { 0 }; + BOOST_TEST(test_attr("1", qi::attr_cast(qi::int_), d)); + BOOST_TEST(d.i == 1); + BOOST_TEST(test_attr("2", qi::attr_cast<test_int_data2>(qi::int_), d)); + BOOST_TEST(d.i == 2); + BOOST_TEST(test_attr("3", qi::attr_cast<test_int_data2, int>(qi::int_), d)); + BOOST_TEST(d.i == 3); + } + + { + std::vector<test_int_data2> v; + + BOOST_TEST(test_attr("1,2", qi::attr_cast(qi::int_) % ',', v)); + BOOST_TEST(v.size() == 2 && v[0].i == 1 && v[1].i == 2); + + v.clear(); + BOOST_TEST(test_attr("1,2" + , qi::attr_cast<test_int_data2>(qi::int_) % ',', v)); + BOOST_TEST(v.size() == 2 && v[0].i == 1 && v[1].i == 2); + + v.clear(); + BOOST_TEST(test_attr("1,2" + , qi::attr_cast<test_int_data2, int>(qi::int_) % ',', v)); + BOOST_TEST(v.size() == 2 && v[0].i == 1 && v[1].i == 2); + } + + { + std::vector<test_int_data2> v; + qi::rule<char const*, int()> r = qi::int_; + + BOOST_TEST(test_attr("1,2", r % ',', v)); + BOOST_TEST(v.size() == 2 && v[0].i == 1 && v[1].i == 2); + } + + { + std::vector<test_int_data2> v; + +// this won't compile as there is no defined transformation for +// test_int_data2 and double +// BOOST_TEST(test_attr("1.0,2.2", qi::attr_cast(qi::double_) % ',', v)); +// BOOST_TEST(test_attr("1.0,2.2" +// , qi::attr_cast<test_int_data2>(qi::double_) % ',', v)); + + BOOST_TEST(test_attr("1.0,2.2" + , qi::attr_cast<test_int_data2, int>(qi::double_) % ',', v)); + BOOST_TEST(v.size() == 2 && v[0].i == 1 && v[1].i == 2); + + qi::rule<char const*, int()> r = qi::double_; + + v.clear(); + BOOST_TEST(test_attr("1.0,2.0", r % ',', v)); + BOOST_TEST(v.size() == 2 && v[0].i == 1 && v[1].i == 2); + } + + return boost::report_errors(); +} diff --git a/src/boost/libs/spirit/test/qi/auto.cpp b/src/boost/libs/spirit/test/qi/auto.cpp new file mode 100644 index 00000000..c64c4c97 --- /dev/null +++ b/src/boost/libs/spirit/test/qi/auto.cpp @@ -0,0 +1,247 @@ +// 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/config/warning_disable.hpp> +#include <boost/detail/lightweight_test.hpp> + +#include <boost/fusion/include/std_pair.hpp> +#include <boost/algorithm/string/predicate.hpp> + +#include <boost/spirit/include/qi_bool.hpp> +#include <boost/spirit/include/qi_char.hpp> +#include <boost/spirit/include/qi_numeric.hpp> +#include <boost/spirit/include/qi_string.hpp> +#include <boost/spirit/include/qi_nonterminal.hpp> +#include <boost/spirit/include/qi_operator.hpp> +#include <boost/spirit/include/qi_directive.hpp> +#include <boost/spirit/include/qi_auto.hpp> + +#include "test.hpp" + +namespace qi = boost::spirit::qi; +namespace traits = boost::spirit::traits; + +/////////////////////////////////////////////////////////////////////////////// +template <typename Char, typename T> +bool test_create_parser(Char const *in, T& t) +{ + Char const* last = in; + while (*last) + last++; + + BOOST_TEST((traits::meta_create_exists<qi::domain, T>::value)); + return qi::phrase_parse(in, last, qi::create_parser<T>(), qi::space, t); +} + +template <typename Char, typename T> +bool test_create_parser_auto(Char const *in, T& t) +{ + Char const* last = in; + while (*last) + last++; + + BOOST_TEST((traits::meta_create_exists<qi::domain, T>::value)); + return qi::phrase_parse(in, last, t, qi::space); +} + +template <typename Char, typename Attribute> +bool test_rule(Char const* in, Attribute const& expected) +{ + BOOST_TEST((traits::meta_create_exists<qi::domain, Attribute>::value)); + + Attribute attr = Attribute(); + qi::rule<Char const*, Attribute()> r = qi::create_parser<Attribute>(); + return spirit_test::test_attr(in, r, attr) && attr == expected; +} + +template <typename Char, typename Attribute, typename Skipper> +bool test_rule(Char const* in, Attribute const& expected, Skipper const& skipper) +{ + BOOST_TEST((traits::meta_create_exists<qi::domain, Attribute>::value)); + + Attribute attr = Attribute(); + qi::rule<Char const*, Attribute(), Skipper> r = qi::create_parser<Attribute>(); + return spirit_test::test_attr(in, r, attr, skipper) && attr == expected; +} + +struct my_type {}; + +/////////////////////////////////////////////////////////////////////////////// +int main() +{ + { + BOOST_TEST((!traits::meta_create_exists<qi::domain, my_type>::value)); + } + + { + // test primitive types + bool b = false; + BOOST_TEST(test_create_parser("true", b) && b == true); + int i = 0; + BOOST_TEST(test_create_parser("1", i) && i == 1); + double d = 0; + BOOST_TEST(test_create_parser("1.1", d) && d == 1.1); + char c = '\0'; + BOOST_TEST(test_create_parser("a", c) && c == 'a'); + wchar_t wc = L'\0'; + BOOST_TEST(test_create_parser(L"a", wc) && wc == L'a'); + + // test containers + std::vector<int> v; + BOOST_TEST(test_create_parser("0 1 2", v) && v.size() == 3 && + v[0] == 0 && v[1] == 1 && v[2] == 2); + + std::list<int> l; + BOOST_TEST(test_create_parser("0 1 2", l) && l.size() == 3 && + *l.begin() == 0 && *(++l.begin()) == 1 && *(++ ++l.begin()) == 2); + + // test optional + boost::optional<int> o; + BOOST_TEST(test_create_parser("", o) && !o); + BOOST_TEST(test_create_parser("1", o) && !!o && boost::get<int>(o) == 1); + + // test alternative + boost::variant<double, bool, std::vector<char> > vv; + BOOST_TEST(test_create_parser("true", vv) && vv.which() == 1 && + boost::get<bool>(vv) == true); + BOOST_TEST(test_create_parser("1.0", vv) && vv.which() == 0 && + boost::get<double>(vv) == 1.0); + BOOST_TEST(test_create_parser("some_string", vv) && vv.which() == 2 && + boost::equals(boost::get<std::vector<char> >(vv), "some_string")); + + // test fusion sequence + std::pair<int, double> p; + BOOST_TEST(test_create_parser("1 2.0", p) && + p.first == 1 && p.second == 2.0); + } + + { + // test containers + std::vector<int> v; + BOOST_TEST(test_create_parser_auto("0 1 2", v) && v.size() == 3 && + v[0] == 0 && v[1] == 1 && v[2] == 2); + + std::list<int> l; + BOOST_TEST(test_create_parser_auto("0 1 2", l) && l.size() == 3 && + *l.begin() == 0 && *(++l.begin()) == 1 && *(++ ++l.begin()) == 2); + + // test optional + boost::optional<int> o; + BOOST_TEST(test_create_parser_auto("", o) && !o); + BOOST_TEST(test_create_parser_auto("1", o) && !!o && boost::get<int>(o) == 1); + + // test alternative + boost::variant<double, bool, std::vector<char> > vv; + BOOST_TEST(test_create_parser_auto("true", vv) && vv.which() == 1 && + boost::get<bool>(vv) == true); + BOOST_TEST(test_create_parser_auto("1.0", vv) && vv.which() == 0 && + boost::get<double>(vv) == 1.0); + BOOST_TEST(test_create_parser_auto("some_string", vv) && vv.which() == 2 && + boost::equals(boost::get<std::vector<char> >(vv), "some_string")); + + // test fusion sequence + std::pair<int, double> p; + BOOST_TEST(test_create_parser_auto("1 2.0", p) && + p.first == 1 && p.second == 2.0); + } + + { + using qi::auto_; + using qi::no_case; + using spirit_test::test_attr; + + // test primitive types + bool b = false; + BOOST_TEST(test_attr("true", auto_, b) && b == true); + int i = 0; + BOOST_TEST(test_attr("1", auto_, i) && i == 1); + double d = 0; + BOOST_TEST(test_attr("1.1", auto_, d) && d == 1.1); + char c = '\0'; + BOOST_TEST(test_attr("a", auto_, c) && c == 'a'); + wchar_t wc = L'\0'; + BOOST_TEST(test_attr(L"a", auto_, wc) && wc == L'a'); + + b = false; + BOOST_TEST(test_attr("TRUE", no_case[auto_], b) && b == true); + + // test containers + std::vector<int> v; + BOOST_TEST(test_attr("0 1 2", auto_, v, qi::space) && v.size() == 3 && + v[0] == 0 && v[1] == 1 && v[2] == 2); + v.clear(); + BOOST_TEST(test_attr("0,1,2", auto_ % ',', v) && v.size() == 3 && + v[0] == 0 && v[1] == 1 && v[2] == 2); + + std::list<int> l; + BOOST_TEST(test_attr("0 1 2", auto_, l, qi::space) && l.size() == 3 && + *l.begin() == 0 && *(++l.begin()) == 1 && *(++ ++l.begin()) == 2); + l.clear(); + BOOST_TEST(test_attr("0,1,2", auto_ % ',', l) && l.size() == 3 && + *l.begin() == 0 && *(++l.begin()) == 1 && *(++ ++l.begin()) == 2); + + // test optional + boost::optional<int> o; + BOOST_TEST(test_attr("", auto_, o) && !o); + BOOST_TEST(test_attr("1", auto_, o) && !!o && boost::get<int>(o) == 1); + + // test alternative + boost::variant<double, bool, std::vector<char> > vv; + BOOST_TEST(test_attr("true", auto_, vv) && vv.which() == 1 && + boost::get<bool>(vv) == true); + BOOST_TEST(test_attr("1.0", auto_, vv) && vv.which() == 0 && + boost::get<double>(vv) == 1.0); + BOOST_TEST(test_create_parser("some_string", vv) && vv.which() == 2 && + boost::equals(boost::get<std::vector<char> >(vv), "some_string")); + + // test fusion sequence + std::pair<int, double> p; + BOOST_TEST(test_attr("1 2.0", auto_, p, qi::space) && + p.first == 1 && p.second == 2.0); + } + + { + // test primitive types + BOOST_TEST(test_rule("true", true)); + BOOST_TEST(test_rule("1", 1)); + BOOST_TEST(test_rule("1.1", 1.1)); + + // test containers + std::vector<int> v; + v.push_back(0); + v.push_back(1); + v.push_back(2); + BOOST_TEST(test_rule("0 1 2", v, qi::space)); + + std::list<int> l; + l.push_back(0); + l.push_back(1); + l.push_back(2); + BOOST_TEST(test_rule("0 1 2", l, qi::space)); + + // test optional + boost::optional<int> o; + BOOST_TEST(test_rule("", o)); + o = 1; + BOOST_TEST(test_rule("1", o)); + + // test alternative +// boost::variant<int, double, float, std::string> vv; +// vv = 1; +// BOOST_TEST(test_rule("1", vv)); +// vv = 1.0; +// BOOST_TEST(test_rule("1.0", vv)); +// vv = 1.0f; +// BOOST_TEST(test_rule("1.0", vv)); +// vv = "some string"; +// BOOST_TEST(test_rule("some string", vv)); + + // test fusion sequence + std::pair<int, double> p (1, 2.0); + BOOST_TEST(test_rule("1 2.0", p, qi::space)); + } + + return boost::report_errors(); +} diff --git a/src/boost/libs/spirit/test/qi/binary.cpp b/src/boost/libs/spirit/test/qi/binary.cpp new file mode 100644 index 00000000..912d5b1c --- /dev/null +++ b/src/boost/libs/spirit/test/qi/binary.cpp @@ -0,0 +1,156 @@ +/*============================================================================= + 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/include/support_argument.hpp> +#include <boost/spirit/include/qi_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::qi::byte_; + using boost::spirit::qi::word; + using boost::spirit::qi::dword; + using boost::spirit::qi::big_word; + using boost::spirit::qi::big_dword; + using boost::spirit::qi::little_word; + using boost::spirit::qi::little_dword; +#ifdef BOOST_HAS_LONG_LONG + using boost::spirit::qi::qword; + using boost::spirit::qi::big_qword; + using boost::spirit::qi::little_qword; +#endif + using boost::spirit::qi::bin_float; + using boost::spirit::qi::big_bin_float; + using boost::spirit::qi::little_bin_float; + using boost::spirit::qi::bin_double; + using boost::spirit::qi::big_bin_double; + using boost::spirit::qi::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/qi/bool.hpp b/src/boost/libs/spirit/test/qi/bool.hpp new file mode 100644 index 00000000..571e41c3 --- /dev/null +++ b/src/boost/libs/spirit/test/qi/bool.hpp @@ -0,0 +1,47 @@ +/*============================================================================= + 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/include/support_argument.hpp> +#include <boost/spirit/include/qi_char.hpp> +#include <boost/spirit/include/qi_numeric.hpp> +#include <boost/spirit/include/qi_directive.hpp> +#include <boost/cstdint.hpp> +#include "test.hpp" + +/////////////////////////////////////////////////////////////////////////////// +struct backwards_bool_policies : boost::spirit::qi::bool_policies<> +{ + // we want to interpret a 'true' spelled backwards as 'false' + template <typename Iterator, typename Attribute> + static bool + parse_false(Iterator& first, Iterator const& last, Attribute& attr) + { + namespace spirit = boost::spirit; + namespace qi = boost::spirit::qi; + if (qi::detail::string_parse("eurt", first, last, qi::unused)) + { + spirit::traits::assign_to(false, attr); // result is false + return true; + } + return false; + } +}; + +/////////////////////////////////////////////////////////////////////////////// +struct test_bool_type +{ + test_bool_type(bool b) : b(b) {} // provide conversion + bool b; +}; + +#endif + diff --git a/src/boost/libs/spirit/test/qi/bool1.cpp b/src/boost/libs/spirit/test/qi/bool1.cpp new file mode 100644 index 00000000..7b07e872 --- /dev/null +++ b/src/boost/libs/spirit/test/qi/bool1.cpp @@ -0,0 +1,84 @@ +/*============================================================================= + 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::qi::bool_; + + { + BOOST_TEST(test("true", bool_)); + BOOST_TEST(test("false", bool_)); + BOOST_TEST(!test("fasle", bool_)); + } + + { + using boost::spirit::qi::true_; + using boost::spirit::qi::false_; + + BOOST_TEST(test("true", true_)); + BOOST_TEST(!test("true", false_)); + BOOST_TEST(test("false", false_)); + BOOST_TEST(!test("false", true_)); + } + + { + using boost::spirit::qi::true_; + using boost::spirit::qi::false_; + using boost::spirit::qi::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::qi::bool_parser<bool, 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::qi::bool_parser<test_bool_type> + 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/qi/bool2.cpp b/src/boost/libs/spirit/test/qi/bool2.cpp new file mode 100644 index 00000000..b1461b09 --- /dev/null +++ b/src/boost/libs/spirit/test/qi/bool2.cpp @@ -0,0 +1,88 @@ +/*============================================================================= + 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::qi::bool_; + using boost::spirit::qi::lit; + using boost::spirit::qi::no_case; + + { + BOOST_TEST(test("true", bool_(true))); + BOOST_TEST(test("false", bool_(false))); + BOOST_TEST(!test("fasle", bool_(false))); + BOOST_TEST(!test("false", bool_(true))); + BOOST_TEST(!test("true", bool_(false))); + } + + { + BOOST_TEST(test("True", no_case[bool_(true)])); + BOOST_TEST(test("False", no_case[bool_(false)])); + BOOST_TEST(test("TRUE", no_case[bool_(true)])); + BOOST_TEST(test("FALSE", no_case[bool_(false)])); + BOOST_TEST(!test("True", no_case[bool_(false)])); + BOOST_TEST(!test("False", no_case[bool_(true)])); + } + + { + bool b = false; + BOOST_TEST(test_attr("true", bool_(true), b) && b); + BOOST_TEST(test_attr("false", bool_(false), b) && !b); + BOOST_TEST(!test_attr("fasle", bool_(false), b)); + } + + { + typedef boost::spirit::qi::bool_parser<bool, backwards_bool_policies> + backwards_bool_type; + backwards_bool_type const backwards_bool = backwards_bool_type(); + + BOOST_TEST(test("true", backwards_bool(true))); + BOOST_TEST(test("eurt", backwards_bool(false))); + BOOST_TEST(!test("true", backwards_bool(false))); + BOOST_TEST(!test("eurt", backwards_bool(true))); + } + + { + using boost::phoenix::ref; + bool n = true, m = false; + + BOOST_TEST(test("true", bool_(ref(n)))); + BOOST_TEST(!test("true", bool_(ref(m)))); + } + + { + BOOST_TEST(test("true", lit(true))); + BOOST_TEST(test("false", lit(false))); + BOOST_TEST(!test("fasle", lit(false))); + BOOST_TEST(!test("false", lit(true))); + BOOST_TEST(!test("true", lit(false))); + } + + { + BOOST_TEST(test("True", no_case[lit(true)])); + BOOST_TEST(test("False", no_case[lit(false)])); + BOOST_TEST(test("TRUE", no_case[lit(true)])); + BOOST_TEST(test("FALSE", no_case[lit(false)])); + BOOST_TEST(!test("True", no_case[lit(false)])); + BOOST_TEST(!test("False", no_case[lit(true)])); + } + + { + using boost::phoenix::ref; + bool n = true, m = false; + + BOOST_TEST(test("true", lit(ref(n)))); + BOOST_TEST(!test("true", lit(ref(m)))); + } + + return boost::report_errors(); +} diff --git a/src/boost/libs/spirit/test/qi/char1.cpp b/src/boost/libs/spirit/test/qi/char1.cpp new file mode 100644 index 00000000..a0e7668d --- /dev/null +++ b/src/boost/libs/spirit/test/qi/char1.cpp @@ -0,0 +1,175 @@ +/*============================================================================= + Copyright (c) 2001-2011 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/include/qi_char.hpp> +#include <boost/spirit/include/qi_action.hpp> +#include <boost/spirit/include/phoenix_core.hpp> +#include <boost/spirit/include/phoenix_operator.hpp> + +#include <iostream> +#include "test.hpp" + +int +main() +{ + using spirit_test::test; + using spirit_test::test_attr; + using spirit_test::print_info; + + { + using namespace boost::spirit::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::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::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'))); + } + + + { // single char strings! + namespace ascii = boost::spirit::ascii; + namespace wide = boost::spirit::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::ascii; + namespace wide = boost::spirit::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 + } + + { // lazy chars + + using namespace boost::spirit::ascii; + + using boost::phoenix::val; + using boost::phoenix::ref; + using boost::spirit::_1; + + BOOST_TEST((test("x", char_(val('x'))))); + BOOST_TEST((test("h", char_(val('a'), val('n'))))); + BOOST_TEST(test("0", char_(val("a-z0-9")))); + + char ch; // make sure lazy chars have an attribute + BOOST_TEST(test("x", char_(val('x'))[ref(ch) = _1])); + BOOST_TEST(ch == 'x'); + } + + { // testing "what" + + using boost::spirit::qi::what; + using boost::spirit::ascii::char_; + using boost::spirit::ascii::alpha; + + print_info(what('x')); + print_info(what(char_('a','z'))); + print_info(what(alpha)); + } + + { + namespace ascii = boost::spirit::qi::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/qi/char2.cpp b/src/boost/libs/spirit/test/qi/char2.cpp new file mode 100644 index 00000000..72c1f5ba --- /dev/null +++ b/src/boost/libs/spirit/test/qi/char2.cpp @@ -0,0 +1,71 @@ +/*============================================================================= + Copyright (c) 2001-2011 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/include/qi_char.hpp> +#include <boost/spirit/include/qi_action.hpp> +#include <boost/spirit/include/phoenix_core.hpp> +#include <boost/spirit/include/phoenix_operator.hpp> + +#include <iostream> +#include "test.hpp" + +int +main() +{ + using spirit_test::test; + using spirit_test::test_attr; + using spirit_test::print_info; + + { + using boost::spirit::qi::lit; + + BOOST_TEST(test("x", lit('x'))); + BOOST_TEST(!test("x", lit('y'))); + + BOOST_TEST(!test("x", ~lit('x'))); + BOOST_TEST(test(" ", ~lit('x'))); + BOOST_TEST(test("X", ~lit('x'))); + + BOOST_TEST(test("x", ~~lit('x'))); + BOOST_TEST(!test(" ", ~~lit('x'))); + BOOST_TEST(!test("X", ~~lit('x'))); + } + + { + using boost::spirit::qi::lit; + using boost::spirit::qi::space; + + BOOST_TEST(test(" x", lit('x'), space)); + BOOST_TEST(!test(" x", lit('y'), space)); + } + + { + using boost::spirit::qi::lit; + + BOOST_TEST(test(L"x", lit(L'x'))); + BOOST_TEST(!test(L"x", lit(L'y'))); + + BOOST_TEST(!test(L"x", ~lit(L'x'))); + BOOST_TEST(test(L" ", ~lit(L'x'))); + BOOST_TEST(test(L"X", ~lit(L'x'))); + + BOOST_TEST(test(L"x", ~~lit(L'x'))); + BOOST_TEST(!test(L" ", ~~lit(L'x'))); + BOOST_TEST(!test(L"X", ~~lit(L'x'))); + } + + { // lazy chars + using boost::spirit::qi::lit; + + using boost::phoenix::val; + + BOOST_TEST((test("x", lit(val('x'))))); + } + + return boost::report_errors(); +} diff --git a/src/boost/libs/spirit/test/qi/char_class.cpp b/src/boost/libs/spirit/test/qi/char_class.cpp new file mode 100644 index 00000000..2ee25e7d --- /dev/null +++ b/src/boost/libs/spirit/test/qi/char_class.cpp @@ -0,0 +1,235 @@ +/*============================================================================= + Copyright (c) 2001-2010 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_UNICODE + +#include <boost/detail/lightweight_test.hpp> +#include <boost/spirit/include/qi_char.hpp> +#include <boost/spirit/include/qi_action.hpp> +#include <boost/spirit/include/support_argument.hpp> +#include <boost/spirit/include/support_attributes.hpp> +#include <boost/spirit/include/phoenix_core.hpp> +#include <boost/spirit/include/phoenix_operator.hpp> +#include <boost/type_traits/is_same.hpp> +#include <boost/static_assert.hpp> + +#include <iostream> +#include "test.hpp" + +int +main() +{ + using spirit_test::test; + using spirit_test::test_attr; + + { + using namespace boost::spirit::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)); + + // should fail, not assert! + // $$$ Removing this test for now $$$ + // BOOST_TEST(!test("\265", space)); + } + + { + using namespace boost::spirit::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)); + } + + { + // we use the hoisted qi namespace this time + using namespace boost::spirit::qi::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::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::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::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)); + } + + { // test attribute extraction + using boost::spirit::qi::domain; + using boost::spirit::traits::attribute_of; + using boost::spirit::iso8859_1::alpha; + using boost::spirit::iso8859_1::alpha_type; + using boost::spirit::result_of::compile; + + BOOST_STATIC_ASSERT(( + boost::is_same< + attribute_of<compile<domain, alpha_type>::type>::type + , unsigned char>::value)); + + int attr = 0; + BOOST_TEST(test_attr("a", alpha, attr)); + BOOST_TEST(attr == 'a'); + } + + { // test attribute extraction + using boost::spirit::iso8859_1::alpha; + using boost::spirit::iso8859_1::space; + char attr = 0; + BOOST_TEST(test_attr(" a", alpha, attr, space)); + BOOST_TEST(attr == 'a'); + } + + { // test action + + using namespace boost::spirit::ascii; + using boost::phoenix::ref; + using boost::spirit::_1; + char ch; + + BOOST_TEST(test("x", alnum[ref(ch) = _1])); + BOOST_TEST(ch == 'x'); + BOOST_TEST(test(" A", alnum[ref(ch) = _1], space)); + BOOST_TEST(ch == 'A'); + } + + return boost::report_errors(); +} diff --git a/src/boost/libs/spirit/test/qi/debug.cpp b/src/boost/libs/spirit/test/qi/debug.cpp new file mode 100644 index 00000000..f32dacf9 --- /dev/null +++ b/src/boost/libs/spirit/test/qi/debug.cpp @@ -0,0 +1,131 @@ +/*============================================================================= + Copyright (c) 2001-2010 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_DEBUG + +#include <boost/detail/lightweight_test.hpp> +#include <boost/spirit/include/qi_operator.hpp> +#include <boost/spirit/include/qi_char.hpp> +#include <boost/spirit/include/qi_string.hpp> +#include <boost/spirit/include/qi_numeric.hpp> +#include <boost/spirit/include/qi_auxiliary.hpp> +#include <boost/spirit/include/qi_nonterminal.hpp> +#include <boost/spirit/include/qi_action.hpp> +#include <boost/spirit/include/phoenix_core.hpp> +#include <boost/spirit/include/phoenix_operator.hpp> +#include <boost/spirit/include/phoenix_object.hpp> +#include <boost/spirit/include/phoenix_bind.hpp> +#include <boost/fusion/include/std_pair.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::ascii; + using namespace boost::spirit::qi::labels; + using boost::spirit::qi::locals; + using boost::spirit::qi::rule; + using boost::spirit::qi::int_; + using boost::spirit::qi::fail; + using boost::spirit::qi::on_error; + using boost::spirit::qi::debug; + using boost::spirit::qi::alpha; + + namespace phx = boost::phoenix; + + { // basic tests + + rule<char const*> a, b, c, start; + + a = 'a'; + b = 'b'; + c = 'c'; + BOOST_SPIRIT_DEBUG_NODE(a); + BOOST_SPIRIT_DEBUG_NODE(b); + BOOST_SPIRIT_DEBUG_NODE(c); + + start = *(a | b | c); + BOOST_SPIRIT_DEBUG_NODE(start); + BOOST_TEST(test("abcabcacb", start)); + + start = (a | b) >> (start | b); + BOOST_SPIRIT_DEBUG_NODE(start); + 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 + + rule<char const*, space_type> a, b, c, start; + + a = 'a'; + b = 'b'; + c = 'c'; + BOOST_SPIRIT_DEBUG_NODE(a); + BOOST_SPIRIT_DEBUG_NODE(b); + BOOST_SPIRIT_DEBUG_NODE(c); + + start = *(a | b | c); + BOOST_SPIRIT_DEBUG_NODE(start); + BOOST_TEST(test(" a b c a b c a c b ", start, space)); + + start = (a | b) >> (start | b); + BOOST_SPIRIT_DEBUG_NODE(start); + 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)); + } + + { // std::container attributes + + typedef boost::fusion::vector<int, char> fs; + rule<char const*, std::vector<fs>(), space_type> start; + start = *(int_ >> alpha); + + BOOST_SPIRIT_DEBUG_NODE(start); + BOOST_TEST(test("1 a 2 b 3 c", start, space)); + } + + { // error handling + + using namespace boost::spirit::ascii; + using boost::phoenix::construct; + using boost::phoenix::bind; + + rule<char const*> r; + r = '(' > int_ > ',' > int_ > ')'; + + on_error<fail> + ( + r, std::cout + << phx::val("Error! Expecting: ") + << _4 + << phx::val(", got: \"") + << construct<std::string>(_3, _2) + << phx::val("\"") + << std::endl + ); + + BOOST_SPIRIT_DEBUG_NODE(r); + 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)); + } + + return boost::report_errors(); +} + diff --git a/src/boost/libs/spirit/test/qi/difference.cpp b/src/boost/libs/spirit/test/qi/difference.cpp new file mode 100644 index 00000000..c9600a82 --- /dev/null +++ b/src/boost/libs/spirit/test/qi/difference.cpp @@ -0,0 +1,78 @@ +/*============================================================================= + Copyright (c) 2001-2010 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/include/qi_operator.hpp> +#include <boost/spirit/include/qi_char.hpp> +#include <boost/spirit/include/qi_string.hpp> +#include <boost/spirit/include/qi_numeric.hpp> +#include <boost/spirit/include/qi_directive.hpp> +#include <boost/spirit/include/qi_action.hpp> +#include <boost/spirit/include/support_argument.hpp> +#include <boost/spirit/include/phoenix_core.hpp> +#include <boost/spirit/include/phoenix_operator.hpp> + +#include <string> +#include <iostream> +#include "test.hpp" + +int +main() +{ + using namespace boost::spirit::ascii; + using boost::spirit::lit; + using spirit_test::test; + + { + BOOST_TEST(test("b", char_ - 'a')); + BOOST_TEST(!test("a", char_ - 'a')); + BOOST_TEST(test("/* abcdefghijk */", "/*" >> *(char_ - "*/") >> "*/")); + } + + { + BOOST_TEST(test("b", char_ - no_case['a'])); + BOOST_TEST(!test("a", char_ - no_case['a'])); + BOOST_TEST(!test("A", char_ - no_case['a'])); + + BOOST_TEST(test("b", no_case[lower - 'a'])); + BOOST_TEST(test("B", no_case[lower - 'a'])); + BOOST_TEST(!test("a", no_case[lower - 'a'])); + BOOST_TEST(!test("A", no_case[lower - 'a'])); + } + + { + // $$$ See difference.hpp why these tests are not done anymore. $$$ + + // BOOST_TEST(test("switcher", lit("switcher") - "switch")); + // BOOST_TEST(test(" switcher ", lit("switcher") - "switch", space)); + + BOOST_TEST(!test("switch", lit("switch") - "switch")); + } + + { + using boost::spirit::_1; + namespace phx = boost::phoenix; + + std::string s; + + BOOST_TEST(test( + "/*abcdefghijk*/" + , "/*" >> *(char_ - "*/")[phx::ref(s) += _1] >> "*/" + )); + BOOST_TEST(s == "abcdefghijk"); + s.clear(); + + BOOST_TEST(test( + " /*abcdefghijk*/" + , "/*" >> *(char_ - "*/")[phx::ref(s) += _1] >> "*/" + , space + )); + BOOST_TEST(s == "abcdefghijk"); + } + + return boost::report_errors(); +} + diff --git a/src/boost/libs/spirit/test/qi/encoding.cpp b/src/boost/libs/spirit/test/qi/encoding.cpp new file mode 100644 index 00000000..54c34e85 --- /dev/null +++ b/src/boost/libs/spirit/test/qi/encoding.cpp @@ -0,0 +1,45 @@ +/*============================================================================= + Copyright (c) 2001-2011 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/include/qi_char.hpp> +#include <boost/spirit/include/qi_string.hpp> +#include <boost/spirit/include/qi_directive.hpp> +#include <boost/spirit/include/qi_action.hpp> +#include <boost/spirit/include/phoenix_core.hpp> +#include <boost/spirit/include/phoenix_operator.hpp> + +#include <iostream> +#include "test.hpp" + +int +main() +{ + using spirit_test::test; + using spirit_test::test_attr; + using boost::spirit::qi::lit; + using boost::spirit::qi::no_case; + using boost::spirit::qi::char_; + using boost::spirit::qi::encoding; + namespace char_encoding = boost::spirit::char_encoding; + + encoding<char_encoding::iso8859_1> iso8859_1; + + { // test extended ASCII characters + BOOST_TEST(test("\xC1", iso8859_1[no_case['\xE1']])); + BOOST_TEST(test("\xC1", iso8859_1[no_case[char_('\xE1')]])); + + BOOST_TEST(test("\xC9", iso8859_1[no_case[char_("\xE5-\xEF")]])); + BOOST_TEST(!test("\xFF", iso8859_1[no_case[char_("\xE5-\xEF")]])); + + BOOST_TEST(test("\xC1\xE1", iso8859_1[no_case["\xE1\xC1"]])); + BOOST_TEST(test("\xC1\xE1", iso8859_1[no_case[lit("\xE1\xC1")]])); + } + + return boost::report_errors(); +} diff --git a/src/boost/libs/spirit/test/qi/end.cpp b/src/boost/libs/spirit/test/qi/end.cpp new file mode 100644 index 00000000..46fde1d6 --- /dev/null +++ b/src/boost/libs/spirit/test/qi/end.cpp @@ -0,0 +1,71 @@ +/*============================================================================= + Copyright (c) 2001-2010 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/include/qi_char.hpp> +#include <boost/spirit/include/qi_auxiliary.hpp> +#include <boost/spirit/include/qi_operator.hpp> +#include <boost/spirit/include/support_argument.hpp> +#include <boost/spirit/include/phoenix_core.hpp> +#include <boost/spirit/include/phoenix_operator.hpp> + +#include <iostream> +#include "test.hpp" + +int +main() +{ + using spirit_test::test; + namespace qi = boost::spirit::qi; + namespace ascii = boost::spirit::ascii; + namespace wide = boost::spirit::standard_wide; + + using qi::eol; + using qi::eoi; + using ascii::space; + + { // eol + BOOST_TEST(test("\r", eol)); + BOOST_TEST(test("\r\n", eol)); + BOOST_TEST(test("\n", eol)); + BOOST_TEST(!test("\b", eol)); + + BOOST_TEST(!test("\r", !eol, false)); + BOOST_TEST(!test("\r\n", !eol, false)); + BOOST_TEST(!test("\n", !eol, false)); + BOOST_TEST(test("\b", !eol, false)); + + BOOST_TEST(test(" \r", eol, ascii::char_(' '))); + BOOST_TEST(test(" \r\n", eol, ascii::char_(' '))); + BOOST_TEST(test(" \n", eol, ascii::char_(' '))); + BOOST_TEST(!test(" \b", eol, ascii::char_(' '))); + + BOOST_TEST(test(L"\r", eol)); + BOOST_TEST(test(L"\r\n", eol)); + BOOST_TEST(test(L"\n", eol)); + BOOST_TEST(!test(L"\b", eol)); + + BOOST_TEST(test(L" \r", eol, wide::char_(L' '))); + BOOST_TEST(test(L" \r\n", eol, wide::char_(L' '))); + BOOST_TEST(test(L" \n", eol, wide::char_(L' '))); + BOOST_TEST(!test(L" \b", eol, wide::char_(L' '))); + } + + { // eoi + BOOST_TEST(test("", eoi)); + BOOST_TEST(!test("a", eoi)); + BOOST_TEST(test("a", !eoi, false)); + BOOST_TEST(!test("", !eoi)); + + BOOST_TEST(test(" ", eoi, space)); + BOOST_TEST(!test(" a", eoi, space)); + BOOST_TEST(test(" a", !eoi, space, false)); + BOOST_TEST(!test(" ", !eoi, space)); + } + + return boost::report_errors(); +} diff --git a/src/boost/libs/spirit/test/qi/eps.cpp b/src/boost/libs/spirit/test/qi/eps.cpp new file mode 100644 index 00000000..a1f5f87b --- /dev/null +++ b/src/boost/libs/spirit/test/qi/eps.cpp @@ -0,0 +1,44 @@ +/*============================================================================= + Copyright (c) 2001-2010 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/include/qi_auxiliary.hpp> +#include <boost/spirit/include/qi_operator.hpp> +#include <boost/spirit/include/phoenix_core.hpp> + +#include <iostream> +#include "test.hpp" + +int +main() +{ + using spirit_test::test; + using boost::spirit::eps; + + { + BOOST_TEST((test("", eps))); + BOOST_TEST((test("xxx", eps, false))); + BOOST_TEST((!test("", !eps))); // not predicate + } + + { // test non-lazy semantic predicate + + BOOST_TEST((test("", eps(true)))); + BOOST_TEST((!test("", eps(false)))); + BOOST_TEST((test("", !eps(false)))); // not predicate + } + + { // test lazy semantic predicate + + using boost::phoenix::val; + + BOOST_TEST((test("", eps(val(true))))); + BOOST_TEST((!test("", eps(val(false))))); + BOOST_TEST((test("", !eps(val(false))))); // not predicate + } + + return boost::report_errors(); +} diff --git a/src/boost/libs/spirit/test/qi/expect.cpp b/src/boost/libs/spirit/test/qi/expect.cpp new file mode 100644 index 00000000..fd55de77 --- /dev/null +++ b/src/boost/libs/spirit/test/qi/expect.cpp @@ -0,0 +1,100 @@ +/*============================================================================= + Copyright (c) 2001-2010 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/include/qi_operator.hpp> +#include <boost/spirit/include/qi_char.hpp> +#include <boost/spirit/include/qi_string.hpp> +#include <boost/spirit/include/qi_numeric.hpp> +#include <boost/spirit/include/qi_directive.hpp> +#include <boost/spirit/include/qi_action.hpp> +#include <boost/spirit/include/qi_nonterminal.hpp> +#include <boost/spirit/include/qi_auxiliary.hpp> +#include <boost/spirit/include/support_argument.hpp> +#include <boost/fusion/include/vector.hpp> +#include <boost/fusion/include/at.hpp> +#include <boost/spirit/include/phoenix_core.hpp> +#include <boost/spirit/include/phoenix_operator.hpp> +#include <boost/spirit/include/phoenix_statement.hpp> + +#include <string> +#include <iostream> +#include "test.hpp" + +int +main() +{ + using namespace boost::spirit; + using namespace boost::spirit::ascii; + using spirit_test::test; + using spirit_test::print_info; + using boost::spirit::qi::expectation_failure; + + { + 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: "; print_info(x.what_); + std::cout << "got: \"" << x.first << '"' << std::endl; + + BOOST_TEST(boost::get<std::string>(x.what_.value) == "o"); + BOOST_TEST(std::string(x.first, x.last) == "i"); + } + } + + { + 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: "; print_info(x.what_); + std::cout << "got: \"" << x.first << '"' << std::endl; + + BOOST_TEST(boost::get<std::string>(x.what_.value) == "o"); + BOOST_TEST(std::string(x.first, x.last) == "i"); + } + } + + { + try + { + 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))); + } + catch (expectation_failure<char const*> const& x) + { + std::cout << "expected: "; print_info(x.what_); + std::cout << "got: \"" << x.first << '"' << std::endl; + + BOOST_TEST(x.what_.tag == "no-case-literal-string"); + BOOST_TEST(boost::get<std::string>(x.what_.value) == "nend"); + BOOST_TEST(std::string(x.first, x.last) == "END"); + } + } + + { + using boost::spirit::qi::rule; + using boost::spirit::eps; + rule<const wchar_t*, void(int)> r; + r = eps > eps(_r1); + } + + return boost::report_errors(); +} + diff --git a/src/boost/libs/spirit/test/qi/expectd.cpp b/src/boost/libs/spirit/test/qi/expectd.cpp new file mode 100644 index 00000000..5be7e7b9 --- /dev/null +++ b/src/boost/libs/spirit/test/qi/expectd.cpp @@ -0,0 +1,130 @@ +/*============================================================================= + Copyright (c) 2001-2010 Joel de Guzman + Copyright (c) 2016 Frank Hein, maxence business consulting 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/include/qi_operator.hpp> +#include <boost/spirit/include/qi_char.hpp> +#include <boost/spirit/include/qi_string.hpp> +#include <boost/spirit/include/qi_numeric.hpp> +#include <boost/spirit/include/qi_directive.hpp> +#include <boost/spirit/include/qi_action.hpp> +#include <boost/spirit/include/qi_nonterminal.hpp> +#include <boost/spirit/include/qi_auxiliary.hpp> +#include <boost/spirit/include/support_argument.hpp> +#include <boost/fusion/include/vector.hpp> +#include <boost/fusion/include/at.hpp> +#include <boost/spirit/include/phoenix_core.hpp> +#include <boost/spirit/include/phoenix_operator.hpp> +#include <boost/spirit/include/phoenix_statement.hpp> + +#include <string> +#include <iostream> +#include "test.hpp" + +int +main() +{ + using namespace boost::spirit; + using namespace boost::spirit::ascii; + using spirit_test::test; + using spirit_test::print_info; + using boost::spirit::qi::expectation_failure; + + + { + try + { + BOOST_TEST((test("aa", expect[char_ >> char_]))); + BOOST_TEST((test("aaa", expect[char_ >> char_ >> char_('a')]))); + BOOST_TEST((test("xi", expect[char_('x') >> char_('i')]))); + BOOST_TEST((test("xin", expect[char_('x') >> char_('i') >> char_('n')]))); + BOOST_TEST((!test("xi", expect[char_('y')]))); // should throw! + } + catch (expectation_failure<char const*> const& x) + { + std::cout << "expected: "; print_info(x.what_); + std::cout << "got: \"" << x.first << '"' << std::endl; + + BOOST_TEST(boost::get<std::string>(x.what_.value) == "y"); + BOOST_TEST(std::string(x.first, x.last) == "xi"); + } + } + + { + try + { + BOOST_TEST((!test("xi", expect[char_('x') >> char_('o')]))); + } + catch (expectation_failure<char const*> const& x) + { + std::cout << "expected: "; print_info(x.what_); + std::cout << "got: \"" << x.first << '"' << std::endl; + + BOOST_TEST(std::string(x.first, x.last) == "xi"); + BOOST_TEST(x.what_.tag == "sequence"); + } + } + + { + try + { + BOOST_TEST((!test(" x i", expect[char_('x') >> char_('o')], space))); + } + catch (expectation_failure<char const*> const& x) + { + std::cout << "expected: "; print_info(x.what_); + std::cout << "got: \"" << x.first << '"' << std::endl; + + BOOST_TEST(std::string(x.first, x.last) == " x i"); + BOOST_TEST(x.what_.tag == "sequence"); + } + } + + { + try + { + BOOST_TEST((test(" a a", expect[char_ >> char_], space))); + BOOST_TEST((test(" x i", expect[char_('x') >> char_('i')], space))); + BOOST_TEST((!test(" x i", expect[char_('y')], space))); + } + catch (expectation_failure<char const*> const& x) + { + std::cout << "expected: "; print_info(x.what_); + std::cout << "got: \"" << x.first << '"' << std::endl; + + BOOST_TEST(boost::get<std::string>(x.what_.value) == "y"); + BOOST_TEST(std::string(x.first, x.last) == "x i"); + } + } + + { + try + { + BOOST_TEST((test("aA", expect[no_case[char_('a') >> 'a']]))); + BOOST_TEST((test("BEGIN END", expect[no_case[lit("begin") >> "end"]], space))); + BOOST_TEST((!test("BEGIN END", expect[no_case[lit("begin") >> "nend"]], space))); + } + catch (expectation_failure<char const*> const& x) + { + std::cout << "expected: "; print_info(x.what_); + std::cout << "got: \"" << x.first << '"' << std::endl; + + BOOST_TEST(x.what_.tag == "sequence"); + BOOST_TEST(std::string(x.first, x.last) == "BEGIN END"); + } + } + + { + using boost::spirit::qi::rule; + using boost::spirit::eps; + rule<const wchar_t*, void(int)> r; + r = expect[eps(_r1)]; + } + + return boost::report_errors(); +} + diff --git a/src/boost/libs/spirit/test/qi/extract_int.cpp b/src/boost/libs/spirit/test/qi/extract_int.cpp new file mode 100644 index 00000000..8c95a199 --- /dev/null +++ b/src/boost/libs/spirit/test/qi/extract_int.cpp @@ -0,0 +1,191 @@ +/*============================================================================= + 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/qi/numeric/numeric_utils.hpp> +#include <boost/static_assert.hpp> +#include <cmath> // for std::pow +#include <iosfwd> +#include <limits> +#include <sstream> + +#ifdef _MSC_VER +# pragma warning(disable: 4127) // conditional expression is constant +#endif + +template <int Min, int Max> +struct custom_int +{ + BOOST_DEFAULTED_FUNCTION(custom_int(), {}) + BOOST_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_; + } + + BOOST_STATIC_CONSTEXPR int max = Max; + BOOST_STATIC_CONSTEXPR int min = Min; + +private: + int value_; +}; + +namespace utils { + +template <int Min, int Max> struct digits; +template <> struct digits<-9, 9> { BOOST_STATIC_CONSTEXPR int r2 = 3, r10 = 1; }; +template <> struct digits<-10, 10> { BOOST_STATIC_CONSTEXPR int r2 = 3, r10 = 1; }; +template <> struct digits<-15, 15> { BOOST_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 BOOST_CONSTEXPR custom_int<Min, Max> max() BOOST_NOEXCEPT_OR_NOTHROW { return Max; } + static BOOST_CONSTEXPR custom_int<Min, Max> min() BOOST_NOEXCEPT_OR_NOTHROW { return Min; } + static BOOST_CONSTEXPR custom_int<Min, Max> lowest() BOOST_NOEXCEPT_OR_NOTHROW { return min(); } + BOOST_STATIC_ASSERT_MSG(numeric_limits<int>::radix == 2, "hardcoded for digits of radix 2"); + BOOST_STATIC_CONSTEXPR int digits = utils::digits<Min, Max>::r2; + BOOST_STATIC_CONSTEXPR int digits10 = utils::digits<Min, Max>::r10; +}; + +} + +namespace qi = boost::spirit::qi; + +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 + BOOST_STATIC_ASSERT_MSG(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 = qi::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 { + 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 + BOOST_STATIC_ASSERT_MSG(T::min <= -Base+1, "test prerequest"); + BOOST_STATIC_ASSERT_MSG(T::max >= Base-1, "test prerequest"); + bool has_sign = *it == '+' || *it == '-'; + char const* begin = it; + int initial = Base - i % Base; // just a 'random' non-equal to i number + T x(initial); + bool r = qi::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, (end - begin) - 1 - has_sign); + BOOST_TEST_EQ(x, i / Base); + } +} + +template <typename T, int Base> +void test_ignore_overflow_digits(char const* it, char const* end, int i) +{ + // TODO: Check accumulating too? + if (i < 0) return; // extract_int does not support IgnoreOverflowDigits + + bool has_sign = *it == '+' || *it == '-'; + char const* begin = it; + int initial = Base - i % Base; // just a 'random' non-equal to i number + T x(initial); + BOOST_TEST((qi::extract_uint<T, Base, 1, -1, false, true>::call(it, end, x))); + if (T::min <= i && i <= T::max) { + BOOST_TEST(it == end); + BOOST_TEST_EQ(x, i); + } + else { + BOOST_TEST_EQ(it - begin, (qi::detail::digits_traits<T, Base>::value) + has_sign); + if (Base == std::numeric_limits<T>::radix) + BOOST_TEST_EQ(it - begin, std::numeric_limits<T>::digits + has_sign); + if (Base == 10) + BOOST_TEST_EQ(it - begin, std::numeric_limits<T>::digits10 + has_sign); + int expected = i; + for (char const* p = it; p < end; ++p) expected /= Base; + BOOST_TEST_EQ(x, expected); + } +} + +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); + // Check that IgnoreOverflowDigits does what we expect + test_ignore_overflow_digits<T, Base>(begin, end, i); +} + +int main() +{ + for (int i = -30; i <= 30; ++i) { + std::ostringstream oss; + oss << i; + std::string s = oss.str(); + char const* begin = s.data(), *const end = begin + s.size(); + + // 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/qi/grammar.cpp b/src/boost/libs/spirit/test/qi/grammar.cpp new file mode 100644 index 00000000..8a7ca14c --- /dev/null +++ b/src/boost/libs/spirit/test/qi/grammar.cpp @@ -0,0 +1,126 @@ +/*============================================================================= + Copyright (c) 2001-2010 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/include/qi_operator.hpp> +#include <boost/spirit/include/qi_char.hpp> +#include <boost/spirit/include/qi_string.hpp> +#include <boost/spirit/include/qi_numeric.hpp> +#include <boost/spirit/include/qi_nonterminal.hpp> +#include <boost/spirit/include/qi_action.hpp> +#include <boost/spirit/include/phoenix_core.hpp> +#include <boost/spirit/include/phoenix_operator.hpp> + +#include <string> +#include <iostream> +#include "test.hpp" + +using spirit_test::test; +using spirit_test::test_attr; + +using boost::spirit::ascii::space_type; +using boost::spirit::ascii::space; +using boost::spirit::int_; +using boost::spirit::qi::grammar; +using boost::spirit::qi::rule; +using boost::spirit::_val; +using boost::spirit::_r1; +using boost::spirit::lit; + +struct num_list : grammar<char const*, space_type> +{ + num_list() : base_type(start) + { + using boost::spirit::int_; + num = int_; + start = num >> *(',' >> num); + } + + rule<char const*, space_type> start, num; +}; + +struct inh_g : grammar<char const*, int(int), space_type> +{ + inh_g() : base_type(start) + { + start = lit("inherited")[_val = _r1]; + } + + rule<char const*, int(int), space_type> start, num; +}; + +struct my_skipper : grammar<char const*> +{ + my_skipper() : base_type(start) + { + start = space; + } + + rule<char const*> start, num; +}; + +struct num_list2 : grammar<char const*, my_skipper> +{ + num_list2() : base_type(start) + { + using boost::spirit::int_; + num = int_; + start = num >> *(',' >> num); + } + + rule<char const*, my_skipper> start, num; +}; + +template <typename Iterator, typename Skipper> +struct num_list3 : grammar<Iterator, Skipper> +{ + template <typename Class> + num_list3(Class&) : grammar<Iterator, Skipper>(start) + { + using boost::spirit::int_; + num = int_; + start = num >> *(',' >> num); + } + + rule<Iterator, Skipper> start, num; +}; + +int +main() +{ + { // simple grammar test + + num_list nlist; + BOOST_TEST(test("123, 456, 789", nlist, space)); + } + + { // simple grammar test with user-skipper + + num_list2 nlist; + my_skipper skip; + BOOST_TEST(test("123, 456, 789", nlist, skip)); + } + + { // direct access to the rules + + num_list g; + BOOST_TEST(test("123", g.num, space)); + BOOST_TEST(test("123, 456, 789", g.start, space)); + } + + { // grammar with inherited attributes + + inh_g g; + int n = -1; + BOOST_TEST(test_attr("inherited", g.start(123), n, space)); // direct to the rule + BOOST_TEST(n == 123); + BOOST_TEST(test_attr("inherited", g(123), n, space)); // using the grammar + BOOST_TEST(n == 123); + } + + return boost::report_errors(); +} + diff --git a/src/boost/libs/spirit/test/qi/grammar_fail.cpp b/src/boost/libs/spirit/test/qi/grammar_fail.cpp new file mode 100644 index 00000000..72b3a566 --- /dev/null +++ b/src/boost/libs/spirit/test/qi/grammar_fail.cpp @@ -0,0 +1,39 @@ +/*============================================================================= + 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/spirit/include/qi_operator.hpp> +#include <boost/spirit/include/qi_char.hpp> +#include <boost/spirit/include/qi_string.hpp> +#include <boost/spirit/include/qi_numeric.hpp> +#include <boost/spirit/include/qi_nonterminal.hpp> +#include <boost/spirit/include/qi_parse.hpp> + +namespace qi = boost::spirit::qi; + +struct num_list : qi::grammar<char const*, qi::rule<char const*> > +{ + num_list() : base_type(start) + { + num = qi::int_; + start = num >> *(',' >> num); + } + + qi::rule<char const*, qi::rule<char const*> > start, num; +}; + +// this test must fail compiling +int main() +{ + char const* input = "some input, it doesn't matter"; + char const* end = &input[strlen(input)]; + + num_list g; + qi::phrase_parse(input, end, g, + qi::space | ('%' >> *~qi::char_('\n') >> '\n')); + + return 0; +} diff --git a/src/boost/libs/spirit/test/qi/hold.cpp b/src/boost/libs/spirit/test/qi/hold.cpp new file mode 100644 index 00000000..332d531d --- /dev/null +++ b/src/boost/libs/spirit/test/qi/hold.cpp @@ -0,0 +1,46 @@ +/*============================================================================= + Copyright (c) 2001-2010 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/include/qi_directive.hpp> +#include <boost/spirit/include/qi_char.hpp> +#include <boost/spirit/include/qi_int.hpp> +#include <boost/spirit/include/qi_operator.hpp> + +#include <iostream> +#include <vector> +#include "test.hpp" + +int +main() +{ + using spirit_test::test; + using spirit_test::test_attr; + using boost::spirit::qi::hold; + using boost::spirit::qi::int_; + using boost::spirit::ascii::alpha; + + { + std::vector<int> vec; + BOOST_TEST(!test_attr("1$", hold[int_ >> ';'], vec)); + BOOST_TEST(vec.size() == 0); + BOOST_TEST(test_attr("1;", hold[int_ >> ';'], vec)); + BOOST_TEST(vec.size() == 1); + BOOST_TEST(vec[0] == 1); + } + + { + std::string attr; + BOOST_TEST( + test_attr( + "abc;", + hold[alpha >> ';'] | (+alpha >> ';'), + attr)); + BOOST_TEST(attr == "abc"); + } + + return boost::report_errors(); +} diff --git a/src/boost/libs/spirit/test/qi/int.hpp b/src/boost/libs/spirit/test/qi/int.hpp new file mode 100644 index 00000000..48e681e1 --- /dev/null +++ b/src/boost/libs/spirit/test/qi/int.hpp @@ -0,0 +1,80 @@ +/*============================================================================= + Copyright (c) 2001-2011 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_INT_HPP) +#define BOOST_SPIRIT_TEST_QI_INT_HPP + +#include <climits> +#include <boost/detail/lightweight_test.hpp> +#include <boost/spirit/include/qi_numeric.hpp> +#include <boost/spirit/include/qi_char.hpp> +#include <boost/spirit/include/qi_action.hpp> +#include <boost/spirit/include/support_argument.hpp> +#include <boost/spirit/include/phoenix_core.hpp> +#include <boost/spirit/include/phoenix_operator.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. +// +/////////////////////////////////////////////////////////////////////////////// +#ifdef BOOST_HAS_LONG_LONG +// Some compilers have long long, but don't define the +// LONG_LONG_MIN and LONG_LONG_MAX macros in limits.h. This +// assumes that long long is 64 bits. + +BOOST_STATIC_ASSERT(sizeof(boost::long_long_type) == 8); + +#if !defined(LONG_LONG_MIN) && !defined(LONG_LONG_MAX) +# define LONG_LONG_MAX 0x7fffffffffffffffLL +# define LONG_LONG_MIN (-LONG_LONG_MAX - 1) +#endif + +#endif // BOOST_HAS_LONG_LONG + +#if INT_MAX != LLONG_MAX + BOOST_STATIC_ASSERT(sizeof(int) == 4); + char const* max_int = "2147483647"; + char const* int_overflow = "2147483648"; + char const* min_int = "-2147483648"; + char const* int_underflow = "-2147483649"; +#else + BOOST_STATIC_ASSERT(sizeof(int) == 8); + char const* max_int = "9223372036854775807"; + char const* int_overflow = "9223372036854775808"; + char const* min_int = "-9223372036854775808"; + char const* int_underflow = "-9223372036854775809"; +#endif + +#ifdef BOOST_HAS_LONG_LONG + char const* max_long_long = "9223372036854775807"; + char const* long_long_overflow = "9223372036854775808"; + char const* min_long_long = "-9223372036854775808"; + char const* long_long_underflow = "-9223372036854775809"; +#endif + +/////////////////////////////////////////////////////////////////////////////// +// 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/qi/int1.cpp b/src/boost/libs/spirit/test/qi/int1.cpp new file mode 100644 index 00000000..630ba196 --- /dev/null +++ b/src/boost/libs/spirit/test/qi/int1.cpp @@ -0,0 +1,173 @@ +/*============================================================================= + Copyright (c) 2001-2011 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" + +int +main() +{ + using spirit_test::test; + using spirit_test::test_attr; + + /////////////////////////////////////////////////////////////////////////// + // signed integer tests + /////////////////////////////////////////////////////////////////////////// + { + using boost::spirit::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 + /////////////////////////////////////////////////////////////////////////// +#ifdef BOOST_HAS_LONG_LONG + { + using boost::spirit::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 == LONG_LONG_MAX); + + BOOST_TEST(test(min_long_long, long_long)); + BOOST_TEST(test_attr(min_long_long, long_long, ll)); + BOOST_TEST(ll == LONG_LONG_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)); + } +#endif + + /////////////////////////////////////////////////////////////////////////// + // short_ and long_ tests + /////////////////////////////////////////////////////////////////////////// + { + using boost::spirit::short_; + using boost::spirit::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::qi::int_parser<boost::int8_t> int8_; + char c; + + BOOST_TEST(!test_attr("999", int8_, c)); + + int i; + using boost::spirit::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::qi::int_parser; + using boost::spirit::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::phoenix::ref; + using boost::spirit::_1; + using boost::spirit::ascii::space; + using boost::spirit::int_; + int n = 0, m = 0; + + BOOST_TEST(test("123", int_[ref(n) = _1])); + BOOST_TEST(n == 123); + BOOST_TEST(test_attr("789", int_[ref(n) = _1], m)); + BOOST_TEST(n == 789 && m == 789); + BOOST_TEST(test(" 456", int_[ref(n) = _1], space)); + BOOST_TEST(n == 456); + } + + /////////////////////////////////////////////////////////////////////////// + // custom int tests + /////////////////////////////////////////////////////////////////////////// + { + using boost::spirit::qi::int_; + using boost::spirit::qi::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)); + } + + return boost::report_errors(); +} diff --git a/src/boost/libs/spirit/test/qi/int2.cpp b/src/boost/libs/spirit/test/qi/int2.cpp new file mode 100644 index 00000000..89f2b327 --- /dev/null +++ b/src/boost/libs/spirit/test/qi/int2.cpp @@ -0,0 +1,108 @@ +/*============================================================================= + Copyright (c) 2001-2011 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" + +int +main() +{ + using spirit_test::test; + using spirit_test::test_attr; + + /////////////////////////////////////////////////////////////////////////// + // signed integer literal tests + /////////////////////////////////////////////////////////////////////////// + { + using boost::spirit::lit; + int i = 123456; + + BOOST_TEST( test("123456", lit(123456))); + BOOST_TEST(!test("123456", lit(0))); + BOOST_TEST( test("123456", lit(i))); + BOOST_TEST(!test("123456", lit(-i))); + BOOST_TEST( test("+425", lit(425))); + BOOST_TEST(!test("+425", lit(17))); + BOOST_TEST( test("-2000", lit(-2000))); + BOOST_TEST(!test("-2000", lit(2000))); + BOOST_TEST( test(max_int, lit(INT_MAX))); + BOOST_TEST(!test(max_int, lit(INT_MIN))); + + BOOST_TEST( test(min_int, lit(INT_MIN))); + BOOST_TEST(!test(min_int, lit(INT_MAX))); + + BOOST_TEST(!test("-", lit(8451))); + BOOST_TEST(!test("+", lit(8451))); + + // with leading zeros + BOOST_TEST(test("000000000098765", lit(98765))); + } + + /////////////////////////////////////////////////////////////////////////// + // long long literal tests + /////////////////////////////////////////////////////////////////////////// +#ifdef BOOST_HAS_LONG_LONG + { + using boost::spirit::lit; + boost::long_long_type ll = 1234567890123456789LL; + + BOOST_TEST( test("1234567890123456789", lit(1234567890123456789LL))); + BOOST_TEST(!test("1234567890123456789", lit(-19LL))); + BOOST_TEST( test("1234567890123456789", lit(ll))); + BOOST_TEST(!test("1234567890123456789", lit(-ll))); + BOOST_TEST( test("-100000000000000", lit(-100000000000000LL))); + BOOST_TEST(!test("-100000000000000", lit(3243515525263LL))); + BOOST_TEST( test(max_long_long, lit(LONG_LONG_MAX))); + BOOST_TEST(!test(max_long_long, lit(LONG_LONG_MIN))); + + BOOST_TEST( test(min_long_long, lit(LONG_LONG_MIN))); + BOOST_TEST(!test(min_long_long, lit(LONG_LONG_MAX))); + } +#endif + + /////////////////////////////////////////////////////////////////////////// + // short_ and long_ literal tests + /////////////////////////////////////////////////////////////////////////// + { + using boost::spirit::lit; + short s = 12345; + long l = 1234567890L; + + BOOST_TEST( test("12345", lit(12345))); + BOOST_TEST(!test("12345", lit(-12345))); + BOOST_TEST( test("12345", lit(s))); + BOOST_TEST(!test("12345", lit(-s))); + BOOST_TEST( test("-12345", lit(-12345))); + BOOST_TEST(!test("-12345", lit(12345))); + BOOST_TEST( test("-12345", lit(-s))); + BOOST_TEST(!test("-12345", lit(s))); + + BOOST_TEST( test("1234567890", lit(1234567890))); + BOOST_TEST(!test("1234567890", lit(-1234567890))); + BOOST_TEST( test("1234567890", lit(l))); + BOOST_TEST(!test("1234567890", lit(-l))); + BOOST_TEST( test("-1234567890", lit(-1234567890))); + BOOST_TEST(!test("-1234567890", lit(1234567890))); + BOOST_TEST( test("-1234567890", lit(-l))); + BOOST_TEST(!test("-1234567890", lit(l))); + } + + /////////////////////////////////////////////////////////////////////////// + // literal lazy tests + /////////////////////////////////////////////////////////////////////////// + { + using boost::phoenix::ref; + using boost::spirit::qi::lit; + int n = 123, m = 321; + + BOOST_TEST(test("123", lit(ref(n)))); + BOOST_TEST(!test("123", lit(ref(m)))); + } + + return boost::report_errors(); +} diff --git a/src/boost/libs/spirit/test/qi/int3.cpp b/src/boost/libs/spirit/test/qi/int3.cpp new file mode 100644 index 00000000..d4fd80d9 --- /dev/null +++ b/src/boost/libs/spirit/test/qi/int3.cpp @@ -0,0 +1,179 @@ +/*============================================================================= + Copyright (c) 2001-2011 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/include/qi_rule.hpp> + +int +main() +{ + using spirit_test::test; + using spirit_test::test_attr; + + /////////////////////////////////////////////////////////////////////////// + // parameterized signed integer tests + /////////////////////////////////////////////////////////////////////////// + { + using boost::spirit::int_; + int i; + + BOOST_TEST(test("123456", int_(123456))); + BOOST_TEST(!test("123456", int_(654321))); + BOOST_TEST(test_attr("123456", int_(123456), i)); + BOOST_TEST(i == 123456); + BOOST_TEST(!test_attr("123456", int_(654321), i)); + + BOOST_TEST(test("+123456", int_(123456))); + BOOST_TEST(!test("+123456", int_(654321))); + BOOST_TEST(test_attr("+123456", int_(123456), i)); + BOOST_TEST(i == 123456); + BOOST_TEST(!test_attr("+123456", int_(654321), i)); + + BOOST_TEST(test("-123456", int_(-123456))); + BOOST_TEST(!test("-123456", int_(123456))); + BOOST_TEST(test_attr("-123456", int_(-123456), i)); + BOOST_TEST(i == -123456); + BOOST_TEST(!test_attr("-123456", int_(123456), i)); + + BOOST_TEST(test(max_int, int_(INT_MAX))); + BOOST_TEST(test_attr(max_int, int_(INT_MAX), i)); + BOOST_TEST(i == INT_MAX); + + BOOST_TEST(test(min_int, int_(INT_MIN))); + BOOST_TEST(test_attr(min_int, int_(INT_MIN), i)); + BOOST_TEST(i == INT_MIN); + + // with leading zeros + BOOST_TEST(test("0000000000123456", int_(123456))); + BOOST_TEST(test_attr("0000000000123456", int_(123456), i)); + BOOST_TEST(i == 123456); + } + + /////////////////////////////////////////////////////////////////////////// + // parameterized long long tests + /////////////////////////////////////////////////////////////////////////// +#ifdef BOOST_HAS_LONG_LONG + { + using boost::spirit::long_long; + boost::long_long_type ll; + + BOOST_TEST(test("1234567890123456789" + , long_long(1234567890123456789LL))); + BOOST_TEST(!test("1234567890123456789" + , long_long(0))); + BOOST_TEST(test_attr("1234567890123456789" + , long_long(1234567890123456789LL), ll)); + BOOST_TEST(ll == 1234567890123456789LL); + BOOST_TEST(!test_attr("1234567890123456789" + , long_long(0), ll)); + + BOOST_TEST(test("-1234567890123456789" + , long_long(-1234567890123456789LL))); + BOOST_TEST(!test("-1234567890123456789" + , long_long(1234567890123456789LL))); + BOOST_TEST(test_attr("-1234567890123456789" + , long_long(-1234567890123456789LL), ll)); + BOOST_TEST(ll == -1234567890123456789LL); + BOOST_TEST(!test_attr("-1234567890123456789" + , long_long(1234567890123456789LL), ll)); + + BOOST_TEST(test(max_long_long, long_long(LONG_LONG_MAX))); + BOOST_TEST(test_attr(max_long_long, long_long(LONG_LONG_MAX), ll)); + BOOST_TEST(ll == LONG_LONG_MAX); + + BOOST_TEST(test(min_long_long, long_long(LONG_LONG_MIN))); + BOOST_TEST(test_attr(min_long_long, long_long(LONG_LONG_MIN), ll)); + BOOST_TEST(ll == LONG_LONG_MIN); + } +#endif + + /////////////////////////////////////////////////////////////////////////// + // parameterized short_ and long_ tests + /////////////////////////////////////////////////////////////////////////// + { + using boost::spirit::short_; + using boost::spirit::long_; + int i; + + BOOST_TEST(test("12345", short_(12345))); + BOOST_TEST(!test("12345", short_(54321))); + BOOST_TEST(test_attr("12345", short_(12345), i)); + BOOST_TEST(i == 12345); + BOOST_TEST(!test_attr("12345", short_(54321), i)); + + BOOST_TEST(test("1234567890", long_(1234567890L))); + BOOST_TEST(!test("1234567890", long_(987654321L))); + BOOST_TEST(test_attr("1234567890", long_(1234567890L), i)); + BOOST_TEST(i == 1234567890); + BOOST_TEST(!test_attr("1234567890", long_(987654321L), i)); + } + + /////////////////////////////////////////////////////////////////////////// + // parameterized action tests + /////////////////////////////////////////////////////////////////////////// + { + using boost::phoenix::ref; + using boost::spirit::ascii::space; + using boost::spirit::qi::int_; + using boost::spirit::qi::_1; + int n = 0, m = 0; + + BOOST_TEST(test("123", int_(123)[ref(n) = _1])); + BOOST_TEST(n == 123); + BOOST_TEST(!test("123", int_(321)[ref(n) = _1])); + + BOOST_TEST(test_attr("789", int_(789)[ref(n) = _1], m)); + BOOST_TEST(n == 789 && m == 789); + BOOST_TEST(!test_attr("789", int_(987)[ref(n) = _1], m)); + + BOOST_TEST(test(" 456", int_(456)[ref(n) = _1], space)); + BOOST_TEST(n == 456); + BOOST_TEST(!test(" 456", int_(654)[ref(n) = _1], space)); + } + + /////////////////////////////////////////////////////////////////////////// + { + using boost::spirit::qi::int_; + using boost::spirit::qi::_1; + using boost::spirit::qi::_val; + using boost::spirit::qi::space; + + int i = 0; + int j = 0; + BOOST_TEST(test_attr("456", int_[_val = _1], i) && i == 456); + BOOST_TEST(test_attr(" 456", int_[_val = _1], j, space) && j == 456); + } + + /////////////////////////////////////////////////////////////////////////// + // parameterized lazy tests + /////////////////////////////////////////////////////////////////////////// + { + using boost::phoenix::ref; + using boost::spirit::qi::int_; + int n = 123, m = 321; + + BOOST_TEST(test("123", int_(ref(n)))); + BOOST_TEST(!test("123", int_(ref(m)))); + } + + /////////////////////////////////////////////////////////////////////////// + // parameterized custom int tests + /////////////////////////////////////////////////////////////////////////// + { + using boost::spirit::qi::int_; + using boost::spirit::qi::int_parser; + custom_int i; + + BOOST_TEST(test_attr("-123456", int_(-123456), i)); + int_parser<custom_int, 10, 1, 2> int2; + BOOST_TEST(test_attr("-12", int2(-12), i)); + } + + return boost::report_errors(); +} diff --git a/src/boost/libs/spirit/test/qi/iterator_check.cpp b/src/boost/libs/spirit/test/qi/iterator_check.cpp new file mode 100644 index 00000000..d58e7d95 --- /dev/null +++ b/src/boost/libs/spirit/test/qi/iterator_check.cpp @@ -0,0 +1,52 @@ +/*============================================================================= + 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/qi.hpp> +#include <boost/range/adaptor/transformed.hpp> + +#include <iostream> +#include <string> +#include <functional> + +namespace { + char transform_func(char c) { + return c < 'a' || 'z' < c ? c : static_cast<char>(c - 'a' + 'A'); + } +} + +int main() +{ + using boost::adaptors::transform; + using boost::spirit::qi::raw; + using boost::spirit::qi::eps; + using boost::spirit::qi::eoi; + using boost::spirit::qi::upper; + using boost::spirit::qi::repeat; + using boost::spirit::qi::parse; + + std::string input = "abcde"; + boost::transformed_range<char(*)(char), std::string> const rng = transform(input, transform_func); + + { + std::string str; + BOOST_TEST((parse(boost::begin(rng), boost::end(rng), +upper >> eoi, str))); + BOOST_TEST(("ABCDE"==str)); + } + + { + boost::iterator_range<boost::range_iterator<boost::transformed_range<char(*)(char), std::string> const>::type> 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/qi/kleene.cpp b/src/boost/libs/spirit/test/qi/kleene.cpp new file mode 100644 index 00000000..c49c3eea --- /dev/null +++ b/src/boost/libs/spirit/test/qi/kleene.cpp @@ -0,0 +1,142 @@ +/*============================================================================= + 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/spirit/include/qi_operator.hpp> +#include <boost/spirit/include/qi_char.hpp> +#include <boost/spirit/include/qi_string.hpp> +#include <boost/spirit/include/qi_numeric.hpp> +#include <boost/spirit/include/qi_directive.hpp> +#include <boost/spirit/include/qi_action.hpp> +#include <boost/spirit/include/support_argument.hpp> +#include <boost/spirit/include/phoenix_core.hpp> +#include <boost/spirit/include/phoenix_operator.hpp> + +#include <string> +#include <iostream> +#include "test.hpp" + +struct x_attr +{ +}; + +namespace boost { namespace spirit { namespace traits +{ + template <> + struct container_value<x_attr> + { + typedef char type; // value type of container + }; + + template <> + struct push_back_container<x_attr, char> + { + 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 namespace boost::spirit::ascii; + using boost::spirit::qi::omit; + using boost::spirit::qi::uint_; + using boost::spirit::qi::int_; + using boost::spirit::qi::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)); + } + + { + BOOST_TEST(test("12345 678 955 987", *uint_, space)); + BOOST_TEST(test("12345, 678, 955, 987", uint_ >> *(',' >> uint_), 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"); + + // The following 2 tests show that omit does not inhibit explicit attributes + s.clear(); + 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"); + } + + { + 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 + namespace phx = boost::phoenix; + using boost::spirit::_1; + + std::vector<char> v; + BOOST_TEST(test("bbbb", (*char_)[phx::ref(v) = _1]) && 4 == v.size() && + v[0] == 'b' && v[1] == 'b' && v[2] == 'b' && v[3] == 'b'); + } + + { // more actions + namespace phx = boost::phoenix; + using boost::spirit::_1; + + std::vector<int> v; + BOOST_TEST(test("123 456 789", (*int_)[phx::ref(v) = _1], space) && 3 == v.size() && + v[0] == 123 && v[1] == 456 && v[2] == 789); + } + + { // attribute customization + + x_attr x; + test_attr("abcde", *char_, x); + } + + return boost::report_errors(); +} + diff --git a/src/boost/libs/spirit/test/qi/lazy.cpp b/src/boost/libs/spirit/test/qi/lazy.cpp new file mode 100644 index 00000000..f1ea3385 --- /dev/null +++ b/src/boost/libs/spirit/test/qi/lazy.cpp @@ -0,0 +1,71 @@ +/*============================================================================= + 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 <boost/detail/lightweight_test.hpp> +#include <boost/spirit/include/qi_char.hpp> +#include <boost/spirit/include/qi_string.hpp> +#include <boost/spirit/include/qi_numeric.hpp> +#include <boost/spirit/include/qi_auxiliary.hpp> +#include <boost/spirit/include/qi_action.hpp> +#include <boost/spirit/include/qi_nonterminal.hpp> +#include <boost/spirit/include/qi_operator.hpp> +#include <boost/spirit/include/support_argument.hpp> +#include <boost/spirit/include/phoenix_core.hpp> +#include <boost/spirit/include/phoenix_operator.hpp> + +#include <iostream> +#include "test.hpp" + +int +main() +{ + using spirit_test::test; + using spirit_test::test_attr; + + namespace qi = boost::spirit::qi; + using boost::spirit::qi::_1; + using boost::spirit::qi::_val; + using boost::spirit::qi::int_; + using boost::spirit::qi::rule; + using boost::spirit::ascii::char_; + + using boost::phoenix::val; + using boost::phoenix::ref; + + { + BOOST_TEST(test("123", val(int_))); + } + + { + int result; + BOOST_TEST(test("123", qi::lazy(val(int_))[ref(result) = _1])); + BOOST_TEST((result == 123)); + } + + { + rule<char const*, char()> r; + + r = char_[_val = _1] >> *qi::lazy(_val); + + BOOST_TEST(test("aaaaaaaaaaaa", r)); + BOOST_TEST(!test("abbbbbbbbbb", r)); + BOOST_TEST(test("bbbbbbbbbbb", r)); + } + + { + rule<char const*, std::string()> r; + + r = + '<' >> *(char_ - '>')[_val += _1] >> '>' + >> "</" >> qi::lazy(_val) >> '>' + ; + + BOOST_TEST(test("<tag></tag>", r)); + BOOST_TEST(!test("<foo></bar>", r)); + } + + return boost::report_errors(); +} diff --git a/src/boost/libs/spirit/test/qi/lexeme.cpp b/src/boost/libs/spirit/test/qi/lexeme.cpp new file mode 100644 index 00000000..e8e144a9 --- /dev/null +++ b/src/boost/libs/spirit/test/qi/lexeme.cpp @@ -0,0 +1,41 @@ +/*============================================================================= + Copyright (c) 2001-2010 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/include/qi_directive.hpp> +#include <boost/spirit/include/qi_char.hpp> +#include <boost/spirit/include/qi_operator.hpp> +#include <boost/spirit/include/qi_nonterminal.hpp> + +#include <iostream> +#include "test.hpp" + +int +main() +{ + using spirit_test::test; + using boost::spirit::ascii::space; + using boost::spirit::ascii::space_type; + using boost::spirit::ascii::digit; + using boost::spirit::qi::lexeme; + using boost::spirit::qi::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))); + + rule<char const*, space_type> rr; + rule<char const*> r; + r = +digit; + 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/qi/list.cpp b/src/boost/libs/spirit/test/qi/list.cpp new file mode 100644 index 00000000..dee8ec1d --- /dev/null +++ b/src/boost/libs/spirit/test/qi/list.cpp @@ -0,0 +1,141 @@ +/*============================================================================= + 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 <set> +#include <map> + +#include <boost/detail/lightweight_test.hpp> + +#include <boost/spirit/include/qi_operator.hpp> +#include <boost/spirit/include/qi_char.hpp> +#include <boost/spirit/include/qi_string.hpp> +#include <boost/spirit/include/qi_numeric.hpp> +#include <boost/spirit/include/qi_directive.hpp> +#include <boost/spirit/include/qi_action.hpp> +#include <boost/spirit/include/support_argument.hpp> +#include <boost/spirit/include/phoenix_core.hpp> +#include <boost/spirit/include/phoenix_operator.hpp> +#include <boost/spirit/include/phoenix_object.hpp> +#include <boost/spirit/include/phoenix_container.hpp> +#include <boost/fusion/include/std_pair.hpp> + +#include <string> +#include <iostream> +#include "test.hpp" + +using namespace spirit_test; + +int +main() +{ + using namespace boost::spirit::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::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::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]); + } + + { + typedef std::set<std::pair<std::string, std::string> > set_type; + set_type s; + BOOST_TEST(test_attr("k1=v1&k2=v2", + (*(char_ - '=') >> '=' >> *(char_ - '&')) % '&', s)); + + set_type::const_iterator it = s.begin(); + BOOST_TEST(s.size() == 2); + BOOST_TEST(it != s.end() && (*it).first == "k1" && (*it).second == "v1"); + BOOST_TEST(++it != s.end() && (*it).first == "k2" && (*it).second == "v2"); + } + + { + typedef std::map<std::string, std::string> map_type; + map_type m; + BOOST_TEST(test_attr("k1=v1&k2=v2", + (*(char_ - '=') >> '=' >> *(char_ - '&')) % '&', m)); + + map_type::const_iterator it = m.begin(); + BOOST_TEST(m.size() == 2); + BOOST_TEST(it != m.end() && (*it).first == "k1" && (*it).second == "v1"); + BOOST_TEST(++it != m.end() && (*it).first == "k2" && (*it).second == "v2"); + } + + { // actions + namespace phx = boost::phoenix; + using boost::phoenix::begin; + using boost::phoenix::end; + using boost::phoenix::construct; + using boost::spirit::qi::_1; + + std::string s; + BOOST_TEST(test("a,b,c,d,e,f,g,h", (char_ % ',') + [phx::ref(s) = construct<std::string>(begin(_1), end(_1))])); + } + + return boost::report_errors(); +} + diff --git a/src/boost/libs/spirit/test/qi/lit1.cpp b/src/boost/libs/spirit/test/qi/lit1.cpp new file mode 100644 index 00000000..6f8eaf08 --- /dev/null +++ b/src/boost/libs/spirit/test/qi/lit1.cpp @@ -0,0 +1,96 @@ +/*============================================================================= + Copyright (c) 2001-2011 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/detail/workaround.hpp> +#include <boost/spirit/include/qi_string.hpp> +#include <boost/spirit/include/qi_char.hpp> +#include <boost/spirit/include/qi_action.hpp> +#include <boost/spirit/include/phoenix_core.hpp> +#include <boost/spirit/include/phoenix_operator.hpp> + +#include <iostream> +#include "test.hpp" + +int +main() +{ + using spirit_test::test; + using spirit_test::test_attr; + using boost::spirit::qi::string; + using boost::spirit::qi::_1; + + { + 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::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::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::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"); + } + + { // lazy string + + using namespace boost::spirit::ascii; + namespace phx = boost::phoenix; + + BOOST_TEST((test("x", string(phx::val("x"))))); + + std::string str; // make sure lazy lits have an attribute + BOOST_TEST(test("x", string(phx::val("x"))[phx::ref(str) = _1])); + BOOST_TEST(str == "x"); + } + + return boost::report_errors(); +} diff --git a/src/boost/libs/spirit/test/qi/lit2.cpp b/src/boost/libs/spirit/test/qi/lit2.cpp new file mode 100644 index 00000000..7d4ef92a --- /dev/null +++ b/src/boost/libs/spirit/test/qi/lit2.cpp @@ -0,0 +1,58 @@ +/*============================================================================= + Copyright (c) 2001-2011 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/detail/workaround.hpp> +#include <boost/spirit/include/qi_string.hpp> +#include <boost/spirit/include/qi_char.hpp> +#include <boost/spirit/include/qi_action.hpp> +#include <boost/spirit/include/phoenix_core.hpp> +#include <boost/spirit/include/phoenix_operator.hpp> + +#include <iostream> +#include "test.hpp" + +int +main() +{ + using spirit_test::test; + using spirit_test::test_attr; + using boost::spirit::qi::lit; + using boost::spirit::qi::_1; + + { + 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::ascii; + BOOST_TEST((test(" kimpo", lit("kimpo"), space))); + BOOST_TEST((test(L" kimpo", lit(L"kimpo"), space))); + } + + { + using namespace boost::spirit::ascii; + 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/qi/match_manip.hpp b/src/boost/libs/spirit/test/qi/match_manip.hpp new file mode 100644 index 00000000..b40ac67f --- /dev/null +++ b/src/boost/libs/spirit/test/qi/match_manip.hpp @@ -0,0 +1,70 @@ +/*============================================================================= + Copyright (c) 2001-2010 Hartmut Kaiser + Copyright (c) 2001-2010 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_MATCH_MANIP_HPP) +#define BOOST_SPIRIT_TEST_MATCH_MANIP_HPP + +#include <boost/config/warning_disable.hpp> + +#include <boost/spirit/include/support_argument.hpp> +#include <boost/spirit/include/qi_action.hpp> +#include <boost/spirit/include/qi_numeric.hpp> +#include <boost/spirit/include/qi_operator.hpp> +#include <boost/spirit/include/qi_char.hpp> +#include <boost/spirit/include/qi_operator.hpp> +#include <boost/spirit/include/qi_stream.hpp> +#include <boost/spirit/include/qi_match.hpp> +#include <boost/spirit/include/qi_match_auto.hpp> +#include <boost/spirit/include/phoenix_core.hpp> +#include <boost/spirit/include/phoenix_operator.hpp> +#include <boost/spirit/include/phoenix_statement.hpp> + +#include <string> +#include <sstream> +#include <vector> +#include <list> + +#include <boost/detail/lightweight_test.hpp> + +/////////////////////////////////////////////////////////////////////////////// +template <typename Char, typename Expr> +bool test(Char const *toparse, Expr const& expr) +{ + namespace spirit = boost::spirit; + BOOST_SPIRIT_ASSERT_MATCH(spirit::qi::domain, Expr); + + std::istringstream istrm(toparse); + istrm.unsetf(std::ios::skipws); + istrm >> spirit::qi::compile<spirit::qi::domain>(expr); + return istrm.good() || istrm.eof(); +} + +template <typename Char, typename Expr, typename CopyExpr, typename CopyAttr + , typename Skipper, typename Attribute> +bool test(Char const *toparse, + boost::spirit::qi::detail::match_manip< + Expr, CopyExpr, CopyAttr, Skipper, Attribute> const& mm) +{ + std::istringstream istrm(toparse); + istrm.unsetf(std::ios::skipws); + istrm >> mm; + return istrm.good() || istrm.eof(); +} + +/////////////////////////////////////////////////////////////////////////////// +bool is_list_ok(std::list<char> const& l) +{ + std::list<char>::const_iterator cit = l.begin(); + if (cit == l.end() || *cit != 'a') + return false; + if (++cit == l.end() || *cit != 'b') + return false; + + return ++cit != l.end() && *cit == 'c'; +} + +#endif diff --git a/src/boost/libs/spirit/test/qi/match_manip1.cpp b/src/boost/libs/spirit/test/qi/match_manip1.cpp new file mode 100644 index 00000000..c9733f4f --- /dev/null +++ b/src/boost/libs/spirit/test/qi/match_manip1.cpp @@ -0,0 +1,116 @@ +/*============================================================================= + Copyright (c) 2001-2010 Hartmut Kaiser + Copyright (c) 2001-2010 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 "match_manip.hpp" + +int +main() +{ + using boost::spirit::qi::_1; + using boost::spirit::qi::_2; + using boost::spirit::qi::match; + using boost::spirit::qi::phrase_match; + using boost::spirit::qi::typed_stream; + using boost::spirit::qi::stream; + using boost::spirit::qi::int_; + + using namespace boost::spirit::ascii; + namespace fusion = boost::fusion; + namespace phx = boost::phoenix; + + { + char c = '\0'; + BOOST_TEST(test( "a", + char_[phx::ref(c) = _1] + ) && c == 'a'); + + c = '\0'; + BOOST_TEST(test( "a", + match(char_[phx::ref(c) = _1]) + ) && c == 'a'); + + c = '\0'; + BOOST_TEST(test( " a", + phrase_match(char_[phx::ref(c) = _1], space) + ) && c == 'a'); + + c = '\0'; + BOOST_TEST(test( "a", + match(char_, c) + ) && c == 'a'); + + c = '\0'; + BOOST_TEST(test( " a", + phrase_match(char_, space, c) + ) && c == 'a'); + } + + { + /////////////////////////////////////////////////////////////////////// + typedef typed_stream<char> char_stream_type; + char_stream_type const char_stream = char_stream_type(); + + typedef typed_stream<int> int_stream_type; + int_stream_type const int_stream = int_stream_type(); + + /////////////////////////////////////////////////////////////////////// + char c = '\0'; + BOOST_TEST(test( "a", + char_stream[phx::ref(c) = _1] + ) && c == 'a'); + + c = '\0'; + BOOST_TEST(test( "a", + match(char_stream[phx::ref(c) = _1]) + ) && c == 'a'); + + c = '\0'; + BOOST_TEST(test( " a", + phrase_match(char_stream[phx::ref(c) = _1], space) + ) && c == 'a'); + + int i = 0; + BOOST_TEST(test( "42", + int_stream[phx::ref(i) = _1] + ) && i == 42); + + i = 0; + BOOST_TEST(test( "42", + match(int_stream[phx::ref(i) = _1]) + ) && i == 42); + + i = 0; + BOOST_TEST(test( " 42", + phrase_match(int_stream[phx::ref(i) = _1], space) + ) && i == 42); + + /////////////////////////////////////////////////////////////////////// + c = '\0'; + BOOST_TEST(test( "a", + match(stream, c) + ) && c == 'a'); + + c = '\0'; + BOOST_TEST(test( " a", + phrase_match(stream, space, c) + ) && c == 'a'); + + i = 0; + BOOST_TEST(test( "42", + match(stream, i) + ) && i == 42); + + i = 0; + BOOST_TEST(test( " 42", + phrase_match(stream, space, i) + ) && i == 42); + } + + return boost::report_errors(); +} + diff --git a/src/boost/libs/spirit/test/qi/match_manip2.cpp b/src/boost/libs/spirit/test/qi/match_manip2.cpp new file mode 100644 index 00000000..6196caab --- /dev/null +++ b/src/boost/libs/spirit/test/qi/match_manip2.cpp @@ -0,0 +1,98 @@ +/*============================================================================= + Copyright (c) 2001-2010 Hartmut Kaiser + Copyright (c) 2001-2010 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 "match_manip.hpp" + +int +main() +{ + using boost::spirit::qi::_1; + using boost::spirit::qi::_2; + using boost::spirit::qi::match; + using boost::spirit::qi::phrase_match; + using boost::spirit::qi::typed_stream; + using boost::spirit::qi::stream; + using boost::spirit::qi::int_; + + using namespace boost::spirit::ascii; + namespace fusion = boost::fusion; + namespace phx = boost::phoenix; + + { + char a = '\0', b = '\0'; + BOOST_TEST(test( "ab", + char_[phx::ref(a) = _1] >> char_[phx::ref(b) = _1] + ) && a == 'a' && b == 'b'); + + a = '\0', b = '\0'; + BOOST_TEST(test( "ab", + match(char_[phx::ref(a) = _1] >> char_[phx::ref(b) = _1]) + ) && a == 'a' && b == 'b'); + + a = '\0', b = '\0'; + BOOST_TEST(test( " a b", + phrase_match(char_[phx::ref(a) = _1] >> char_[phx::ref(b) = _1], space) + ) && a == 'a' && b == 'b'); + + fusion::vector<char, char> t; + BOOST_TEST(test( "ab", + match(char_ >> char_, t) + ) && fusion::at_c<0>(t) == 'a' && fusion::at_c<1>(t) == 'b'); + + t = fusion::vector<char, char>(); + BOOST_TEST(test( " a b", + phrase_match(char_ >> char_, space, t) + ) && fusion::at_c<0>(t) == 'a' && fusion::at_c<1>(t) == 'b'); + } + + { + char a = '\0', b = '\0', c = '\0'; + BOOST_TEST(test( "abc", + char_[phx::ref(a) = _1] >> char_[phx::ref(b) = _1] >> char_[phx::ref(c) = _1] + ) && a == 'a' && b == 'b' && c == 'c'); + + BOOST_TEST(test( "abc", + match(char_('a') >> char_('b') >> char_('c')) + )); + + BOOST_TEST(test( " a b c", + phrase_match(char_('a') >> char_('b') >> char_('c'), space) + )); + + BOOST_TEST(!test( "abc", + match(char_('a') >> char_('b') >> char_('d')) + )); + + BOOST_TEST(!test( " a b c", + phrase_match(char_('a') >> char_('b') >> char_('d'), space) + )); + + fusion::vector<char, char, char> t; + BOOST_TEST(test( "abc", + match(char_ >> char_ >> char_, t) + ) && fusion::at_c<0>(t) == 'a' && fusion::at_c<1>(t) == 'b' && fusion::at_c<2>(t) == 'c'); + + t = fusion::vector<char, char, char>(); + BOOST_TEST(test( " a b c", + phrase_match(char_ >> char_ >> char_, space, t) + ) && fusion::at_c<0>(t) == 'a' && fusion::at_c<1>(t) == 'b' && fusion::at_c<2>(t) == 'c'); + + t = fusion::vector<char, char, char>(); + BOOST_TEST(test( "abc", + match(t) + ) && fusion::at_c<0>(t) == 'a' && fusion::at_c<1>(t) == 'b' && fusion::at_c<2>(t) == 'c'); + + t = fusion::vector<char, char, char>(); + BOOST_TEST(test( " a b c", + phrase_match(t, space) + ) && fusion::at_c<0>(t) == 'a' && fusion::at_c<1>(t) == 'b' && fusion::at_c<2>(t) == 'c'); + } + + return boost::report_errors(); +} + diff --git a/src/boost/libs/spirit/test/qi/match_manip3.cpp b/src/boost/libs/spirit/test/qi/match_manip3.cpp new file mode 100644 index 00000000..6f272bb8 --- /dev/null +++ b/src/boost/libs/spirit/test/qi/match_manip3.cpp @@ -0,0 +1,113 @@ +/*============================================================================= + Copyright (c) 2001-2010 Hartmut Kaiser + Copyright (c) 2001-2010 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 "match_manip.hpp" + +int +main() +{ + using boost::spirit::qi::_1; + using boost::spirit::qi::_2; + using boost::spirit::qi::match; + using boost::spirit::qi::phrase_match; + using boost::spirit::qi::typed_stream; + using boost::spirit::qi::stream; + using boost::spirit::qi::int_; + + using namespace boost::spirit::ascii; + namespace fusion = boost::fusion; + namespace phx = boost::phoenix; + + { + char a = '\0'; + int i = 0; + BOOST_TEST(test( "a2", + (char_ >> int_)[phx::ref(a) = _1, phx::ref(i) = _2] + ) && a == 'a' && i == 2); + + fusion::vector<char, int> t; + BOOST_TEST(test( "a2", + match(char_ >> int_, t) + ) && fusion::at_c<0>(t) == 'a' && fusion::at_c<1>(t) == 2); + + t = fusion::vector<char, int>(); + BOOST_TEST(test( " a 2", + phrase_match(char_ >> int_, space, t) + ) && fusion::at_c<0>(t) == 'a' && fusion::at_c<1>(t) == 2); + + BOOST_TEST(!test( "a2", + match(char_ >> alpha, t) + )); + BOOST_TEST(!test( " a 2", + phrase_match(char_ >> alpha, space, t) + )); + } + + { + // parse elements of a vector + std::vector<char> v; + BOOST_TEST(test( "abc", + (*char_)[phx::ref(v) = _1] + ) && 3 == v.size() && v[0] == 'a' && v[1] == 'b' && v[2] == 'c'); + + v.clear(); + BOOST_TEST(test( "abc", + match(*char_, v) + ) && 3 == v.size() && v[0] == 'a' && v[1] == 'b' && v[2] == 'c'); + + v.clear(); + BOOST_TEST(test( " a b c", + phrase_match(*char_, space, v) + ) && 3 == v.size() && v[0] == 'a' && v[1] == 'b' && v[2] == 'c'); + + v.clear(); + BOOST_TEST(test( "abc", + match(v) + ) && 3 == v.size() && v[0] == 'a' && v[1] == 'b' && v[2] == 'c'); + + v.clear(); + BOOST_TEST(test( " a b c", + phrase_match(v, space) + ) && 3 == v.size() && v[0] == 'a' && v[1] == 'b' && v[2] == 'c'); + + // parse a comma separated list of vector elements + v.clear(); + BOOST_TEST(test( "a,b,c", + match(char_ % ',', v) + ) && 3 == v.size() && v[0] == 'a' && v[1] == 'b' && v[2] == 'c'); + + v.clear(); + BOOST_TEST(test( " a , b , c", + phrase_match(char_ % ',', space, v) + ) && 3 == v.size() && v[0] == 'a' && v[1] == 'b' && v[2] == 'c'); + + // output all elements of a list + std::list<char> l; + BOOST_TEST(test( "abc", + match(*char_, l) + ) && 3 == l.size() && is_list_ok(l)); + + l.clear(); + BOOST_TEST(test( " a b c", + phrase_match(*char_, space, l) + ) && 3 == l.size() && is_list_ok(l)); + + l.clear(); + BOOST_TEST(test( "abc", + match(l) + ) && 3 == l.size() && is_list_ok(l)); + + l.clear(); + BOOST_TEST(test( " a b c", + phrase_match(l, space) + ) && 3 == l.size() && is_list_ok(l)); + } + + return boost::report_errors(); +} + diff --git a/src/boost/libs/spirit/test/qi/match_manip_attr.cpp b/src/boost/libs/spirit/test/qi/match_manip_attr.cpp new file mode 100644 index 00000000..e3417992 --- /dev/null +++ b/src/boost/libs/spirit/test/qi/match_manip_attr.cpp @@ -0,0 +1,168 @@ +// 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/config/warning_disable.hpp> +#include <boost/detail/lightweight_test.hpp> + +#include <boost/spirit/include/qi_char.hpp> +#include <boost/spirit/include/qi_operator.hpp> +#include <boost/spirit/include/qi_parse.hpp> + +#include "test_manip_attr.hpp" + +#if SPIRIT_ARGUMENTS_LIMIT < 10 +# error SPIRIT_ARGUMENTS_LIMIT must be at least 10 to run the test +#endif + +using namespace spirit_test; + +/////////////////////////////////////////////////////////////////////////////// +int main() +{ + using namespace boost::spirit; + + { + using namespace boost::spirit::ascii; + + BOOST_TEST(test("1", char_, '1')); + BOOST_TEST(test("12", char_ >> char_, '1', '2')); + BOOST_TEST(test("123", char_ >> char_ >> char_, '1', '2', '3')); + BOOST_TEST(test("1234" + , char_ >> char_ >> char_ >> char_ + , '1', '2', '3', '4')); + BOOST_TEST(test("12345" + , char_ >> char_ >> char_ >> char_ >> char_ + , '1', '2', '3', '4', '5')); + BOOST_TEST(test("123456" + , char_ >> char_ >> char_ >> char_ >> char_ >> char_ + , '1', '2', '3', '4', '5', '6')); + BOOST_TEST(test("1234567" + , char_ >> char_ >> char_ >> char_ >> char_ >> char_ >> char_ + , '1', '2', '3', '4', '5', '6', '7')); + BOOST_TEST(test("12345678" + , char_ >> char_ >> char_ >> char_ >> char_ >> char_ >> char_ >> char_ + , '1', '2', '3', '4', '5', '6', '7', '8')); + BOOST_TEST(test("123456789" + , char_ >> char_ >> char_ >> char_ >> char_ >> char_ >> char_ >> char_ >> char_ + , '1', '2', '3', '4', '5', '6', '7', '8', '9')); + BOOST_TEST(test("1234567890" + , char_ >> char_ >> char_ >> char_ >> char_ >> char_ >> char_ >> char_ >> char_ >> char_ + , '1', '2', '3', '4', '5', '6', '7', '8', '9', '0')); + } + + { + using namespace boost::spirit::ascii; + + BOOST_TEST(test_skipped(" 1 ", char_, space, '1')); + BOOST_TEST(test_skipped(" 1 2 " + , char_ >> char_, space, '1', '2')); + BOOST_TEST(test_skipped(" 1 2 3 " + , char_ >> char_ >> char_, space, '1', '2', '3')); + BOOST_TEST(test_skipped(" 1 2 3 4 " + , char_ >> char_ >> char_ >> char_ + , space, '1', '2', '3', '4')); + BOOST_TEST(test_skipped(" 1 2 3 4 5 " + , char_ >> char_ >> char_ >> char_ >> char_ + , space, '1', '2', '3', '4', '5')); + BOOST_TEST(test_skipped(" 1 2 3 4 5 6 " + , char_ >> char_ >> char_ >> char_ >> char_ >> char_ + , space, '1', '2', '3', '4', '5', '6')); + BOOST_TEST(test_skipped(" 1 2 3 4 5 6 7 " + , char_ >> char_ >> char_ >> char_ >> char_ >> char_ >> char_ + , space, '1', '2', '3', '4', '5', '6', '7')); + BOOST_TEST(test_skipped(" 1 2 3 4 5 6 7 8 " + , char_ >> char_ >> char_ >> char_ >> char_ >> char_ >> char_ >> char_ + , space, '1', '2', '3', '4', '5', '6', '7', '8')); + BOOST_TEST(test_skipped(" 1 2 3 4 5 6 7 8 9 " + , char_ >> char_ >> char_ >> char_ >> char_ >> char_ >> char_ >> char_ >> char_ + , space, '1', '2', '3', '4', '5', '6', '7', '8', '9')); + BOOST_TEST(test_skipped(" 1 2 3 4 5 6 7 8 9 0 " + , char_ >> char_ >> char_ >> char_ >> char_ >> char_ >> char_ >> char_ >> char_ >> char_ + , space, '1', '2', '3', '4', '5', '6', '7', '8', '9', '0')); + } + + { + using namespace boost::spirit::ascii; + using boost::spirit::qi::skip_flag; + + BOOST_TEST(test_postskipped(" 1 ", char_, space + , skip_flag::postskip, '1')); + BOOST_TEST(test_postskipped(" 1 2 " + , char_ >> char_, space, skip_flag::postskip + , '1', '2')); + BOOST_TEST(test_postskipped(" 1 2 3 " + , char_ >> char_ >> char_, space + , skip_flag::postskip, '1', '2', '3')); + BOOST_TEST(test_postskipped(" 1 2 3 4 " + , char_ >> char_ >> char_ >> char_ + , space, skip_flag::postskip, '1', '2', '3', '4')); + BOOST_TEST(test_postskipped(" 1 2 3 4 5 " + , char_ >> char_ >> char_ >> char_ >> char_ + , space, skip_flag::postskip, '1', '2', '3', '4', '5')); + BOOST_TEST(test_postskipped(" 1 2 3 4 5 6 " + , char_ >> char_ >> char_ >> char_ >> char_ >> char_ + , space, skip_flag::postskip + , '1', '2', '3', '4', '5', '6')); + BOOST_TEST(test_postskipped(" 1 2 3 4 5 6 7 " + , char_ >> char_ >> char_ >> char_ >> char_ >> char_ >> char_ + , space, skip_flag::postskip + , '1', '2', '3', '4', '5', '6', '7')); + BOOST_TEST(test_postskipped(" 1 2 3 4 5 6 7 8 " + , char_ >> char_ >> char_ >> char_ >> char_ >> char_ >> char_ >> char_ + , space, skip_flag::postskip + , '1', '2', '3', '4', '5', '6', '7', '8')); + BOOST_TEST(test_postskipped(" 1 2 3 4 5 6 7 8 9 " + , char_ >> char_ >> char_ >> char_ >> char_ >> char_ >> char_ >> char_ >> char_ + , space, skip_flag::postskip + , '1', '2', '3', '4', '5', '6', '7', '8', '9')); + BOOST_TEST(test_postskipped(" 1 2 3 4 5 6 7 8 9 0 " + , char_ >> char_ >> char_ >> char_ >> char_ >> char_ >> char_ >> char_ >> char_ >> char_ + , space, skip_flag::postskip + , '1', '2', '3', '4', '5', '6', '7', '8', '9', '0')); + } + + { + using namespace boost::spirit::ascii; + using boost::spirit::qi::skip_flag; + + BOOST_TEST(test_postskipped(" 1", char_, space + , skip_flag::dont_postskip, '1')); + BOOST_TEST(test_postskipped(" 1 2" + , char_ >> char_, space, skip_flag::dont_postskip + , '1', '2')); + BOOST_TEST(test_postskipped(" 1 2 3" + , char_ >> char_ >> char_, space + , skip_flag::dont_postskip, '1', '2', '3')); + BOOST_TEST(test_postskipped(" 1 2 3 4" + , char_ >> char_ >> char_ >> char_ + , space, skip_flag::dont_postskip, '1', '2', '3', '4')); + BOOST_TEST(test_postskipped(" 1 2 3 4 5" + , char_ >> char_ >> char_ >> char_ >> char_ + , space, skip_flag::dont_postskip, '1', '2', '3', '4', '5')); + BOOST_TEST(test_postskipped(" 1 2 3 4 5 6" + , char_ >> char_ >> char_ >> char_ >> char_ >> char_ + , space, skip_flag::dont_postskip + , '1', '2', '3', '4', '5', '6')); + BOOST_TEST(test_postskipped(" 1 2 3 4 5 6 7" + , char_ >> char_ >> char_ >> char_ >> char_ >> char_ >> char_ + , space, skip_flag::dont_postskip + , '1', '2', '3', '4', '5', '6', '7')); + BOOST_TEST(test_postskipped(" 1 2 3 4 5 6 7 8" + , char_ >> char_ >> char_ >> char_ >> char_ >> char_ >> char_ >> char_ + , space, skip_flag::dont_postskip + , '1', '2', '3', '4', '5', '6', '7', '8')); + BOOST_TEST(test_postskipped(" 1 2 3 4 5 6 7 8 9" + , char_ >> char_ >> char_ >> char_ >> char_ >> char_ >> char_ >> char_ >> char_ + , space, skip_flag::dont_postskip + , '1', '2', '3', '4', '5', '6', '7', '8', '9')); + BOOST_TEST(test_postskipped(" 1 2 3 4 5 6 7 8 9 0" + , char_ >> char_ >> char_ >> char_ >> char_ >> char_ >> char_ >> char_ >> char_ >> char_ + , space, skip_flag::dont_postskip + , '1', '2', '3', '4', '5', '6', '7', '8', '9', '0')); + } + + return boost::report_errors(); +} + diff --git a/src/boost/libs/spirit/test/qi/matches.cpp b/src/boost/libs/spirit/test/qi/matches.cpp new file mode 100644 index 00000000..2da889bf --- /dev/null +++ b/src/boost/libs/spirit/test/qi/matches.cpp @@ -0,0 +1,40 @@ +/*============================================================================= + 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/include/qi_char.hpp> +#include <boost/spirit/include/qi_directive.hpp> + +#include <iostream> +#include "test.hpp" + +namespace qi = boost::spirit::qi; + +int main() +{ + using spirit_test::test; + using spirit_test::test_attr; + using qi::matches; + using qi::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/qi/no_case.cpp b/src/boost/libs/spirit/test/qi/no_case.cpp new file mode 100644 index 00000000..4b1079bb --- /dev/null +++ b/src/boost/libs/spirit/test/qi/no_case.cpp @@ -0,0 +1,174 @@ +/*============================================================================= + Copyright (c) 2001-2011 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/include/qi_char.hpp> +#include <boost/spirit/include/qi_string.hpp> +#include <boost/spirit/include/qi_directive.hpp> +#include <boost/spirit/include/qi_action.hpp> +#include <boost/spirit/include/phoenix_core.hpp> +#include <boost/spirit/include/phoenix_operator.hpp> + +#include <iostream> +#include "test.hpp" + +int +main() +{ + using spirit_test::test; + using spirit_test::test_attr; + using boost::spirit::qi::lit; + + { + using namespace boost::spirit::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::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::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::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::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::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::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::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::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::standard; + namespace standard_wide = boost::spirit::standard_wide; + + BOOST_TEST(test("x", standard::no_case[standard::char_("a-z")])); + BOOST_TEST(test("X", standard::no_case[standard::char_("a-z")])); + BOOST_TEST(test(L"X", standard_wide::no_case[standard_wide::char_(L"a-z")])); + BOOST_TEST(test(L"X", standard_wide::no_case[standard_wide::char_(L"X")])); + } + + { + using namespace boost::spirit::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])); + } + + { // lazy no_case chars + + using namespace boost::spirit::ascii; + + using boost::phoenix::val; + using boost::phoenix::ref; + using boost::spirit::_1; + + BOOST_TEST((test("X", no_case[val('x')]))); + BOOST_TEST((test("h", no_case[char_(val('a'), val('n'))]))); + BOOST_TEST(test("0", no_case[char_(val("a-z0-9"))])); + + char ch; // make sure lazy chars have an attribute + BOOST_TEST(test("x", no_case[char_(val('x'))][ref(ch) = _1])); + BOOST_TEST(ch == 'x'); + } + + { // lazy no_case lits + + using namespace boost::spirit::ascii; + using boost::phoenix::val; + + BOOST_TEST(test("Bochi Bochi", no_case[val("bochi bochi")])); + BOOST_TEST(test("BOCHI BOCHI", no_case[val("bochi bochi")])); + BOOST_TEST(!test("Vavoo", no_case[val("bochi bochi")])); + } + + return boost::report_errors(); +} diff --git a/src/boost/libs/spirit/test/qi/no_skip.cpp b/src/boost/libs/spirit/test/qi/no_skip.cpp new file mode 100644 index 00000000..cad79e43 --- /dev/null +++ b/src/boost/libs/spirit/test/qi/no_skip.cpp @@ -0,0 +1,50 @@ +/*============================================================================= + Copyright (c) 2001-2010 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/include/qi_directive.hpp> +#include <boost/spirit/include/qi_char.hpp> +#include <boost/spirit/include/qi_operator.hpp> +#include <boost/spirit/include/qi_nonterminal.hpp> + +#include <iostream> +#include "test.hpp" + +int +main() +{ + using spirit_test::test_attr; + using boost::spirit::qi::no_skip; + using boost::spirit::qi::lexeme; + using boost::spirit::qi::char_; + using boost::spirit::qi::space; + + // without skipping no_skip is equivalent to lexeme + { + std::string str; + BOOST_TEST((test_attr("' abc '", '\'' >> no_skip[+~char_('\'')] >> '\'', str) && + str == " abc ")); + } + { + std::string str; + BOOST_TEST((test_attr("' abc '", '\'' >> lexeme[+~char_('\'')] >> '\'', str) && + 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) && + str == " abc ")); + } + { + std::string str; + BOOST_TEST((test_attr("' abc '", '\'' >> lexeme[+~char_('\'')] >> '\'', str, space) && + str == "abc ")); + } + + return boost::report_errors(); +} diff --git a/src/boost/libs/spirit/test/qi/not_predicate.cpp b/src/boost/libs/spirit/test/qi/not_predicate.cpp new file mode 100644 index 00000000..80b6a75d --- /dev/null +++ b/src/boost/libs/spirit/test/qi/not_predicate.cpp @@ -0,0 +1,27 @@ +/*============================================================================= + Copyright (c) 2001-2010 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/include/qi_operator.hpp> +#include <boost/spirit/include/qi_numeric.hpp> + +#include <iostream> +#include "test.hpp" + +int +main() +{ + using spirit_test::test; + using boost::spirit::qi::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/qi/omit.cpp b/src/boost/libs/spirit/test/qi/omit.cpp new file mode 100644 index 00000000..eacf112c --- /dev/null +++ b/src/boost/libs/spirit/test/qi/omit.cpp @@ -0,0 +1,127 @@ +/*============================================================================= + 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 <boost/detail/lightweight_test.hpp> +#include <boost/spirit/include/qi_operator.hpp> +#include <boost/spirit/include/qi_char.hpp> +#include <boost/spirit/include/qi_string.hpp> +#include <boost/spirit/include/qi_directive.hpp> +#include <boost/spirit/include/qi_numeric.hpp> +#include <boost/spirit/include/qi_action.hpp> +#include <boost/spirit/include/support_argument.hpp> +#include <boost/spirit/include/phoenix_core.hpp> +#include <boost/spirit/include/phoenix_operator.hpp> + +#include <string> +#include <iostream> +#include "test.hpp" + +int +main() +{ + using namespace boost::spirit::ascii; + using boost::spirit::qi::omit; + using boost::spirit::qi::unused_type; + using boost::spirit::qi::unused; + using boost::spirit::qi::int_; + using boost::spirit::qi::_1; + + 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; + + using boost::phoenix::ref; + + BOOST_TEST(test("x123\"a string\"", (char_ >> omit[int_] >> "\"a string\"") + [ref(c) = _1])); + BOOST_TEST(c == 'x'); + } + + + { // test action with omitted attribute + int n = 0; + + using boost::phoenix::ref; + + BOOST_TEST(test("x 123 \"a string\"", + (omit[char_] >> int_ >> "\"a string\"")[ref(n) = _1], space)); + BOOST_TEST(n == 123); + } + + return boost::report_errors(); +} + diff --git a/src/boost/libs/spirit/test/qi/optional.cpp b/src/boost/libs/spirit/test/qi/optional.cpp new file mode 100644 index 00000000..22855dee --- /dev/null +++ b/src/boost/libs/spirit/test/qi/optional.cpp @@ -0,0 +1,111 @@ +/*============================================================================= + 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 <boost/detail/lightweight_test.hpp> +#include <boost/spirit/include/qi_char.hpp> +#include <boost/spirit/include/qi_numeric.hpp> +#include <boost/spirit/include/qi_operator.hpp> +#include <boost/spirit/include/qi_action.hpp> +#include <boost/spirit/include/qi_directive.hpp> +#include <boost/spirit/include/support_argument.hpp> +#include <boost/spirit/include/phoenix_core.hpp> +#include <boost/spirit/include/phoenix_operator.hpp> +#include <boost/fusion/adapted/struct.hpp> + +#include <iostream> +#include "test.hpp" + +struct adata +{ + int a; + boost::optional<int> b; +}; + +BOOST_FUSION_ADAPT_STRUCT( + adata, + (int, a) + (boost::optional<int>, b) +) + +struct test_attribute_type +{ + template <typename Attribute, typename Context> + void operator()(Attribute&, Context&, bool&) const + { + BOOST_TEST(typeid(Attribute).name() == typeid(boost::optional<int>).name()); + } +}; + +int +main() +{ + using spirit_test::test; + using spirit_test::test_attr; + + using boost::spirit::qi::_1; + using boost::spirit::qi::int_; + using boost::spirit::qi::omit; + using boost::spirit::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"); + } + + { + namespace phx = boost::phoenix; + + boost::optional<int> n = 0; + BOOST_TEST((test("1234", (-int_)[phx::ref(n) = _1]))); + BOOST_TEST(n.get() == 1234); + + n = boost::optional<int>(); + BOOST_TEST((test("abcd", (-int_)[phx::ref(n) = _1], 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); + } + + return boost::report_errors(); +} diff --git a/src/boost/libs/spirit/test/qi/parse_attr.cpp b/src/boost/libs/spirit/test/qi/parse_attr.cpp new file mode 100644 index 00000000..b15c8551 --- /dev/null +++ b/src/boost/libs/spirit/test/qi/parse_attr.cpp @@ -0,0 +1,168 @@ +// 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/config/warning_disable.hpp> +#include <boost/detail/lightweight_test.hpp> + +#include <boost/spirit/include/qi_char.hpp> +#include <boost/spirit/include/qi_operator.hpp> +#include <boost/spirit/include/qi_parse_attr.hpp> + +#include "test_attr.hpp" + +#if SPIRIT_ARGUMENTS_LIMIT < 10 +# error SPIRIT_ARGUMENTS_LIMIT must be at least 10 to run the test +#endif + +using namespace spirit_test; + +/////////////////////////////////////////////////////////////////////////////// +int main() +{ + using namespace boost::spirit; + + { + using namespace boost::spirit::ascii; + + BOOST_TEST(test("1", char_, '1')); + BOOST_TEST(test("12", char_ >> char_, '1', '2')); + BOOST_TEST(test("123", char_ >> char_ >> char_, '1', '2', '3')); + BOOST_TEST(test("1234" + , char_ >> char_ >> char_ >> char_ + , '1', '2', '3', '4')); + BOOST_TEST(test("12345" + , char_ >> char_ >> char_ >> char_ >> char_ + , '1', '2', '3', '4', '5')); + BOOST_TEST(test("123456" + , char_ >> char_ >> char_ >> char_ >> char_ >> char_ + , '1', '2', '3', '4', '5', '6')); + BOOST_TEST(test("1234567" + , char_ >> char_ >> char_ >> char_ >> char_ >> char_ >> char_ + , '1', '2', '3', '4', '5', '6', '7')); + BOOST_TEST(test("12345678" + , char_ >> char_ >> char_ >> char_ >> char_ >> char_ >> char_ >> char_ + , '1', '2', '3', '4', '5', '6', '7', '8')); + BOOST_TEST(test("123456789" + , char_ >> char_ >> char_ >> char_ >> char_ >> char_ >> char_ >> char_ >> char_ + , '1', '2', '3', '4', '5', '6', '7', '8', '9')); + BOOST_TEST(test("1234567890" + , char_ >> char_ >> char_ >> char_ >> char_ >> char_ >> char_ >> char_ >> char_ >> char_ + , '1', '2', '3', '4', '5', '6', '7', '8', '9', '0')); + } + + { + using namespace boost::spirit::ascii; + + BOOST_TEST(test_skipped(" 1 ", char_, space, '1')); + BOOST_TEST(test_skipped(" 1 2 " + , char_ >> char_, space, '1', '2')); + BOOST_TEST(test_skipped(" 1 2 3 " + , char_ >> char_ >> char_, space, '1', '2', '3')); + BOOST_TEST(test_skipped(" 1 2 3 4 " + , char_ >> char_ >> char_ >> char_ + , space, '1', '2', '3', '4')); + BOOST_TEST(test_skipped(" 1 2 3 4 5 " + , char_ >> char_ >> char_ >> char_ >> char_ + , space, '1', '2', '3', '4', '5')); + BOOST_TEST(test_skipped(" 1 2 3 4 5 6 " + , char_ >> char_ >> char_ >> char_ >> char_ >> char_ + , space, '1', '2', '3', '4', '5', '6')); + BOOST_TEST(test_skipped(" 1 2 3 4 5 6 7 " + , char_ >> char_ >> char_ >> char_ >> char_ >> char_ >> char_ + , space, '1', '2', '3', '4', '5', '6', '7')); + BOOST_TEST(test_skipped(" 1 2 3 4 5 6 7 8 " + , char_ >> char_ >> char_ >> char_ >> char_ >> char_ >> char_ >> char_ + , space, '1', '2', '3', '4', '5', '6', '7', '8')); + BOOST_TEST(test_skipped(" 1 2 3 4 5 6 7 8 9 " + , char_ >> char_ >> char_ >> char_ >> char_ >> char_ >> char_ >> char_ >> char_ + , space, '1', '2', '3', '4', '5', '6', '7', '8', '9')); + BOOST_TEST(test_skipped(" 1 2 3 4 5 6 7 8 9 0 " + , char_ >> char_ >> char_ >> char_ >> char_ >> char_ >> char_ >> char_ >> char_ >> char_ + , space, '1', '2', '3', '4', '5', '6', '7', '8', '9', '0')); + } + + { + using namespace boost::spirit::ascii; + using boost::spirit::qi::skip_flag; + + BOOST_TEST(test_postskipped(" 1 ", char_, space + , skip_flag::postskip, '1')); + BOOST_TEST(test_postskipped(" 1 2 " + , char_ >> char_, space, skip_flag::postskip + , '1', '2')); + BOOST_TEST(test_postskipped(" 1 2 3 " + , char_ >> char_ >> char_, space + , skip_flag::postskip, '1', '2', '3')); + BOOST_TEST(test_postskipped(" 1 2 3 4 " + , char_ >> char_ >> char_ >> char_ + , space, skip_flag::postskip, '1', '2', '3', '4')); + BOOST_TEST(test_postskipped(" 1 2 3 4 5 " + , char_ >> char_ >> char_ >> char_ >> char_ + , space, skip_flag::postskip, '1', '2', '3', '4', '5')); + BOOST_TEST(test_postskipped(" 1 2 3 4 5 6 " + , char_ >> char_ >> char_ >> char_ >> char_ >> char_ + , space, skip_flag::postskip + , '1', '2', '3', '4', '5', '6')); + BOOST_TEST(test_postskipped(" 1 2 3 4 5 6 7 " + , char_ >> char_ >> char_ >> char_ >> char_ >> char_ >> char_ + , space, skip_flag::postskip + , '1', '2', '3', '4', '5', '6', '7')); + BOOST_TEST(test_postskipped(" 1 2 3 4 5 6 7 8 " + , char_ >> char_ >> char_ >> char_ >> char_ >> char_ >> char_ >> char_ + , space, skip_flag::postskip + , '1', '2', '3', '4', '5', '6', '7', '8')); + BOOST_TEST(test_postskipped(" 1 2 3 4 5 6 7 8 9 " + , char_ >> char_ >> char_ >> char_ >> char_ >> char_ >> char_ >> char_ >> char_ + , space, skip_flag::postskip + , '1', '2', '3', '4', '5', '6', '7', '8', '9')); + BOOST_TEST(test_postskipped(" 1 2 3 4 5 6 7 8 9 0 " + , char_ >> char_ >> char_ >> char_ >> char_ >> char_ >> char_ >> char_ >> char_ >> char_ + , space, skip_flag::postskip + , '1', '2', '3', '4', '5', '6', '7', '8', '9', '0')); + } + + { + using namespace boost::spirit::ascii; + using boost::spirit::qi::skip_flag; + + BOOST_TEST(test_postskipped(" 1", char_, space + , skip_flag::dont_postskip, '1')); + BOOST_TEST(test_postskipped(" 1 2" + , char_ >> char_, space, skip_flag::dont_postskip + , '1', '2')); + BOOST_TEST(test_postskipped(" 1 2 3" + , char_ >> char_ >> char_, space + , skip_flag::dont_postskip, '1', '2', '3')); + BOOST_TEST(test_postskipped(" 1 2 3 4" + , char_ >> char_ >> char_ >> char_ + , space, skip_flag::dont_postskip, '1', '2', '3', '4')); + BOOST_TEST(test_postskipped(" 1 2 3 4 5" + , char_ >> char_ >> char_ >> char_ >> char_ + , space, skip_flag::dont_postskip, '1', '2', '3', '4', '5')); + BOOST_TEST(test_postskipped(" 1 2 3 4 5 6" + , char_ >> char_ >> char_ >> char_ >> char_ >> char_ + , space, skip_flag::dont_postskip + , '1', '2', '3', '4', '5', '6')); + BOOST_TEST(test_postskipped(" 1 2 3 4 5 6 7" + , char_ >> char_ >> char_ >> char_ >> char_ >> char_ >> char_ + , space, skip_flag::dont_postskip + , '1', '2', '3', '4', '5', '6', '7')); + BOOST_TEST(test_postskipped(" 1 2 3 4 5 6 7 8" + , char_ >> char_ >> char_ >> char_ >> char_ >> char_ >> char_ >> char_ + , space, skip_flag::dont_postskip + , '1', '2', '3', '4', '5', '6', '7', '8')); + BOOST_TEST(test_postskipped(" 1 2 3 4 5 6 7 8 9" + , char_ >> char_ >> char_ >> char_ >> char_ >> char_ >> char_ >> char_ >> char_ + , space, skip_flag::dont_postskip + , '1', '2', '3', '4', '5', '6', '7', '8', '9')); + BOOST_TEST(test_postskipped(" 1 2 3 4 5 6 7 8 9 0" + , char_ >> char_ >> char_ >> char_ >> char_ >> char_ >> char_ >> char_ >> char_ >> char_ + , space, skip_flag::dont_postskip + , '1', '2', '3', '4', '5', '6', '7', '8', '9', '0')); + } + + return boost::report_errors(); +} + diff --git a/src/boost/libs/spirit/test/qi/pass_container1.cpp b/src/boost/libs/spirit/test/qi/pass_container1.cpp new file mode 100644 index 00000000..c78e0777 --- /dev/null +++ b/src/boost/libs/spirit/test/qi/pass_container1.cpp @@ -0,0 +1,187 @@ +// 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 <string> +#include <vector> +#include <set> +#include <map> + +#include <boost/detail/lightweight_test.hpp> + +#include <boost/spirit/include/qi_operator.hpp> +#include <boost/spirit/include/qi_char.hpp> +#include <boost/spirit/include/qi_string.hpp> +#include <boost/spirit/include/qi_numeric.hpp> +#include <boost/spirit/include/qi_directive.hpp> +#include <boost/spirit/include/qi_action.hpp> +#include <boost/spirit/include/qi_auxiliary.hpp> +#include <boost/spirit/include/support_argument.hpp> +#include <boost/fusion/include/std_pair.hpp> + +#include <string> +#include <iostream> +#include "test.hpp" + +using namespace spirit_test; + +inline bool compare(std::vector<char> const& v, std::string const& s) +{ + return v.size() == s.size() && std::equal(v.begin(), v.end(), s.begin()); +} + +int main() +{ + using boost::spirit::qi::char_; + using boost::spirit::qi::omit; + + { + std::vector<char> v; + BOOST_TEST(test_attr("a,b,c,d,e,f,g,h", char_ % ',', v) && + compare(v, "abcdefgh")); + + std::string s; + BOOST_TEST(test_attr("a,b,c,d,e,f,g,h", char_ % ',', s) && + s == "abcdefgh"); + + BOOST_TEST(test("a,b,c,d,e,f,g,h", char_ % ',')); + BOOST_TEST(test("a,b,c,d,e,f,g,h", omit[char_] % ',')); + } + + { + std::vector<char> v1; + BOOST_TEST(test_attr("ab,cd,ef,gh", (char_ >> char_) % ',', v1) && + compare(v1, "abcdefgh")); + v1.clear(); + BOOST_TEST(test_attr("ab,cd,ef,gh", (char_ >> omit[char_]) % ',', v1) && + compare(v1, "aceg")); + + std::string s; + BOOST_TEST(test_attr("ab,cd,ef,gh", (char_ >> char_) % ',', s) && + s == "abcdefgh"); + s.clear(); + BOOST_TEST(test_attr("ab,cd,ef,gh", (char_ >> omit[char_]) % ',', s) && + s == "aceg"); + + std::vector<std::pair<char, char> > v2; + BOOST_TEST(test_attr("ab,cd,ef,gh", (char_ >> char_) % ',', v2) && + v2.size() == 4 && + v2[0] == std::make_pair('a', 'b') && + v2[1] == std::make_pair('c', 'd') && + v2[2] == std::make_pair('e', 'f') && + v2[3] == std::make_pair('g', 'h')); + + s.clear(); + BOOST_TEST(test_attr("ab,cd,efg", (char_ >> char_) % ',' >> char_, s) && + s == "abcdefg"); + + BOOST_TEST(test("ab,cd,ef,gh", (char_ >> char_) % ',')); + BOOST_TEST(test("ab,cd,ef,gh", (omit[char_ >> char_]) % ',')); + } + + { + std::vector<char> v1; + BOOST_TEST(test_attr("abc,def,gh", (char_ >> *~char_(',')) % ',', v1) && + compare(v1, "abcdefgh")); + v1.clear(); + BOOST_TEST(test_attr("abc,def,gh", (char_ >> omit[*~char_(',')]) % ',', v1) && + compare(v1, "adg")); + v1.clear(); + BOOST_TEST(test_attr("abc,def,gh", (omit[char_] >> *~char_(',')) % ',', v1) && + compare(v1, "bcefh")); + + std::string s1; + BOOST_TEST(test_attr("abc,def,gh", (char_ >> *~char_(',')) % ',', s1) && + s1 == "abcdefgh"); + s1.clear(); + BOOST_TEST(test_attr("abc,def,gh", (char_ >> omit[*~char_(',')]) % ',', s1) && + s1 == "adg"); + s1.clear(); + BOOST_TEST(test_attr("abc,def,gh", (omit[char_] >> *~char_(',')) % ',', s1) && + s1 == "bcefh"); + + std::vector<std::pair<char, std::vector<char> > > v2; + BOOST_TEST(test_attr("abc,def,gh", (char_ >> *~char_(',')) % ',', v2) && + v2.size() == 3 && + v2[0].first == 'a' && compare(v2[0].second, "bc") && + v2[1].first == 'd' && compare(v2[1].second, "ef") && + v2[2].first == 'g' && compare(v2[2].second, "h")); + + std::vector<std::vector<char> > v3; + BOOST_TEST(test_attr("abc,def,gh", (omit[char_] >> *~char_(',')) % ',', v3) && + v3.size() == 3 && + compare(v3[0], "bc") && compare(v3[1], "ef") && + compare(v3[2], "h")); + + std::vector<char> v4; + BOOST_TEST(test_attr("abc,def,gh", (char_ >> omit[*~char_(',')]) % ',', v4) && + v4.size() == 3 && + v4[0] == 'a' && v4[1] == 'd' && v4[2] == 'g'); + + std::vector<std::string> v5; + BOOST_TEST(test_attr("abc,def,gh", (omit[char_] >> *~char_(',')) % ',', v5) && + v5.size() == 3 && + v5[0] == "bc" && v5[1] == "ef" && v5[2] == "h"); + + std::string s2; + BOOST_TEST(test_attr("abc,def,gh", (char_ >> omit[*~char_(',')]) % ',', s2) && + s2.size() == 3 && + s2 == "adg"); + + BOOST_TEST(test("abc,def,gh", (char_ >> *~char_(',')) % ',')); + BOOST_TEST(test("abc,def,gh", (omit[char_ >> *~char_(',')]) % ',')); + } + + { + using boost::spirit::qi::alpha; + using boost::spirit::qi::digit; + + std::vector<char> v1; + BOOST_TEST(test_attr("ab12,cd34,ef56", (*alpha >> *digit) % ',', v1) && + compare(v1, "ab12cd34ef56")); + v1.clear(); + BOOST_TEST(test_attr("ab12,cd34,ef56", (omit[*alpha] >> *digit) % ',', v1) && + compare(v1, "123456")); + v1.clear(); + BOOST_TEST(test_attr("ab12,cd34,ef56", (*alpha >> omit[*digit]) % ',', v1) && + compare(v1, "abcdef")); + + std::string s1; + BOOST_TEST(test_attr("ab12,cd34,ef56", (*alpha >> *digit) % ',', s1) && + s1 == "ab12cd34ef56"); + s1.clear(); + BOOST_TEST(test_attr("ab12,cd34,ef56", (omit[*alpha] >> *digit) % ',', s1) && + s1 == "123456"); + s1.clear(); + BOOST_TEST(test_attr("ab12,cd34,ef56", (*alpha >> omit[*digit]) % ',', s1) && + s1 == "abcdef"); + + std::vector<std::pair<std::vector<char>, std::vector<char> > > v2; + BOOST_TEST(test_attr("ab12,cd34,ef56", (*alpha >> *digit) % ',', v2) && + v2.size() == 3 && + compare(v2[0].first, "ab") && compare(v2[0].second, "12") && + compare(v2[1].first, "cd") && compare(v2[1].second, "34") && + compare(v2[2].first, "ef") && compare(v2[2].second, "56")); + + std::vector<std::pair<std::string, std::string> > v3; + BOOST_TEST(test_attr("ab12,cd34,ef56", (*alpha >> *digit) % ',', v3) && + v3.size() == 3 && + v3[0].first == "ab" && v3[0].second == "12" && + v3[1].first == "cd" && v3[1].second == "34" && + v3[2].first == "ef" && v3[2].second == "56"); + + std::vector<std::vector<char> > v4; + BOOST_TEST(test_attr("ab12,cd34,ef56", (omit[*alpha] >> *digit) % ',', v4) && + v4.size() == 3 && + compare(v4[0], "12") && + compare(v4[1], "34") && + compare(v4[2], "56")); + + BOOST_TEST(test("ab12,cd34,ef56", (*alpha >> *digit) % ',')); + BOOST_TEST(test("ab12,cd34,ef56", omit[*alpha >> *digit] % ',')); + } + + return boost::report_errors(); +} + diff --git a/src/boost/libs/spirit/test/qi/pass_container2.cpp b/src/boost/libs/spirit/test/qi/pass_container2.cpp new file mode 100644 index 00000000..ef54dca5 --- /dev/null +++ b/src/boost/libs/spirit/test/qi/pass_container2.cpp @@ -0,0 +1,266 @@ +// 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/config/warning_disable.hpp> +#include <boost/detail/lightweight_test.hpp> + +#include <string> +#include <vector> +#include <set> +#include <map> +#include <iostream> + +#include <boost/spirit/include/qi_operator.hpp> +#include <boost/spirit/include/qi_char.hpp> +#include <boost/spirit/include/qi_string.hpp> +#include <boost/spirit/include/qi_numeric.hpp> +#include <boost/spirit/include/qi_directive.hpp> +#include <boost/spirit/include/qi_action.hpp> +#include <boost/spirit/include/qi_auxiliary.hpp> +#include <boost/spirit/include/qi_nonterminal.hpp> +#include <boost/spirit/include/support_argument.hpp> +#include <boost/fusion/include/adapt_struct.hpp> +#include <boost/fusion/include/std_pair.hpp> +#include <boost/fusion/include/vector.hpp> + +#include "test.hpp" + +using namespace spirit_test; + +inline bool compare(std::vector<char> const& v, std::string const& s) +{ + return v.size() == s.size() && std::equal(v.begin(), v.end(), s.begin()); +} + +struct A +{ + int i1; + double d2; +}; + +BOOST_FUSION_ADAPT_STRUCT( + A, + (int, i1) + (double, d2) +) + +int main() +{ + using boost::spirit::qi::char_; + using boost::spirit::qi::omit; + + { + std::vector<std::vector<char> > v1; + BOOST_TEST(test_attr("abc,def,gh", *~char_(',') % ',', v1) && + v1.size() == 3 && + compare(v1[0], "abc") && + compare(v1[1], "def") && + compare(v1[2], "gh")); + + std::vector<std::string> v2; + BOOST_TEST(test_attr("abc,def,gh", *~char_(',') % ',', v2) && + v2.size() == 3 && v2[0] == "abc" && v2[1] == "def" && v2[2] == "gh"); + + BOOST_TEST(test("abc,def,gh", *~char_(',') % ',')); + BOOST_TEST(test("abc,def,gh", omit[*~char_(',')] % ',')); + } + + { + std::vector<char> v1; + BOOST_TEST(test_attr("a", char_ >> -(char_ % ','), v1) && + compare(v1, "a")); + v1.clear(); + BOOST_TEST(test_attr("ab,c", char_ >> -(char_ % ','), v1) && + compare(v1, "abc")); + v1.clear(); + BOOST_TEST(test_attr("a", char_ >> -char_, v1) && + compare(v1, "a")); + v1.clear(); + BOOST_TEST(test_attr("ab", char_ >> -char_, v1) && + compare(v1, "ab")); + + std::vector<boost::optional<char> > v2; + BOOST_TEST(test_attr("a", char_ >> -char_, v2) && + v2.size() == 2 && + boost::get<char>(v2[0]) == 'a' && + !v2[1]); + v2.clear(); + BOOST_TEST(test_attr("ab", char_ >> -char_, v2) && + v2.size() == 2 && + boost::get<char>(v2[0]) == 'a' && + boost::get<char>(v2[1]) == 'b'); + + std::string s; + BOOST_TEST(test_attr("a", char_ >> -(char_ % ','), s) && + s == "a"); + s.clear(); + BOOST_TEST(test_attr("ab,c", char_ >> -(char_ % ','), s) && + s == "abc"); + s.clear(); + BOOST_TEST(test_attr("ab", char_ >> -char_, s) && + s == "ab"); + s.clear(); + BOOST_TEST(test_attr("a", char_ >> -char_, s) && + s == "a"); + + BOOST_TEST(test("a", char_ >> -(char_ % ','))); + BOOST_TEST(test("ab,c", char_ >> -(char_ % ','))); + BOOST_TEST(test("a", char_ >> -char_)); + BOOST_TEST(test("ab", char_ >> -char_)); + } + + { + using boost::spirit::qi::eps; + + std::vector<char> v; + BOOST_TEST(test_attr("a", char_ >> ((char_ % ',') | eps), v) && + compare(v, "a")); + v.clear(); + BOOST_TEST(test_attr("ab,c", char_ >> ((char_ % ',') | eps), v) && + compare(v, "abc")); + + std::string s; + BOOST_TEST(test_attr("a", char_ >> ((char_ % ',') | eps), s) && + s == "a"); + s.clear(); + BOOST_TEST(test_attr("ab,c", char_ >> ((char_ % ',') | eps), s) && + s == "abc"); + + BOOST_TEST(test("a", char_ >> ((char_ % ',') | eps))); + BOOST_TEST(test("ab,c", char_ >> ((char_ % ',') | eps))); + } + + { + std::vector<char> v1; + BOOST_TEST(test_attr("abc1,abc2", + *~char_(',') >> *(',' >> *~char_(',')), v1) && + compare(v1, "abc1abc2")); + + std::vector<std::string> v2; + BOOST_TEST(test_attr("abc1,abc2", + *~char_(',') >> *(',' >> *~char_(',')), v2) && + v2.size() == 2 && + v2[0] == "abc1" && + v2[1] == "abc2"); + + std::string s; + BOOST_TEST(test_attr("abc1,abc2", + *~char_(',') >> *(',' >> *~char_(',')), s) && + s == "abc1abc2"); + } + + { + using boost::spirit::qi::alpha; + using boost::spirit::qi::digit; + + std::vector<char> v1; + BOOST_TEST(test_attr("ab1cd2", *(alpha >> alpha | +digit), v1) && + compare(v1, "ab1cd2")); + v1.clear(); + BOOST_TEST(test_attr("ab1cd2", *(alpha >> alpha | digit), v1) && + compare(v1, "ab1cd2")); + + std::string s1; + BOOST_TEST(test_attr("ab1cd2", *(alpha >> alpha | +digit), s1) && + s1 == "ab1cd2"); + s1.clear(); + BOOST_TEST(test_attr("ab1cd2", *(alpha >> alpha | digit), s1) && + s1 == "ab1cd2"); + } + + { + using boost::spirit::qi::rule; + using boost::spirit::qi::space; + using boost::spirit::qi::space_type; + using boost::spirit::qi::int_; + using boost::spirit::qi::double_; + + std::vector<A> v; + BOOST_TEST(test_attr("A 1 2.0", 'A' >> *(int_ >> double_), v, space) && + v.size() == 1 && v[0].i1 == 1 && v[0].d2 == 2.0); + + v.clear(); + BOOST_TEST(test_attr("1 2.0", *(int_ >> double_), v, space) && + v.size() == 1 && v[0].i1 == 1 && v[0].d2 == 2.0); + + v.clear(); + rule<char const*, std::vector<A>()> r = *(int_ >> ',' >> double_); + BOOST_TEST(test_attr("1,2.0", r, v) && + v.size() == 1 && v[0].i1 == 1 && v[0].d2 == 2.0); + } + + { + using boost::spirit::qi::rule; + using boost::spirit::qi::int_; + using boost::spirit::qi::double_; + + rule<char const*, A()> r = int_ >> ',' >> double_; + rule<char const*, std::vector<A>()> r2 = 'A' >> *(r >> ',' >> r); + + std::vector<A> v; + BOOST_TEST(test_attr("A1,2.0,3,4.0", r2, v) && + v.size() == 2 && v[0].i1 == 1.0 && v[0].d2 == 2.0 && + v[1].i1 == 3.0 && v[1].d2 == 4.0); + + v.clear(); + BOOST_TEST(test_attr("A1,2.0,3,4.0", 'A' >> *(r >> ',' >> r), v) && + v.size() == 2 && v[0].i1 == 1.0 && v[0].d2 == 2.0 && + v[1].i1 == 3.0 && v[1].d2 == 4.0); + + v.clear(); + BOOST_TEST(test_attr("1,2.0,3,4.0", *(r >> ',' >> r), v) && + v.size() == 2 && v[0].i1 == 1.0 && v[0].d2 == 2.0 && + v[1].i1 == 3.0 && v[1].d2 == 4.0); + } + + { + using boost::spirit::qi::rule; + using boost::spirit::qi::int_; + using boost::spirit::qi::double_; + using boost::fusion::at_c; + + typedef boost::fusion::vector<int, double> data_type; + + rule<char const*, data_type()> r = int_ >> ',' >> double_; + rule<char const*, std::vector<data_type>()> r2 = 'A' >> *(r >> ',' >> r); + + std::vector<data_type> v; + BOOST_TEST(test_attr("A1,2.0,3,4.0", r2, v) && + v.size() == 2 && at_c<0>(v[0]) == 1 && at_c<1>(v[0]) == 2.0 && + at_c<0>(v[1]) == 3 && at_c<1>(v[1]) == 4.0); + + v.clear(); + BOOST_TEST(test_attr("A1,2.0,3,4.0", 'A' >> *(r >> ',' >> r), v) && + v.size() == 2 && at_c<0>(v[0]) == 1 && at_c<1>(v[0]) == 2.0 && + at_c<0>(v[1]) == 3 && at_c<1>(v[1]) == 4.0); + + v.clear(); + BOOST_TEST(test_attr("1,2.0,3,4.0", *(r >> ',' >> r), v) && + v.size() == 2 && at_c<0>(v[0]) == 1 && at_c<1>(v[0]) == 2.0 && + at_c<0>(v[1]) == 3 && at_c<1>(v[1]) == 4.0); + } + +// doesn't currently work +// { +// std::vector<std::vector<char> > v2; +// BOOST_TEST(test_attr("ab1cd123", *(alpha >> alpha | +digit), v2) && +// v2.size() == 4 && +// compare(v2[0], "ab") && +// compare(v2[1], "1") && +// compare(v2[2], "cd") && +// compare(v2[3], "123")); +// +// std::vector<std::string> v3; +// BOOST_TEST(test_attr("ab1cd123", *(alpha >> alpha | +digit), v3) && +// v3.size() == 4 && +// v3[0] == "ab" && +// v3[1] == "1" && +// v3[2] == "cd" && +// v3[3] == "123"); +// } + + return boost::report_errors(); +} + diff --git a/src/boost/libs/spirit/test/qi/pass_container3.cpp b/src/boost/libs/spirit/test/qi/pass_container3.cpp new file mode 100644 index 00000000..a501de06 --- /dev/null +++ b/src/boost/libs/spirit/test/qi/pass_container3.cpp @@ -0,0 +1,65 @@ +// 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) + +// compilation test only + +#include <boost/config/warning_disable.hpp> +#include <boost/detail/lightweight_test.hpp> + +#include <string> +#include <vector> + +#include <boost/spirit/include/qi.hpp> +#include <boost/fusion/include/adapt_struct.hpp> + +#include <boost/variant.hpp> + +#include "test.hpp" + +using namespace spirit_test; + +////////////////////////////////////////////////////////////////////////////// +struct ast; // Forward declaration + +typedef boost::variant< + double, char, int, std::string, boost::recursive_wrapper<ast> +> ast_element; + +struct ast +{ + int op; + std::vector<ast_element> children; + ast() {} +}; + +BOOST_FUSION_ADAPT_STRUCT( + ast, + (int, op) + (std::vector<ast_element>, children) +) + +/////////////////////////////////////////////////////////////////////////////// +int main() +{ + namespace qi = boost::spirit::qi; + + { + qi::rule<char const*, ast()> num_expr; + num_expr = (*(qi::char_ >> num_expr))[ qi::_1 ]; + } + +// doesn't currently work +// { +// qi::rule<char const*, std::string()> str = "abc"; +// qi::rule<char const*, std::string()> r = +// '"' >> *('\\' >> qi::char_ | str) >> "'"; +// +// std::string s; +// BOOST_TEST(test_attr("\"abc\\a\"", r, s) && s == "abca"); +// } + + return boost::report_errors(); +} + diff --git a/src/boost/libs/spirit/test/qi/pch.hpp b/src/boost/libs/spirit/test/qi/pch.hpp new file mode 100644 index 00000000..44e5cb18 --- /dev/null +++ b/src/boost/libs/spirit/test/qi/pch.hpp @@ -0,0 +1,23 @@ +/*============================================================================= + Copyright (c) 2019 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) +=============================================================================*/ +#ifdef BOOST_BUILD_PCH_ENABLED + +#include <boost/spirit/include/qi.hpp> +#include <boost/spirit/include/support_argument.hpp> +#include <boost/spirit/include/phoenix_core.hpp> +#include <boost/spirit/include/phoenix_operator.hpp> +#include <boost/core/lightweight_test.hpp> +#include <boost/optional.hpp> +#include <boost/variant.hpp> +#include <map> +#include <set> +#include <vector> +#include <string> +#include <sstream> +#include <iostream> + +#endif diff --git a/src/boost/libs/spirit/test/qi/permutation.cpp b/src/boost/libs/spirit/test/qi/permutation.cpp new file mode 100644 index 00000000..d29174e3 --- /dev/null +++ b/src/boost/libs/spirit/test/qi/permutation.cpp @@ -0,0 +1,129 @@ +/*============================================================================= + Copyright (c) 2001-2010 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/include/qi_operator.hpp> +#include <boost/spirit/include/qi_char.hpp> +#include <boost/spirit/include/qi_string.hpp> +#include <boost/spirit/include/qi_numeric.hpp> +#include <boost/spirit/include/qi_action.hpp> +#include <boost/spirit/include/qi_nonterminal.hpp> +#include <boost/spirit/include/support_argument.hpp> +#include <boost/fusion/include/vector.hpp> +#include <boost/fusion/include/at.hpp> +#include <boost/spirit/include/phoenix_core.hpp> +#include <boost/spirit/include/phoenix_operator.hpp> +#include <boost/optional.hpp> + +#include <string> +#include <iostream> +#include "test.hpp" + +using namespace spirit_test; + +int +main() +{ + using boost::spirit::qi::int_; + using boost::spirit::qi::_1; + using boost::spirit::qi::_2; + using boost::spirit::qi::rule; + using boost::spirit::ascii::alpha; + using boost::spirit::ascii::char_; + + using boost::fusion::vector; + using boost::fusion::at_c; + using boost::optional; + + { + BOOST_TEST((test("a", char_('a') ^ char_('b') ^ char_('c')))); + BOOST_TEST((test("b", char_('a') ^ char_('b') ^ char_('c')))); + BOOST_TEST((test("ab", char_('a') ^ char_('b') ^ char_('c')))); + BOOST_TEST((test("ba", char_('a') ^ char_('b') ^ char_('c')))); + BOOST_TEST((test("abc", char_('a') ^ char_('b') ^ char_('c')))); + BOOST_TEST((test("acb", char_('a') ^ char_('b') ^ char_('c')))); + BOOST_TEST((test("bca", char_('a') ^ char_('b') ^ char_('c')))); + BOOST_TEST((test("bac", char_('a') ^ char_('b') ^ char_('c')))); + BOOST_TEST((test("cab", char_('a') ^ char_('b') ^ char_('c')))); + BOOST_TEST((test("cba", char_('a') ^ char_('b') ^ char_('c')))); + + BOOST_TEST((!test("cca", char_('a') ^ char_('b') ^ char_('c')))); + } + + { // test optional must stay uninitialized + optional<int> i; + BOOST_TEST((test_attr("", -int_ ^ int_, i))); + BOOST_TEST(!i); + } + + { + vector<optional<int>, optional<char> > attr; + + BOOST_TEST((test_attr("a", int_ ^ alpha, attr))); + BOOST_TEST((!at_c<0>(attr))); + BOOST_TEST((at_c<1>(attr).get() == 'a')); + + at_c<1>(attr) = optional<char>(); // clear the optional + BOOST_TEST((test_attr("123", int_ ^ alpha, attr))); + BOOST_TEST((at_c<0>(attr).get() == 123)); + BOOST_TEST((!at_c<1>(attr))); + + at_c<0>(attr) = optional<int>(); // clear the optional + BOOST_TEST((test_attr("123a", int_ ^ alpha, attr))); + BOOST_TEST((at_c<0>(attr).get() == 123)); + BOOST_TEST((at_c<1>(attr).get() == 'a')); + + at_c<0>(attr) = optional<int>(); // clear the optional + at_c<1>(attr) = optional<char>(); // clear the optional + BOOST_TEST((test_attr("a123", int_ ^ alpha, attr))); + BOOST_TEST((at_c<0>(attr).get() == 123)); + BOOST_TEST((at_c<1>(attr).get() == 'a')); + } + + { // test action + using namespace boost::phoenix; + namespace phx = boost::phoenix; + + optional<int> i; + optional<char> c; + + BOOST_TEST((test("123a", (int_ ^ alpha)[phx::ref(i) = _1, phx::ref(c) = _2]))); + BOOST_TEST((i.get() == 123)); + BOOST_TEST((c.get() == 'a')); + } + + { // test rule %= + + typedef vector<optional<int>, optional<char> > attr_type; + attr_type attr; + + rule<char const*, attr_type()> r; + r %= int_ ^ alpha; + + BOOST_TEST((test_attr("a", r, attr))); + BOOST_TEST((!at_c<0>(attr))); + BOOST_TEST((at_c<1>(attr).get() == 'a')); + + at_c<1>(attr) = optional<char>(); // clear the optional + BOOST_TEST((test_attr("123", r, attr))); + BOOST_TEST((at_c<0>(attr).get() == 123)); + BOOST_TEST((!at_c<1>(attr))); + + at_c<0>(attr) = optional<int>(); // clear the optional + BOOST_TEST((test_attr("123a", r, attr))); + BOOST_TEST((at_c<0>(attr).get() == 123)); + BOOST_TEST((at_c<1>(attr).get() == 'a')); + + at_c<0>(attr) = optional<int>(); // clear the optional + at_c<1>(attr) = optional<char>(); // clear the optional + BOOST_TEST((test_attr("a123", r, attr))); + BOOST_TEST((at_c<0>(attr).get() == 123)); + BOOST_TEST((at_c<1>(attr).get() == 'a')); + } + + return boost::report_errors(); +} + diff --git a/src/boost/libs/spirit/test/qi/plus.cpp b/src/boost/libs/spirit/test/qi/plus.cpp new file mode 100644 index 00000000..3207d8c3 --- /dev/null +++ b/src/boost/libs/spirit/test/qi/plus.cpp @@ -0,0 +1,130 @@ +/*============================================================================= + Copyright (c) 2001-2010 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/include/qi_operator.hpp> +#include <boost/spirit/include/qi_char.hpp> +#include <boost/spirit/include/qi_string.hpp> +#include <boost/spirit/include/qi_numeric.hpp> +#include <boost/spirit/include/qi_directive.hpp> +#include <boost/spirit/include/qi_action.hpp> +#include <boost/spirit/include/support_argument.hpp> +#include <boost/spirit/include/phoenix_core.hpp> +#include <boost/spirit/include/phoenix_operator.hpp> + +#include <string> +#include <iostream> +#include "test.hpp" + +struct x_attr +{ +}; + +namespace boost { namespace spirit { namespace traits +{ + template <> + struct container_value<x_attr> + { + typedef char type; // value type of container + }; + + template <> + struct push_back_container<x_attr, char> + { + 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 namespace boost::spirit::ascii; + using boost::spirit::qi::int_; + using boost::spirit::qi::omit; + using boost::spirit::qi::lit; + using boost::spirit::qi::_1; + using boost::spirit::qi::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)); + } + + { + // 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 + namespace phx = boost::phoenix; + + std::vector<char> v; + BOOST_TEST(test("bbbb", (+char_)[phx::ref(v) = _1]) && 4 == v.size() && + v[0] == 'b' && v[1] == 'b' && v[2] == 'b' && v[3] == 'b'); + } + + { // more actions + namespace phx = boost::phoenix; + + std::vector<int> v; + BOOST_TEST(test("1 2 3", (+int_)[phx::ref(v) = _1], space) && 3 == v.size() && + v[0] == 1 && v[1] == 2 && v[2] == 3); + } + + { // attribute customization + + x_attr x; + test_attr("abcde", +char_, x); + } + + return boost::report_errors(); +} + diff --git a/src/boost/libs/spirit/test/qi/range_run.cpp b/src/boost/libs/spirit/test/qi/range_run.cpp new file mode 100644 index 00000000..dc90b79c --- /dev/null +++ b/src/boost/libs/spirit/test/qi/range_run.cpp @@ -0,0 +1,200 @@ +/*============================================================================= + 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 <iostream> +#include <cctype> +#include <boost/detail/lightweight_test.hpp> +#include <boost/spirit/home/support/char_set/range_run.hpp> +#include <boost/dynamic_bitset.hpp> +#include <boost/integer_traits.hpp> +#if defined(_MSC_VER) && _MSC_VER < 1700 +# pragma warning(disable: 4127) // conditional expression is constant +#endif +#include <boost/random.hpp> + +#if defined(_MSC_VER) +# pragma warning(disable: 4127) // conditional expression is constant +# pragma warning(disable: 4800) // 'int' : forcing value to bool 'true' or 'false' warning +#endif + +template <typename Char> +void acid_test() +{ + if (sizeof(Char) == sizeof(unsigned)) + return; // don't do this test if we have a Char that's very big. + // the smaller chars will suffice for testing. + + using boost::spirit::support::detail::range_run; + using boost::spirit::support::detail::range; + + typedef boost::integer_traits<Char> integer_traits; + Char const const_min = integer_traits::const_min; + Char const const_max = integer_traits::const_max; + unsigned bit_set_size = unsigned(const_max)-unsigned(const_min)+1; + int const test_size = 1000; + + boost::mt19937 rng; + Char min = const_min; + Char max = const_max; + boost::uniform_int<Char> char_(min, max); + boost::variate_generator<boost::mt19937&, boost::uniform_int<Char> > + gen(rng, char_); + boost::uniform_int<Char> _1of10(1, 10); + boost::variate_generator<boost::mt19937&, boost::uniform_int<Char> > + on_or_off(rng, _1of10); + + range_run<Char> rr; + boost::dynamic_bitset<unsigned> bset(bit_set_size); + + for (int i = 0; i < test_size; ++i) + { + range<Char> r = range<Char>(gen(), gen()); + if (r.first > r.last) + std::swap(r.first, r.last); + + bool set = on_or_off() != 1; + if (set) + rr.set(r); + else + rr.clear(r); + for (int j = r.first; j <= int(r.last); ++j) + bset[j-const_min] = set; + } + + for (int i = const_min; i <= int(const_max); ++i) + { + BOOST_TEST(rr.test(static_cast<Char>(i)) == bset[i-const_min]); + } +} + +int +main() +{ + using boost::spirit::support::detail::range_run; + using boost::spirit::support::detail::range; + + { + range_run<char> rr; + rr.set(range<char>('a', 'a')); + for (char c = 0; c < 127; ++c) + { + BOOST_TEST((c == 'a') == rr.test(c)); + } + } + { + range_run<char> rr; + rr.set(range<char>('a', 'z')); + rr.set(range<char>('A', 'Z')); + rr.clear(range<char>('A', 'Z')); + for (char c = 0; c < 127; ++c) + { + BOOST_TEST(bool(std::islower(c)) == rr.test(c)); + } + } + { + range_run<char> rr; + rr.set(range<char>(0, 0)); + for (char c = 0; c < 127; ++c) + { + BOOST_TEST((c == 0) == rr.test(c)); + } + rr.set(range<char>(0, 50)); + for (char c = 0; c < 127; ++c) + { + BOOST_TEST(((c >= 0) && (c <= 50)) == rr.test(c)); + } + } + { + range_run<unsigned char> rr; + rr.set(range<unsigned char>(255, 255)); + for (unsigned char c = 0; c < 255; ++c) + { + BOOST_TEST((c == 255) == rr.test(c)); + } + rr.set(range<unsigned char>(250, 255)); + for (unsigned char c = 0; c < 255; ++c) + { + BOOST_TEST((c >= 250) == rr.test(c)); + } + } + { + range_run<char> rr; + rr.set(range<char>('a', 'z')); + rr.set(range<char>('A', 'Z')); + for (char c = 0; c < 127; ++c) + { + BOOST_TEST(bool(std::isalpha(c)) == rr.test(c)); + } + } + { + range_run<char> rr; + rr.set(range<char>('a', 'z')); + rr.set(range<char>('A', 'Z')); + rr.clear(range<char>('J', 'j')); + for (char c = 0; c < 127; ++c) + { + BOOST_TEST((bool(std::isalpha(c)) && (c < 'J' || c > 'j')) == rr.test(c)); + } + } + { + range_run<char> rr; + rr.set(range<char>(3, 3)); + rr.set(range<char>(1, 5)); + BOOST_TEST(rr.test(5)); + } + { + range_run<char> rr; + for (char c = 0; c < 127; ++c) + { + if (c & 1) + { + rr.set(range<char>(c, c)); + } + } + for (char c = 0; c < 127; ++c) + { + BOOST_TEST(bool((c & 1)) == rr.test(c)); + } + rr.clear(range<char>(90, 105)); + for (char c = 0; c < 127; ++c) + { + BOOST_TEST((bool((c & 1)) && (c < 90 || c > 105)) == rr.test(c)); + } + } + { + range_run<char> rr; + rr.set(range<char>('c', 'e')); + rr.set(range<char>('g', 'i')); + rr.set(range<char>('d', 'k')); + for (char c = 'a'; c <= 'm'; ++c) + { + BOOST_TEST((c >= 'c' && c <= 'k') == rr.test(c)); + } + } + { + typedef boost::integer_traits<char> traits; + char const const_min = traits::const_min; + range_run<char> rr; + rr.set(range<char>(const_min, const_min+16)); + rr.clear(range<char>(const_min, const_min+8)); + BOOST_TEST(!rr.test(const_min)); + BOOST_TEST(!rr.test(const_min+8)); + BOOST_TEST(rr.test(const_min+9)); + BOOST_TEST(rr.test(const_min+16)); + BOOST_TEST(!rr.test(const_min+17)); + } + { + acid_test<char>(); + acid_test<signed char>(); + acid_test<unsigned char>(); + acid_test<wchar_t>(); + acid_test<short>(); + acid_test<signed short>(); + acid_test<unsigned short>(); + } + + return boost::report_errors(); +} diff --git a/src/boost/libs/spirit/test/qi/raw.cpp b/src/boost/libs/spirit/test/qi/raw.cpp new file mode 100644 index 00000000..2ccb2a54 --- /dev/null +++ b/src/boost/libs/spirit/test/qi/raw.cpp @@ -0,0 +1,49 @@ +/*============================================================================= + Copyright (c) 2001-2010 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/include/qi_directive.hpp> +#include <boost/spirit/include/qi_char.hpp> +#include <boost/spirit/include/qi_operator.hpp> +#include <boost/spirit/include/qi_auxiliary.hpp> + +#include <iostream> +#include <string> +#include "test.hpp" + +int +main() +{ + using spirit_test::test; + using spirit_test::test_attr; + using namespace boost::spirit::ascii; + using boost::spirit::qi::raw; + using boost::spirit::qi::eps; + + { + 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_TEST((test_attr("x", raw[alpha] >> eps, range))); + } + + return boost::report_errors(); +} diff --git a/src/boost/libs/spirit/test/qi/real.hpp b/src/boost/libs/spirit/test/qi/real.hpp new file mode 100644 index 00000000..462e83a1 --- /dev/null +++ b/src/boost/libs/spirit/test/qi/real.hpp @@ -0,0 +1,125 @@ +/*============================================================================= + 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_QI_REAL_HPP) +#define BOOST_SPIRIT_TEST_QI_REAL_HPP + +#include <climits> +#include <boost/math/concepts/real_concept.hpp> +#include <boost/detail/lightweight_test.hpp> +#include <boost/spirit/include/qi_char.hpp> +#include <boost/spirit/include/qi_numeric.hpp> +#include <boost/spirit/include/qi_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::qi::ureal_policies<T> +{ + // 2 decimal places Max + template <typename Iterator, typename Attribute> + static bool + parse_frac_n(Iterator& first, Iterator const& last, Attribute& attr, int& frac_digits) + { + namespace qi = boost::spirit::qi; + Iterator savef = first; + bool r = qi::extract_uint<Attribute, 10, 1, 2, true>::call(first, last, attr); + frac_digits = static_cast<int>(std::distance(savef, first)); + return r; + } + + // 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::qi::uint_parser; + namespace qi = boost::spirit::qi; + + 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 (qi::parse(iter, last, ',') && qi::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::qi::real_policies<T> +{ + static bool const allow_trailing_dot = false; +}; + +template <typename T> +struct no_leading_dot_policy : boost::spirit::qi::real_policies<T> +{ + static bool const allow_leading_dot = false; +}; + +template <typename T> +bool +compare(T n, double 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/qi/real1.cpp b/src/boost/libs/spirit/test/qi/real1.cpp new file mode 100644 index 00000000..f2282b35 --- /dev/null +++ b/src/boost/libs/spirit/test/qi/real1.cpp @@ -0,0 +1,122 @@ +/*============================================================================= + Copyright (c) 2001-2011 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::qi::uint_parser; + using boost::spirit::qi::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::qi::real_parser; + using boost::spirit::qi::parse; + using boost::spirit::qi::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)); + + BOOST_TEST(test("4em", udouble, false)); + BOOST_TEST(test_attr("4em", udouble, d, false) && compare(d, 4.0)); + } + + return boost::report_errors(); +} diff --git a/src/boost/libs/spirit/test/qi/real2.cpp b/src/boost/libs/spirit/test/qi/real2.cpp new file mode 100644 index 00000000..e30226b2 --- /dev/null +++ b/src/boost/libs/spirit/test/qi/real2.cpp @@ -0,0 +1,171 @@ +/*============================================================================= + Copyright (c) 2001-2011 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; + /////////////////////////////////////////////////////////////////////////// + // signed real number tests + /////////////////////////////////////////////////////////////////////////// + { + using boost::spirit::qi::double_; + using boost::spirit::qi::float_; + using boost::spirit::qi::parse; + double d; + float f; + + BOOST_TEST(test("-1234", double_)); + BOOST_TEST(test_attr("-1234", double_, d) && compare(d, -1234)); + + BOOST_TEST(test("-1.2e3", double_)); + BOOST_TEST(test_attr("-1.2e3", double_, d) && compare(d, -1.2e3)); + + BOOST_TEST(test("+1.2e3", double_)); + BOOST_TEST(test_attr("+1.2e3", double_, d) && compare(d, 1.2e3)); + + BOOST_TEST(test("-0.1", double_)); + BOOST_TEST(test_attr("-0.1", double_, d) && compare(d, -0.1)); + + BOOST_TEST(test("-1.2e-3", double_)); + BOOST_TEST(test_attr("-1.2e-3", double_, d) && compare(d, -1.2e-3)); + + BOOST_TEST(test("-1.e2", double_)); + BOOST_TEST(test_attr("-1.e2", double_, d) && compare(d, -1.e2)); + + BOOST_TEST(test("-.2e3", double_)); + BOOST_TEST(test_attr("-.2e3", double_, d) && compare(d, -.2e3)); + + BOOST_TEST(test("-2e3", double_)); + BOOST_TEST(test_attr("-2e3", double_, d) && compare(d, -2e3)); + + BOOST_TEST(!test("-e3", double_)); + BOOST_TEST(!test_attr("-e3", double_, d)); + + BOOST_TEST(!test("-1.2e", double_)); + BOOST_TEST(!test_attr("-1.2e", double_, d)); + + 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! + + BOOST_TEST(test_attr("1.7976931348623157e+308", double_, d)); // DBL_MAX + BOOST_TEST(d == 1.7976931348623157e+308); // exact! + + BOOST_TEST(test_attr("2.2204460492503131e-16", double_, d)); // DBL_EPSILON + BOOST_TEST(d == 2.2204460492503131e-16); // exact! + + BOOST_TEST(test_attr("2.2250738585072014e-308", double_, d)); // DBL_MIN + BOOST_TEST(d == 2.2250738585072014e-308); // exact! + + BOOST_TEST(test_attr("4.9406564584124654e-324", double_, d)); // DBL_DENORM_MIN + BOOST_TEST(d == 4.9406564584124654e-324); // exact! + + BOOST_TEST(test_attr("219721.03839999999", double_, d)); + BOOST_TEST(d == 219721.03839999999); // exact! + + BOOST_TEST(test_attr("-5.7222349715140557e+307", double_, d)); + BOOST_TEST(d == -5.7222349715140557e+307); // exact! + + BOOST_TEST(test_attr("2.2204460492503131e-16", double_, d)); + BOOST_TEST(d == 2.2204460492503131e-16); // exact! + + // floats... + + BOOST_TEST(test_attr("3.402823466e+38", float_, f)); // FLT_MAX + BOOST_TEST(f == 3.402823466e+38F); // exact! + + BOOST_TEST(test_attr("1.192092896e-07", float_, f)); // FLT_EPSILON + BOOST_TEST(f == 1.192092896e-07F); // exact! + + BOOST_TEST(test_attr("1.175494351e-38", float_, f)); // FLT_MIN + BOOST_TEST(f == 1.175494351e-38F); // exact! + + BOOST_TEST(test_attr("219721.03839999999", float_, f)); + BOOST_TEST(f == 219721.03839999999f); // inexact + + BOOST_TEST(test_attr("2.2204460492503131e-16", float_, f)); + BOOST_TEST(f == 2.2204460492503131e-16f); // inexact + + // big exponents! + // fail, but do not assert! + BOOST_TEST(!test_attr("123e1234000000", double_, d)); + BOOST_TEST(!test_attr("123e-1234000000", double_, d)); + + using boost::math::fpclassify; + using boost::spirit::detail::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.2676506002282294e+30)); + + BOOST_TEST(test_attr("12676506.00228229401496703205376", double_, d) && + compare(d, 12676506.00228229, 0.00000001)); + + BOOST_TEST(test_attr("12676506.00228229401496703205376E6", double_, d) && + compare(d, 12676506002282.29, 0.01)); + + char const* long_number = "17976931348623157081452742373170435679807056" + "7525844996598917476803157260780028538760589558632766878171540458953" + "5143824642343213268894641827684675467035375169860499105765512820762" + "4549009038932894407586850845513394230458323690322294816580855933212" + "3348274797826204144723168738177180919299881250404026184124858368.00" + "00000000000000"; + + BOOST_TEST(test_attr(long_number, double_, d) && + compare(d, 1.7976931348623157e+308)); + } + + return boost::report_errors(); +} diff --git a/src/boost/libs/spirit/test/qi/real3.cpp b/src/boost/libs/spirit/test/qi/real3.cpp new file mode 100644 index 00000000..610e2814 --- /dev/null +++ b/src/boost/libs/spirit/test/qi/real3.cpp @@ -0,0 +1,85 @@ +/*============================================================================= + 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) +=============================================================================*/ + +#include "real.hpp" + +int +main() +{ + using spirit_test::test; + using spirit_test::test_attr; + + /////////////////////////////////////////////////////////////////////////// + // strict real number tests + /////////////////////////////////////////////////////////////////////////// + { + using boost::spirit::qi::real_parser; + using boost::spirit::qi::parse; + using boost::spirit::qi::strict_ureal_policies; + using boost::spirit::qi::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::qi::real_parser; + using boost::spirit::qi::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/qi/real4.cpp b/src/boost/libs/spirit/test/qi/real4.cpp new file mode 100644 index 00000000..45d1ca7e --- /dev/null +++ b/src/boost/libs/spirit/test/qi/real4.cpp @@ -0,0 +1,73 @@ +/*============================================================================= + Copyright (c) 2001-2011 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::qi::real_parser; + using boost::spirit::qi::real_policies; + using boost::spirit::qi::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::qi::double_; + custom_real n; + + BOOST_TEST(test_attr("-123456e6", double_, n)); + } + + return boost::report_errors(); +} diff --git a/src/boost/libs/spirit/test/qi/real5.cpp b/src/boost/libs/spirit/test/qi/real5.cpp new file mode 100644 index 00000000..3749c4c6 --- /dev/null +++ b/src/boost/libs/spirit/test/qi/real5.cpp @@ -0,0 +1,137 @@ +/*============================================================================= + Copyright (c) 2001-2011 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; + + /////////////////////////////////////////////////////////////////////////// + // parameterized signed real number tests + /////////////////////////////////////////////////////////////////////////// + { + using boost::spirit::qi::double_; + double d; + + BOOST_TEST(test("+1234", double_(1234))); + BOOST_TEST(!test("+1234", double_(-1234))); + BOOST_TEST(test_attr("+1234", double_(1234), d)); + BOOST_TEST(compare(d, 1234)); + BOOST_TEST(!test_attr("+1234", double_(-1234), d)); + + BOOST_TEST(test("-1234", double_(-1234))); + BOOST_TEST(!test("-1234", double_(1234))); + BOOST_TEST(test_attr("-1234", double_(-1234), d)); + BOOST_TEST(compare(d, -1234)); + BOOST_TEST(!test_attr("-1234", double_(1234), d)); + + BOOST_TEST(test("+1.2e3", double_(1.2e3))); + BOOST_TEST(!test("+1.2e3", double_(-1.2e3))); + BOOST_TEST(test_attr("+1.2e3", double_(1.2e3), d)); + BOOST_TEST(compare(d, 1.2e3)); + BOOST_TEST(!test_attr("+1.2e3", double_(-1.2e3), d)); + + BOOST_TEST(test("-1.2e3", double_(-1.2e3))); + BOOST_TEST(!test("-1.2e3", double_(1.2e3))); + BOOST_TEST(test_attr("-1.2e3", double_(-1.2e3), d)); + BOOST_TEST(compare(d, -1.2e3)); + BOOST_TEST(!test_attr("-1.2e3", double_(1.2e3), d)); + } + + /////////////////////////////////////////////////////////////////////////// + // parameterized unsigned real number tests + /////////////////////////////////////////////////////////////////////////// + { + using boost::spirit::qi::real_parser; + using boost::spirit::qi::ureal_policies; + double d; + + real_parser<double, ureal_policies<double> > udouble; + + BOOST_TEST(test("1234", udouble(1234))); + BOOST_TEST(!test("1234", udouble(4321))); + BOOST_TEST(test_attr("1234", udouble(1234), d)); + BOOST_TEST(compare(d, 1234)); + BOOST_TEST(!test_attr("1234", udouble(4321), d)); + + BOOST_TEST(test("1.2e3", udouble(1.2e3))); + BOOST_TEST(!test("1.2e3", udouble(3.2e1))); + BOOST_TEST(test_attr("1.2e3", udouble(1.2e3), d)); + BOOST_TEST(compare(d, 1.2e3)); + BOOST_TEST(!test_attr("1.2e3", udouble(3.2e1), d)); + } + + /////////////////////////////////////////////////////////////////////////// + // parameterized custom data type + /////////////////////////////////////////////////////////////////////////// + { + using boost::math::concepts::real_concept; + using boost::spirit::qi::real_parser; + using boost::spirit::qi::real_policies; + + real_parser<real_concept, real_policies<real_concept> > custom_real; + real_concept d; + + BOOST_TEST(test("-1234", custom_real(-1234))); + BOOST_TEST(!test("-1234", custom_real(4321))); + BOOST_TEST(test_attr("-1234", custom_real(-1234), d)); + BOOST_TEST(compare(d, -1234)); + BOOST_TEST(!test_attr("-1234", custom_real(-4321), d)); + + BOOST_TEST(test("1.2e3", custom_real(1.2e3))); + BOOST_TEST(!test("1.2e3", custom_real(-1.2e3))); + BOOST_TEST(test_attr("1.2e3", custom_real(1.2e3), d)); + BOOST_TEST(compare(d, 1.2e3)); + BOOST_TEST(!test_attr("1.2e3", custom_real(-3.2e1), d)); + } + + /////////////////////////////////////////////////////////////////////////// + // parameterized lazy tests + /////////////////////////////////////////////////////////////////////////// + { + using boost::phoenix::ref; + using boost::spirit::qi::double_; + double n = 1.2e3, m = 3.2e1; + + BOOST_TEST(test("1.2e3", double_(ref(n)))); + BOOST_TEST(!test("1.2e3", double_(ref(m)))); + } + + /////////////////////////////////////////////////////////////////////////// + // literal real number tests + /////////////////////////////////////////////////////////////////////////// + { + using boost::spirit::qi::lit; + + BOOST_TEST(test("+1.2e3", lit(1.2e3))); + BOOST_TEST(!test("+1.2e3", lit(-1.2e3))); + BOOST_TEST(test("-1.2e3", lit(-1.2e3))); + BOOST_TEST(!test("-1.2e3", lit(1.2e3))); + BOOST_TEST(test("1.2e3", lit(1.2e3))); + BOOST_TEST(!test("1.2e3", lit(3.2e1))); + } + + /////////////////////////////////////////////////////////////////////////// + // literal lazy tests + /////////////////////////////////////////////////////////////////////////// + { + using boost::spirit::qi::lit; + using boost::phoenix::ref; + double n = 1.2e3, m = 3.2e1; + + BOOST_TEST(test("1.2e3", lit(ref(n)))); + BOOST_TEST(!test("1.2e3", lit(ref(m)))); + } + + return boost::report_errors(); +} diff --git a/src/boost/libs/spirit/test/qi/regression_adapt_adt.cpp b/src/boost/libs/spirit/test/qi/regression_adapt_adt.cpp new file mode 100644 index 00000000..4727853c --- /dev/null +++ b/src/boost/libs/spirit/test/qi/regression_adapt_adt.cpp @@ -0,0 +1,103 @@ +// Copyright (c) 2011 Roji Philip +// 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/config/warning_disable.hpp> +#include <boost/detail/lightweight_test.hpp> + +#include <boost/fusion/include/adapt_adt.hpp> +#include <boost/optional.hpp> + +#include <boost/spirit/include/qi.hpp> +#include <boost/spirit/include/support_adapt_adt_attributes.hpp> + +#include "test.hpp" + +/////////////////////////////////////////////////////////////////////////////// +struct test1 +{ + unsigned var; + boost::optional<unsigned> opt; + + unsigned& getvar() { return var; } + unsigned const& getvar() const { return var; } + void setvar(unsigned val) { var = val; } + + boost::optional<unsigned>& getopt() { return opt; } + boost::optional<unsigned> const& getopt() const { return opt; } + void setopt(boost::optional<unsigned> const& val) { opt = val; } +}; + +BOOST_FUSION_ADAPT_ADT( + test1, + (unsigned&, unsigned const&, obj.getvar(), obj.setvar(val)) + (boost::optional<unsigned>&, boost::optional<unsigned> const&, + obj.getopt(), obj.setopt(val)) +) + +/////////////////////////////////////////////////////////////////////////////// +struct test2 +{ + std::string str; + boost::optional<std::string> optstr; + + std::string& getstring() { return str; } + std::string const& getstring() const { return str; } + void setstring(std::string const& val) { str = val; } + + boost::optional<std::string>& getoptstring() { return optstr; } + boost::optional<std::string> const& getoptstring() const { return optstr; } + void setoptstring(boost::optional<std::string> const& val) { optstr = val; } +}; + +BOOST_FUSION_ADAPT_ADT( + test2, + (std::string&, std::string const&, obj.getstring(), obj.setstring(val)) + (boost::optional<std::string>&, boost::optional<std::string> const&, + obj.getoptstring(), obj.setoptstring(val)) +) + +/////////////////////////////////////////////////////////////////////////////// +int main() +{ + using spirit_test::test_attr; + namespace qi = boost::spirit::qi; + + { + test1 data; + BOOST_TEST(test_attr("123@999", qi::uint_ >> -('@' >> qi::uint_), data) && + data.var == 123 && data.opt && data.opt.get() == 999); + } + + { + test1 data; + BOOST_TEST(test_attr("123", qi::uint_ >> -('@' >> qi::uint_), data) && + data.var == 123 && !data.opt); + } + + { + test2 data; + BOOST_TEST(test_attr("Hello:OptionalHello", + +qi::alnum >> -(':' >> +qi::alnum), data) && + data.str == "Hello" && + data.optstr && data.optstr.get() == "OptionalHello"); + } + + { + test2 data; + BOOST_TEST(test_attr("Hello", + +qi::alnum >> -(':' >> +qi::alnum), data) && + data.str == "Hello" && !data.optstr); + } + + { // GH#396 + qi::rule<char const*, unsigned()> uint_r = qi::uint_; + test1 data; + BOOST_TEST(test_attr("123@999", uint_r >> -('@' >> uint_r), data) && + data.var == 123 && data.opt && data.opt.get() == 999); + } + + return boost::report_errors(); +} diff --git a/src/boost/libs/spirit/test/qi/regression_attr_with_action.cpp b/src/boost/libs/spirit/test/qi/regression_attr_with_action.cpp new file mode 100644 index 00000000..3ba922f0 --- /dev/null +++ b/src/boost/libs/spirit/test/qi/regression_attr_with_action.cpp @@ -0,0 +1,27 @@ +// Copyright (c) 2010 Daniel James +// 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) + +// this is a compile only regression test + +#include <boost/config/warning_disable.hpp> +#include <boost/spirit/include/qi.hpp> + +namespace qi = boost::spirit::qi; + +struct source_mode {}; + +struct process_type +{ + template <typename A, typename B, typename C> + void operator()(A&, B&, C&) const {} +}; + +int main() +{ + process_type process; + qi::rule<char const*> x = qi::attr(source_mode()) [process]; + return 0; +} diff --git a/src/boost/libs/spirit/test/qi/regression_binary_action.cpp b/src/boost/libs/spirit/test/qi/regression_binary_action.cpp new file mode 100644 index 00000000..b418e8be --- /dev/null +++ b/src/boost/libs/spirit/test/qi/regression_binary_action.cpp @@ -0,0 +1,55 @@ +/*============================================================================= + Copyright (c) 2001-2011 Hartmut Kaiser + Copyright (c) 2011 Matthias Born + + 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/include/qi_operator.hpp> +#include <boost/spirit/include/qi_char.hpp> +#include <boost/spirit/include/qi_attr.hpp> +#include <boost/spirit/include/qi_binary.hpp> +#include <boost/spirit/include/qi_omit.hpp> +#include <boost/spirit/include/qi_nonterminal.hpp> +#include <boost/spirit/include/qi_action.hpp> +#include <boost/spirit/include/phoenix_core.hpp> +#include <boost/spirit/include/phoenix_operator.hpp> +#include <boost/fusion/include/adapt_struct.hpp> +#include <boost/predef/other/endian.h> +#include "test.hpp" + +int main() +{ +// This test assumes a little endian architecture +#if BOOST_ENDIAN_LITTLE_BYTE + using spirit_test::test_attr; + using boost::spirit::qi::rule; + using boost::spirit::qi::locals; + using boost::spirit::qi::little_word; + using boost::spirit::qi::omit; + using boost::spirit::qi::_1; + using boost::spirit::qi::_a; + using boost::spirit::qi::attr; + + rule<char const*, short int(), locals<short int> > pass; + pass = little_word; + + rule<char const*, short int(), locals<short int> > pass_ugly; + pass_ugly %= omit[little_word[_a=_1]] >> attr(_a); + + rule<char const*, short int(), locals<short int> > fail; + fail %= little_word[_a=_1]; + + short int us = 0; + BOOST_TEST(test_attr("\x01\x02", pass, us) && us == 0x0201); + + us = 0; + BOOST_TEST(test_attr("\x01\x02", pass_ugly, us) && us == 0x0201); + + us = 0; + BOOST_TEST(test_attr("\x01\x02", fail, us) && us == 0x0201); +#endif + return boost::report_errors(); +} diff --git a/src/boost/libs/spirit/test/qi/regression_clear.cpp b/src/boost/libs/spirit/test/qi/regression_clear.cpp new file mode 100644 index 00000000..3c7fe77d --- /dev/null +++ b/src/boost/libs/spirit/test/qi/regression_clear.cpp @@ -0,0 +1,38 @@ +// Copyright (c) 2010 Daniel James +// 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/config/warning_disable.hpp> +#include <boost/detail/lightweight_test.hpp> + +#include <boost/spirit/include/qi.hpp> +#include <vector> + +int main() +{ + typedef char const* Iterator; + namespace qi = boost::spirit::qi; + + qi::rule<Iterator, std::vector<boost::iterator_range<Iterator> >()> list; + list = *qi::raw[qi::char_]; // This fails to compile + + char const* test = "abcdef"; + unsigned test_length = 6; + char const* test_begin = test; + char const* test_end = test + test_length; + std::vector<boost::iterator_range<Iterator> > result; + bool r = qi::parse(test_begin, test_end, list, result); + + BOOST_TEST(r); + BOOST_TEST(test_begin == test_end); + BOOST_TEST(result.size() == test_length); + + for(unsigned i = 0; i < test_length; ++i) { + BOOST_TEST(result[i].begin() == test + i); + BOOST_TEST(result[i].end() == test + i + 1); + } + + return boost::report_errors(); +} diff --git a/src/boost/libs/spirit/test/qi/regression_container_attribute.cpp b/src/boost/libs/spirit/test/qi/regression_container_attribute.cpp new file mode 100644 index 00000000..52545335 --- /dev/null +++ b/src/boost/libs/spirit/test/qi/regression_container_attribute.cpp @@ -0,0 +1,23 @@ +// Copyright (c) 2001-2011 Hartmut Kaiser +// Copyright (c) 2011 Joerg Becker +// +// 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) + +// compile test only + +#include <boost/spirit/include/qi.hpp> +#include <string> + +int main() +{ + namespace qi = boost::spirit::qi; + + qi::rule < std::string::const_iterator, std::string() > const t = + "s" >> qi::attr( std::string() ); + + boost::spirit::qi::symbols< char, std::string > keywords; + keywords.add( "keyword", std::string( "keyword" ) ); + qi::rule < std::string::const_iterator, std::string() > const u = + qi::lexeme[keywords >> !( qi::alnum | '_' )] >> qi::attr( std::string() ); +} diff --git a/src/boost/libs/spirit/test/qi/regression_debug_optional.cpp b/src/boost/libs/spirit/test/qi/regression_debug_optional.cpp new file mode 100644 index 00000000..2694871c --- /dev/null +++ b/src/boost/libs/spirit/test/qi/regression_debug_optional.cpp @@ -0,0 +1,24 @@ +// Copyright (c) 2010 Carl Philipp Reh +// 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) + +// make sure optionals play well with debug output + +#define BOOST_SPIRIT_DEBUG +#include <boost/detail/lightweight_test.hpp> +#include <boost/spirit/include/qi.hpp> +#include <boost/spirit/home/support/attributes.hpp> +#include <boost/optional.hpp> + +int main() +{ + boost::spirit::qi::rule< + char const *, + boost::optional<int>() + > foo; + + BOOST_SPIRIT_DEBUG_NODE(foo); + return boost::report_errors(); +} diff --git a/src/boost/libs/spirit/test/qi/regression_float_fraction.cpp b/src/boost/libs/spirit/test/qi/regression_float_fraction.cpp new file mode 100644 index 00000000..7da588a0 --- /dev/null +++ b/src/boost/libs/spirit/test/qi/regression_float_fraction.cpp @@ -0,0 +1,35 @@ +/*============================================================================= + Copyright (c) 2001-2011 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 <boost/detail/lightweight_test.hpp> +#include <boost/spirit/include/qi_numeric.hpp> + +#include "test.hpp" + +int +main() +{ + using spirit_test::test_attr; + using boost::spirit::qi::float_; + + std::cerr.precision(9); + + float f = 0.0f; + + // this should pass, but currently doesn't because of the way the real + // parser handles the fractional part of a number + BOOST_TEST(test_attr("123233.4124", float_, f)); + BOOST_TEST_EQ(f, 123233.4124f); + BOOST_TEST(test_attr("987654.3219", float_, f)); + BOOST_TEST_EQ(f, 987654.3219f); + + return boost::report_errors(); +} + diff --git a/src/boost/libs/spirit/test/qi/regression_fusion_proto_spirit.cpp b/src/boost/libs/spirit/test/qi/regression_fusion_proto_spirit.cpp new file mode 100644 index 00000000..f64fe46a --- /dev/null +++ b/src/boost/libs/spirit/test/qi/regression_fusion_proto_spirit.cpp @@ -0,0 +1,30 @@ +/*============================================================================= + Copyright (c) 2001-2011 Hartmut Kaiser + Copyright (c) 2011 Robert Nelson + + 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) +=============================================================================*/ + +// These (compilation) tests verify that Proto's operator overloads do not +// trigger the corresponding operator overloads exposed by Fusion. + +#include <boost/fusion/tuple.hpp> +#include <boost/spirit/include/qi_operator.hpp> +#include <boost/spirit/include/qi_eps.hpp> +#include <boost/spirit/include/qi_nonterminal.hpp> +#include <string> + +int main() +{ + namespace qi = boost::spirit::qi; + + static qi::rule<std::string::const_iterator> const a; + static qi::rule<std::string::const_iterator> const b; + qi::rule<std::string::const_iterator> rule = a > b; + + int vars; + qi::rule<std::string::const_iterator, int(const int&)> const r; + qi::rule<std::string::const_iterator, int()> r2 = + r(boost::phoenix::ref(vars)) > qi::eps; +} diff --git a/src/boost/libs/spirit/test/qi/regression_lazy_repeat.cpp b/src/boost/libs/spirit/test/qi/regression_lazy_repeat.cpp new file mode 100644 index 00000000..1aa7b88f --- /dev/null +++ b/src/boost/libs/spirit/test/qi/regression_lazy_repeat.cpp @@ -0,0 +1,36 @@ +/*============================================================================= + 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 <boost/detail/lightweight_test.hpp> +#include <boost/spirit/include/qi_operator.hpp> +#include <boost/spirit/include/qi_char.hpp> +#include <boost/spirit/include/qi_repeat.hpp> +#include <boost/spirit/include/phoenix_core.hpp> + +#include "test.hpp" + +int +main() +{ + using spirit_test::test_attr; + using boost::spirit::qi::repeat; + using boost::spirit::qi::char_; + using boost::phoenix::ref; + + int n = 5; + std::string s = ""; + + // this was broken by the addition of handles_container, due to incorrect + // dispatching of lazy parsers/directives/terminals in pass_container + BOOST_TEST(test_attr("foobar", char_ >> repeat(ref(n))[char_], s)); + + BOOST_TEST_EQ(s, "foobar"); + + return boost::report_errors(); +} + diff --git a/src/boost/libs/spirit/test/qi/regression_numeric_alternatives.cpp b/src/boost/libs/spirit/test/qi/regression_numeric_alternatives.cpp new file mode 100644 index 00000000..8f04911c --- /dev/null +++ b/src/boost/libs/spirit/test/qi/regression_numeric_alternatives.cpp @@ -0,0 +1,76 @@ +// 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 <boost/detail/lightweight_test.hpp> +#include <boost/spirit/include/qi.hpp> + +#include "test.hpp" + +int main() +{ + using spirit_test::test; + using boost::spirit::qi::rule; + using boost::spirit::qi::parse; + using boost::spirit::qi::int_; + using boost::spirit::qi::uint_; + using boost::spirit::qi::short_; + using boost::spirit::qi::ushort_; + using boost::spirit::qi::long_; + using boost::spirit::qi::ulong_; + using boost::spirit::qi::float_; + using boost::spirit::qi::double_; + using boost::spirit::qi::long_double; + using boost::spirit::qi::bool_; + +#ifdef BOOST_HAS_LONG_LONG + using boost::spirit::qi::long_long; + using boost::spirit::qi::ulong_long; +#endif + + BOOST_TEST(test("-123", short_(0) | short_(-123))); + BOOST_TEST(test("-123", short_(-123) | short_(0))); + + BOOST_TEST(test("123", ushort_(0) | ushort_(123))); + BOOST_TEST(test("123", ushort_(123) | ushort_(0))); + + BOOST_TEST(test("-123456", int_(0) | int_(-123456))); + BOOST_TEST(test("-123456", int_(-123456) | int_(0))); + + BOOST_TEST(test("123456", uint_(0) | uint_(123456))); + BOOST_TEST(test("123456", uint_(123456) | uint_(0))); + + BOOST_TEST(test("-123456789", long_(0) | long_(-123456789L))); + BOOST_TEST(test("-123456789", long_(-123456789L) | long_(0))); + + BOOST_TEST(test("123456789", ulong_(0) | ulong_(123456789UL))); + BOOST_TEST(test("123456789", ulong_(123456789UL) | ulong_(0))); + +#ifdef BOOST_HAS_LONG_LONG + BOOST_TEST(test("-1234567890123456789", + long_long(0) | long_long(-1234567890123456789LL))); + BOOST_TEST(test("-1234567890123456789", + long_long(-1234567890123456789LL) | long_long(0))); + + BOOST_TEST(test("1234567890123456789", + ulong_long(0) | ulong_long(1234567890123456789ULL))); + BOOST_TEST(test("1234567890123456789", + ulong_long(1234567890123456789ULL) | ulong_long(0))); +#endif + + BOOST_TEST(test("1.23", float_(0) | float_(1.23f))); + BOOST_TEST(test("1.23", float_(1.23f) | float_(0))); + + BOOST_TEST(test("123.456", double_(0) | double_(123.456))); + BOOST_TEST(test("123.456", double_(123.456) | double_(0))); + + BOOST_TEST(test("123456.789", long_double(0) | long_double(123456.789l))); + BOOST_TEST(test("123456.789", long_double(123456.789l) | long_double(0))); + + BOOST_TEST(test("true", bool_(false) | bool_(true))); + BOOST_TEST(test("true", bool_(true) | bool_(false))); + + return boost::report_errors(); +} + diff --git a/src/boost/libs/spirit/test/qi/regression_one_element_fusion_sequence.cpp b/src/boost/libs/spirit/test/qi/regression_one_element_fusion_sequence.cpp new file mode 100644 index 00000000..65fa980a --- /dev/null +++ b/src/boost/libs/spirit/test/qi/regression_one_element_fusion_sequence.cpp @@ -0,0 +1,32 @@ +// Copyright (c) 2001-2011 Hartmut Kaiser +// Copyright (c) 2010 Daniel James +// +// 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) + +// This compilation test fails if proto expressions are not properly +// distinguished from 'normal' Fusion sequences. + +#include <boost/spirit/include/qi_operator.hpp> +#include <boost/spirit/include/qi_char.hpp> +#include <boost/spirit/include/qi_symbols.hpp> +#include <boost/spirit/include/qi_nonterminal.hpp> +#include <boost/spirit/include/qi_action.hpp> +#include <boost/spirit/include/phoenix_core.hpp> +#include <boost/spirit/include/phoenix_operator.hpp> +#include <string> + +int main() +{ + namespace qi = boost::spirit::qi; + typedef std::string::const_iterator iterator; + + qi::symbols<char, qi::rule<iterator> > phrase_keyword_rules; + qi::rule<iterator, qi::locals<qi::rule<iterator> > > phrase_markup_impl; + + phrase_markup_impl + = (phrase_keyword_rules >> !qi::alnum) [qi::_a = qi::_1] + ; + + return 0; +} diff --git a/src/boost/libs/spirit/test/qi/regression_one_element_sequence_attribute.cpp b/src/boost/libs/spirit/test/qi/regression_one_element_sequence_attribute.cpp new file mode 100644 index 00000000..5728ad1a --- /dev/null +++ b/src/boost/libs/spirit/test/qi/regression_one_element_sequence_attribute.cpp @@ -0,0 +1,40 @@ +// Copyright (c) 2010 Josh Wilson +// 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/config/warning_disable.hpp> +#include <boost/spirit/include/qi.hpp> +#include <boost/fusion/include/adapt_struct.hpp> +#include <boost/variant.hpp> +#include <string> + +namespace qi = boost::spirit::qi; + +/////////////////////////////////////////////////////////////////////////////// +struct Number { float base; }; + +BOOST_FUSION_ADAPT_STRUCT( Number, (float, base) ) + +void instantiate1() +{ + qi::symbols<char, Number> sym; + qi::rule<std::string::const_iterator, Number()> rule; + rule %= sym; // Caused compiler error after getting r61322 +} + +/////////////////////////////////////////////////////////////////////////////// +typedef boost::variant<int, float> internal_type; + +struct Number2 { internal_type base; }; + +BOOST_FUSION_ADAPT_STRUCT( Number2, (internal_type, base) ) + +void instantiate2() +{ + qi::symbols<char, Number2> sym; + qi::rule<std::string::const_iterator, Number2()> rule; + rule %= sym; // Caused compiler error after getting r61322 +} + diff --git a/src/boost/libs/spirit/test/qi/regression_reorder.cpp b/src/boost/libs/spirit/test/qi/regression_reorder.cpp new file mode 100644 index 00000000..297e9987 --- /dev/null +++ b/src/boost/libs/spirit/test/qi/regression_reorder.cpp @@ -0,0 +1,83 @@ +// Copyright (c) 2010 Olaf Peter +// 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/include/qi_operator.hpp> +#include <boost/spirit/include/qi_char.hpp> +#include <boost/spirit/include/qi_string.hpp> +#include <boost/spirit/include/qi_numeric.hpp> +#include <boost/spirit/include/qi_directive.hpp> +#include <boost/spirit/include/qi_nonterminal.hpp> +#include <boost/fusion/include/nview.hpp> + +namespace qi = boost::spirit::qi; +namespace ascii = boost::spirit::ascii; +namespace fusion = boost::fusion; +namespace mpl = boost::mpl; + +int main() +{ + using fusion::result_of::as_nview; + using fusion::at_c; + using boost::optional; + using boost::variant; + using ascii::space_type; + using ascii::no_case; + using qi::lit; + using qi::double_; + + typedef fusion::vector< + optional<double>, // 0 - U + optional<double>, // 1 - V + optional<double> // 2 - W + > uvw_type; + + typedef as_nview<uvw_type, 0, 1, 2>::type uvw_reordered_type; + typedef as_nview<uvw_type, 2, 0, 1>::type vwu_reordered_type; + + typedef char const* iterator_type; + + qi::rule<iterator_type, optional<double>(), space_type> u,v,w; + qi::rule<iterator_type, uvw_reordered_type(), space_type> uvw; + qi::rule<iterator_type, vwu_reordered_type(), space_type> vwu; + + u = no_case[ "NA" ] | ( double_ >> -lit( "U" ) ); + v = no_case[ "NA" ] | ( double_ >> -lit( "V" ) ); + w = no_case[ "NA" ] | ( double_ >> -lit( "W" ) ); + + uvw = u > v > w; + vwu = v > w > u; + + uvw_type uvw_data; + { + iterator_type first = "1U 2V 3W"; + iterator_type last = first + std::strlen(first); + + uvw_reordered_type uvw_result( uvw_data ); + + BOOST_TEST(qi::phrase_parse(first, last, uvw, ascii::space, uvw_result)); + BOOST_TEST(fusion::at_c<0>(uvw_result) && *fusion::at_c<0>(uvw_result) == 1); + BOOST_TEST(fusion::at_c<1>(uvw_result) && *fusion::at_c<1>(uvw_result) == 2); + BOOST_TEST(fusion::at_c<2>(uvw_result) && *fusion::at_c<2>(uvw_result) == 3); + } + + { + iterator_type first = "2V 3W 1U"; + iterator_type last = first + std::strlen(first); + + vwu_reordered_type uvw_result(uvw_data); + + BOOST_TEST(qi::phrase_parse(first, last, vwu, ascii::space, uvw_result)); + BOOST_TEST(fusion::at_c<0>(uvw_result) && *fusion::at_c<0>(uvw_result) == 2); + BOOST_TEST(fusion::at_c<1>(uvw_result) && *fusion::at_c<1>(uvw_result) == 3); + BOOST_TEST(fusion::at_c<2>(uvw_result) && *fusion::at_c<2>(uvw_result) == 1); + } + + return boost::report_errors(); +} + + diff --git a/src/boost/libs/spirit/test/qi/regression_repeat.cpp b/src/boost/libs/spirit/test/qi/regression_repeat.cpp new file mode 100644 index 00000000..8db616b9 --- /dev/null +++ b/src/boost/libs/spirit/test/qi/regression_repeat.cpp @@ -0,0 +1,44 @@ +// Copyright (c) 2001-2010 Hartmut Kaiser +// Copyright (c) 2010 Head Geek +// +// 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 <iostream> +#include <boost/detail/lightweight_test.hpp> +#include <boost/spirit/include/qi.hpp> + +namespace qi = boost::spirit::qi; +using qi::omit; +using qi::repeat; +using std::cout; +using std::endl; + +typedef qi::rule<std::string::const_iterator, std::string()> strrule_type; + +void test(const std::string input, strrule_type rule, std::string result) +{ + std::string target; + std::string::const_iterator i = input.begin(), ie = input.end(); + + BOOST_TEST(qi::parse(i, ie, rule, target) && target == result); +} + +int main() +{ + strrule_type obsolete_year = + omit[-qi::char_(" \t")] >> + repeat(2)[qi::digit] >> + omit[-qi::char_(" \t")]; + strrule_type correct_year = repeat(4)[qi::digit]; + + test("1776", qi::hold[correct_year] | repeat(2)[qi::digit], "1776"); + test("76", obsolete_year, "76"); + test("76", qi::hold[obsolete_year] | correct_year, "76"); + test(" 76", qi::hold[correct_year] | obsolete_year, "76"); + test("76", qi::hold[correct_year] | obsolete_year, "76"); + test("76", qi::hold[correct_year] | repeat(2)[qi::digit], "76"); + + return boost::report_errors(); +} + diff --git a/src/boost/libs/spirit/test/qi/regression_stream_eof.cpp b/src/boost/libs/spirit/test/qi/regression_stream_eof.cpp new file mode 100644 index 00000000..394d2fcf --- /dev/null +++ b/src/boost/libs/spirit/test/qi/regression_stream_eof.cpp @@ -0,0 +1,40 @@ +// Copyright (c) 2012 Louis Dionne +// Copyright (c) 2001-2012 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/config/warning_disable.hpp> +#include <boost/detail/lightweight_test.hpp> + +#include <boost/spirit/include/qi.hpp> + +#include <iostream> +#include <string> + +struct MyInt +{ + int i_; + + template <typename Istream> + friend Istream operator>>(Istream& is, MyInt& self) + { + is >> self.i_; + return is; + } +}; + +int main() +{ + using namespace boost::spirit::qi; + typedef std::string::const_iterator Iterator; + + std::string input = "1"; + Iterator first(input.begin()), last(input.end()); + rule<Iterator, int()> my_int = stream_parser<char, MyInt>(); + BOOST_TEST(parse(first, last, my_int)); + BOOST_TEST(first == last); + + return boost::report_errors(); +} + diff --git a/src/boost/libs/spirit/test/qi/regression_transform_assignment.cpp b/src/boost/libs/spirit/test/qi/regression_transform_assignment.cpp new file mode 100644 index 00000000..621ccb1b --- /dev/null +++ b/src/boost/libs/spirit/test/qi/regression_transform_assignment.cpp @@ -0,0 +1,74 @@ +// Copyright (c) 2001-2011 Hartmut Kaiser +// Copyright (c) 2011 Dean Michael Berries +// +// 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/config/warning_disable.hpp> + +#include <boost/spirit/include/qi.hpp> +#include <boost/fusion/tuple.hpp> +#include <string> + +struct foo_parts +{ + boost::optional<std::string> first; + std::string second; +}; + +namespace boost { namespace spirit { namespace traits +{ + template <> + struct transform_attribute<foo_parts + , fusion::tuple<std::string &, optional<std::string> &> + , spirit::qi::domain> + { + typedef fusion::tuple<std::string&, optional<std::string>&> type; + + static type pre(foo_parts & parts) + { + return fusion::tie(parts.second, parts.first); + } + + static void post(foo_parts &, type const &) {} + static void fail(foo_parts &) {} + }; +}}} + +namespace qi = boost::spirit::qi; + +template <typename Iterator> +struct foo_grammar : qi::grammar<Iterator, foo_parts()> +{ + foo_grammar() : foo_grammar::base_type(start, "foo") + { + foo_part = + +qi::alpha >> -(+qi::digit) + | qi::attr(std::string()) + >> qi::attr(boost::optional<std::string>()) + ; + + start = foo_part.alias(); + } + + typedef boost::fusion::tuple<std::string&, boost::optional<std::string>&> + tuple_type; + + qi::rule<Iterator, tuple_type()> foo_part; + qi::rule<Iterator, foo_parts()> start; +}; + +int main() +{ + foo_parts instance; + foo_grammar<std::string::iterator> grammar; + std::string input = "abc123"; + + BOOST_TEST(qi::parse(input.begin(), input.end(), grammar, instance) && + instance.first && instance.first.get() == "123" && + instance.second == "abc"); + + return boost::report_errors(); +} + diff --git a/src/boost/libs/spirit/test/qi/repeat.cpp b/src/boost/libs/spirit/test/qi/repeat.cpp new file mode 100644 index 00000000..dffe8c66 --- /dev/null +++ b/src/boost/libs/spirit/test/qi/repeat.cpp @@ -0,0 +1,259 @@ +/*============================================================================= + 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/include/qi_operator.hpp> +#include <boost/spirit/include/qi_char.hpp> +#include <boost/spirit/include/qi_string.hpp> +#include <boost/spirit/include/qi_numeric.hpp> +#include <boost/spirit/include/qi_directive.hpp> +#include <boost/spirit/include/qi_action.hpp> +#include <boost/spirit/include/support_argument.hpp> +#include <boost/spirit/include/phoenix_core.hpp> +#include <boost/spirit/include/phoenix_operator.hpp> + +#include <string> +#include <iostream> +#include "test.hpp" + +struct x_attr +{ +}; + +namespace boost { namespace spirit { namespace traits +{ + template <> + struct container_value<x_attr> + { + typedef char type; // value type of container + }; + + template <> + struct push_back_container<x_attr, char> + { + static bool call(x_attr& /*c*/, char /*val*/) + { + // push back value type into container + return true; + } + }; +}}} + +int +main() +{ + using spirit_test::test_attr; + using spirit_test::test; + + using namespace boost::spirit::ascii; + using boost::spirit::qi::repeat; + using boost::spirit::qi::inf; + using boost::spirit::qi::omit; + using boost::spirit::qi::int_; + using boost::spirit::qi::_1; + using boost::spirit::qi::lexeme; + + { + 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)); + } + + { + BOOST_TEST(test("aBcdeFGH", no_case[repeat(8)[lower]])); + BOOST_TEST(test("a B cde FGH", no_case[repeat(8)[lower]], 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"); + } + + { + std::string s; + BOOST_TEST(test_attr("bbbb", repeat(4)[char_], s) && s == "bbbb"); + + s.clear(); + BOOST_TEST(test_attr("b b b b", repeat(4)[char_], s, space) && s == "bbbb"); + + // The following 2 tests show that omit does not inhibit explicit attributes + s.clear(); + BOOST_TEST(test_attr("bbbb", omit[repeat(4)[char_('b')]], s) && s == "bbbb"); + + s.clear(); + BOOST_TEST(test_attr("b b b b", omit[repeat(4)[char_('b')]], s, space) && s == "bbbb"); + } + + { + 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)); + } + + { // actions + namespace phx = boost::phoenix; + + std::vector<char> v; + BOOST_TEST(test("bbbb", repeat(4)[char_][phx::ref(v) = _1]) && 4 == v.size() && + v[0] == 'b' && v[1] == 'b' && v[2] == 'b' && v[3] == 'b'); + } + + { // more actions + namespace phx = boost::phoenix; + + std::vector<int> v; + BOOST_TEST(test("123 456 789", repeat(3)[int_][phx::ref(v) = _1], space) && 3 == v.size() && + v[0] == 123 && v[1] == 456 && v[2] == 789); + } + + { // lazy repeats + using boost::phoenix::val; + + BOOST_TEST(test("aaaaaaaa", repeat(val(8))[char_])); + BOOST_TEST(!test("aa", repeat(val(3))[char_])); + + BOOST_TEST(test("aaa", repeat(val(3), val(5))[char_])); + BOOST_TEST(test("aaaaa", repeat(val(3), val(5))[char_])); + BOOST_TEST(!test("aaaaaa", repeat(val(3), val(5))[char_])); + BOOST_TEST(!test("aa", repeat(val(3), val(5))[char_])); + + BOOST_TEST(test("aaa", repeat(val(3), val(inf))[char_])); + BOOST_TEST(test("aaaaa", repeat(val(3), val(inf))[char_])); + BOOST_TEST(test("aaaaaa", repeat(val(3), val(inf))[char_])); + BOOST_TEST(!test("aa", repeat(val(3), val(inf))[char_])); + } + + { // more lazy repeats + using boost::phoenix::val; + + BOOST_TEST(test("aaa", repeat(3, val(5))[char_])); + BOOST_TEST(test("aaaaa", repeat(val(3), 5)[char_])); + BOOST_TEST(!test("aaaaaa", repeat(3, val(5))[char_])); + BOOST_TEST(!test("aa", repeat(val(3), 5)[char_])); + +//#warning "testcase commented out" + BOOST_TEST(test("aaa", repeat(val(3), inf)[char_])); + BOOST_TEST(test("aaaaa", repeat(3, val(inf))[char_])); + BOOST_TEST(test("aaaaaa", repeat(val(3), inf)[char_])); + BOOST_TEST(!test("aa", repeat(3, val(inf))[char_])); + } + + { // attribute customization + + x_attr x; + test_attr("abcde", repeat[char_], x); + test_attr("abcde", repeat(5)[char_], x); + test_attr("abcde", repeat(1, 5)[char_], x); + test_attr("abcde", repeat(1, inf)[char_], x); + } + + return boost::report_errors(); +} + diff --git a/src/boost/libs/spirit/test/qi/rule1.cpp b/src/boost/libs/spirit/test/qi/rule1.cpp new file mode 100644 index 00000000..97370e8e --- /dev/null +++ b/src/boost/libs/spirit/test/qi/rule1.cpp @@ -0,0 +1,163 @@ +/*============================================================================= + 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 <boost/detail/lightweight_test.hpp> +#include <boost/spirit/include/qi_operator.hpp> +#include <boost/spirit/include/qi_char.hpp> +#include <boost/spirit/include/qi_string.hpp> +#include <boost/spirit/include/qi_numeric.hpp> +#include <boost/spirit/include/qi_auxiliary.hpp> +#include <boost/spirit/include/qi_directive.hpp> +#include <boost/spirit/include/qi_nonterminal.hpp> +#include <boost/spirit/include/qi_action.hpp> +#include <boost/fusion/include/std_pair.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::ascii; + using namespace boost::spirit::qi::labels; + using boost::spirit::qi::locals; + using boost::spirit::qi::rule; + using boost::spirit::qi::int_; + using boost::spirit::qi::uint_; + using boost::spirit::qi::fail; + using boost::spirit::qi::on_error; + using boost::spirit::qi::debug; + using boost::spirit::qi::lit; + + { // basic tests + + rule<char const*> a, b, c, start; + + a = 'a'; + b = 'b'; + c = 'c'; + + a.name("a"); + b.name("b"); + c.name("c"); + start.name("start"); + + debug(a); + debug(b); + debug(c); + debug(start); + + start = *(a | b | c); + BOOST_TEST(test("abcabcacb", start)); + + start = (a | b) >> (start | b); + BOOST_TEST(test("aaaabababaaabbb", start)); + BOOST_TEST(test("aaaabababaaabba", start, false)); + + // ignore the skipper! + BOOST_TEST(test("aaaabababaaabba", start, space, false)); + } + + { // basic tests with direct initialization + + rule<char const*> a ('a'); + rule<char const*> b ('b'); + rule<char const*> c ('c'); +#ifdef BOOST_CLANG +# pragma clang diagnostic push +// variable 'start' is uninitialized when used within its own initialization +# pragma clang diagnostic ignored "-Wuninitialized" +#endif + rule<char const*> start = (a | b) >> (start | b); +#ifdef BOOST_CLANG +# pragma clang diagnostic pop +#endif + + 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 + rule<char const*, space_type> a, b, c, start; + + a = 'a'; + b = 'b'; + c = 'c'; + + a.name("a"); + b.name("b"); + c.name("c"); + start.name("start"); + + debug(a); + debug(b); + debug(c); + debug(start); + + start = *(a | b | c); + BOOST_TEST(test(" a b c a b c a c b ", start, space)); + + start = (a | b) >> (start | 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 + + rule<char const*, space_type> a, b, c, start; + + a = 'a'; + b = 'b'; + c = 'c'; + + a.name("a"); + b.name("b"); + c.name("c"); + start.name("start"); + + debug(a); + debug(b); + debug(c); + debug(start); + + start = *(a | b) >> c; + + using boost::spirit::qi::phrase_parse; + using boost::spirit::qi::skip_flag; + { + 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_postskip) + && s1 == e1 - 5); + } + + 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, start, space, skip_flag::postskip) + && 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, start, space, skip_flag::dont_postskip) + && s1 == e1 - 1); + } + } + + return boost::report_errors(); +} + diff --git a/src/boost/libs/spirit/test/qi/rule2.cpp b/src/boost/libs/spirit/test/qi/rule2.cpp new file mode 100644 index 00000000..ac6b2f4f --- /dev/null +++ b/src/boost/libs/spirit/test/qi/rule2.cpp @@ -0,0 +1,157 @@ +/*============================================================================= + 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 <boost/detail/lightweight_test.hpp> +#include <boost/spirit/include/qi_operator.hpp> +#include <boost/spirit/include/qi_char.hpp> +#include <boost/spirit/include/qi_string.hpp> +#include <boost/spirit/include/qi_numeric.hpp> +#include <boost/spirit/include/qi_auxiliary.hpp> +#include <boost/spirit/include/qi_directive.hpp> +#include <boost/spirit/include/qi_nonterminal.hpp> +#include <boost/spirit/include/qi_action.hpp> +#include <boost/spirit/include/phoenix_core.hpp> +#include <boost/spirit/include/phoenix_operator.hpp> +#include <boost/fusion/include/std_pair.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::ascii; + using namespace boost::spirit::qi::labels; + using boost::spirit::qi::locals; + using boost::spirit::qi::rule; + using boost::spirit::qi::int_; + using boost::spirit::qi::uint_; + using boost::spirit::qi::fail; + using boost::spirit::qi::on_error; + using boost::spirit::qi::debug; + using boost::spirit::qi::lit; + + namespace phx = boost::phoenix; + + { // test unassigned rule + + rule<char const*> a; + BOOST_TEST(!test("x", a)); + } + + { // alias tests + + rule<char const*> a, b, c, d, start; + + a = 'a'; + b = 'b'; + c = 'c'; + d = start.alias(); // d will always track start + + start = *(a | b | c); + BOOST_TEST(test("abcabcacb", d)); + + start = (a | b) >> (start | b); + BOOST_TEST(test("aaaabababaaabbb", d)); + } + + { // copy tests + + rule<char const*> a, b, c, start; + + a = 'a'; + b = 'b'; + c = 'c'; + + // The FF is the dynamic equivalent of start = *(a | b | c); + start = a; + start = start.copy() | b; + start = start.copy() | c; + start = *(start.copy()); + + BOOST_TEST(test("abcabcacb", start)); + + // The FF is the dynamic equivalent of start = (a | b) >> (start | b); + start = b; + start = a | start.copy(); + start = start.copy() >> (start | b); + + BOOST_TEST(test("aaaabababaaabbb", start)); + BOOST_TEST(test("aaaabababaaabba", start, false)); + } + + { // context tests + + char ch; + rule<char const*, char()> a; + a = alpha[_val = _1]; + + BOOST_TEST(test("x", a[phx::ref(ch) = _1])); + BOOST_TEST(ch == 'x'); + + BOOST_TEST(test_attr("z", a, ch)); // attribute is given. + BOOST_TEST(ch == 'z'); + } + + { // auto rules tests + + char ch = '\0'; + rule<char const*, char()> a; + a %= alpha; + + BOOST_TEST(test("x", a[phx::ref(ch) = _1])); + BOOST_TEST(ch == 'x'); + ch = '\0'; + BOOST_TEST(test_attr("z", a, ch)); // attribute is given. + BOOST_TEST(ch == 'z'); + + a = alpha; // test deduced auto rule behavior + ch = '\0'; + BOOST_TEST(test("x", a[phx::ref(ch) = _1])); + 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; + rule<char const*, std::string()> r; + r %= char_ >> *(',' >> char_); + + BOOST_TEST(test("a,b,c,d,e,f", r[phx::ref(s) = _1])); + BOOST_TEST(s == "abcdef"); + + r = char_ >> *(',' >> char_); // test deduced auto rule behavior + s.clear(); + BOOST_TEST(test("a,b,c,d,e,f", r[phx::ref(s) = _1])); + BOOST_TEST(s == "abcdef"); + + r %= char_ >> char_ >> char_ >> char_ >> char_ >> char_; + s.clear(); + BOOST_TEST(test("abcdef", r[phx::ref(s) = _1])); + BOOST_TEST(s == "abcdef"); + + r = char_ >> char_ >> char_ >> char_ >> char_ >> char_; + s.clear(); + BOOST_TEST(test("abcdef", r[phx::ref(s) = _1])); + BOOST_TEST(s == "abcdef"); + } + + return boost::report_errors(); +} + diff --git a/src/boost/libs/spirit/test/qi/rule3.cpp b/src/boost/libs/spirit/test/qi/rule3.cpp new file mode 100644 index 00000000..7e59f117 --- /dev/null +++ b/src/boost/libs/spirit/test/qi/rule3.cpp @@ -0,0 +1,143 @@ +/*============================================================================= + 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 <boost/detail/lightweight_test.hpp> +#include <boost/spirit/include/qi_operator.hpp> +#include <boost/spirit/include/qi_char.hpp> +#include <boost/spirit/include/qi_string.hpp> +#include <boost/spirit/include/qi_numeric.hpp> +#include <boost/spirit/include/qi_auxiliary.hpp> +#include <boost/spirit/include/qi_directive.hpp> +#include <boost/spirit/include/qi_nonterminal.hpp> +#include <boost/spirit/include/qi_action.hpp> +#include <boost/spirit/include/phoenix_core.hpp> +#include <boost/spirit/include/phoenix_operator.hpp> +#include <boost/fusion/include/std_pair.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::ascii; + using namespace boost::spirit::qi::labels; + using boost::spirit::qi::locals; + using boost::spirit::qi::rule; + using boost::spirit::qi::int_; + using boost::spirit::qi::uint_; + using boost::spirit::qi::fail; + using boost::spirit::qi::on_error; + using boost::spirit::qi::debug; + using boost::spirit::qi::lit; + + namespace phx = boost::phoenix; + + { // synth attribute value-init + + std::string s; + rule<char const*, char()> r; + r = alpha[_val += _1]; + BOOST_TEST(test_attr("abcdef", +r, s)); + BOOST_TEST(s == "abcdef"); + } + + { // auto rules aliasing tests + + char ch = '\0'; + rule<char const*, char()> a, b; + a %= b; + b %= alpha; + + BOOST_TEST(test("x", a[phx::ref(ch) = _1])); + BOOST_TEST(ch == 'x'); + ch = '\0'; + BOOST_TEST(test_attr("z", a, ch)); // attribute is given. + BOOST_TEST(ch == 'z'); + + a = b; // test deduced auto rule behavior + b = alpha; + + ch = '\0'; + BOOST_TEST(test("x", a[phx::ref(ch) = _1])); + BOOST_TEST(ch == 'x'); + ch = '\0'; + BOOST_TEST(test_attr("z", a, ch)); // attribute is given. + BOOST_TEST(ch == 'z'); + } + + { // context (w/arg) tests + + char ch; + rule<char const*, char(int)> a; // 1 arg + a = alpha[_val = _1 + _r1]; + + BOOST_TEST(test("x", a(phx::val(1))[phx::ref(ch) = _1])); + BOOST_TEST(ch == 'x' + 1); + + BOOST_TEST(test_attr("a", a(1), ch)); // allow scalars as rule args too. + BOOST_TEST(ch == 'a' + 1); + + rule<char const*, char(int, int)> b; // 2 args + b = alpha[_val = _1 + _r1 + _r2]; + BOOST_TEST(test_attr("a", b(1, 2), ch)); + BOOST_TEST(ch == 'a' + 1 + 2); + } + + { // context (w/ reference arg) tests + + char ch; + rule<char const*, void(char&)> a; // 1 arg (reference) + a = alpha[_r1 = _1]; + + BOOST_TEST(test("x", a(phx::ref(ch)))); + BOOST_TEST(ch == 'x'); + } + + { // context (w/locals) tests + + rule<char const*, locals<char> > a; // 1 local + a = alpha[_a = _1] >> char_(_a); + BOOST_TEST(test("aa", a)); + BOOST_TEST(!test("ax", a)); + } + + { // context (w/args and locals) tests + + rule<char const*, void(int), locals<char> > a; // 1 arg + 1 local + a = alpha[_a = _1 + _r1] >> char_(_a); + BOOST_TEST(test("ab", a(phx::val(1)))); + BOOST_TEST(test("xy", a(phx::val(1)))); + BOOST_TEST(!test("ax", a(phx::val(1)))); + } + + { // void() has unused type (void == unused_type) + + std::pair<int, char> attr; + rule<char const*, void()> r; + r = char_; + BOOST_TEST(test_attr("123ax", int_ >> char_ >> r, attr)); + BOOST_TEST(attr.first == 123); + BOOST_TEST(attr.second == 'a'); + } + + { // bug: test that injected attributes are ok + + rule<char const*, char(int) > r; + + // problem code: + r = char_(_r1)[_val = _1]; + } + + return boost::report_errors(); +} + diff --git a/src/boost/libs/spirit/test/qi/rule4.cpp b/src/boost/libs/spirit/test/qi/rule4.cpp new file mode 100644 index 00000000..9519c044 --- /dev/null +++ b/src/boost/libs/spirit/test/qi/rule4.cpp @@ -0,0 +1,192 @@ +/*============================================================================= + 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 <boost/detail/lightweight_test.hpp> +#include <boost/spirit/include/qi_operator.hpp> +#include <boost/spirit/include/qi_char.hpp> +#include <boost/spirit/include/qi_string.hpp> +#include <boost/spirit/include/qi_numeric.hpp> +#include <boost/spirit/include/qi_auxiliary.hpp> +#include <boost/spirit/include/qi_directive.hpp> +#include <boost/spirit/include/qi_nonterminal.hpp> +#include <boost/spirit/include/qi_action.hpp> +#include <boost/spirit/include/phoenix_core.hpp> +#include <boost/spirit/include/phoenix_operator.hpp> +#include <boost/spirit/include/phoenix_object.hpp> +#include <boost/spirit/include/phoenix_bind.hpp> +#include <boost/fusion/include/std_pair.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::ascii; + using namespace boost::spirit::qi::labels; + using boost::spirit::qi::locals; + using boost::spirit::qi::rule; + using boost::spirit::qi::int_; + using boost::spirit::qi::uint_; + using boost::spirit::qi::fail; + using boost::spirit::qi::on_error; + using boost::spirit::qi::debug; + using boost::spirit::qi::lit; + + namespace phx = boost::phoenix; + + + { // show that ra = rb and ra %= rb works as expected + rule<char const*, int() > ra, rb; + int attr; + + ra %= int_; + BOOST_TEST(test_attr("123", ra, attr)); + BOOST_TEST(attr == 123); + + rb %= ra; + BOOST_TEST(test_attr("123", rb, attr)); + BOOST_TEST(attr == 123); + + rb = ra; + BOOST_TEST(test_attr("123", rb, attr)); + BOOST_TEST(attr == 123); + } + + { // std::string as container attribute with auto rules + + rule<char const*, std::string()> text; + text %= +(!char_(')') >> !char_('>') >> char_); + std::string attr; + BOOST_TEST(test_attr("x", text, attr)); + BOOST_TEST(attr == "x"); + + // test deduced auto rule behavior + text = +(!char_(')') >> !char_('>') >> char_); + attr.clear(); + BOOST_TEST(test_attr("x", text, attr)); + BOOST_TEST(attr == "x"); + } + + { // error handling + + using namespace boost::spirit::ascii; + using boost::phoenix::construct; + using boost::phoenix::bind; + + rule<char const*> r; + r = '(' > int_ > ',' > int_ > ')'; + + on_error<fail> + ( + r, std::cout + << phx::val("Error! Expecting: ") + << _4 + << phx::val(", got: \"") + << construct<std::string>(_3, _2) + << phx::val("\"") + << std::endl + ); + + 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)); + } + + { // specifying the encoding + + typedef boost::spirit::char_encoding::iso8859_1 iso8859_1; + rule<char const*, iso8859_1> r; + + r = no_case['\xE1']; + BOOST_TEST(test("\xC1", r)); + r = no_case[char_('\xE1')]; + BOOST_TEST(test("\xC1", r)); + + r = no_case[char_("\xE5-\xEF")]; + BOOST_TEST(test("\xC9", r)); + BOOST_TEST(!test("\xFF", r)); + + r = no_case["\xE1\xC1"]; + BOOST_TEST(test("\xC1\xE1", r)); + r = no_case[lit("\xE1\xC1")]; + BOOST_TEST(test("\xC1\xE1", r)); + } + + { + typedef boost::variant<double, int> v_type; + rule<const char*, v_type()> r1 = 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; + rule<const char*, ov_type()> r2 = 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; + rule<const char*, vector<int>()> r = int_; + + vector<int> v(0); + BOOST_TEST(test_attr("1", r, v) && at_c<0>(v) == 1); + } + + { + using boost::fusion::vector; + using boost::fusion::at_c; + rule<const char*, vector<unsigned int>()> r = uint_; + + vector<unsigned int> v(0); + BOOST_TEST(test_attr("1", r, v) && at_c<0>(v) == 1); + } + + /////////////////////////////////////////////////////////////////////////// + { + using boost::spirit::qi::int_; + using boost::spirit::qi::_1; + using boost::spirit::qi::_val; + using boost::spirit::qi::space; + using boost::spirit::qi::space_type; + + rule<const char*, int()> r1 = int_; + rule<const char*, int(), space_type> r2 = int_; + + int i = 0; + int j = 0; + BOOST_TEST(test_attr("456", r1[_val = _1], i) && i == 456); + BOOST_TEST(test_attr(" 456", r2[_val = _1], j, space) && j == 456); + } + +#if 0 // disabling test (can't fix) + { + using boost::spirit::qi::lexeme; + using boost::spirit::qi::alnum; + + rule<const char*, std::string()> literal_; + literal_ = lexeme[ +(alnum | '_') ]; + + std::string attr; + BOOST_TEST(test_attr("foo_bar", literal_, attr) && attr == "foo_bar"); + std::cout << attr << std::endl; + } +#endif + + return boost::report_errors(); +} + diff --git a/src/boost/libs/spirit/test/qi/rule_fail.cpp b/src/boost/libs/spirit/test/qi/rule_fail.cpp new file mode 100644 index 00000000..b1141062 --- /dev/null +++ b/src/boost/libs/spirit/test/qi/rule_fail.cpp @@ -0,0 +1,30 @@ +/*============================================================================= + 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/spirit/include/qi_operator.hpp> +#include <boost/spirit/include/qi_char.hpp> +#include <boost/spirit/include/qi_numeric.hpp> +#include <boost/spirit/include/qi_nonterminal.hpp> +#include <boost/spirit/include/qi_parse.hpp> + +using namespace boost::spirit; +using namespace boost::spirit::qi; + +// this test must fail compiling +int main() +{ + char const* input = "some input, it doesn't matter"; + char const* end = &input[strlen(input)]; + + rule<char const*, rule<char const*> > def; + def = int_ >> *(',' >> int_); + + phrase_parse(input, end, def, + qi::space | ('%' >> *~char_('\n') >> '\n')); + + return 0; +} diff --git a/src/boost/libs/spirit/test/qi/sequence.cpp b/src/boost/libs/spirit/test/qi/sequence.cpp new file mode 100644 index 00000000..657e70e6 --- /dev/null +++ b/src/boost/libs/spirit/test/qi/sequence.cpp @@ -0,0 +1,337 @@ +/*============================================================================= + 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 <boost/detail/lightweight_test.hpp> +#include <boost/spirit/include/qi_operator.hpp> +#include <boost/spirit/include/qi_char.hpp> +#include <boost/spirit/include/qi_string.hpp> +#include <boost/spirit/include/qi_numeric.hpp> +#include <boost/spirit/include/qi_directive.hpp> +#include <boost/spirit/include/qi_action.hpp> +#include <boost/spirit/include/qi_nonterminal.hpp> +#include <boost/spirit/include/support_argument.hpp> +#include <boost/spirit/include/phoenix_core.hpp> +#include <boost/spirit/include/phoenix_operator.hpp> + +#include <string> +#include <iostream> +#include "test.hpp" + +int +main() +{ + using namespace boost::spirit::ascii; + using boost::spirit::qi::lit; + using boost::spirit::qi::unused; + using boost::spirit::qi::int_; + using boost::spirit::qi::double_; + using boost::spirit::qi::what; + using boost::spirit::qi::rule; + using boost::spirit::qi::_1; + using boost::spirit::qi::_2; + + using boost::fusion::vector; + using boost::fusion::at_c; + + using spirit_test::test; + using spirit_test::test_attr; + using spirit_test::print_info; + + { + 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_('x') >> char_('o')))); + BOOST_TEST((test("xin", char_('x') >> char_('i') >> char_('n')))); + } + + { + 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("abcdefg", char_ >> char_ >> "cdefg", attr))); + BOOST_TEST((at_c<0>(attr) == 'a')); + BOOST_TEST((at_c<1>(attr) == 'b')); + } + + { + 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')); + } + + { + // unused_type means we don't care about the attribute + 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')); + } + + { + // unused_type means we don't care about the attribute, even at the end + 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 + vector<double, int> fv; + rule<char const*, vector<double, int>()> r; + r %= double_ >> ',' >> int_; + BOOST_TEST((test_attr("test:2.0,1", "test:" >> r, fv) && + fv == vector<double, int>(2.0, 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))); + } + + { +#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::qi::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)); + + 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(); + + using boost::spirit::qi::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"); + } + + // 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; + rule<char const*, std::string()> e = *~char_(','); + rule<char const*, std::vector<std::string>()> l = 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; + rule<char const*, std::string()> e = *~char_(','); + rule<char const*, std::string()> l = 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'); + + 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]); + + v.clear(); + BOOST_TEST(test_attr("a", char_, v)); + BOOST_TEST(v.size() == 1 && v[0] == 'a'); + } + + { // test action + using boost::phoenix::ref; + char c = 0; + int n = 0; + + BOOST_TEST(test("x123\"a string\"", (char_ >> int_ >> "\"a string\"") + [ref(c) = _1, ref(n) = _2])); + BOOST_TEST(c == 'x'); + BOOST_TEST(n == 123); + } + + { // test action + using boost::phoenix::ref; + char c = 0; + int n = 0; + + BOOST_TEST(test("x 123 \"a string\"", (char_ >> int_ >> "\"a string\"") + [ref(c) = _1, ref(n) = _2], space)); + BOOST_TEST(c == 'x'); + BOOST_TEST(n == 123); + } + + { // testing "what" + print_info(what(alpha | char_('x') >> lit("hello") >> int_)); + } + +// { // compile check only +// using boost::spirit::qi::rule; +// typedef boost::fusion::vector<int, double> tuple_type; +// typedef std::vector<boost::fusion::vector<int, double> > attr_type; +// +// rule<char const*, tuple_type()> r = int_ >> ',' >> double_; +// rule<char const*, attr_type()> r2 = r >> *(',' >> r); +// //~ rule<char const*, attr_type()> r2 = r % ','; +// } + + return boost::report_errors(); +} + diff --git a/src/boost/libs/spirit/test/qi/sequential_or.cpp b/src/boost/libs/spirit/test/qi/sequential_or.cpp new file mode 100644 index 00000000..4738f233 --- /dev/null +++ b/src/boost/libs/spirit/test/qi/sequential_or.cpp @@ -0,0 +1,110 @@ +/*============================================================================= + 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 <boost/detail/lightweight_test.hpp> +#include <boost/spirit/include/qi_operator.hpp> +#include <boost/spirit/include/qi_char.hpp> +#include <boost/spirit/include/qi_string.hpp> +#include <boost/spirit/include/qi_numeric.hpp> +#include <boost/spirit/include/qi_action.hpp> +#include <boost/spirit/include/support_argument.hpp> +#include <boost/fusion/include/vector.hpp> +#include <boost/fusion/include/at.hpp> +#include <boost/spirit/include/phoenix_core.hpp> +#include <boost/spirit/include/phoenix_operator.hpp> +#include <boost/optional.hpp> + +#include <string> +#include <iostream> +#include "test.hpp" + +int +main() +{ + using spirit_test::test; + using spirit_test::test_attr; + + using boost::spirit::qi::int_; + using boost::spirit::qi::_1; + using boost::spirit::qi::_2; + using boost::spirit::ascii::char_; + using boost::spirit::ascii::alpha; + using boost::fusion::vector; + using boost::fusion::at_c; + using boost::optional; + + { + BOOST_TEST((test("a", char_('a') || char_('b')))); + BOOST_TEST((test("b", char_('a') || char_('b')))); + BOOST_TEST((test("ab", char_('a') || char_('b')))); + } + + { + vector<optional<int>, optional<char> > attr; + + BOOST_TEST((test_attr("a", int_ || alpha, attr))); + BOOST_TEST((!at_c<0>(attr))); + BOOST_TEST((at_c<1>(attr).get() == 'a')); + + at_c<1>(attr) = optional<char>(); // clear the optional + BOOST_TEST((test_attr("123", int_ || alpha, attr))); + BOOST_TEST((at_c<0>(attr).get() == 123)); + BOOST_TEST((!at_c<1>(attr))); + + at_c<0>(attr) = optional<int>(); // clear the optional + BOOST_TEST((test_attr("123a", int_ || alpha, attr))); + BOOST_TEST((at_c<0>(attr).get() == 123)); + BOOST_TEST((at_c<1>(attr).get() == 'a')); + + BOOST_TEST((!test("a123", int_ || alpha))); + } + + { // test whether optional<optional<>> gets properly handled + vector<optional<int>, optional<int> > attr1; + BOOST_TEST((test_attr("123", int_ || '[' >> -int_ >> ']', attr1))); + BOOST_TEST((at_c<0>(attr1) && at_c<0>(attr1).get() == 123)); + BOOST_TEST((!at_c<1>(attr1))); + + vector<optional<int>, optional<int> > attr2; + BOOST_TEST((test_attr("[123]", int_ || '[' >> -int_ >> ']', attr2))); + BOOST_TEST((!at_c<0>(attr2))); + BOOST_TEST((at_c<1>(attr2) && at_c<1>(attr2).get() == 123)); + + vector<optional<int>, optional<optional<int> > > attr3; + BOOST_TEST((test_attr("[]", int_ || '[' >> -int_ >> ']', attr3))); + BOOST_TEST((!at_c<0>(attr3))); + BOOST_TEST((at_c<1>(attr3) && !at_c<1>(attr3).get())); + } + + { // test unused attribute handling + + vector<optional<int>, optional<char> > attr; + BOOST_TEST((test_attr("123abc", int_ || ("ab" >> char_), attr))); + BOOST_TEST((at_c<0>(attr).get() == 123)); + BOOST_TEST((at_c<1>(attr).get() == 'c')); + } + + { // test unused attribute handling + + optional<int> attr; + BOOST_TEST((test_attr("123ab", int_ || "ab", attr))); + BOOST_TEST((attr == 123)); + } + + { // test action + namespace phx = boost::phoenix; + + optional<int> i; + optional<char> c; + + BOOST_TEST((test("123a", (int_ || alpha)[phx::ref(i) = _1, phx::ref(c) = _2]))); + BOOST_TEST((i.get() == 123)); + BOOST_TEST((c.get() == 'a')); + } + + return boost::report_errors(); +} + diff --git a/src/boost/libs/spirit/test/qi/skip.cpp b/src/boost/libs/spirit/test/qi/skip.cpp new file mode 100644 index 00000000..cc0c1a88 --- /dev/null +++ b/src/boost/libs/spirit/test/qi/skip.cpp @@ -0,0 +1,55 @@ +/*============================================================================= + 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 <boost/detail/lightweight_test.hpp> +#include <boost/spirit/include/qi_char.hpp> +#include <boost/spirit/include/qi_directive.hpp> +#include <boost/spirit/include/qi_operator.hpp> +#include <boost/spirit/include/phoenix_core.hpp> + +#include <iostream> +#include "test.hpp" + +int +main() +{ + using spirit_test::test; + using spirit_test::test_attr; + using boost::spirit::qi::skip; + using boost::spirit::qi::lexeme; + using boost::spirit::qi::lit; + using boost::spirit::ascii::char_; + using boost::spirit::ascii::space; + using boost::spirit::ascii::alpha; + + { + 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))); + } + + { // lazy skip + using boost::phoenix::val; + + BOOST_TEST((test("a b c d", skip(val(space))[*char_]))); + } + + return boost::report_errors(); +} diff --git a/src/boost/libs/spirit/test/qi/stream.cpp b/src/boost/libs/spirit/test/qi/stream.cpp new file mode 100644 index 00000000..3d764e53 --- /dev/null +++ b/src/boost/libs/spirit/test/qi/stream.cpp @@ -0,0 +1,60 @@ +/*============================================================================= + Copyright (c) 2001-2011 Hartmut Kaiser + Copyright (c) 2011 Brian O'Kennedy + + 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/include/qi_char.hpp> +#include <boost/spirit/include/qi_numeric.hpp> +#include <boost/spirit/include/qi_stream.hpp> +#include <boost/spirit/include/qi_operator.hpp> + +#include "test.hpp" + +struct complex +{ + complex (double a = 0.0, double b = 0.0) : a(a), b(b) {} + double a, b; +}; + +std::istream& operator>> (std::istream& is, complex& z) +{ + char lbrace = '\0', comma = '\0', rbrace = '\0'; + is >> lbrace >> z.a >> comma >> z.b >> rbrace; + if (lbrace != '{' || comma != ',' || rbrace != '}') + is.setstate(std::ios_base::failbit); + + return is; +} + +int main() +{ + using spirit_test::test_attr; + + { + using boost::spirit::qi::blank; + using boost::spirit::qi::double_; + using boost::spirit::qi::stream; + using boost::spirit::qi::stream_parser; + using boost::fusion::at_c; + + complex c; + BOOST_TEST(test_attr("{1.0,2.5}", + stream_parser<char, complex>(), c, blank) && + c.a == 1.0 && c.b == 2.5); + + boost::fusion::vector<complex, double> d; + BOOST_TEST(test_attr("{1.0,2.5},123.456", + stream >> ',' >> double_, d, blank) && + at_c<0>(d).a == 1.0 && at_c<0>(d).b == 2.5 && at_c<1>(d) == 123.456); + } + + return boost::report_errors(); +} + + diff --git a/src/boost/libs/spirit/test/qi/symbols1.cpp b/src/boost/libs/spirit/test/qi/symbols1.cpp new file mode 100644 index 00000000..80632a74 --- /dev/null +++ b/src/boost/libs/spirit/test/qi/symbols1.cpp @@ -0,0 +1,204 @@ +/*============================================================================= + Copyright (c) 2001-2010 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/spirit/include/qi_string.hpp> +#include <boost/spirit/include/qi_char.hpp> +#include <boost/spirit/include/qi_action.hpp> +#include <boost/spirit/include/qi_auxiliary.hpp> +#include <boost/spirit/include/qi_directive.hpp> +#include <boost/spirit/include/qi_operator.hpp> +#include <boost/spirit/include/qi_nonterminal.hpp> +#include <boost/spirit/include/support_argument.hpp> +#include <boost/spirit/include/phoenix_core.hpp> +#include <boost/spirit/include/phoenix_operator.hpp> + +#include <boost/core/lightweight_test.hpp> +#include <boost/core/lightweight_test_trait.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::qi::symbols; + using boost::spirit::qi::rule; + using boost::spirit::qi::lazy; + using boost::spirit::qi::_r1; + + { // basics + symbols<char, int> sym; + + sym.add + ("Joel") + ("Ruby") + ("Tenji") + ("Tutit") + ("Kim") + ("Joey") + ("Joeyboy") + ; + + BOOST_TEST_TRAIT_TRUE((boost::spirit::traits::is_parser<symbols<char, int> >)); + + 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<char, 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<char, 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::ascii; + + symbols<char, 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<char, int> sym; + + sym.add + ("Joel", 1) + ("Ruby", 2) + ("Tenji", 3) + ("Tutit", 4) + ("Kim", 5) + ("Joey", 6) + ("Joeyboy", 7) + ; + + 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("Joeyboy", sym, i))); + BOOST_TEST(i == 7); + 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 + namespace phx = boost::phoenix; + using boost::spirit::_1; + + symbols<char, int> sym; + sym.add + ("Joel", 1) + ("Ruby", 2) + ("Tenji", 3) + ("Tutit", 4) + ("Kim", 5) + ("Joey", 6) + ; + + int i; + BOOST_TEST((test("Joel", sym[phx::ref(i) = _1]))); + BOOST_TEST(i == 1); + BOOST_TEST((test("Ruby", sym[phx::ref(i) = _1]))); + BOOST_TEST(i == 2); + BOOST_TEST((test("Tenji", sym[phx::ref(i) = _1]))); + BOOST_TEST(i == 3); + BOOST_TEST((test("Tutit", sym[phx::ref(i) = _1]))); + BOOST_TEST(i == 4); + BOOST_TEST((test("Kim", sym[phx::ref(i) = _1]))); + BOOST_TEST(i == 5); + BOOST_TEST((test("Joey", sym[phx::ref(i) = _1]))); + BOOST_TEST(i == 6); + BOOST_TEST((!test("XXX", sym[phx::ref(i) = _1]))); + } + + return boost::report_errors(); +} diff --git a/src/boost/libs/spirit/test/qi/symbols2.cpp b/src/boost/libs/spirit/test/qi/symbols2.cpp new file mode 100644 index 00000000..a9ceea19 --- /dev/null +++ b/src/boost/libs/spirit/test/qi/symbols2.cpp @@ -0,0 +1,233 @@ +/*============================================================================= + 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 <boost/detail/lightweight_test.hpp> +#include <boost/spirit/include/qi_string.hpp> +#include <boost/spirit/include/qi_char.hpp> +#include <boost/spirit/include/qi_action.hpp> +#include <boost/spirit/include/qi_auxiliary.hpp> +#include <boost/spirit/include/qi_directive.hpp> +#include <boost/spirit/include/qi_operator.hpp> +#include <boost/spirit/include/qi_nonterminal.hpp> +#include <boost/spirit/include/support_argument.hpp> +#include <boost/spirit/include/phoenix_core.hpp> +#include <boost/spirit/include/phoenix_operator.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::qi::symbols; + using boost::spirit::qi::rule; + using boost::spirit::qi::lazy; + using boost::spirit::qi::_r1; + + { // construction from symbol array + char const* syms[] = {"Joel","Ruby","Tenji","Tutit","Kim","Joey"}; + symbols<char, 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<char, 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))); + } + + { + namespace phx = boost::phoenix; + + symbols<char, int> sym; + sym.add + ("a", 1) + ("b", 2) + ; + + rule<char const*, int(symbols<char, int>&)> r; + r %= lazy(_r1); + + int i = 0; + BOOST_TEST(test_attr("a", r(phx::ref(sym)), i)); + BOOST_TEST(i == 1); + BOOST_TEST(test_attr("b", r(phx::ref(sym)), i)); + BOOST_TEST(i == 2); + BOOST_TEST(!test("c", r(phx::ref(sym)))); + } + + { // find + + symbols<char, 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<char, 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 <char, int> sym,sym2; + sym.name("test"); + BOOST_TEST(sym.name()=="test"); + sym2 = sym; + BOOST_TEST(sym2.name()=="test"); + + symbols <char,int> sym3(sym); + BOOST_TEST(sym3.name()=="test"); + } + + { // Substrings + + symbols<char, 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<char, 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<char, 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/qi/terminal_ex.cpp b/src/boost/libs/spirit/test/qi/terminal_ex.cpp new file mode 100644 index 00000000..8514f113 --- /dev/null +++ b/src/boost/libs/spirit/test/qi/terminal_ex.cpp @@ -0,0 +1,392 @@ +/*============================================================================= + Copyright (c) 2008 Francois Barel + + 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/type_traits/is_same.hpp> + +#include <boost/spirit/include/qi_operator.hpp> +#include <boost/spirit/include/qi_char.hpp> +#include <boost/spirit/include/phoenix_core.hpp> +#include <boost/spirit/include/phoenix_operator.hpp> + +#include <iterator> +#include "test.hpp" + + +namespace testns +{ + + BOOST_SPIRIT_TERMINAL_NAME_EX( ops, ops_type ) + + + /////////////////////////////////////////////////////////////////////////// + // Parsers + /////////////////////////////////////////////////////////////////////////// + + template <typename T1> + struct ops_1_parser + : boost::spirit::qi::primitive_parser<ops_1_parser<T1> > + { + ops_1_parser(T1 t1) + : t1(t1) + {} + + template <typename Context, typename Iterator> + struct attribute + { + typedef int type; // Number of parsed chars. + }; + + template <typename Iterator, typename Context + , typename Skipper, typename Attribute> + bool parse(Iterator& first, Iterator const& last + , Context& /*context*/, Skipper const& skipper + , Attribute& attr) const + { + boost::spirit::qi::skip_over(first, last, skipper); + + int count = 0; + + Iterator it = first; + typedef typename std::iterator_traits<Iterator>::value_type Char; + for (T1 t = 0; t < t1; t++, count++) + if (it == last || *it++ != Char('+')) + return false; + + boost::spirit::traits::assign_to(count, attr); + first = it; + return true; + } + + template <typename Context> + boost::spirit::qi::info what(Context& /*context*/) const + { + return boost::spirit::qi::info("ops_1"); + } + + const T1 t1; + + // silence MSVC warning C4512: assignment operator could not be generated + BOOST_DELETED_FUNCTION(ops_1_parser& operator= (ops_1_parser const&)); + }; + + template <typename T1, typename T2> + struct ops_2_parser + : boost::spirit::qi::primitive_parser<ops_2_parser<T1, T2> > + { + ops_2_parser(T1 t1, T2 t2) + : t1(t1) + , t2(t2) + {} + + template <typename Context, typename Iterator> + struct attribute + { + typedef int type; // Number of parsed chars. + }; + + template <typename Iterator, typename Context + , typename Skipper, typename Attribute> + bool parse(Iterator& first, Iterator const& last + , Context& /*context*/, Skipper const& skipper + , Attribute& attr) const + { + boost::spirit::qi::skip_over(first, last, skipper); + + int count = 0; + + Iterator it = first; + typedef typename std::iterator_traits<Iterator>::value_type Char; + for (T1 t = 0; t < t1; t++, count++) + if (it == last || *it++ != Char('+')) + return false; + for (T2 t = 0; t < t2; t++, count++) + if (it == last || *it++ != Char('-')) + return false; + + boost::spirit::traits::assign_to(count, attr); + first = it; + return true; + } + + template <typename Context> + boost::spirit::qi::info what(Context& /*context*/) const + { + return boost::spirit::qi::info("ops_2"); + } + + const T1 t1; + const T2 t2; + + // silence MSVC warning C4512: assignment operator could not be generated + BOOST_DELETED_FUNCTION(ops_2_parser& operator= (ops_2_parser const&)); + }; + + template <typename T1, typename T2, typename T3> + struct ops_3_parser + : boost::spirit::qi::primitive_parser<ops_3_parser<T1, T2, T3> > + { + ops_3_parser(T1 t1, T2 t2, T3 t3) + : t1(t1) + , t2(t2) + , t3(t3) + {} + + template <typename Context, typename Iterator> + struct attribute + { + typedef int type; // Number of parsed chars. + }; + + template <typename Iterator, typename Context + , typename Skipper, typename Attribute> + bool parse(Iterator& first, Iterator const& last + , Context& /*context*/, Skipper const& skipper + , Attribute& attr) const + { + boost::spirit::qi::skip_over(first, last, skipper); + + int count = 0; + + Iterator it = first; + typedef typename std::iterator_traits<Iterator>::value_type Char; + for (T1 t = 0; t < t1; t++, count++) + if (it == last || *it++ != Char('+')) + return false; + for (T2 t = 0; t < t2; t++, count++) + if (it == last || *it++ != Char('-')) + return false; + for (T3 t = 0; t < t3; t++, count++) + if (it == last || *it++ != Char('*')) + return false; + + boost::spirit::traits::assign_to(count, attr); + first = it; + return true; + } + + template <typename Context> + boost::spirit::qi::info what(Context& /*context*/) const + { + return boost::spirit::qi::info("ops_3"); + } + + const T1 t1; + const T2 t2; + const T3 t3; + + // silence MSVC warning C4512: assignment operator could not be generated + BOOST_DELETED_FUNCTION(ops_3_parser& operator= (ops_3_parser const&)); + }; + +} + + +namespace boost { namespace spirit +{ + + /////////////////////////////////////////////////////////////////////////// + // Enablers + /////////////////////////////////////////////////////////////////////////// + + template <typename T1> + struct use_terminal<qi::domain + , terminal_ex<testns::tag::ops, fusion::vector1<T1> > > + : mpl::true_ {}; + + template <typename T1, typename T2> + struct use_terminal<qi::domain + , terminal_ex<testns::tag::ops, fusion::vector2<T1, T2> > > + : mpl::true_ {}; + + template <typename T1, typename T2, typename T3> + struct use_terminal<qi::domain + , terminal_ex<testns::tag::ops, fusion::vector3<T1, T2, T3> > > + : mpl::true_ {}; + + template <> + struct use_lazy_terminal<qi::domain, testns::tag::ops, 1> + : mpl::true_ {}; + + template <> + struct use_lazy_terminal<qi::domain, testns::tag::ops, 2> + : mpl::true_ {}; + + template <> + struct use_lazy_terminal<qi::domain, testns::tag::ops, 3> + : mpl::true_ {}; + +}} + +namespace boost { namespace spirit { namespace qi +{ + + /////////////////////////////////////////////////////////////////////////// + // Parser generators: make_xxx function (objects) + /////////////////////////////////////////////////////////////////////////// + + template <typename Modifiers, typename T1> + struct make_primitive< + terminal_ex<testns::tag::ops, fusion::vector1<T1> > + , Modifiers> + { + typedef testns::ops_1_parser<T1> result_type; + template <typename Terminal> + result_type operator()(const Terminal& term, unused_type) const + { + return result_type( + fusion::at_c<0>(term.args) + ); + } + }; + + template <typename Modifiers, typename T1, typename T2> + struct make_primitive< + terminal_ex<testns::tag::ops, fusion::vector2<T1, T2> > + , Modifiers> + { + typedef testns::ops_2_parser<T1, T2> result_type; + template <typename Terminal> + result_type operator()(const Terminal& term, unused_type) const + { + return result_type( + fusion::at_c<0>(term.args) + , fusion::at_c<1>(term.args) + ); + } + }; + + template <typename Modifiers, typename T1, typename T2, typename T3> + struct make_primitive< + terminal_ex<testns::tag::ops, fusion::vector3<T1, T2, T3> > + , Modifiers> + { + typedef testns::ops_3_parser<T1, T2, T3> result_type; + template <typename Terminal> + result_type operator()(const Terminal& term, unused_type) const + { + return result_type( + fusion::at_c<0>(term.args) + , fusion::at_c<1>(term.args) + , fusion::at_c<2>(term.args) + ); + } + }; + +}}} + + +namespace testns +{ + template <typename T1, typename T> + void check_type_1(const T& /*t*/) + { + BOOST_STATIC_ASSERT(( boost::is_same<T + , typename boost::spirit::terminal<testns::tag::ops>::result<T1>::type >::value )); + } + + template <typename T1, typename T2, typename T> + void check_type_2(const T& /*t*/) + { + BOOST_STATIC_ASSERT(( boost::is_same<T + , typename boost::spirit::terminal<testns::tag::ops>::result<T1, T2>::type >::value )); + } + + template <typename T1, typename T2, typename T3, typename T> + void check_type_3(const T& /*t*/) + { + BOOST_STATIC_ASSERT(( boost::is_same<T + , typename boost::spirit::terminal<testns::tag::ops>::result<T1, T2, T3>::type >::value )); + } +} + + +int +main() +{ + using spirit_test::test_attr; + using spirit_test::test; + + using testns::ops; + using testns::check_type_1; + using testns::check_type_2; + using testns::check_type_3; + + { // immediate args + int c = 0; +#define IP1 ops(2) + check_type_1<int>(IP1); + BOOST_TEST(test_attr("++/", IP1 >> '/', c) && c == 2); + + c = 0; +#define IP2 ops(2, 3) + check_type_2<int, int>(IP2); + BOOST_TEST(test_attr("++---/", IP2 >> '/', c) && c == 5); + + c = 0; +#define IP3 ops(2, 3, 4) + check_type_3<int, int, int>(IP3); + BOOST_TEST(!test("++---***/", IP3 >> '/')); +#define IP4 ops(2, 3, 4) + check_type_3<int, int, int>(IP4); + BOOST_TEST(test_attr("++---****/", IP4 >> '/', c) && c == 9); + } + + using boost::phoenix::val; + using boost::phoenix::actor; + using boost::phoenix::expression::value; + + { // all lazy args + int c = 0; +#define LP1 ops(val(1)) + check_type_1<value<int>::type>(LP1); + BOOST_TEST(test_attr("+/", LP1 >> '/', c) && c == 1); + + c = 0; +#define LP2 ops(val(1), val(4)) + check_type_2<value<int>::type, value<int>::type>(LP2); + BOOST_TEST(test_attr("+----/", LP2 >> '/', c) && c == 5); + + c = 0; +#define LP3 ops(val((char)2), val(3.), val(4)) + check_type_3<value<char>::type, value<double>::type, value<int>::type>(LP3); + BOOST_TEST(!test("++---***/", LP3 >> '/')); +#define LP4 ops(val(1), val(2), val(3)) + check_type_3<value<int>::type, value<int>::type, value<int>::type>(LP4); + BOOST_TEST(test_attr("+--***/", LP4 >> '/', c) && c == 6); + } + + { // mixed immediate and lazy args + namespace fusion = boost::fusion; + namespace phx = boost::phoenix; + + int c = 0; +#define MP1 ops(val(3), 2) + check_type_2<value<int>::type, int>(MP1); + BOOST_TEST(test_attr("+++--/", MP1 >> '/', c) && c == 5); + + c = 0; +#define MP2 ops(4, val(1)) + check_type_2<int, value<int>::type>(MP2); + BOOST_TEST(test_attr("++++-/", MP2 >> '/', c) && c == 5); + + c = 0; +#define MP3 ops(2, val(2), val(2)) + check_type_3<int, value<int>::type, value<int>::type>(MP3); + BOOST_TEST(!test("++-**/", MP3 >> '/')); +#define MP4 ops(2, val(2), 2) + check_type_3<int, value<int>::type, int>(MP4); + BOOST_TEST(test_attr("++--**/", MP4 >> '/', c) && c == 6); + + c = 0; +#define MP5 ops(val(5) - val(3), 2, val(2)) + check_type_3<phx::expression::minus<value<int>::type, value<int>::type>::type, int, value<int>::type>(MP5); + BOOST_TEST(test_attr("++--**/", MP5 >> '/', c) && c == 6); + } + + return boost::report_errors(); +} + diff --git a/src/boost/libs/spirit/test/qi/test.hpp b/src/boost/libs/spirit/test/qi/test.hpp new file mode 100644 index 00000000..3efb667d --- /dev/null +++ b/src/boost/libs/spirit/test/qi/test.hpp @@ -0,0 +1,154 @@ +/*============================================================================= + 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) +=============================================================================*/ +#if !defined(BOOST_SPIRIT_TEST_FEBRUARY_01_2007_0605PM) +#define BOOST_SPIRIT_TEST_FEBRUARY_01_2007_0605PM + +#include <boost/spirit/include/qi_parse.hpp> +#include <boost/spirit/include/qi_what.hpp> +#include <boost/variant/apply_visitor.hpp> +#include <iostream> + +namespace spirit_test +{ + template <typename Char, typename Parser> + bool test(Char const* in, Parser const& p, bool full_match = true) + { + // we don't care about the result of the "what" function. + // we only care that all parsers have it: + boost::spirit::qi::what(p); + + Char const* last = in; + while (*last) + last++; + return boost::spirit::qi::parse(in, last, p) + && (!full_match || (in == last)); + } + + template <typename Char, typename Parser, typename Skipper> + bool test(Char const* in, Parser const& p + , Skipper const& s, bool full_match = true) + { + // we don't care about the result of the "what" function. + // we only care that all parsers have it: + boost::spirit::qi::what(p); + + Char const* last = in; + while (*last) + last++; + return boost::spirit::qi::phrase_parse(in, last, p, s) + && (!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) + { + // we don't care about the result of the "what" function. + // we only care that all parsers have it: + boost::spirit::qi::what(p); + + Char const* last = in + size; + return boost::spirit::qi::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) + { + // we don't care about the result of the "what" function. + // we only care that all parsers have it: + boost::spirit::qi::what(p); + + Char const* last = in + size; + return boost::spirit::qi::phrase_parse(in, last, p, s) + && (!full_match || (in == last)); + } + + template <typename Char, typename Parser, typename Attr> + bool test_attr(Char const* in, Parser const& p + , Attr& attr, bool full_match = true) + { + // we don't care about the result of the "what" function. + // we only care that all parsers have it: + boost::spirit::qi::what(p); + + Char const* last = in; + while (*last) + last++; + return boost::spirit::qi::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) + { + // we don't care about the result of the "what" function. + // we only care that all parsers have it: + boost::spirit::qi::what(p); + + Char const* last = in; + while (*last) + last++; + return boost::spirit::qi::phrase_parse(in, last, p, s, attr) + && (!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) + { + // we don't care about the result of the "what" function. + // we only care that all parsers have it: + boost::spirit::qi::what(p); + + Char const* last = in + size; + return boost::spirit::qi::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) + { + // we don't care about the result of the "what" function. + // we only care that all parsers have it: + boost::spirit::qi::what(p); + + Char const* last = in + size; + return boost::spirit::qi::phrase_parse(in, last, p, s, attr) + && (!full_match || (in == last)); + } + + struct printer + { + typedef boost::spirit::utf8_string string; + + void element(string const& tag, string const& value, int depth) const + { + for (int i = 0; i < (depth*4); ++i) // indent to depth + std::cout << ' '; + + std::cout << "tag: " << tag; + if (value != "") + std::cout << ", value: " << value; + std::cout << std::endl; + } + }; + + void print_info(boost::spirit::info const& what) + { + using boost::spirit::basic_info_walker; + + printer pr; + basic_info_walker<printer> walker(pr, what.tag, 0); + boost::apply_visitor(walker, what.value); + } +} + +#endif diff --git a/src/boost/libs/spirit/test/qi/test_attr.hpp b/src/boost/libs/spirit/test/qi/test_attr.hpp new file mode 100644 index 00000000..f55031c5 --- /dev/null +++ b/src/boost/libs/spirit/test/qi/test_attr.hpp @@ -0,0 +1,123 @@ +// Copyright (c) 2001-2011 Hartmut Kaiser +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#if !defined(BOOST_PP_IS_ITERATING) + +#if !defined(BOOST_SPIRIT_QI_TEST_ATTR_APR_23_2009_0605PM) +#define BOOST_SPIRIT_QI_TEST_ATTR_APR_23_2009_0605PM + +#include <cstring> +#include <string> +#include <iterator> +#include <iostream> +#include <typeinfo> + +#include <boost/spirit/include/qi_parse.hpp> +#include <boost/spirit/include/qi_what.hpp> + +#include <boost/preprocessor/cat.hpp> +#include <boost/preprocessor/iterate.hpp> +#include <boost/preprocessor/repetition/repeat.hpp> +#include <boost/preprocessor/repetition/enum_params.hpp> +#include <boost/preprocessor/repetition/enum_binary_params.hpp> + +#define BOOST_PP_FILENAME_1 "test_attr.hpp" +#define BOOST_PP_ITERATION_LIMITS (1, SPIRIT_ARGUMENTS_LIMIT) +#include BOOST_PP_ITERATE() + +#endif + +/////////////////////////////////////////////////////////////////////////////// +// +// Preprocessor vertical repetition code +// +/////////////////////////////////////////////////////////////////////////////// +#else // defined(BOOST_PP_IS_ITERATING) + +#define N BOOST_PP_ITERATION() +#define DEFINE_ATTRIBUTE(z, n, _) \ + BOOST_PP_CAT(A, n) BOOST_PP_CAT(attr, n) = BOOST_PP_CAT(A, n)(); +#define COMPARE_ATTRIBUTE(z, n, _) \ + BOOST_PP_CAT(attr, n) == BOOST_PP_CAT(val, n) && + +namespace spirit_test +{ + /////////////////////////////////////////////////////////////////////////// + template <typename Char, typename Parser + , BOOST_PP_ENUM_PARAMS(N, typename A)> + inline bool test(Char const *in, Parser const& p + , BOOST_PP_ENUM_BINARY_PARAMS(N, A, val)) + { + namespace qi = boost::spirit::qi; + + // we don't care about the result of the "what" function. + // we only care that all parsers have it: + qi::what(p); + + Char const* last = in; + while (*last) + last++; + + BOOST_PP_REPEAT(N, DEFINE_ATTRIBUTE, _); + bool result = qi::parse(in, last, p, BOOST_PP_ENUM_PARAMS(N, attr)); + + return result && BOOST_PP_REPEAT(N, COMPARE_ATTRIBUTE, _) in == last; + } + + /////////////////////////////////////////////////////////////////////////// + template <typename Char, typename Parser, typename Skipper + , BOOST_PP_ENUM_PARAMS(N, typename A)> + inline bool test_skipped(Char const *in, Parser const& p + , Skipper const& skipper, BOOST_PP_ENUM_BINARY_PARAMS(N, A, val)) + { + namespace qi = boost::spirit::qi; + + // we don't care about the result of the "what" function. + // we only care that all parsers have it: + qi::what(p); + + Char const* last = in; + while (*last) + last++; + + BOOST_PP_REPEAT(N, DEFINE_ATTRIBUTE, _); + bool result = qi::phrase_parse(in, last, p, skipper + , BOOST_PP_ENUM_PARAMS(N, attr)); + + return result && BOOST_PP_REPEAT(N, COMPARE_ATTRIBUTE, _) in == last; + } + + /////////////////////////////////////////////////////////////////////////// + template <typename Char, typename Parser, typename Skipper + , BOOST_PP_ENUM_PARAMS(N, typename A)> + inline bool test_postskipped(Char const *in, Parser const& p + , Skipper const& skipper + , BOOST_SCOPED_ENUM(boost::spirit::qi::skip_flag) post_skip + , BOOST_PP_ENUM_BINARY_PARAMS(N, A, val)) + { + namespace qi = boost::spirit::qi; + + // we don't care about the result of the "what" function. + // we only care that all parsers have it: + qi::what(p); + + Char const* last = in; + while (*last) + last++; + + BOOST_PP_REPEAT(N, DEFINE_ATTRIBUTE, _); + bool result = qi::phrase_parse(in, last, p, skipper, post_skip + , BOOST_PP_ENUM_PARAMS(N, attr)); + + return result && BOOST_PP_REPEAT(N, COMPARE_ATTRIBUTE, _) in == last; + } + +} // namespace spirit_test + +#undef COMPARE_ATTRIBUTE +#undef DEFINE_ATTRIBUTE +#undef N + +#endif diff --git a/src/boost/libs/spirit/test/qi/test_manip_attr.hpp b/src/boost/libs/spirit/test/qi/test_manip_attr.hpp new file mode 100644 index 00000000..b0982813 --- /dev/null +++ b/src/boost/libs/spirit/test/qi/test_manip_attr.hpp @@ -0,0 +1,102 @@ +// Copyright (c) 2001-2011 Hartmut Kaiser +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#if !defined(BOOST_PP_IS_ITERATING) + +#if !defined(BOOST_SPIRIT_QI_TEST_MANIP_ATTR_APR_23_2009_0605PM) +#define BOOST_SPIRIT_QI_TEST_MANIP_ATTR_APR_23_2009_0605PM + +#include <cstring> +#include <string> +#include <iterator> +#include <iostream> +#include <typeinfo> + +#include <boost/spirit/include/qi_parse.hpp> +#include <boost/spirit/include/qi_stream.hpp> +#include <boost/spirit/include/qi_match_attr.hpp> + +#include <boost/preprocessor/cat.hpp> +#include <boost/preprocessor/iterate.hpp> +#include <boost/preprocessor/repetition/repeat.hpp> +#include <boost/preprocessor/repetition/enum_params.hpp> +#include <boost/preprocessor/repetition/enum_binary_params.hpp> + +#define BOOST_PP_FILENAME_1 "test_manip_attr.hpp" +#define BOOST_PP_ITERATION_LIMITS (1, SPIRIT_ARGUMENTS_LIMIT) +#include BOOST_PP_ITERATE() + +#endif + +/////////////////////////////////////////////////////////////////////////////// +// +// Preprocessor vertical repetition code +// +/////////////////////////////////////////////////////////////////////////////// +#else // defined(BOOST_PP_IS_ITERATING) + +#define N BOOST_PP_ITERATION() +#define DEFINE_ATTRIBUTE(z, n, _) \ + BOOST_PP_CAT(A, n) BOOST_PP_CAT(attr, n) = BOOST_PP_CAT(A, n)(); +#define COMPARE_ATTRIBUTE(z, n, _) \ + BOOST_PP_CAT(attr, n) == BOOST_PP_CAT(val, n) && + +namespace spirit_test +{ + /////////////////////////////////////////////////////////////////////////// + template <typename Char, typename Parser + , BOOST_PP_ENUM_PARAMS(N, typename A)> + inline bool test(Char const *in, Parser const& p + , BOOST_PP_ENUM_BINARY_PARAMS(N, A, val)) + { + namespace qi = boost::spirit::qi; + + std::basic_stringstream<Char> strm(in); + BOOST_PP_REPEAT(N, DEFINE_ATTRIBUTE, _); + strm >> qi::match(p, BOOST_PP_ENUM_PARAMS(N, attr)); + + return strm.eof() && BOOST_PP_REPEAT(N, COMPARE_ATTRIBUTE, _) true; + } + + /////////////////////////////////////////////////////////////////////////// + template <typename Char, typename Parser, typename Skipper + , BOOST_PP_ENUM_PARAMS(N, typename A)> + inline bool test_skipped(Char const *in, Parser const& p + , Skipper const& skipper, BOOST_PP_ENUM_BINARY_PARAMS(N, A, val)) + { + namespace qi = boost::spirit::qi; + + std::basic_stringstream<Char> strm(in); + BOOST_PP_REPEAT(N, DEFINE_ATTRIBUTE, _); + strm >> qi::phrase_match(p, skipper, BOOST_PP_ENUM_PARAMS(N, attr)); + + return strm.eof() && BOOST_PP_REPEAT(N, COMPARE_ATTRIBUTE, _) true; + } + + /////////////////////////////////////////////////////////////////////////// + template <typename Char, typename Parser, typename Skipper + , BOOST_PP_ENUM_PARAMS(N, typename A)> + inline bool test_postskipped(Char const *in, Parser const& p + , Skipper const& skipper + , BOOST_SCOPED_ENUM(boost::spirit::qi::skip_flag) post_skip + , BOOST_PP_ENUM_BINARY_PARAMS(N, A, val)) + { + namespace qi = boost::spirit::qi; + + std::basic_stringstream<Char> strm(in); + BOOST_PP_REPEAT(N, DEFINE_ATTRIBUTE, _); + strm >> qi::phrase_match(p, skipper, post_skip + , BOOST_PP_ENUM_PARAMS(N, attr)); + + return strm.eof() && BOOST_PP_REPEAT(N, COMPARE_ATTRIBUTE, _) true; + } + +} // namespace spirit_test + +#undef COMPARE_ATTRIBUTE +#undef DEFINE_ATTRIBUTE +#undef N + +#endif diff --git a/src/boost/libs/spirit/test/qi/to_utf8.cpp b/src/boost/libs/spirit/test/qi/to_utf8.cpp new file mode 100644 index 00000000..d0fbdf71 --- /dev/null +++ b/src/boost/libs/spirit/test/qi/to_utf8.cpp @@ -0,0 +1,32 @@ +/*============================================================================= + 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/support/utf8.hpp> + +#if defined(_MSC_VER) && _MSC_VER < 1700 +# pragma warning(disable: 4428) // universal-character-name encountered in source +#endif + +int main() +{ + using boost::spirit::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/qi/tst.cpp b/src/boost/libs/spirit/test/qi/tst.cpp new file mode 100644 index 00000000..05ed7aab --- /dev/null +++ b/src/boost/libs/spirit/test/qi/tst.cpp @@ -0,0 +1,362 @@ +/*============================================================================= + Copyright (c) 2001-2010 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/qi/string/tst.hpp> +#include <boost/spirit/home/qi/string/tst_map.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> + void docheck(TST const& tst, 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); + BOOST_TEST((r != 0) == expected); + 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; + } + + struct no_case_filter + { + template <typename Char> + Char operator()(Char ch) const + { + return static_cast<Char>(std::tolower(ch)); + } + }; + + template <typename TST, typename Char> + void nc_check(TST const& tst, 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, no_case_filter()); + BOOST_TEST((r != 0) == expected); + if (r != 0) + BOOST_TEST((s-first) == N); + if (r) + BOOST_TEST(*r == val); + } +} + +template <typename Lookup, typename WideLookup> +void tests() +{ + { // basic tests + Lookup lookup; + + docheck(lookup, "not-yet-there", false); + docheck(lookup, "", false); + + add(lookup, "apple", 123); + docheck(lookup, "apple", true, 5, 123); // full match + docheck(lookup, "banana", false); // no-match + docheck(lookup, "applexxx", true, 5, 123); // partial match + + add(lookup, "applepie", 456); + docheck(lookup, "applepie", true, 8, 456); // full match + docheck(lookup, "banana", false); // no-match + docheck(lookup, "applepiexxx", true, 8, 456); // partial match + docheck(lookup, "apple", true, 5, 123); // full match + docheck(lookup, "applexxx", true, 5, 123); // partial match + docheck(lookup, "adam", false); // no-match + + add(lookup, "a", 101); + docheck(lookup, "applepie", true, 8, 456); // full match + docheck(lookup, "banana", false); // no-match + docheck(lookup, "applepiexxx", true, 8, 456); // partial match + docheck(lookup, "apple", true, 5, 123); // full match + docheck(lookup, "applexxx", true, 5, 123); // partial match + docheck(lookup, "adam", true, 1, 101); // partial match + } + + { // variation of above + Lookup lookup; + + add(lookup, "applepie", 456); + add(lookup, "apple", 123); + + docheck(lookup, "applepie", true, 8, 456); // full match + docheck(lookup, "banana", false); // no-match + docheck(lookup, "applepiexxx", true, 8, 456); // partial match + docheck(lookup, "apple", true, 5, 123); // full match + docheck(lookup, "applexxx", true, 5, 123); // partial match + } + { // variation of above + Lookup lookup; + + add(lookup, "applepie", 456); + add(lookup, "apple", 123); + + docheck(lookup, "applepie", true, 8, 456); // full match + docheck(lookup, "banana", false); // no-match + docheck(lookup, "applepiexxx", true, 8, 456); // partial match + docheck(lookup, "apple", true, 5, 123); // full match + docheck(lookup, "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, "pineapple", true, 9, 1); + docheck(lookup, "orange", true, 6, 2); + docheck(lookup, "banana", true, 6, 3); + docheck(lookup, "apple", true, 5, 5); + docheck(lookup, "pizza", false); + docheck(lookup, "steak", false); + docheck(lookup, "applepie", true, 8, 4); + docheck(lookup, "bananarama", true, 6, 3); + docheck(lookup, "applet", true, 5, 5); + docheck(lookup, "applepi", true, 5, 5); + docheck(lookup, "appl", false); + + docheck(lookup, "pineapplez", true, 9, 1); + docheck(lookup, "orangez", true, 6, 2); + docheck(lookup, "bananaz", true, 6, 3); + docheck(lookup, "applez", true, 5, 5); + docheck(lookup, "pizzaz", false); + docheck(lookup, "steakz", false); + docheck(lookup, "applepiez", true, 8, 4); + docheck(lookup, "bananaramaz", true, 6, 3); + docheck(lookup, "appletz", true, 5, 5); + docheck(lookup, "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, L"pineapple", true, 9, 1); + docheck(lookup, L"orange", true, 6, 2); + docheck(lookup, L"banana", true, 6, 3); + docheck(lookup, L"apple", true, 5, 5); + docheck(lookup, L"pizza", false); + docheck(lookup, L"steak", false); + docheck(lookup, L"applepie", true, 8, 4); + docheck(lookup, L"bananarama", true, 6, 3); + docheck(lookup, L"applet", true, 5, 5); + docheck(lookup, L"applepi", true, 5, 5); + docheck(lookup, L"appl", false); + + docheck(lookup, L"pineapplez", true, 9, 1); + docheck(lookup, L"orangez", true, 6, 2); + docheck(lookup, L"bananaz", true, 6, 3); + docheck(lookup, L"applez", true, 5, 5); + docheck(lookup, L"pizzaz", false); + docheck(lookup, L"steakz", false); + docheck(lookup, L"applepiez", true, 8, 4); + docheck(lookup, L"bananaramaz", true, 6, 3); + docheck(lookup, L"appletz", true, 5, 5); + docheck(lookup, 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, "pineapple", true, 9, 1); + docheck(lookup, "orange", true, 6, 2); + docheck(lookup, "banana", true, 6, 3); + docheck(lookup, "apple", true, 5, 5); + docheck(lookup, "applepie", true, 8, 4); + docheck(lookup, "bananarama", true, 6, 3); + docheck(lookup, "applet", true, 5, 5); + docheck(lookup, "applepi", true, 5, 5); + docheck(lookup, "appl", false); + + remove(lookup, "banana"); + docheck(lookup, "pineapple", true, 9, 1); + docheck(lookup, "orange", true, 6, 2); + docheck(lookup, "banana", false); + docheck(lookup, "apple", true, 5, 5); + docheck(lookup, "applepie", true, 8, 4); + docheck(lookup, "bananarama", false); + docheck(lookup, "applet", true, 5, 5); + docheck(lookup, "applepi", true, 5, 5); + docheck(lookup, "appl", false); + + remove(lookup, "apple"); + docheck(lookup, "pineapple", true, 9, 1); + docheck(lookup, "orange", true, 6, 2); + docheck(lookup, "apple", false); + docheck(lookup, "applepie", true, 8, 4); + docheck(lookup, "applet", false); + docheck(lookup, "applepi", false); + docheck(lookup, "appl", false); + + remove(lookup, "orange"); + docheck(lookup, "pineapple", true, 9, 1); + docheck(lookup, "orange", false); + docheck(lookup, "applepie", true, 8, 4); + + remove(lookup, "pineapple"); + docheck(lookup, "pineapple", false); + docheck(lookup, "orange", false); + docheck(lookup, "applepie", true, 8, 4); + + remove(lookup, "applepie"); + docheck(lookup, "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, "pineapple", true, 9, 1); + docheck(lookupb, "orange", true, 6, 2); + docheck(lookupb, "banana", true, 6, 3); + docheck(lookupb, "apple", true, 5, 5); + docheck(lookupb, "pizza", false); + docheck(lookupb, "steak", false); + docheck(lookupb, "applepie", true, 8, 4); + docheck(lookupb, "bananarama", true, 6, 3); + docheck(lookupb, "applet", true, 5, 5); + docheck(lookupb, "applepi", true, 5, 5); + docheck(lookupb, "appl", false); + + lookupb.clear(); // clear + docheck(lookupb, "pineapple", false); + docheck(lookupb, "orange", false); + docheck(lookupb, "banana", false); + docheck(lookupb, "apple", false); + docheck(lookupb, "applepie", false); + docheck(lookupb, "bananarama", false); + docheck(lookupb, "applet", false); + docheck(lookupb, "applepi", false); + docheck(lookupb, "appl", false); + + lookupb = lookupa; // assign + docheck(lookupb, "pineapple", true, 9, 1); + docheck(lookupb, "orange", true, 6, 2); + docheck(lookupb, "banana", true, 6, 3); + docheck(lookupb, "apple", true, 5, 5); + docheck(lookupb, "pizza", false); + docheck(lookupb, "steak", false); + docheck(lookupb, "applepie", true, 8, 4); + docheck(lookupb, "bananarama", true, 6, 3); + docheck(lookupb, "applet", true, 5, 5); + docheck(lookupb, "applepi", true, 5, 5); + docheck(lookupb, "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); + + nc_check(lookup, "pineapple", true, 9, 1); + nc_check(lookup, "orange", true, 6, 2); + nc_check(lookup, "banana", true, 6, 3); + nc_check(lookup, "apple", true, 5, 5); + nc_check(lookup, "applepie", true, 8, 4); + + nc_check(lookup, "PINEAPPLE", true, 9, 1); + nc_check(lookup, "ORANGE", true, 6, 2); + nc_check(lookup, "BANANA", true, 6, 3); + nc_check(lookup, "APPLE", true, 5, 5); + nc_check(lookup, "APPLEPIE", true, 8, 4); + + nc_check(lookup, "pineApple", true, 9, 1); + nc_check(lookup, "orangE", true, 6, 2); + nc_check(lookup, "Banana", true, 6, 3); + nc_check(lookup, "aPPLe", true, 5, 5); + nc_check(lookup, "ApplePie", true, 8, 4); + + print(lookup); + } +} + +int main() +{ + using boost::spirit::qi::tst; + using boost::spirit::qi::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/qi/uint.hpp b/src/boost/libs/spirit/test/qi/uint.hpp new file mode 100644 index 00000000..e22cc629 --- /dev/null +++ b/src/boost/libs/spirit/test/qi/uint.hpp @@ -0,0 +1,64 @@ +/*============================================================================= + Copyright (c) 2001-2011 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/include/qi_numeric.hpp> +#include <boost/spirit/include/qi_char.hpp> +#include <boost/spirit/include/qi_action.hpp> +#include <boost/spirit/include/support_argument.hpp> +#include <boost/spirit/include/phoenix_core.hpp> +#include <boost/spirit/include/phoenix_operator.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/qi/uint1.cpp b/src/boost/libs/spirit/test/qi/uint1.cpp new file mode 100644 index 00000000..87c2d415 --- /dev/null +++ b/src/boost/libs/spirit/test/qi/uint1.cpp @@ -0,0 +1,217 @@ +/*============================================================================= + Copyright (c) 2001-2011 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" + +int +main() +{ + using spirit_test::test; + using spirit_test::test_attr; + /////////////////////////////////////////////////////////////////////////// + // unsigned tests + /////////////////////////////////////////////////////////////////////////// + { + using boost::spirit::qi::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::qi::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::qi::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::qi::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::qi::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::qi::parse(first, last, uint_exact4, u) + && first != last && (last-first == 3) && u == 0); + + first = "0001400"; + last = first + std::strlen(first); + BOOST_TEST(boost::spirit::qi::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); + + uint_parser<boost::uint8_t, 10, 1, 3> uchar_3; + unsigned char uc; + BOOST_TEST(test_attr("255", uchar_3, uc, true)); + BOOST_TEST(uc == 255); + BOOST_TEST(!test_attr("256", uchar_3, uc, false)); + BOOST_TEST(!test_attr("257", uchar_3, uc, false)); + } + + /////////////////////////////////////////////////////////////////////////// + // action tests + /////////////////////////////////////////////////////////////////////////// + { + using boost::phoenix::ref; + using boost::spirit::qi::_1; + using boost::spirit::qi::uint_; + using boost::spirit::ascii::space; + int n; + + BOOST_TEST(test("123", uint_[ref(n) = _1])); + BOOST_TEST(n == 123); + BOOST_TEST(test(" 456", uint_[ref(n) = _1], space)); + BOOST_TEST(n == 456); + } + + /////////////////////////////////////////////////////////////////////////// + // Check overflow is parse error + /////////////////////////////////////////////////////////////////////////// + { + boost::spirit::qi::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::qi::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::qi::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::qi::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::qi::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::qi::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::qi::uint_; + using boost::spirit::qi::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/qi/uint2.cpp b/src/boost/libs/spirit/test/qi/uint2.cpp new file mode 100644 index 00000000..51df6980 --- /dev/null +++ b/src/boost/libs/spirit/test/qi/uint2.cpp @@ -0,0 +1,75 @@ +/*============================================================================= + Copyright (c) 2001-2011 Joel de Guzman + 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" + +int +main() +{ + using spirit_test::test; + using spirit_test::test_attr; + + /////////////////////////////////////////////////////////////////////////// + // unsigned integer literal tests + /////////////////////////////////////////////////////////////////////////// + { + using boost::spirit::lit; + unsigned i = 123456; + + BOOST_TEST( test("123456", lit(123456U))); + BOOST_TEST(!test("123456", lit(0U))); + BOOST_TEST( test("123456", lit(i))); + BOOST_TEST(!test("123456", lit(unsigned(i - 1)))); + } + + /////////////////////////////////////////////////////////////////////////// + // unsigned long long literal tests + /////////////////////////////////////////////////////////////////////////// +#ifdef BOOST_HAS_LONG_LONG + { + using boost::spirit::lit; + using boost::ulong_long_type; + ulong_long_type ll = 1234567890123456789ULL; + + BOOST_TEST( test("1234567890123456789", lit(1234567890123456789ULL))); + BOOST_TEST(!test("1234567890123456789", lit(0ULL))); + BOOST_TEST( test("1234567890123456789", lit(ll))); + BOOST_TEST(!test("1234567890123456789", lit(ulong_long_type(ll - 1)))); + } +#endif + + /////////////////////////////////////////////////////////////////////////// + // ushort_ and ulong_ literal tests + /////////////////////////////////////////////////////////////////////////// + { + using boost::spirit::lit; + unsigned short s = 12345; + unsigned long l = 1234567890L; + + BOOST_TEST( test("12345", lit(s))); + BOOST_TEST(!test("12345", lit(s - 1))); + BOOST_TEST( test("1234567890", lit(1234567890UL))); + BOOST_TEST(!test("1234567890", lit(98765321UL))); + BOOST_TEST( test("1234567890", lit(l))); + BOOST_TEST(!test("1234567890", lit(l - 1))); + } + + /////////////////////////////////////////////////////////////////////////// + // literal lazy tests + /////////////////////////////////////////////////////////////////////////// + { + using boost::phoenix::ref; + using boost::spirit::qi::lit; + unsigned n = 123, m = 321; + + BOOST_TEST(test("123", lit(ref(n)))); + BOOST_TEST(!test("123", lit(ref(m)))); + } + + return boost::report_errors(); +} diff --git a/src/boost/libs/spirit/test/qi/uint3.cpp b/src/boost/libs/spirit/test/qi/uint3.cpp new file mode 100644 index 00000000..c7de8529 --- /dev/null +++ b/src/boost/libs/spirit/test/qi/uint3.cpp @@ -0,0 +1,148 @@ +/*============================================================================= + Copyright (c) 2001-2011 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" + +int +main() +{ + using spirit_test::test; + using spirit_test::test_attr; + /////////////////////////////////////////////////////////////////////////// + // parameterized unsigned tests + /////////////////////////////////////////////////////////////////////////// + { + using boost::spirit::qi::uint_; + unsigned u; + + BOOST_TEST(test("123456", uint_(123456))); + BOOST_TEST(!test("123456", uint_(654321))); + BOOST_TEST(test_attr("123456", uint_(123456), u)); + BOOST_TEST(u == 123456); + BOOST_TEST(!test_attr("123456", uint_(654321), u)); + + BOOST_TEST(test(max_unsigned, uint_(UINT_MAX))); + BOOST_TEST(test_attr(max_unsigned, uint_(UINT_MAX), u)); + BOOST_TEST(u == UINT_MAX); + } + + /////////////////////////////////////////////////////////////////////////// + // parameterized binary tests + /////////////////////////////////////////////////////////////////////////// + { + using boost::spirit::qi::bin; + unsigned u; + + BOOST_TEST(test("11111110", bin(0xFE))); + BOOST_TEST(!test("11111110", bin(0xEF))); + BOOST_TEST(test_attr("11111110", bin(0xFE), u)); + BOOST_TEST(u == 0xFE); + BOOST_TEST(!test_attr("11111110", bin(0xEF), u)); + + BOOST_TEST(test(max_binary, bin(UINT_MAX))); + BOOST_TEST(test_attr(max_binary, bin(UINT_MAX), u)); + BOOST_TEST(u == UINT_MAX); + } + + /////////////////////////////////////////////////////////////////////////// + // parameterized octal tests + /////////////////////////////////////////////////////////////////////////// + { + using boost::spirit::qi::oct; + unsigned u; + + BOOST_TEST(test("12545674515", oct(012545674515))); +#if UINT_MAX > 4294967296 // > 32 bits only + BOOST_TEST(!test("12545674515", oct(051547654521))); +#endif + BOOST_TEST(test_attr("12545674515", oct(012545674515), u)); + BOOST_TEST(u == 012545674515); +#if UINT_MAX > 4294967296 // > 32 bits only + BOOST_TEST(!test_attr("12545674515", oct(051547654521), u)); +#endif + + BOOST_TEST(test(max_octal, oct(UINT_MAX))); + BOOST_TEST(test_attr(max_octal, oct(UINT_MAX), u)); + BOOST_TEST(u == UINT_MAX); + } + + /////////////////////////////////////////////////////////////////////////// + // parameterized hex tests + /////////////////////////////////////////////////////////////////////////// + { + using boost::spirit::qi::hex; + unsigned u; + + BOOST_TEST(test("95BC8DF", hex(0x95BC8DF))); + BOOST_TEST(!test("95BC8DF", hex(0xFD8CB59))); + BOOST_TEST(test_attr("95BC8DF", hex(0x95BC8DF), u)); + BOOST_TEST(u == 0x95BC8DF); + BOOST_TEST(!test_attr("95BC8DF", hex(0xFD8CB59), u)); + + BOOST_TEST(test("abcdef12", hex(0xabcdef12))); + BOOST_TEST(!test("abcdef12", hex(0x12fedcba))); + BOOST_TEST(test_attr("abcdef12", hex(0xabcdef12), u)); + BOOST_TEST(u == 0xabcdef12); + BOOST_TEST(!test_attr("abcdef12", hex(0x12fedcba), u)); + + BOOST_TEST(test(max_hex, hex(UINT_MAX))); + BOOST_TEST(test_attr(max_hex, hex(UINT_MAX), u)); + BOOST_TEST(u == UINT_MAX); + } + + /////////////////////////////////////////////////////////////////////////// + // parameterized action tests + /////////////////////////////////////////////////////////////////////////// + { + using boost::phoenix::ref; + using boost::spirit::ascii::space; + using boost::spirit::qi::uint_; + using boost::spirit::qi::_1; + unsigned n, m; + + BOOST_TEST(test("123", uint_(123)[ref(n) = _1])); + BOOST_TEST(n == 123); + BOOST_TEST(!test("123", uint_(321)[ref(n) = _1])); + + BOOST_TEST(test_attr("789", uint_(789)[ref(n) = _1], m)); + BOOST_TEST(n == 789 && m == 789); + BOOST_TEST(!test_attr("789", uint_(987)[ref(n) = _1], m)); + + BOOST_TEST(test(" 456", uint_(456)[ref(n) = _1], space)); + BOOST_TEST(n == 456); + BOOST_TEST(!test(" 456", uint_(654)[ref(n) = _1], space)); + } + + /////////////////////////////////////////////////////////////////////////// + // parameterized lazy tests + /////////////////////////////////////////////////////////////////////////// + { + using boost::phoenix::ref; + using boost::spirit::qi::uint_; + unsigned n = 123, m = 321; + + BOOST_TEST(test("123", uint_(ref(n)))); + BOOST_TEST(!test("123", uint_(ref(m)))); + } + + /////////////////////////////////////////////////////////////////////////// + // parameterized custom uint tests + /////////////////////////////////////////////////////////////////////////// + { + using boost::spirit::qi::uint_; + using boost::spirit::qi::uint_parser; + custom_uint u; + + BOOST_TEST(test_attr("123456", uint_(123456), u)); + uint_parser<custom_uint, 10, 1, 2> uint2; + BOOST_TEST(test_attr("12", uint2(12), u)); + } + + return boost::report_errors(); +} diff --git a/src/boost/libs/spirit/test/qi/uint_radix.cpp b/src/boost/libs/spirit/test/qi/uint_radix.cpp new file mode 100644 index 00000000..6ab7d193 --- /dev/null +++ b/src/boost/libs/spirit/test/qi/uint_radix.cpp @@ -0,0 +1,744 @@ +/*============================================================================= + 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/include/qi_numeric.hpp> +#include <boost/spirit/include/qi_char.hpp> +#include <boost/spirit/include/qi_action.hpp> +#include <boost/spirit/include/support_argument.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::qi::uint_; + using boost::spirit::qi::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/qi/uint_radix.hpp b/src/boost/libs/spirit/test/qi/uint_radix.hpp new file mode 100644 index 00000000..2606877e --- /dev/null +++ b/src/boost/libs/spirit/test/qi/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_QI_UINT4_HPP) +#define BOOST_SPIRIT_TEST_QI_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 diff --git a/src/boost/libs/spirit/test/qi/utree1.cpp b/src/boost/libs/spirit/test/qi/utree1.cpp new file mode 100644 index 00000000..e40bfdb6 --- /dev/null +++ b/src/boost/libs/spirit/test/qi/utree1.cpp @@ -0,0 +1,197 @@ +// Copyright (c) 2001-2011 Hartmut Kaiser +// Copyright (c) 2001-2011 Joel de Guzman +// Copyright (c) 2010 Bryce Lelbach +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#include <boost/config/warning_disable.hpp> +#include <boost/detail/lightweight_test.hpp> + +#include <boost/mpl/print.hpp> +#include <boost/spirit/include/qi.hpp> +#include <boost/spirit/include/support_utree.hpp> + +#include <sstream> + +#include "test.hpp" + +inline bool check(boost::spirit::utree const& val, std::string expected) +{ + std::stringstream s; + s << val; + if (s.str() == expected + " ") + return true; + + std::cerr << "got result: " << s.str() + << ", expected: " << expected << std::endl; + return false; +} + +int main() +{ + using spirit_test::test_attr; + using boost::spirit::utree; + using boost::spirit::utree_type; + using boost::spirit::utf8_string_range_type; + using boost::spirit::utf8_symbol_type; + using boost::spirit::utf8_string_type; + + using boost::spirit::qi::real_parser; + using boost::spirit::qi::strict_real_policies; + using boost::spirit::qi::digit; + using boost::spirit::qi::char_; + using boost::spirit::qi::string; + using boost::spirit::qi::int_; + using boost::spirit::qi::double_; + using boost::spirit::qi::space; + using boost::spirit::qi::space_type; + using boost::spirit::qi::rule; + using boost::spirit::qi::as; + using boost::spirit::qi::lexeme; + + // primitive data types + { + utree ut; + BOOST_TEST(test_attr("x", char_, ut) && + ut.which() == utree_type::string_type && check(ut, "\"x\"")); + ut.clear(); + BOOST_TEST(test_attr("123", int_, ut) && + ut.which() == utree_type::int_type && check(ut, "123")); + ut.clear(); + BOOST_TEST(test_attr("123.45", double_, ut) && + ut.which() == utree_type::double_type && check(ut, "123.45")); + ut.clear(); + + rule<char const*, utf8_string_type()> r1 = lexeme[*char_]; + + BOOST_TEST(test_attr("foo", r1, ut) && + ut.which() == utree_type::string_type && check(ut, "\"foo\"")); + ut.clear(); + + rule<char const*, utf8_symbol_type()> r2 = lexeme[*char_]; + + BOOST_TEST(test_attr("xyz", r2, ut) && + ut.which() == utree_type::symbol_type && check(ut, "xyz")); + } + + // single character parsers + { + utree ut; + + // this rule returns a utree string + rule<char const*, utree()> r1 = char_("abc"); + + // this rule forces a utree list to be returned + rule<char const*, utree::list_type()> r2 = char_("abc"); + + BOOST_TEST(test_attr("a", r1, ut) && + ut.which() == utree_type::string_type && check(ut, "\"a\"")); + ut.clear(); + BOOST_TEST(test_attr("a", r2, ut) && + ut.which() == utree_type::list_type && check(ut, "( \"a\" )")); + } + + // sequences + { + using boost::spirit::qi::as_string; + + utree ut; + BOOST_TEST(test_attr("xy", char_ >> char_, ut) && + ut.which() == utree_type::list_type && check(ut, "( \"x\" \"y\" )")); + ut.clear(); + BOOST_TEST(test_attr("123 456", int_ >> int_, ut, space) && + ut.which() == utree_type::list_type && check(ut, "( 123 456 )")); + ut.clear(); + BOOST_TEST(test_attr("1.23 4.56", double_ >> double_, ut, space) && + ut.which() == utree_type::list_type && check(ut, "( 1.23 4.56 )")); + ut.clear(); + BOOST_TEST(test_attr("1.2ab", double_ >> *char_, ut) && + ut.which() == utree_type::list_type && check(ut, "( 1.2 \"a\" \"b\" )")); + ut.clear(); + BOOST_TEST(test_attr("ab1.2", *~digit >> double_, ut) && + ut.which() == utree_type::list_type && check(ut, "( \"a\" \"b\" 1.2 )")); + + // forces a utree list + rule<char const*, utree::list_type()> r1 = double_; + + ut.clear(); + BOOST_TEST(test_attr("1.2ab", r1 >> *char_, ut) && + ut.which() == utree_type::list_type && check(ut, "( ( 1.2 ) \"a\" \"b\" )")); + ut.clear(); + BOOST_TEST(test_attr("ab1.2", *~digit >> r1, ut) && + ut.which() == utree_type::list_type && check(ut, "( \"a\" \"b\" ( 1.2 ) )")); + ut.clear(); + + // implicitly a utree list, because of sequence attribute rules + rule<char const*, utree()> r2 = int_ >> char_("!") >> double_; + + BOOST_TEST(test_attr("17!3.14", r2, ut) && + ut.which() == utree_type::list_type && check(ut, "( 17 \"!\" 3.14 )")); + ut.clear(); + + rule<char const*, utree()> r3 = double_ >> as_string[string("foo")] >> int_; + + BOOST_TEST(test_attr("0.5foo5", r3, ut) && + ut.which() == utree_type::list_type && check(ut, "( 0.5 \"foo\" 5 )")); + } + + { + utree ut; + + rule<char const*, utree()> r1 = char_; + rule<char const*, utree::list_type()> r2 = double_; + rule<char const*, utree::list_type()> r3 = char_; + + BOOST_TEST(test_attr("a25.5b", r1 >> r2 >> r3, ut)); + BOOST_TEST(ut.which() == utree_type::list_type); + BOOST_TEST(check(ut, "( \"a\" ( 25.5 ) ( \"b\" ) )")); + ut.clear(); + + BOOST_TEST(test_attr("a25.5b", r3 >> r2 >> r1, ut)); + BOOST_TEST(ut.which() == utree_type::list_type); + BOOST_TEST(check(ut, "( ( \"a\" ) ( 25.5 ) \"b\" )")); + ut.clear(); + + BOOST_TEST(test_attr("a25.5b", char_ >> r2 >> r3, ut)); + BOOST_TEST(ut.which() == utree_type::list_type); + BOOST_TEST(check(ut, "( \"a\" ( 25.5 ) ( \"b\" ) )")); + ut.clear(); + + BOOST_TEST(test_attr("a25.5b", r3 >> r2 >> char_, ut)); + BOOST_TEST(ut.which() == utree_type::list_type); + BOOST_TEST(check(ut, "( ( \"a\" ) ( 25.5 ) \"b\" )")); + ut.clear(); + +#if defined(BOOST_CLANG) +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Woverloaded-shift-op-parentheses" +#endif + + BOOST_TEST(test_attr("a25.5b", r1 > r2 >> r3, ut)); + BOOST_TEST(ut.which() == utree_type::list_type); + BOOST_TEST(check(ut, "( \"a\" ( 25.5 ) ( \"b\" ) )")); + ut.clear(); + + BOOST_TEST(test_attr("a25.5b", r3 >> r2 > r1, ut)); + BOOST_TEST(ut.which() == utree_type::list_type); + BOOST_TEST(check(ut, "( ( \"a\" ) ( 25.5 ) \"b\" )")); + ut.clear(); + + BOOST_TEST(test_attr("a25.5b", char_ > r2 >> r3, ut)); + BOOST_TEST(ut.which() == utree_type::list_type); + BOOST_TEST(check(ut, "( \"a\" ( 25.5 ) ( \"b\" ) )")); + ut.clear(); + + BOOST_TEST(test_attr("a25.5b", r3 >> r2 > char_, ut)); + BOOST_TEST(ut.which() == utree_type::list_type); + BOOST_TEST(check(ut, "( ( \"a\" ) ( 25.5 ) \"b\" )")); + +#if defined(BOOST_CLANG) +#pragma clang diagnostic pop +#endif + } + + return boost::report_errors(); +} + diff --git a/src/boost/libs/spirit/test/qi/utree2.cpp b/src/boost/libs/spirit/test/qi/utree2.cpp new file mode 100644 index 00000000..cf8165ed --- /dev/null +++ b/src/boost/libs/spirit/test/qi/utree2.cpp @@ -0,0 +1,164 @@ +// Copyright (c) 2001-2011 Hartmut Kaiser +// Copyright (c) 2001-2011 Joel de Guzman +// Copyright (c) 2010 Bryce Lelbach +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#include <boost/config/warning_disable.hpp> +#include <boost/detail/lightweight_test.hpp> + +#include <boost/spirit/include/qi.hpp> +#include <boost/spirit/include/support_utree.hpp> +#include <boost/type_traits/is_same.hpp> + +#include <sstream> + +#include "test.hpp" + +template <typename Expr, typename Iterator = boost::spirit::unused_type> +struct attribute_of_parser +{ + typedef typename boost::spirit::result_of::compile< + boost::spirit::qi::domain, Expr + >::type parser_expression_type; + + typedef typename boost::spirit::traits::attribute_of< + parser_expression_type, boost::spirit::unused_type, Iterator + >::type type; +}; + +template <typename Expected, typename Expr> +inline bool compare_attribute_type(Expr const&) +{ + typedef typename attribute_of_parser<Expr>::type type; + return boost::is_same<type, Expected>::value; +} + +inline bool check(boost::spirit::utree const& val, std::string expected) +{ + std::stringstream s; + s << val; + if (s.str() == expected + " ") + return true; + + std::cerr << "got result: " << s.str() + << ", expected: " << expected << std::endl; + return false; +} + +int main() +{ + using spirit_test::test_attr; + using boost::spirit::utree; + using boost::spirit::utree_type; + using boost::spirit::utf8_string_range_type; + using boost::spirit::utf8_symbol_type; + using boost::spirit::utf8_string_type; + + using boost::spirit::qi::real_parser; + using boost::spirit::qi::strict_real_policies; + using boost::spirit::qi::digit; + using boost::spirit::qi::char_; + using boost::spirit::qi::string; + using boost::spirit::qi::int_; + using boost::spirit::qi::double_; + using boost::spirit::qi::space; + using boost::spirit::qi::space_type; + using boost::spirit::qi::rule; + using boost::spirit::qi::as; + using boost::spirit::qi::lexeme; + + // kleene star + { + typedef real_parser<double, strict_real_policies<double> > + strict_double_type; + strict_double_type const strict_double = strict_double_type(); + + utree ut; + BOOST_TEST(test_attr("xy", *char_, ut) && + ut.which() == utree_type::list_type && check(ut, "( \"x\" \"y\" )")); + ut.clear(); + BOOST_TEST(test_attr("123 456", *int_, ut, space) && + ut.which() == utree_type::list_type && check(ut, "( 123 456 )")); + ut.clear(); + BOOST_TEST(test_attr("1.23 4.56", *double_, ut, space) && + ut.which() == utree_type::list_type && check(ut, "( 1.23 4.56 )")); + ut.clear(); + + rule<char const*, utree(), space_type> r1; + rule<char const*, utree::list_type(), space_type> r2 = '(' >> *r1 >> ')'; + r1 = strict_double | int_ | ~char_("()") | r2; + + BOOST_TEST(test_attr("(x y)", r1, ut, space) && + ut.which() == utree_type::list_type && check(ut, "( \"x\" \"y\" )")); + ut.clear(); + BOOST_TEST(test_attr("(((123)) 456)", r1, ut, space) && + ut.which() == utree_type::list_type && check(ut, "( ( ( 123 ) ) 456 )")); + ut.clear(); + BOOST_TEST(test_attr("((1.23 4.56))", r1, ut, space) && + ut.which() == utree_type::list_type && check(ut, "( ( 1.23 4.56 ) )")); + ut.clear(); + BOOST_TEST(test_attr("x", r1, ut, space) && + ut.which() == utree_type::string_type && check(ut, "\"x\"")); + ut.clear(); + BOOST_TEST(test_attr("123", r1, ut, space) && + ut.which() == utree_type::int_type && check(ut, "123")); + ut.clear(); + BOOST_TEST(test_attr("123.456", r1, ut, space) && + ut.which() == utree_type::double_type && check(ut, "123.456")); + ut.clear(); + BOOST_TEST(test_attr("()", r1, ut, space) && + ut.which() == utree_type::list_type && + check(ut, "( )")); + ut.clear(); + BOOST_TEST(test_attr("((()))", r1, ut, space) && + ut.which() == utree_type::list_type && + check(ut, "( ( ( ) ) )")); + ut.clear(); + } + + // special attribute transformation for utree in alternatives + { + rule<char const*, utree()> r1; + rule<char const*, utree::list_type()> r2; + + BOOST_TEST(compare_attribute_type<utree>( + r1 | -r1 | *r1 | r2 | -r2 | *r2)); + } + + // lists + { + utree ut; + BOOST_TEST(test_attr("x,y", char_ % ',', ut) && + ut.which() == utree_type::list_type && check(ut, "( \"x\" \"y\" )")); + ut.clear(); + BOOST_TEST(test_attr("123,456", int_ % ',', ut) && + ut.which() == utree_type::list_type && check(ut, "( 123 456 )")); + ut.clear(); + BOOST_TEST(test_attr("1.23,4.56", double_ % ',', ut) && + ut.which() == utree_type::list_type && check(ut, "( 1.23 4.56 )")); + + rule<char const*, std::vector<char>()> r1 = char_ % ','; + ut.clear(); + BOOST_TEST(test_attr("x,y", r1, ut) && + ut.which() == utree_type::list_type && check(ut, "( \"x\" \"y\" )")); + + rule<char const*, std::vector<int>()> r2 = int_ % ','; + ut.clear(); + BOOST_TEST(test_attr("123,456", r2, ut) && + ut.which() == utree_type::list_type && check(ut, "( 123 456 )")); + + rule<char const*, std::vector<double>()> r3 = double_ % ','; + ut.clear(); + BOOST_TEST(test_attr("1.23,4.56", r3, ut) && + ut.which() == utree_type::list_type && check(ut, "( 1.23 4.56 )")); + + rule<char const*, utree()> r4 = double_ % ','; + ut.clear(); + BOOST_TEST(test_attr("1.23,4.56", r4, ut) && + ut.which() == utree_type::list_type && check(ut, "( 1.23 4.56 )")); + } + + return boost::report_errors(); +} diff --git a/src/boost/libs/spirit/test/qi/utree3.cpp b/src/boost/libs/spirit/test/qi/utree3.cpp new file mode 100644 index 00000000..00722657 --- /dev/null +++ b/src/boost/libs/spirit/test/qi/utree3.cpp @@ -0,0 +1,197 @@ +// Copyright (c) 2001-2011 Hartmut Kaiser +// Copyright (c) 2001-2011 Joel de Guzman +// Copyright (c) 2010 Bryce Lelbach +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#include <boost/config/warning_disable.hpp> +#include <boost/detail/lightweight_test.hpp> + +#include <boost/spirit/include/qi.hpp> +#include <boost/spirit/include/support_utree.hpp> +#include <boost/mpl/print.hpp> + +#include <sstream> + +#include "test.hpp" + +inline bool check(boost::spirit::utree const& val, std::string expected) +{ + std::stringstream s; + s << val; + if (s.str() == expected + " ") + return true; + + std::cerr << "got result: " << s.str() + << ", expected: " << expected << std::endl; + return false; +} + +int main() +{ + using spirit_test::test_attr; + using boost::spirit::utree; + using boost::spirit::utree_type; + using boost::spirit::utf8_string_range_type; + using boost::spirit::utf8_symbol_type; + using boost::spirit::utf8_string_type; + + using boost::spirit::qi::real_parser; + using boost::spirit::qi::strict_real_policies; + using boost::spirit::qi::digit; + using boost::spirit::qi::char_; + using boost::spirit::qi::string; + using boost::spirit::qi::int_; + using boost::spirit::qi::double_; + using boost::spirit::qi::space; + using boost::spirit::qi::space_type; + using boost::spirit::qi::rule; + using boost::spirit::qi::as; + using boost::spirit::qi::lexeme; + + // alternatives + { + typedef real_parser<double, strict_real_policies<double> > + strict_double_type; + strict_double_type const strict_double = strict_double_type(); + + utree ut; + BOOST_TEST(test_attr("10", strict_double | int_, ut) && + ut.which() == utree_type::int_type && check(ut, "10")); + ut.clear(); + BOOST_TEST(test_attr("10.2", strict_double | int_, ut) && + ut.which() == utree_type::double_type && check(ut, "10.2")); + + rule<char const*, boost::variant<int, double>()> r1 = strict_double | int_; + ut.clear(); + BOOST_TEST(test_attr("10", r1, ut) && + ut.which() == utree_type::int_type && check(ut, "10")); + ut.clear(); + BOOST_TEST(test_attr("10.2", r1, ut) && + ut.which() == utree_type::double_type && check(ut, "10.2")); + + rule<char const*, utree()> r2 = strict_double | int_; + ut.clear(); + BOOST_TEST(test_attr("10", r2, ut) && + ut.which() == utree_type::int_type && check(ut, "10")); + ut.clear(); + BOOST_TEST(test_attr("10.2", r2, ut) && + ut.which() == utree_type::double_type && check(ut, "10.2")); + + rule<char const*, utree::list_type()> r3 = strict_double | int_; + ut.clear(); + BOOST_TEST(test_attr("10", r3, ut) && + ut.which() == utree_type::list_type && check(ut, "( 10 )")); + ut.clear(); + BOOST_TEST(test_attr("10.2", r3, ut) && + ut.which() == utree_type::list_type && check(ut, "( 10.2 )")); + } + + // optionals + { + utree ut; + + BOOST_TEST(test_attr("x", -char_, ut)); + BOOST_TEST(ut.which() == utree_type::string_type); + BOOST_TEST(check(ut, "\"x\"")); + ut.clear(); + + BOOST_TEST(test_attr("", -char_, ut)); + BOOST_TEST(ut.which() == utree_type::invalid_type); + BOOST_TEST(check(ut, "<invalid>")); + ut.clear(); + + BOOST_TEST(test_attr("1x", int_ >> -char_, ut)); + BOOST_TEST(ut.which() == utree_type::list_type); + BOOST_TEST(check(ut, "( 1 \"x\" )")); + ut.clear(); + + BOOST_TEST(test_attr("1", int_ >> -char_, ut)); + BOOST_TEST(ut.which() == utree_type::list_type); + BOOST_TEST(check(ut, "( 1 )")); + ut.clear(); + + BOOST_TEST(test_attr("1x", -int_ >> char_, ut)); + BOOST_TEST(ut.which() == utree_type::list_type); + BOOST_TEST(check(ut, "( 1 \"x\" )")); + ut.clear(); + + BOOST_TEST(test_attr("x", -int_ >> char_, ut)); + BOOST_TEST(ut.which() == utree_type::list_type); + BOOST_TEST(check(ut, "( \"x\" )")); + ut.clear(); + + rule<char const*, utree::list_type()> r1 = int_ >> -char_; + + BOOST_TEST(test_attr("1x", r1, ut)); + BOOST_TEST(ut.which() == utree_type::list_type); + BOOST_TEST(check(ut, "( 1 \"x\" )")); + ut.clear(); + + BOOST_TEST(test_attr("1", r1, ut)); + BOOST_TEST(ut.which() == utree_type::list_type); + BOOST_TEST(check(ut, "( 1 )")); + ut.clear(); + + rule<char const*, utree::list_type()> r2 = -int_ >> char_; + + BOOST_TEST(test_attr("1x", r2, ut)); + BOOST_TEST(ut.which() == utree_type::list_type); + BOOST_TEST(check(ut, "( 1 \"x\" )")); + ut.clear(); + + BOOST_TEST(test_attr("x", r2, ut)); + BOOST_TEST(ut.which() == utree_type::list_type); + BOOST_TEST(check(ut, "( \"x\" )")); + ut.clear(); + + rule<char const*, utree()> r3 = int_; + + BOOST_TEST(test_attr("1", -r3, ut)); + BOOST_TEST(ut.which() == utree_type::int_type); + BOOST_TEST(check(ut, "1")); + ut.clear(); + + BOOST_TEST(test_attr("", -r3, ut)); + BOOST_TEST(ut.which() == utree_type::invalid_type); + BOOST_TEST(check(ut, "<invalid>")); + ut.clear(); + } + + // as_string + { + using boost::spirit::qi::as_string; + + utree ut; + BOOST_TEST(test_attr("xy", as_string[char_ >> char_], ut) && + ut.which() == utree_type::string_type && check(ut, "\"xy\"")); + ut.clear(); + + BOOST_TEST(test_attr("ab1.2", as_string[*~digit] >> double_, ut) && + ut.which() == utree_type::list_type && check(ut, "( \"ab\" 1.2 )")); + ut.clear(); + + BOOST_TEST(test_attr("xy", as_string[*char_], ut) && + ut.which() == utree_type::string_type && check(ut, "\"xy\"")); + ut.clear(); + + BOOST_TEST(test_attr("x,y", as_string[char_ >> ',' >> char_], ut) && + ut.which() == utree_type::string_type && check(ut, "\"xy\"")); + ut.clear(); + + BOOST_TEST(test_attr("x,y", char_ >> ',' >> char_, ut) && + ut.which() == utree_type::list_type && check(ut, "( \"x\" \"y\" )")); + ut.clear(); + + BOOST_TEST(test_attr("a,b1.2", as_string[~digit % ','] >> double_, ut) && + ut.which() == utree_type::list_type && check(ut, "( \"ab\" 1.2 )")); + ut.clear(); + + BOOST_TEST(test_attr("a,b1.2", ~digit % ',' >> double_, ut) && + ut.which() == utree_type::list_type && check(ut, "( \"a\" \"b\" 1.2 )")); + ut.clear(); + } + + return boost::report_errors(); +} diff --git a/src/boost/libs/spirit/test/qi/utree4.cpp b/src/boost/libs/spirit/test/qi/utree4.cpp new file mode 100644 index 00000000..19698c97 --- /dev/null +++ b/src/boost/libs/spirit/test/qi/utree4.cpp @@ -0,0 +1,184 @@ +// Copyright (c) 2001-2011 Hartmut Kaiser +// Copyright (c) 2001-2011 Joel de Guzman +// Copyright (c) 2010 Bryce Lelbach +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#include <boost/config/warning_disable.hpp> +#include <boost/detail/lightweight_test.hpp> + +#include <boost/spirit/include/qi.hpp> +#include <boost/spirit/include/support_utree.hpp> +#include <boost/mpl/print.hpp> + +#include <sstream> + +#include "test.hpp" + +inline bool check(boost::spirit::utree const& val, std::string expected) +{ + std::stringstream s; + s << val; + if (s.str() == expected + " ") + return true; + + std::cerr << "got result: " << s.str() + << ", expected: " << expected << std::endl; + return false; +} + +int main() +{ + using spirit_test::test_attr; + using boost::spirit::utree; + using boost::spirit::utree_type; + using boost::spirit::utf8_string_range_type; + using boost::spirit::utf8_symbol_type; + using boost::spirit::utf8_string_type; + + using boost::spirit::qi::real_parser; + using boost::spirit::qi::strict_real_policies; + using boost::spirit::qi::digit; + using boost::spirit::qi::char_; + using boost::spirit::qi::string; + using boost::spirit::qi::int_; + using boost::spirit::qi::double_; + using boost::spirit::qi::space; + using boost::spirit::qi::space_type; + using boost::spirit::qi::rule; + using boost::spirit::qi::as; + using boost::spirit::qi::lexeme; + + // as + { + typedef as<std::string> as_string_type; + as_string_type const as_string = as_string_type(); + + typedef as<utf8_symbol_type> as_symbol_type; + as_symbol_type const as_symbol = as_symbol_type(); + + utree ut; + BOOST_TEST(test_attr("xy", as_string[char_ >> char_], ut) && + ut.which() == utree_type::string_type && check(ut, "\"xy\"")); + ut.clear(); + + BOOST_TEST(test_attr("ab1.2", as_string[*~digit] >> double_, ut) && + ut.which() == utree_type::list_type && check(ut, "( \"ab\" 1.2 )")); + ut.clear(); + + BOOST_TEST(test_attr("xy", as_string[*char_], ut) && + ut.which() == utree_type::string_type && check(ut, "\"xy\"")); + ut.clear(); + + BOOST_TEST(test_attr("x,y", as_string[char_ >> ',' >> char_], ut) && + ut.which() == utree_type::string_type && check(ut, "\"xy\"")); + ut.clear(); + + BOOST_TEST(test_attr("x,y", char_ >> ',' >> char_, ut) && + ut.which() == utree_type::list_type && check(ut, "( \"x\" \"y\" )")); + ut.clear(); + + BOOST_TEST(test_attr("a,b1.2", as_string[~digit % ','] >> double_, ut) && + ut.which() == utree_type::list_type && check(ut, "( \"ab\" 1.2 )")); + ut.clear(); + + BOOST_TEST(test_attr("a,b1.2", ~digit % ',' >> double_, ut) && + ut.which() == utree_type::list_type && check(ut, "( \"a\" \"b\" 1.2 )")); + ut.clear(); + + BOOST_TEST(test_attr("xy", as_symbol[char_ >> char_], ut) && + ut.which() == utree_type::symbol_type && check(ut, "xy")); + ut.clear(); + + BOOST_TEST(test_attr("ab1.2", as_symbol[*~digit] >> double_, ut) && + ut.which() == utree_type::list_type && check(ut, "( ab 1.2 )")); + ut.clear(); + + BOOST_TEST(test_attr("xy", as_symbol[*char_], ut) && + ut.which() == utree_type::symbol_type && check(ut, "xy")); + ut.clear(); + + BOOST_TEST(test_attr("x,y", as_symbol[char_ >> ',' >> char_], ut) && + ut.which() == utree_type::symbol_type && check(ut, "xy")); + ut.clear(); + BOOST_TEST(test_attr("a,b1.2", as_symbol[~digit % ','] >> double_, ut) && + ut.which() == utree_type::list_type && check(ut, "( ab 1.2 )")); + ut.clear(); + } + + // subtrees + { + // -(+int_) is forcing a subtree + utree ut; + BOOST_TEST(test_attr("1 2", int_ >> ' ' >> -(+int_), ut) && + ut.which() == utree_type::list_type && check(ut, "( 1 2 )")); + ut.clear(); + + BOOST_TEST(test_attr("1 2", int_ >> ' ' >> *int_, ut) && + ut.which() == utree_type::list_type && check(ut, "( 1 2 )")); + ut.clear(); + + rule<char const*, std::vector<int>()> r1 = int_ % ','; + BOOST_TEST(test_attr("1 2,3", int_ >> ' ' >> r1, ut) && + ut.which() == utree_type::list_type && check(ut, "( 1 2 3 )")); + ut.clear(); + + BOOST_TEST(test_attr("1,2 2,3", r1 >> ' ' >> r1, ut) && + ut.which() == utree_type::list_type && check(ut, "( 1 2 2 3 )")); + ut.clear(); + + rule<char const*, utree()> r2 = int_ % ','; + BOOST_TEST(test_attr("1 2,3", int_ >> ' ' >> r2, ut) && + ut.which() == utree_type::list_type && check(ut, "( 1 2 3 )")); + ut.clear(); + + BOOST_TEST(test_attr("1,2 2,3", r2 >> ' ' >> r2, ut) && + ut.which() == utree_type::list_type && check(ut, "( 1 2 2 3 )")); + ut.clear(); + + rule<char const*, utree::list_type()> r3 = int_ % ','; + BOOST_TEST(test_attr("1 2,3", int_ >> ' ' >> r3, ut) && + ut.which() == utree_type::list_type && check(ut, "( 1 ( 2 3 ) )")); + ut.clear(); + + BOOST_TEST(test_attr("1,2 2,3", r3 >> ' ' >> r3, ut) && + ut.which() == utree_type::list_type && check(ut, "( ( 1 2 ) ( 2 3 ) )")); + ut.clear(); + + rule<char const*, utree()> r4 = int_; + BOOST_TEST(test_attr("1 1", int_ >> ' ' >> -r4, ut) && + ut.which() == utree_type::list_type && check(ut, "( 1 1 )")); + ut.clear(); + + BOOST_TEST(test_attr("1 ", int_ >> ' ' >> -r4, ut) && + ut.which() == utree_type::list_type && check(ut, "( 1 )")); + ut.clear(); + + rule<char const*, utree::list_type()> r5 = -r4; + BOOST_TEST(test_attr("1", r5, ut) && + ut.which() == utree_type::list_type && check(ut, "( 1 )")); + ut.clear(); + + BOOST_TEST(test_attr("", r5, ut) && + ut.which() == utree_type::list_type && check(ut, "( )")); + ut.clear(); + + BOOST_TEST(test_attr("1 1", r5 >> ' ' >> r5, ut) && + ut.which() == utree_type::list_type && check(ut, "( ( 1 ) ( 1 ) )")); + ut.clear(); + + rule<char const*, utree::list_type()> r6 = int_; + rule<char const*, utree()> r7 = -r6; + BOOST_TEST(test_attr("1", r7, ut) && + ut.which() == utree_type::list_type && check(ut, "( 1 )")); + ut.clear(); + + rule<char const*, utree::list_type()> r8 = r6 >> ' ' >> r6; + BOOST_TEST(test_attr("1 1", r8, ut) && + ut.which() == utree_type::list_type && check(ut, "( ( 1 ) ( 1 ) )")); + ut.clear(); + } + + return boost::report_errors(); +} |