diff options
Diffstat (limited to 'src/boost/libs/spirit/test')
323 files changed, 38090 insertions, 0 deletions
diff --git a/src/boost/libs/spirit/test/Jamfile b/src/boost/libs/spirit/test/Jamfile new file mode 100644 index 00000000..451215a4 --- /dev/null +++ b/src/boost/libs/spirit/test/Jamfile @@ -0,0 +1,15 @@ +#============================================================================== +# Copyright (c) 2001-2011 Joel de Guzman +# Copyright (c) 2001-2012 Hartmut Kaiser +# Copyright (c) 2011 Bryce Lelbach +# +# Use, modification and distribution is subject to the Boost Software +# License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +# http://www.boost.org/LICENSE_1_0.txt) +#============================================================================== + +build-project karma ; +build-project lex ; +build-project qi ; +build-project support ; +build-project x3 ; diff --git a/src/boost/libs/spirit/test/karma/Jamfile b/src/boost/libs/spirit/test/karma/Jamfile new file mode 100644 index 00000000..953bdb02 --- /dev/null +++ b/src/boost/libs/spirit/test/karma/Jamfile @@ -0,0 +1,137 @@ +#============================================================================== +# 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-karma + : requirements + <include>. + <c++-template-depth>512 + ; + +############################################################################### + +cpp-pch pch : pch.hpp : : : <include>. <toolset>msvc:<cxxflags>"/FIpch.hpp" ; + +explicit pch ; + +############################################################################### + +local subproject-name = karma ; + +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 ; +run alternative1.cpp ; +run alternative2.cpp ; +run and_predicate.cpp ; +run attribute.cpp ; +run auto1.cpp ; +run auto2.cpp ; +run auto3.cpp ; +run binary1.cpp ; +run binary2.cpp ; +run binary3.cpp ; +run bool.cpp ; +run buffer.cpp ; +run case_handling1.cpp ; +run case_handling2.cpp ; +run case_handling3.cpp ; +run center_alignment.cpp ; +run char1.cpp ; +run char2.cpp ; +run char3.cpp ; +run char_class.cpp ; +run columns.cpp ; +run debug.cpp : : : <pch>off ; +run delimiter.cpp ; +run duplicate.cpp ; +run encoding.cpp ; +run eol.cpp ; +run eps.cpp ; +run format_manip.cpp ; +run format_manip_attr.cpp ; +run format_pointer_container.cpp ; +run generate_attr.cpp ; +run grammar.cpp ; +run int1.cpp ; +run int2.cpp ; +run int3.cpp ; +run kleene.cpp ; +run lazy.cpp ; +run left_alignment.cpp ; +run list.cpp ; +run lit.cpp ; +run maxwidth.cpp ; +run not_predicate.cpp ; +run omit.cpp ; +run optional.cpp ; +run pattern1.cpp ; +run pattern2.cpp ; +run pattern3.cpp ; +run pattern4.cpp ; +run plus.cpp ; +run real1.cpp ; +run real2.cpp ; +run real3.cpp ; +run repeat1.cpp ; +run repeat2.cpp ; +run right_alignment.cpp ; +run sequence1.cpp ; +run sequence2.cpp ; +run stream.cpp ; +run symbols1.cpp ; +run symbols2.cpp ; +run symbols3.cpp ; +run tricky_alignment.cpp ; +run uint_radix.cpp ; +run utree1.cpp ; +run utree2.cpp ; +run utree3.cpp ; +run wstream.cpp ; + +compile regression_const_real_policies.cpp ; +run regression_adapt_adt.cpp ; +run regression_center_alignment.cpp ; +run regression_container_variant_sequence.cpp ; +run regression_iterator.cpp ; +run regression_optional_double.cpp ; +run regression_real_0.cpp ; +run regression_real_policy_sign.cpp ; +run regression_real_scientific.cpp ; +run regression_semantic_action_attribute.cpp ; +run regression_unicode_char.cpp : : : <pch>off ; diff --git a/src/boost/libs/spirit/test/karma/actions.cpp b/src/boost/libs/spirit/test/karma/actions.cpp new file mode 100644 index 00000000..2f3623e5 --- /dev/null +++ b/src/boost/libs/spirit/test/karma/actions.cpp @@ -0,0 +1,137 @@ +/*============================================================================= + 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/karma_char.hpp> +#include <boost/spirit/include/karma_numeric.hpp> +#include <boost/spirit/include/karma_action.hpp> +#include <boost/spirit/include/karma_generate.hpp> +#include <boost/spirit/include/karma_operator.hpp> +#include <boost/bind.hpp> +#include <boost/lambda/lambda.hpp> + +#include <sstream> +#include "test.hpp" + +using namespace spirit_test; +using boost::spirit::unused_type; + +void read1(int& i) +{ + i = 42; +} + +void read2(int& i, unused_type) +{ + i = 42; +} + +void read3(int& i, unused_type, bool&) +{ + i = 42; +} + +void read3_fail(int& i, unused_type, bool& pass) +{ + i = 42; + pass = false; +} + +struct read_action +{ + void operator()(int& i, unused_type, unused_type) const + { + i = 42; + } +}; + +/////////////////////////////////////////////////////////////////////////////// +int main() +{ + using boost::spirit::karma::int_; + { + BOOST_TEST(test("42", int_[&read1])); + BOOST_TEST(test_delimited("42 ", int_[&read1], ' ')); + BOOST_TEST(test("42", int_[&read2])); + BOOST_TEST(test_delimited("42 ", int_[&read2], ' ')); + BOOST_TEST(test("42", int_[&read3])); + BOOST_TEST(test_delimited("42 ", int_[&read3], ' ')); + BOOST_TEST(!test("42", int_[&read3_fail])); + BOOST_TEST(!test_delimited("42 ", int_[&read3_fail], ' ')); + } + + { + BOOST_TEST(test("42", int_[read_action()])); + BOOST_TEST(test_delimited("42 ", int_[read_action()], ' ')); + } + + { + BOOST_TEST(test("42", int_[boost::bind(&read1, _1)])); + BOOST_TEST(test_delimited("42 ", int_[boost::bind(&read1, _1)], ' ')); + BOOST_TEST(test("42", int_[boost::bind(&read2, _1, _2)])); + BOOST_TEST(test_delimited("42 ", int_[boost::bind(&read2, _1, _2)], ' ')); + BOOST_TEST(test("42", int_[boost::bind(&read3, _1, _2, _3)])); + BOOST_TEST(test_delimited("42 ", int_[boost::bind(&read3, _1, _2, _3)], ' ')); + } + + { + namespace lambda = boost::lambda; + { + std::stringstream strm("42"); + BOOST_TEST(test("42", int_[strm >> lambda::_1])); + } + { + std::stringstream strm("42"); + BOOST_TEST(test_delimited("42 ", int_[strm >> lambda::_1], ' ')); + } + } + + { + BOOST_TEST(test("{42}", '{' << int_[&read1] << '}')); + BOOST_TEST(test_delimited("{ 42 } ", '{' << int_[&read1] << '}', ' ')); + BOOST_TEST(test("{42}", '{' << int_[&read2] << '}')); + BOOST_TEST(test_delimited("{ 42 } ", '{' << int_[&read2] << '}', ' ')); + BOOST_TEST(test("{42}", '{' << int_[&read3] << '}')); + BOOST_TEST(test_delimited("{ 42 } ", '{' << int_[&read3] << '}', ' ')); + } + + { + BOOST_TEST(test("{42}", '{' << int_[read_action()] << '}')); + BOOST_TEST(test_delimited("{ 42 } ", '{' << int_[read_action()] << '}', ' ')); + } + + { + BOOST_TEST(test("{42}", '{' << int_[boost::bind(&read1, _1)] << '}')); + BOOST_TEST(test_delimited("{ 42 } ", + '{' << int_[boost::bind(&read1, _1)] << '}', ' ')); + BOOST_TEST(test("{42}", '{' << int_[boost::bind(&read2, _1, _2)] << '}')); + BOOST_TEST(test_delimited("{ 42 } ", + '{' << int_[boost::bind(&read2, _1, _2)] << '}', ' ')); + BOOST_TEST(test("{42}", '{' << int_[boost::bind(&read3, _1, _2, _3)] << '}')); + BOOST_TEST(test_delimited("{ 42 } ", + '{' << int_[boost::bind(&read3, _1, _2, _3)] << '}', ' ')); + } + + { + namespace lambda = boost::lambda; + { + std::stringstream strm("42"); + BOOST_TEST(test("{42}", '{' << int_[strm >> lambda::_1] << '}')); + } + { + std::stringstream strm("42"); + BOOST_TEST(test_delimited("{ 42 } ", + '{' << int_[strm >> lambda::_1] << '}', ' ')); + } + } + + return boost::report_errors(); +} + diff --git a/src/boost/libs/spirit/test/karma/alternative1.cpp b/src/boost/libs/spirit/test/karma/alternative1.cpp new file mode 100644 index 00000000..461e4b06 --- /dev/null +++ b/src/boost/libs/spirit/test/karma/alternative1.cpp @@ -0,0 +1,162 @@ +// 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/karma_auxiliary.hpp> +#include <boost/spirit/include/karma_char.hpp> +#include <boost/spirit/include/karma_string.hpp> +#include <boost/spirit/include/karma_numeric.hpp> +#include <boost/spirit/include/karma_generate.hpp> +#include <boost/spirit/include/karma_operator.hpp> +#include <boost/spirit/include/karma_directive.hpp> +#include <boost/spirit/include/karma_nonterminal.hpp> +#include <boost/spirit/include/karma_auxiliary.hpp> + +#include "test.hpp" + +using namespace spirit_test; + +/////////////////////////////////////////////////////////////////////////////// +int +main() +{ + using namespace boost; + using namespace boost::spirit; + using namespace boost::spirit::ascii; + + { + BOOST_TEST(test("x", char_('x') | char_('i'))); + BOOST_TEST(test("xi", char_('x') << char_('i') | char_('i'))); + BOOST_TEST(test("i", char_('i') | char_('x') << char_('i'))); + + BOOST_TEST(test("x", buffer[char_('x')] | char_('i'))); + + variant<int, char> v (10); + BOOST_TEST(test("10", char_ | int_, v)); + BOOST_TEST(test("10", int_ | char_, v)); + BOOST_TEST(test("a", lit('a') | char_ | int_, v)); + BOOST_TEST(test("a", char_ | lit('a') | int_, v)); + BOOST_TEST(test("10", int_ | lit('a') | char_, v)); + + v = 'c'; + BOOST_TEST(test("c", char_ | int_, v)); + BOOST_TEST(test("a", lit('a') | char_ | int_, v)); + BOOST_TEST(test("c", char_ | lit('a') | int_, v)); + BOOST_TEST(test("a", int_ | lit('a') | char_, v)); + BOOST_TEST(test("c", int_ | char_ | lit('a'), v)); + } + + // testing for alignment/truncation problems on little endian systems + // (big endian systems will fail one of the other tests below) + { + // test optional attribute + optional<variant<int, char> > v; + BOOST_TEST(!test("", char_ | int_, v)); + BOOST_TEST(!test("", int_ | char_, v)); + BOOST_TEST(test("a", lit('a') | char_ | int_, v)); + BOOST_TEST(test("a", char_ | lit('a') | int_, v)); + BOOST_TEST(test("a", int_ | lit('a') | char_, v)); + + v = 10; + BOOST_TEST(test("10", char_ | int_, v)); + BOOST_TEST(test("10", int_ | char_, v)); + BOOST_TEST(test("a", lit('a') | char_ | int_, v)); + BOOST_TEST(test("a", char_ | lit('a') | int_, v)); + BOOST_TEST(test("10", int_ | lit('a') | char_, v)); + + v = 'c'; + BOOST_TEST(test("c", char_ | int_, v)); + BOOST_TEST(test("a", lit('a') | char_ | int_, v)); + BOOST_TEST(test("c", char_ | lit('a') | int_, v)); + BOOST_TEST(test("a", int_ | lit('a') | char_, v)); + BOOST_TEST(test("c", int_ | char_ | lit('a'), v)); + } + + { + // more tests for optional attribute + optional<int> o; + BOOST_TEST(test("a", lit('a') | int_, o)); + BOOST_TEST(test("a", int_ | lit('a'), o)); + + o = 10; + BOOST_TEST(test("a", lit('a') | int_, o)); + BOOST_TEST(test("10", int_ | lit('a'), o)); + } + + { + int i = 10; + BOOST_TEST(test("a", lit('a') | int_, i)); + BOOST_TEST(test("10", int_ | lit('a'), i)); + } + + { + optional<std::string> o; + BOOST_TEST(test("xyzzy", ("(" << string << ")") | lit("xyzzy"), o)); + + o = "plugh"; + BOOST_TEST(test("(plugh)", ("(" << string << ")") | lit("xyzzy"), o)); + } + + { + BOOST_TEST(test("abc", string | int_, std::string("abc"))); + BOOST_TEST(test("1234", string | int_, 1234)); + BOOST_TEST(test("abc", int_ | string, std::string("abc"))); + BOOST_TEST(test("1234", int_ | string, 1234)); + } + + { + // testing for alignment/truncation problems on little endian systems + // (big endian systems will fail one of the other tests below) + std::basic_string<wchar_t> generated; + std::back_insert_iterator<std::basic_string<wchar_t> > outit(generated); + boost::variant<int, char> v(10); + bool result = karma::generate_delimited(outit + , karma::int_ | karma::char_, karma::char_(' '), v); + BOOST_TEST(result && generated == L"10 "); + } + + { + boost::optional<int> v; + BOOST_TEST(test("error", int_ | "error" << omit[-int_], v)); + BOOST_TEST(!test("error", int_ | "error" << omit[int_], v)); + BOOST_TEST(test("error", int_ | "error" << skip[int_], v)); + v = 1; + BOOST_TEST(test("1", int_ | "error" << omit[-int_], v)); + BOOST_TEST(test("1", int_ | "error" << omit[int_], v)); + BOOST_TEST(test("1", int_ | "error" << skip[int_], v)); + } + + { + typedef spirit_test::output_iterator<char>::type outiter_type; + namespace karma = boost::spirit::karma; + + karma::rule<outiter_type, int()> r = int_; + std::vector<int> v; + BOOST_TEST(test("", '>' << r % ',' | karma::eps, v)); + + v.push_back(1); + v.push_back(2); + v.push_back(3); + v.push_back(4); + BOOST_TEST(test(">1,2,3,4", '>' << r % ',' | karma::eps, v)); + } + + { + typedef spirit_test::output_iterator<char>::type outiter_type; + namespace karma = boost::spirit::karma; + + karma::rule<outiter_type, boost::optional<int>()> r = int_; + boost::optional<int> o; + BOOST_TEST(test("error", r | "error", o)); + + o = 10; + BOOST_TEST(test("10", r | "error", o)); + } + + return boost::report_errors(); +} + diff --git a/src/boost/libs/spirit/test/karma/alternative2.cpp b/src/boost/libs/spirit/test/karma/alternative2.cpp new file mode 100644 index 00000000..7e90b165 --- /dev/null +++ b/src/boost/libs/spirit/test/karma/alternative2.cpp @@ -0,0 +1,141 @@ +// 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/karma_auxiliary.hpp> +#include <boost/spirit/include/karma_char.hpp> +#include <boost/spirit/include/karma_string.hpp> +#include <boost/spirit/include/karma_numeric.hpp> +#include <boost/spirit/include/karma_generate.hpp> +#include <boost/spirit/include/karma_operator.hpp> +#include <boost/spirit/include/karma_directive.hpp> +#include <boost/spirit/include/karma_nonterminal.hpp> +#include <boost/spirit/include/karma_auxiliary.hpp> + +#include "test.hpp" + +using namespace spirit_test; + +/////////////////////////////////////////////////////////////////////////////// +int +main() +{ + using namespace boost; + using namespace boost::spirit; + using namespace boost::spirit::ascii; + + { + // test if alternatives with all components having unused + // attribute generate first alternative + fusion::vector<char, char> v('a', 'b'); + BOOST_TEST(test("axb", char_ << (lit('x') | lit('i')) << char_, v)); + BOOST_TEST(test("axib", + char_ << (lit('x') << lit('i') | lit('i')) << char_, v)); + } + + { + BOOST_TEST(test_delimited("x ", char_('x') | char_('i'), char_(' '))); + BOOST_TEST(test_delimited("x i ", + char_('x') << char_('i') | char_('i'), char_(' '))); + BOOST_TEST(test_delimited("i ", + char_('i') | char_('x') << char_('i'), char_(' '))); + + variant<int, char> v (10); + BOOST_TEST(test_delimited("10 ", char_ | int_, v, char_(' '))); + BOOST_TEST(test_delimited("10 ", int_ | char_, v, char_(' '))); + BOOST_TEST(test_delimited("a ", lit('a') | char_ | int_, v, char_(' '))); + BOOST_TEST(test_delimited("a ", char_ | lit('a') | int_, v, char_(' '))); + BOOST_TEST(test_delimited("10 ", int_ | lit('a') | char_, v, char_(' '))); + + v = 'c'; + BOOST_TEST(test_delimited("c ", char_ | int_, v, char_(' '))); + BOOST_TEST(test_delimited("a ", lit('a') | char_ | int_, v, char_(' '))); + BOOST_TEST(test_delimited("c ", char_ | lit('a') | int_, v, char_(' '))); + BOOST_TEST(test_delimited("a ", int_ | lit('a') | char_, v, char_(' '))); + BOOST_TEST(test_delimited("c ", int_ | char_ | lit('a'), v, char_(' '))); + } + +// this leads to infinite loops +// { +// variant<int, std::string> v(10); +// BOOST_TEST(test("10", int_ | +char_, v)); +// +// v = "abc"; +// BOOST_TEST(test("abc", int_ | +char_, v)); +// } + + { + // if nothing matches, the first explicit alternative will be chosen + variant<double, char const*> v (10.0); + BOOST_TEST(test("11", char_ | lit(11), v)); + BOOST_TEST(test("11", lit(11) | char_ , v)); + BOOST_TEST(test("10.0", double_ | lit(11), v)); + BOOST_TEST(test("11", lit(11) | double_, v)); + BOOST_TEST(!test("", char_ | int_, v)); + + v = "c"; + BOOST_TEST(test("11", char_ | lit(11), v)); + BOOST_TEST(test("11", double_ | lit(11), v)); + BOOST_TEST(!test("", char_ | int_, v)); + } + + { + // in strict mode if nothing matches, the alternative will fail + variant<double, char const*> v (10.0); + BOOST_TEST(!test("11", strict[char_ | lit(11)], v)); + BOOST_TEST(test("11", strict[lit(11) | char_] , v)); + + v = "c"; + BOOST_TEST(!test("11", strict[char_ | lit(11)], v)); + } + + { + // if nothing matches, the first explicit alternative will be chosen + variant<double, char const*> v (10.0); + BOOST_TEST(test_delimited("11 ", char_ | lit(11), v, char_(' '))); + BOOST_TEST(test_delimited("11 ", lit(11) | char_ , v, char_(' '))); + BOOST_TEST(test_delimited("10.0 ", double_ | lit(11), v, char_(' '))); + BOOST_TEST(test_delimited("11 ", lit(11) | double_, v, char_(' '))); + BOOST_TEST(!test_delimited("", char_ | int_, v, char_(' '))); + + v = "c"; + BOOST_TEST(test_delimited("11 ", char_ | lit(11), v, char_(' '))); + BOOST_TEST(test_delimited("11 ", double_ | lit(11), v, char_(' '))); + BOOST_TEST(!test_delimited("", char_ | int_, v, char_(' '))); + } + + { + // if nothing matches, the first explicit alternative will be chosen, + // optionals need to be accepted + optional<variant<double, char const*> > v (10.0); + BOOST_TEST(test_delimited("11 ", char_ | lit(11), v, char_(' '))); + BOOST_TEST(test_delimited("11 ", lit(11) | char_ , v, char_(' '))); + BOOST_TEST(test_delimited("10.0 ", double_ | lit(11), v, char_(' '))); + BOOST_TEST(test_delimited("11 ", lit(11) | double_, v, char_(' '))); + BOOST_TEST(!test_delimited("", char_ | int_, v, char_(' '))); + + v = "c"; + BOOST_TEST(test_delimited("11 ", char_ | lit(11), v, char_(' '))); + BOOST_TEST(test_delimited("11 ", double_ | lit(11), v, char_(' '))); + BOOST_TEST(!test_delimited("", char_ | int_, v, char_(' '))); + } + + { + std::vector<int> v; + BOOST_TEST(test("[]", '[' << (int_ % ", ") << ']' | "[]", v)); + BOOST_TEST(test("[]", '[' << -(int_ % ", ") << ']', v)); + BOOST_TEST(test("[]", '[' << ((int_ % ", ") | eps) << ']', v)); + + v.push_back(5); + v.push_back(5); + v.push_back(5); + BOOST_TEST(test("[5, 5, 5]", '[' << (int_ % ", ") << ']' | "[]", v)); + } + + return boost::report_errors(); +} + diff --git a/src/boost/libs/spirit/test/karma/and_predicate.cpp b/src/boost/libs/spirit/test/karma/and_predicate.cpp new file mode 100644 index 00000000..83965856 --- /dev/null +++ b/src/boost/libs/spirit/test/karma/and_predicate.cpp @@ -0,0 +1,36 @@ +// 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/karma_numeric.hpp> +#include <boost/spirit/include/karma_generate.hpp> +#include <boost/spirit/include/karma_operator.hpp> +#include <boost/spirit/include/karma_auxiliary.hpp> +#include <boost/spirit/include/karma_char.hpp> + +#include <iostream> +#include "test.hpp" + +int +main() +{ + using namespace spirit_test; + using namespace boost::spirit; + + { + BOOST_TEST(test("1", int_(1) << &(int_(2) << &int_(3) << int_(4)))); + } + + { + using boost::spirit::ascii::char_; + + BOOST_TEST(test("b", &char_('a') << 'b' | 'c', 'a')); + BOOST_TEST(test("c", &char_('a') << 'b' | 'c', 'x')); + } + + return boost::report_errors(); +} diff --git a/src/boost/libs/spirit/test/karma/attribute.cpp b/src/boost/libs/spirit/test/karma/attribute.cpp new file mode 100644 index 00000000..6fdafdc9 --- /dev/null +++ b/src/boost/libs/spirit/test/karma/attribute.cpp @@ -0,0 +1,214 @@ +// 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/phoenix_limits.hpp> + +#include <boost/fusion/include/struct.hpp> +#include <boost/fusion/include/nview.hpp> + +#include <boost/spirit/include/karma_char.hpp> +#include <boost/spirit/include/karma_string.hpp> +#include <boost/spirit/include/karma_numeric.hpp> +#include <boost/spirit/include/karma_operator.hpp> +#include <boost/spirit/include/karma_nonterminal.hpp> +#include <boost/spirit/include/karma_auxiliary.hpp> + +#include "test.hpp" + +using namespace spirit_test; + +/////////////////////////////////////////////////////////////////////////////// +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) +) + +/////////////////////////////////////////////////////////////////////////////// +// this is just a test structure we need to use in place of an int +struct test_int_data1 +{ + int i; +}; + +// so we provide a custom attribute transformation +namespace boost { namespace spirit { namespace traits +{ + template <> + struct transform_attribute<test_int_data1 const, int, karma::domain> + { + typedef int type; + static int pre(test_int_data1 const& d) { return d.i; } + }; +}}} + +/////////////////////////////////////////////////////////////////////////////// +// this is another test structure we need to use in place of an int, but this +// time we use a reference to the embedded element +struct test_int_data2 +{ + int i; +}; + +// so we provide a custom attribute transformation +namespace boost { namespace spirit { namespace traits +{ + template <> + struct transform_attribute<test_int_data2 const, int, karma::domain> + { + typedef int const& type; + static int const& pre(test_int_data2 const& d) { return d.i; } + }; +}}} + +/////////////////////////////////////////////////////////////////////////////// +int main() +{ + namespace fusion = boost::fusion; + namespace karma = boost::spirit::karma; + + test_data d1 = { "s11", "s12", 1, 2.5, "s13" }; + { + + BOOST_TEST(test("s121", + karma::string << karma::int_, + fusion::as_nview<2, 0>(d1))); + + BOOST_TEST(test_delimited("s12 1 ", + karma::string << karma::int_, + fusion::as_nview<2, 0>(d1), ' ')); + } + + { + test_data d2 = { "s21", "s22", 2, 3.4, "s23" }; + typedef fusion::result_of::as_nview<test_data const, 1, 2, 4>::type + test_view; + std::vector<test_data> v; + v.push_back(d1); + v.push_back(d2); + + karma::rule<output_iterator<char>::type, test_view()> r = + karma::string << karma::string << karma::double_; + + BOOST_TEST(test("s11s122.5\ns21s223.4", r % karma::eol, v)); + BOOST_TEST(test_delimited("s11s122.5 \n s21s223.4 ", + r % karma::eol, v, ' ')); + } + + { + test_int_data1 d = { 1 }; + BOOST_TEST(test("1", karma::attr_cast(karma::int_), d)); + BOOST_TEST(test("1", karma::attr_cast<test_int_data1>(karma::int_), d)); + BOOST_TEST(test("1", karma::attr_cast<test_int_data1, int>(karma::int_), d)); + } + + { + test_int_data1 d[] = {{ 1 }, { 2 }}; + std::vector<test_int_data1> v; + v.push_back(d[0]); + v.push_back(d[1]); + + BOOST_TEST(test("1,2", karma::attr_cast(karma::int_) % ',', v)); + BOOST_TEST(test("1,2" + , karma::attr_cast<test_int_data1>(karma::int_) % ',', v)); + BOOST_TEST(test("1,2" + , karma::attr_cast<test_int_data1, int>(karma::int_) % ',', v)); + } + + { + test_int_data1 d[] = {{ 1 }, { 2 }}; + std::vector<test_int_data1> v; + v.push_back(d[0]); + v.push_back(d[1]); + + karma::rule<output_iterator<char>::type, int()> r = karma::int_; + BOOST_TEST(test("1,2", r % ',', v)); + } + + { + test_int_data1 d[] = {{ 1 }, { 2 }}; + std::vector<test_int_data1> v; + v.push_back(d[0]); + v.push_back(d[1] ); + +// this won't compile as there is no defined transformation for +// test_int_data1 and double +// BOOST_TEST(test("1.0,2.0", karma::attr_cast(karma::double_) % ',', v)); +// BOOST_TEST(test("1.0,2.0" +// , karma::attr_cast<test_int_data1>(karma::double_) % ',', v)); + + BOOST_TEST(test("1.0,2.0" + , karma::attr_cast<test_int_data1, int>(karma::double_) % ',', v)); + + karma::rule<output_iterator<char>::type, int()> r = karma::double_; + BOOST_TEST(test("1.0,2.0", r % ',', v)); + } + + { + test_int_data2 d = { 1 }; + BOOST_TEST(test("1", karma::attr_cast(karma::int_), d)); + BOOST_TEST(test("1", karma::attr_cast<test_int_data2>(karma::int_), d)); + BOOST_TEST(test("1", karma::attr_cast<test_int_data2, int>(karma::int_), d)); + } + + { + test_int_data2 d[] = {{ 1 }, { 2 }}; + std::vector<test_int_data2> v; + v.push_back(d[0]); + v.push_back(d[1]); + + BOOST_TEST(test("1,2", karma::attr_cast(karma::int_) % ',', v)); + BOOST_TEST(test("1,2" + , karma::attr_cast<test_int_data2>(karma::int_) % ',', v)); + BOOST_TEST(test("1,2" + , karma::attr_cast<test_int_data2, int>(karma::int_) % ',', v)); + } + + { + test_int_data2 d[] = {{ 1 }, { 2 }}; + std::vector<test_int_data2> v; + v.push_back(d[0]); + v.push_back(d[1]); + + karma::rule<output_iterator<char>::type, int()> r = karma::int_; + BOOST_TEST(test("1,2", r % ',', v)); + } + + { + test_int_data2 d[] = {{ 1 }, { 2 }}; + std::vector<test_int_data2> v; + v.push_back(d[0]); + v.push_back(d[1] ); + +// this won't compile as there is no defined transformation for +// test_int_data2 and double +// BOOST_TEST(test("1.0,2.0", karma::attr_cast(karma::double_) % ',', v)); +// BOOST_TEST(test("1.0,2.0" +// , karma::attr_cast<test_int_data2>(karma::double_) % ',', v)); + + BOOST_TEST(test("1.0,2.0" + , karma::attr_cast<test_int_data2, int>(karma::double_) % ',', v)); + + karma::rule<output_iterator<char>::type, int()> r = karma::double_; + BOOST_TEST(test("1.0,2.0", r % ',', v)); + } + + return boost::report_errors(); +} diff --git a/src/boost/libs/spirit/test/karma/auto.hpp b/src/boost/libs/spirit/test/karma/auto.hpp new file mode 100644 index 00000000..a2d1ae79 --- /dev/null +++ b/src/boost/libs/spirit/test/karma/auto.hpp @@ -0,0 +1,79 @@ +// 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) + +#if !defined(BOOST_SPIRIT_TEST_AUTO_HPP) +#define BOOST_SPIRIT_TEST_AUTO_HPP + +#include <boost/config/warning_disable.hpp> +#include <boost/detail/lightweight_test.hpp> + +#include <boost/fusion/include/std_pair.hpp> +#include <boost/spirit/include/karma_bool.hpp> +#include <boost/spirit/include/karma_char.hpp> +#include <boost/spirit/include/karma_numeric.hpp> +#include <boost/spirit/include/karma_string.hpp> +#include <boost/spirit/include/karma_nonterminal.hpp> +#include <boost/spirit/include/karma_operator.hpp> +#include <boost/spirit/include/karma_directive.hpp> +#include <boost/spirit/include/karma_auto.hpp> + +#include "test.hpp" + +namespace karma = boost::spirit::karma; +namespace traits = boost::spirit::traits; + +/////////////////////////////////////////////////////////////////////////////// +template <typename Char, typename T> +bool test_create_generator(Char const *expected, T const& t) +{ + std::basic_string<Char> generated; + std::back_insert_iterator<std::basic_string<Char> > sink(generated); + + BOOST_TEST((traits::meta_create_exists<karma::domain, T>::value)); + bool result = karma::generate(sink, karma::create_generator<T>(), t); + + spirit_test::print_if_failed("test_create_generator", result, generated, expected); + return result && generated == expected; +} + +template <typename Char, typename T> +bool test_create_generator_auto(Char const *expected, T const& t) +{ + std::basic_string<Char> generated; + std::back_insert_iterator<std::basic_string<Char> > sink(generated); + + BOOST_TEST((traits::meta_create_exists<karma::domain, T>::value)); + bool result = karma::generate(sink, t); + + spirit_test::print_if_failed("test_create_generator (auto)", result, generated, expected); + return result && generated == expected; +} + +template <typename Char, typename Attribute> +bool test_rule(Char const *expected, Attribute const& attr) +{ + BOOST_TEST((traits::meta_create_exists<karma::domain, Attribute>::value)); + + typedef typename spirit_test::output_iterator<Char>::type sink_type; + karma::rule<sink_type, Attribute()> r = + karma::create_generator<Attribute>(); + return spirit_test::test(expected, r, attr); +} + +template <typename Char, typename Attribute, typename Delimiter> +bool test_rule_delimited(Char const *expected, Attribute const& attr + , Delimiter const& d) +{ + BOOST_TEST((traits::meta_create_exists<karma::domain, Attribute>::value)); + + typedef typename spirit_test::output_iterator<Char>::type sink_type; + karma::rule<sink_type, Attribute(), Delimiter> r = + karma::create_generator<Attribute>(); + return spirit_test::test_delimited(expected, r, attr, d); +} + +struct my_type {}; + +#endif diff --git a/src/boost/libs/spirit/test/karma/auto1.cpp b/src/boost/libs/spirit/test/karma/auto1.cpp new file mode 100644 index 00000000..a3b4850f --- /dev/null +++ b/src/boost/libs/spirit/test/karma/auto1.cpp @@ -0,0 +1,104 @@ +// 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 "auto.hpp" + +/////////////////////////////////////////////////////////////////////////////// +int main() +{ + { + BOOST_TEST((!traits::meta_create_exists<karma::domain, my_type>::value)); + } + + { + // test primitive types + BOOST_TEST(test_create_generator("true", true)); + BOOST_TEST(test_create_generator("1", 1)); + BOOST_TEST(test_create_generator("1.1", 1.1)); + BOOST_TEST(test_create_generator("test", std::string("test"))); + BOOST_TEST(test_create_generator("a", 'a')); + BOOST_TEST(test_create_generator(L"a", L'a')); + + // test containers + std::vector<int> v; + v.push_back(0); + v.push_back(1); + v.push_back(2); + BOOST_TEST(test_create_generator("012", v)); + + std::list<int> l; + l.push_back(0); + l.push_back(1); + l.push_back(2); + BOOST_TEST(test_create_generator("012", l)); + + // test optional + boost::optional<int> o; + BOOST_TEST(test_create_generator("", o)); + o = 1; + BOOST_TEST(test_create_generator("1", o)); + + // test alternative + boost::variant<int, double, float, std::string> vv; + vv = 1; + BOOST_TEST(test_create_generator("1", vv)); + vv = 1.0; + BOOST_TEST(test_create_generator("1.0", vv)); + vv = 1.0f; + BOOST_TEST(test_create_generator("1.0", vv)); + vv = "some string"; + BOOST_TEST(test_create_generator("some string", vv)); + + // test fusion sequence + std::pair<int, double> p (1, 2.0); + BOOST_TEST(test_create_generator("12.0", p)); + } + + { + // test primitive types +// BOOST_TEST(test_create_generator_auto("true", true)); +// BOOST_TEST(test_create_generator_auto("1", 1)); +// BOOST_TEST(test_create_generator_auto("1.1", 1.1)); +// BOOST_TEST(test_create_generator_auto("test", std::string("test"))); +// BOOST_TEST(test_create_generator_auto("a", 'a')); +// BOOST_TEST(test_create_generator_auto(L"a", L'a')); + + // test containers + std::vector<int> v; + v.push_back(0); + v.push_back(1); + v.push_back(2); + BOOST_TEST(test_create_generator_auto("012", v)); + + std::list<int> l; + l.push_back(0); + l.push_back(1); + l.push_back(2); + BOOST_TEST(test_create_generator_auto("012", l)); + + // test optional + boost::optional<int> o; + BOOST_TEST(test_create_generator_auto("", o)); + o = 1; + BOOST_TEST(test_create_generator_auto("1", o)); + + // test alternative + boost::variant<int, double, float, std::string> vv; + vv = 1; + BOOST_TEST(test_create_generator_auto("1", vv)); + vv = 1.0; + BOOST_TEST(test_create_generator_auto("1.0", vv)); + vv = 1.0f; + BOOST_TEST(test_create_generator_auto("1.0", vv)); + vv = "some string"; + BOOST_TEST(test_create_generator_auto("some string", vv)); + + // test fusion sequence + std::pair<int, double> p (1, 2.0); + BOOST_TEST(test_create_generator_auto("12.0", p)); + } + + return boost::report_errors(); +} diff --git a/src/boost/libs/spirit/test/karma/auto2.cpp b/src/boost/libs/spirit/test/karma/auto2.cpp new file mode 100644 index 00000000..4527b869 --- /dev/null +++ b/src/boost/libs/spirit/test/karma/auto2.cpp @@ -0,0 +1,126 @@ +// 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 "auto.hpp" + +/////////////////////////////////////////////////////////////////////////////// +int main() +{ + { + using karma::auto_; + using karma::upper; + using spirit_test::test; + using spirit_test::test_delimited; + + // test primitive types + BOOST_TEST(test("true", auto_, true)); + BOOST_TEST(test("1", auto_, 1)); + BOOST_TEST(test("1.1", auto_, 1.1)); + BOOST_TEST(test("test", auto_, "test")); + BOOST_TEST(test(L"test", auto_, L"test")); + BOOST_TEST(test("a", auto_, 'a')); + BOOST_TEST(test(L"a", auto_, L'a')); + + BOOST_TEST(test("TRUE", upper[auto_], true)); + BOOST_TEST(test("TEST", upper[auto_], "test")); + + // test containers + std::vector<int> v; + v.push_back(0); + v.push_back(1); + v.push_back(2); + BOOST_TEST(test("012", auto_, v)); + BOOST_TEST(test("0,1,2", auto_ % ',', v)); + BOOST_TEST(test_delimited("0,1,2,", auto_, v, ',')); + + std::list<int> l; + l.push_back(0); + l.push_back(1); + l.push_back(2); + BOOST_TEST(test("012", auto_, l)); + BOOST_TEST(test("0,1,2", auto_ % ',', l)); + BOOST_TEST(test_delimited("0,1,2,", auto_, l, ',')); + + // test optional + boost::optional<int> o; + BOOST_TEST(test("", auto_, o)); + o = 1; + BOOST_TEST(test("1", auto_, o)); + + // test alternative + boost::variant<int, double, float, std::string> vv; + vv = 1; + BOOST_TEST(test("1", auto_, vv)); + vv = 1.0; + BOOST_TEST(test("1.0", auto_, vv)); + vv = 1.0f; + BOOST_TEST(test("1.0", auto_, vv)); + vv = "some string"; + BOOST_TEST(test("some string", auto_, vv)); + + // test fusion sequence + std::pair<int, double> p (1, 2.0); + BOOST_TEST(test("12.0", auto_, p)); + BOOST_TEST(test_delimited("1,2.0,", auto_, p, ',')); + } + + { + using karma::auto_; + using karma::upper; + using spirit_test::test; + using spirit_test::test_delimited; + + // test primitive types + BOOST_TEST(test("true", auto_(true))); + BOOST_TEST(test("1", auto_(1))); + BOOST_TEST(test("1.1", auto_(1.1))); + BOOST_TEST(test("test", auto_("test"))); + BOOST_TEST(test(L"test", auto_(L"test"))); + BOOST_TEST(test("a", auto_('a'))); + BOOST_TEST(test(L"a", auto_(L'a'))); + + BOOST_TEST(test("TRUE", upper[auto_(true)])); + BOOST_TEST(test("TEST", upper[auto_("test")])); + + // test containers + std::vector<int> v; + v.push_back(0); + v.push_back(1); + v.push_back(2); + BOOST_TEST(test("012", auto_(v))); + BOOST_TEST(test_delimited("0,1,2,", auto_(v), ',')); + + std::list<int> l; + l.push_back(0); + l.push_back(1); + l.push_back(2); + BOOST_TEST(test("012", auto_(l))); + BOOST_TEST(test_delimited("0,1,2,", auto_(l), ',')); + + // test optional + boost::optional<int> o; + BOOST_TEST(test("", auto_(o))); + o = 1; + BOOST_TEST(test("1", auto_(o))); + + // test alternative + boost::variant<int, double, float, std::string> vv; + vv = 1; + BOOST_TEST(test("1", auto_(vv))); + vv = 1.0; + BOOST_TEST(test("1.0", auto_(vv))); + vv = 1.0f; + BOOST_TEST(test("1.0", auto_(vv))); + vv = "some string"; + BOOST_TEST(test("some string", auto_(vv))); + + // test fusion sequence + std::pair<int, double> p (1, 2.0); + BOOST_TEST(test("12.0", auto_, p)); + BOOST_TEST(test_delimited("1,2.0,", auto_(p), ',')); + } + + return boost::report_errors(); +} diff --git a/src/boost/libs/spirit/test/karma/auto3.cpp b/src/boost/libs/spirit/test/karma/auto3.cpp new file mode 100644 index 00000000..ffbcdc9a --- /dev/null +++ b/src/boost/libs/spirit/test/karma/auto3.cpp @@ -0,0 +1,60 @@ +// 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 "auto.hpp" + +/////////////////////////////////////////////////////////////////////////////// +int main() +{ + { + using spirit_test::test; + using spirit_test::test_delimited; + + // test primitive types + BOOST_TEST(test_rule("true", true)); + BOOST_TEST(test_rule("1", 1)); + BOOST_TEST(test_rule("1.1", 1.1)); + BOOST_TEST(test_rule("test", std::string("test"))); + + // test containers + std::vector<int> v; + v.push_back(0); + v.push_back(1); + v.push_back(2); + BOOST_TEST(test_rule("012", v)); + BOOST_TEST(test_rule_delimited("0,1,2,", v, ',')); + + std::list<int> l; + l.push_back(0); + l.push_back(1); + l.push_back(2); + BOOST_TEST(test_rule("012", l)); + BOOST_TEST(test_rule_delimited("0,1,2,", l, ',')); + + // 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("12.0", p)); + BOOST_TEST(test_rule_delimited("1,2.0,", p, ',')); + } + + return boost::report_errors(); +} diff --git a/src/boost/libs/spirit/test/karma/binary1.cpp b/src/boost/libs/spirit/test/karma/binary1.cpp new file mode 100644 index 00000000..336d2b42 --- /dev/null +++ b/src/boost/libs/spirit/test/karma/binary1.cpp @@ -0,0 +1,113 @@ +// 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/karma_binary.hpp> +#include <boost/spirit/include/karma_generate.hpp> + +#include <boost/predef/other/endian.h> + +#include "test.hpp" + +using namespace spirit_test; + +/////////////////////////////////////////////////////////////////////////////// +int +main() +{ + using namespace boost::spirit; + + { // test native endian binaries +#if BOOST_ENDIAN_LITTLE_BYTE + BOOST_TEST(binary_test("\x01", 1, byte_, 0x01)); + BOOST_TEST(binary_test("\x80", 1, byte_, 0x80)); + BOOST_TEST(binary_test("\x01\x82", 2, word, 0x8201)); + BOOST_TEST(binary_test("\x81\x02", 2, word, 0x0281)); + BOOST_TEST(binary_test("\x01\x02\x03\x84", 4, dword, 0x84030201)); + BOOST_TEST(binary_test("\x81\x02\x03\x04", 4, dword, 0x04030281)); +#ifdef BOOST_HAS_LONG_LONG + BOOST_TEST(binary_test("\x01\x02\x03\x04\x05\x06\x07\x88", 8, qword, + 0x8807060504030201LL)); + BOOST_TEST(binary_test("\x81\x02\x03\x04\x05\x06\x07\x08", 8, qword, + 0x0807060504030281LL)); +#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)); + + BOOST_TEST(binary_test_delimited("\x01\x00\x00\x00", 4, byte_, 0x01, pad(4))); + BOOST_TEST(binary_test_delimited("\x01\x02\x00\x00", 4, word, 0x0201, pad(4))); + BOOST_TEST(binary_test_delimited("\x01\x02\x03\x04", 4, dword, 0x04030201, pad(4))); +#ifdef BOOST_HAS_LONG_LONG + BOOST_TEST(binary_test_delimited("\x01\x02\x03\x04\x05\x06\x07\x08\x00\x00", 10, + qword, 0x0807060504030201LL, pad(10))); +#endif + BOOST_TEST(binary_test_delimited("\x00\x00\x80\x3f", 4, bin_float, + 1.0f, pad(4))); + BOOST_TEST(binary_test_delimited("\x00\x00\x00\x00\x00\x00\xf0\x3f", 8, + bin_double, 1.0, pad(8))); + +#else // BOOST_ENDIAN_LITTLE_BYTE + + BOOST_TEST(binary_test("\x01", 1, byte_, 0x01)); + BOOST_TEST(binary_test("\x80", 1, byte_, 0x80)); + BOOST_TEST(binary_test("\x01\x82", 2, word, 0x0182)); + BOOST_TEST(binary_test("\x81\x02", 2, word, 0x8102)); + BOOST_TEST(binary_test("\x01\x02\x03\x84", 4, dword, 0x01020384)); + BOOST_TEST(binary_test("\x81\x02\x03\x04", 4, dword, 0x81020304)); +#ifdef BOOST_HAS_LONG_LONG + BOOST_TEST(binary_test("\x01\x02\x03\x04\x05\x06\x07\x88", 8, qword, + 0x0102030405060788LL)); + BOOST_TEST(binary_test("\x81\x02\x03\x04\x05\x06\x07\x08", 8, qword, + 0x8102030405060708LL)); +#endif + BOOST_TEST(binary_test("\x3f\x80\x00\x00", 4, bin_float, 1.0f)); + BOOST_TEST(binary_test("\x3f\xf0\x00\x00\x00\x00\x00\x00", 8, + bin_double, 1.0)); + + BOOST_TEST(binary_test_delimited("\x01\x00\x00\x00", 4, byte_, 0x01, pad(4))); + BOOST_TEST(binary_test_delimited("\x01\x02\x00\x00", 4, word, 0x0102, pad(4))); + BOOST_TEST(binary_test_delimited("\x01\x02\x03\x04", 4, dword, 0x01020304, pad(4))); +#ifdef BOOST_HAS_LONG_LONG + BOOST_TEST(binary_test_delimited("\x01\x02\x03\x04\x05\x06\x07\x08\x00\x00", 10, + qword, 0x0102030405060708LL, pad(10))); +#endif + BOOST_TEST(binary_test_delimited("\x3f\x80\x00\x00", 4, bin_float, + 1.0f, pad(4))); + BOOST_TEST(binary_test_delimited("\x3f\xf0\x00\x00\x00\x00\x00\x00", 8, + bin_double, 1.0, pad(8))); +#endif + } + + { // test native endian binaries +#if BOOST_ENDIAN_LITTLE_BYTE + BOOST_TEST(binary_test("\x01", 1, byte_(0x01))); + BOOST_TEST(binary_test("\x01\x02", 2, word(0x0201))); + BOOST_TEST(binary_test("\x01\x02\x03\x04", 4, dword(0x04030201))); +#ifdef BOOST_HAS_LONG_LONG + BOOST_TEST(binary_test("\x01\x02\x03\x04\x05\x06\x07\x08", 8, + 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(binary_test("\x01", 1, byte_(0x01))); + BOOST_TEST(binary_test("\x01\x02", 2, word(0x0102))); + BOOST_TEST(binary_test("\x01\x02\x03\x04", 4, dword(0x01020304))); +#ifdef BOOST_HAS_LONG_LONG + BOOST_TEST(binary_test("\x01\x02\x03\x04\x05\x06\x07\x08", 8, + qword(0x0102030405060708LL))); +#endif + BOOST_TEST(binary_test("\x3f\x80\x00\x00", 4, bin_float(1.0f))); + BOOST_TEST(binary_test("\x3f\xf0\x00\x00\x00\x00\x00\x00", 8, + bin_double(1.0))); +#endif + } + + return boost::report_errors(); +} diff --git a/src/boost/libs/spirit/test/karma/binary2.cpp b/src/boost/libs/spirit/test/karma/binary2.cpp new file mode 100644 index 00000000..00f82032 --- /dev/null +++ b/src/boost/libs/spirit/test/karma/binary2.cpp @@ -0,0 +1,131 @@ +// 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/karma_binary.hpp> +#include <boost/spirit/include/karma_generate.hpp> + +#include <boost/predef/other/endian.h> + +#include "test.hpp" + +using namespace spirit_test; + +/////////////////////////////////////////////////////////////////////////////// +int +main() +{ + using namespace boost::spirit; + + { // test big endian binaries + BOOST_TEST(binary_test("\x01\x82", 2, big_word, 0x0182)); + BOOST_TEST(binary_test("\x81\x02", 2, big_word, 0x8102)); + BOOST_TEST(binary_test("\x01\x02\x03\x84", 4, big_dword, 0x01020384)); + BOOST_TEST(binary_test("\x81\x02\x03\x04", 4, big_dword, 0x81020304)); +#ifdef BOOST_HAS_LONG_LONG + BOOST_TEST(binary_test("\x01\x02\x03\x04\x05\x06\x07\x88", 8, big_qword, + 0x0102030405060788LL)); + BOOST_TEST(binary_test("\x81\x02\x03\x04\x05\x06\x07\x08", 8, big_qword, + 0x8102030405060708LL)); + BOOST_TEST(binary_test_delimited("\x01\x02\x03\x04\x05\x06\x07\x08\x00\x00", + 10, big_qword, 0x0102030405060708LL, pad(10))); +#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)); + BOOST_TEST(binary_test_delimited("\x3f\xf0\x00\x00\x00\x00\x00\x00\x00\x00", + 10, big_bin_double, 1.0, pad(10))); + } + + { + BOOST_TEST(binary_test("\x01\x02", 2, big_word(0x0102))); + BOOST_TEST(binary_test("\x01\x02\x03\x04", 4, big_dword(0x01020304))); +#ifdef BOOST_HAS_LONG_LONG + BOOST_TEST(binary_test("\x01\x02\x03\x04\x05\x06\x07\x08", 8, + big_qword(0x0102030405060708LL))); + BOOST_TEST(binary_test_delimited("\x01\x02\x03\x04\x05\x06\x07\x08\x00\x00", + 10, big_qword(0x0102030405060708LL), pad(10))); +#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))); + BOOST_TEST(binary_test_delimited("\x3f\xf0\x00\x00\x00\x00\x00\x00\x00\x00", + 10, big_bin_double(1.0), pad(10))); + } + + { // test little endian binaries + BOOST_TEST(binary_test("\x01\x82", 2, little_word, 0x8201)); + BOOST_TEST(binary_test("\x81\x02", 2, little_word, 0x0281)); + BOOST_TEST(binary_test("\x01\x02\x03\x84", 4, little_dword, 0x84030201)); + BOOST_TEST(binary_test("\x81\x02\x03\x04", 4, little_dword, 0x04030281)); +#ifdef BOOST_HAS_LONG_LONG + BOOST_TEST(binary_test("\x01\x02\x03\x04\x05\x06\x07\x88", 8, little_qword, + 0x8807060504030201LL)); + BOOST_TEST(binary_test("\x81\x02\x03\x04\x05\x06\x07\x08", 8, little_qword, + 0x0807060504030281LL)); + BOOST_TEST(binary_test_delimited("\x01\x02\x03\x04\x05\x06\x07\x08\x00\x00", + 10, little_qword, 0x0807060504030201LL, pad(10))); +#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)); + BOOST_TEST(binary_test_delimited("\x00\x00\x00\x00\x00\x00\xf0\x3f\x00\x00", + 10, little_bin_double, 1.0, pad(10))); + } + + { + BOOST_TEST(binary_test("\x01\x02", 2, little_word(0x0201))); + BOOST_TEST(binary_test("\x01\x02\x03\x04", 4, little_dword(0x04030201))); +#ifdef BOOST_HAS_LONG_LONG + BOOST_TEST(binary_test("\x01\x02\x03\x04\x05\x06\x07\x08", 8, + little_qword(0x0807060504030201LL))); + BOOST_TEST(binary_test_delimited("\x01\x02\x03\x04\x05\x06\x07\x08\x00\x00", + 10, little_qword(0x0807060504030201LL), pad(10))); +#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))); + BOOST_TEST(binary_test_delimited("\x00\x00\x00\x00\x00\x00\xf0\x3f\x00\x00", + 10, little_bin_double(1.0), pad(10))); + } + + { // test native endian binaries + boost::optional<boost::uint8_t> v8; + boost::optional<boost::uint16_t> v16; + boost::optional<boost::uint32_t> v32; + boost::optional<float> vf; + boost::optional<double> vd; + +#if BOOST_ENDIAN_LITTLE_BYTE + + BOOST_TEST(!binary_test("", 0, byte_, v8)); + BOOST_TEST(!binary_test("", 0, word, v16)); + BOOST_TEST(!binary_test("", 0, dword, v32)); +#ifdef BOOST_HAS_LONG_LONG + boost::optional<boost::uint64_t> v64; + BOOST_TEST(!binary_test("", 0, qword, v64)); +#endif + BOOST_TEST(!binary_test("", 0, bin_float, vf)); + BOOST_TEST(!binary_test("", 0, bin_double, vd)); + +#else // BOOST_ENDIAN_LITTLE_BYTE + + BOOST_TEST(!binary_test("", 0, byte_, v8)); + BOOST_TEST(!binary_test("", 0, word, v16)); + BOOST_TEST(!binary_test("", 0, dword, v32)); +#ifdef BOOST_HAS_LONG_LONG + boost::optional<boost::uint64_t> v64; + BOOST_TEST(!binary_test("", 0, qword, v64)); +#endif + BOOST_TEST(!binary_test("", 0, bin_float, vf)); + BOOST_TEST(!binary_test("", 0, bin_double, vd)); + +#endif + } + + return boost::report_errors(); +} diff --git a/src/boost/libs/spirit/test/karma/binary3.cpp b/src/boost/libs/spirit/test/karma/binary3.cpp new file mode 100644 index 00000000..d666307e --- /dev/null +++ b/src/boost/libs/spirit/test/karma/binary3.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/karma_binary.hpp> +#include <boost/spirit/include/karma_generate.hpp> + +#include <boost/spirit/include/phoenix_core.hpp> +#include <boost/spirit/include/phoenix_operator.hpp> + +#include <boost/predef/other/endian.h> + +#include "test.hpp" + +using namespace spirit_test; + +/////////////////////////////////////////////////////////////////////////////// +int +main() +{ + using namespace boost::spirit; + using namespace boost::phoenix; + + { // test optional attributes + +#if BOOST_ENDIAN_LITTLE_BYTE + boost::optional<boost::uint8_t> v8 (0x01); + BOOST_TEST(binary_test("\x01", 1, byte_, v8)); + boost::optional<boost::uint16_t> v16 (0x0201); + BOOST_TEST(binary_test("\x01\x02", 2, word, v16)); + boost::optional<boost::uint32_t> v32 (0x04030201); + BOOST_TEST(binary_test("\x01\x02\x03\x04", 4, dword, v32)); +#ifdef BOOST_HAS_LONG_LONG + boost::optional<boost::uint64_t> v64 (0x0807060504030201LL); + BOOST_TEST(binary_test("\x01\x02\x03\x04\x05\x06\x07\x08", 8, qword, v64)); +#endif + boost::optional<float> vf(1.0f); + BOOST_TEST(binary_test("\x00\x00\x80\x3f", 4, bin_float, vf)); + boost::optional<double> vd(1.0); + BOOST_TEST(binary_test("\x00\x00\x00\x00\x00\x00\xf0\x3f", 8, + bin_double, vd)); + +#else // BOOST_ENDIAN_LITTLE_BYTE + + boost::optional<boost::uint8_t> v8 (0x01); + BOOST_TEST(binary_test("\x01", 1, byte_, v8)); + boost::optional<boost::uint16_t> v16 (0x0102); + BOOST_TEST(binary_test("\x01\x02", 2, word, v16)); + boost::optional<boost::uint32_t> v32 (0x01020304); + BOOST_TEST(binary_test("\x01\x02\x03\x04", 4, dword, v32)); +#ifdef BOOST_HAS_LONG_LONG + boost::optional<boost::uint64_t> v64 (0x0102030405060708LL); + BOOST_TEST(binary_test("\x01\x02\x03\x04\x05\x06\x07\x08", 8, qword, v64)); +#endif + boost::optional<float> vf(1.0f); + BOOST_TEST(binary_test("\x3f\x80\x00\x00", 4, bin_float, vf)); + boost::optional<double> vd(1.0); + BOOST_TEST(binary_test("\x3f\xf0\x00\x00\x00\x00\x00\x00", 8, + bin_double, vd)); + +#endif + } + +// we support Phoenix attributes only starting with V2.2 +#if SPIRIT_VERSION >= 0x2020 + { // test Phoenix expression attributes, only supported if + // karma_phoenix_attributes.hpp is included + namespace phoenix = boost::phoenix; + +#if BOOST_ENDIAN_LITTLE_BYTE + BOOST_TEST(binary_test("\x01", 1, byte_, phoenix::val(0x01))); + BOOST_TEST(binary_test("\x01\x02", 2, word, phoenix::val(0x0201))); + BOOST_TEST(binary_test("\x01\x02\x03\x04", 4, dword, + phoenix::val(0x04030201))); + + boost::uint8_t v8 (0x01); + BOOST_TEST(binary_test("\x01", 1, byte_, phoenix::ref(v8))); + BOOST_TEST(binary_test("\x02", 1, byte_, ++phoenix::ref(v8))); + + boost::uint16_t v16 (0x0201); + BOOST_TEST(binary_test("\x01\x02", 2, word, phoenix::ref(v16))); + BOOST_TEST(binary_test("\x02\x02", 2, word, ++phoenix::ref(v16))); + + boost::uint32_t v32 (0x04030201); + BOOST_TEST(binary_test("\x01\x02\x03\x04", 4, dword, phoenix::ref(v32))); + BOOST_TEST(binary_test("\x02\x02\x03\x04", 4, dword, ++phoenix::ref(v32))); + +#ifdef BOOST_HAS_LONG_LONG + BOOST_TEST(binary_test("\x01\x02\x03\x04\x05\x06\x07\x08", 8, qword, + phoenix::val(0x0807060504030201LL))); + + boost::uint64_t v64 (0x0807060504030201LL); + BOOST_TEST(binary_test("\x01\x02\x03\x04\x05\x06\x07\x08", 8, qword, + phoenix::ref(v64))); + BOOST_TEST(binary_test("\x02\x02\x03\x04\x05\x06\x07\x08", 8, qword, + ++phoenix::ref(v64))); +#endif + BOOST_TEST(binary_test("\x00\x00\x80\x3f", 4, bin_float, + phoenix::val(1.0f))); + float vf(1.0f); + BOOST_TEST(binary_test("\x00\x00\x80\x3f", 4, bin_float, + phoenix::ref(vf))); + BOOST_TEST(binary_test("\x00\x00\x00\x40", 4, bin_float, + ++phoenix::ref(vf))); + + BOOST_TEST(binary_test("\x00\x00\x00\x00\x00\x00\xf0\x3f", 8, + bin_double, phoenix::val(1.0))); + double vd(1.0); + BOOST_TEST(binary_test("\x00\x00\x00\x00\x00\x00\xf0\x3f", 8, + bin_double, phoenix::ref(vd))); + BOOST_TEST(binary_test("\x00\x00\x00\x00\x00\x00\x00\x40", 8, + bin_double, ++phoenix::ref(vd))); + +#else // BOOST_ENDIAN_LITTLE_BYTE + + BOOST_TEST(binary_test("\x01", 1, byte_, phoenix::val(0x01))); + BOOST_TEST(binary_test("\x01\x02", 2, word, phoenix::val(0x0102))); + BOOST_TEST(binary_test("\x01\x02\x03\x04", 4, dword, + phoenix::val(0x01020304))); + + boost::uint8_t v8 (0x01); + BOOST_TEST(binary_test("\x01", 1, byte_, phoenix::ref(v8))); + BOOST_TEST(binary_test("\x02", 1, byte_, ++phoenix::ref(v8))); + + boost::uint16_t v16 (0x0102); + BOOST_TEST(binary_test("\x01\x02", 2, word, phoenix::ref(v16))); + BOOST_TEST(binary_test("\x01\x03", 2, word, ++phoenix::ref(v16))); + + boost::uint32_t v32 (0x01020304); + BOOST_TEST(binary_test("\x01\x02\x03\x04", 4, dword, phoenix::ref(v32))); + BOOST_TEST(binary_test("\x01\x02\x03\x05", 4, dword, ++phoenix::ref(v32))); + +#ifdef BOOST_HAS_LONG_LONG + BOOST_TEST(binary_test("\x01\x02\x03\x04\x05\x06\x07\x08", 8, qword, + phoenix::val(0x0102030405060708LL))); + + boost::uint64_t v64 (0x0102030405060708LL); + BOOST_TEST(binary_test("\x01\x02\x03\x04\x05\x06\x07\x08", 8, qword, + phoenix::ref(v64))); + BOOST_TEST(binary_test("\x01\x02\x03\x04\x05\x06\x07\x09", 8, qword, + ++phoenix::ref(v64))); +#endif + BOOST_TEST(binary_test("\x3f\x80\x00\x00", 4, bin_float, + phoenix::val(1.0f))); + float vf(1.0f); + BOOST_TEST(binary_test("\x3f\x80\x00\x00", 4, bin_float, + phoenix::ref(vf))); + BOOST_TEST(binary_test("\x40\x00\x00\x00", 4, bin_float, + ++phoenix::ref(vf))); + + BOOST_TEST(binary_test("\x3f\xf0\x00\x00\x00\x00\x00\x00", 8, + bin_double, phoenix::val(1.0))); + double vd(1.0); + BOOST_TEST(binary_test("\x3f\xf0\x00\x00\x00\x00\x00\x00", 8, + bin_double, phoenix::ref(vd))); + BOOST_TEST(binary_test("\x40\x00\x00\x00\x00\x00\x00\x00", 8, + bin_double, ++phoenix::ref(vd))); + +#endif + } +#endif + + return boost::report_errors(); +} diff --git a/src/boost/libs/spirit/test/karma/bool.cpp b/src/boost/libs/spirit/test/karma/bool.cpp new file mode 100644 index 00000000..4627bd08 --- /dev/null +++ b/src/boost/libs/spirit/test/karma/bool.cpp @@ -0,0 +1,184 @@ +/*============================================================================= + 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/karma_string.hpp> +#include <boost/spirit/include/karma_numeric.hpp> +#include <boost/spirit/include/karma_directive.hpp> +#include <boost/spirit/include/karma_operator.hpp> +#include <boost/spirit/include/karma_phoenix_attributes.hpp> + +#include <boost/spirit/include/phoenix_core.hpp> +#include <boost/spirit/include/phoenix_operator.hpp> + +#include "test.hpp" + +using namespace spirit_test; + +/////////////////////////////////////////////////////////////////////////////// +// special bool output policy allowing to spell false as true backwards (eurt) +struct special_bool_policy : boost::spirit::karma::bool_policies<> +{ + template <typename CharEncoding, typename Tag + , typename OutputIterator> + static bool generate_false(OutputIterator& sink, bool) + { + // we want to spell the names of true and false backwards + return boost::spirit::karma::string_inserter<CharEncoding, Tag>:: + call(sink, "eurt"); + } +}; + +/////////////////////////////////////////////////////////////////////////////// +// special policy allowing to use any type as a boolean +struct test_bool_data +{ + explicit test_bool_data(bool b) : b(b) {} + + bool b; + + // we need to provide (safe) convertibility to bool +private: + struct dummy { void true_() {} }; + typedef void (dummy::*safe_bool)(); + +public: + operator safe_bool () const { return b ? &dummy::true_ : 0; } +}; + +struct test_bool_policy : boost::spirit::karma::bool_policies<> +{ + template <typename Inserter, typename OutputIterator, typename Policies> + static bool + call (OutputIterator& sink, test_bool_data b, Policies const& p) + { + // call the predefined inserter to do the job + return Inserter::call_n(sink, bool(b), p); + } +}; + + +/////////////////////////////////////////////////////////////////////////////// +int main() +{ + using boost::spirit::karma::bool_; + using boost::spirit::karma::false_; + using boost::spirit::karma::true_; + using boost::spirit::karma::lit; + using boost::spirit::karma::lower; + using boost::spirit::karma::upper; + + // testing plain bool + { + BOOST_TEST(test("false", bool_, false)); + BOOST_TEST(test("true", bool_, true)); + BOOST_TEST(test("false", false_, false)); + BOOST_TEST(test("true", true_, true)); + BOOST_TEST(test("false", bool_(false))); + BOOST_TEST(test("true", bool_(true))); + BOOST_TEST(test("false", bool_(false), false)); + BOOST_TEST(test("true", bool_(true), true)); + BOOST_TEST(!test("", bool_(false), true)); + BOOST_TEST(!test("", bool_(true), false)); + BOOST_TEST(test("false", lit(false))); + BOOST_TEST(test("true", lit(true))); + } + + // test optional attributes + { + boost::optional<bool> optbool; + + BOOST_TEST(!test("", bool_, optbool)); + BOOST_TEST(test("", -bool_, optbool)); + optbool = false; + BOOST_TEST(test("false", bool_, optbool)); + BOOST_TEST(test("false", -bool_, optbool)); + optbool = true; + BOOST_TEST(test("true", bool_, optbool)); + BOOST_TEST(test("true", -bool_, optbool)); + } + +// we support Phoenix attributes only starting with V2.2 +#if SPIRIT_VERSION >= 0x2020 + // test Phoenix expression attributes (requires to include + // karma_phoenix_attributes.hpp) + { + namespace phoenix = boost::phoenix; + + BOOST_TEST(test("true", bool_, phoenix::val(true))); + + bool b = false; + BOOST_TEST(test("false", bool_, phoenix::ref(b))); + BOOST_TEST(test("true", bool_, !phoenix::ref(b))); + } +#endif + + { + BOOST_TEST(test("false", lower[bool_], false)); + BOOST_TEST(test("true", lower[bool_], true)); + BOOST_TEST(test("false", lower[bool_(false)])); + BOOST_TEST(test("true", lower[bool_(true)])); + BOOST_TEST(test("false", lower[bool_(false)], false)); + BOOST_TEST(test("true", lower[bool_(true)], true)); + BOOST_TEST(!test("", lower[bool_(false)], true)); + BOOST_TEST(!test("", lower[bool_(true)], false)); + BOOST_TEST(test("false", lower[lit(false)])); + BOOST_TEST(test("true", lower[lit(true)])); + } + + { + BOOST_TEST(test("FALSE", upper[bool_], false)); + BOOST_TEST(test("TRUE", upper[bool_], true)); + BOOST_TEST(test("FALSE", upper[bool_(false)])); + BOOST_TEST(test("TRUE", upper[bool_(true)])); + BOOST_TEST(test("FALSE", upper[bool_(false)], false)); + BOOST_TEST(test("TRUE", upper[bool_(true)], true)); + BOOST_TEST(!test("", upper[bool_(false)], true)); + BOOST_TEST(!test("", upper[bool_(true)], false)); + BOOST_TEST(test("FALSE", upper[lit(false)])); + BOOST_TEST(test("TRUE", upper[lit(true)])); + } + + { + typedef boost::spirit::karma::bool_generator<bool, special_bool_policy> + backwards_bool_type; + backwards_bool_type const backwards_bool = backwards_bool_type(); + + BOOST_TEST(test("eurt", backwards_bool, false)); + BOOST_TEST(test("true", backwards_bool, true)); + BOOST_TEST(test("eurt", backwards_bool(false))); + BOOST_TEST(test("true", backwards_bool(true))); + BOOST_TEST(test("eurt", backwards_bool(false), false)); + BOOST_TEST(test("true", backwards_bool(true), true)); + BOOST_TEST(!test("", backwards_bool(false), true)); + BOOST_TEST(!test("", backwards_bool(true), false)); + } + + { + typedef boost::spirit::karma::bool_generator< + test_bool_data, test_bool_policy> test_bool_type; + test_bool_type const test_bool = test_bool_type(); + + test_bool_data const test_false = test_bool_data(false); + test_bool_data const test_true = test_bool_data(true); + + BOOST_TEST(test("false", test_bool, test_false)); + BOOST_TEST(test("true", test_bool, test_true)); + BOOST_TEST(test("false", test_bool(test_false))); + BOOST_TEST(test("true", test_bool(test_true))); + BOOST_TEST(test("false", test_bool(test_false), test_false)); + BOOST_TEST(test("true", test_bool(test_true), test_true)); + BOOST_TEST(!test("", test_bool(test_false), test_true)); + BOOST_TEST(!test("", test_bool(test_true), test_false)); + } + + return boost::report_errors(); +} + diff --git a/src/boost/libs/spirit/test/karma/buffer.cpp b/src/boost/libs/spirit/test/karma/buffer.cpp new file mode 100644 index 00000000..ef8d12a3 --- /dev/null +++ b/src/boost/libs/spirit/test/karma/buffer.cpp @@ -0,0 +1,53 @@ +// 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/karma_numeric.hpp> +#include <boost/spirit/include/karma_generate.hpp> +#include <boost/spirit/include/karma_operator.hpp> +#include <boost/spirit/include/karma_directive.hpp> +#include <boost/spirit/include/karma_char.hpp> + +#include <iostream> +#include "test.hpp" + +int +main() +{ + using namespace spirit_test; + using namespace boost::spirit; + + { + using boost::spirit::karma::double_; + using boost::spirit::karma::buffer; + + std::vector<double> v; + BOOST_TEST(test("", -buffer['[' << +double_ << ']'], v)); + + v.push_back(1.0); + v.push_back(2.0); + BOOST_TEST(test("[1.02.0]", buffer['[' << +double_ << ']'], v)); + BOOST_TEST(test("[1.02.0]", buffer[buffer['[' << +double_ << ']']], v)); + } + + { + using boost::spirit::karma::double_; + using boost::spirit::karma::buffer; + using boost::spirit::ascii::space; + + std::vector<double> v; + BOOST_TEST(test_delimited("", + -buffer['[' << +double_ << ']'], v, space)); + + v.push_back(1.0); + v.push_back(2.0); + BOOST_TEST(test_delimited("[ 1.0 2.0 ] ", + buffer['[' << +double_ << ']'], v, space)); + } + + return boost::report_errors(); +} diff --git a/src/boost/libs/spirit/test/karma/case_handling1.cpp b/src/boost/libs/spirit/test/karma/case_handling1.cpp new file mode 100644 index 00000000..2af1dafe --- /dev/null +++ b/src/boost/libs/spirit/test/karma/case_handling1.cpp @@ -0,0 +1,96 @@ +// 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/detail/workaround.hpp> + +#include <boost/spirit/include/karma_char.hpp> +#include <boost/spirit/include/karma_string.hpp> +#include <boost/spirit/include/karma_generate.hpp> +#include <boost/spirit/include/karma_directive.hpp> + +#include "test.hpp" + +using namespace spirit_test; + +/////////////////////////////////////////////////////////////////////////////// +int +main() +{ + using namespace boost::spirit; + + { + using namespace boost::spirit::ascii; + + BOOST_TEST(test("x", lower['X'])); + BOOST_TEST(test("x", lower['x'])); + + BOOST_TEST(test("x", lower[char_], 'X')); + BOOST_TEST(test("x", lower[char_], 'x')); + BOOST_TEST(test("x", lower[char_('X')])); + BOOST_TEST(test("x", lower[char_('x')])); + + BOOST_TEST(test(" ", lower[space])); + BOOST_TEST(test("\t", lower[space], '\t')); + + BOOST_TEST(test("x", lower[lower['X']])); + BOOST_TEST(test("x", lower[lower['x']])); + + BOOST_TEST(test("x", lower[lower[char_]], 'X')); + BOOST_TEST(test("x", lower[lower[char_]], 'x')); + BOOST_TEST(test("x", lower[lower[char_('X')]])); + BOOST_TEST(test("x", lower[lower[char_('x')]])); + + BOOST_TEST(test(" ", lower[lower[space]])); + BOOST_TEST(test("\t", lower[lower[space]], '\t')); + + BOOST_TEST(test("X", upper[lower['X']])); + BOOST_TEST(test("X", upper[lower['x']])); + + BOOST_TEST(test("X", upper[lower[char_]], 'X')); + BOOST_TEST(test("X", upper[lower[char_]], 'x')); + BOOST_TEST(test("X", upper[lower[char_('X')]])); + BOOST_TEST(test("X", upper[lower[char_('x')]])); + + BOOST_TEST(test(" ", upper[lower[space]])); + BOOST_TEST(test("\t", upper[lower[space]], '\t')); + + BOOST_TEST(test("X", upper['X'])); + BOOST_TEST(test("X", upper['x'])); + + BOOST_TEST(test("X", upper[char_], 'X')); + BOOST_TEST(test("X", upper[char_], 'x')); + BOOST_TEST(test("X", upper[char_('X')])); + BOOST_TEST(test("X", upper[char_('x')])); + + BOOST_TEST(test(" ", upper[space])); + BOOST_TEST(test("\t", upper[space], '\t')); + + BOOST_TEST(test("x", lower[upper['X']])); + BOOST_TEST(test("x", lower[upper['x']])); + + BOOST_TEST(test("x", lower[upper[char_]], 'X')); + BOOST_TEST(test("x", lower[upper[char_]], 'x')); + BOOST_TEST(test("x", lower[upper[char_('X')]])); + BOOST_TEST(test("x", lower[upper[char_('x')]])); + + BOOST_TEST(test(" ", lower[upper[space]])); + BOOST_TEST(test("\t", lower[upper[space]], '\t')); + + BOOST_TEST(test("X", upper[upper['X']])); + BOOST_TEST(test("X", upper[upper['x']])); + + BOOST_TEST(test("X", upper[upper[char_]], 'X')); + BOOST_TEST(test("X", upper[upper[char_]], 'x')); + BOOST_TEST(test("X", upper[upper[char_('X')]])); + BOOST_TEST(test("X", upper[upper[char_('x')]])); + + BOOST_TEST(test(" ", upper[upper[space]])); + BOOST_TEST(test("\t", upper[upper[space]], '\t')); + } + + return boost::report_errors(); +} diff --git a/src/boost/libs/spirit/test/karma/case_handling2.cpp b/src/boost/libs/spirit/test/karma/case_handling2.cpp new file mode 100644 index 00000000..16687106 --- /dev/null +++ b/src/boost/libs/spirit/test/karma/case_handling2.cpp @@ -0,0 +1,114 @@ +// 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/detail/workaround.hpp> + +#include <boost/spirit/include/karma_char.hpp> +#include <boost/spirit/include/karma_string.hpp> +#include <boost/spirit/include/karma_generate.hpp> +#include <boost/spirit/include/karma_directive.hpp> + +#include "test.hpp" + +using namespace spirit_test; + +/////////////////////////////////////////////////////////////////////////////// +int +main() +{ + using namespace boost::spirit; + + { + using namespace boost::spirit::standard_wide; + + BOOST_TEST(test(L"x", lower[L'X'])); + BOOST_TEST(test(L"x", lower[L'x'])); + + BOOST_TEST(test(L"x", lower[char_], L'X')); + BOOST_TEST(test(L"x", lower[char_], L'x')); + BOOST_TEST(test(L"x", lower[char_(L'X')])); + BOOST_TEST(test(L"x", lower[char_(L'x')])); + + BOOST_TEST(test(L" ", lower[space])); + BOOST_TEST(test(L"\t", lower[space], L'\t')); + + BOOST_TEST(test(L"x", lower[lower[L'X']])); + BOOST_TEST(test(L"x", lower[lower[L'x']])); + + BOOST_TEST(test(L"x", lower[lower[char_]], L'X')); + BOOST_TEST(test(L"x", lower[lower[char_]], L'x')); + BOOST_TEST(test(L"x", lower[lower[char_(L'X')]])); + BOOST_TEST(test(L"x", lower[lower[char_(L'x')]])); + + BOOST_TEST(test(L" ", lower[lower[space]])); + BOOST_TEST(test(L"\t", lower[lower[space]], L'\t')); + + BOOST_TEST(test(L"X", upper[lower[L'X']])); + BOOST_TEST(test(L"X", upper[lower[L'x']])); + + BOOST_TEST(test(L"X", upper[lower[char_]], L'X')); + BOOST_TEST(test(L"X", upper[lower[char_]], L'x')); + BOOST_TEST(test(L"X", upper[lower[char_(L'X')]])); + BOOST_TEST(test(L"X", upper[lower[char_(L'x')]])); + + BOOST_TEST(test(L" ", upper[lower[space]])); + BOOST_TEST(test(L"\t", upper[lower[space]], L'\t')); + + BOOST_TEST(test(L"X", upper[L'X'])); + BOOST_TEST(test(L"X", upper[L'x'])); + + BOOST_TEST(test(L"X", upper[char_], L'X')); + BOOST_TEST(test(L"X", upper[char_], L'x')); + BOOST_TEST(test(L"X", upper[char_(L'X')])); + BOOST_TEST(test(L"X", upper[char_(L'x')])); + + BOOST_TEST(test(L" ", upper[space])); + BOOST_TEST(test(L"\t", upper[space], L'\t')); + + BOOST_TEST(test(L"x", lower[upper[L'X']])); + BOOST_TEST(test(L"x", lower[upper[L'x']])); + + BOOST_TEST(test(L"x", lower[upper[char_]], L'X')); + BOOST_TEST(test(L"x", lower[upper[char_]], L'x')); + BOOST_TEST(test(L"x", lower[upper[char_(L'X')]])); + BOOST_TEST(test(L"x", lower[upper[char_(L'x')]])); + + BOOST_TEST(test(L" ", lower[upper[space]])); + BOOST_TEST(test(L"\t", lower[upper[space]], L'\t')); + + BOOST_TEST(test(L"X", upper[upper[L'X']])); + BOOST_TEST(test(L"X", upper[upper[L'x']])); + + BOOST_TEST(test(L"X", upper[upper[char_]], L'X')); + BOOST_TEST(test(L"X", upper[upper[char_]], L'x')); + BOOST_TEST(test(L"X", upper[upper[char_(L'X')]])); + BOOST_TEST(test(L"X", upper[upper[char_(L'x')]])); + + BOOST_TEST(test(L" ", upper[upper[space]])); + BOOST_TEST(test(L"\t", upper[upper[space]], L'\t')); + } + + { // test extended ASCII characters + using namespace boost::spirit::iso8859_1; + + BOOST_TEST(test("\xE4\xE4", lower["\xC4\xE4"])); + BOOST_TEST(test("\xE4\xE4", lower["\xC4\xE4"])); + + BOOST_TEST(test("\xC4\xC4", upper["\xC4\xE4"])); + BOOST_TEST(test("\xC4\xC4", upper["\xC4\xE4"])); + } + + { + using namespace boost::spirit::ascii; + using boost::phoenix::val; + + BOOST_TEST(test("x", lower[val('X')])); + BOOST_TEST(test("x", lower[val('x')])); + } + + return boost::report_errors(); +} diff --git a/src/boost/libs/spirit/test/karma/case_handling3.cpp b/src/boost/libs/spirit/test/karma/case_handling3.cpp new file mode 100644 index 00000000..018a6184 --- /dev/null +++ b/src/boost/libs/spirit/test/karma/case_handling3.cpp @@ -0,0 +1,110 @@ +// 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/detail/workaround.hpp> + +#include <boost/spirit/include/karma_char.hpp> +#include <boost/spirit/include/karma_string.hpp> +#include <boost/spirit/include/karma_generate.hpp> +#include <boost/spirit/include/karma_directive.hpp> + +#include "test.hpp" + +using namespace spirit_test; + +/////////////////////////////////////////////////////////////////////////////// +int +main() +{ + using namespace boost::spirit; + + { // test extended ASCII characters + using namespace boost::spirit::iso8859_1; + + BOOST_TEST(test("\xE4", lower['\xC4'])); + BOOST_TEST(test("\xE4", lower['\xE4'])); + + BOOST_TEST(test("\xC4", upper['\xC4'])); + BOOST_TEST(test("\xC4", upper['\xE4'])); + } + + { + using namespace boost::spirit::ascii; + + BOOST_TEST(test("a1- ", lower["a1- "])); + BOOST_TEST(test("a1- ", lower["a1- "])); + BOOST_TEST(test("a1- ", lower["a1- "])); + BOOST_TEST(test("a1- ", lower["A1- "])); + + BOOST_TEST(test("a1- ", lower[string], "a1- ")); + BOOST_TEST(test("a1- ", lower[string], "A1- ")); + BOOST_TEST(test("a1- ", lower[lit("a1- ")])); + BOOST_TEST(test("a1- ", lower[lit("A1- ")])); + BOOST_TEST(test("a1- ", lower[string("a1- ")])); + BOOST_TEST(test("a1- ", lower[string("A1- ")])); + + BOOST_TEST(test("a1- ", lower[lower["a1- "]])); + BOOST_TEST(test("a1- ", lower[lower["a1- "]])); + BOOST_TEST(test("a1- ", lower[lower["a1- "]])); + BOOST_TEST(test("a1- ", lower[lower["A1- "]])); + + BOOST_TEST(test("a1- ", lower[lower[string]], "a1- ")); + BOOST_TEST(test("a1- ", lower[lower[string]], "A1- ")); + BOOST_TEST(test("a1- ", lower[lower[lit("a1- ")]])); + BOOST_TEST(test("a1- ", lower[lower[lit("A1- ")]])); + BOOST_TEST(test("a1- ", lower[lower[string("a1- ")]])); + BOOST_TEST(test("a1- ", lower[lower[string("A1- ")]])); + + BOOST_TEST(test("A1- ", upper[lower["a1- "]])); + BOOST_TEST(test("A1- ", upper[lower["a1- "]])); + BOOST_TEST(test("A1- ", upper[lower["a1- "]])); + BOOST_TEST(test("A1- ", upper[lower["A1- "]])); + + BOOST_TEST(test("A1- ", upper[lower[string]], "a1- ")); + BOOST_TEST(test("A1- ", upper[lower[string]], "A1- ")); + BOOST_TEST(test("A1- ", upper[lower[lit("a1- ")]])); + BOOST_TEST(test("A1- ", upper[lower[lit("A1- ")]])); + BOOST_TEST(test("A1- ", upper[lower[string("a1- ")]])); + BOOST_TEST(test("A1- ", upper[lower[string("A1- ")]])); + + BOOST_TEST(test("A1- ", upper["a1- "])); + BOOST_TEST(test("A1- ", upper["a1- "])); + BOOST_TEST(test("A1- ", upper["a1- "])); + BOOST_TEST(test("A1- ", upper["A1- "])); + + BOOST_TEST(test("A1- ", upper[string], "a1- ")); + BOOST_TEST(test("A1- ", upper[string], "A1- ")); + BOOST_TEST(test("A1- ", upper[lit("a1- ")])); + BOOST_TEST(test("A1- ", upper[lit("A1- ")])); + + BOOST_TEST(test("a1- ", lower[upper["a1- "]])); + BOOST_TEST(test("a1- ", lower[upper["a1- "]])); + BOOST_TEST(test("a1- ", lower[upper["a1- "]])); + BOOST_TEST(test("a1- ", lower[upper["A1- "]])); + + BOOST_TEST(test("a1- ", lower[upper[string]], "a1- ")); + BOOST_TEST(test("a1- ", lower[upper[string]], "A1- ")); + BOOST_TEST(test("a1- ", lower[upper[lit("a1- ")]])); + BOOST_TEST(test("a1- ", lower[upper[lit("A1- ")]])); + BOOST_TEST(test("a1- ", lower[upper[string("a1- ")]])); + BOOST_TEST(test("a1- ", lower[upper[string("A1- ")]])); + + BOOST_TEST(test("A1- ", upper[upper["a1- "]])); + BOOST_TEST(test("A1- ", upper[upper["a1- "]])); + BOOST_TEST(test("A1- ", upper[upper["a1- "]])); + BOOST_TEST(test("A1- ", upper[upper["A1- "]])); + + BOOST_TEST(test("A1- ", upper[upper[string]], "a1- ")); + BOOST_TEST(test("A1- ", upper[upper[string]], "A1- ")); + BOOST_TEST(test("A1- ", upper[upper[lit("a1- ")]])); + BOOST_TEST(test("A1- ", upper[upper[lit("A1- ")]])); + BOOST_TEST(test("A1- ", upper[upper[string("a1- ")]])); + BOOST_TEST(test("A1- ", upper[upper[string("A1- ")]])); + } + + return boost::report_errors(); +} diff --git a/src/boost/libs/spirit/test/karma/center_alignment.cpp b/src/boost/libs/spirit/test/karma/center_alignment.cpp new file mode 100644 index 00000000..a5e01efe --- /dev/null +++ b/src/boost/libs/spirit/test/karma/center_alignment.cpp @@ -0,0 +1,87 @@ +// 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/karma_char.hpp> +#include <boost/spirit/include/karma_string.hpp> +#include <boost/spirit/include/karma_numeric.hpp> +#include <boost/spirit/include/karma_generate.hpp> +#include <boost/spirit/include/karma_directive.hpp> +#include <boost/spirit/include/karma_upper_lower_case.hpp> + +#include <string> +#include <iterator> + +#include "test.hpp" + +/////////////////////////////////////////////////////////////////////////////// +int +main() +{ + using namespace spirit_test; + using namespace boost::spirit; + using namespace boost::spirit::ascii; + + { + BOOST_TEST(test(" x ", center[char_('x')])); + BOOST_TEST(test(" x ", center[char_], 'x')); + BOOST_TEST(test(" x ", center['x'])); + + BOOST_TEST(test(" x ", center(10)[char_('x')])); + BOOST_TEST(test(" x ", center(10)[char_], 'x')); + BOOST_TEST(test(" x ", center(10)['x'])); + + BOOST_TEST(test("*****x****", center(10, char_('*'))[char_('x')])); + BOOST_TEST(test("*****x****", center(10, '*')[char_], 'x')); + BOOST_TEST(test("*****x****", center(10, '*')['x'])); + BOOST_TEST(test("aaaaaxaaaa", lower[center(10, 'A')['X']])); + BOOST_TEST(test("AAAAAXAAAA", upper[center(10, 'a')['x']])); + + + BOOST_TEST(test("*****x****", center(char_('*'))[char_('x')])); + BOOST_TEST(test("*****x****", center(char_('*'))[char_], 'x')); + BOOST_TEST(test("*****x****", center(char_('*'))['x'])); + + BOOST_TEST(test(" x ", center(11)[char_('x')])); + + BOOST_TEST(test(" abc ", center[lit("abc")])); + BOOST_TEST(test(" abc ", center[string], "abc")); + + BOOST_TEST(test(" abc ", center(10)[lit("abc")])); + BOOST_TEST(test(" abc ", center(10)[string], "abc")); + BOOST_TEST(test(" abc ", center(10)["abc"])); + + BOOST_TEST(test(" abc ", center(11)[lit("abc")])); + BOOST_TEST(test(" ab ", center(11)[lit("ab")])); + + BOOST_TEST(test("****abc***", center(10, char_('*'))[lit("abc")])); + BOOST_TEST(test("****abc***", center(10, '*')[string], "abc")); + BOOST_TEST(test("****abc***", center(10, '*')["abc"])); + + BOOST_TEST(test("****abc***", center(char_('*'))[lit("abc")])); + BOOST_TEST(test("****abc***", center(char_('*'))[string], "abc")); + BOOST_TEST(test("****abc***", center(char_('*'))["abc"])); + + BOOST_TEST(test(" abc ", center(11)[lit("abc")])); + + BOOST_TEST(test(" 100 ", center[int_(100)])); + BOOST_TEST(test(" 100 ", center[int_], 100)); + + BOOST_TEST(test(" 100 ", center(10)[int_(100)])); + BOOST_TEST(test(" 100 ", center(10)[int_], 100)); + + BOOST_TEST(test("****100***", center(10, char_('*'))[int_(100)])); + BOOST_TEST(test("****100***", center(10, '*')[int_], 100)); + + BOOST_TEST(test(" 100 ", center(11)[int_(100)])); + + BOOST_TEST(test("****100***", center(char_('*'))[int_(100)])); + BOOST_TEST(test("****100***", center(char_('*'))[int_], 100)); + } + + return boost::report_errors(); +} diff --git a/src/boost/libs/spirit/test/karma/char1.cpp b/src/boost/libs/spirit/test/karma/char1.cpp new file mode 100644 index 00000000..e1c4dc40 --- /dev/null +++ b/src/boost/libs/spirit/test/karma/char1.cpp @@ -0,0 +1,176 @@ +// 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/karma_char.hpp> +#include <boost/spirit/include/karma_generate.hpp> +#include <boost/spirit/include/karma_action.hpp> +#include <boost/spirit/include/karma_phoenix_attributes.hpp> + +#include <boost/spirit/include/phoenix_core.hpp> +#include <boost/spirit/include/phoenix_operator.hpp> +#include <boost/spirit/include/phoenix_statement.hpp> + +#include "test.hpp" + +using namespace spirit_test; + +/////////////////////////////////////////////////////////////////////////////// +int +main() +{ + using namespace boost::spirit; + using namespace boost::phoenix; + + { + using namespace boost::spirit::ascii; + + BOOST_TEST(test("x", 'x')); + BOOST_TEST(test(L"x", L'x')); + BOOST_TEST(!test("x", 'y')); + BOOST_TEST(!test(L"x", L'y')); + + BOOST_TEST(test("x", "x")); + BOOST_TEST(test(L"x", L"x")); + BOOST_TEST(!test("x", "y")); + BOOST_TEST(!test(L"x", L"y")); + + BOOST_TEST(test("x", char_, 'x')); + BOOST_TEST(test(L"x", char_, L'x')); + BOOST_TEST(!test("x", char_, 'y')); + BOOST_TEST(!test(L"x", char_, L'y')); + + BOOST_TEST(test("x", char_('x'))); + BOOST_TEST(!test("x", char_('y'))); + + BOOST_TEST(test("x", char_('x'), 'x')); + BOOST_TEST(!test("", char_('y'), 'x')); + + BOOST_TEST(test("x", char_("x"))); + + BOOST_TEST(test("a", char_('a', 'z'), 'a')); + BOOST_TEST(test("b", char_('a', 'z'), 'b')); + BOOST_TEST(!test("", char_('a', 'z'), 'A')); + + BOOST_TEST(test("a", char_("a-z"), 'a')); + BOOST_TEST(test("b", char_("a-z"), 'b')); + BOOST_TEST(!test("", char_("a-z"), 'A')); + +#if defined(KARMA_FAIL_COMPILATION) + BOOST_TEST(test("x", char_)); // anychar without a parameter doesn't make any sense + BOOST_TEST(test("", char_('a', 'z'))); // char sets without attribute neither +#endif + + BOOST_TEST(!test("", ~char_('x'))); + + BOOST_TEST(!test("", ~char_('x'), 'x')); + BOOST_TEST(test("x", ~char_('y'), 'x')); + + BOOST_TEST(!test("", ~char_("x"))); + + BOOST_TEST(!test("", ~char_('a', 'z'), 'a')); + BOOST_TEST(!test("", ~char_('a', 'z'), 'b')); + BOOST_TEST(test("A", ~char_('a', 'z'), 'A')); + + BOOST_TEST(!test("", ~char_("a-z"), 'a')); + BOOST_TEST(!test("", ~char_("a-z"), 'b')); + BOOST_TEST(test("A", ~char_("a-z"), 'A')); + + BOOST_TEST(test("x", ~~char_('x'))); + BOOST_TEST(!test("x", ~~char_('y'))); + + BOOST_TEST(test("x", ~~char_('x'), 'x')); + BOOST_TEST(!test("", ~~char_('y'), 'x')); + + BOOST_TEST(test("x", ~~char_("x"))); + + BOOST_TEST(test("a", ~~char_('a', 'z'), 'a')); + BOOST_TEST(test("b", ~~char_('a', 'z'), 'b')); + BOOST_TEST(!test("", ~~char_('a', 'z'), 'A')); + + BOOST_TEST(test("a", ~~char_("a-z"), 'a')); + BOOST_TEST(test("b", ~~char_("a-z"), 'b')); + BOOST_TEST(!test("", ~~char_("a-z"), 'A')); + } + + { + using namespace boost::spirit::standard_wide; + + BOOST_TEST(test(L"x", 'x')); + BOOST_TEST(test(L"x", L'x')); + BOOST_TEST(!test(L"x", 'y')); + BOOST_TEST(!test(L"x", L'y')); + + BOOST_TEST(test(L"x", "x")); + BOOST_TEST(test(L"x", L"x")); + BOOST_TEST(!test(L"x", "y")); + BOOST_TEST(!test(L"x", L"y")); + + BOOST_TEST(test(L"x", char_, 'x')); + BOOST_TEST(test(L"x", char_, L'x')); + BOOST_TEST(!test(L"x", char_, 'y')); + BOOST_TEST(!test(L"x", char_, L'y')); + + BOOST_TEST(test(L"x", char_('x'))); + BOOST_TEST(test(L"x", char_(L'x'))); + BOOST_TEST(!test(L"x", char_('y'))); + BOOST_TEST(!test(L"x", char_(L'y'))); + + BOOST_TEST(test(L"x", char_(L'x'), L'x')); + BOOST_TEST(!test(L"", char_('y'), L'x')); + + BOOST_TEST(test(L"x", char_(L"x"))); + + BOOST_TEST(test("a", char_("a", "z"), 'a')); + BOOST_TEST(test(L"a", char_(L"a", L"z"), L'a')); + +#if defined(KARMA_FAIL_COMPILATION) + BOOST_TEST(test("x", char_)); // anychar without a parameter doesn't make any sense +#endif + + BOOST_TEST(!test(L"", ~char_('x'))); + BOOST_TEST(!test(L"", ~char_(L'x'))); + + BOOST_TEST(!test(L"", ~char_(L'x'), L'x')); + BOOST_TEST(test(L"x", ~char_('y'), L'x')); + + BOOST_TEST(!test(L"", ~char_(L"x"))); + } + + { // lazy chars + namespace ascii = boost::spirit::ascii; + namespace wide = boost::spirit::standard_wide; + + using namespace boost::phoenix; + + BOOST_TEST((test("x", ascii::char_(val('x'))))); + BOOST_TEST((test(L"x", wide::char_(val(L'x'))))); + + BOOST_TEST((test("x", ascii::char_(val('x')), 'x'))); + BOOST_TEST((test(L"x", wide::char_(val(L'x')), L'x'))); + + BOOST_TEST((!test("", ascii::char_(val('y')), 'x'))); + BOOST_TEST((!test(L"", wide::char_(val(L'y')), L'x'))); + } + + // we can pass optionals as attributes to any generator + { + namespace ascii = boost::spirit::ascii; + namespace wide = boost::spirit::standard_wide; + + boost::optional<char> v; + boost::optional<wchar_t> w; + + BOOST_TEST(!test("", ascii::char_, v)); + BOOST_TEST(!test(L"", wide::char_, w)); + + BOOST_TEST(!test("", ascii::char_('x'), v)); + BOOST_TEST(!test(L"", wide::char_(L'x'), w)); + } + + return boost::report_errors(); +} diff --git a/src/boost/libs/spirit/test/karma/char2.cpp b/src/boost/libs/spirit/test/karma/char2.cpp new file mode 100644 index 00000000..aae587bf --- /dev/null +++ b/src/boost/libs/spirit/test/karma/char2.cpp @@ -0,0 +1,158 @@ +// 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/karma_char.hpp> +#include <boost/spirit/include/karma_generate.hpp> +#include <boost/spirit/include/karma_action.hpp> +#include <boost/spirit/include/karma_phoenix_attributes.hpp> + +#include <boost/spirit/include/phoenix_core.hpp> +#include <boost/spirit/include/phoenix_operator.hpp> +#include <boost/spirit/include/phoenix_statement.hpp> + +#include "test.hpp" + +using namespace spirit_test; + +/////////////////////////////////////////////////////////////////////////////// +int +main() +{ + using namespace boost::spirit; + using namespace boost::phoenix; + + { + using namespace boost::spirit::ascii; + + BOOST_TEST(test(" ", space)); + BOOST_TEST(test(L" ", space)); + BOOST_TEST(!test("\t", space)); + BOOST_TEST(!test(L"\t", space)); + + BOOST_TEST(test(" ", space, ' ')); + BOOST_TEST(test(L" ", space, L' ')); + BOOST_TEST(test("\t", space, '\t')); + BOOST_TEST(test(L"\t", space, L'\t')); + + BOOST_TEST(!test("", space, 'x')); + BOOST_TEST(!test(L"", space, L'x')); + + BOOST_TEST(!test(" ", ~space, ' ')); + BOOST_TEST(!test(L" ", ~space, L' ')); + + BOOST_TEST(test("x", ~space, 'x')); + BOOST_TEST(test(L"x", ~space, L'x')); + } + + { + using namespace boost::spirit::standard_wide; + + BOOST_TEST(test(" ", space)); + BOOST_TEST(test(L" ", space)); + BOOST_TEST(!test("\t", space)); + BOOST_TEST(!test(L"\t", space)); + + BOOST_TEST(test(" ", space, ' ')); + BOOST_TEST(test(L" ", space, L' ')); + BOOST_TEST(test("\t", space, '\t')); + BOOST_TEST(test(L"\t", space, L'\t')); + + BOOST_TEST(!test("", space, 'x')); + BOOST_TEST(!test(L"", space, L'x')); + } + + { + using namespace boost::spirit::ascii; + + BOOST_TEST(test_delimited("x ", 'x', ' ')); + BOOST_TEST(test_delimited(L"x ", L'x', L' ')); + BOOST_TEST(!test_delimited("x ", 'y', ' ')); + BOOST_TEST(!test_delimited(L"x ", L'y', L' ')); + + BOOST_TEST(test_delimited("x ", 'x', ' ')); + BOOST_TEST(test_delimited(L"x ", L'x', L' ')); + BOOST_TEST(!test_delimited("x ", 'y', ' ')); + BOOST_TEST(!test_delimited(L"x ", L'y', L' ')); + + BOOST_TEST(test_delimited("x ", char_, 'x', ' ')); + BOOST_TEST(test_delimited(L"x ", char_, L'x', L' ')); + BOOST_TEST(!test_delimited("x ", char_, 'y', ' ')); + BOOST_TEST(!test_delimited(L"x ", char_, L'y', L' ')); + + BOOST_TEST(test_delimited("x ", char_('x'), ' ')); + BOOST_TEST(!test_delimited("x ", char_('y'), ' ')); + + BOOST_TEST(test_delimited("x ", char_('x'), 'x', ' ')); + BOOST_TEST(!test_delimited("", char_('y'), 'x', ' ')); + + BOOST_TEST(test_delimited("x ", char_("x"), ' ')); + +#if defined(KARMA_FAIL_COMPILATION) + BOOST_TEST(test_delimited("x ", char_, ' ')); // anychar without a parameter doesn't make any sense +#endif + } + + { // pre-delimiting + { + std::string generated; + std::back_insert_iterator<std::string> it(generated); + BOOST_TEST(karma::generate_delimited(it, '_', '^' + , karma::delimit_flag::predelimit)); + BOOST_TEST(generated == "^_^"); + } + { + using namespace boost::spirit::standard_wide; + std::basic_string<wchar_t> generated; + std::back_insert_iterator<std::basic_string<wchar_t> > it(generated); + BOOST_TEST(karma::generate_delimited(it, char_, L'.' + , karma::delimit_flag::predelimit, L'x')); + BOOST_TEST(generated == L".x."); + } + } + + // action tests + { + using namespace boost::spirit::ascii; + + BOOST_TEST(test("x", char_[_1 = val('x')])); + BOOST_TEST(!test("x", char_[_1 = val('y')])); + } + +// we support Phoenix attributes only starting with V2.2 +#if SPIRIT_VERSION >= 0x2020 + // yes, we can use phoenix expressions as attributes as well + // but only if we include karma_phoenix_attributes.hpp + { + namespace ascii = boost::spirit::ascii; + namespace phoenix = boost::phoenix; + + BOOST_TEST(test("x", ascii::char_, phoenix::val('x'))); + + char c = 'x'; + BOOST_TEST(test("x", ascii::char_, phoenix::ref(c))); + BOOST_TEST(test("y", ascii::char_, ++phoenix::ref(c))); + } +#endif + + { + namespace ascii = boost::spirit::ascii; + namespace wide = boost::spirit::standard_wide; + + boost::optional<char> v ('x'); + boost::optional<wchar_t> w (L'x'); + + BOOST_TEST(test("x", ascii::char_, v)); + BOOST_TEST(test(L"x", wide::char_, w)); + BOOST_TEST(test("x", ascii::char_('x'), v)); + BOOST_TEST(test(L"x", wide::char_(L'x'), w)); + BOOST_TEST(!test("", ascii::char_('y'), v)); + BOOST_TEST(!test(L"", wide::char_(L'y'), w)); + } + + return boost::report_errors(); +} diff --git a/src/boost/libs/spirit/test/karma/char3.cpp b/src/boost/libs/spirit/test/karma/char3.cpp new file mode 100644 index 00000000..55e5978b --- /dev/null +++ b/src/boost/libs/spirit/test/karma/char3.cpp @@ -0,0 +1,103 @@ +// 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/karma_char.hpp> +#include <boost/spirit/include/karma_generate.hpp> +#include <boost/spirit/include/karma_action.hpp> +#include <boost/spirit/include/karma_phoenix_attributes.hpp> + +#include <boost/spirit/include/phoenix_core.hpp> +#include <boost/spirit/include/phoenix_operator.hpp> +#include <boost/spirit/include/phoenix_statement.hpp> + +#include "test.hpp" + +using namespace spirit_test; + +/////////////////////////////////////////////////////////////////////////////// +int +main() +{ + using namespace boost::spirit; + using namespace boost::phoenix; + using boost::spirit::karma::lit; + + { + BOOST_TEST(test("x", lit('x'))); + BOOST_TEST(!test("x", lit('y'))); + + BOOST_TEST(test("x", lit('x'), 'x')); + BOOST_TEST(!test("", lit('y'), 'x')); + +// BOOST_TEST(test("a", lit('a', 'z'), 'a')); +// BOOST_TEST(test("b", lit('a', 'z'), 'b')); +// BOOST_TEST(!test("", lit('a', 'z'), 'A')); + + BOOST_TEST(!test("", ~lit('x'))); + + BOOST_TEST(!test("", ~lit('x'), 'x')); + BOOST_TEST(test("x", ~lit('y'), 'x')); + +// BOOST_TEST(!test("", ~lit('a', 'z'), 'a')); +// BOOST_TEST(!test("", ~lit('a', 'z'), 'b')); +// BOOST_TEST(test("A", ~lit('a', 'z'), 'A')); + + BOOST_TEST(test("x", ~~lit('x'))); + BOOST_TEST(!test("x", ~~lit('y'))); + + BOOST_TEST(test("x", ~~lit('x'), 'x')); + BOOST_TEST(!test("", ~~lit('y'), 'x')); + +// BOOST_TEST(test("a", ~~lit('a', 'z'), 'a')); +// BOOST_TEST(test("b", ~~lit('a', 'z'), 'b')); +// BOOST_TEST(!test("", ~~lit('a', 'z'), 'A')); + } + + { + BOOST_TEST(test(L"x", lit('x'))); + BOOST_TEST(test(L"x", lit(L'x'))); + BOOST_TEST(!test(L"x", lit('y'))); + BOOST_TEST(!test(L"x", lit(L'y'))); + + BOOST_TEST(test(L"x", lit(L'x'), L'x')); + BOOST_TEST(!test(L"", lit('y'), L'x')); + +// BOOST_TEST(test("a", lit("a", "z"), 'a')); +// BOOST_TEST(test(L"a", lit(L"a", L"z"), L'a')); + + BOOST_TEST(!test(L"", ~lit('x'))); + BOOST_TEST(!test(L"", ~lit(L'x'))); + + BOOST_TEST(!test(L"", ~lit(L'x'), L'x')); + BOOST_TEST(test(L"x", ~lit('y'), L'x')); + } + + { // lazy chars + using namespace boost::phoenix; + + BOOST_TEST((test("x", lit(val('x'))))); + BOOST_TEST((test(L"x", lit(val(L'x'))))); + + BOOST_TEST((test("x", lit(val('x')), 'x'))); + BOOST_TEST((test(L"x", lit(val(L'x')), L'x'))); + + BOOST_TEST((!test("", lit(val('y')), 'x'))); + BOOST_TEST((!test(L"", lit(val(L'y')), L'x'))); + } + + // we can pass optionals as attributes to any generator + { + boost::optional<char> v; + boost::optional<wchar_t> w; + + BOOST_TEST(!test("", lit('x'), v)); + BOOST_TEST(!test(L"", lit(L'x'), w)); + } + + return boost::report_errors(); +} diff --git a/src/boost/libs/spirit/test/karma/char_class.cpp b/src/boost/libs/spirit/test/karma/char_class.cpp new file mode 100644 index 00000000..88c5ad6b --- /dev/null +++ b/src/boost/libs/spirit/test/karma/char_class.cpp @@ -0,0 +1,197 @@ +// 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/karma_char.hpp> +#include <boost/spirit/include/karma_generate.hpp> +#include <boost/spirit/include/karma_directive.hpp> + +#include <string> +#include <iterator> + +#include "test.hpp" + +/////////////////////////////////////////////////////////////////////////////// +int main() +{ + using namespace spirit_test; + using namespace boost::spirit; + + { + using namespace boost::spirit::ascii; + BOOST_TEST(test("a", alpha, 'a')); + BOOST_TEST(!test("", alpha, '1')); + BOOST_TEST(test(" ", blank, ' ')); + BOOST_TEST(!test("", blank, 'x')); + BOOST_TEST(test("1", digit, '1')); + BOOST_TEST(!test("", digit, 'x')); + BOOST_TEST(test("a", lower, 'a')); + BOOST_TEST(!test("", lower, 'A')); + BOOST_TEST(test("!", punct, '!')); + BOOST_TEST(!test("", punct, 'x')); + BOOST_TEST(test(" ", space)); + BOOST_TEST(test(" ", space, ' ')); + BOOST_TEST(!test("", space, '\n')); + BOOST_TEST(test("\r", space, '\r')); + BOOST_TEST(test("\t", space, '\t')); + BOOST_TEST(test("A", upper, 'A')); + BOOST_TEST(!test("", upper, 'a')); + BOOST_TEST(test("A", xdigit, 'A')); + BOOST_TEST(test("0", xdigit, '0')); + BOOST_TEST(test("f", xdigit, 'f')); + BOOST_TEST(!test("", xdigit, 'g')); + } + + { + using namespace boost::spirit::ascii; + BOOST_TEST(!test("", ~alpha, 'a')); + BOOST_TEST(test("1", ~alpha, '1')); + BOOST_TEST(!test("", ~blank, ' ')); + BOOST_TEST(test("x", ~blank, 'x')); + BOOST_TEST(!test("", ~digit, '1')); + BOOST_TEST(test("x", ~digit, 'x')); + BOOST_TEST(!test("", ~lower, 'a')); + BOOST_TEST(test("A", ~lower, 'A')); + BOOST_TEST(!test("", ~punct, '!')); + BOOST_TEST(test("x", ~punct, 'x')); + BOOST_TEST(!test("", ~space)); + BOOST_TEST(!test("", ~space, ' ')); + BOOST_TEST(!test("", ~space, '\r')); + BOOST_TEST(!test("", ~space, '\t')); + BOOST_TEST(!test("", ~upper, 'A')); + BOOST_TEST(test("a", ~upper, 'a')); + BOOST_TEST(!test("", ~xdigit, 'A')); + BOOST_TEST(!test("", ~xdigit, '0')); + BOOST_TEST(!test("", ~xdigit, 'f')); + BOOST_TEST(test("g", ~xdigit, 'g')); + } + + { + using namespace boost::spirit::ascii; + BOOST_TEST(test("a", ~~alpha, 'a')); + BOOST_TEST(!test("", ~~alpha, '1')); + BOOST_TEST(test(" ", ~~blank, ' ')); + BOOST_TEST(!test("", ~~blank, 'x')); + BOOST_TEST(test("1", ~~digit, '1')); + BOOST_TEST(!test("", ~~digit, 'x')); + BOOST_TEST(test("a", ~~lower, 'a')); + BOOST_TEST(!test("", ~~lower, 'A')); + BOOST_TEST(test("!", ~~punct, '!')); + BOOST_TEST(!test("", ~~punct, 'x')); + BOOST_TEST(test(" ", ~~space)); + BOOST_TEST(test(" ", ~~space, ' ')); + BOOST_TEST(!test("", ~~space, '\n')); + BOOST_TEST(test("\r", ~~space, '\r')); + BOOST_TEST(test("\t", ~~space, '\t')); + BOOST_TEST(test("A", ~~upper, 'A')); + BOOST_TEST(!test("", ~~upper, 'a')); + BOOST_TEST(test("A", ~~xdigit, 'A')); + BOOST_TEST(test("0", ~~xdigit, '0')); + BOOST_TEST(test("f", ~~xdigit, 'f')); + BOOST_TEST(!test("", ~~xdigit, 'g')); + } + + { + using namespace boost::spirit::ascii; + BOOST_TEST(test("a", lower[alpha], 'a')); + BOOST_TEST(!test("", lower[alpha], 'A')); + BOOST_TEST(!test("", lower[alpha], '1')); + BOOST_TEST(test("a", lower[alnum], 'a')); + BOOST_TEST(!test("", lower[alnum], 'A')); + BOOST_TEST(test("1", lower[alnum], '1')); + + BOOST_TEST(!test("", upper[alpha], 'a')); + BOOST_TEST(test("A", upper[alpha], 'A')); + BOOST_TEST(!test("", upper[alpha], '1')); + BOOST_TEST(!test("", upper[alnum], 'a')); + BOOST_TEST(test("A", upper[alnum], 'A')); + BOOST_TEST(test("1", upper[alnum], '1')); + } + + { + using namespace boost::spirit::iso8859_1; + BOOST_TEST(test("a", alpha, 'a')); + BOOST_TEST(!test("", alpha, '1')); + BOOST_TEST(test(" ", blank, ' ')); + BOOST_TEST(!test("", blank, 'x')); + BOOST_TEST(test("1", digit, '1')); + BOOST_TEST(!test("", digit, 'x')); + BOOST_TEST(test("a", lower, 'a')); + BOOST_TEST(!test("", lower, 'A')); + BOOST_TEST(test("!", punct, '!')); + BOOST_TEST(!test("", punct, 'x')); + BOOST_TEST(test(" ", space)); + BOOST_TEST(test(" ", space, ' ')); + BOOST_TEST(!test("", space, '\n')); + BOOST_TEST(test("\r", space, '\r')); + BOOST_TEST(test("\t", space, '\t')); + BOOST_TEST(test("A", upper, 'A')); + BOOST_TEST(!test("", upper, 'a')); + BOOST_TEST(test("A", xdigit, 'A')); + BOOST_TEST(test("0", xdigit, '0')); + BOOST_TEST(test("f", xdigit, 'f')); + BOOST_TEST(!test("", xdigit, 'g')); + + + // test extended ASCII characters + BOOST_TEST(test("\xE9", alpha, '\xE9')); + BOOST_TEST(test("\xE9", lower, '\xE9')); + BOOST_TEST(!test("", upper, '\xE9')); + } + + { + using namespace boost::spirit::standard; + BOOST_TEST(test("a", alpha, 'a')); + BOOST_TEST(!test("", alpha, '1')); + BOOST_TEST(test(" ", blank, ' ')); + BOOST_TEST(!test("", blank, 'x')); + BOOST_TEST(test("1", digit, '1')); + BOOST_TEST(!test("", digit, 'x')); + BOOST_TEST(test("a", lower, 'a')); + BOOST_TEST(!test("", lower, 'A')); + BOOST_TEST(test("!", punct, '!')); + BOOST_TEST(!test("", punct, 'x')); + BOOST_TEST(test(" ", space)); + BOOST_TEST(test(" ", space, ' ')); + BOOST_TEST(!test("", space, '\n')); + BOOST_TEST(test("\r", space, '\r')); + BOOST_TEST(test("\t", space, '\t')); + BOOST_TEST(test("A", upper, 'A')); + BOOST_TEST(!test("", upper, 'a')); + BOOST_TEST(test("A", xdigit, 'A')); + BOOST_TEST(test("0", xdigit, '0')); + BOOST_TEST(test("f", xdigit, 'f')); + BOOST_TEST(!test("", xdigit, 'g')); + } + + { + using namespace boost::spirit::standard_wide; + BOOST_TEST(test(L"a", alpha, L'a')); + BOOST_TEST(!test(L"", alpha, L'1')); + BOOST_TEST(test(L" ", blank, L' ')); + BOOST_TEST(!test(L"", blank, L'x')); + BOOST_TEST(test(L"1", digit, L'1')); + BOOST_TEST(!test(L"", digit, L'x')); + BOOST_TEST(test(L"a", lower, L'a')); + BOOST_TEST(!test(L"", lower, L'A')); + BOOST_TEST(test(L"!", punct, L'!')); + BOOST_TEST(!test(L"", punct, L'x')); + BOOST_TEST(test(L" ", space)); + BOOST_TEST(test(L" ", space, L' ')); + BOOST_TEST(!test(L"", space, L'\n')); + BOOST_TEST(test(L"\r", space, L'\r')); + BOOST_TEST(test(L"\t", space, L'\t')); + BOOST_TEST(test(L"A", upper, L'A')); + BOOST_TEST(!test(L"", upper, L'a')); + BOOST_TEST(test(L"A", xdigit, L'A')); + BOOST_TEST(test(L"0", xdigit, L'0')); + BOOST_TEST(test(L"f", xdigit, L'f')); + BOOST_TEST(!test(L"", xdigit, L'g')); + } + + return boost::report_errors(); +} diff --git a/src/boost/libs/spirit/test/karma/columns.cpp b/src/boost/libs/spirit/test/karma/columns.cpp new file mode 100644 index 00000000..070724b4 --- /dev/null +++ b/src/boost/libs/spirit/test/karma/columns.cpp @@ -0,0 +1,97 @@ +// 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/karma_char.hpp> +#include <boost/spirit/include/karma_generate.hpp> +#include <boost/spirit/include/karma_numeric.hpp> +#include <boost/spirit/include/karma_directive.hpp> + +#include <boost/spirit/include/karma_nonterminal.hpp> +#include <boost/spirit/include/karma_action.hpp> + +#include <boost/spirit/include/phoenix_core.hpp> + +#include "test.hpp" + +using namespace spirit_test; +namespace karma = boost::spirit::karma; + +/////////////////////////////////////////////////////////////////////////////// +int +main() +{ + { + using karma::columns; + using karma::int_; + + std::vector<int> v; + for (int i = 0; i < 11; ++i) + v.push_back(i); + + BOOST_TEST(test("01234\n56789\n10\n", columns[*int_], v)); + BOOST_TEST(test_delimited("0 1 2 3 4 \n5 6 7 8 9 \n10 \n", columns[*int_] + , v, karma::space)); + } + + { + using karma::columns; + using karma::int_; + + std::vector<int> v; + for (int i = 0; i < 11; ++i) + v.push_back(i); + + BOOST_TEST(test("012\n345\n678\n910\n", columns(3)[*int_], v)); + BOOST_TEST(test_delimited("0 1 2 \n3 4 5 \n6 7 8 \n9 10 \n" + , columns(3)[*int_], v, karma::space)); + } + + { + using karma::columns; + using karma::int_; + using boost::phoenix::ref; + + std::vector<int> v; + for (int i = 0; i < 11; ++i) + v.push_back(i); + + int count = 3; + BOOST_TEST(test("012\n345\n678\n910\n", columns(ref(count))[*int_], v)); + BOOST_TEST(test_delimited("0 1 2 \n3 4 5 \n6 7 8 \n9 10 \n" + , columns(val(ref(count)))[*int_], v, karma::space)); + } + + { + using karma::columns; + using karma::int_; + using karma::lit; + + std::vector<int> v; + for (int i = 0; i < 11; ++i) + v.push_back(i); + + BOOST_TEST(test("01234\t56789\t10\t", columns(lit('\t'))[*int_], v)); + BOOST_TEST(test_delimited("0 1 2 3 4 \t5 6 7 8 9 \t10 \t" + , columns(lit('\t'))[*int_], v, karma::space)); + } + + { + using karma::columns; + using karma::int_; + using karma::lit; + + std::vector<int> v; + for (int i = 0; i < 11; ++i) + v.push_back(i); + + BOOST_TEST(test("012\t345\t678\t910\t", columns(3, lit('\t'))[*int_], v)); + BOOST_TEST(test_delimited("0 1 2 \t3 4 5 \t6 7 8 \t9 10 \t" + , columns(3, lit('\t'))[*int_], v, karma::space)); + } + return boost::report_errors(); +} diff --git a/src/boost/libs/spirit/test/karma/debug.cpp b/src/boost/libs/spirit/test/karma/debug.cpp new file mode 100644 index 00000000..19137d44 --- /dev/null +++ b/src/boost/libs/spirit/test/karma/debug.cpp @@ -0,0 +1,107 @@ +// 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) + +#define BOOST_SPIRIT_KARMA_DEBUG + +#include <boost/detail/lightweight_test.hpp> +#include <boost/spirit/include/karma_operator.hpp> +#include <boost/spirit/include/karma_char.hpp> +#include <boost/spirit/include/karma_string.hpp> +#include <boost/spirit/include/karma_numeric.hpp> +#include <boost/spirit/include/karma_auxiliary.hpp> +#include <boost/spirit/include/karma_nonterminal.hpp> +#include <boost/spirit/include/karma_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; + using spirit_test::test_delimited; + + using namespace boost::spirit::ascii; + using namespace boost::spirit::karma::labels; + using boost::spirit::karma::locals; + using boost::spirit::karma::rule; + using boost::spirit::karma::char_; + using boost::spirit::karma::debug; + using boost::spirit::karma::space; + using boost::spirit::karma::eps; + + typedef spirit_test::output_iterator<char>::type outiter_type; + + { // basic tests + rule<outiter_type, char()> a, b, c; + rule<outiter_type, std::vector<char>()> start; + + std::vector<char> v; + v.push_back('a'); + v.push_back('b'); + v.push_back('a'); + v.push_back('c'); + v.push_back('a'); + v.push_back('b'); + v.push_back('b'); + v.push_back('a'); + + a = char_('a'); + b = char_('b'); + c = char_('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("abacabba", start, v)); + + // ignore the delimiter + BOOST_TEST(test_delimited("abacabba ", start, v, space)); + + std::vector<char> v1; + v1.push_back('b'); + v1.push_back('c'); + + start = (a | b) << c; + BOOST_SPIRIT_DEBUG_NODE(start); + BOOST_TEST(test("bc", start, v1)); + } + + { // tests with locals + rule<outiter_type, char()> a, b, c; + rule<outiter_type, std::vector<char>(), locals<int, double> > start; + + std::vector<char> v; + v.push_back('a'); + v.push_back('b'); + v.push_back('a'); + v.push_back('c'); + v.push_back('a'); + v.push_back('b'); + v.push_back('b'); + v.push_back('a'); + + a = char_('a'); + b = char_('b'); + c = char_('c'); + BOOST_SPIRIT_DEBUG_NODE(a); + BOOST_SPIRIT_DEBUG_NODE(b); + BOOST_SPIRIT_DEBUG_NODE(c); + + start %= eps[_a = 0, _b = 2.0] << *(a[++_a] | b | c); + BOOST_SPIRIT_DEBUG_NODE(start); + BOOST_TEST(test("abacabba", start, v)); + } + + return boost::report_errors(); +} + diff --git a/src/boost/libs/spirit/test/karma/delimiter.cpp b/src/boost/libs/spirit/test/karma/delimiter.cpp new file mode 100644 index 00000000..15133189 --- /dev/null +++ b/src/boost/libs/spirit/test/karma/delimiter.cpp @@ -0,0 +1,83 @@ +// 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/karma_char.hpp> +#include <boost/spirit/include/karma_generate.hpp> +#include <boost/spirit/include/karma_directive.hpp> +#include <boost/spirit/include/karma_operator.hpp> +#include <boost/spirit/include/karma_nonterminal.hpp> +#include <boost/spirit/include/karma_string.hpp> + +#include "test.hpp" + +using namespace spirit_test; + +/////////////////////////////////////////////////////////////////////////////// +int +main() +{ + using namespace boost::spirit; + using namespace boost::spirit::ascii; + + { + BOOST_TEST(test("a b ", delimit[char_('a') << 'b'])); + BOOST_TEST(test("a*b*", delimit('*')[char_('a') << 'b'])); + + BOOST_TEST(test("ab c d", + char_('a') << delimit[char_('b') << 'c'] << 'd')); + BOOST_TEST(test("ab*c*d", + char_('a') << delimit('*')[char_('b') << 'c'] << 'd')); + + BOOST_TEST(test_delimited("a b ", delimit[char_('a') << 'b'], char_(' '))); + BOOST_TEST(test_delimited("a*b*", delimit('*')[char_('a') << 'b'], char_(' '))); + + BOOST_TEST(test_delimited("a b c d ", + char_('a') << delimit[char_('b') << 'c'] << 'd', char_(' '))); + BOOST_TEST(test_delimited("a b*c*d ", + char_('a') << delimit('*')[char_('b') << 'c'] << 'd', char_(' '))); + } + + { + BOOST_TEST(test("ab", verbatim[char_('a') << 'b'])); + BOOST_TEST(test("abcd", + char_('a') << verbatim[char_('b') << 'c'] << 'd')); + + BOOST_TEST(test_delimited("ab ", + verbatim[char_('a') << 'b'], char_(' '))); + BOOST_TEST(test_delimited("a bc d ", + char_('a') << verbatim[char_('b') << 'c'] << 'd', char_(' '))); + } + + { + BOOST_TEST(test("ab", no_delimit[char_('a') << 'b'])); + BOOST_TEST(test("abcd", + char_('a') << no_delimit[char_('b') << 'c'] << 'd')); + + BOOST_TEST(test_delimited("ab", + no_delimit[char_('a') << 'b'], char_(' '))); + BOOST_TEST(test_delimited("a bcd ", + char_('a') << no_delimit[char_('b') << 'c'] << 'd', char_(' '))); + } + + { + // The doubled delimiters at the end are generated by the 'b' generator + // and the verbatim[] directive. Currently, there is no easy way to + // avoid this. + BOOST_TEST(test("a b ", delimit[verbatim[delimit[char_('a') << 'b']]])); + BOOST_TEST(test_delimited("a*b**", + verbatim[delimit[char_('a') << 'b']], char_('*'))); + } + + { + karma::rule<output_iterator<char>::type, BOOST_TYPEOF(", ")> r = "abc"; + BOOST_TEST(test("abc, ", delimit(", ")[r])); + } + + return boost::report_errors(); +} + diff --git a/src/boost/libs/spirit/test/karma/duplicate.cpp b/src/boost/libs/spirit/test/karma/duplicate.cpp new file mode 100644 index 00000000..57f824b4 --- /dev/null +++ b/src/boost/libs/spirit/test/karma/duplicate.cpp @@ -0,0 +1,56 @@ +// 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/karma.hpp> + +#include <iostream> +#include "test.hpp" + +using namespace spirit_test; + +int main() +{ + using boost::spirit::karma::double_; + using boost::spirit::karma::space; + using boost::spirit::karma::duplicate; + + // test for sequences + { + BOOST_TEST(test("2.02.0", duplicate[double_ << double_], 2.0)); + BOOST_TEST(test_delimited("2.0 2.0 ", + duplicate[double_ << double_], 2.0, space)); + BOOST_TEST(test("2.02.02.0", + duplicate[double_ << double_ << double_], 2.0)); + BOOST_TEST(test_delimited("2.0 2.0 2.0 ", + duplicate[double_ << double_ << double_], 2.0, space)); + } + + // test for non-sequences + { + BOOST_TEST(test("2.02.0", duplicate["2.0" << double_], 2.0)); + BOOST_TEST(test_delimited("2.0 2.0 ", + duplicate["2.0" << double_], 2.0, space)); + } + + // test for subjects exposing no attribute + { + BOOST_TEST(test("2.02.0", duplicate["2.0"] << double_, 2.0)); + BOOST_TEST(test_delimited("2.0 2.0 ", + duplicate["2.0"] << double_, 2.0, space)); + } + + // test for attribute reporting + { + BOOST_TEST(test("bar", (duplicate["bar"] | "foo"))); + BOOST_TEST(test("2.0", (duplicate[double_] | "foo"), 2.0)); + BOOST_TEST(test("2.02.0", + (duplicate[double_ << double_] | "foo"), 2.0)); + } + + return boost::report_errors(); +} diff --git a/src/boost/libs/spirit/test/karma/encoding.cpp b/src/boost/libs/spirit/test/karma/encoding.cpp new file mode 100644 index 00000000..05e8018c --- /dev/null +++ b/src/boost/libs/spirit/test/karma/encoding.cpp @@ -0,0 +1,55 @@ +// 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/karma_char.hpp> +#include <boost/spirit/include/karma_string.hpp> +#include <boost/spirit/include/karma_directive.hpp> +#include <boost/spirit/include/karma_action.hpp> + +#include <iostream> +#include "test.hpp" + +int +main() +{ + using spirit_test::test; + using boost::spirit::karma::lit; + using boost::spirit::karma::lower; + using boost::spirit::karma::upper; + using boost::spirit::karma::char_; + using boost::spirit::karma::encoding; + namespace char_encoding = boost::spirit::char_encoding; + + encoding<char_encoding::iso8859_1> iso8859_1; + + { // test extended ASCII characters + BOOST_TEST(test("\xE1", iso8859_1[lower['\xE1']])); + BOOST_TEST(test("\xC1", iso8859_1[upper['\xE1']])); + BOOST_TEST(test("\xE1", iso8859_1[lower[char_('\xE1')]])); + BOOST_TEST(test("\xC1", iso8859_1[upper[char_('\xE1')]])); + BOOST_TEST(test("\xE1", iso8859_1[lower[lit('\xE1')]])); + BOOST_TEST(test("\xC1", iso8859_1[upper[lit('\xE1')]])); + BOOST_TEST(test("\xE1", iso8859_1[lower[char_]], '\xE1')); + BOOST_TEST(test("\xC1", iso8859_1[upper[char_]], '\xE1')); + BOOST_TEST(test("\xE1", iso8859_1[lower['\xC1']])); + BOOST_TEST(test("\xC1", iso8859_1[upper['\xC1']])); + BOOST_TEST(test("\xE1", iso8859_1[lower[char_('\xC1')]])); + BOOST_TEST(test("\xC1", iso8859_1[upper[char_('\xC1')]])); + BOOST_TEST(test("\xE1", iso8859_1[lower[lit('\xC1')]])); + BOOST_TEST(test("\xC1", iso8859_1[upper[lit('\xC1')]])); + BOOST_TEST(test("\xE1", iso8859_1[lower[char_]], '\xC1')); + BOOST_TEST(test("\xC1", iso8859_1[upper[char_]], '\xC1')); + + BOOST_TEST(test("\xE4\xE4", iso8859_1[lower["\xC4\xE4"]])); + BOOST_TEST(test("\xE4\xE4", iso8859_1[lower[lit("\xC4\xE4")]])); + + BOOST_TEST(test("\xC4\xC4", iso8859_1[upper["\xC4\xE4"]])); + BOOST_TEST(test("\xC4\xC4", iso8859_1[upper[lit("\xC4\xE4")]])); + } + + return boost::report_errors(); +} diff --git a/src/boost/libs/spirit/test/karma/eol.cpp b/src/boost/libs/spirit/test/karma/eol.cpp new file mode 100644 index 00000000..cf4e18d1 --- /dev/null +++ b/src/boost/libs/spirit/test/karma/eol.cpp @@ -0,0 +1,33 @@ +// 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/karma_auxiliary.hpp> +#include <boost/spirit/include/karma_char.hpp> +#include <boost/spirit/include/karma_generate.hpp> + +#include <iostream> +#include "test.hpp" + +int +main() +{ + using namespace spirit_test; + using namespace boost::spirit; + using namespace boost::spirit::ascii; + + { + BOOST_TEST((test("\n", eol))); + BOOST_TEST((test("\n", eol))); + } + + { + BOOST_TEST((test_delimited("\n ", eol, space))); + BOOST_TEST((test_delimited("\n ", eol, space))); + } + + return boost::report_errors(); +} diff --git a/src/boost/libs/spirit/test/karma/eps.cpp b/src/boost/libs/spirit/test/karma/eps.cpp new file mode 100644 index 00000000..6833d273 --- /dev/null +++ b/src/boost/libs/spirit/test/karma/eps.cpp @@ -0,0 +1,59 @@ +// 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/karma_auxiliary.hpp> +#include <boost/spirit/include/karma_char.hpp> +#include <boost/spirit/include/karma_numeric.hpp> +#include <boost/spirit/include/karma_generate.hpp> +#include <boost/spirit/include/karma_operator.hpp> +#include <boost/spirit/include/phoenix_core.hpp> + +#include <iostream> +#include "test.hpp" + +int +main() +{ + using namespace spirit_test; + using namespace boost::spirit; + + { + using namespace boost::spirit::ascii; + + BOOST_TEST(test("", eps)); + BOOST_TEST(test_delimited(" ", eps, space)); + + BOOST_TEST(!test("", !eps)); + BOOST_TEST(!test_delimited(" ", !eps, space)); + } + + { // test direct argument + using namespace boost::phoenix; + + BOOST_TEST(test("", eps(true))); + BOOST_TEST(!test("", eps(false))); + } + + { // test action + using namespace boost::phoenix; + + BOOST_TEST(test("", eps(val(true)))); + BOOST_TEST(!test("", eps(val(false)))); + } + + { // test no delimiter when argument is false + using namespace boost::spirit::ascii; + + std::string generated; + std::back_insert_iterator<std::string> outit(generated); + BOOST_TEST(!karma::generate_delimited(outit, eps(false), space)); + BOOST_TEST(generated.empty()); + } + + return boost::report_errors(); +} diff --git a/src/boost/libs/spirit/test/karma/format_manip.cpp b/src/boost/libs/spirit/test/karma/format_manip.cpp new file mode 100644 index 00000000..494eee4a --- /dev/null +++ b/src/boost/libs/spirit/test/karma/format_manip.cpp @@ -0,0 +1,215 @@ +// 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/mpl/print.hpp> +#include <boost/config/warning_disable.hpp> +#include <boost/spirit/include/karma.hpp> +#include <boost/spirit/include/karma_format.hpp> +#include <boost/spirit/include/karma_format_auto.hpp> +#include <boost/spirit/include/karma_stream.hpp> +#include <boost/spirit/include/phoenix_core.hpp> +#include <boost/spirit/include/phoenix_operator.hpp> + +#include <string> +#include <sstream> +#include <vector> +#include <list> + +#include <boost/detail/lightweight_test.hpp> +#include <boost/assign/std/vector.hpp> +#include <boost/assign/std/list.hpp> + +/////////////////////////////////////////////////////////////////////////////// +template <typename Char, typename Expr> +bool test(Char const *expected, Expr const& xpr) +{ + // Report invalid expression error as early as possible. + // If you got an error_invalid_expression error message here, + // then the expression (expr) is not a valid spirit karma expression. + BOOST_SPIRIT_ASSERT_MATCH(boost::spirit::karma::domain, Expr); + + std::ostringstream ostrm; + ostrm << boost::spirit::compile<boost::spirit::karma::domain>(xpr); + return ostrm.good() && ostrm.str() == expected; +} + +template <typename Char, typename Expr, typename CopyExpr, typename CopyAttr + , typename Delimiter, typename Attribute> +bool test(Char const *expected, + boost::spirit::karma::detail::format_manip< + Expr, CopyExpr, CopyAttr, Delimiter, Attribute> const& fm) +{ + std::ostringstream ostrm; + ostrm << fm; + return ostrm.good() && ostrm.str() == expected; +} + +/////////////////////////////////////////////////////////////////////////////// +int +main() +{ + using namespace boost::spirit; + using namespace boost::spirit::ascii; + + namespace fusion = boost::fusion; + using namespace boost::phoenix; + + { + BOOST_TEST(test( "a", + char_('a') + )); + BOOST_TEST(test( "a", + char_[_1 = val('a')] + )); + BOOST_TEST(test( "a", + karma::format(char_[_1 = val('a')]) + )); + BOOST_TEST(test( "a ", + karma::format_delimited(char_[_1 = val('a')], space) + )); + BOOST_TEST(test( "a", + karma::format(char_, 'a') + )); + BOOST_TEST(test( "a ", + karma::format_delimited(char_, space, 'a') + )); + } + + { + BOOST_TEST(test( "ab", + char_[_1 = val('a')] << char_[_1 = val('b')] + )); + BOOST_TEST(test( "ab", + karma::format(char_[_1 = val('a')] << char_[_1 = val('b')]) + )); + BOOST_TEST(test( "a b ", + karma::format_delimited(char_[_1 = val('a')] << char_[_1 = val('b')], space) + )); + + fusion::vector<char, char> t('a', 'b'); + + BOOST_TEST(test( "ab", + karma::format(char_ << char_, t) + )); + BOOST_TEST(test( "a b ", + karma::format_delimited(char_ << char_, space, t) + )); + + BOOST_TEST(test( "ab", + karma::format(t) + )); + BOOST_TEST(test( "a b ", + karma::format_delimited(t, space) + )); + } + + { + BOOST_TEST(test( "abc", + char_[_1 = 'a'] << char_[_1 = 'b'] << char_[_1 = 'c'] + )); + BOOST_TEST(test( "abc", + karma::format(char_('a') << char_('b') << char_('c')) + )); + BOOST_TEST(test( "a b c ", + karma::format_delimited(char_('a') << char_('b') << char_('c'), space) + )); + + fusion::vector<char, char, char> t('a', 'b', 'c'); + + BOOST_TEST(test( "abc", + karma::format(char_ << char_ << char_, t) + )); + BOOST_TEST(test( "a b c ", + karma::format_delimited(char_ << char_ << char_, space, t) + )); + } + + { + BOOST_TEST(test( "a2", + (char_ << int_)[_1 = 'a', _2 = 2] + )); + + fusion::vector<char, int> t('a', 2); + + BOOST_TEST(test( "a2", + karma::format(char_ << int_, t) + )); + BOOST_TEST(test( "a 2 ", + karma::format_delimited(char_ << int_, space, t) + )); + } + + using namespace boost::assign; + + { + // output all elements of a vector + std::vector<char> v; + v += 'a', 'b', 'c'; + + BOOST_TEST(test( "abc", + (*char_)[_1 = v] + )); + BOOST_TEST(test( "abc", + karma::format(*char_, v) + )); + BOOST_TEST(test( "a b c ", + karma::format_delimited(*char_, space, v) + )); + + BOOST_TEST(test( "abc", + karma::format(v) + )); + BOOST_TEST(test( "a b c ", + karma::format_delimited(v, space) + )); + + // output a comma separated list of vector elements + BOOST_TEST(test( "a, b, c", + (char_ % lit(", "))[_0 = fusion::make_single_view(v)] + )); + BOOST_TEST(test( "a, b, c", + karma::format((char_ % lit(", "))[_0 = fusion::make_single_view(v)]) + )); + BOOST_TEST(test( "a , b , c ", + karma::format_delimited((char_ % ',')[_0 = fusion::make_single_view(v)], space) + )); + BOOST_TEST(test( "a,b,c", + karma::format(char_ % ',', v) + )); + BOOST_TEST(test( "a , b , c ", + karma::format_delimited(char_ % ',', space, v) + )); + + // output all elements of a list + std::list<char> l; + l += 'a', 'b', 'c'; + +// BOOST_TEST(test( "abc", +// (*char_)[_1 = l] +// )); +// BOOST_TEST(test( "abc", +// karma::format((*char_)[_1 = l]) +// )); +// BOOST_TEST(test( "a b c ", +// karma::format_delimited((*char_)[_1 = l], space) +// )); + BOOST_TEST(test( "abc", + karma::format(*char_, l) + )); + BOOST_TEST(test( "a b c ", + karma::format_delimited(*char_, space, l) + )); + + BOOST_TEST(test( "abc", + karma::format(l) + )); + BOOST_TEST(test( "a b c ", + karma::format_delimited(l, space) + )); + } + + return boost::report_errors(); +} + diff --git a/src/boost/libs/spirit/test/karma/format_manip_attr.cpp b/src/boost/libs/spirit/test/karma/format_manip_attr.cpp new file mode 100644 index 00000000..75645aed --- /dev/null +++ b/src/boost/libs/spirit/test/karma/format_manip_attr.cpp @@ -0,0 +1,175 @@ +// 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/karma_char.hpp> +#include <boost/spirit/include/karma_numeric.hpp> +#include <boost/spirit/include/karma_directive.hpp> +#include <boost/spirit/include/karma_operator.hpp> +#include <boost/spirit/include/karma_action.hpp> +#include <boost/spirit/include/karma_stream.hpp> +#include <boost/spirit/include/karma_format_attr.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 spirit_test::test; +using spirit_test::test_delimited; +using spirit_test::test_predelimited; + +/////////////////////////////////////////////////////////////////////////////// +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_delimited("1 ", char_, space, '1')); + BOOST_TEST(test_delimited("1 2 " + , char_ << char_, space, '1', '2')); + BOOST_TEST(test_delimited("1 2 3 " + , char_ << char_ << char_, space, '1', '2', '3')); + BOOST_TEST(test_delimited("1 2 3 4 " + , char_ << char_ << char_ << char_ + , space, '1', '2', '3', '4')); + BOOST_TEST(test_delimited("1 2 3 4 5 " + , char_ << char_ << char_ << char_ << char_ + , space, '1', '2', '3', '4', '5')); + BOOST_TEST(test_delimited("1 2 3 4 5 6 " + , char_ << char_ << char_ << char_ << char_ << char_ + , space, '1', '2', '3', '4', '5', '6')); + BOOST_TEST(test_delimited("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_delimited("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_delimited("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_delimited("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::karma::delimit_flag; + + BOOST_TEST(test_predelimited(" 1 ", char_, space + , delimit_flag::predelimit, '1')); + BOOST_TEST(test_predelimited(" 1 2 " + , char_ << char_, space, delimit_flag::predelimit + , '1', '2')); + BOOST_TEST(test_predelimited(" 1 2 3 " + , char_ << char_ << char_, space + , delimit_flag::predelimit, '1', '2', '3')); + BOOST_TEST(test_predelimited(" 1 2 3 4 " + , char_ << char_ << char_ << char_ + , space, delimit_flag::predelimit, '1', '2', '3', '4')); + BOOST_TEST(test_predelimited(" 1 2 3 4 5 " + , char_ << char_ << char_ << char_ << char_ + , space, delimit_flag::predelimit, '1', '2', '3', '4', '5')); + BOOST_TEST(test_predelimited(" 1 2 3 4 5 6 " + , char_ << char_ << char_ << char_ << char_ << char_ + , space, delimit_flag::predelimit + , '1', '2', '3', '4', '5', '6')); + BOOST_TEST(test_predelimited(" 1 2 3 4 5 6 7 " + , char_ << char_ << char_ << char_ << char_ << char_ << char_ + , space, delimit_flag::predelimit + , '1', '2', '3', '4', '5', '6', '7')); + BOOST_TEST(test_predelimited(" 1 2 3 4 5 6 7 8 " + , char_ << char_ << char_ << char_ << char_ << char_ << char_ << char_ + , space, delimit_flag::predelimit + , '1', '2', '3', '4', '5', '6', '7', '8')); + BOOST_TEST(test_predelimited(" 1 2 3 4 5 6 7 8 9 " + , char_ << char_ << char_ << char_ << char_ << char_ << char_ << char_ << char_ + , space, delimit_flag::predelimit + , '1', '2', '3', '4', '5', '6', '7', '8', '9')); + BOOST_TEST(test_predelimited(" 1 2 3 4 5 6 7 8 9 0 " + , char_ << char_ << char_ << char_ << char_ << char_ << char_ << char_ << char_ << char_ + , space, delimit_flag::predelimit + , '1', '2', '3', '4', '5', '6', '7', '8', '9', '0')); + } + + { + using namespace boost::spirit::ascii; + using boost::spirit::karma::delimit_flag; + + BOOST_TEST(test_predelimited("1 ", char_, space + , delimit_flag::dont_predelimit, '1')); + BOOST_TEST(test_predelimited("1 2 " + , char_ << char_, space, delimit_flag::dont_predelimit + , '1', '2')); + BOOST_TEST(test_predelimited("1 2 3 " + , char_ << char_ << char_, space + , delimit_flag::dont_predelimit, '1', '2', '3')); + BOOST_TEST(test_predelimited("1 2 3 4 " + , char_ << char_ << char_ << char_ + , space, delimit_flag::dont_predelimit, '1', '2', '3', '4')); + BOOST_TEST(test_predelimited("1 2 3 4 5 " + , char_ << char_ << char_ << char_ << char_ + , space, delimit_flag::dont_predelimit, '1', '2', '3', '4', '5')); + BOOST_TEST(test_predelimited("1 2 3 4 5 6 " + , char_ << char_ << char_ << char_ << char_ << char_ + , space, delimit_flag::dont_predelimit + , '1', '2', '3', '4', '5', '6')); + BOOST_TEST(test_predelimited("1 2 3 4 5 6 7 " + , char_ << char_ << char_ << char_ << char_ << char_ << char_ + , space, delimit_flag::dont_predelimit + , '1', '2', '3', '4', '5', '6', '7')); + BOOST_TEST(test_predelimited("1 2 3 4 5 6 7 8 " + , char_ << char_ << char_ << char_ << char_ << char_ << char_ << char_ + , space, delimit_flag::dont_predelimit + , '1', '2', '3', '4', '5', '6', '7', '8')); + BOOST_TEST(test_predelimited("1 2 3 4 5 6 7 8 9 " + , char_ << char_ << char_ << char_ << char_ << char_ << char_ << char_ << char_ + , space, delimit_flag::dont_predelimit + , '1', '2', '3', '4', '5', '6', '7', '8', '9')); + BOOST_TEST(test_predelimited("1 2 3 4 5 6 7 8 9 0 " + , char_ << char_ << char_ << char_ << char_ << char_ << char_ << char_ << char_ << char_ + , space, delimit_flag::dont_predelimit + , '1', '2', '3', '4', '5', '6', '7', '8', '9', '0')); + } + + return boost::report_errors(); +} + diff --git a/src/boost/libs/spirit/test/karma/format_pointer_container.cpp b/src/boost/libs/spirit/test/karma/format_pointer_container.cpp new file mode 100644 index 00000000..98da2b36 --- /dev/null +++ b/src/boost/libs/spirit/test/karma/format_pointer_container.cpp @@ -0,0 +1,59 @@ +// Copyright (c) 2009 Matthias Vallentin +// +// Distributed under the 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/iterator/indirect_iterator.hpp> +#include <boost/make_shared.hpp> +#include <boost/noncopyable.hpp> +#include <boost/spirit/include/karma.hpp> +#include <boost/spirit/include/karma_format.hpp> + +#include <sstream> +#include <string> +#include <vector> + +struct foo : boost::noncopyable +{ + foo() + : str("foo") + { + } + + std::string str; +}; + +template <typename Stream> +Stream& operator<<(Stream& out, const foo& f) +{ + out << f.str; + return out; +} + +int main() +{ + using namespace boost::spirit; + + typedef boost::shared_ptr<foo> foo_ptr; + std::vector<foo_ptr> v; + + std::size_t i = 10; + while (i--) + v.push_back(boost::make_shared<foo>()); + + typedef boost::indirect_iterator<std::vector<foo_ptr>::const_iterator> + iterator_type; + + std::stringstream strm; + strm + << karma::format(stream % ',', + boost::iterator_range<iterator_type>( + iterator_type(v.begin()), iterator_type(v.end()) + ) + ); + BOOST_TEST(strm.str() == "foo,foo,foo,foo,foo,foo,foo,foo,foo,foo"); + + return boost::report_errors(); +} diff --git a/src/boost/libs/spirit/test/karma/generate_attr.cpp b/src/boost/libs/spirit/test/karma/generate_attr.cpp new file mode 100644 index 00000000..7656f4c3 --- /dev/null +++ b/src/boost/libs/spirit/test/karma/generate_attr.cpp @@ -0,0 +1,169 @@ +// 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/karma_char.hpp> +#include <boost/spirit/include/karma_operator.hpp> +#include <boost/spirit/include/karma_generate_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_delimited("1 ", char_, space, '1')); + BOOST_TEST(test_delimited("1 2 " + , char_ << char_, space, '1', '2')); + BOOST_TEST(test_delimited("1 2 3 " + , char_ << char_ << char_, space, '1', '2', '3')); + BOOST_TEST(test_delimited("1 2 3 4 " + , char_ << char_ << char_ << char_ + , space, '1', '2', '3', '4')); + BOOST_TEST(test_delimited("1 2 3 4 5 " + , char_ << char_ << char_ << char_ << char_ + , space, '1', '2', '3', '4', '5')); + BOOST_TEST(test_delimited("1 2 3 4 5 6 " + , char_ << char_ << char_ << char_ << char_ << char_ + , space, '1', '2', '3', '4', '5', '6')); + BOOST_TEST(test_delimited("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_delimited("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_delimited("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_delimited("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::karma::delimit_flag; + + BOOST_TEST(test_predelimited(" 1 ", char_, space + , delimit_flag::predelimit, '1')); + BOOST_TEST(test_predelimited(" 1 2 " + , char_ << char_, space, delimit_flag::predelimit + , '1', '2')); + BOOST_TEST(test_predelimited(" 1 2 3 " + , char_ << char_ << char_, space + , delimit_flag::predelimit, '1', '2', '3')); + BOOST_TEST(test_predelimited(" 1 2 3 4 " + , char_ << char_ << char_ << char_ + , space, delimit_flag::predelimit, '1', '2', '3', '4')); + BOOST_TEST(test_predelimited(" 1 2 3 4 5 " + , char_ << char_ << char_ << char_ << char_ + , space, delimit_flag::predelimit, '1', '2', '3', '4', '5')); + BOOST_TEST(test_predelimited(" 1 2 3 4 5 6 " + , char_ << char_ << char_ << char_ << char_ << char_ + , space, delimit_flag::predelimit + , '1', '2', '3', '4', '5', '6')); + BOOST_TEST(test_predelimited(" 1 2 3 4 5 6 7 " + , char_ << char_ << char_ << char_ << char_ << char_ << char_ + , space, delimit_flag::predelimit + , '1', '2', '3', '4', '5', '6', '7')); + BOOST_TEST(test_predelimited(" 1 2 3 4 5 6 7 8 " + , char_ << char_ << char_ << char_ << char_ << char_ << char_ << char_ + , space, delimit_flag::predelimit + , '1', '2', '3', '4', '5', '6', '7', '8')); + BOOST_TEST(test_predelimited(" 1 2 3 4 5 6 7 8 9 " + , char_ << char_ << char_ << char_ << char_ << char_ << char_ << char_ << char_ + , space, delimit_flag::predelimit + , '1', '2', '3', '4', '5', '6', '7', '8', '9')); + BOOST_TEST(test_predelimited(" 1 2 3 4 5 6 7 8 9 0 " + , char_ << char_ << char_ << char_ << char_ << char_ << char_ << char_ << char_ << char_ + , space, delimit_flag::predelimit + , '1', '2', '3', '4', '5', '6', '7', '8', '9', '0')); + } + + { + using namespace boost::spirit::ascii; + using boost::spirit::karma::delimit_flag; + + BOOST_TEST(test_predelimited("1 ", char_, space + , delimit_flag::dont_predelimit, '1')); + BOOST_TEST(test_predelimited("1 2 " + , char_ << char_, space, delimit_flag::dont_predelimit + , '1', '2')); + BOOST_TEST(test_predelimited("1 2 3 " + , char_ << char_ << char_, space + , delimit_flag::dont_predelimit, '1', '2', '3')); + BOOST_TEST(test_predelimited("1 2 3 4 " + , char_ << char_ << char_ << char_ + , space, delimit_flag::dont_predelimit, '1', '2', '3', '4')); + BOOST_TEST(test_predelimited("1 2 3 4 5 " + , char_ << char_ << char_ << char_ << char_ + , space, delimit_flag::dont_predelimit, '1', '2', '3', '4', '5')); + BOOST_TEST(test_predelimited("1 2 3 4 5 6 " + , char_ << char_ << char_ << char_ << char_ << char_ + , space, delimit_flag::dont_predelimit + , '1', '2', '3', '4', '5', '6')); + BOOST_TEST(test_predelimited("1 2 3 4 5 6 7 " + , char_ << char_ << char_ << char_ << char_ << char_ << char_ + , space, delimit_flag::dont_predelimit + , '1', '2', '3', '4', '5', '6', '7')); + BOOST_TEST(test_predelimited("1 2 3 4 5 6 7 8 " + , char_ << char_ << char_ << char_ << char_ << char_ << char_ << char_ + , space, delimit_flag::dont_predelimit + , '1', '2', '3', '4', '5', '6', '7', '8')); + BOOST_TEST(test_predelimited("1 2 3 4 5 6 7 8 9 " + , char_ << char_ << char_ << char_ << char_ << char_ << char_ << char_ << char_ + , space, delimit_flag::dont_predelimit + , '1', '2', '3', '4', '5', '6', '7', '8', '9')); + BOOST_TEST(test_predelimited("1 2 3 4 5 6 7 8 9 0 " + , char_ << char_ << char_ << char_ << char_ << char_ << char_ << char_ << char_ << char_ + , space, delimit_flag::dont_predelimit + , '1', '2', '3', '4', '5', '6', '7', '8', '9', '0')); + } + + return boost::report_errors(); +} + diff --git a/src/boost/libs/spirit/test/karma/grammar.cpp b/src/boost/libs/spirit/test/karma/grammar.cpp new file mode 100644 index 00000000..d95956de --- /dev/null +++ b/src/boost/libs/spirit/test/karma/grammar.cpp @@ -0,0 +1,57 @@ +// 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/karma_operator.hpp> +#include <boost/spirit/include/karma_char.hpp> +#include <boost/spirit/include/karma_string.hpp> +#include <boost/spirit/include/karma_numeric.hpp> +#include <boost/spirit/include/karma_nonterminal.hpp> +#include <boost/spirit/include/karma_action.hpp> + +#include <string> +#include <iostream> + +#include "test.hpp" + +using namespace spirit_test; +using namespace boost::spirit; +using namespace boost::spirit::ascii; + +typedef spirit_test::output_iterator<char>::type outiter_type; + +struct num_list : karma::grammar<outiter_type, space_type> +{ + num_list() : num_list::base_type(start) + { + using boost::spirit::int_; + num1 = int_(123); + num2 = int_(456); + num3 = int_(789); + start = num1 << ',' << num2 << ',' << num3; + } + + karma::rule<outiter_type, space_type> start, num1, num2, num3; +}; + +int +main() +{ + { // simple grammar test + num_list nlist; + BOOST_TEST(test_delimited("123 , 456 , 789 ", nlist, space)); + } + + { // direct access to the rules + num_list def; + BOOST_TEST(test_delimited("123 ", def.num1, space)); + BOOST_TEST(test_delimited("123 , 456 , 789 ", def.start, space)); + } + + return boost::report_errors(); +} + diff --git a/src/boost/libs/spirit/test/karma/grammar_fail.cpp b/src/boost/libs/spirit/test/karma/grammar_fail.cpp new file mode 100644 index 00000000..9af96765 --- /dev/null +++ b/src/boost/libs/spirit/test/karma/grammar_fail.cpp @@ -0,0 +1,45 @@ +/*============================================================================= + 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/spirit/include/karma_operator.hpp> +#include <boost/spirit/include/karma_char.hpp> +#include <boost/spirit/include/karma_string.hpp> +#include <boost/spirit/include/karma_numeric.hpp> +#include <boost/spirit/include/karma_nonterminal.hpp> +#include <boost/spirit/include/karma_generate.hpp> + +#include "test.hpp" + +using namespace boost::spirit; +using namespace boost::spirit::ascii; + +typedef spirit_test::output_iterator<char>::type outiter_type; + +struct num_list : karma::grammar<outiter_type, karma::rule<outiter_type> > +{ + num_list() : num_list::base_type(start) + { + start = int_(1) << ',' << int_(0); + } + + karma::rule<outiter_type, karma::rule<outiter_type> > start; +}; + +// this test must fail compiling as the rule is used with an incompatible +// delimiter type +int main() +{ + std::string generated; + + std::back_insert_iterator<std::string> outit(generated); + num_list def; + generate_delimited(outit, def, char_('%') << '\n'); + + return 0; +} diff --git a/src/boost/libs/spirit/test/karma/int1.cpp b/src/boost/libs/spirit/test/karma/int1.cpp new file mode 100644 index 00000000..4bb40a83 --- /dev/null +++ b/src/boost/libs/spirit/test/karma/int1.cpp @@ -0,0 +1,170 @@ +// 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/mpl/vector.hpp> +#include <boost/mpl/for_each.hpp> +#include <boost/mpl/if.hpp> +#include <boost/mpl/bool.hpp> + +#include <boost/spirit/include/phoenix_core.hpp> +#include <boost/spirit/include/phoenix_operator.hpp> + +#include <boost/spirit/include/karma_char.hpp> +#include <boost/spirit/include/karma_numeric.hpp> +#include <boost/spirit/include/karma_directive.hpp> +#include <boost/spirit/include/karma_action.hpp> + +#include <boost/limits.hpp> +#include "test.hpp" + +using namespace spirit_test; + +/////////////////////////////////////////////////////////////////////////////// +int +main() +{ + using namespace boost::spirit; + + { + using namespace boost::spirit::ascii; + + /////////////////////////////////////////////////////////////////////// + // this is currently ambiguous with character literals + BOOST_TEST(test("0", 0)); + BOOST_TEST(test("123", 123)); + BOOST_TEST(test("-123", -123)); + + BOOST_TEST(test("0", int_, 0)); + BOOST_TEST(test("123", int_, 123)); + BOOST_TEST(test("-123", int_, -123)); + + BOOST_TEST(test_delimited("0 ", int_, 0, char_(' '))); + BOOST_TEST(test_delimited("123 ", int_, 123, char_(' '))); + BOOST_TEST(test_delimited("-123 ", int_, -123, char_(' '))); + + BOOST_TEST(test("0", lower[int_], 0)); + BOOST_TEST(test("123", lower[int_], 123)); + BOOST_TEST(test("-123", lower[int_], -123)); + + BOOST_TEST(test_delimited("0 ", lower[int_], 0, char_(' '))); + BOOST_TEST(test_delimited("123 ", lower[int_], 123, char_(' '))); + BOOST_TEST(test_delimited("-123 ", lower[int_], -123, char_(' '))); + + BOOST_TEST(test("0", upper[int_], 0)); + BOOST_TEST(test("123", upper[int_], 123)); + BOOST_TEST(test("-123", upper[int_], -123)); + + BOOST_TEST(test_delimited("0 ", upper[int_], 0, char_(' '))); + BOOST_TEST(test_delimited("123 ", upper[int_], 123, char_(' '))); + BOOST_TEST(test_delimited("-123 ", upper[int_], -123, char_(' '))); + + /////////////////////////////////////////////////////////////////////// + BOOST_TEST(test("0", int_(0))); + BOOST_TEST(test("123", int_(123))); + BOOST_TEST(test("-123", int_(-123))); + + BOOST_TEST(test_delimited("0 ", int_(0), char_(' '))); + BOOST_TEST(test_delimited("123 ", int_(123), char_(' '))); + BOOST_TEST(test_delimited("-123 ", int_(-123), char_(' '))); + + BOOST_TEST(test("0", lower[int_(0)])); + BOOST_TEST(test("123", lower[int_(123)])); + BOOST_TEST(test("-123", lower[int_(-123)])); + + BOOST_TEST(test_delimited("0 ", lower[int_(0)], char_(' '))); + BOOST_TEST(test_delimited("123 ", lower[int_(123)], char_(' '))); + BOOST_TEST(test_delimited("-123 ", lower[int_(-123)], char_(' '))); + + BOOST_TEST(test("0", upper[int_(0)])); + BOOST_TEST(test("123", upper[int_(123)])); + BOOST_TEST(test("-123", upper[int_(-123)])); + + BOOST_TEST(test_delimited("0 ", upper[int_(0)], char_(' '))); + BOOST_TEST(test_delimited("123 ", upper[int_(123)], char_(' '))); + BOOST_TEST(test_delimited("-123 ", upper[int_(-123)], char_(' '))); + } + + { // literals, make sure there are no ambiguities + BOOST_TEST(test("0", lit(short(0)))); + BOOST_TEST(test("0", lit(0))); + BOOST_TEST(test("0", lit(0L))); +#ifdef BOOST_HAS_LONG_LONG + BOOST_TEST(test("0", lit(0LL))); +#endif + + BOOST_TEST(test("0", lit((unsigned short)0))); + BOOST_TEST(test("0", lit(0U))); + BOOST_TEST(test("0", lit(0UL))); +#ifdef BOOST_HAS_LONG_LONG + BOOST_TEST(test("0", lit(0ULL))); +#endif + + BOOST_TEST(test("a", lit('a'))); + BOOST_TEST(test("a", 'a')); + BOOST_TEST(test(L"a", L'a')); + } + + { // lazy numerics + using namespace boost::phoenix; + + BOOST_TEST(test("0", int_(val(0)))); + BOOST_TEST(test("123", int_(val(123)))); + BOOST_TEST(test("-123", int_(val(-123)))); + + int i1 = 0, i2 = 123, i3 = -123; + BOOST_TEST(test("0", int_(ref(i1)))); + BOOST_TEST(test("123", int_(ref(i2)))); + BOOST_TEST(test("-123", int_(ref(i3)))); + } + + { + /////////////////////////////////////////////////////////////////////// + using namespace boost::spirit::ascii; + BOOST_TEST(test("1234", uint_(1234))); + BOOST_TEST(test("ff", hex(0xff))); + BOOST_TEST(test("1234", oct(01234))); + BOOST_TEST(test("11110000", bin(0xf0))); + + BOOST_TEST(test_delimited("1234 ", uint_(1234), char_(' '))); + BOOST_TEST(test_delimited("ff ", hex(0xff), char_(' '))); + BOOST_TEST(test_delimited("1234 ", oct(01234), char_(' '))); + BOOST_TEST(test_delimited("11110000 ", bin(0xf0), char_(' '))); + + BOOST_TEST(test("1234", lower[uint_(1234)])); + BOOST_TEST(test("ff", lower[hex(0xff)])); + BOOST_TEST(test("1234", lower[oct(01234)])); + BOOST_TEST(test("11110000", lower[bin(0xf0)])); + + BOOST_TEST(test_delimited("1234 ", lower[uint_(1234)], char_(' '))); + BOOST_TEST(test_delimited("ff ", lower[hex(0xff)], char_(' '))); + BOOST_TEST(test_delimited("1234 ", lower[oct(01234)], char_(' '))); + BOOST_TEST(test_delimited("11110000 ", lower[bin(0xf0)], char_(' '))); + + BOOST_TEST(test("1234", upper[uint_(1234)])); + BOOST_TEST(test("FF", upper[hex(0xff)])); + BOOST_TEST(test("1234", upper[oct(01234)])); + BOOST_TEST(test("11110000", upper[bin(0xf0)])); + + BOOST_TEST(test_delimited("1234 ", upper[uint_(1234)], char_(' '))); + BOOST_TEST(test_delimited("FF ", upper[hex(0xff)], char_(' '))); + BOOST_TEST(test_delimited("1234 ", upper[oct(01234)], char_(' '))); + BOOST_TEST(test_delimited("11110000 ", upper[bin(0xf0)], char_(' '))); + + BOOST_TEST(test("FF", upper[upper[hex(0xff)]])); + BOOST_TEST(test("FF", upper[lower[hex(0xff)]])); + BOOST_TEST(test("ff", lower[upper[hex(0xff)]])); + BOOST_TEST(test("ff", lower[lower[hex(0xff)]])); + + BOOST_TEST(test_delimited("FF ", upper[upper[hex(0xff)]], char_(' '))); + BOOST_TEST(test_delimited("FF ", upper[lower[hex(0xff)]], char_(' '))); + BOOST_TEST(test_delimited("ff ", lower[upper[hex(0xff)]], char_(' '))); + BOOST_TEST(test_delimited("ff ", lower[lower[hex(0xff)]], char_(' '))); + } + + return boost::report_errors(); +} + diff --git a/src/boost/libs/spirit/test/karma/int2.cpp b/src/boost/libs/spirit/test/karma/int2.cpp new file mode 100644 index 00000000..1912d73c --- /dev/null +++ b/src/boost/libs/spirit/test/karma/int2.cpp @@ -0,0 +1,177 @@ +// 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/mpl/vector.hpp> +#include <boost/mpl/for_each.hpp> +#include <boost/mpl/if.hpp> +#include <boost/mpl/bool.hpp> + +#include <boost/spirit/include/phoenix_core.hpp> +#include <boost/spirit/include/phoenix_operator.hpp> + +#include <boost/spirit/include/karma_char.hpp> +#include <boost/spirit/include/karma_numeric.hpp> +#include <boost/spirit/include/karma_directive.hpp> +#include <boost/spirit/include/karma_action.hpp> +#include <boost/spirit/include/karma_rule.hpp> + +#include <boost/limits.hpp> +#include "test.hpp" + +using namespace spirit_test; + + +/////////////////////////////////////////////////////////////////////////////// +int +main() +{ + using namespace boost::spirit; + + { + using namespace boost::spirit::ascii; + + karma::int_generator<int, 10, true> const signed_int = + karma::int_generator<int, 10, true>(); + + /////////////////////////////////////////////////////////////////////// + BOOST_TEST(test(" 0", signed_int, 0)); + BOOST_TEST(test("+123", signed_int, 123)); + BOOST_TEST(test("-123", signed_int, -123)); + + BOOST_TEST(test_delimited(" 0 ", signed_int, 0, char_(' '))); + BOOST_TEST(test_delimited("+123 ", signed_int, 123, char_(' '))); + BOOST_TEST(test_delimited("-123 ", signed_int, -123, char_(' '))); + + BOOST_TEST(test(" 0", lower[signed_int], 0)); + BOOST_TEST(test("+123", lower[signed_int], 123)); + BOOST_TEST(test("-123", lower[signed_int], -123)); + + BOOST_TEST(test_delimited(" 0 ", lower[signed_int], 0, char_(' '))); + BOOST_TEST(test_delimited("+123 ", lower[signed_int], 123, char_(' '))); + BOOST_TEST(test_delimited("-123 ", lower[signed_int], -123, char_(' '))); + + BOOST_TEST(test(" 0", upper[signed_int], 0)); + BOOST_TEST(test("+123", upper[signed_int], 123)); + BOOST_TEST(test("-123", upper[signed_int], -123)); + + BOOST_TEST(test_delimited(" 0 ", upper[signed_int], 0, char_(' '))); + BOOST_TEST(test_delimited("+123 ", upper[signed_int], 123, char_(' '))); + BOOST_TEST(test_delimited("-123 ", upper[signed_int], -123, char_(' '))); + + /////////////////////////////////////////////////////////////////////// + BOOST_TEST(test(" 0", signed_int(0))); + BOOST_TEST(test("+123", signed_int(123))); + BOOST_TEST(test("-123", signed_int(-123))); + + BOOST_TEST(test_delimited(" 0 ", signed_int(0), char_(' '))); + BOOST_TEST(test_delimited("+123 ", signed_int(123), char_(' '))); + BOOST_TEST(test_delimited("-123 ", signed_int(-123), char_(' '))); + + BOOST_TEST(test(" 0", lower[signed_int(0)])); + BOOST_TEST(test("+123", lower[signed_int(123)])); + BOOST_TEST(test("-123", lower[signed_int(-123)])); + + BOOST_TEST(test_delimited(" 0 ", lower[signed_int(0)], char_(' '))); + BOOST_TEST(test_delimited("+123 ", lower[signed_int(123)], char_(' '))); + BOOST_TEST(test_delimited("-123 ", lower[signed_int(-123)], char_(' '))); + + BOOST_TEST(test(" 0", upper[signed_int(0)])); + BOOST_TEST(test("+123", upper[signed_int(123)])); + BOOST_TEST(test("-123", upper[signed_int(-123)])); + + BOOST_TEST(test_delimited(" 0 ", upper[signed_int(0)], char_(' '))); + BOOST_TEST(test_delimited("+123 ", upper[signed_int(123)], char_(' '))); + BOOST_TEST(test_delimited("-123 ", upper[signed_int(-123)], char_(' '))); + + using namespace boost::phoenix; + + BOOST_TEST(test(" 0", signed_int(val(0)))); + BOOST_TEST(test("+123", signed_int(val(123)))); + BOOST_TEST(test("-123", signed_int(val(-123)))); + + int i1 = 0, i2 = 123, i3 = -123; + BOOST_TEST(test(" 0", signed_int(ref(i1)))); + BOOST_TEST(test("+123", signed_int(ref(i2)))); + BOOST_TEST(test("-123", signed_int(ref(i3)))); + } + + { + /////////////////////////////////////////////////////////////////////// + using namespace boost::spirit::ascii; + + BOOST_TEST(test("1234", uint_, 1234)); + BOOST_TEST(test("ff", hex, 0xff)); + BOOST_TEST(test("1234", oct, 01234)); + BOOST_TEST(test("11110000", bin, 0xf0)); + + BOOST_TEST(test_delimited("1234 ", uint_, 1234, char_(' '))); + BOOST_TEST(test_delimited("ff ", hex, 0xff, char_(' '))); + BOOST_TEST(test_delimited("1234 ", oct, 01234, char_(' '))); + BOOST_TEST(test_delimited("11110000 ", bin, 0xf0, char_(' '))); + + // test unsigned generator with signed integral value + BOOST_TEST(test("ff", hex, (char)0xff)); + BOOST_TEST(test_delimited("ff ", hex, (char)0xff, char_(' '))); + + BOOST_TEST(test("1234", lower[uint_], 1234)); + BOOST_TEST(test("ff", lower[hex], 0xff)); + BOOST_TEST(test("1234", lower[oct], 01234)); + BOOST_TEST(test("11110000", lower[bin], 0xf0)); + + BOOST_TEST(test_delimited("1234 ", lower[uint_], 1234, char_(' '))); + BOOST_TEST(test_delimited("ff ", lower[hex], 0xff, char_(' '))); + BOOST_TEST(test_delimited("1234 ", lower[oct], 01234, char_(' '))); + BOOST_TEST(test_delimited("11110000 ", lower[bin], 0xf0, char_(' '))); + + BOOST_TEST(test("1234", upper[uint_], 1234)); + BOOST_TEST(test("FF", upper[hex], 0xff)); + BOOST_TEST(test("1234", upper[oct], 01234)); + BOOST_TEST(test("11110000", upper[bin], 0xf0)); + + BOOST_TEST(test_delimited("1234 ", upper[uint_], 1234, char_(' '))); + BOOST_TEST(test_delimited("FF ", upper[hex], 0xff, char_(' '))); + BOOST_TEST(test_delimited("1234 ", upper[oct], 01234, char_(' '))); + BOOST_TEST(test_delimited("11110000 ", upper[bin], 0xf0, char_(' '))); + + // no generator transformation should occur for uint_'s + BOOST_TEST(test("1234", upper[upper[uint_]], 1234)); + BOOST_TEST(test("1234", upper[lower[uint_]], 1234)); + BOOST_TEST(test("1234", lower[upper[uint_]], 1234)); + BOOST_TEST(test("1234", lower[lower[uint_]], 1234)); + + BOOST_TEST(test_delimited("1234 ", upper[upper[uint_]], 1234, char_(' '))); + BOOST_TEST(test_delimited("1234 ", upper[lower[uint_]], 1234, char_(' '))); + BOOST_TEST(test_delimited("1234 ", lower[upper[uint_]], 1234, char_(' '))); + BOOST_TEST(test_delimited("1234 ", lower[lower[uint_]], 1234, char_(' '))); + + BOOST_TEST(test("FF", upper[upper[hex]], 0xff)); + BOOST_TEST(test("FF", upper[lower[hex]], 0xff)); + BOOST_TEST(test("ff", lower[upper[hex]], 0xff)); + BOOST_TEST(test("ff", lower[lower[hex]], 0xff)); + + BOOST_TEST(test_delimited("FF ", upper[upper[hex]], 0xff, char_(' '))); + BOOST_TEST(test_delimited("FF ", upper[lower[hex]], 0xff, char_(' '))); + BOOST_TEST(test_delimited("ff ", lower[upper[hex]], 0xff, char_(' '))); + BOOST_TEST(test_delimited("ff ", lower[lower[hex]], 0xff, char_(' '))); + } + + /////////////////////////////////////////////////////////////////////////// + { + using boost::spirit::karma::int_; + using boost::spirit::karma::_1; + using boost::spirit::karma::_val; + using boost::spirit::karma::space; + + int i = 123; + int j = 456; + BOOST_TEST(test("123", int_[_1 = _val], i)); + BOOST_TEST(test_delimited("456 ", int_[_1 = _val], j, space)); + } + + return boost::report_errors(); +} + diff --git a/src/boost/libs/spirit/test/karma/int3.cpp b/src/boost/libs/spirit/test/karma/int3.cpp new file mode 100644 index 00000000..47c5ad34 --- /dev/null +++ b/src/boost/libs/spirit/test/karma/int3.cpp @@ -0,0 +1,126 @@ +// 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/lexical_cast.hpp> +#include <boost/mpl/vector.hpp> +#include <boost/mpl/for_each.hpp> +#include <boost/mpl/if.hpp> +#include <boost/mpl/bool.hpp> + +#include <boost/spirit/include/phoenix_core.hpp> +#include <boost/spirit/include/phoenix_operator.hpp> + +#include <boost/spirit/include/karma_char.hpp> +#include <boost/spirit/include/karma_numeric.hpp> +#include <boost/spirit/include/karma_directive.hpp> +#include <boost/spirit/include/karma_action.hpp> +#include <boost/spirit/include/karma_phoenix_attributes.hpp> + +#include <boost/limits.hpp> +#include "test.hpp" + +using namespace spirit_test; + +/////////////////////////////////////////////////////////////////////////////// +struct test_minmax +{ + template <typename T> + void operator()(T) const + { + using namespace boost::spirit; + using namespace boost::phoenix; + + T minval = (std::numeric_limits<T>::min)(); + T maxval = (std::numeric_limits<T>::max)(); + + std::string expected_minval = boost::lexical_cast<std::string>(minval); + std::string expected_maxval = boost::lexical_cast<std::string>(maxval); + + // create a correct generator type from the given integer type + typedef typename + boost::mpl::if_< + boost::mpl::bool_<std::numeric_limits<T>::is_signed>, + karma::int_generator<T>, + karma::uint_generator<T> + >::type + int_generator_type; + + int_generator_type const gen = int_generator_type(); + + BOOST_TEST(test(expected_maxval, gen, maxval)); + BOOST_TEST(test(expected_minval, gen, minval)); + BOOST_TEST(test(expected_maxval, gen(maxval))); + BOOST_TEST(test(expected_minval, gen(minval))); + BOOST_TEST(test(expected_maxval, gen(maxval), maxval)); + BOOST_TEST(test(expected_minval, gen(minval), minval)); + BOOST_TEST(!test("", gen(maxval), maxval-1)); + BOOST_TEST(!test("", gen(minval), minval+1)); + BOOST_TEST(test(expected_maxval, lit(maxval))); + BOOST_TEST(test(expected_minval, lit(minval))); + + BOOST_TEST(test_delimited(expected_maxval + " ", gen, maxval, char(' '))); + BOOST_TEST(test_delimited(expected_minval + " ", gen, minval, char(' '))); + BOOST_TEST(test_delimited(expected_maxval + " ", gen(maxval), char(' '))); + BOOST_TEST(test_delimited(expected_minval + " ", gen(minval), char(' '))); + BOOST_TEST(test_delimited(expected_maxval + " ", gen(maxval), maxval, char(' '))); + BOOST_TEST(test_delimited(expected_minval + " ", gen(minval), minval, char(' '))); + BOOST_TEST(!test_delimited("", gen(maxval), maxval-1, char(' '))); + BOOST_TEST(!test_delimited("", gen(minval), minval+1, char(' '))); + BOOST_TEST(test_delimited(expected_maxval + " ", lit(maxval), char(' '))); + BOOST_TEST(test_delimited(expected_minval + " ", lit(minval), char(' '))); + + // action tests + BOOST_TEST(test(expected_maxval, gen[_1 = val(maxval)])); + BOOST_TEST(test(expected_minval, gen[_1 = val(minval)])); + + // optional tests + boost::optional<T> optmin, optmax(maxval); + + BOOST_TEST(!test("", gen, optmin)); + BOOST_TEST(!test("", gen(minval), optmin)); + + optmin = minval; + BOOST_TEST(test(expected_minval, gen, optmin)); + BOOST_TEST(test(expected_maxval, gen, optmax)); + BOOST_TEST(test(expected_minval, gen(minval), optmin)); + BOOST_TEST(test(expected_maxval, gen(maxval), optmax)); + +// we support Phoenix attributes only starting with V2.2 +#if SPIRIT_VERSION >= 0x2020 + // Phoenix expression tests (only supported while including + // karma_phoenix_attributes.hpp + namespace phoenix = boost::phoenix; + + BOOST_TEST(test("1", gen, phoenix::val(1))); + + T val = 1; + BOOST_TEST(test("1", gen, phoenix::ref(val))); + BOOST_TEST(test("2", gen, ++phoenix::ref(val))); +#endif + } +}; + +/////////////////////////////////////////////////////////////////////////////// +int +main() +{ + using namespace boost::spirit; + +// test boundary values + typedef boost::mpl::vector< +#ifdef BOOST_HAS_LONG_LONG + boost::long_long_type, boost::ulong_long_type, +#endif + short, unsigned short, + int, unsigned int, + long, unsigned long + > integer_types; + boost::mpl::for_each<integer_types>(test_minmax()); + + return boost::report_errors(); +} + diff --git a/src/boost/libs/spirit/test/karma/kleene.cpp b/src/boost/libs/spirit/test/karma/kleene.cpp new file mode 100644 index 00000000..693c31e3 --- /dev/null +++ b/src/boost/libs/spirit/test/karma/kleene.cpp @@ -0,0 +1,244 @@ +// 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/assign/std/vector.hpp> + +#include <boost/spirit/include/karma_char.hpp> +#include <boost/spirit/include/karma_string.hpp> +#include <boost/spirit/include/karma_numeric.hpp> +#include <boost/spirit/include/karma_generate.hpp> +#include <boost/spirit/include/karma_operator.hpp> +#include <boost/spirit/include/karma_action.hpp> +#include <boost/spirit/include/karma_nonterminal.hpp> +#include <boost/spirit/include/karma_auxiliary.hpp> +#include <boost/spirit/include/karma_directive.hpp> +#include <boost/fusion/include/vector.hpp> +#include <boost/spirit/include/phoenix_core.hpp> +#include <boost/spirit/include/phoenix_operator.hpp> +#include <boost/fusion/include/std_pair.hpp> + +#include <boost/assign/std/vector.hpp> + +#include "test.hpp" + +using namespace spirit_test; + +/////////////////////////////////////////////////////////////////////////////// +struct action +{ + action (std::vector<char>& vec) + : vec(vec), it(vec.begin()) + {} + + void operator()(unsigned& value, boost::spirit::unused_type, bool& pass) const + { + pass = (it != vec.end()); + if (pass) + value = *it++; + } + + std::vector<char>& vec; + mutable std::vector<char>::iterator it; +}; + +struct A +{ + double d1; + double d2; +}; + +BOOST_FUSION_ADAPT_STRUCT( + A, + (double, d1) + (double, d2) +) + +/////////////////////////////////////////////////////////////////////////////// +int main() +{ + using namespace boost::spirit; + using namespace boost::spirit::ascii; + namespace fusion = boost::fusion; + + { + std::string s1("aaaa"); + BOOST_TEST(test("aaaa", *char_, s1)); + BOOST_TEST(test_delimited("a a a a ", *char_, s1, ' ')); + + std::string s2(""); + BOOST_TEST(test("", *char_, s2)); + BOOST_TEST(test_delimited("", *char_, s2, ' ')); + } + + { + std::string s1("aaaaa"); + BOOST_TEST(test("aaaaa", char_ << *(char_ << char_), s1)); + BOOST_TEST(test_delimited("a a a a a ", + char_ << *(char_ << char_), s1, ' ')); + + s1 = "a"; + BOOST_TEST(test("a", char_ << *(char_ << char_), s1)); + s1 = "aa"; + BOOST_TEST(!test("", char_ << *(char_ << char_), s1)); +// BOOST_TEST(test("aa", char_ << *buffer[char_ << char_] << char_, s1)); + s1 = "aaaa"; + BOOST_TEST(!test("", char_ << *(char_ << char_), s1)); +// BOOST_TEST(test("aaaa", char_ << *buffer[char_ << char_] << char_, s1)); + } + + { + using boost::spirit::karma::strict; + using boost::spirit::karma::relaxed; + using namespace boost::assign; + + typedef std::pair<char, char> data; + std::vector<data> v1; + v1 += std::make_pair('a', 'a'), + std::make_pair('b', 'b'), + std::make_pair('c', 'c'), + std::make_pair('d', 'd'), + std::make_pair('e', 'e'), + std::make_pair('f', 'f'), + std::make_pair('g', 'g'); + + karma::rule<spirit_test::output_iterator<char>::type, data()> r; + r = &char_('a') << char_; + + BOOST_TEST(test("a", r << *(r << r), v1)); + BOOST_TEST(test("a", relaxed[r << *(r << r)], v1)); + BOOST_TEST(!test("", strict[r << *(r << r)], v1)); + + v1 += std::make_pair('a', 'a'); + + BOOST_TEST(!test("", r << *(r << r), v1)); + BOOST_TEST(!test("", relaxed[r << *(r << r)], v1)); + BOOST_TEST(!test("", strict[r << *(r << r)], v1)); + + v1 += std::make_pair('a', 'a'); + + BOOST_TEST(test("aaa", r << *(r << r), v1)); + BOOST_TEST(test("aaa", relaxed[r << *(r << r)], v1)); + BOOST_TEST(!test("", strict[r << *(r << r)], v1)); + } + + { + using namespace boost::assign; + + std::vector<char> v; + v += 'a', 'b', 'c'; + + BOOST_TEST(test("abc", *char_, v)); + BOOST_TEST(test_delimited("a b c ", *char_, v, ' ')); + } + + { + using namespace boost::assign; + + std::vector<int> v; + v += 10, 20, 30; + + BOOST_TEST(test("102030", *int_, v)); + BOOST_TEST(test_delimited("10, 20, 30, ", *int_, v, lit(", "))); + + BOOST_TEST(test("10,20,30,", *(int_ << ','), v)); + BOOST_TEST(test_delimited("10 , 20 , 30 , ", *(int_ << ','), v, lit(' '))); + +// leads to infinite loops +// fusion::vector<char, char> cc ('a', 'c'); +// BOOST_TEST(test("ac", char_ << *(lit(' ') << ',') << char_, cc)); +// BOOST_TEST(test_delimited("a c ", +// char_ << *(lit(' ') << ',') << char_, cc, " ")); + } + + { // actions + using namespace boost::assign; + namespace phx = boost::phoenix; + + std::vector<char> v; + v += 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'; + + BOOST_TEST(test("abcdefgh", (*char_)[_1 = phx::ref(v)])); + BOOST_TEST(test_delimited("a b c d e f g h ", + (*char_ )[_1 = phx::ref(v)], space)); + } + + // failing sub-generators + { + using boost::spirit::karma::strict; + using boost::spirit::karma::relaxed; + + using namespace boost::assign; + + typedef std::pair<char, char> data; + std::vector<data> v2; + v2 += std::make_pair('a', 'a'), + std::make_pair('b', 'b'), + std::make_pair('c', 'c'), + std::make_pair('d', 'd'), + std::make_pair('e', 'e'), + std::make_pair('f', 'f'), + std::make_pair('g', 'g'); + + karma::rule<spirit_test::output_iterator<char>::type, data()> r; + + r = &char_('d') << char_; + BOOST_TEST(test("d", *r, v2)); + BOOST_TEST(test("d", relaxed[*r], v2)); + BOOST_TEST(test("", strict[*r], v2)); + + r = &char_('a') << char_; + BOOST_TEST(test("a", *r, v2)); + BOOST_TEST(test("a", relaxed[*r], v2)); + BOOST_TEST(test("a", strict[*r], v2)); + + r = &char_('g') << char_; + BOOST_TEST(test("g", *r, v2)); + BOOST_TEST(test("g", relaxed[*r], v2)); + BOOST_TEST(test("", strict[*r], v2)); + + r = !char_('d') << char_; + BOOST_TEST(test("abcefg", *r, v2)); + BOOST_TEST(test("abcefg", relaxed[*r], v2)); + BOOST_TEST(test("abc", strict[*r], v2)); + + r = !char_('a') << char_; + BOOST_TEST(test("bcdefg", *r, v2)); + BOOST_TEST(test("bcdefg", relaxed[*r], v2)); + BOOST_TEST(test("", strict[*r], v2)); + + r = !char_('g') << char_; + BOOST_TEST(test("abcdef", *r, v2)); + BOOST_TEST(test("abcdef", relaxed[*r], v2)); + BOOST_TEST(test("abcdef", strict[*r], v2)); + + r = &char_('A') << char_; + BOOST_TEST(test("", *r, v2)); + } + + { + // make sure user defined end condition is applied if no attribute + // is passed in + using namespace boost::assign; + + std::vector<char> v; + v += 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'; + BOOST_TEST(test("[6162636465666768]", '[' << *hex[action(v)] << ']')); + } + + { + using boost::spirit::karma::double_; + + std::vector<A> v(1); + v[0].d1 = 1.0; + v[0].d2 = 2.0; + BOOST_TEST(test("A1.02.0", 'A' << *(double_ << double_), v)); + } + + return boost::report_errors(); +} + diff --git a/src/boost/libs/spirit/test/karma/lazy.cpp b/src/boost/libs/spirit/test/karma/lazy.cpp new file mode 100644 index 00000000..86476f01 --- /dev/null +++ b/src/boost/libs/spirit/test/karma/lazy.cpp @@ -0,0 +1,52 @@ +// 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/karma_char.hpp> +#include <boost/spirit/include/karma_string.hpp> +#include <boost/spirit/include/karma_numeric.hpp> +#include <boost/spirit/include/karma_auxiliary.hpp> +#include <boost/spirit/include/karma_action.hpp> +// #include <boost/spirit/include/karma_nonterminal.hpp> +// #include <boost/spirit/include/karma_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() +{ + namespace karma = boost::spirit::karma; + using spirit_test::test; + using namespace boost::spirit; + using namespace boost::spirit::karma; + namespace phx = boost::phoenix; + + { + BOOST_TEST(test("123", karma::lazy(phx::val(int_)), 123)); + } + + { + int result = 123; + BOOST_TEST(test("123", karma::lazy(phx::val(int_))[_1 = phx::ref(result)])); + } + +// { +// typedef spirit_test::output_iterator<char>::type outiter_type; +// rule<outiter_type, void(std::string)> r; +// +// r = char_('<') << karma::lazy(_r1) << '>' << "</" << karma::lazy(_r1) << '>'; +// +// std::string tag("tag"), foo("foo"); +// BOOST_TEST(test("<tag></tag>", r (phx::ref(tag)))); +// BOOST_TEST(!test("<foo></bar>", r (phx::ref(foo)))); +// } + + return boost::report_errors(); +} diff --git a/src/boost/libs/spirit/test/karma/left_alignment.cpp b/src/boost/libs/spirit/test/karma/left_alignment.cpp new file mode 100644 index 00000000..5b189883 --- /dev/null +++ b/src/boost/libs/spirit/test/karma/left_alignment.cpp @@ -0,0 +1,74 @@ +// 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/karma_char.hpp> +#include <boost/spirit/include/karma_string.hpp> +#include <boost/spirit/include/karma_numeric.hpp> +#include <boost/spirit/include/karma_generate.hpp> +#include <boost/spirit/include/karma_directive.hpp> +#include <boost/spirit/include/karma_upper_lower_case.hpp> + +#include "test.hpp" + +/////////////////////////////////////////////////////////////////////////////// +int +main() +{ + using namespace spirit_test; + using namespace boost::spirit; + using namespace boost::spirit::ascii; + + { + BOOST_TEST(test("x ", left_align[char_('x')])); + BOOST_TEST(test("x ", left_align[char_], 'x')); + BOOST_TEST(test("x ", left_align['x'])); + + BOOST_TEST(test("x ", left_align(10)[char_('x')])); + BOOST_TEST(test("x ", left_align(10)[char_], 'x')); + BOOST_TEST(test("x ", left_align(10)['x'])); + + BOOST_TEST(test("x*********", left_align(10, char_('*'))[char_('x')])); + BOOST_TEST(test("x*********", left_align(10, '*')[char_], 'x')); + BOOST_TEST(test("x*********", left_align(10, '*')['x'])); + BOOST_TEST(test("xaaaaaaaaa", lower[left_align(10, 'A')['X']])); + BOOST_TEST(test("XAAAAAAAAA", upper[left_align(10, 'a')['x']])); + + BOOST_TEST(test("x*********", left_align(char_('*'))[char_('x')])); + BOOST_TEST(test("x*********", left_align(char_('*'))[char_], 'x')); + BOOST_TEST(test("x*********", left_align(char_('*'))['x'])); + + BOOST_TEST(test("abc ", left_align[lit("abc")])); + BOOST_TEST(test("abc ", left_align[string], "abc")); + + BOOST_TEST(test("abc ", left_align(10)[lit("abc")])); + BOOST_TEST(test("abc ", left_align(10)[string], "abc")); + BOOST_TEST(test("abc ", left_align(10)["abc"])); + + BOOST_TEST(test("abc*******", left_align(10, char_('*'))[lit("abc")])); + BOOST_TEST(test("abc*******", left_align(10, '*')[string], "abc")); + BOOST_TEST(test("abc*******", left_align(10, '*')["abc"])); + + BOOST_TEST(test("abc*******", left_align(char_('*'))[lit("abc")])); + BOOST_TEST(test("abc*******", left_align(char_('*'))[string], "abc")); + BOOST_TEST(test("abc*******", left_align(char_('*'))["abc"])); + + BOOST_TEST(test("100 ", left_align[int_(100)])); + BOOST_TEST(test("100 ", left_align[int_], 100)); + + BOOST_TEST(test("100 ", left_align(10)[int_(100)])); + BOOST_TEST(test("100 ", left_align(10)[int_], 100)); + + BOOST_TEST(test("100*******", left_align(10, char_('*'))[int_(100)])); + BOOST_TEST(test("100*******", left_align(10, '*')[int_], 100)); + + BOOST_TEST(test("100*******", left_align(char_('*'))[int_(100)])); + BOOST_TEST(test("100*******", left_align(char_('*'))[int_], 100)); + } + + return boost::report_errors(); +} diff --git a/src/boost/libs/spirit/test/karma/list.cpp b/src/boost/libs/spirit/test/karma/list.cpp new file mode 100644 index 00000000..686b0ab4 --- /dev/null +++ b/src/boost/libs/spirit/test/karma/list.cpp @@ -0,0 +1,151 @@ +// 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/mpl/print.hpp> + +#include <boost/spirit/include/karma_operator.hpp> +#include <boost/spirit/include/karma_char.hpp> +#include <boost/spirit/include/karma_string.hpp> +#include <boost/spirit/include/karma_numeric.hpp> +#include <boost/spirit/include/karma_directive.hpp> +#include <boost/spirit/include/karma_action.hpp> +#include <boost/spirit/include/karma_nonterminal.hpp> +#include <boost/spirit/include/karma_auxiliary.hpp> +#include <boost/spirit/include/phoenix_core.hpp> +#include <boost/spirit/include/phoenix_operator.hpp> +#include <boost/fusion/include/std_pair.hpp> + +#include <boost/assign/std/vector.hpp> + +#include <string> +#include <vector> +#include <iostream> + +#include "test.hpp" + +using namespace spirit_test; +using boost::spirit::unused_type; + +/////////////////////////////////////////////////////////////////////////////// +struct action +{ + action (std::vector<char>& vec) + : vec(vec), it(vec.begin()) + {} + + void operator()(unsigned& value, unused_type const&, bool& pass) const + { + pass = (it != vec.end()); + if (pass) + value = *it++; + } + + std::vector<char>& vec; + mutable std::vector<char>::iterator it; +}; + +/////////////////////////////////////////////////////////////////////////////// +int main() +{ + using namespace boost::spirit; + using namespace boost::spirit::ascii; + + using namespace boost::assign; + + std::vector<char> v; + v += 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'; + + { + BOOST_TEST(test("a,b,c,d,e,f,g,h", char_ % ',', v)); + BOOST_TEST(test_delimited("a , b , c , d , e , f , g , h ", + char_ % ',', v, space)); + } + + { + std::string s ("abcdefgh"); + BOOST_TEST(test("a,b,c,d,e,f,g,h", char_ % ',', s)); + BOOST_TEST(test_delimited("a , b , c , d , e , f , g , h ", + char_ % ',', s, space)); + } + + { + std::string s ("abcdefg"); + BOOST_TEST(test("abc,de,fg", char_ << ((char_ << char_) % ','), s)); + BOOST_TEST(test_delimited("a b c , d e , f g ", + char_ << ((char_ << char_) % ','), s, space)); + } + + { // actions + namespace phx = boost::phoenix; + + BOOST_TEST(test("a,b,c,d,e,f,g,h", (char_ % ',')[_1 = phx::ref(v)])); + BOOST_TEST(test_delimited("a , b , c , d , e , f , g , h ", + (char_ % ',')[_1 = phx::ref(v)], space)); + } + + // failing sub-generators + { + using boost::spirit::karma::strict; + using boost::spirit::karma::relaxed; + + typedef std::pair<char, char> data; + std::vector<data> v2; + v2 += std::make_pair('a', 'a'), + std::make_pair('b', 'b'), + std::make_pair('c', 'c'), + std::make_pair('d', 'd'), + std::make_pair('e', 'e'), + std::make_pair('f', 'f'), + std::make_pair('g', 'g'); + + karma::rule<spirit_test::output_iterator<char>::type, data()> r; + + r = &char_('d') << char_; + BOOST_TEST(test("d", r % ',', v2)); + BOOST_TEST(test("d", relaxed[r % ','], v2)); + BOOST_TEST(!test("", strict[r % ','], v2)); + + r = &char_('a') << char_; + BOOST_TEST(test("a", r % ',', v2)); + BOOST_TEST(test("a", relaxed[r % ','], v2)); + BOOST_TEST(test("a", strict[r % ','], v2)); + + r = &char_('g') << char_; + BOOST_TEST(test("g", r % ',', v2)); + BOOST_TEST(test("g", relaxed[r % ','], v2)); + BOOST_TEST(!test("", strict[r % ','], v2)); + + r = !char_('d') << char_; + BOOST_TEST(test("a,b,c,e,f,g", r % ',', v2)); + BOOST_TEST(test("a,b,c,e,f,g", relaxed[r % ','], v2)); + BOOST_TEST(test("a,b,c", strict[r % ','], v2)); + + r = !char_('a') << char_; + BOOST_TEST(test("b,c,d,e,f,g", r % ',', v2)); + BOOST_TEST(test("b,c,d,e,f,g", relaxed[r % ','], v2)); + BOOST_TEST(!test("", strict[r % ','], v2)); + + r = !char_('g') << char_; + BOOST_TEST(test("a,b,c,d,e,f", r % ',', v2)); + BOOST_TEST(test("a,b,c,d,e,f", relaxed[r % ','], v2)); + BOOST_TEST(test("a,b,c,d,e,f", strict[r % ','], v2)); + + r = &char_('A') << char_; + BOOST_TEST(!test("", r % ',', v2)); + } + + { + // make sure user defined end condition is applied if no attribute + // is passed in + BOOST_TEST(test("[61,62,63,64,65,66,67,68]", + '[' << hex[action(v)] % ',' << ']')); + } + + return boost::report_errors(); +} + diff --git a/src/boost/libs/spirit/test/karma/lit.cpp b/src/boost/libs/spirit/test/karma/lit.cpp new file mode 100644 index 00000000..9eb4d4f0 --- /dev/null +++ b/src/boost/libs/spirit/test/karma/lit.cpp @@ -0,0 +1,194 @@ +// 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/karma_char.hpp> +#include <boost/spirit/include/karma_string.hpp> +#include <boost/spirit/include/karma_generate.hpp> +#include <boost/spirit/include/karma_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" + +using namespace spirit_test; + +/////////////////////////////////////////////////////////////////////////////// +int +main() +{ + using namespace boost::spirit; + + { + using namespace boost::spirit::ascii; + + BOOST_TEST(test("a", lit('a'))); + BOOST_TEST(!test("a", lit('b'))); + + BOOST_TEST(test("abc", "abc")); + BOOST_TEST(!test("abcd", "abc")); + + BOOST_TEST(test("abc", lit("abc"))); + BOOST_TEST(!test("abcd", lit("abc"))); + + BOOST_TEST(test("abc", string, "abc")); + BOOST_TEST(!test("abcd", string, "abc")); + + BOOST_TEST(test("abc", string("abc"))); + BOOST_TEST(!test("abcd", string("abc"))); + + BOOST_TEST(test("abc", string("abc"), "abc")); + BOOST_TEST(!test("", string("abc"), "abcd")); + BOOST_TEST(!test("", string("abcd"), "abc")); + BOOST_TEST(!test("", string("abc"), "abcd")); // don't match prefixes only + } + + { + using namespace boost::spirit::ascii; + + std::string str("abc"); + BOOST_TEST(test("abc", lit(str))); + BOOST_TEST(!test("abcd", lit(str))); + + BOOST_TEST(test("abc", string(str))); + BOOST_TEST(!test("abcd", string(str))); + + BOOST_TEST(test("abc", string, str)); + BOOST_TEST(!test("abcd", string, str)); + + BOOST_TEST(test("abc", str)); + BOOST_TEST(!test("abcd", str)); + } + + { + using namespace boost::spirit::standard_wide; + + std::basic_string<wchar_t> wstr(L"abc"); + BOOST_TEST(test(L"abc", lit(wstr))); + BOOST_TEST(!test(L"abcd", lit(wstr))); + + BOOST_TEST(test(L"abc", string, wstr)); + BOOST_TEST(!test(L"abcd", string, wstr)); + + BOOST_TEST(test(L"abc", wstr)); + BOOST_TEST(!test(L"abcd", wstr)); + } + + { + using namespace boost::spirit::ascii; + + BOOST_TEST(test(L"a", lit(L'a'))); + BOOST_TEST(!test(L"a", lit(L'b'))); + + BOOST_TEST(test(L"abc", L"abc")); + BOOST_TEST(test(L"abc", "abc")); + BOOST_TEST(!test(L"abcd", L"abc")); + + BOOST_TEST(test(L"abc", lit(L"abc"))); + BOOST_TEST(!test(L"abcd", lit(L"abc"))); + + BOOST_TEST(test(L"abc", string(L"abc"))); + BOOST_TEST(!test(L"abcd", string(L"abc"))); + + BOOST_TEST(test(L"abc", string, L"abc")); + BOOST_TEST(!test(L"abcd", string, L"abc")); + + BOOST_TEST(test(L"abc", string, "abc")); + BOOST_TEST(!test(L"abcd", string, "abc")); + } + + { + using namespace boost::spirit::karma; + + const char test_data[] = "abc\x00s"; + const std::string str(test_data, sizeof(test_data) - 1); + + BOOST_TEST(test(str, lit(str))); + BOOST_TEST(!test("abc", lit(str))); + + BOOST_TEST(test(str, string(str))); + BOOST_TEST(!test("abc", string(str))); + + BOOST_TEST(test(str, string, str)); + BOOST_TEST(!test("abc", string, str)); + + BOOST_TEST(test(str, str)); + BOOST_TEST(!test("abc", str)); + } + + { + using namespace boost::spirit::ascii; + + BOOST_TEST(test_delimited("a ", lit('a'), ' ')); + BOOST_TEST(!test_delimited("a ", lit('b'), ' ')); + + BOOST_TEST(test_delimited("abc ", "abc", ' ')); + BOOST_TEST(!test_delimited("abcd ", "abc", ' ')); + + BOOST_TEST(test_delimited("abc ", lit("abc"), ' ')); + BOOST_TEST(!test_delimited("abcd ", lit("abc"), ' ')); + + BOOST_TEST(test_delimited("abc ", string, "abc", ' ')); + BOOST_TEST(!test_delimited("abcd ", string, "abc", ' ')); + + BOOST_TEST(test_delimited("abc ", string("abc"), ' ')); + BOOST_TEST(!test_delimited("abcd ", string("abc"), ' ')); + + BOOST_TEST(test_delimited("abc ", string("abc"), "abc", ' ')); + BOOST_TEST(!test_delimited("", string("abc"), "abcd", ' ')); + BOOST_TEST(!test_delimited("", string("abcd"), "abc", ' ')); + BOOST_TEST(!test_delimited("", string("abc"), "abcd", ' ')); // don't match prefixes only + } + + { + using namespace boost::spirit::ascii; + + BOOST_TEST(test_delimited(L"a ", lit(L'a'), ' ')); + BOOST_TEST(!test_delimited(L"a ", lit(L'b'), ' ')); + + BOOST_TEST(test_delimited(L"abc ", L"abc", ' ')); + BOOST_TEST(!test_delimited(L"abcd ", L"abc", ' ')); + + BOOST_TEST(test_delimited(L"abc ", lit(L"abc"), ' ')); + BOOST_TEST(!test_delimited(L"abcd ", lit(L"abc"), ' ')); + + BOOST_TEST(test_delimited(L"abc ", string, L"abc", ' ')); + BOOST_TEST(!test_delimited(L"abcd ", string, L"abc", ' ')); + + BOOST_TEST(test_delimited(L"abc ", string(L"abc"), ' ')); + BOOST_TEST(!test_delimited(L"abcd ", string(L"abc"), ' ')); + } + + { // test action + namespace phx = boost::phoenix; + using namespace boost::spirit::ascii; + + std::string str("abc"); + BOOST_TEST(test("abc", string[_1 = phx::ref(str)])); + BOOST_TEST(test_delimited("abc ", string[_1 = phx::ref(str)], space)); + } + + { // lazy strings + namespace phx = boost::phoenix; + using namespace boost::spirit::ascii; + + std::basic_string<char> s("abc"); + BOOST_TEST((test("abc", lit(phx::val(s))))); + BOOST_TEST((test("abc", string(phx::val(s))))); + + BOOST_TEST(test("abc", string(phx::val(s)), "abc")); + BOOST_TEST(!test("", string(phx::val(s)), "abcd")); + BOOST_TEST(!test("", string(phx::val(s)), "abc")); + + std::basic_string<wchar_t> ws(L"abc"); + BOOST_TEST((test(L"abc", lit(phx::ref(ws))))); + BOOST_TEST((test(L"abc", string(phx::ref(ws))))); + } + + return boost::report_errors(); +} diff --git a/src/boost/libs/spirit/test/karma/maxwidth.cpp b/src/boost/libs/spirit/test/karma/maxwidth.cpp new file mode 100644 index 00000000..75066a11 --- /dev/null +++ b/src/boost/libs/spirit/test/karma/maxwidth.cpp @@ -0,0 +1,77 @@ +// 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/karma_char.hpp> +#include <boost/spirit/include/karma_string.hpp> +#include <boost/spirit/include/karma_numeric.hpp> +#include <boost/spirit/include/karma_generate.hpp> +#include <boost/spirit/include/karma_directive.hpp> + +#include "test.hpp" + +using namespace spirit_test; + +/////////////////////////////////////////////////////////////////////////////// +int +main() +{ + using namespace boost::spirit; + using namespace boost::spirit::ascii; + + { + BOOST_TEST(test("0123456789", maxwidth[lit("0123456789")])); + BOOST_TEST(test("012345678", maxwidth[lit("012345678")])); + BOOST_TEST(test("0123456789", maxwidth[lit("01234567890")])); + + BOOST_TEST(test("0123456789", maxwidth[string], "0123456789")); + BOOST_TEST(test("012345678", maxwidth[string], "012345678")); + BOOST_TEST(test("0123456789", maxwidth[string], "01234567890")); + } + + { + BOOST_TEST(test("01234567", maxwidth(8)[lit("01234567")])); + BOOST_TEST(test("0123456", maxwidth(8)[lit("0123456")])); + BOOST_TEST(test("01234567", maxwidth(8)[lit("012345678")])); + + BOOST_TEST(test("01234567", maxwidth(8)[string], "01234567")); + BOOST_TEST(test("0123456", maxwidth(8)[string], "0123456")); + BOOST_TEST(test("01234567", maxwidth(8)[string], "012345678")); + } + + { + std::string str; + BOOST_TEST(test("01234567", + maxwidth(8, std::back_inserter(str))[lit("01234567")]) && + str.empty()); + + str = ""; + BOOST_TEST(test("0123456", + maxwidth(8, std::back_inserter(str))[lit("0123456")]) && + str.empty()); + + str = ""; + BOOST_TEST(test("01234567", + maxwidth(8, std::back_inserter(str))[lit("012345678")]) && + str == "8"); + } + + { + using namespace boost::phoenix; + + BOOST_TEST(test("01234567", maxwidth(val(8))[lit("01234567")])); + BOOST_TEST(test("0123456", maxwidth(val(8))[lit("0123456")])); + BOOST_TEST(test("01234567", maxwidth(val(8))[lit("012345678")])); + + int w = 8; + BOOST_TEST(test("01234567", maxwidth(ref(w))[string], "01234567")); + BOOST_TEST(test("0123456", maxwidth(ref(w))[string], "0123456")); + BOOST_TEST(test("01234567", maxwidth(ref(w))[string], "012345678")); + } + + return boost::report_errors(); +} diff --git a/src/boost/libs/spirit/test/karma/not_predicate.cpp b/src/boost/libs/spirit/test/karma/not_predicate.cpp new file mode 100644 index 00000000..6b4abeb9 --- /dev/null +++ b/src/boost/libs/spirit/test/karma/not_predicate.cpp @@ -0,0 +1,36 @@ +// 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/karma_generate.hpp> +#include <boost/spirit/include/karma_operator.hpp> +#include <boost/spirit/include/karma_auxiliary.hpp> +#include <boost/spirit/include/karma_char.hpp> +#include <boost/spirit/include/karma_string.hpp> + +#include <iostream> +#include "test.hpp" + +int +main() +{ + using namespace spirit_test; + using namespace boost::spirit; + + { + using boost::spirit::ascii::char_; + using boost::spirit::ascii::string; + + BOOST_TEST(test("c", !char_('a') << 'b' | 'c', 'a')); + BOOST_TEST(test("b", !char_('a') << 'b' | 'c', 'x')); + + BOOST_TEST(test("def", !string("123") << "abc" | "def", "123")); + BOOST_TEST(test("abc", !string("123") << "abc" | "def", "456")); + } + + return boost::report_errors(); +} diff --git a/src/boost/libs/spirit/test/karma/omit.cpp b/src/boost/libs/spirit/test/karma/omit.cpp new file mode 100644 index 00000000..9a349697 --- /dev/null +++ b/src/boost/libs/spirit/test/karma/omit.cpp @@ -0,0 +1,79 @@ +// 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/karma.hpp> +#include <boost/fusion/include/std_pair.hpp> +#include <boost/spirit/include/phoenix_core.hpp> +#include <boost/spirit/include/phoenix_operator.hpp> + +#include <iostream> +#include "test.hpp" + +using namespace spirit_test; + +int main() +{ + using boost::spirit::karma::_1; + using boost::spirit::karma::_a; + using boost::spirit::karma::double_; + using boost::spirit::karma::int_; + using boost::spirit::karma::omit; + using boost::spirit::karma::skip; + using boost::spirit::karma::rule; + using boost::spirit::karma::locals; + + typedef spirit_test::output_iterator<char>::type outiter_type; + typedef std::pair<std::vector<int>, int> attribute_type; + + rule<outiter_type, attribute_type(), locals<int> > r; + + attribute_type a; + a.first.push_back(0x01); + a.first.push_back(0x02); + a.first.push_back(0x04); + a.first.push_back(0x08); + a.second = 0; + + // omit[] is supposed to execute the embedded generator + { + std::pair<double, double> p (1.0, 2.0); + BOOST_TEST(test("2.0", omit[double_] << double_, p)); + + r %= omit[ *(int_[_a = _a + _1]) ] << int_[_1 = _a]; + BOOST_TEST(test("15", r, a)); + } + + // even if omit[] never fails, it has to honor the result of the + // embedded generator + { + typedef std::pair<double, double> attribute_type; + rule<outiter_type, attribute_type()> r; + + r %= omit[double_(1.0) << double_] | "42"; + + attribute_type p1 (1.0, 2.0); + BOOST_TEST(test("", r, p1)); + + attribute_type p2 (10.0, 2.0); + BOOST_TEST(test("42", r, p2)); + } + + // skip[] is not supposed to execute the embedded generator + { + using boost::spirit::karma::double_; + using boost::spirit::karma::skip; + + std::pair<double, double> p (1.0, 2.0); + BOOST_TEST(test("2.0", skip[double_] << double_, p)); + + r %= skip[ *(int_[_a = _a + _1]) ] << int_[_1 = _a]; + BOOST_TEST(test("0", r, a)); + } + + return boost::report_errors(); +} diff --git a/src/boost/libs/spirit/test/karma/optional.cpp b/src/boost/libs/spirit/test/karma/optional.cpp new file mode 100644 index 00000000..3369c1e6 --- /dev/null +++ b/src/boost/libs/spirit/test/karma/optional.cpp @@ -0,0 +1,90 @@ +// 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/karma_char.hpp> +#include <boost/spirit/include/karma_operator.hpp> +#include <boost/spirit/include/karma_numeric.hpp> +#include <boost/spirit/include/karma_action.hpp> +#include <boost/spirit/include/phoenix_core.hpp> +#include <boost/spirit/include/phoenix_operator.hpp> + +#include <iostream> +#include "test.hpp" + +int main() +{ + using namespace spirit_test; + using namespace boost::spirit; + using namespace boost::spirit::ascii; + + { + boost::optional<int> opt; + BOOST_TEST(test("", -int_, opt)); + + opt = 10; + BOOST_TEST(test("10", -int_, opt)); + } + + { + int opt = 10; + BOOST_TEST(test("10", -int_, opt)); + } + + { + boost::optional<int> opt; + BOOST_TEST(test_delimited("", -int_, opt, space)); + + opt = 10; + BOOST_TEST(test_delimited("10 ", -int_, opt, space)); + } + + { + int opt = 10; + BOOST_TEST(test_delimited("10 ", -int_, opt, space)); + } + + { // test action + using namespace boost::phoenix; + namespace phoenix = boost::phoenix; + + boost::optional<int> n ; + BOOST_TEST(test("", (-int_)[_1 = phoenix::ref(n)])); + + n = 1234; + BOOST_TEST(test("1234", (-int_)[_1 = phoenix::ref(n)])); + } + + { // test action + using namespace boost::phoenix; + namespace phoenix = boost::phoenix; + + int n = 1234; + BOOST_TEST(test("1234", (-int_)[_1 = phoenix::ref(n)])); + } + + { // test action + using namespace boost::phoenix; + namespace phoenix = boost::phoenix; + + boost::optional<int> n; + BOOST_TEST(test_delimited("", (-int_)[_1 = phoenix::ref(n)], space)); + + n = 1234; + BOOST_TEST(test_delimited("1234 ", (-int_)[_1 = phoenix::ref(n)], space)); + } + + { // test action + using namespace boost::phoenix; + namespace phoenix = boost::phoenix; + + int n = 1234; + BOOST_TEST(test_delimited("1234 ", (-int_)[_1 = phoenix::ref(n)], space)); + } + + return boost::report_errors(); +} diff --git a/src/boost/libs/spirit/test/karma/pattern1.cpp b/src/boost/libs/spirit/test/karma/pattern1.cpp new file mode 100644 index 00000000..9892bb05 --- /dev/null +++ b/src/boost/libs/spirit/test/karma/pattern1.cpp @@ -0,0 +1,112 @@ +// 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/karma_operator.hpp> +#include <boost/spirit/include/karma_char.hpp> +#include <boost/spirit/include/karma_auxiliary.hpp> +#include <boost/spirit/include/karma_string.hpp> +#include <boost/spirit/include/karma_numeric.hpp> +#include <boost/spirit/include/karma_nonterminal.hpp> +#include <boost/spirit/include/karma_action.hpp> +#include <boost/spirit/include/phoenix_core.hpp> +#include <boost/spirit/include/phoenix_operator.hpp> +#include <boost/spirit/include/phoenix_fusion.hpp> + +#include "test.hpp" + +using namespace spirit_test; + +/////////////////////////////////////////////////////////////////////////////// +int main() +{ + using namespace boost; + using namespace boost::spirit; + using namespace boost::spirit::ascii; + + typedef spirit_test::output_iterator<char>::type outiter_type; + + // test rule parameter propagation + { + using boost::phoenix::at_c; + + karma::rule<outiter_type, fusion::vector<char, int, double>()> start; + fusion::vector<char, int, double> vec('a', 10, 12.4); + + start %= char_ << int_ << double_; + BOOST_TEST(test("a1012.4", start, vec)); + + karma::rule<outiter_type, char()> a; + karma::rule<outiter_type, int()> b; + karma::rule<outiter_type, double()> c; + + a %= char_ << eps; + b %= int_; + c %= double_; + start = a[_1 = at_c<0>(_r0)] << b[_1 = at_c<1>(_r0)] << c[_1 = at_c<2>(_r0)]; + BOOST_TEST(test("a1012.4", start, vec)); + + start = (a << b << c)[_1 = at_c<0>(_r0), _2 = at_c<1>(_r0), _3 = at_c<2>(_r0)]; + BOOST_TEST(test("a1012.4", start, vec)); + + start = a << b << c; + BOOST_TEST(test("a1012.4", start, vec)); + + start %= a << b << c; + BOOST_TEST(test("a1012.4", start, vec)); + } + + { + using boost::phoenix::at_c; + + karma::rule<outiter_type, space_type, fusion::vector<char, int, double>()> start; + fusion::vector<char, int, double> vec('a', 10, 12.4); + + start %= char_ << int_ << double_; + BOOST_TEST(test_delimited("a 10 12.4 ", start, vec, space)); + + karma::rule<outiter_type, space_type, char()> a; + karma::rule<outiter_type, space_type, int()> b; + karma::rule<outiter_type, space_type, double()> c; + + a %= char_ << eps; + b %= int_; + c %= double_; + start = a[_1 = at_c<0>(_r0)] << b[_1 = at_c<1>(_r0)] << c[_1 = at_c<2>(_r0)]; + BOOST_TEST(test_delimited("a 10 12.4 ", start, vec, space)); + + start = (a << b << c)[_1 = at_c<0>(_r0), _2 = at_c<1>(_r0), _3 = at_c<2>(_r0)]; + BOOST_TEST(test_delimited("a 10 12.4 ", start, vec, space)); + + start = a << b << c; + BOOST_TEST(test_delimited("a 10 12.4 ", start, vec, space)); + + start %= a << b << c; + BOOST_TEST(test_delimited("a 10 12.4 ", start, vec, space)); + } + + // test direct initalization + { + using boost::phoenix::at_c; + + fusion::vector<char, int, double> vec('a', 10, 12.4); + karma::rule<outiter_type, space_type, fusion::vector<char, int, double>()> + start = char_ << int_ << double_;; + + BOOST_TEST(test_delimited("a 10 12.4 ", start, vec, space)); + + karma::rule<outiter_type, space_type, char()> a = char_ << eps; + karma::rule<outiter_type, space_type, int()> b = int_; + karma::rule<outiter_type, space_type, double()> c = double_; + + start = a[_1 = at_c<0>(_r0)] << b[_1 = at_c<1>(_r0)] << c[_1 = at_c<2>(_r0)]; + BOOST_TEST(test_delimited("a 10 12.4 ", start, vec, space)); + } + + return boost::report_errors(); +} + diff --git a/src/boost/libs/spirit/test/karma/pattern2.cpp b/src/boost/libs/spirit/test/karma/pattern2.cpp new file mode 100644 index 00000000..4621065e --- /dev/null +++ b/src/boost/libs/spirit/test/karma/pattern2.cpp @@ -0,0 +1,153 @@ +// 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/karma_operator.hpp> +#include <boost/spirit/include/karma_char.hpp> +#include <boost/spirit/include/karma_auxiliary.hpp> +#include <boost/spirit/include/karma_string.hpp> +#include <boost/spirit/include/karma_numeric.hpp> +#include <boost/spirit/include/karma_nonterminal.hpp> +#include <boost/spirit/include/karma_action.hpp> +#include <boost/spirit/include/phoenix_core.hpp> +#include <boost/spirit/include/phoenix_operator.hpp> + +#include "test.hpp" + +using namespace spirit_test; + +/////////////////////////////////////////////////////////////////////////////// +int main() +{ + using namespace boost; + using namespace boost::spirit; + using namespace boost::spirit::ascii; + + typedef spirit_test::output_iterator<char>::type outiter_type; + + // locals test + { + karma::rule<outiter_type, locals<std::string> > start; + + start = string[_1 = "abc", _a = _1] << int_[_1 = 10] << string[_1 = _a]; + BOOST_TEST(test("abc10abc", start)); + } + + { + karma::rule<outiter_type, space_type, locals<std::string> > start; + + start = string[_1 = "abc", _a = _1] << int_[_1 = 10] << string[_1 = _a]; + BOOST_TEST(test_delimited("abc 10 abc ", start, space)); + } + + // alias tests + { + typedef variant<char, int, double> var_type; + + karma::rule<outiter_type, var_type()> d, start; + + d = start.alias(); // d will always track start + + start = (char_ | int_ | double_)[_1 = _val]; + + var_type v ('a'); + BOOST_TEST(test("a", d, v)); + v = 10; + BOOST_TEST(test("10", d, v)); + v = 12.4; + BOOST_TEST(test("12.4", d, v)); + } + + { + typedef variant<char, int, double> var_type; + + karma::rule<outiter_type, space_type, var_type()> d, start; + + d = start.alias(); // d will always track start + + start = (char_ | int_ | double_)[_1 = _val]; + + var_type v ('a'); + BOOST_TEST(test_delimited("a ", d, v, space)); + v = 10; + BOOST_TEST(test_delimited("10 ", d, v, space)); + v = 12.4; + BOOST_TEST(test_delimited("12.4 ", d, v, space)); + } + + { + typedef variant<char, int, double> var_type; + + karma::rule<outiter_type, var_type()> d, start; + + d = start.alias(); // d will always track start + + start %= char_ | int_ | double_; + + var_type v ('a'); + BOOST_TEST(test("a", d, v)); + v = 10; + BOOST_TEST(test("10", d, v)); + v = 12.4; + BOOST_TEST(test("12.4", d, v)); + + start = char_ | int_ | double_; + + v = 'a'; + BOOST_TEST(test("a", d, v)); + v = 10; + BOOST_TEST(test("10", d, v)); + v = 12.4; + BOOST_TEST(test("12.4", d, v)); + } + + { + typedef variant<char, int, double> var_type; + + karma::rule<outiter_type, space_type, var_type()> d, start; + + d = start.alias(); // d will always track start + + start %= char_ | int_ | double_; + + var_type v ('a'); + BOOST_TEST(test_delimited("a ", d, v, space)); + v = 10; + BOOST_TEST(test_delimited("10 ", d, v, space)); + v = 12.4; + BOOST_TEST(test_delimited("12.4 ", d, v, space)); + + start = char_ | int_ | double_; + + v = 'a'; + BOOST_TEST(test_delimited("a ", d, v, space)); + v = 10; + BOOST_TEST(test_delimited("10 ", d, v, space)); + v = 12.4; + BOOST_TEST(test_delimited("12.4 ", d, v, space)); + } + + /////////////////////////////////////////////////////////////////////////// + { + using boost::spirit::karma::int_; + using boost::spirit::karma::_1; + using boost::spirit::karma::_val; + using boost::spirit::karma::space; + using boost::spirit::karma::space_type; + + karma::rule<outiter_type, int()> r1 = int_; + karma::rule<outiter_type, space_type, int()> r2 = int_; + + int i = 123; + int j = 456; + BOOST_TEST(test("123", r1[_1 = _val], i)); + BOOST_TEST(test_delimited("456 ", r2[_1 = _val], j, space)); + } + + return boost::report_errors(); +} + diff --git a/src/boost/libs/spirit/test/karma/pattern3.cpp b/src/boost/libs/spirit/test/karma/pattern3.cpp new file mode 100644 index 00000000..f5ff2bc0 --- /dev/null +++ b/src/boost/libs/spirit/test/karma/pattern3.cpp @@ -0,0 +1,120 @@ +// 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/karma_operator.hpp> +#include <boost/spirit/include/karma_char.hpp> +#include <boost/spirit/include/karma_auxiliary.hpp> +#include <boost/spirit/include/karma_string.hpp> +#include <boost/spirit/include/karma_numeric.hpp> +#include <boost/spirit/include/karma_nonterminal.hpp> +#include <boost/spirit/include/karma_action.hpp> +#include <boost/spirit/include/phoenix_core.hpp> +#include <boost/spirit/include/phoenix_operator.hpp> + +#include "test.hpp" + +using namespace spirit_test; + +/////////////////////////////////////////////////////////////////////////////// +int main() +{ + using namespace boost; + using namespace boost::spirit; + using namespace boost::spirit::ascii; + + typedef spirit_test::output_iterator<char>::type outiter_type; + + // basic tests + { + karma::rule<outiter_type> start; + + start = char_[_1 = 'a'] << int_[_1 = 10] << double_[_1 = 12.4]; + BOOST_TEST(test("a1012.4", start)); + + start = (char_ << int_ << double_)[_1 = 'a', _2 = 10, _3 = 12.4]; + BOOST_TEST(test("a1012.4", start)); + + karma::rule<outiter_type> a, b, c; + a = char_[_1 = 'a']; + b = int_[_1 = 10]; + c = double_[_1 = 12.4]; + + start = a << b << c; + BOOST_TEST(test("a1012.4", start)); + } + + // basic tests with delimiter + { + karma::rule<outiter_type, space_type> start; + + start = char_[_1 = 'a'] << int_[_1 = 10] << double_[_1 = 12.4]; + BOOST_TEST(test_delimited("a 10 12.4 ", start, space)); + + start = (char_ << int_ << double_)[_1 = 'a', _2 = 10, _3 = 12.4]; + BOOST_TEST(test_delimited("a 10 12.4 ", start, space)); + + karma::rule<outiter_type, space_type> a, b, c; + a = char_[_1 = 'a']; + b = int_[_1 = 10]; + c = double_[_1 = 12.4]; + + start = a << b << c; + BOOST_TEST(test_delimited("a 10 12.4 ", start, space)); + } + + // basic tests involving a direct parameter + { + typedef variant<char, int, double> var_type; + + karma::rule<outiter_type, var_type()> start; + + start = (char_ | int_ | double_)[_1 = _r0]; + + var_type v ('a'); + BOOST_TEST(test("a", start, v)); + v = 10; + BOOST_TEST(test("10", start, v)); + v = 12.4; + BOOST_TEST(test("12.4", start, v)); + } + + { + typedef variant<char, int, double> var_type; + + karma::rule<outiter_type, space_type, var_type()> start; + + start = (char_ | int_ | double_)[_1 = _r0]; + + var_type v ('a'); + BOOST_TEST(test_delimited("a ", start, v, space)); + v = 10; + BOOST_TEST(test_delimited("10 ", start, v, space)); + v = 12.4; + BOOST_TEST(test_delimited("12.4 ", start, v, space)); + } + + // test handling of single element fusion sequences + { + using boost::fusion::vector; + karma::rule<outiter_type, vector<int>()> r = int_; + + vector<int> v(1); + BOOST_TEST(test("1", r, v)); + } + + { + using boost::fusion::vector; + karma::rule<outiter_type, space_type, vector<int>()> r = int_; + + vector<int> v(1); + BOOST_TEST(test_delimited("1 ", r, v, space)); + } + + return boost::report_errors(); +} + diff --git a/src/boost/libs/spirit/test/karma/pattern4.cpp b/src/boost/libs/spirit/test/karma/pattern4.cpp new file mode 100644 index 00000000..b67939c6 --- /dev/null +++ b/src/boost/libs/spirit/test/karma/pattern4.cpp @@ -0,0 +1,141 @@ +// 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/karma_operator.hpp> +#include <boost/spirit/include/karma_char.hpp> +#include <boost/spirit/include/karma_auxiliary.hpp> +#include <boost/spirit/include/karma_string.hpp> +#include <boost/spirit/include/karma_numeric.hpp> +#include <boost/spirit/include/karma_nonterminal.hpp> +#include <boost/spirit/include/karma_action.hpp> +#include <boost/spirit/include/karma_directive.hpp> +#include <boost/spirit/include/phoenix_core.hpp> +#include <boost/spirit/include/phoenix_operator.hpp> + +#include "test.hpp" + +using namespace spirit_test; + +/////////////////////////////////////////////////////////////////////////////// +int main() +{ + using namespace boost; + using namespace boost::spirit; + using namespace boost::spirit::ascii; + + typedef spirit_test::output_iterator<char>::type outiter_type; + + { + karma::rule<outiter_type, void(char, int, double)> start; + fusion::vector<char, int, double> vec('a', 10, 12.4); + + start = char_[_1 = _r1] << int_[_1 = _r2] << double_[_1 = _r3]; + BOOST_TEST(test("a1012.4", start('a', 10, 12.4))); + + start = (char_ << int_ << double_)[_1 = _r1, _2 = _r2, _3 = _r3]; + BOOST_TEST(test("a1012.4", start('a', 10, 12.4))); + + karma::rule<outiter_type, void(char)> a; + karma::rule<outiter_type, void(int)> b; + karma::rule<outiter_type, void(double)> c; + + a = char_[_1 = _r1]; + b = int_[_1 = _r1]; + c = double_[_1 = _r1]; + start = a(_r1) << b(_r2) << c(_r3); + BOOST_TEST(test("a1012.4", start('a', 10, 12.4))); + } + + { + karma::rule<outiter_type, space_type, void(char, int, double)> start; + fusion::vector<char, int, double> vec('a', 10, 12.4); + + start = char_[_1 = _r1] << int_[_1 = _r2] << double_[_1 = _r3]; + BOOST_TEST(test_delimited("a 10 12.4 ", start('a', 10, 12.4), space)); + + start = (char_ << int_ << double_)[_1 = _r1, _2 = _r2, _3 = _r3]; + BOOST_TEST(test_delimited("a 10 12.4 ", start('a', 10, 12.4), space)); + + karma::rule<outiter_type, space_type, void(char)> a; + karma::rule<outiter_type, space_type, void(int)> b; + karma::rule<outiter_type, space_type, void(double)> c; + + a = char_[_1 = _r1]; + b = int_[_1 = _r1]; + c = double_[_1 = _r1]; + start = a(_r1) << b(_r2) << c(_r3); + BOOST_TEST(test_delimited("a 10 12.4 ", start('a', 10, 12.4), space)); + } + + // copy tests + { + karma::rule<outiter_type> a, b, c, start; + + a = 'a'; + b = int_(10); + c = double_(12.4); + + // 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("a1012.4", start)); + } + + { + karma::rule<outiter_type, space_type> a, b, c, start; + + a = 'a'; + b = int_(10); + c = double_(12.4); + + // 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_delimited("a 10 12.4 ", start, space)); + } + + { // specifying the encoding + using karma::lower; + using karma::upper; + using karma::string; + + typedef boost::spirit::char_encoding::iso8859_1 iso8859_1; + karma::rule<outiter_type, iso8859_1> r; + + r = lower['\xE1']; + BOOST_TEST(test("\xE1", r)); + r = lower[char_('\xC1')]; + BOOST_TEST(test("\xE1", r)); + r = upper['\xE1']; + BOOST_TEST(test("\xC1", r)); + r = upper[char_('\xC1')]; + BOOST_TEST(test("\xC1", r)); + + r = lower["\xE1\xC1"]; + BOOST_TEST(test("\xE1\xE1", r)); + r = lower[lit("\xE1\xC1")]; + BOOST_TEST(test("\xE1\xE1", r)); + r = lower[string("\xE1\xC1")]; + BOOST_TEST(test("\xE1\xE1", r)); + r = upper["\xE1\xC1"]; + BOOST_TEST(test("\xC1\xC1", r)); + r = upper[lit("\xE1\xC1")]; + BOOST_TEST(test("\xC1\xC1", r)); + r = upper[string("\xE1\xC1")]; + BOOST_TEST(test("\xC1\xC1", r)); + } + + return boost::report_errors(); +} + diff --git a/src/boost/libs/spirit/test/karma/pch.hpp b/src/boost/libs/spirit/test/karma/pch.hpp new file mode 100644 index 00000000..dd711908 --- /dev/null +++ b/src/boost/libs/spirit/test/karma/pch.hpp @@ -0,0 +1,21 @@ +/*============================================================================= + 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/karma.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 <vector> +#include <string> +#include <sstream> +#include <iostream> + +#endif diff --git a/src/boost/libs/spirit/test/karma/plus.cpp b/src/boost/libs/spirit/test/karma/plus.cpp new file mode 100644 index 00000000..1bd2daab --- /dev/null +++ b/src/boost/libs/spirit/test/karma/plus.cpp @@ -0,0 +1,223 @@ +// 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/assign/std/vector.hpp> + +#include <boost/spirit/include/karma_char.hpp> +#include <boost/spirit/include/karma_string.hpp> +#include <boost/spirit/include/karma_numeric.hpp> +#include <boost/spirit/include/karma_generate.hpp> +#include <boost/spirit/include/karma_operator.hpp> +#include <boost/spirit/include/karma_action.hpp> +#include <boost/spirit/include/karma_nonterminal.hpp> +#include <boost/spirit/include/karma_auxiliary.hpp> +#include <boost/spirit/include/karma_directive.hpp> +#include <boost/fusion/include/vector.hpp> +#include <boost/spirit/include/phoenix_core.hpp> +#include <boost/spirit/include/phoenix_operator.hpp> +#include <boost/fusion/include/std_pair.hpp> + +#include "test.hpp" + +using namespace spirit_test; + +/////////////////////////////////////////////////////////////////////////////// +struct action +{ + action (std::vector<char>& vec) + : vec(vec), it(vec.begin()) + {} + + void operator()(unsigned& value, boost::spirit::unused_type, bool& pass) const + { + pass = (it != vec.end()); + if (pass) + value = *it++; + } + + std::vector<char>& vec; + mutable std::vector<char>::iterator it; +}; + +/////////////////////////////////////////////////////////////////////////////// +int main() +{ + using namespace boost::spirit; + using namespace boost::spirit::ascii; + namespace fusion = boost::fusion; + + { + std::string s1("aaaa"); + BOOST_TEST(test("aaaa", +char_, s1)); + BOOST_TEST(test_delimited("a a a a ", +char_, s1, ' ')); + + std::string s2("a"); + BOOST_TEST(test("a", +char_, s2)); + BOOST_TEST(test_delimited("a ", +char_, s2, ' ')); + + std::string s3(""); + BOOST_TEST(!test("", +char_, s2)); + BOOST_TEST(!test_delimited("", +char_, s3, ' ')); + } + + { + std::string s1("aaaaa"); + BOOST_TEST(test("aaaaa", char_ << +(char_ << char_), s1)); + BOOST_TEST(test_delimited("a a a a a ", + char_ << +(char_ << char_), s1, ' ')); + + s1 = "a"; + BOOST_TEST(!test("", char_ << +(char_ << char_), s1)); + s1 = "aa"; + BOOST_TEST(!test("", char_ << +(char_ << char_), s1)); + s1 = "aaaa"; + BOOST_TEST(!test("", char_ << +(char_ << char_), s1)); + } + + { + using boost::spirit::karma::strict; + using boost::spirit::karma::relaxed; + using namespace boost::assign; + + typedef std::pair<char, char> data; + std::vector<data> v1; + v1 += std::make_pair('a', 'a'), + std::make_pair('b', 'b'), + std::make_pair('c', 'c'), + std::make_pair('d', 'd'), + std::make_pair('e', 'e'), + std::make_pair('f', 'f'), + std::make_pair('g', 'g'); + + karma::rule<spirit_test::output_iterator<char>::type, data()> r; + r = &char_('a') << char_; + + BOOST_TEST(!test("", r << +(r << r), v1)); + BOOST_TEST(!test("", relaxed[r << +(r << r)], v1)); + BOOST_TEST(!test("", strict[r << +(r << r)], v1)); + + v1 += std::make_pair('a', 'a'); + + BOOST_TEST(!test("", r << *(r << r), v1)); + BOOST_TEST(!test("", relaxed[r << +(r << r)], v1)); + BOOST_TEST(!test("", strict[r << +(r << r)], v1)); + + v1 += std::make_pair('a', 'a'); + + BOOST_TEST(test("aaa", r << +(r << r), v1)); + BOOST_TEST(test("aaa", relaxed[r << +(r << r)], v1)); + BOOST_TEST(!test("", strict[r << +(r << r)], v1)); + } + + { + using namespace boost::assign; + + std::vector<char> v; + v += 'a', 'b', 'c'; + + BOOST_TEST(test("abc", +char_, v)); + BOOST_TEST(test_delimited("a b c ", +char_, v, ' ')); + } + + { + using namespace boost::assign; + + std::vector<int> v; + v += 10, 20, 30; + + BOOST_TEST(test("102030", +int_, v)); + BOOST_TEST(test_delimited("10, 20, 30, ", +int_, v, lit(", "))); + + BOOST_TEST(test("10,20,30,", +(int_ << ','), v)); + BOOST_TEST(test_delimited("10 , 20 , 30 , ", +(int_ << ','), v, lit(' '))); + +// leads to infinite loops +// fusion::vector<char, char> cc ('a', 'c'); +// BOOST_TEST(test("ac", char_ << !+(lit(' ') << ',') << char_, cc)); +// BOOST_TEST(test_delimited("a c ", +// char_ << !+(lit(' ') << ',') << char_, cc, " ")); + } + + { // actions + using namespace boost::assign; + namespace phx = boost::phoenix; + + std::vector<char> v; + v += 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'; + + BOOST_TEST(test("abcdefgh", (+char_)[_1 = phx::ref(v)])); + BOOST_TEST(test_delimited("a b c d e f g h ", + (+char_ )[_1 = phx::ref(v)], space)); + } + + // failing sub-generators + { + using boost::spirit::karma::strict; + using boost::spirit::karma::relaxed; + + using namespace boost::assign; + + typedef std::pair<char, char> data; + std::vector<data> v2; + v2 += std::make_pair('a', 'a'), + std::make_pair('b', 'b'), + std::make_pair('c', 'c'), + std::make_pair('d', 'd'), + std::make_pair('e', 'e'), + std::make_pair('f', 'f'), + std::make_pair('g', 'g'); + + karma::rule<spirit_test::output_iterator<char>::type, data()> r; + + r = &char_('d') << char_; + BOOST_TEST(test("d", +r, v2)); + BOOST_TEST(test("d", relaxed[+r], v2)); + BOOST_TEST(!test("", strict[+r], v2)); + + r = &char_('a') << char_; + BOOST_TEST(test("a", +r, v2)); + BOOST_TEST(test("a", relaxed[+r], v2)); + BOOST_TEST(test("a", strict[+r], v2)); + + r = &char_('g') << char_; + BOOST_TEST(test("g", +r, v2)); + BOOST_TEST(test("g", relaxed[+r], v2)); + BOOST_TEST(!test("", strict[+r], v2)); + + r = !char_('d') << char_; + BOOST_TEST(test("abcefg", +r, v2)); + BOOST_TEST(test("abcefg", relaxed[+r], v2)); + BOOST_TEST(test("abc", strict[+r], v2)); + + r = !char_('a') << char_; + BOOST_TEST(test("bcdefg", +r, v2)); + BOOST_TEST(test("bcdefg", relaxed[+r], v2)); + BOOST_TEST(!test("", strict[+r], v2)); + + r = !char_('g') << char_; + BOOST_TEST(test("abcdef", +r, v2)); + BOOST_TEST(test("abcdef", +r, v2)); + BOOST_TEST(test("abcdef", +r, v2)); + + r = &char_('A') << char_; + BOOST_TEST(!test("", +r, v2)); + } + + { + // make sure user defined end condition is applied if no attribute + // is passed in + using namespace boost::assign; + + std::vector<char> v; + v += 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'; + BOOST_TEST(test("[6162636465666768]", '[' << +hex[action(v)] << ']')); + } + + return boost::report_errors(); +} + diff --git a/src/boost/libs/spirit/test/karma/real.hpp b/src/boost/libs/spirit/test/karma/real.hpp new file mode 100644 index 00000000..0acc7ed8 --- /dev/null +++ b/src/boost/libs/spirit/test/karma/real.hpp @@ -0,0 +1,115 @@ +/*============================================================================== + Copyright (c) 2001-2010 Hartmut Kaiser + Copyright (c) 2010 Bryce Lelbach + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ + +#if !defined(BOOST_SPIRIT_TEST_REAL_NUMERICS_HPP) +#define BOOST_SPIRIT_TEST_REAL_NUMERICS_HPP + +#include <boost/version.hpp> +#include <boost/config/warning_disable.hpp> +#include <boost/detail/lightweight_test.hpp> +#include <boost/math/concepts/real_concept.hpp> + +#include <boost/spirit/include/karma_char.hpp> +#include <boost/spirit/include/karma_numeric.hpp> +#include <boost/spirit/include/karma_generate.hpp> +#include <boost/spirit/include/karma_directive.hpp> + +#include <boost/limits.hpp> +#include "test.hpp" + +using namespace spirit_test; + +/////////////////////////////////////////////////////////////////////////////// +// policy for real_generator, which forces the scientific notation +template <typename T> +struct scientific_policy : boost::spirit::karma::real_policies<T> +{ + // we want the numbers always to be in scientific format + typedef boost::spirit::karma::real_policies<T> base_type; + static int floatfield(T) { return base_type::fmtflags::scientific; } +}; + +/////////////////////////////////////////////////////////////////////////////// +// policy for real_generator, which forces the fixed notation +template <typename T> +struct fixed_policy : boost::spirit::karma::real_policies<T> +{ + typedef boost::spirit::karma::real_policies<T> base_type; + + // we want the numbers always to be in fixed format + static int floatfield(T) { return base_type::fmtflags::fixed; } +}; + +/////////////////////////////////////////////////////////////////////////////// +// policy for real_generator, which forces to output trailing zeros in the +// fractional part +template <typename T> +struct trailing_zeros_policy : boost::spirit::karma::real_policies<T> // 4 digits +{ + // we want the numbers always to contain trailing zeros up to 4 digits in + // the fractional part + static bool trailing_zeros(T) { return true; } + + // we want to generate up to 4 fractional digits + static unsigned int precision(T) { return 4; } +}; + +/////////////////////////////////////////////////////////////////////////////// +// policy for real_generator, which forces the sign to be generated +template <typename T> +struct signed_policy : boost::spirit::karma::real_policies<T> +{ + // we want to always have a sign generated + static bool force_sign(T) + { + return true; + } +}; + +/////////////////////////////////////////////////////////////////////////////// +// policy for real_generator, which forces to output trailing zeros in the +// fractional part +template <typename T> +struct bordercase_policy : boost::spirit::karma::real_policies<T> +{ + // we want to generate up to the maximum significant amount of fractional + // digits + static unsigned int precision(T) + { + return std::numeric_limits<T>::digits10 + 1; + } +}; + +/////////////////////////////////////////////////////////////////////////////// +// policy for real_generator, which forces to output trailing zeros in the +// fractional part +template <typename T> +struct statefull_policy : boost::spirit::karma::real_policies<T> +{ + statefull_policy(int precision = 4, bool trailingzeros = false) + : precision_(precision), trailingzeros_(trailingzeros) + {} + + // we want to generate up to the maximum significant amount of fractional + // digits + unsigned int precision(T) const + { + return precision_; + } + + bool trailing_zeros(T) const + { + return trailingzeros_; + } + + int precision_; + bool trailingzeros_; +}; + +#endif // BOOST_SPIRIT_TEST_REAL_NUMERICS_HPP + diff --git a/src/boost/libs/spirit/test/karma/real1.cpp b/src/boost/libs/spirit/test/karma/real1.cpp new file mode 100644 index 00000000..8bb41102 --- /dev/null +++ b/src/boost/libs/spirit/test/karma/real1.cpp @@ -0,0 +1,180 @@ +// 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 "real.hpp" + +/////////////////////////////////////////////////////////////////////////////// +int main() +{ + using namespace boost::spirit; + + { + /////////////////////////////////////////////////////////////////////// + // use the default real_policies + BOOST_TEST(test("0.0", double_, 0.0)); + BOOST_TEST(test("1.0", double_, 1.0)); + BOOST_TEST(test("1.0", double_, 1.0001)); + BOOST_TEST(test("1.001", double_, 1.001)); + BOOST_TEST(test("1.01", double_, 1.010)); + BOOST_TEST(test("1.1", double_, 1.100)); + + BOOST_TEST(test("1.234e-04", double_, 0.00012345)); + BOOST_TEST(test("0.001", double_, 0.0012345)); + BOOST_TEST(test("0.012", double_, 0.012345)); + BOOST_TEST(test("0.123", double_, 0.12345)); + BOOST_TEST(test("1.234", double_, 1.2345)); + BOOST_TEST(test("12.346", double_, 12.346)); + BOOST_TEST(test("123.46", double_, 123.46)); + BOOST_TEST(test("1234.5", double_, 1234.5)); + BOOST_TEST(test("12342.0", double_, 12342.)); + BOOST_TEST(test("1.234e05", double_, 123420.)); + + BOOST_TEST(test("-1.0", double_, -1.0)); + BOOST_TEST(test("-1.234", double_, -1.2345)); + BOOST_TEST(test("-1.235", double_, -1.2346)); + BOOST_TEST(test("-1234.2", double_, -1234.2)); + + BOOST_TEST(test("1.0", double_(1.0))); + BOOST_TEST(test("1.0", double_(1.0001))); + BOOST_TEST(test("1.001", double_(1.001))); + BOOST_TEST(test("1.01", double_(1.010))); + BOOST_TEST(test("1.1", double_(1.100))); + + BOOST_TEST(test("1.234e-04", double_(0.00012345))); + BOOST_TEST(test("0.001", double_(0.0012345))); + BOOST_TEST(test("0.012", double_(0.012345))); + BOOST_TEST(test("0.123", double_(0.12345))); + BOOST_TEST(test("1.234", double_(1.2345))); + BOOST_TEST(test("12.346", double_(12.346))); + BOOST_TEST(test("123.46", double_(123.46))); + BOOST_TEST(test("1234.5", double_(1234.5))); + BOOST_TEST(test("12342.0", double_(12342.))); + BOOST_TEST(test("1.234e05", double_(123420.))); + } + + { + /////////////////////////////////////////////////////////////////////// + // test NaN and Inf + BOOST_TEST(test("nan", double_, std::numeric_limits<double>::quiet_NaN())); + BOOST_TEST(test("-nan", double_, -std::numeric_limits<double>::quiet_NaN())); + BOOST_TEST(test("inf", double_, std::numeric_limits<double>::infinity())); + BOOST_TEST(test("-inf", double_, -std::numeric_limits<double>::infinity())); + + typedef karma::real_generator<double, signed_policy<double> > signed_type; + signed_type const signed_ = signed_type(); + + BOOST_TEST(test("+nan", signed_, std::numeric_limits<double>::quiet_NaN())); + BOOST_TEST(test("-nan", signed_, -std::numeric_limits<double>::quiet_NaN())); + BOOST_TEST(test("+inf", signed_, std::numeric_limits<double>::infinity())); + BOOST_TEST(test("-inf", signed_, -std::numeric_limits<double>::infinity())); +#if defined(BOOST_SPIRIT_ZERO_PROBLEM) + BOOST_TEST(test(" 0.0", signed_, 0.0)); +#endif + + BOOST_TEST(test("+nan", signed_(std::numeric_limits<double>::quiet_NaN()))); + BOOST_TEST(test("-nan", signed_(-std::numeric_limits<double>::quiet_NaN()))); + BOOST_TEST(test("+inf", signed_(std::numeric_limits<double>::infinity()))); + BOOST_TEST(test("-inf", signed_(-std::numeric_limits<double>::infinity()))); +#if defined(BOOST_SPIRIT_ZERO_PROBLEM) + BOOST_TEST(test(" 0.0", signed_(0.0))); +#endif + } + + { + /////////////////////////////////////////////////////////////////////// + typedef karma::real_generator<double, statefull_policy<double> > + statefull_type; + + statefull_policy<double> policy(5, true); + statefull_type const statefull = statefull_type(policy); + + BOOST_TEST(test("0.00000", statefull, 0.0)); + BOOST_TEST(test("0.00000", statefull(0.0))); + + using namespace boost::phoenix; + BOOST_TEST(test("0.00000", statefull(val(0.0)))); + } + + { + /////////////////////////////////////////////////////////////////////// + typedef karma::real_generator<double, trailing_zeros_policy<double> > + trailing_zeros_type; + trailing_zeros_type const trail_zeros = trailing_zeros_type(); + + BOOST_TEST(test("0.0000", trail_zeros, 0.0)); + BOOST_TEST(test("1.0000", trail_zeros, 1.0)); + BOOST_TEST(test("1.0001", trail_zeros, 1.0001)); + BOOST_TEST(test("1.0010", trail_zeros, 1.001)); + BOOST_TEST(test("1.0100", trail_zeros, 1.010)); + BOOST_TEST(test("1.1000", trail_zeros, 1.100)); + + BOOST_TEST(test("1.2345e-04", trail_zeros, 0.00012345)); + BOOST_TEST(test("0.0012", trail_zeros, 0.0012345)); + BOOST_TEST(test("0.0123", trail_zeros, 0.012345)); + BOOST_TEST(test("0.1235", trail_zeros, 0.12345)); + BOOST_TEST(test("1.2345", trail_zeros, 1.2345)); + BOOST_TEST(test("12.3460", trail_zeros, 12.346)); + BOOST_TEST(test("123.4600", trail_zeros, 123.46)); + BOOST_TEST(test("1234.5000", trail_zeros, 1234.5)); + BOOST_TEST(test("12342.0000", trail_zeros, 12342.)); + BOOST_TEST(test("1.2342e05", trail_zeros, 123420.)); + + BOOST_TEST(test("-1.0000", trail_zeros, -1.0)); + BOOST_TEST(test("-1.2345", trail_zeros, -1.2345)); + BOOST_TEST(test("-1.2346", trail_zeros, -1.2346)); + BOOST_TEST(test("-1234.2000", trail_zeros, -1234.2)); + + BOOST_TEST(test("1.0000", trail_zeros(1.0))); + BOOST_TEST(test("1.0001", trail_zeros(1.0001))); + BOOST_TEST(test("1.0010", trail_zeros(1.001))); + BOOST_TEST(test("1.0100", trail_zeros(1.010))); + BOOST_TEST(test("1.1000", trail_zeros(1.100))); + + BOOST_TEST(test("1.2345e-04", trail_zeros(0.00012345))); + BOOST_TEST(test("0.0012", trail_zeros(0.0012345))); + BOOST_TEST(test("0.0123", trail_zeros(0.012345))); + BOOST_TEST(test("0.1235", trail_zeros(0.12345))); + BOOST_TEST(test("1.2345", trail_zeros(1.2345))); + BOOST_TEST(test("12.3460", trail_zeros(12.346))); + BOOST_TEST(test("123.4600", trail_zeros(123.46))); + BOOST_TEST(test("1234.5000", trail_zeros(1234.5))); + BOOST_TEST(test("12342.0000", trail_zeros(12342.))); + BOOST_TEST(test("1.2342e05", trail_zeros(123420.))); + } + + { + using namespace boost::spirit::ascii; + + /////////////////////////////////////////////////////////////////////// + // test NaN and Inf + BOOST_TEST(test("NAN", upper[double_], + std::numeric_limits<double>::quiet_NaN())); + BOOST_TEST(test("-NAN", upper[double_], + -std::numeric_limits<double>::quiet_NaN())); + BOOST_TEST(test("INF", upper[double_], + std::numeric_limits<double>::infinity())); + BOOST_TEST(test("-INF", upper[double_], + -std::numeric_limits<double>::infinity())); + + typedef karma::real_generator<double, signed_policy<double> > signed_type; + signed_type const signed_ = signed_type(); + + BOOST_TEST(test("+NAN", upper[signed_], + std::numeric_limits<double>::quiet_NaN())); + BOOST_TEST(test("-NAN", upper[signed_], + -std::numeric_limits<double>::quiet_NaN())); + BOOST_TEST(test("+INF", upper[signed_], + std::numeric_limits<double>::infinity())); + BOOST_TEST(test("-INF", upper[signed_], + -std::numeric_limits<double>::infinity())); +#if defined(BOOST_SPIRIT_ZERO_PROBLEM) + BOOST_TEST(test(" 0.0", upper[signed_], 0.0)); +#endif + } + + + return boost::report_errors(); +} diff --git a/src/boost/libs/spirit/test/karma/real2.cpp b/src/boost/libs/spirit/test/karma/real2.cpp new file mode 100644 index 00000000..62ff60d6 --- /dev/null +++ b/src/boost/libs/spirit/test/karma/real2.cpp @@ -0,0 +1,163 @@ +// 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 "real.hpp" + +/////////////////////////////////////////////////////////////////////////////// +int main() +{ + using namespace boost::spirit; + + { + using namespace boost::spirit::ascii; + + /////////////////////////////////////////////////////////////////////// + BOOST_TEST(test_delimited("0.0 ", double_, 0.0, char_(' '))); + BOOST_TEST(test_delimited("1.0 ", double_, 1.0, char_(' '))); + BOOST_TEST(test_delimited("1.0 ", double_, 1.0001, char_(' '))); + BOOST_TEST(test_delimited("1.001 ", double_, 1.001, char_(' '))); + BOOST_TEST(test_delimited("1.01 ", double_, 1.010, char_(' '))); + BOOST_TEST(test_delimited("1.1 ", double_, 1.100, char_(' '))); + + BOOST_TEST(test_delimited("1.234e-04 ", double_, 0.00012345, char_(' '))); + BOOST_TEST(test_delimited("0.001 ", double_, 0.0012345, char_(' '))); + BOOST_TEST(test_delimited("0.012 ", double_, 0.012345, char_(' '))); + BOOST_TEST(test_delimited("0.123 ", double_, 0.12345, char_(' '))); + BOOST_TEST(test_delimited("1.234 ", double_, 1.2345, char_(' '))); + BOOST_TEST(test_delimited("12.346 ", double_, 12.346, char_(' '))); + BOOST_TEST(test_delimited("123.46 ", double_, 123.46, char_(' '))); + BOOST_TEST(test_delimited("1234.5 ", double_, 1234.5, char_(' '))); + BOOST_TEST(test_delimited("12342.0 ", double_, 12342., char_(' '))); + BOOST_TEST(test_delimited("1.234e05 ", double_, 123420., char_(' '))); + + BOOST_TEST(test_delimited("-1.0 ", double_, -1.0, char_(' '))); + BOOST_TEST(test_delimited("-1.234 ", double_, -1.2345, char_(' '))); + BOOST_TEST(test_delimited("-1.235 ", double_, -1.2346, char_(' '))); + BOOST_TEST(test_delimited("-1234.2 ", double_, -1234.2, char_(' '))); + + BOOST_TEST(test_delimited("1.0 ", double_(1.0), char_(' '))); + BOOST_TEST(test_delimited("1.0 ", double_(1.0001), char_(' '))); + BOOST_TEST(test_delimited("1.001 ", double_(1.001), char_(' '))); + BOOST_TEST(test_delimited("1.01 ", double_(1.010), char_(' '))); + BOOST_TEST(test_delimited("1.1 ", double_(1.100), char_(' '))); + + BOOST_TEST(test_delimited("1.234e-04 ", double_(0.00012345), char_(' '))); + BOOST_TEST(test_delimited("0.001 ", double_(0.0012345), char_(' '))); + BOOST_TEST(test_delimited("0.012 ", double_(0.012345), char_(' '))); + BOOST_TEST(test_delimited("0.123 ", double_(0.12345), char_(' '))); + BOOST_TEST(test_delimited("1.234 ", double_(1.2345), char_(' '))); + BOOST_TEST(test_delimited("12.346 ", double_(12.346), char_(' '))); + BOOST_TEST(test_delimited("123.46 ", double_(123.46), char_(' '))); + BOOST_TEST(test_delimited("1234.5 ", double_(1234.5), char_(' '))); + BOOST_TEST(test_delimited("12342.0 ", double_(12342.), char_(' '))); + BOOST_TEST(test_delimited("1.234e05 ", double_(123420.), char_(' '))); + } + + { + using namespace boost::spirit::ascii; + + /////////////////////////////////////////////////////////////////////// + // test NaN and Inf + BOOST_TEST(test_delimited("nan ", double_, + std::numeric_limits<double>::quiet_NaN(), char_(' '))); + BOOST_TEST(test_delimited("-nan ", double_, + -std::numeric_limits<double>::quiet_NaN(), char_(' '))); + BOOST_TEST(test_delimited("inf ", double_, + std::numeric_limits<double>::infinity(), char_(' '))); + BOOST_TEST(test_delimited("-inf ", double_, + -std::numeric_limits<double>::infinity(), char_(' '))); + + typedef karma::real_generator<double, signed_policy<double> > signed_type; + signed_type const signed_ = signed_type(); + + BOOST_TEST(test_delimited("+nan ", signed_, + std::numeric_limits<double>::quiet_NaN(), char_(' '))); + BOOST_TEST(test_delimited("-nan ", signed_, + -std::numeric_limits<double>::quiet_NaN(), char_(' '))); + BOOST_TEST(test_delimited("+inf ", signed_, + std::numeric_limits<double>::infinity(), char_(' '))); + BOOST_TEST(test_delimited("-inf ", signed_, + -std::numeric_limits<double>::infinity(), char_(' '))); +#if defined(BOOST_SPIRIT_ZERO_PROBLEM) + BOOST_TEST(test_delimited(" 0.0 ", signed_, 0.0, char_(' '))); +#endif + } + + { + using namespace boost::spirit::ascii; + + /////////////////////////////////////////////////////////////////////// + typedef karma::real_generator<double, scientific_policy<double> > + science_type; + science_type const science = science_type(); + + BOOST_TEST(test("0.0e00", science, 0.0)); + BOOST_TEST(test("1.0e00", science, 1.0)); + + BOOST_TEST(test("1.234e-05", science, 0.000012345)); + BOOST_TEST(test("1.234e-04", science, 0.00012345)); + BOOST_TEST(test("1.234e-03", science, 0.0012345)); + BOOST_TEST(test("1.234e-02", science, 0.012345)); + BOOST_TEST(test("1.235e-01", science, 0.12345)); // note the rounding error! + BOOST_TEST(test("1.234e00", science, 1.2345)); + BOOST_TEST(test("1.235e01", science, 12.346)); + BOOST_TEST(test("1.235e02", science, 123.46)); + BOOST_TEST(test("1.234e03", science, 1234.5)); + BOOST_TEST(test("1.234e04", science, 12342.)); + BOOST_TEST(test("1.234e05", science, 123420.)); + + BOOST_TEST(test("-1.234e-05", science, -0.000012345)); + BOOST_TEST(test("-1.234e-04", science, -0.00012345)); + BOOST_TEST(test("-1.234e-03", science, -0.0012345)); + BOOST_TEST(test("-1.234e-02", science, -0.012345)); + BOOST_TEST(test("-1.235e-01", science, -0.12345)); // note the rounding error! + BOOST_TEST(test("-1.234e00", science, -1.2345)); + BOOST_TEST(test("-1.235e01", science, -12.346)); + BOOST_TEST(test("-1.235e02", science, -123.46)); + BOOST_TEST(test("-1.234e03", science, -1234.5)); + BOOST_TEST(test("-1.234e04", science, -12342.)); + BOOST_TEST(test("-1.234e05", science, -123420.)); + + BOOST_TEST(test("1.234E-05", upper[science], 0.000012345)); + BOOST_TEST(test("1.234E-04", upper[science], 0.00012345)); + BOOST_TEST(test("1.234E-03", upper[science], 0.0012345)); + BOOST_TEST(test("1.234E-02", upper[science], 0.012345)); + BOOST_TEST(test("1.235E-01", upper[science], 0.12345)); // note the rounding error! + BOOST_TEST(test("1.234E00", upper[science], 1.2345)); + BOOST_TEST(test("1.235E01", upper[science], 12.346)); + BOOST_TEST(test("1.235E02", upper[science], 123.46)); + BOOST_TEST(test("1.234E03", upper[science], 1234.5)); + BOOST_TEST(test("1.234E04", upper[science], 12342.)); + BOOST_TEST(test("1.234E05", upper[science], 123420.)); + + BOOST_TEST(test("-1.234E-05", upper[science], -0.000012345)); + BOOST_TEST(test("-1.234E-04", upper[science], -0.00012345)); + BOOST_TEST(test("-1.234E-03", upper[science], -0.0012345)); + BOOST_TEST(test("-1.234E-02", upper[science], -0.012345)); + BOOST_TEST(test("-1.235E-01", upper[science], -0.12345)); // note the rounding error! + BOOST_TEST(test("-1.234E00", upper[science], -1.2345)); + BOOST_TEST(test("-1.235E01", upper[science], -12.346)); + BOOST_TEST(test("-1.235E02", upper[science], -123.46)); + BOOST_TEST(test("-1.234E03", upper[science], -1234.5)); + BOOST_TEST(test("-1.234E04", upper[science], -12342.)); + BOOST_TEST(test("-1.234E05", upper[science], -123420.)); + } + + { + BOOST_TEST(test("1.0", lit(1.0))); + BOOST_TEST(test("1.0", lit(1.0f))); + BOOST_TEST(test("1.0", lit(1.0l))); + + BOOST_TEST(test("1.0", double_(1.0), 1.0)); + BOOST_TEST(test("1.0", float_(1.0), 1.0f)); + BOOST_TEST(test("1.0", long_double(1.0), 1.0l)); + BOOST_TEST(!test("", double_(1.0), 2.0)); + BOOST_TEST(!test("", float_(1.0), 2.0f)); + BOOST_TEST(!test("", long_double(1.0), 2.0l)); + } + + return boost::report_errors(); +} diff --git a/src/boost/libs/spirit/test/karma/real3.cpp b/src/boost/libs/spirit/test/karma/real3.cpp new file mode 100644 index 00000000..fda1508c --- /dev/null +++ b/src/boost/libs/spirit/test/karma/real3.cpp @@ -0,0 +1,185 @@ +// 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 <boost/spirit/include/version.hpp> +#include <boost/spirit/include/karma_phoenix_attributes.hpp> +#include <boost/spirit/include/phoenix_core.hpp> +#include <boost/spirit/include/phoenix_operator.hpp> +#include "real.hpp" + +/////////////////////////////////////////////////////////////////////////////// +// the customization points below have been added only recently +#if SPIRIT_VERSION >= 0x2050 +// does not provide proper std::numeric_limits, we need to roll our own +namespace boost { namespace spirit { namespace traits +{ + template <> + struct is_nan<boost::math::concepts::real_concept> + { + static bool call(boost::math::concepts::real_concept n) + { + return test_nan(n.value()); + } + }; + + template <> + struct is_infinite<boost::math::concepts::real_concept> + { + static bool call(boost::math::concepts::real_concept n) + { + return test_infinite(n.value()); + } + }; +}}} +#endif + +/////////////////////////////////////////////////////////////////////////////// +int main() +{ + using namespace boost::spirit; + + { + using namespace boost::spirit::ascii; + + /////////////////////////////////////////////////////////////////////// + typedef karma::real_generator<double, fixed_policy<double> > fixed_type; + fixed_type const fixed = fixed_type(); + + BOOST_TEST(test("0.0", fixed, 0.0)); + BOOST_TEST(test("1.0", fixed, 1.0)); + + BOOST_TEST(test("0.0", fixed, 0.000012345)); + BOOST_TEST(test("0.0", fixed, 0.00012345)); + BOOST_TEST(test("0.001", fixed, 0.0012345)); + BOOST_TEST(test("0.012", fixed, 0.012345)); + BOOST_TEST(test("0.123", fixed, 0.12345)); + BOOST_TEST(test("1.234", fixed, 1.2345)); + BOOST_TEST(test("12.345", fixed, 12.345)); + BOOST_TEST(test("123.45", fixed, 123.45)); + BOOST_TEST(test("1234.5", fixed, 1234.5)); + BOOST_TEST(test("12342.0", fixed, 12342.)); + BOOST_TEST(test("123420.0", fixed, 123420.)); + BOOST_TEST(test("123420000000000000000.0", fixed, 1.23420e20)); + + BOOST_TEST(test("0.0", fixed, -0.000012345)); + BOOST_TEST(test("0.0", fixed, -0.00012345)); + BOOST_TEST(test("-0.001", fixed, -0.0012345)); + BOOST_TEST(test("-0.012", fixed, -0.012345)); + BOOST_TEST(test("-0.123", fixed, -0.12345)); + BOOST_TEST(test("-1.234", fixed, -1.2345)); + BOOST_TEST(test("-12.346", fixed, -12.346)); + BOOST_TEST(test("-123.46", fixed, -123.46)); + BOOST_TEST(test("-1234.5", fixed, -1234.5)); + BOOST_TEST(test("-12342.0", fixed, -12342.)); + BOOST_TEST(test("-123420.0", fixed, -123420.)); + BOOST_TEST(test("-123420000000000000000.0", fixed, -1.23420e20)); + } + +// support for using real_concept with a Karma generator has been implemented +// in Boost versions > 1.36 only, additionally real_concept is available only +// if BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS is not defined +#if BOOST_VERSION > 103600 && !defined(BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS) + { + using boost::math::concepts::real_concept; + typedef karma::real_generator<real_concept> custom_type; + custom_type const custom = custom_type(); + + BOOST_TEST(test("0.0", custom, real_concept(0.0))); + BOOST_TEST(test("1.0", custom, real_concept(1.0))); + BOOST_TEST(test("1.0", custom, real_concept(1.0001))); + BOOST_TEST(test("1.001", custom, real_concept(1.001))); + BOOST_TEST(test("1.01", custom, real_concept(1.010))); + BOOST_TEST(test("1.1", custom, real_concept(1.100))); + + BOOST_TEST(test("1.234e-04", custom, real_concept(0.00012345))); + BOOST_TEST(test("0.001", custom, real_concept(0.0012345))); + BOOST_TEST(test("0.012", custom, real_concept(0.012345))); + BOOST_TEST(test("0.123", custom, real_concept(0.12345))); + BOOST_TEST(test("1.234", custom, real_concept(1.2345))); + BOOST_TEST(test("12.346", custom, real_concept(12.346))); + BOOST_TEST(test("123.46", custom, real_concept(123.46))); + BOOST_TEST(test("1234.5", custom, real_concept(1234.5))); + BOOST_TEST(test("12342.0", custom, real_concept(12342.))); + BOOST_TEST(test("1.234e05", custom, real_concept(123420.))); + + BOOST_TEST(test("-1.0", custom, real_concept(-1.0))); + BOOST_TEST(test("-1.234", custom, real_concept(-1.2345))); + BOOST_TEST(test("-1.235", custom, real_concept(-1.2346))); + BOOST_TEST(test("-1234.2", custom, real_concept(-1234.2))); + + BOOST_TEST(test("1.0", custom(real_concept(1.0)))); + BOOST_TEST(test("1.0", custom(real_concept(1.0001)))); + BOOST_TEST(test("1.001", custom(real_concept(1.001)))); + BOOST_TEST(test("1.01", custom(real_concept(1.010)))); + BOOST_TEST(test("1.1", custom(real_concept(1.100)))); + + BOOST_TEST(test("1.234e-04", custom(real_concept(0.00012345)))); + BOOST_TEST(test("0.001", custom(real_concept(0.0012345)))); + BOOST_TEST(test("0.012", custom(real_concept(0.012345)))); + BOOST_TEST(test("0.123", custom(real_concept(0.12345)))); + BOOST_TEST(test("1.234", custom(real_concept(1.2345)))); + BOOST_TEST(test("12.346", custom(real_concept(12.346)))); + BOOST_TEST(test("123.46", custom(real_concept(123.46)))); + BOOST_TEST(test("1234.5", custom(real_concept(1234.5)))); + BOOST_TEST(test("12342.0", custom(real_concept(12342.)))); + BOOST_TEST(test("1.234e05", custom(real_concept(123420.)))); + } +#endif + +// this appears to be broken on Apple Tiger x86 with gcc4.0.1 +#if (__GNUC__*10000 + __GNUC_MINOR__*100 + __GNUC_PATCHLEVEL__ != 40001) || \ + !defined(__APPLE__) + { + /////////////////////////////////////////////////////////////////////// + typedef karma::real_generator<double, bordercase_policy<double> > + bordercase_type; + bordercase_type const bordercase = bordercase_type(); + +// BOOST_TEST(test("-5.7222349715140557e307", +// bordercase(-5.7222349715140557e307))); + + BOOST_TEST(test("1.7976931348623158e308", + bordercase(1.7976931348623158e308))); // DBL_MAX + BOOST_TEST(test("-1.7976931348623158e308", + bordercase(-1.7976931348623158e308))); // -DBL_MAX + BOOST_TEST(test("2.2250738585072014e-308", + bordercase(2.2250738585072014e-308))); // DBL_MIN + BOOST_TEST(test("-2.2250738585072014e-308", + bordercase(-2.2250738585072014e-308))); // -DBL_MIN + } +#endif + + { + boost::optional<double> v; + BOOST_TEST(!test("", double_, v)); + BOOST_TEST(!test("", double_(1.0), v)); + + v = 1.0; + BOOST_TEST(test("1.0", double_, v)); + BOOST_TEST(test("1.0", double_(1.0), v)); + } + +// we support Phoenix attributes only starting with V2.2 +#if SPIRIT_VERSION >= 0x2020 + { // Phoenix expression tests (requires to include + // karma_phoenix_attributes.hpp) + namespace phoenix = boost::phoenix; + + BOOST_TEST(test("1.0", double_, phoenix::val(1.0))); + + double d = 1.2; + BOOST_TEST(test("1.2", double_, phoenix::ref(d))); + BOOST_TEST(test("2.2", double_, ++phoenix::ref(d))); + } +#endif + + // test for denormalized numbers + { + BOOST_TEST(test("4.941e-324", double_, std::numeric_limits<double>::denorm_min())); + } + return boost::report_errors(); +} + diff --git a/src/boost/libs/spirit/test/karma/regression_adapt_adt.cpp b/src/boost/libs/spirit/test/karma/regression_adapt_adt.cpp new file mode 100644 index 00000000..41e88dc5 --- /dev/null +++ b/src/boost/libs/spirit/test/karma/regression_adapt_adt.cpp @@ -0,0 +1,176 @@ +// Copyright (c) 2001-2011 Hartmut Kaiser +// Copyright (c) 2011 Colin Rundel +// +// Distributed under the 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/mpl/print.hpp> +#include <boost/config/warning_disable.hpp> +#include <boost/detail/lightweight_test.hpp> + +#include <boost/fusion/include/adapt_adt.hpp> + +#include <boost/spirit/include/karma.hpp> +#include <boost/spirit/include/support_adapt_adt_attributes.hpp> + +#include "test.hpp" + +/////////////////////////////////////////////////////////////////////////////// +class data1 +{ +private: + int width_; + int height_; + +public: + data1() + : width_(400), height_(400) + {} + + data1(int width, int height) + : width_(width), height_(height) + {} + + int width() const { return width_;} + int height() const { return height_;} + + void set_width(int width) { width_ = width;} + void set_height(int height) { height_ = height;} +}; + +BOOST_FUSION_ADAPT_ADT( + data1, + (int, int, obj.width(), obj.set_width(val)) + (int, int, obj.height(), obj.set_height(val)) +) + +/////////////////////////////////////////////////////////////////////////////// +class data2 +{ +private: + std::string data_; + +public: + data2() + : data_("test") + {} + + data2(std::string const& data) + : data_(data) + {} + + std::string const& data() const { return data_;} + void set_data(std::string const& data) { data_ = data;} +}; + +BOOST_FUSION_ADAPT_ADT( + data2, + (std::string, std::string const&, obj.data(), obj.set_data(val)) +) + +/////////////////////////////////////////////////////////////////////////////// +class data3 +{ +private: + double data_; + +public: + data3(double data = 0.0) + : data_(data) + {} + + double data() const { return data_;} + void set_data(double data) { data_ = data;} +}; + +BOOST_FUSION_ADAPT_ADT( + data3, + (double, double, obj.data(), obj.set_data(val)) +) + +/////////////////////////////////////////////////////////////////////////////// +class data4 +{ +public: + boost::optional<int> a_; + boost::optional<double> b_; + boost::optional<std::string> c_; + + boost::optional<int> const& a() const { return a_; } + boost::optional<double> const& b() const { return b_; } + boost::optional<std::string> const& c() const { return c_; } +}; + + +BOOST_FUSION_ADAPT_ADT( + data4, + (boost::optional<int>, boost::optional<int> const&, obj.a(), /**/) + (boost::optional<double>, boost::optional<double> const&, obj.b(), /**/) + (boost::optional<std::string>, boost::optional<std::string> const&, obj.c(), /**/) +) + +/////////////////////////////////////////////////////////////////////////////// +int main () +{ + using spirit_test::test; + + { + using boost::spirit::karma::int_; + + data1 b(800, 600); + BOOST_TEST(test("width: 800\nheight: 600\n", + "width: " << int_ << "\n" << "height: " << int_ << "\n", b)); + } + + { + using boost::spirit::karma::char_; + using boost::spirit::karma::string; + + data2 d("test"); + BOOST_TEST(test("data: test\n", "data: " << +char_ << "\n", d)); + BOOST_TEST(test("data: test\n", "data: " << string << "\n", d)); + } + + { + using boost::spirit::karma::double_; + + BOOST_TEST(test("x=0.0\n", "x=" << double_ << "\n", data3(0))); + BOOST_TEST(test("x=1.1\n", "x=" << double_ << "\n", data3(1.1))); + BOOST_TEST(test("x=1.0e10\n", "x=" << double_ << "\n", data3(1e10))); + +#if defined(_MSC_VER) && _MSC_VER < 1900 +# pragma warning(push) +# pragma warning(disable: 4127) // conditional expression is constant +#endif + BOOST_TEST(test("x=inf\n", "x=" << double_ << "\n", + data3(std::numeric_limits<double>::infinity()))); + if (std::numeric_limits<double>::has_quiet_NaN) { + BOOST_TEST(test("x=nan\n", "x=" << double_ << "\n", + data3(std::numeric_limits<double>::quiet_NaN()))); + } + if (std::numeric_limits<double>::has_signaling_NaN) { + BOOST_TEST(test("x=nan\n", "x=" << double_ << "\n", + data3(std::numeric_limits<double>::signaling_NaN()))); + } +#if defined(_MSC_VER) && _MSC_VER < 1900 +# pragma warning(pop) +#endif + } + + { + using boost::spirit::karma::double_; + using boost::spirit::karma::int_; + using boost::spirit::karma::string; + + data4 d; + d.b_ = 10; + + BOOST_TEST(test( + "Testing: b: 10.0\n", + "Testing: " << -("a: " << int_ << "\n") + << -("b: " << double_ << "\n") + << -("c: " << string << "\n"), d)); + } + + return boost::report_errors(); +} diff --git a/src/boost/libs/spirit/test/karma/regression_center_alignment.cpp b/src/boost/libs/spirit/test/karma/regression_center_alignment.cpp new file mode 100644 index 00000000..a2ff3b3c --- /dev/null +++ b/src/boost/libs/spirit/test/karma/regression_center_alignment.cpp @@ -0,0 +1,66 @@ +// Copyright (c) 2001-2012 Hartmut Kaiser +// Copyright (c) 2012 yyyy yyyy <typhoonking77@hotmail.com> +// +// Distributed under the 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<boost/spirit/include/karma.hpp> + +int main() +{ + namespace karma = boost::spirit::karma; + + int num[] = {0, 1, 2, 3, 4, 5}; + std::vector<int> contents(num, num + sizeof(num) / sizeof(int)); + + { + std::string result; + BOOST_TEST(karma::generate(std::back_inserter(result), + *karma::center[karma::int_], contents)); + BOOST_TEST(result == " 0 1 2 3 4 5 "); + } + + { + std::string result; + BOOST_TEST(karma::generate(std::back_inserter(result), + *karma::center(5)[karma::int_], contents)); + BOOST_TEST(result == " 0 1 2 3 4 5 "); + } + + { + std::string result; + BOOST_TEST(karma::generate(std::back_inserter(result), + *karma::center("_")[karma::int_], contents)); + BOOST_TEST(result == "_____0_________1_________2_________3_________4_________5____"); + } + + { + std::string result; + BOOST_TEST(karma::generate(std::back_inserter(result), + *karma::center(5, "_")[karma::int_], contents)); + BOOST_TEST(result == "__0____1____2____3____4____5__"); + } + + { + std::string result; + BOOST_TEST(karma::generate(std::back_inserter(result), + *karma::center(karma::char_("_"))[karma::int_], contents)); + BOOST_TEST(result == "_____0_________1_________2_________3_________4_________5____"); + } + + { + std::string result; + BOOST_TEST(karma::generate(std::back_inserter(result), + *karma::center(5, karma::char_("_"))[karma::int_], contents)); + BOOST_TEST(result == "__0____1____2____3____4____5__"); + } + + return boost::report_errors(); +} + diff --git a/src/boost/libs/spirit/test/karma/regression_const_real_policies.cpp b/src/boost/libs/spirit/test/karma/regression_const_real_policies.cpp new file mode 100644 index 00000000..122ceea1 --- /dev/null +++ b/src/boost/libs/spirit/test/karma/regression_const_real_policies.cpp @@ -0,0 +1,25 @@ +// Copyright (c) 2001-2011 Hartmut Kaiser +// Copyright (c) 2011 Jeroen Habraken +// +// Distributed under the 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 verifying it's possible to use const types for real_policies. + +#include <boost/spirit/include/karma.hpp> + +#include <iterator> +#include <string> + +int main() +{ + using namespace boost::spirit::karma; + + typedef real_generator<double const, real_policies<double const> > + double_const_type; + + std::string generated; + generate(std::back_inserter(generated), double_const_type(), 1.0); + + return 0; +} diff --git a/src/boost/libs/spirit/test/karma/regression_container_variant_sequence.cpp b/src/boost/libs/spirit/test/karma/regression_container_variant_sequence.cpp new file mode 100644 index 00000000..56df14e2 --- /dev/null +++ b/src/boost/libs/spirit/test/karma/regression_container_variant_sequence.cpp @@ -0,0 +1,71 @@ +// Copyright (c) 2001-2012 Hartmut Kaiser +// Copyright (c) 2012 Benjamin Schindler +// +// Distributed under the 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/karma.hpp> +#include <boost/fusion/include/adapt_struct.hpp> +#include <set> + +namespace generator +{ + struct Enum + { + std::string enumName; + std::vector<std::string> enumEntries; + }; + typedef boost::variant<std::string, Enum> VariantType; + + namespace karma = boost::spirit::karma; + + // Our grammar definition + template<typename Iterator> + struct SettingsHeaderGenerator: karma::grammar<Iterator, VariantType()> + { + SettingsHeaderGenerator() : SettingsHeaderGenerator::base_type(baseRule) + { + using karma::lit; + using karma::string; + + enumRule = lit("enum ") << string << lit("\n{\n") << string % ",\n" << "}"; + declarationRule = lit("class ") << string << ';'; + baseRule = (declarationRule | enumRule) << lit("\n"); + + baseRule.name("base"); + enumRule.name("enum"); + declarationRule.name("declaration"); + } + + karma::rule<Iterator, std::string()> declarationRule; + karma::rule<Iterator, Enum()> enumRule; + karma::rule<Iterator, VariantType()> baseRule; + }; + + template <typename OutputIterator> + bool generate_header(OutputIterator& sink, VariantType& data) + { + SettingsHeaderGenerator<OutputIterator> generator; + return karma::generate(sink, generator, data); + } +} + +BOOST_FUSION_ADAPT_STRUCT(generator::Enum, + (std::string, enumName) + (std::vector<std::string>, enumEntries) +) + +int main() +{ + generator::VariantType variant = "bla"; + std::string generated; + std::back_insert_iterator<std::string> sink(generated); + BOOST_TEST(generator::generate_header(sink, variant)); + BOOST_TEST(generated == "class bla;\n"); + + return boost::report_errors(); +} + diff --git a/src/boost/libs/spirit/test/karma/regression_iterator.cpp b/src/boost/libs/spirit/test/karma/regression_iterator.cpp new file mode 100644 index 00000000..915d61aa --- /dev/null +++ b/src/boost/libs/spirit/test/karma/regression_iterator.cpp @@ -0,0 +1,42 @@ +// Copyright (c) 2013 Louis Dionne +// Copyright (c) 2001-2013 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/range/adaptor/transformed.hpp> +#include <boost/spirit/include/karma.hpp> + +#include <iostream> + +// Note how the return is made by value instead of by reference. +template <typename T> T identity(T const& t) { return t; } + +template <typename Char, typename Expr, typename CopyExpr, typename CopyAttr + , typename Delimiter, typename Attribute> +bool test(Char const *expected, + boost::spirit::karma::detail::format_manip< + Expr, CopyExpr, CopyAttr, Delimiter, Attribute> const& fm) +{ + std::ostringstream ostrm; + ostrm << fm; + return ostrm.good() && ostrm.str() == expected; +} + +int main() +{ + namespace karma = boost::spirit::karma; + namespace adaptors = boost::adaptors; + int ints[] = {0, 1, 2, 3, 4}; + + BOOST_TEST((test("0 1 2 3 4", + karma::format(karma::int_ % ' ', + ints | adaptors::transformed(&identity<int>))) + )); + + return boost::report_errors(); +} + diff --git a/src/boost/libs/spirit/test/karma/regression_optional_double.cpp b/src/boost/libs/spirit/test/karma/regression_optional_double.cpp new file mode 100644 index 00000000..b1fc422a --- /dev/null +++ b/src/boost/libs/spirit/test/karma/regression_optional_double.cpp @@ -0,0 +1,52 @@ +// 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/config/warning_disable.hpp> +#include <boost/spirit/include/karma.hpp> +#include <boost/detail/lightweight_test.hpp> + +namespace client +{ + namespace karma = boost::spirit::karma; + + template <typename OutputIterator> + struct grammar + : karma::grammar<OutputIterator, boost::optional<double>()> + { + grammar() + : grammar::base_type(start) + { + using karma::double_; + + u = double_ << "U"; + start = ( !double_ << "NA" ) | u; + + start.name("start"); + u.name("u"); + } + + karma::rule<OutputIterator, double()> u; + karma::rule<OutputIterator, boost::optional<double>()> start; + }; +} + +int main() +{ + namespace karma = boost::spirit::karma; + + typedef std::back_insert_iterator<std::string> sink_type; + + boost::optional<double> d1, d2; + d2 = 1.0; + + std::string generated1, generated2; + client::grammar<sink_type> g; + + BOOST_TEST(karma::generate(sink_type(generated1), g, d1) && generated1 == "NA"); + BOOST_TEST(karma::generate(sink_type(generated2), g, d2) && generated2 == "1.0U"); + + return boost::report_errors(); +} diff --git a/src/boost/libs/spirit/test/karma/regression_real_0.cpp b/src/boost/libs/spirit/test/karma/regression_real_0.cpp new file mode 100644 index 00000000..c04c1424 --- /dev/null +++ b/src/boost/libs/spirit/test/karma/regression_real_0.cpp @@ -0,0 +1,24 @@ +// Copyright (c) 2012 Agustin K-ballo Berge +// 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/spirit/include/karma.hpp> +#include <boost/detail/lightweight_test.hpp> + +#include <iterator> +#include <sstream> +#include <string> + +int main() +{ + namespace karma = boost::spirit::karma; + std::string output; + std::back_insert_iterator< std::string > sink = std::back_inserter( output ); + karma::generate( sink, karma::double_, 0 ); // prints ¨inf¨ instead of ¨0.0¨ + BOOST_TEST((output == "0.0")); + return boost::report_errors(); +} + diff --git a/src/boost/libs/spirit/test/karma/regression_real_policy_sign.cpp b/src/boost/libs/spirit/test/karma/regression_real_policy_sign.cpp new file mode 100644 index 00000000..e4225f7f --- /dev/null +++ b/src/boost/libs/spirit/test/karma/regression_real_policy_sign.cpp @@ -0,0 +1,43 @@ +// Copyright (c) 2013 Alex Korobka +// +// Distributed under the 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 test checks whether #8970 was fixed + +#include <boost/config/warning_disable.hpp> +#include <boost/detail/lightweight_test.hpp> +#include <iostream> +#include <boost/spirit/include/karma.hpp> + +#include "test.hpp" + +using namespace spirit_test; +using namespace boost::spirit; + +template <typename Num> +struct signed_policy : karma::real_policies<Num> +{ + static bool force_sign(Num /*n*/) { return true; } +}; + +int main() +{ + karma::real_generator<double, signed_policy<double> > const force_sign_double = + karma::real_generator<double, signed_policy<double> >(); + + BOOST_TEST(test("-0.123", force_sign_double, -0.123)); + BOOST_TEST(test("-1.123", force_sign_double, -1.123)); + BOOST_TEST(test("0.0", force_sign_double, 0)); + BOOST_TEST(test("+0.123", force_sign_double, 0.123)); + BOOST_TEST(test("+1.123", force_sign_double, 1.123)); + + using karma::double_; + BOOST_TEST(test("-0.123", double_, -0.123)); + BOOST_TEST(test("-1.123", double_, -1.123)); + BOOST_TEST(test("0.0", double_, 0)); + BOOST_TEST(test("0.123", double_, 0.123)); + BOOST_TEST(test("1.123", double_, 1.123)); + + return boost::report_errors(); +} diff --git a/src/boost/libs/spirit/test/karma/regression_real_scientific.cpp b/src/boost/libs/spirit/test/karma/regression_real_scientific.cpp new file mode 100644 index 00000000..45f67965 --- /dev/null +++ b/src/boost/libs/spirit/test/karma/regression_real_scientific.cpp @@ -0,0 +1,40 @@ +// Copyright (c) 2010 Lars Kielhorn +// 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/karma.hpp> + +#include <iostream> +#include <string> +#include <iterator> + +namespace karma = boost::spirit::karma; + +// define a new real number formatting policy +template <typename Num> +struct scientific_policy : karma::real_policies<Num> +{ + // we want the numbers always to be in scientific format + static int floatfield(Num) { return std::ios_base::scientific; } +}; + +int main() +{ + // define a new generator type based on the new policy + typedef karma::real_generator<double, scientific_policy<double> > + science_type; + science_type const scientific = science_type(); + + std::string output; + typedef std::back_insert_iterator<std::string> output_iterator; + output_iterator sink(output); + + // should output: 1.0e-01, but will output: 10.0e-02 + BOOST_TEST(karma::generate(sink, scientific, 0.1) && output == "1.0e-01"); + + return boost::report_errors(); +} diff --git a/src/boost/libs/spirit/test/karma/regression_semantic_action_attribute.cpp b/src/boost/libs/spirit/test/karma/regression_semantic_action_attribute.cpp new file mode 100644 index 00000000..01265d9f --- /dev/null +++ b/src/boost/libs/spirit/test/karma/regression_semantic_action_attribute.cpp @@ -0,0 +1,36 @@ +// Copyright (c) 2010 Michael Caisse +// 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 <string> +#include <vector> +#include <boost/spirit/include/karma.hpp> +#include <boost/spirit/include/phoenix_core.hpp> +#include <boost/spirit/include/phoenix_operator.hpp> + +#include "test.hpp" + +using namespace spirit_test; + +namespace karma = boost::spirit::karma; +namespace phx = boost::phoenix; + +int main() +{ + using karma::int_; + using karma::_1; + + BOOST_TEST(test("16909060", int_[ _1 = phx::val(0x01020304) ])); + + // make sure the passed attribute type does not enforce the attribute type + // for the semantic action + unsigned char char_value = 8; + BOOST_TEST(test("16909060", int_[ _1 = phx::val(0x01020304) ], char_value)); + + return boost::report_errors(); +} diff --git a/src/boost/libs/spirit/test/karma/regression_unicode_char.cpp b/src/boost/libs/spirit/test/karma/regression_unicode_char.cpp new file mode 100644 index 00000000..ab76acab --- /dev/null +++ b/src/boost/libs/spirit/test/karma/regression_unicode_char.cpp @@ -0,0 +1,63 @@ +// Copyright (c) 2012 David Bailey +// 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> + +#ifndef BOOST_SPIRIT_UNICODE +#define BOOST_SPIRIT_UNICODE +#endif + +#include <boost/spirit/home/karma/nonterminal/grammar.hpp> +#include <boost/spirit/home/karma/nonterminal/rule.hpp> +#include <boost/spirit/home/karma/char.hpp> + +#include "test.hpp" + +using namespace spirit_test; + +/////////////////////////////////////////////////////////////////////////////// +template <typename OutputIterator> +struct unicode_char_grammar_ + : public boost::spirit::karma::grammar< + OutputIterator, boost::spirit::char_encoding::unicode::char_type()> +{ + unicode_char_grammar_() : unicode_char_grammar_::base_type(thechar) + { + using boost::spirit::karma::unicode::char_; + thechar = char_; + } + + boost::spirit::karma::rule< + OutputIterator, boost::spirit::char_encoding::unicode::char_type() + > thechar; +}; + +int +main() +{ + using namespace boost::spirit; + + { + typedef std::basic_string<char_encoding::unicode::char_type> unicode_string; + typedef std::back_insert_iterator<unicode_string> unicode_back_insert_iterator_type; + + using namespace boost::spirit::unicode; + + BOOST_TEST(test("x", char_, 'x')); + BOOST_TEST(test(L"x", char_, L'x')); + + char_encoding::unicode::char_type unicodeCharacter = 0x00000078u; + std::basic_string<char_encoding::unicode::char_type> expected; + expected.push_back(unicodeCharacter); + + unicode_char_grammar_<unicode_back_insert_iterator_type> unichar; + + BOOST_TEST(test(expected, unichar, unicodeCharacter)); + } + + return boost::report_errors(); +} diff --git a/src/boost/libs/spirit/test/karma/repeat1.cpp b/src/boost/libs/spirit/test/karma/repeat1.cpp new file mode 100644 index 00000000..ed0bc5d9 --- /dev/null +++ b/src/boost/libs/spirit/test/karma/repeat1.cpp @@ -0,0 +1,144 @@ +// 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/assign/std/vector.hpp> + +#include <boost/spirit/include/karma_operator.hpp> +#include <boost/spirit/include/karma_char.hpp> +#include <boost/spirit/include/karma_string.hpp> +#include <boost/spirit/include/karma_numeric.hpp> +#include <boost/spirit/include/karma_directive.hpp> +#include <boost/spirit/include/karma_operator.hpp> +#include <boost/spirit/include/karma_action.hpp> +#include <boost/spirit/include/karma_nonterminal.hpp> +#include <boost/spirit/include/karma_auxiliary.hpp> +#include <boost/spirit/include/karma_directive.hpp> +#include <boost/spirit/include/karma_phoenix_attributes.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 <string> +#include <iostream> +#include <vector> + +#include "test.hpp" + +using namespace spirit_test; + +/////////////////////////////////////////////////////////////////////////////// +struct action +{ + action (std::vector<char>& vec) + : vec(vec), it(vec.begin()) + {} + + void operator()(unsigned& value, boost::spirit::unused_type, bool& pass) const + { + pass = (it != vec.end()); + if (pass) + value = *it++; + } + + std::vector<char>& vec; + mutable std::vector<char>::iterator it; +}; + +/////////////////////////////////////////////////////////////////////////////// +int main() +{ + using namespace boost::spirit::ascii; + using boost::spirit::karma::repeat; + using boost::spirit::karma::inf; + using boost::spirit::karma::int_; + using boost::spirit::karma::hex; + using boost::spirit::karma::_1; + + { // lazy repeats + using boost::phoenix::val; + + std::string str8("aaaaaaaa"); + BOOST_TEST(test("aaaaaaaa", repeat[char_], str8)); // kleene synonym + BOOST_TEST(test("aaaaaaaa", repeat(val(8))[char_], str8)); + BOOST_TEST(test("aaa", repeat(val(3))[char_], str8)); + BOOST_TEST(!test("aaaaaaaa", repeat(val(9))[char_], str8)); + + std::string str3("aaa"); + BOOST_TEST(test("aaaaa", repeat(val(3), val(5))[char_], str8)); + BOOST_TEST(test("aaa", repeat(val(3), val(5))[char_], str3)); + BOOST_TEST(!test("aaa", repeat(val(4), val(5))[char_], str3)); + + BOOST_TEST(test("aaa", repeat(val(3), val(inf))[char_], str3)); + BOOST_TEST(test("aaaaaaaa", repeat(val(3), val(inf))[char_], str8)); + BOOST_TEST(!test("aaa", repeat(val(4), val(inf))[char_], str3)); + } + + + { + std::string str8("aaaaaaaa"); + BOOST_TEST(test("aaaaaaaa", repeat[char_], str8)); // kleene synonym + BOOST_TEST(test("aaaaaaaa", repeat(8)[char_], str8)); + BOOST_TEST(test("aaa", repeat(3)[char_], str8)); + BOOST_TEST(!test("aaaaaaaa", repeat(9)[char_], str8)); + + std::string str3("aaa"); + BOOST_TEST(test("aaaaa", repeat(3, 5)[char_], str8)); + BOOST_TEST(test("aaa", repeat(3, 5)[char_], str3)); + BOOST_TEST(!test("aaa", repeat(4, 5)[char_], str3)); + + BOOST_TEST(test("aaa", repeat(3, inf)[char_], str3)); + BOOST_TEST(test("aaaaaaaa", repeat(3, inf)[char_], str8)); + BOOST_TEST(!test("aaa", repeat(4, inf)[char_], str3)); + } + + { + std::string str8("aaaaaaaa"); + BOOST_TEST(test_delimited("a a a a a a a a ", repeat[char_], str8, space)); + BOOST_TEST(test_delimited("a a a a a a a a ", repeat(8)[char_], str8, space)); + BOOST_TEST(test_delimited("a a a ", repeat(3)[char_], str8, space)); + BOOST_TEST(!test_delimited("a a a a a a a a ", repeat(9)[char_], str8, space)); + + std::string str3("aaa"); + BOOST_TEST(test_delimited("a a a a a ", repeat(3, 5)[char_], str8, space)); + BOOST_TEST(test_delimited("a a a ", repeat(3, 5)[char_], str3, space)); + BOOST_TEST(!test_delimited("a a a ", repeat(4, 5)[char_], str3, space)); + + BOOST_TEST(test_delimited("a a a ", repeat(3, inf)[char_], str3, space)); + BOOST_TEST(test_delimited("a a a a a a a a ", repeat(3, inf)[char_], str8, space)); + BOOST_TEST(!test_delimited("a a a ", repeat(4, inf)[char_], str3, space)); + } + + { + // make sure user defined end condition is applied if no attribute + // is passed in + using namespace boost::assign; + + std::vector<char> v; + v += 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'; + BOOST_TEST(test("[6162636465666768]", + '[' << repeat[hex[action(v)]] << ']')); + } + +// we support Phoenix attributes only starting with V2.2 +#if SPIRIT_VERSION >= 0x2020 + { + namespace ascii = boost::spirit::ascii; + namespace phoenix = boost::phoenix; + + char c = 'a'; + BOOST_TEST(test("bcd", repeat(3)[ascii::char_[_1 = ++phoenix::ref(c)]])); + + c = 'a'; + BOOST_TEST(test("bcd", repeat(3)[ascii::char_], ++phoenix::ref(c))); + } +#endif + + return boost::report_errors(); +} + diff --git a/src/boost/libs/spirit/test/karma/repeat2.cpp b/src/boost/libs/spirit/test/karma/repeat2.cpp new file mode 100644 index 00000000..68464f33 --- /dev/null +++ b/src/boost/libs/spirit/test/karma/repeat2.cpp @@ -0,0 +1,152 @@ +// 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/assign/std/vector.hpp> + +#include <boost/spirit/include/karma_operator.hpp> +#include <boost/spirit/include/karma_char.hpp> +#include <boost/spirit/include/karma_string.hpp> +#include <boost/spirit/include/karma_numeric.hpp> +#include <boost/spirit/include/karma_directive.hpp> +#include <boost/spirit/include/karma_operator.hpp> +#include <boost/spirit/include/karma_action.hpp> +#include <boost/spirit/include/karma_nonterminal.hpp> +#include <boost/spirit/include/karma_auxiliary.hpp> +#include <boost/spirit/include/karma_directive.hpp> +#include <boost/spirit/include/karma_phoenix_attributes.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 <string> +#include <iostream> +#include <vector> + +#include "test.hpp" + +using namespace spirit_test; + +/////////////////////////////////////////////////////////////////////////////// +int main() +{ + using namespace boost::spirit::ascii; + using boost::spirit::karma::repeat; + using boost::spirit::karma::inf; + using boost::spirit::karma::int_; + using boost::spirit::karma::hex; + using boost::spirit::karma::_1; + + { + std::string str("aBcdeFGH"); + BOOST_TEST(test("abcdefgh", lower[repeat(8)[char_]], str)); + BOOST_TEST(test_delimited("A B C D E F G H ", upper[repeat(8)[char_]], str, space)); + } + + { + std::string s1 = "aaaaa"; + BOOST_TEST(test("aaaaa", char_ << repeat(2)[char_ << char_], s1)); + s1 = "aaa"; + BOOST_TEST(test("aaa", char_ << repeat(1, 2)[char_ << char_], s1)); + s1 = "aa"; + BOOST_TEST(!test("", char_ << repeat(1)[char_ << char_], s1)); + } + + { // actions + namespace phx = boost::phoenix; + + std::vector<char> v; + v.push_back('a'); + v.push_back('a'); + v.push_back('a'); + v.push_back('a'); + BOOST_TEST(test("aaaa", repeat(4)[char_][_1 = phx::ref(v)])); + } + + { // more actions + namespace phx = boost::phoenix; + + std::vector<int> v; + v.push_back(123); + v.push_back(456); + v.push_back(789); + BOOST_TEST(test_delimited("123 456 789 ", repeat(3)[int_][_1 = phx::ref(v)], space)); + } + + // failing sub-generators + { + using boost::spirit::karma::strict; + using boost::spirit::karma::relaxed; + + using namespace boost::assign; + namespace karma = boost::spirit::karma; + + typedef std::pair<char, char> data; + std::vector<data> v2, v3; + v2 += std::make_pair('a', 'a'), + std::make_pair('b', 'b'), + std::make_pair('c', 'c'), + std::make_pair('d', 'd'), + std::make_pair('e', 'e'), + std::make_pair('f', 'f'), + std::make_pair('g', 'g'); + v3 += std::make_pair('a', 'a'), + std::make_pair('b', 'b'), + std::make_pair('c', 'c'), + std::make_pair('d', 'd'); + + karma::rule<spirit_test::output_iterator<char>::type, data()> r; + + r = &char_('d') << char_; + BOOST_TEST(test("d", repeat[r], v2)); + BOOST_TEST(test("d", relaxed[repeat[r]], v2)); + BOOST_TEST(test("", strict[repeat[r]], v2)); + + r = !char_('d') << char_; + BOOST_TEST(test("abcefg", repeat(6)[r], v2)); + BOOST_TEST(!test("", repeat(5)[r], v2)); + BOOST_TEST(test("abcefg", relaxed[repeat(6)[r]], v2)); + BOOST_TEST(!test("", relaxed[repeat(5)[r]], v2)); + BOOST_TEST(!test("", strict[repeat(6)[r]], v2)); + BOOST_TEST(!test("", strict[repeat(5)[r]], v2)); + + r = !char_('c') << char_; + BOOST_TEST(test("abd", repeat(3)[r], v2)); + BOOST_TEST(test("abd", relaxed[repeat(3)[r]], v2)); + BOOST_TEST(!test("", strict[repeat(3)[r]], v2)); + + r = !char_('a') << char_; + BOOST_TEST(test("bcdef", repeat(3, 5)[r], v2)); + BOOST_TEST(test("bcd", repeat(3, 5)[r], v3)); + BOOST_TEST(!test("", repeat(4, 5)[r], v3)); + BOOST_TEST(test("bcdef", relaxed[repeat(3, 5)[r]], v2)); + BOOST_TEST(test("bcd", relaxed[repeat(3, 5)[r]], v3)); + BOOST_TEST(!test("", relaxed[repeat(4, 5)[r]], v3)); + BOOST_TEST(!test("", strict[repeat(3, 5)[r]], v2)); + BOOST_TEST(!test("", strict[repeat(3, 5)[r]], v3)); + BOOST_TEST(!test("", strict[repeat(4, 5)[r]], v3)); + + BOOST_TEST(test("bcd", repeat(3, inf)[r], v3)); + BOOST_TEST(test("bcdefg", repeat(3, inf)[r], v2)); + BOOST_TEST(!test("", repeat(4, inf)[r], v3)); + + r = !char_('g') << char_; + BOOST_TEST(test("abcde", repeat(3, 5)[r], v2)); + BOOST_TEST(test("abcd", repeat(3, 5)[r], v3)); + BOOST_TEST(!test("", repeat(4, 5)[r], v3)); + BOOST_TEST(test("abcde", relaxed[repeat(3, 5)[r]], v2)); + BOOST_TEST(test("abcd", relaxed[repeat(3, 5)[r]], v3)); + BOOST_TEST(!test("", relaxed[repeat(4, 5)[r]], v3)); + BOOST_TEST(test("abcde", strict[repeat(3, 5)[r]], v2)); + BOOST_TEST(test("abcd", strict[repeat(3, 5)[r]], v3)); + BOOST_TEST(!test("", strict[repeat(5)[r]], v3)); + } + + return boost::report_errors(); +} + diff --git a/src/boost/libs/spirit/test/karma/right_alignment.cpp b/src/boost/libs/spirit/test/karma/right_alignment.cpp new file mode 100644 index 00000000..ba505b66 --- /dev/null +++ b/src/boost/libs/spirit/test/karma/right_alignment.cpp @@ -0,0 +1,74 @@ +// 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/karma_char.hpp> +#include <boost/spirit/include/karma_string.hpp> +#include <boost/spirit/include/karma_numeric.hpp> +#include <boost/spirit/include/karma_generate.hpp> +#include <boost/spirit/include/karma_directive.hpp> +#include <boost/spirit/include/karma_upper_lower_case.hpp> + +#include "test.hpp" + +/////////////////////////////////////////////////////////////////////////////// +int +main() +{ + using namespace spirit_test; + using namespace boost::spirit; + using namespace boost::spirit::ascii; + + { + BOOST_TEST(test(" x", right_align[char_('x')])); + BOOST_TEST(test(" x", right_align[char_], 'x')); + BOOST_TEST(test(" x", right_align['x'])); + + BOOST_TEST(test(" x", right_align(10)[char_('x')])); + BOOST_TEST(test(" x", right_align(10)[char_], 'x')); + BOOST_TEST(test(" x", right_align(10)['x'])); + + BOOST_TEST(test("*********x", right_align(10, char_('*'))[char_('x')])); + BOOST_TEST(test("*********x", right_align(10, '*')[char_], 'x')); + BOOST_TEST(test("*********x", right_align(10, '*')['x'])); + BOOST_TEST(test("aaaaaaaaax", lower[right_align(10, 'A')['X']])); + BOOST_TEST(test("AAAAAAAAAX", upper[right_align(10, 'a')['x']])); + + BOOST_TEST(test("*********x", right_align(char_('*'))[char_('x')])); + BOOST_TEST(test("*********x", right_align(char_('*'))[char_], 'x')); + BOOST_TEST(test("*********x", right_align(char_('*'))['x'])); + + BOOST_TEST(test(" abc", right_align[lit("abc")])); + BOOST_TEST(test(" abc", right_align[string], "abc")); + + BOOST_TEST(test(" abc", right_align(10)[lit("abc")])); + BOOST_TEST(test(" abc", right_align(10)[string], "abc")); + BOOST_TEST(test(" abc", right_align(10)["abc"])); + + BOOST_TEST(test("*******abc", right_align(10, char_('*'))[lit("abc")])); + BOOST_TEST(test("*******abc", right_align(10, '*')[string], "abc")); + BOOST_TEST(test("*******abc", right_align(10, '*')["abc"])); + + BOOST_TEST(test("*******abc", right_align(char_('*'))[lit("abc")])); + BOOST_TEST(test("*******abc", right_align(char_('*'))[string], "abc")); + BOOST_TEST(test("*******abc", right_align(char_('*'))["abc"])); + + BOOST_TEST(test(" 100", right_align[int_(100)])); + BOOST_TEST(test(" 100", right_align[int_], 100)); + + BOOST_TEST(test(" 100", right_align(10)[int_(100)])); + BOOST_TEST(test(" 100", right_align(10)[int_], 100)); + + BOOST_TEST(test("*******100", right_align(10, char_('*'))[int_(100)])); + BOOST_TEST(test("*******100", right_align(10, '*')[int_], 100)); + + BOOST_TEST(test("*******100", right_align(char_('*'))[int_(100)])); + BOOST_TEST(test("*******100", right_align(char_('*'))[int_], 100)); + } + + return boost::report_errors(); +} diff --git a/src/boost/libs/spirit/test/karma/rule_fail.cpp b/src/boost/libs/spirit/test/karma/rule_fail.cpp new file mode 100644 index 00000000..36143416 --- /dev/null +++ b/src/boost/libs/spirit/test/karma/rule_fail.cpp @@ -0,0 +1,36 @@ +/*============================================================================= + 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/spirit/include/karma_operator.hpp> +#include <boost/spirit/include/karma_char.hpp> +#include <boost/spirit/include/karma_numeric.hpp> +#include <boost/spirit/include/karma_nonterminal.hpp> +#include <boost/spirit/include/karma_generate.hpp> +#include <boost/function_output_iterator.hpp> + +#include "test.hpp" + +using namespace boost::spirit; +using namespace boost::spirit::ascii; + +// this test must fail compiling as the rule is used with an incompatible +// delimiter type +int main() +{ + typedef spirit_test::output_iterator<char>::type outiter_type; + + std::string generated; + + karma::rule<outiter_type, karma::rule<outiter_type> > def; + def = int_(1) << ',' << int_(0); + + std::back_insert_iterator<std::string> outit(generated); + generate_delimited(outit, def, char_('%') << '\n'); + + return 0; +} diff --git a/src/boost/libs/spirit/test/karma/sequence1.cpp b/src/boost/libs/spirit/test/karma/sequence1.cpp new file mode 100644 index 00000000..e35efe80 --- /dev/null +++ b/src/boost/libs/spirit/test/karma/sequence1.cpp @@ -0,0 +1,140 @@ +// 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/karma_char.hpp> +#include <boost/spirit/include/karma_string.hpp> +#include <boost/spirit/include/karma_numeric.hpp> +#include <boost/spirit/include/karma_generate.hpp> +#include <boost/spirit/include/karma_operator.hpp> +#include <boost/spirit/include/karma_directive.hpp> +#include <boost/spirit/include/karma_action.hpp> +#include <boost/spirit/include/karma_nonterminal.hpp> +#include <boost/spirit/include/karma_auxiliary.hpp> +#include <boost/spirit/include/karma_directive.hpp> +#include <boost/spirit/include/support_unused.hpp> +#include <boost/fusion/include/vector.hpp> + +#include "test.hpp" + +using namespace spirit_test; + +/////////////////////////////////////////////////////////////////////////////// +int main() +{ + using namespace boost::spirit; + using namespace boost::spirit::ascii; + namespace fusion = boost::fusion; + + { + BOOST_TEST(test("xi", char_('x') << char_('i'))); + BOOST_TEST(!test("xi", char_('x') << char_('o'))); + } + + { + BOOST_TEST(test_delimited("x i ", char_('x') << 'i', char(' '))); + BOOST_TEST(!test_delimited("x i ", + char_('x') << char_('o'), char(' '))); + } + + { + BOOST_TEST(test_delimited("Hello , World ", + lit("Hello") << ',' << "World", char(' '))); + } + + { + // a single element + char attr = 'a'; + BOOST_TEST((test("ab", char_ << 'b', attr))); + } + + { + // a single element fusion sequence + fusion::vector<char> attr('a'); + BOOST_TEST((test("ab", char_ << 'b', attr))); + } + + { + fusion::vector<char, char, std::string> p ('a', 'b', "cdefg"); + BOOST_TEST(test("abcdefg", char_ << char_ << string, p)); + BOOST_TEST(test_delimited("a b cdefg ", + char_ << char_ << string, p, char(' '))); + } + + { + fusion::vector<char, int, char> p ('a', 12, 'c'); + BOOST_TEST(test("a12c", char_ << int_ << char_, p)); + BOOST_TEST(test_delimited("a 12 c ", + char_ << int_ << char_, p, char(' '))); + } + + { + // element sequence can be shorter and longer than the attribute + // sequence + using boost::spirit::karma::strict; + using boost::spirit::karma::relaxed; + + fusion::vector<char, int, char> p ('a', 12, 'c'); + BOOST_TEST(test("a12", char_ << int_, p)); + BOOST_TEST(test_delimited("a 12 ", char_ << int_, p, char(' '))); + + BOOST_TEST(test("a12", relaxed[char_ << int_], p)); + BOOST_TEST(test_delimited("a 12 ", relaxed[char_ << int_], p, char(' '))); + + BOOST_TEST(!test("", strict[char_ << int_], p)); + BOOST_TEST(!test_delimited("", strict[char_ << int_], p, char(' '))); + + fusion::vector<char, int> p1 ('a', 12); + BOOST_TEST(test("a12c", char_ << int_ << char_('c'), p1)); + BOOST_TEST(test_delimited("a 12 c ", char_ << int_ << char_('c'), + p1, char(' '))); + + BOOST_TEST(test("a12c", relaxed[char_ << int_ << char_('c')], p1)); + BOOST_TEST(test_delimited("a 12 c ", + relaxed[char_ << int_ << char_('c')], p1, char(' '))); + + BOOST_TEST(!test("", strict[char_ << int_ << char_('c')], p1)); + BOOST_TEST(!test_delimited("", strict[char_ << int_ << char_('c')], + p1, char(' '))); + + BOOST_TEST(test("a12", strict[char_ << int_], p1)); + BOOST_TEST(test_delimited("a 12 ", strict[char_ << int_], p1, char(' '))); + + std::string value("foo ' bar"); + BOOST_TEST(test("\"foo ' bar\"", '"' << strict[*(~char_('*'))] << '"', value)); + BOOST_TEST(test("\"foo ' bar\"", strict['"' << *(~char_('*')) << '"'], value)); + } + + { + // if all elements of a sequence have unused parameters, the whole + // sequence has an unused parameter as well + fusion::vector<char, char> p ('a', 'e'); + BOOST_TEST(test("abcde", + char_ << (lit('b') << 'c' << 'd') << char_, p)); + BOOST_TEST(test_delimited("a b c d e ", + char_ << (lit('b') << 'c' << 'd') << char_, p, char(' '))); + } + + { + // literal generators do not need an attribute + fusion::vector<char, char> p('a', 'c'); + BOOST_TEST(test("abc", char_ << 'b' << char_, p)); + BOOST_TEST(test_delimited("a b c ", + char_ << 'b' << char_, p, char(' '))); + } + + { + // literal generators do not need an attribute, not even at the end + fusion::vector<char, char> p('a', 'c'); + BOOST_TEST(test("acb", char_ << char_ << 'b', p)); + BOOST_TEST(test_delimited("a c b ", + char_ << char_ << 'b', p, char(' '))); + } + + return boost::report_errors(); +} + diff --git a/src/boost/libs/spirit/test/karma/sequence2.cpp b/src/boost/libs/spirit/test/karma/sequence2.cpp new file mode 100644 index 00000000..926d2487 --- /dev/null +++ b/src/boost/libs/spirit/test/karma/sequence2.cpp @@ -0,0 +1,183 @@ +// 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/karma_char.hpp> +#include <boost/spirit/include/karma_string.hpp> +#include <boost/spirit/include/karma_numeric.hpp> +#include <boost/spirit/include/karma_generate.hpp> +#include <boost/spirit/include/karma_operator.hpp> +#include <boost/spirit/include/karma_directive.hpp> +#include <boost/spirit/include/karma_action.hpp> +#include <boost/spirit/include/karma_nonterminal.hpp> +#include <boost/spirit/include/karma_auxiliary.hpp> +#include <boost/spirit/include/karma_directive.hpp> +#include <boost/spirit/include/support_unused.hpp> +#include <boost/spirit/include/phoenix_core.hpp> +#include <boost/spirit/include/phoenix_operator.hpp> +#include <boost/spirit/include/phoenix_function.hpp> +#include <boost/fusion/include/vector.hpp> + +#include "test.hpp" + +using namespace spirit_test; + +/////////////////////////////////////////////////////////////////////////////// +// lazy version of fusion::size +struct seqsize_impl +{ + template <typename Sequence> + struct result + : boost::fusion::result_of::size<Sequence> + {}; + + template <typename This, typename Sequence> + struct result<This(Sequence)> + : result<typename boost::proto::detail::uncvref<Sequence>::type> + {}; + + template <typename Sequence> + typename result<Sequence>::type + operator()(Sequence const& seq) const + { + return boost::fusion::size(seq); + } +}; + +boost::phoenix::function<seqsize_impl> const seqsize = seqsize_impl(); + +/////////////////////////////////////////////////////////////////////////////// +int main() +{ + using namespace boost::spirit; + using namespace boost::spirit::ascii; + namespace fusion = boost::fusion; + + { + std::list<int> v; + v.push_back(1); + v.push_back(2); + v.push_back(3); + BOOST_TEST(test("123", int_ << int_ << int_, v)); + BOOST_TEST(test_delimited("1 2 3 ", int_ << int_ << int_, v, ' ')); + BOOST_TEST(test("1,2,3", int_ << ',' << int_ << ',' << int_, v)); + BOOST_TEST(test_delimited("1 , 2 , 3 ", int_ << ',' << int_ << ',' << int_, v, ' ')); + } + + { + BOOST_TEST(test("aa", lower[char_('A') << 'a'])); + BOOST_TEST(test_delimited("BEGIN END ", + upper[lit("begin") << "end"], char(' '))); + BOOST_TEST(!test_delimited("BEGIN END ", + upper[lit("begin") << "nend"], char(' '))); + + BOOST_TEST(test("Aa ", left_align[char_('A') << 'a'])); + BOOST_TEST(test(" Aa ", center[char_('A') << 'a'])); + BOOST_TEST(test(" Aa", right_align[char_('A') << 'a'])); + } + + { + // make sure single element tuples get passed through if the rhs + // has a single element tuple as its attribute + typedef spirit_test::output_iterator<char>::type iterator_type; + fusion::vector<double, int> fv(2.0, 1); + karma::rule<iterator_type, fusion::vector<double, int>()> r; + r %= double_ << ',' << int_; + BOOST_TEST(test("test:2.0,1", "test:" << r, fv)); + } + + // action tests + { + using namespace boost::phoenix; + + BOOST_TEST(test("abcdefg", + (char_ << char_ << string)[_1 = 'a', _2 = 'b', _3 = "cdefg"])); + BOOST_TEST(test_delimited("a b cdefg ", + (char_ << char_ << string)[_1 = 'a', _2 = 'b', _3 = "cdefg"], + char(' '))); + + BOOST_TEST(test_delimited("a 12 c ", + (char_ << lit(12) << char_)[_1 = 'a', _2 = 'c'], char(' '))); + + char c = 'c'; + BOOST_TEST(test("abc", + (char_[_1 = 'a'] << 'b' << char_)[_1 = 'x', _2 = ref(c)])); + BOOST_TEST(test_delimited("a b c ", + (char_[_1 = 'a'] << 'b' << char_)[_2 = ref(c)], char(' '))); + + BOOST_TEST(test("aa", lower[char_ << 'A'][_1 = 'A'])); + BOOST_TEST(test("AA", upper[char_ << 'a'][_1 = 'a'])); + + BOOST_TEST(test("Aa ", left_align[char_ << 'a'][_1 = 'A'])); + BOOST_TEST(test(" Aa ", center[char_ << 'a'][_1 = 'A'])); + BOOST_TEST(test(" Aa", right_align[char_ << 'a'][_1 = 'A'])); + } + + // test special case where sequence has a one element vector attribute + // sequence and this element is a rule (attribute has to be passed through + // without change) + { + typedef spirit_test::output_iterator<char>::type outiter_type; + namespace karma = boost::spirit::karma; + + karma::rule<outiter_type, std::vector<int>()> r = -(int_ % ','); + std::vector<int> v; + BOOST_TEST(test(">", '>' << r, v)); + + v.push_back(1); + v.push_back(2); + v.push_back(3); + v.push_back(4); + BOOST_TEST(test(">1,2,3,4", '>' << r, v)); + } + + { + namespace karma = boost::spirit::karma; + typedef spirit_test::output_iterator<char>::type outiter_type; + + karma::rule<outiter_type, std::string()> e = karma::string; + karma::rule<outiter_type, std::vector<std::string>()> l = e << *(',' << e); + + std::vector<std::string> v; + v.push_back("abc1"); + v.push_back("abc2"); + v.push_back("abc3"); + BOOST_TEST(test("abc1,abc2,abc3", l, v)); + } + + { + namespace karma = boost::spirit::karma; + namespace phoenix = boost::phoenix; + + typedef spirit_test::output_iterator<char>::type outiter_type; + typedef fusion::vector<char, char, char> vector_type; + + vector_type p ('a', 'b', 'c'); + BOOST_TEST(test("ab", char_ << char_, p)); + + karma::rule<outiter_type, vector_type()> r; + r %= char_ << char_ << &karma::eps[seqsize(_val) == 3]; + BOOST_TEST(!test("", r, p)); + + r %= char_ << char_ << char_ << &karma::eps[seqsize(_val) == 3]; + BOOST_TEST(test("abc", r, p)); + } + + { + std::list<int> v; + v.push_back(1); + v.push_back(2); + v.push_back(3); + v.push_back(4); + + BOOST_TEST(test("1234", repeat(2)[int_] << *int_, v)); + BOOST_TEST(test_delimited("1 2 3 4 ", repeat(2)[int_] << *int_, v, char(' '))); + } + + return boost::report_errors(); +} + diff --git a/src/boost/libs/spirit/test/karma/stream.cpp b/src/boost/libs/spirit/test/karma/stream.cpp new file mode 100644 index 00000000..36ab6e6c --- /dev/null +++ b/src/boost/libs/spirit/test/karma/stream.cpp @@ -0,0 +1,134 @@ +// 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 <cwchar> +#include <streambuf> +#include <iostream> + +#include <boost/config/warning_disable.hpp> +#include <boost/detail/lightweight_test.hpp> +#include <boost/cstdint.hpp> + +#include <boost/spirit/include/karma_char.hpp> +#include <boost/spirit/include/karma_string.hpp> +#include <boost/spirit/include/karma_stream.hpp> +#include <boost/spirit/include/karma_directive.hpp> +#include <boost/spirit/include/phoenix_core.hpp> +#include <boost/spirit/include/phoenix_operator.hpp> + +#include "test.hpp" + +using namespace spirit_test; + +// a simple complex number representation z = a + bi +struct complex +{ + complex (double a, double b) + : a(a), b(b) + {} + + double a; + double b; + + template <typename Char> + friend std::basic_ostream<Char>& + operator<< (std::basic_ostream<Char>& os, complex z) + { + os << "{" << z.a << "," << z.b << "}"; + return os; + } +}; + +/////////////////////////////////////////////////////////////////////////////// +int +main() +{ + using namespace boost::spirit; + + { + BOOST_TEST(test("x", stream, 'x')); + BOOST_TEST(test("xyz", stream, "xyz")); + BOOST_TEST(test("xyz", stream, std::string("xyz"))); + BOOST_TEST(test("1", stream, 1)); + BOOST_TEST(test("1.1", stream, 1.1)); + BOOST_TEST(test("{1.2,2.4}", stream, complex(1.2, 2.4))); + } + + { + BOOST_TEST(test("x", stream('x'))); + BOOST_TEST(test("xyz", stream("xyz"))); + BOOST_TEST(test("xyz", stream(std::string("xyz")))); + BOOST_TEST(test("1", stream(1))); + BOOST_TEST(test("1.1", stream(1.1))); + BOOST_TEST(test("{1.2,2.4}", stream(complex(1.2, 2.4)))); + } + + { + using namespace boost::spirit::ascii; + + BOOST_TEST(test("x", lower[stream], 'X')); + BOOST_TEST(test("xyz", lower[stream], "XYZ")); + BOOST_TEST(test("xyz", lower[stream], std::string("XYZ"))); + BOOST_TEST(test("X", upper[stream], 'x')); + BOOST_TEST(test("XYZ", upper[stream], "xyz")); + BOOST_TEST(test("XYZ", upper[stream], std::string("xyz"))); + } + + { + BOOST_TEST(test_delimited("x ", stream, 'x', ' ')); + BOOST_TEST(test_delimited("xyz ", stream, "xyz", ' ')); + BOOST_TEST(test_delimited("xyz ", stream, std::string("xyz"), ' ')); + BOOST_TEST(test_delimited("1 ", stream, 1, ' ')); + BOOST_TEST(test_delimited("1.1 ", stream, 1.1, ' ')); + BOOST_TEST(test_delimited("{1.2,2.4} ", stream, complex(1.2, 2.4), ' ')); + } + + { + typedef karma::stream_generator<utf8_char> utf8_stream_type; + utf8_stream_type const utf8_stream = utf8_stream_type(); + + BOOST_TEST(test_delimited("x ", utf8_stream, 'x', ' ')); + BOOST_TEST(test_delimited("xyz ", utf8_stream, "xyz", ' ')); + BOOST_TEST(test_delimited("xyz ", utf8_stream, std::string("xyz"), ' ')); + BOOST_TEST(test_delimited("1 ", utf8_stream, 1, ' ')); + BOOST_TEST(test_delimited("1.1 ", utf8_stream, 1.1, ' ')); + BOOST_TEST(test_delimited("{1.2,2.4} ", utf8_stream, complex(1.2, 2.4), ' ')); + + BOOST_TEST(test("x", utf8_stream('x'))); + BOOST_TEST(test("xyz", utf8_stream("xyz"))); + BOOST_TEST(test("xyz", utf8_stream(std::string("xyz")))); + BOOST_TEST(test("1", utf8_stream(1))); + BOOST_TEST(test("1.1", utf8_stream(1.1))); + BOOST_TEST(test("{1.2,2.4}", utf8_stream(complex(1.2, 2.4)))); + } + + { + using namespace boost::spirit::ascii; + + BOOST_TEST(test_delimited("x ", lower[stream], 'X', ' ')); + BOOST_TEST(test_delimited("xyz ", lower[stream], "XYZ", ' ')); + BOOST_TEST(test_delimited("xyz ", lower[stream], std::string("XYZ"), ' ')); + BOOST_TEST(test_delimited("X ", upper[stream], 'x', ' ')); + BOOST_TEST(test_delimited("XYZ ", upper[stream], "xyz", ' ')); + BOOST_TEST(test_delimited("XYZ ", upper[stream], std::string("xyz"), ' ')); + } + + { // lazy streams + namespace phx = boost::phoenix; + + std::basic_string<char> s("abc"); + BOOST_TEST((test("abc", stream(phx::val(s))))); + BOOST_TEST((test("abc", stream(phx::ref(s))))); + } + + { + boost::optional<char> c; + BOOST_TEST(!test("", stream, c)); + c = 'x'; + BOOST_TEST(test("x", stream, c)); + } + + return boost::report_errors(); +} diff --git a/src/boost/libs/spirit/test/karma/symbols1.cpp b/src/boost/libs/spirit/test/karma/symbols1.cpp new file mode 100644 index 00000000..0fcea278 --- /dev/null +++ b/src/boost/libs/spirit/test/karma/symbols1.cpp @@ -0,0 +1,106 @@ +// 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/spirit/include/karma_auxiliary.hpp> +#include <boost/spirit/include/karma_char.hpp> +#include <boost/spirit/include/karma_string.hpp> +#include <boost/spirit/include/karma_operator.hpp> +#include <boost/spirit/include/karma_directive.hpp> +#include <boost/spirit/include/karma_generate.hpp> +#include <boost/spirit/include/karma_nonterminal.hpp> + +#include <boost/core/lightweight_test.hpp> +#include <boost/core/lightweight_test_trait.hpp> + +#include "test.hpp" + +namespace fusion = boost::fusion; + +template <typename T> +inline std::vector<T> +make_vector(T const& t1, T const& t2) +{ + std::vector<T> v; + v.push_back(t1); + v.push_back(t2); + return v; +} + +int main() +{ + using spirit_test::test; + using boost::spirit::karma::symbols; + + { // basics + symbols<char, std::string> sym; + + sym.add + ('j', "Joel") + ('h', "Hartmut") + ('t', "Tom") + ('k', "Kim") + ; + + BOOST_TEST_TRAIT_TRUE(( + boost::spirit::traits::is_generator< + symbols<char, std::string> >)); + + BOOST_TEST((test("Joel", sym, 'j'))); + BOOST_TEST((test("Hartmut", sym, 'h'))); + BOOST_TEST((test("Tom", sym, 't'))); + BOOST_TEST((test("Kim", sym, 'k'))); + BOOST_TEST((!test("", sym, 'x'))); + + // test copy + symbols<char, std::string> sym2; + sym2 = sym; + BOOST_TEST((test("Joel", sym2, 'j'))); + BOOST_TEST((test("Hartmut", sym2, 'h'))); + BOOST_TEST((test("Tom", sym2, 't'))); + BOOST_TEST((test("Kim", sym2, 'k'))); + BOOST_TEST((!test("", sym2, 'x'))); + + // make sure it plays well with other generators + BOOST_TEST((test("Joelyo", sym << "yo", 'j'))); + + sym.remove + ('j') + ('h') + ; + + BOOST_TEST((!test("", sym, 'j'))); + BOOST_TEST((!test("", sym, 'h'))); + } + + { // lower/upper handling + using namespace boost::spirit::ascii; + using boost::spirit::karma::lower; + using boost::spirit::karma::upper; + + symbols<char, std::string> sym; + sym.add + ('j', "Joel") + ('h', "Hartmut") + ('t', "Tom") + ('k', "Kim") + ; + + BOOST_TEST((test("joel", lower[sym], 'j'))); + BOOST_TEST((test("hartmut", lower[sym], 'h'))); + BOOST_TEST((test("tom", lower[sym], 't'))); + BOOST_TEST((test("kim", lower[sym], 'k'))); + + BOOST_TEST((test("JOEL", upper[sym], 'j'))); + BOOST_TEST((test("HARTMUT", upper[sym], 'h'))); + BOOST_TEST((test("TOM", upper[sym], 't'))); + BOOST_TEST((test("KIM", upper[sym], 'k'))); + + // make sure it plays well with other generators + BOOST_TEST((test("joelyo", lower[sym] << "yo", 'j'))); + BOOST_TEST((test("JOELyo", upper[sym] << "yo", 'j'))); + } + + return boost::report_errors(); +} diff --git a/src/boost/libs/spirit/test/karma/symbols2.cpp b/src/boost/libs/spirit/test/karma/symbols2.cpp new file mode 100644 index 00000000..e2fdcd53 --- /dev/null +++ b/src/boost/libs/spirit/test/karma/symbols2.cpp @@ -0,0 +1,146 @@ +// 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/spirit/include/karma_auxiliary.hpp> +#include <boost/spirit/include/karma_char.hpp> +#include <boost/spirit/include/karma_string.hpp> +#include <boost/spirit/include/karma_operator.hpp> +#include <boost/spirit/include/karma_directive.hpp> +#include <boost/spirit/include/karma_generate.hpp> +#include <boost/spirit/include/karma_nonterminal.hpp> + +#include <boost/core/lightweight_test.hpp> +#include <boost/core/lightweight_test_trait.hpp> + +#include "test.hpp" + +namespace fusion = boost::fusion; + +template <typename T> +inline std::vector<T> +make_vector(T const& t1, T const& t2) +{ + std::vector<T> v; + v.push_back(t1); + v.push_back(t2); + return v; +} + +int main() +{ + using spirit_test::test; + using boost::spirit::karma::symbols; + + { // advanced + using boost::spirit::karma::rule; + using boost::spirit::karma::lit; + + typedef spirit_test::output_iterator<char>::type output_iterator_type; + + symbols<char, rule<output_iterator_type> > sym; + + rule<output_iterator_type> r1 = lit("Joel"); + rule<output_iterator_type> r2 = lit("Hartmut"); + rule<output_iterator_type> r3 = lit("Tom"); + rule<output_iterator_type> r4 = lit("Kim"); + + sym.add + ('j', r1.alias()) + ('h', r2.alias()) + ('t', r3.alias()) + ('k', r4.alias()) + ; + + BOOST_TEST_TRAIT_TRUE(( + boost::spirit::traits::is_generator< + symbols<char, rule<output_iterator_type> > >)); + + BOOST_TEST((test("Joel", sym, 'j'))); + BOOST_TEST((test("Hartmut", sym, 'h'))); + BOOST_TEST((test("Tom", sym, 't'))); + BOOST_TEST((test("Kim", sym, 'k'))); + BOOST_TEST((!test("", sym, 'x'))); + + // test copy + symbols<char, rule<output_iterator_type> > sym2; + sym2 = sym; + BOOST_TEST((test("Joel", sym2, 'j'))); + BOOST_TEST((test("Hartmut", sym2, 'h'))); + BOOST_TEST((test("Tom", sym2, 't'))); + BOOST_TEST((test("Kim", sym2, 'k'))); + BOOST_TEST((!test("", sym2, 'x'))); + + // make sure it plays well with other generators + BOOST_TEST((test("Joelyo", sym << "yo", 'j'))); + + sym.remove + ('j') + ('h') + ; + + BOOST_TEST((!test("", sym, 'j'))); + BOOST_TEST((!test("", sym, 'h'))); + } + + { // more advanced + using boost::spirit::karma::rule; + using boost::spirit::karma::lit; + using boost::spirit::karma::string; + + typedef spirit_test::output_iterator<char>::type output_iterator_type; + + symbols<char, rule<output_iterator_type, std::string()> > sym; + rule<output_iterator_type, std::string()> r1 = string; + + sym.add + ('j', r1.alias()) + ('h', r1.alias()) + ('t', r1.alias()) + ('k', r1.alias()) + ; + + BOOST_TEST_TRAIT_TRUE(( + boost::spirit::traits::is_generator< + symbols<char, std::string> >)); + + BOOST_TEST((test("Joel", sym, fusion::make_vector('j', "Joel")))); + BOOST_TEST((test("Hartmut", sym, fusion::make_vector('h', "Hartmut")))); + BOOST_TEST((test("Tom", sym, fusion::make_vector('t', "Tom")))); + BOOST_TEST((test("Kim", sym, fusion::make_vector('k', "Kim")))); + BOOST_TEST((!test("", sym, 'x'))); + + // test copy + symbols<char, rule<output_iterator_type, std::string()> > sym2; + sym2 = sym; + BOOST_TEST((test("Joel", sym2, fusion::make_vector('j', "Joel")))); + BOOST_TEST((test("Hartmut", sym2, fusion::make_vector('h', "Hartmut")))); + BOOST_TEST((test("Tom", sym2, fusion::make_vector('t', "Tom")))); + BOOST_TEST((test("Kim", sym2, fusion::make_vector('k', "Kim")))); + BOOST_TEST((!test("", sym2, 'x'))); + + // make sure it plays well with other generators + BOOST_TEST((test("Joelyo", sym << "yo", fusion::make_vector('j', "Joel")))); + + sym.remove + ('j') + ('h') + ; + + BOOST_TEST((!test("", sym, 'j'))); + BOOST_TEST((!test("", sym, 'h'))); + } + + { // test for proto problem with rvalue references (10-11-2011) + symbols<char, std::string> sym; + + sym += std::make_pair('j', "Joel"); + sym += std::make_pair('h', "Hartmut"); + + BOOST_TEST((test("Joel", sym, 'j'))); + BOOST_TEST((test("Hartmut", sym, 'h'))); + } + + return boost::report_errors(); +} diff --git a/src/boost/libs/spirit/test/karma/symbols3.cpp b/src/boost/libs/spirit/test/karma/symbols3.cpp new file mode 100644 index 00000000..fd07dbf5 --- /dev/null +++ b/src/boost/libs/spirit/test/karma/symbols3.cpp @@ -0,0 +1,139 @@ +// 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/spirit/include/karma_auxiliary.hpp> +#include <boost/spirit/include/karma_char.hpp> +#include <boost/spirit/include/karma_string.hpp> +#include <boost/spirit/include/karma_operator.hpp> +#include <boost/spirit/include/karma_directive.hpp> +#include <boost/spirit/include/karma_generate.hpp> +#include <boost/spirit/include/karma_nonterminal.hpp> + +#include <boost/core/lightweight_test.hpp> +#include <boost/core/lightweight_test_trait.hpp> + +#include "test.hpp" + +namespace fusion = boost::fusion; + +template <typename T> +inline std::vector<T> +make_vector(T const& t1, T const& t2) +{ + std::vector<T> v; + v.push_back(t1); + v.push_back(t2); + return v; +} + +int main() +{ + using spirit_test::test; + using boost::spirit::karma::symbols; + + { // more advanced + using boost::spirit::karma::rule; + using boost::spirit::karma::lit; + using boost::spirit::karma::char_; + + typedef spirit_test::output_iterator<char>::type output_iterator_type; + + symbols<char, rule<output_iterator_type, char()> > sym; + rule<output_iterator_type, char()> r1 = char_; + + sym.add + ('j', r1.alias()) + ('h', r1.alias()) + ('t', r1.alias()) + ('k', r1.alias()) + ; + + BOOST_TEST_TRAIT_TRUE(( + boost::spirit::traits::is_generator< + symbols<char, rule<output_iterator_type, char()> > >)); + + BOOST_TEST((test("J", sym, make_vector('j', 'J')))); + BOOST_TEST((test("H", sym, make_vector('h', 'H')))); + BOOST_TEST((test("T", sym, make_vector('t', 'T')))); + BOOST_TEST((test("K", sym, make_vector('k', 'K')))); + BOOST_TEST((!test("", sym, 'x'))); + + // test copy + symbols<char, rule<output_iterator_type, char()> > sym2; + sym2 = sym; + BOOST_TEST((test("J", sym2, make_vector('j', 'J')))); + BOOST_TEST((test("H", sym2, make_vector('h', 'H')))); + BOOST_TEST((test("T", sym2, make_vector('t', 'T')))); + BOOST_TEST((test("K", sym2, make_vector('k', 'K')))); + BOOST_TEST((!test("", sym2, 'x'))); + + // make sure it plays well with other generators + BOOST_TEST((test("Jyo", sym << "yo", make_vector('j', 'J')))); + + sym.remove + ('j') + ('h') + ; + + BOOST_TEST((!test("", sym, 'j'))); + BOOST_TEST((!test("", sym, 'h'))); + } + + { // basics + symbols<std::string> sym; + + sym.add + ("Joel") + ("Hartmut") + ("Tom") + ("Kim") + ; + + BOOST_TEST_TRAIT_TRUE(( + boost::spirit::traits::is_generator< + symbols<char, std::string> >)); + + BOOST_TEST((test("Joel", sym, "Joel"))); + BOOST_TEST((test("Hartmut", sym, "Hartmut"))); + BOOST_TEST((test("Tom", sym, "Tom"))); + BOOST_TEST((test("Kim", sym, "Kim"))); + BOOST_TEST((!test("", sym, "X"))); + + // test copy + symbols<std::string> sym2; + sym2 = sym; + BOOST_TEST((test("Joel", sym2, "Joel"))); + BOOST_TEST((test("Hartmut", sym2, "Hartmut"))); + BOOST_TEST((test("Tom", sym2, "Tom"))); + BOOST_TEST((test("Kim", sym2, "Kim"))); + BOOST_TEST((!test("", sym2, "X"))); + + // make sure it plays well with other generators + BOOST_TEST((test("Joelyo", sym << "yo", "Joel"))); + + sym.remove + ("Joel") + ("Hartmut") + ; + + BOOST_TEST((!test("", sym, "Joel"))); + BOOST_TEST((!test("", sym, "Hartmut"))); + } + + { // name + symbols <std::string> sym("test1"), sym2; + BOOST_TEST(sym.name() == "test1"); + + sym.name("test"); + BOOST_TEST(sym.name() == "test"); + sym2 = sym; + BOOST_TEST(sym2.name() == "test"); + + symbols <std::string> sym3(sym); + BOOST_TEST(sym3.name() == "test"); + } + + return boost::report_errors(); +} diff --git a/src/boost/libs/spirit/test/karma/test.hpp b/src/boost/libs/spirit/test/karma/test.hpp new file mode 100644 index 00000000..be6ac500 --- /dev/null +++ b/src/boost/libs/spirit/test/karma/test.hpp @@ -0,0 +1,328 @@ +// Copyright (c) 2001-2011 Hartmut Kaiser +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#if !defined(BOOST_SPIRIT_KARMA_TEST_FEB_23_2007_1221PM) +#define BOOST_SPIRIT_KARMA_TEST_FEB_23_2007_1221PM + +#include <cstring> +#include <string> +#include <iterator> +#include <iostream> +#include <iomanip> +#include <typeinfo> + +#include <boost/foreach.hpp> +#include <boost/spirit/include/karma_generate.hpp> +#include <boost/spirit/include/karma_what.hpp> + +namespace spirit_test +{ + /////////////////////////////////////////////////////////////////////////// + struct display_type + { + template<typename T> + void operator()(T const &) const + { + std::cout << typeid(T).name() << std::endl; + } + + template<typename T> + static void print() + { + std::cout << typeid(T).name() << std::endl; + } + }; + + display_type const display = {}; + + /////////////////////////////////////////////////////////////////////////// + template <typename Char> + struct output_iterator + { + typedef std::basic_string<Char> string_type; + typedef std::back_insert_iterator<string_type> type; + }; + + /////////////////////////////////////////////////////////////////////////// + template <typename Char, typename T> + void print_if_failed(char const* func, bool result + , std::basic_string<Char> const& generated, T const& expected) + { + if (!result) + std::cerr << "in " << func << ": result is false" << std::endl; + else if (generated != expected) + std::cerr << "in " << func << ": generated \"" + << std::string(generated.begin(), generated.end()) + << "\"" << std::endl; + } + + /////////////////////////////////////////////////////////////////////////// + template <typename Char, typename T> + void print_binary_if_failed(char const* func, bool result + , std::basic_string<Char> const& generated, T const& expected) + { + if (!result) + std::cerr << "in " << func << ": result is false" << std::endl; + else if (generated.size() != expected.size() || + std::memcmp(generated.c_str(), expected.c_str(), generated.size())) + { + std::cerr << "in " << func << ": generated \""; + BOOST_FOREACH(int c, generated) + std::cerr << "\\x" << std::hex << std::setfill('0') << std::setw(2) << c; + std::cerr << "\"" << std::endl; + } + } + + /////////////////////////////////////////////////////////////////////////// + template <typename Char, typename Generator> + inline bool test(Char const *expected, Generator const& g) + { + namespace karma = boost::spirit::karma; + typedef std::basic_string<Char> string_type; + + // we don't care about the result of the "what" function. + // we only care that all generators have it: + karma::what(g); + + string_type generated; + std::back_insert_iterator<string_type> outit(generated); + bool result = karma::generate(outit, g); + + print_if_failed("test", result, generated, expected); + return result && generated == expected; + } + + template <typename Char, typename Generator> + inline bool test(std::basic_string<Char> const& expected, Generator const& g) + { + namespace karma = boost::spirit::karma; + typedef std::basic_string<Char> string_type; + + // we don't care about the result of the "what" function. + // we only care that all generators have it: + karma::what(g); + + string_type generated; + std::back_insert_iterator<string_type> outit(generated); + bool result = karma::generate(outit, g); + + print_if_failed("test", result, generated, expected); + return result && generated == expected; + } + + /////////////////////////////////////////////////////////////////////////// + template <typename Char, typename Generator, typename Attribute> + inline bool test(Char const *expected, Generator const& g, + Attribute const &attrib) + { + namespace karma = boost::spirit::karma; + typedef std::basic_string<Char> string_type; + + // we don't care about the result of the "what" function. + // we only care that all generators have it: + karma::what(g); + + string_type generated; + std::back_insert_iterator<string_type> outit(generated); + bool result = karma::generate(outit, g, attrib); + + print_if_failed("test", result, generated, expected); + return result && generated == expected; + } + + template <typename Char, typename Generator, typename Attribute> + inline bool test(std::basic_string<Char> const& expected, Generator const& g, + Attribute const &attrib) + { + namespace karma = boost::spirit::karma; + typedef std::basic_string<Char> string_type; + + // we don't care about the result of the "what" function. + // we only care that all generators have it: + karma::what(g); + + string_type generated; + std::back_insert_iterator<string_type> outit(generated); + bool result = karma::generate(outit, g, attrib); + + print_if_failed("test", result, generated, expected); + return result && generated == expected; + } + + /////////////////////////////////////////////////////////////////////////// + template <typename Char, typename Generator, typename Delimiter> + inline bool test_delimited(Char const *expected, Generator const& g, + Delimiter const& d) + { + namespace karma = boost::spirit::karma; + typedef std::basic_string<Char> string_type; + + // we don't care about the result of the "what" function. + // we only care that all generators have it: + karma::what(g); + + string_type generated; + std::back_insert_iterator<string_type> outit(generated); + bool result = karma::generate_delimited(outit, g, d); + + print_if_failed("test_delimited", result, generated, expected); + return result && generated == expected; + } + + template <typename Char, typename Generator, typename Delimiter> + inline bool test_delimited(std::basic_string<Char> const& expected, + Generator const& g, Delimiter const& d) + { + namespace karma = boost::spirit::karma; + typedef std::basic_string<Char> string_type; + + // we don't care about the result of the "what" function. + // we only care that all generators have it: + karma::what(g); + + string_type generated; + std::back_insert_iterator<string_type> outit(generated); + bool result = karma::generate_delimited(outit, g, d); + + print_if_failed("test_delimited", result, generated, expected); + return result && generated == expected; + } + + /////////////////////////////////////////////////////////////////////////// + template <typename Char, typename Generator, typename Attribute, + typename Delimiter> + inline bool test_delimited(Char const *expected, Generator const& g, + Attribute const &attrib, Delimiter const& d) + { + namespace karma = boost::spirit::karma; + typedef std::basic_string<Char> string_type; + + // we don't care about the result of the "what" function. + // we only care that all generators have it: + karma::what(g); + + string_type generated; + std::back_insert_iterator<string_type> outit(generated); + bool result = karma::generate_delimited(outit, g, d, attrib); + + print_if_failed("test_delimited", result, generated, expected); + return result && generated == expected; + } + + template <typename Char, typename Generator, typename Attribute, + typename Delimiter> + inline bool test_delimited(std::basic_string<Char> const& expected, + Generator const& g, Attribute const &attrib, Delimiter const& d) + { + namespace karma = boost::spirit::karma; + typedef std::basic_string<Char> string_type; + + // we don't care about the result of the "what" function. + // we only care that all generators have it: + karma::what(g); + + string_type generated; + std::back_insert_iterator<string_type> outit(generated); + bool result = karma::generate_delimited(outit, g, d, attrib); + + print_if_failed("test_delimited", result, generated, expected); + return result && generated == expected; + } + + /////////////////////////////////////////////////////////////////////////// + template <typename Generator> + inline bool + binary_test(char const *expected, std::size_t size, + Generator const& g) + { + namespace karma = boost::spirit::karma; + typedef std::basic_string<char> string_type; + + // we don't care about the result of the "what" function. + // we only care that all generators have it: + karma::what(g); + + string_type generated; + std::back_insert_iterator<string_type> outit(generated); + bool result = karma::generate(outit, g); + + print_binary_if_failed("binary_test", result, generated + , std::string(expected, size)); + return result && generated.size() == size + && !std::memcmp(generated.c_str(), expected, size); + } + + /////////////////////////////////////////////////////////////////////////// + template <typename Generator, typename Attribute> + inline bool + binary_test(char const *expected, std::size_t size, + Generator const& g, Attribute const &attrib) + { + namespace karma = boost::spirit::karma; + typedef std::basic_string<char> string_type; + + // we don't care about the result of the "what" function. + // we only care that all generators have it: + karma::what(g); + + string_type generated; + std::back_insert_iterator<string_type> outit(generated); + bool result = karma::generate(outit, g, attrib); + + print_binary_if_failed("binary_test", result, generated + , std::string(expected, size)); + return result && generated.size() == size + && !std::memcmp(generated.c_str(), expected, size); + } + + /////////////////////////////////////////////////////////////////////////// + template <typename Generator, typename Delimiter> + inline bool + binary_test_delimited(char const *expected, std::size_t size, + Generator const& g, Delimiter const& d) + { + namespace karma = boost::spirit::karma; + typedef std::basic_string<char> string_type; + + // we don't care about the result of the "what" function. + // we only care that all generators have it: + karma::what(g); + + string_type generated; + std::back_insert_iterator<string_type> outit(generated); + bool result = karma::generate_delimited(outit, g, d); + + print_binary_if_failed("binary_test_delimited", result, generated + , std::string(expected, size)); + return result && generated.size() == size + && !std::memcmp(generated.c_str(), expected, size); + } + + /////////////////////////////////////////////////////////////////////////// + template <typename Generator, typename Attribute, typename Delimiter> + inline bool + binary_test_delimited(char const *expected, std::size_t size, + Generator const& g, Attribute const &attrib, Delimiter const& d) + { + namespace karma = boost::spirit::karma; + typedef std::basic_string<char> string_type; + + // we don't care about the result of the "what" function. + // we only care that all generators have it: + karma::what(g); + + string_type generated; + std::back_insert_iterator<string_type> outit(generated); + bool result = karma::generate_delimited(outit, g, d, attrib); + + print_binary_if_failed("binary_test_delimited", result, generated + , std::string(expected, size)); + return result && generated.size() == size + && !std::memcmp(generated.c_str(), expected, size); + } + +} // namespace spirit_test + +#endif // !BOOST_SPIRIT_KARMA_TEST_FEB_23_2007_1221PM diff --git a/src/boost/libs/spirit/test/karma/test_attr.hpp b/src/boost/libs/spirit/test/karma/test_attr.hpp new file mode 100644 index 00000000..ad0f0441 --- /dev/null +++ b/src/boost/libs/spirit/test/karma/test_attr.hpp @@ -0,0 +1,137 @@ +// 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_KARMA_TEST_ATTR_APR_23_2009_0605PM) +#define BOOST_SPIRIT_KARMA_TEST_ATTR_APR_23_2009_0605PM + +#include <cstring> +#include <string> +#include <iterator> +#include <iostream> +#include <typeinfo> + +#include <boost/spirit/include/karma_generate.hpp> +#include <boost/spirit/include/karma_what.hpp> + +#include <boost/preprocessor/iterate.hpp> +#include <boost/preprocessor/repetition/enum.hpp> +#include <boost/preprocessor/repetition/enum_params.hpp> +#include <boost/preprocessor/repetition/enum_binary_params.hpp> + +namespace spirit_test +{ + /////////////////////////////////////////////////////////////////////////// + template <typename Char> + struct output_iterator + { + typedef std::basic_string<Char> string_type; + typedef std::back_insert_iterator<string_type> type; + }; + + /////////////////////////////////////////////////////////////////////////// + template <typename Char, typename T> + void print_if_failed(char const* func, bool result + , std::basic_string<Char> const& generated, T const& expected) + { + if (!result) + std::cerr << "in " << func << ": result is false" << std::endl; + else if (generated != expected) + std::cerr << "in " << func << ": generated \"" + << std::string(generated.begin(), generated.end()) + << "\"" << std::endl; + } +} + +#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() + +namespace spirit_test +{ + /////////////////////////////////////////////////////////////////////////// + template <typename Char, typename Generator + , BOOST_PP_ENUM_PARAMS(N, typename A)> + inline bool test(Char const *expected, Generator const& g + , BOOST_PP_ENUM_BINARY_PARAMS(N, A, const& attr)) + { + namespace karma = boost::spirit::karma; + typedef std::basic_string<Char> string_type; + + // we don't care about the result of the "what" function. + // we only care that all generators have it: + karma::what(g); + + string_type generated; + std::back_insert_iterator<string_type> outit(generated); + bool result = karma::generate(outit, g, BOOST_PP_ENUM_PARAMS(N, attr)); + + print_if_failed("test", result, generated, expected); + return result && generated == expected; + } + + /////////////////////////////////////////////////////////////////////////// + template <typename Char, typename Generator, typename Delimiter + , BOOST_PP_ENUM_PARAMS(N, typename A)> + inline bool test_delimited(Char const *expected, Generator const& g + , Delimiter const& d, BOOST_PP_ENUM_BINARY_PARAMS(N, A, const& attr)) + { + namespace karma = boost::spirit::karma; + typedef std::basic_string<Char> string_type; + + // we don't care about the result of the "what" function. + // we only care that all generators have it: + karma::what(g); + + string_type generated; + std::back_insert_iterator<string_type> outit(generated); + bool result = karma::generate_delimited(outit, g, d + , BOOST_PP_ENUM_PARAMS(N, attr)); + + print_if_failed("test_delimited", result, generated, expected); + return result && generated == expected; + } + + /////////////////////////////////////////////////////////////////////////// + template <typename Char, typename Generator, typename Delimiter + , BOOST_PP_ENUM_PARAMS(N, typename A)> + inline bool test_predelimited(Char const *expected, Generator const& g + , Delimiter const& d + , BOOST_SCOPED_ENUM(boost::spirit::karma::delimit_flag) pre_delimit + , BOOST_PP_ENUM_BINARY_PARAMS(N, A, const& attr)) + { + namespace karma = boost::spirit::karma; + typedef std::basic_string<Char> string_type; + + // we don't care about the result of the "what" function. + // we only care that all generators have it: + karma::what(g); + + string_type generated; + std::back_insert_iterator<string_type> outit(generated); + bool result = karma::generate_delimited(outit, g, d + , pre_delimit, BOOST_PP_ENUM_PARAMS(N, attr)); + + print_if_failed("test_predelimited", result, generated, expected); + return result && generated == expected; + } + +} // namespace spirit_test + +#undef N + +#endif diff --git a/src/boost/libs/spirit/test/karma/test_manip_attr.hpp b/src/boost/libs/spirit/test/karma/test_manip_attr.hpp new file mode 100644 index 00000000..4b8e7be0 --- /dev/null +++ b/src/boost/libs/spirit/test/karma/test_manip_attr.hpp @@ -0,0 +1,109 @@ +// 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_KARMA_TEST_MANIP_ATTR_APR_24_2009_0834AM) +#define BOOST_SPIRIT_KARMA_TEST_MANIP_ATTR_APR_24_2009_0834AM + +#include <cstring> +#include <string> +#include <iterator> +#include <iostream> +#include <typeinfo> + +#include <boost/spirit/include/karma_stream.hpp> + +#include <boost/preprocessor/iterate.hpp> +#include <boost/preprocessor/repetition/enum.hpp> +#include <boost/preprocessor/repetition/enum_params.hpp> +#include <boost/preprocessor/repetition/enum_binary_params.hpp> + +namespace spirit_test +{ + /////////////////////////////////////////////////////////////////////////// + template <typename Char, typename T> + void print_if_failed(char const* func, bool result + , std::basic_string<Char> const& generated, T const& expected) + { + if (!result) + std::cerr << "in " << func << ": result is false" << std::endl; + else if (generated != expected) + std::cerr << "in " << func << ": generated \"" + << std::string(generated.begin(), generated.end()) + << "\"" << std::endl; + } +} + +#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() + +namespace spirit_test +{ + /////////////////////////////////////////////////////////////////////////// + template <typename Char, typename Generator + , BOOST_PP_ENUM_PARAMS(N, typename A)> + inline bool test(Char const *expected, Generator const& g + , BOOST_PP_ENUM_BINARY_PARAMS(N, A, const& attr)) + { + namespace karma = boost::spirit::karma; + + std::ostringstream ostrm; + ostrm << karma::format(g, BOOST_PP_ENUM_PARAMS(N, attr)); + + print_if_failed("test", ostrm.good(), ostrm.str(), expected); + return ostrm.good() && ostrm.str() == expected; + } + + /////////////////////////////////////////////////////////////////////////// + template <typename Char, typename Generator, typename Delimiter + , BOOST_PP_ENUM_PARAMS(N, typename A)> + inline bool test_delimited(Char const *expected, Generator const& g + , Delimiter const& d, BOOST_PP_ENUM_BINARY_PARAMS(N, A, const& attr)) + { + namespace karma = boost::spirit::karma; + + std::ostringstream ostrm; + ostrm << karma::format_delimited(g, d, BOOST_PP_ENUM_PARAMS(N, attr)); + + print_if_failed("test_delimited", ostrm.good(), ostrm.str(), expected); + return ostrm.good() && ostrm.str() == expected; + } + + /////////////////////////////////////////////////////////////////////////// + template <typename Char, typename Generator, typename Delimiter + , BOOST_PP_ENUM_PARAMS(N, typename A)> + inline bool test_predelimited(Char const *expected, Generator const& g + , Delimiter const& d + , BOOST_SCOPED_ENUM(boost::spirit::karma::delimit_flag) pre_delimit + , BOOST_PP_ENUM_BINARY_PARAMS(N, A, const& attr)) + { + namespace karma = boost::spirit::karma; + + std::ostringstream ostrm; + ostrm << karma::format_delimited(g, d, pre_delimit + , BOOST_PP_ENUM_PARAMS(N, attr)); + + print_if_failed("test_predelimited", ostrm.good(), ostrm.str(), expected); + return ostrm.good() && ostrm.str() == expected; + } + +} // namespace spirit_test + +#undef N + +#endif diff --git a/src/boost/libs/spirit/test/karma/tricky_alignment.cpp b/src/boost/libs/spirit/test/karma/tricky_alignment.cpp new file mode 100644 index 00000000..f851f9d6 --- /dev/null +++ b/src/boost/libs/spirit/test/karma/tricky_alignment.cpp @@ -0,0 +1,130 @@ +// 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/karma_char.hpp> +#include <boost/spirit/include/karma_string.hpp> +#include <boost/spirit/include/karma_numeric.hpp> +#include <boost/spirit/include/karma_generate.hpp> +#include <boost/spirit/include/karma_directive.hpp> + +#include "test.hpp" + +/////////////////////////////////////////////////////////////////////////////// +int +main() +{ + using namespace spirit_test; + using namespace boost::spirit; + using namespace boost::spirit::ascii; + + { + BOOST_TEST(test("x *****", left_align(15, '*')[left_align[char_('x')]])); + BOOST_TEST(test(" x *****", left_align(15, '*')[center[char_('x')]])); + BOOST_TEST(test(" x*****", left_align(15, '*')[right_align[char_('x')]])); + + BOOST_TEST(test("*****x ", right_align(15, '*')[left_align[char_('x')]])); + BOOST_TEST(test("***** x ", right_align(15, '*')[center[char_('x')]])); + BOOST_TEST(test("***** x", right_align(15, '*')[right_align[char_('x')]])); + + BOOST_TEST(test("***x **", center(15, '*')[left_align[char_('x')]])); + BOOST_TEST(test("*** x **", center(15, '*')[center[char_('x')]])); + BOOST_TEST(test("*** x**", center(15, '*')[right_align[char_('x')]])); + + BOOST_TEST(test("ab *****", left_align(15, '*')[left_align[lit("ab")]])); + BOOST_TEST(test(" ab *****", left_align(15, '*')[center[lit("ab")]])); + BOOST_TEST(test(" ab*****", left_align(15, '*')[right_align[lit("ab")]])); + + BOOST_TEST(test("*****ab ", right_align(15, '*')[left_align[lit("ab")]])); + BOOST_TEST(test("***** ab ", right_align(15, '*')[center[lit("ab")]])); + BOOST_TEST(test("***** ab", right_align(15, '*')[right_align[lit("ab")]])); + + BOOST_TEST(test("***ab **", center(15, '*')[left_align[lit("ab")]])); + BOOST_TEST(test("*** ab **", center(15, '*')[center[lit("ab")]])); + BOOST_TEST(test("*** ab**", center(15, '*')[right_align[lit("ab")]])); + } + + { + BOOST_TEST(test("x ******", left_align(16, '*')[left_align[char_('x')]])); + BOOST_TEST(test(" x ******", left_align(16, '*')[center[char_('x')]])); + BOOST_TEST(test(" x******", left_align(16, '*')[right_align[char_('x')]])); + + BOOST_TEST(test("******x ", right_align(16, '*')[left_align[char_('x')]])); + BOOST_TEST(test("****** x ", right_align(16, '*')[center[char_('x')]])); + BOOST_TEST(test("****** x", right_align(16, '*')[right_align[char_('x')]])); + + BOOST_TEST(test("***x ***", center(16, '*')[left_align[char_('x')]])); + BOOST_TEST(test("*** x ***", center(16, '*')[center[char_('x')]])); + BOOST_TEST(test("*** x***", center(16, '*')[right_align[char_('x')]])); + + BOOST_TEST(test("ab ******", left_align(16, '*')[left_align[lit("ab")]])); + BOOST_TEST(test(" ab ******", left_align(16, '*')[center[lit("ab")]])); + BOOST_TEST(test(" ab******", left_align(16, '*')[right_align[lit("ab")]])); + + BOOST_TEST(test("******ab ", right_align(16, '*')[left_align[lit("ab")]])); + BOOST_TEST(test("****** ab ", right_align(16, '*')[center[lit("ab")]])); + BOOST_TEST(test("****** ab", right_align(16, '*')[right_align[lit("ab")]])); + + BOOST_TEST(test("***ab ***", center(16, '*')[left_align[lit("ab")]])); + BOOST_TEST(test("*** ab ***", center(16, '*')[center[lit("ab")]])); + BOOST_TEST(test("*** ab***", center(16, '*')[right_align[lit("ab")]])); + } + + { + BOOST_TEST(test("x ****", left_align(15, '*')[left_align(11)[char_('x')]])); + BOOST_TEST(test(" x ****", left_align(15, '*')[center(11)[char_('x')]])); + BOOST_TEST(test(" x****", left_align(15, '*')[right_align(11)[char_('x')]])); + + BOOST_TEST(test("****x ", right_align(15, '*')[left_align(11)[char_('x')]])); + BOOST_TEST(test("**** x ", right_align(15, '*')[center(11)[char_('x')]])); + BOOST_TEST(test("**** x", right_align(15, '*')[right_align(11)[char_('x')]])); + + BOOST_TEST(test("**x **", center(15, '*')[left_align(11)[char_('x')]])); + BOOST_TEST(test("** x **", center(15, '*')[center(11)[char_('x')]])); + BOOST_TEST(test("** x**", center(15, '*')[right_align(11)[char_('x')]])); + + BOOST_TEST(test("ab ****", left_align(15, '*')[left_align(11)[lit("ab")]])); + BOOST_TEST(test(" ab ****", left_align(15, '*')[center(11)[lit("ab")]])); + BOOST_TEST(test(" ab****", left_align(15, '*')[right_align(11)[lit("ab")]])); + + BOOST_TEST(test("****ab ", right_align(15, '*')[left_align(11)[lit("ab")]])); + BOOST_TEST(test("**** ab ", right_align(15, '*')[center(11)[lit("ab")]])); + BOOST_TEST(test("**** ab", right_align(15, '*')[right_align(11)[lit("ab")]])); + + BOOST_TEST(test("**ab **", center(15, '*')[left_align(11)[lit("ab")]])); + BOOST_TEST(test("** ab **", center(15, '*')[center(11)[lit("ab")]])); + BOOST_TEST(test("** ab**", center(15, '*')[right_align(11)[lit("ab")]])); + } + + { + BOOST_TEST(test("x *****", left_align(16, '*')[left_align(11)[char_('x')]])); + BOOST_TEST(test(" x *****", left_align(16, '*')[center(11)[char_('x')]])); + BOOST_TEST(test(" x*****", left_align(16, '*')[right_align(11)[char_('x')]])); + + BOOST_TEST(test("*****x ", right_align(16, '*')[left_align(11)[char_('x')]])); + BOOST_TEST(test("***** x ", right_align(16, '*')[center(11)[char_('x')]])); + BOOST_TEST(test("***** x", right_align(16, '*')[right_align(11)[char_('x')]])); + + BOOST_TEST(test("***x **", center(16, '*')[left_align(11)[char_('x')]])); + BOOST_TEST(test("*** x **", center(16, '*')[center(11)[char_('x')]])); + BOOST_TEST(test("*** x**", center(16, '*')[right_align(11)[char_('x')]])); + + BOOST_TEST(test("ab *****", left_align(16, '*')[left_align(11)[lit("ab")]])); + BOOST_TEST(test(" ab *****", left_align(16, '*')[center(11)[lit("ab")]])); + BOOST_TEST(test(" ab*****", left_align(16, '*')[right_align(11)[lit("ab")]])); + + BOOST_TEST(test("*****ab ", right_align(16, '*')[left_align(11)[lit("ab")]])); + BOOST_TEST(test("***** ab ", right_align(16, '*')[center(11)[lit("ab")]])); + BOOST_TEST(test("***** ab", right_align(16, '*')[right_align(11)[lit("ab")]])); + + BOOST_TEST(test("***ab **", center(16, '*')[left_align(11)[lit("ab")]])); + BOOST_TEST(test("*** ab **", center(16, '*')[center(11)[lit("ab")]])); + BOOST_TEST(test("*** ab**", center(16, '*')[right_align(11)[lit("ab")]])); + } + + return boost::report_errors(); +} diff --git a/src/boost/libs/spirit/test/karma/uint_radix.cpp b/src/boost/libs/spirit/test/karma/uint_radix.cpp new file mode 100644 index 00000000..a39838fb --- /dev/null +++ b/src/boost/libs/spirit/test/karma/uint_radix.cpp @@ -0,0 +1,507 @@ +// Copyright (c) 2001-2011 Hartmut Kaiser +// 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/karma_numeric.hpp> + +#include <boost/cstdint.hpp> + +#include "test.hpp" + +/////////////////////////////////////////////////////////////////////////////// +// +// *** BEWARE PLATFORM DEPENDENT!!! *** +// *** The following assumes 32 bit boost::uint32_tegers. +// *** Modify these constants when appropriate. +// +/////////////////////////////////////////////////////////////////////////////// + +char const* max_unsigned_base2 = "11111111111111111111111111111111"; +char const* max_unsigned_base3 = "102002022201221111210"; +char const* max_unsigned_base4 = "3333333333333333"; +char const* max_unsigned_base5 = "32244002423140"; +char const* max_unsigned_base6 = "1550104015503"; +char const* max_unsigned_base7 = "211301422353"; +char const* max_unsigned_base8 = "37777777777"; +char const* max_unsigned_base9 = "12068657453"; +char const* max_unsigned_base11 = "1904440553"; +char const* max_unsigned_base12 = "9ba461593"; +char const* max_unsigned_base13 = "535a79888"; +char const* max_unsigned_base14 = "2ca5b7463"; +char const* max_unsigned_base15 = "1a20dcd80"; +char const* max_unsigned_base16 = "ffffffff"; +char const* max_unsigned_base17 = "a7ffda90"; +char const* max_unsigned_base18 = "704he7g3"; +char const* max_unsigned_base19 = "4f5aff65"; +char const* max_unsigned_base20 = "3723ai4f"; +char const* max_unsigned_base21 = "281d55i3"; +char const* max_unsigned_base22 = "1fj8b183"; +char const* max_unsigned_base23 = "1606k7ib"; +char const* max_unsigned_base24 = "mb994af"; +char const* max_unsigned_base25 = "hek2mgk"; +char const* max_unsigned_base26 = "dnchbnl"; +char const* max_unsigned_base27 = "b28jpdl"; +char const* max_unsigned_base28 = "8pfgih3"; +char const* max_unsigned_base29 = "76beigf"; +char const* max_unsigned_base30 = "5qmcpqf"; +char const* max_unsigned_base31 = "4q0jto3"; +char const* max_unsigned_base32 = "3vvvvvv"; +char const* max_unsigned_base33 = "3aokq93"; +char const* max_unsigned_base34 = "2qhxjlh"; +char const* max_unsigned_base35 = "2br45qa"; +char const* max_unsigned_base36 = "1z141z3"; + +int +main() +{ + using spirit_test::test; + using boost::spirit::karma::uint_generator; + + /////////////////////////////////////////////////////////////////////////// + // arbitrary radix test (base 2) + /////////////////////////////////////////////////////////////////////////// + { + uint_generator<boost::uint32_t, 2> base2_generator; + + BOOST_TEST(test("1100111100100110010", base2_generator(424242))); + BOOST_TEST(test("1100111100100110010", base2_generator, 424242)); + + BOOST_TEST(test(max_unsigned_base2, base2_generator(0xffffffffu))); + BOOST_TEST(test(max_unsigned_base2, base2_generator, 0xffffffffu)); + } + + /////////////////////////////////////////////////////////////////////////// + // arbitrary radix test (base 3) + /////////////////////////////////////////////////////////////////////////// + { + uint_generator<boost::uint32_t, 3> base3_generator; + + BOOST_TEST(test("210112221200", base3_generator(424242))); + BOOST_TEST(test("210112221200", base3_generator, 424242)); + + BOOST_TEST(test(max_unsigned_base3, base3_generator(0xffffffffu))); + BOOST_TEST(test(max_unsigned_base3, base3_generator, 0xffffffffu)); + } + + /////////////////////////////////////////////////////////////////////////// + // arbitrary radix test (base 4) + /////////////////////////////////////////////////////////////////////////// + { + uint_generator<boost::uint32_t, 4> base4_generator; + + BOOST_TEST(test("1213210302", base4_generator(424242))); + BOOST_TEST(test("1213210302", base4_generator, 424242)); + + BOOST_TEST(test(max_unsigned_base4, base4_generator(0xffffffffu))); + BOOST_TEST(test(max_unsigned_base4, base4_generator, 0xffffffffu)); + } + + /////////////////////////////////////////////////////////////////////////// + // arbitrary radix test (base 5) + /////////////////////////////////////////////////////////////////////////// + { + uint_generator<boost::uint32_t, 5> base5_generator; + + BOOST_TEST(test("102033432", base5_generator(424242))); + BOOST_TEST(test("102033432", base5_generator, 424242)); + + BOOST_TEST(test(max_unsigned_base5, base5_generator(0xffffffffu))); + BOOST_TEST(test(max_unsigned_base5, base5_generator, 0xffffffffu)); + } + + /////////////////////////////////////////////////////////////////////////// + // arbitrary radix test (base 6) + /////////////////////////////////////////////////////////////////////////// + { + uint_generator<boost::uint32_t, 6> base6_generator; + + BOOST_TEST(test("13032030", base6_generator(424242))); + BOOST_TEST(test("13032030", base6_generator, 424242)); + + BOOST_TEST(test(max_unsigned_base6, base6_generator(0xffffffffu))); + BOOST_TEST(test(max_unsigned_base6, base6_generator, 0xffffffffu)); + } + + /////////////////////////////////////////////////////////////////////////// + // arbitrary radix test (base 7) + /////////////////////////////////////////////////////////////////////////// + { + uint_generator<boost::uint32_t, 7> base7_generator; + + BOOST_TEST(test("3414600", base7_generator(424242))); + BOOST_TEST(test("3414600", base7_generator, 424242)); + + BOOST_TEST(test(max_unsigned_base7, base7_generator(0xffffffffu))); + BOOST_TEST(test(max_unsigned_base7, base7_generator, 0xffffffffu)); + } + + /////////////////////////////////////////////////////////////////////////// + // arbitrary radix test (base 8) + /////////////////////////////////////////////////////////////////////////// + { + uint_generator<boost::uint32_t, 8> base8_generator; + + BOOST_TEST(test("1474462", base8_generator(424242))); + BOOST_TEST(test("1474462", base8_generator, 424242)); + + BOOST_TEST(test(max_unsigned_base8, base8_generator(0xffffffffu))); + BOOST_TEST(test(max_unsigned_base8, base8_generator, 0xffffffffu)); + } + + /////////////////////////////////////////////////////////////////////////// + // arbitrary radix test (base 9) + /////////////////////////////////////////////////////////////////////////// + { + uint_generator<boost::uint32_t, 9> base9_generator; + + BOOST_TEST(test("715850", base9_generator(424242))); + BOOST_TEST(test("715850", base9_generator, 424242)); + + BOOST_TEST(test(max_unsigned_base9, base9_generator(0xffffffffu))); + BOOST_TEST(test(max_unsigned_base9, base9_generator, 0xffffffffu)); + } + + /////////////////////////////////////////////////////////////////////////// + // arbitrary radix test (base 11) + /////////////////////////////////////////////////////////////////////////// + { + uint_generator<boost::uint32_t, 11> base11_generator; + + BOOST_TEST(test("26a815", base11_generator(424242))); + BOOST_TEST(test("26a815", base11_generator, 424242)); + + BOOST_TEST(test(max_unsigned_base11, base11_generator(0xffffffffu))); + BOOST_TEST(test(max_unsigned_base11, base11_generator, 0xffffffffu)); + } + + /////////////////////////////////////////////////////////////////////////// + // arbitrary radix test (base 12) + /////////////////////////////////////////////////////////////////////////// + { + uint_generator<boost::uint32_t, 12> base12_generator; + + BOOST_TEST(test("185616", base12_generator(424242))); + BOOST_TEST(test("185616", base12_generator, 424242)); + + BOOST_TEST(test(max_unsigned_base12, base12_generator(0xffffffffu))); + BOOST_TEST(test(max_unsigned_base12, base12_generator, 0xffffffffu)); + } + + /////////////////////////////////////////////////////////////////////////// + // arbitrary radix test (base 13) + /////////////////////////////////////////////////////////////////////////// + { + uint_generator<boost::uint32_t, 13> base13_generator; + + BOOST_TEST(test("11b140", base13_generator(424242))); + BOOST_TEST(test("11b140", base13_generator, 424242)); + + BOOST_TEST(test(max_unsigned_base13, base13_generator(0xffffffffu))); + BOOST_TEST(test(max_unsigned_base13, base13_generator, 0xffffffffu)); + } + + /////////////////////////////////////////////////////////////////////////// + // arbitrary radix test (base 14) + /////////////////////////////////////////////////////////////////////////// + { + uint_generator<boost::uint32_t, 14> base14_generator; + + BOOST_TEST(test("b0870", base14_generator(424242))); + BOOST_TEST(test("b0870", base14_generator, 424242)); + + BOOST_TEST(test(max_unsigned_base14, base14_generator(0xffffffffu))); + BOOST_TEST(test(max_unsigned_base14, base14_generator, 0xffffffffu)); + } + + /////////////////////////////////////////////////////////////////////////// + // arbitrary radix test (base 15) + /////////////////////////////////////////////////////////////////////////// + { + uint_generator<boost::uint32_t, 15> base15_generator; + + BOOST_TEST(test("85a7c", base15_generator(424242))); + BOOST_TEST(test("85a7c", base15_generator, 424242)); + + BOOST_TEST(test(max_unsigned_base15, base15_generator(0xffffffffu))); + BOOST_TEST(test(max_unsigned_base15, base15_generator, 0xffffffffu)); + } + + /////////////////////////////////////////////////////////////////////////// + // arbitrary radix test (base 16) + /////////////////////////////////////////////////////////////////////////// + { + uint_generator<boost::uint32_t, 16> base16_generator; + + BOOST_TEST(test("67932", base16_generator(424242))); + BOOST_TEST(test("67932", base16_generator, 424242)); + + BOOST_TEST(test(max_unsigned_base16, base16_generator(0xffffffffu))); + BOOST_TEST(test(max_unsigned_base16, base16_generator, 0xffffffffu)); + } + + /////////////////////////////////////////////////////////////////////////// + // arbitrary radix test (base 17) + /////////////////////////////////////////////////////////////////////////// + { + uint_generator<boost::uint32_t, 17> base17_generator; + + BOOST_TEST(test("515g7", base17_generator(424242))); + BOOST_TEST(test("515g7", base17_generator, 424242)); + + BOOST_TEST(test(max_unsigned_base17, base17_generator(0xffffffffu))); + BOOST_TEST(test(max_unsigned_base17, base17_generator, 0xffffffffu)); + } + + /////////////////////////////////////////////////////////////////////////// + // arbitrary radix test (base 18) + /////////////////////////////////////////////////////////////////////////// + { + uint_generator<boost::uint32_t, 18> base18_generator; + + BOOST_TEST(test("40d70", base18_generator(424242))); + BOOST_TEST(test("40d70", base18_generator, 424242)); + + BOOST_TEST(test(max_unsigned_base18, base18_generator(0xffffffffu))); + BOOST_TEST(test(max_unsigned_base18, base18_generator, 0xffffffffu)); + } + + /////////////////////////////////////////////////////////////////////////// + // arbitrary radix test (base 19) + /////////////////////////////////////////////////////////////////////////// + { + uint_generator<boost::uint32_t, 19> base19_generator; + + BOOST_TEST(test("34g3a", base19_generator(424242))); + BOOST_TEST(test("34g3a", base19_generator, 424242)); + + BOOST_TEST(test(max_unsigned_base19, base19_generator(0xffffffffu))); + BOOST_TEST(test(max_unsigned_base19, base19_generator, 0xffffffffu)); + } + + /////////////////////////////////////////////////////////////////////////// + // arbitrary radix test (base 20) + /////////////////////////////////////////////////////////////////////////// + { + uint_generator<boost::uint32_t, 20> base20_generator; + + BOOST_TEST(test("2d0c2", base20_generator(424242))); + BOOST_TEST(test("2d0c2", base20_generator, 424242)); + + BOOST_TEST(test(max_unsigned_base20, base20_generator(0xffffffffu))); + BOOST_TEST(test(max_unsigned_base20, base20_generator, 0xffffffffu)); + } + + /////////////////////////////////////////////////////////////////////////// + // arbitrary radix test (base 21) + /////////////////////////////////////////////////////////////////////////// + { + uint_generator<boost::uint32_t, 21> base21_generator; + + BOOST_TEST(test("23h00", base21_generator(424242))); + BOOST_TEST(test("23h00", base21_generator, 424242)); + + BOOST_TEST(test(max_unsigned_base21, base21_generator(0xffffffffu))); + BOOST_TEST(test(max_unsigned_base21, base21_generator, 0xffffffffu)); + } + + /////////////////////////////////////////////////////////////////////////// + // arbitrary radix test (base 22) + /////////////////////////////////////////////////////////////////////////// + { + uint_generator<boost::uint32_t, 22> base22_generator; + + BOOST_TEST(test("1hibg", base22_generator(424242))); + BOOST_TEST(test("1hibg", base22_generator, 424242)); + + BOOST_TEST(test(max_unsigned_base22, base22_generator(0xffffffffu))); + BOOST_TEST(test(max_unsigned_base22, base22_generator, 0xffffffffu)); + } + + /////////////////////////////////////////////////////////////////////////// + // arbitrary radix test (base 23) + /////////////////////////////////////////////////////////////////////////// + { + uint_generator<boost::uint32_t, 23> base23_generator; + + BOOST_TEST(test("1bjm7", base23_generator(424242))); + BOOST_TEST(test("1bjm7", base23_generator, 424242)); + + BOOST_TEST(test(max_unsigned_base23, base23_generator(0xffffffffu))); + BOOST_TEST(test(max_unsigned_base23, base23_generator, 0xffffffffu)); + } + + /////////////////////////////////////////////////////////////////////////// + // arbitrary radix test (base 24) + /////////////////////////////////////////////////////////////////////////// + { + uint_generator<boost::uint32_t, 24> base24_generator; + + BOOST_TEST(test("16gci", base24_generator(424242))); + BOOST_TEST(test("16gci", base24_generator, 424242)); + + BOOST_TEST(test(max_unsigned_base24, base24_generator(0xffffffffu))); + BOOST_TEST(test(max_unsigned_base24, base24_generator, 0xffffffffu)); + } + + /////////////////////////////////////////////////////////////////////////// + // arbitrary radix test (base 25) + /////////////////////////////////////////////////////////////////////////// + { + uint_generator<boost::uint32_t, 25> base25_generator; + + BOOST_TEST(test("123jh", base25_generator(424242))); + BOOST_TEST(test("123jh", base25_generator, 424242)); + + BOOST_TEST(test(max_unsigned_base25, base25_generator(0xffffffffu))); + BOOST_TEST(test(max_unsigned_base25, base25_generator, 0xffffffffu)); + } + + /////////////////////////////////////////////////////////////////////////// + // arbitrary radix test (base 26) + /////////////////////////////////////////////////////////////////////////// + { + uint_generator<boost::uint32_t, 26> base26_generator; + + BOOST_TEST(test("o3f0", base26_generator(424242))); + BOOST_TEST(test("o3f0", base26_generator, 424242)); + + BOOST_TEST(test(max_unsigned_base26, base26_generator(0xffffffffu))); + BOOST_TEST(test(max_unsigned_base26, base26_generator, 0xffffffffu)); + } + + /////////////////////////////////////////////////////////////////////////// + // arbitrary radix test (base 27) + /////////////////////////////////////////////////////////////////////////// + { + uint_generator<boost::uint32_t, 27> base27_generator; + + BOOST_TEST(test("lepi", base27_generator(424242))); + BOOST_TEST(test("lepi", base27_generator, 424242)); + + BOOST_TEST(test(max_unsigned_base27, base27_generator(0xffffffffu))); + BOOST_TEST(test(max_unsigned_base27, base27_generator, 0xffffffffu)); + } + + /////////////////////////////////////////////////////////////////////////// + // arbitrary radix test (base 28) + /////////////////////////////////////////////////////////////////////////// + { + uint_generator<boost::uint32_t, 28> base28_generator; + + BOOST_TEST(test("j93e", base28_generator(424242))); + BOOST_TEST(test("j93e", base28_generator, 424242)); + + BOOST_TEST(test(max_unsigned_base28, base28_generator(0xffffffffu))); + BOOST_TEST(test(max_unsigned_base28, base28_generator, 0xffffffffu)); + } + + /////////////////////////////////////////////////////////////////////////// + // arbitrary radix test (base 29) + /////////////////////////////////////////////////////////////////////////// + { + uint_generator<boost::uint32_t, 29> base29_generator; + + BOOST_TEST(test("hbd1", base29_generator(424242))); + BOOST_TEST(test("hbd1", base29_generator, 424242)); + + BOOST_TEST(test(max_unsigned_base29, base29_generator(0xffffffffu))); + BOOST_TEST(test(max_unsigned_base29, base29_generator, 0xffffffffu)); + } + + /////////////////////////////////////////////////////////////////////////// + // arbitrary radix test (base 30) + /////////////////////////////////////////////////////////////////////////// + { + uint_generator<boost::uint32_t, 30> base30_generator; + + BOOST_TEST(test("flbc", base30_generator(424242))); + BOOST_TEST(test("flbc", base30_generator, 424242)); + + BOOST_TEST(test(max_unsigned_base30, base30_generator(0xffffffffu))); + BOOST_TEST(test(max_unsigned_base30, base30_generator, 0xffffffffu)); + } + + /////////////////////////////////////////////////////////////////////////// + // arbitrary radix test (base 31) + /////////////////////////////////////////////////////////////////////////// + { + uint_generator<boost::uint32_t, 31> base31_generator; + + BOOST_TEST(test("e7e7", base31_generator(424242))); + BOOST_TEST(test("e7e7", base31_generator, 424242)); + + BOOST_TEST(test(max_unsigned_base31, base31_generator(0xffffffffu))); + BOOST_TEST(test(max_unsigned_base31, base31_generator, 0xffffffffu)); + } + + /////////////////////////////////////////////////////////////////////////// + // arbitrary radix test (base 32) + /////////////////////////////////////////////////////////////////////////// + { + uint_generator<boost::uint32_t, 32> base32_generator; + + BOOST_TEST(test("cu9i", base32_generator(424242))); + BOOST_TEST(test("cu9i", base32_generator, 424242)); + + BOOST_TEST(test(max_unsigned_base32, base32_generator(0xffffffffu))); + BOOST_TEST(test(max_unsigned_base32, base32_generator, 0xffffffffu)); + } + + /////////////////////////////////////////////////////////////////////////// + // arbitrary radix test (base 33) + /////////////////////////////////////////////////////////////////////////// + { + uint_generator<boost::uint32_t, 33> base33_generator; + + BOOST_TEST(test("bqir", base33_generator(424242))); + BOOST_TEST(test("bqir", base33_generator, 424242)); + + BOOST_TEST(test(max_unsigned_base33, base33_generator(0xffffffffu))); + BOOST_TEST(test(max_unsigned_base33, base33_generator, 0xffffffffu)); + } + + /////////////////////////////////////////////////////////////////////////// + // arbitrary radix test (base 34) + /////////////////////////////////////////////////////////////////////////// + { + uint_generator<boost::uint32_t, 34> base34_generator; + + BOOST_TEST(test("aqxo", base34_generator(424242))); + BOOST_TEST(test("aqxo", base34_generator, 424242)); + + BOOST_TEST(test(max_unsigned_base34, base34_generator(0xffffffffu))); + BOOST_TEST(test(max_unsigned_base34, base34_generator, 0xffffffffu)); + } + + /////////////////////////////////////////////////////////////////////////// + // arbitrary radix test (base 35) + /////////////////////////////////////////////////////////////////////////// + { + uint_generator<boost::uint32_t, 35> base35_generator; + + BOOST_TEST(test("9vb7", base35_generator(424242))); + BOOST_TEST(test("9vb7", base35_generator, 424242)); + + BOOST_TEST(test(max_unsigned_base35, base35_generator(0xffffffffu))); + BOOST_TEST(test(max_unsigned_base35, base35_generator, 0xffffffffu)); + } + + /////////////////////////////////////////////////////////////////////////// + // arbitrary radix test (base 36) + /////////////////////////////////////////////////////////////////////////// + { + uint_generator<boost::uint32_t, 36> base36_generator; + + BOOST_TEST(test("93ci", base36_generator(424242))); + BOOST_TEST(test("93ci", base36_generator, 424242)); + + BOOST_TEST(test(max_unsigned_base36, base36_generator(0xffffffffu))); + BOOST_TEST(test(max_unsigned_base36, base36_generator, 0xffffffffu)); + } + + return boost::report_errors(); +} diff --git a/src/boost/libs/spirit/test/karma/utree1.cpp b/src/boost/libs/spirit/test/karma/utree1.cpp new file mode 100644 index 00000000..5728b103 --- /dev/null +++ b/src/boost/libs/spirit/test/karma/utree1.cpp @@ -0,0 +1,128 @@ +// 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/karma.hpp> +#include <boost/spirit/include/support_utree.hpp> + +#include <sstream> + +#include "test.hpp" + +int main() +{ + using spirit_test::test; + using spirit_test::test_delimited; + using boost::spirit::utree; + using boost::spirit::utree_type; + using boost::spirit::utf8_string_range_type; + using boost::spirit::utf8_string_type; + using boost::spirit::utf8_symbol_type; + + using boost::spirit::karma::char_; + using boost::spirit::karma::bool_; + using boost::spirit::karma::int_; + using boost::spirit::karma::double_; + using boost::spirit::karma::string; + using boost::spirit::karma::space; + using boost::spirit::karma::rule; + + typedef spirit_test::output_iterator<char>::type output_iterator; + + // primitive data types + { + utree ut('x'); + BOOST_TEST(test("x", char_, ut)); + + ut = false; + BOOST_TEST(test("false", bool_, ut)); + + ut = 123; + BOOST_TEST(test("123", int_, ut)); + + ut = 123.45; + BOOST_TEST(test("123.45", double_, ut)); + + ut = "abc"; + BOOST_TEST(test("abc", string, ut)); + + ut = utf8_symbol_type("xyz"); + BOOST_TEST(test("xyz", string, ut)); + } + + // sequences + { + using boost::spirit::karma::digit; + using boost::spirit::karma::repeat; + + utree ut; + ut.push_back('x'); + ut.push_back('y'); + BOOST_TEST(test("xy", char_ << char_, ut)); + + ut.clear(); + ut.push_back(123); + ut.push_back(456); + BOOST_TEST(test_delimited("123 456 ", int_ << int_, ut, space)); + + ut.clear(); + ut.push_back(1.23); + ut.push_back(4.56); + BOOST_TEST(test_delimited("1.23 4.56 ", double_ << double_, ut, space)); + + ut.clear(); + ut.push_back(1.23); + ut.push_back("ab"); + BOOST_TEST(test("1.23ab", double_ << string, ut)); + + ut.clear(); + + rule<output_iterator, double()> r1 = double_; + rule<output_iterator, utree()> r2 = double_; + + // ( 1.23 "a" "b" ) + ut.push_back(1.23); + ut.push_back('a'); + ut.push_back('b'); + BOOST_TEST(test("1.23ab", double_ << *char_, ut)); + BOOST_TEST(test("1.23ab", r1 << *char_, ut)); + BOOST_TEST(test("1.23ab", r2 << *char_, ut)); + + // ( ( 1.23 ) "a" "b" ) + ut.clear(); + utree ut1; + ut1.push_back(1.23); + ut.push_back(ut1); + ut.push_back('a'); + ut.push_back('b'); + BOOST_TEST(test("1.23ab", r1 << *char_, ut)); + BOOST_TEST(test("1.23ab", r2 << *char_, ut)); + + // ( "a" "b" 1.23 ) + ut.clear(); + ut.push_back('a'); + ut.push_back('b'); + ut.push_back(1.23); + BOOST_TEST(test("ab1.23", repeat(2)[~digit] << double_, ut)); + BOOST_TEST(test("ab1.23", repeat(2)[~digit] << r1, ut)); + BOOST_TEST(test("ab1.23", repeat(2)[~digit] << r2, ut)); + + // ( "a" "b" ( 1.23 ) ) + ut.clear(); + ut.push_back('a'); + ut.push_back('b'); + ut.push_back(ut1); + BOOST_TEST(test("ab1.23", repeat(2)[~digit] << r1, ut)); + BOOST_TEST(test("ab1.23", repeat(2)[~digit] << r2, ut)); + } + + return boost::report_errors(); +} diff --git a/src/boost/libs/spirit/test/karma/utree2.cpp b/src/boost/libs/spirit/test/karma/utree2.cpp new file mode 100644 index 00000000..429ddda1 --- /dev/null +++ b/src/boost/libs/spirit/test/karma/utree2.cpp @@ -0,0 +1,155 @@ +// 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/karma.hpp> +#include <boost/spirit/include/support_utree.hpp> + +#include <sstream> + +#include "test.hpp" + +int main() +{ + using spirit_test::test; + using spirit_test::test_delimited; + using boost::spirit::utree; + using boost::spirit::utree_type; + using boost::spirit::utf8_string_range_type; + using boost::spirit::utf8_string_type; + using boost::spirit::utf8_symbol_type; + + using boost::spirit::karma::char_; + using boost::spirit::karma::bool_; + using boost::spirit::karma::int_; + using boost::spirit::karma::double_; + using boost::spirit::karma::string; + using boost::spirit::karma::space; + using boost::spirit::karma::rule; + + typedef spirit_test::output_iterator<char>::type output_iterator; + + // kleene star + { + utree ut; + ut.push_back('a'); + ut.push_back('b'); + BOOST_TEST(test("ab", *char_, ut)); + + ut.clear(); + ut.push_back(123); + ut.push_back(456); + BOOST_TEST(test_delimited("123 456 ", *int_, ut, space)); + + ut.clear(); + ut.push_back(1.23); + ut.push_back(4.56); + BOOST_TEST(test_delimited("1.23 4.56 ", *double_, ut, space)); + } + + // lists + { + rule<output_iterator, utree()> r1, r1ref; + rule<output_iterator, utf8_string_range_type()> r1str; + rule<output_iterator, utree::const_range()> r1list; + + r1 = double_ | int_ | r1str | r1list | r1ref; + + r1ref = r1.alias(); + + r1str = string; + + r1list = '(' << -(r1 % ',') << ')'; + + // ( "abc" "def" ) + utree ut; + ut.push_back("abc"); + ut.push_back("def"); + BOOST_TEST(test("abc,def", string % ',', ut)); + BOOST_TEST(test("(abc,def)", r1, ut)); + + // ( ( "abc" "def" ) ) + utree ut1; + ut1.push_back(ut); + BOOST_TEST(test("((abc,def))", r1, ut1)); + +// rule<output_iterator, std::vector<char>()> r2 = char_ % ','; +// BOOST_TEST(test("abc,def", r2, ut)); +// BOOST_TEST(test("abc,def", r2, ut1)); + + // ( ( "abc" "def" ) ( "abc" "def" ) ) + ut1.push_back(ut); + BOOST_TEST(test("(abc,def) (abc,def)", r1 << ' ' << r1, ut1)); + + // ( 123 456 ) + ut.clear(); + ut.push_back(123); + ut.push_back(456); + BOOST_TEST(test("123,456", int_ % ',', ut)); + BOOST_TEST(test("(123,456)", r1, ut)); + + // ( ( 123 456 ) ) + ut1.clear(); + ut1.push_back(ut); + BOOST_TEST(test("((123,456))", r1, ut1)); + +// rule<output_iterator, std::vector<int>()> r4 = int_ % ','; +// BOOST_TEST(test("123,456", r4, ut)); +// BOOST_TEST(test("123,456", r4, ut1)); + + // ( ( 123 456 ) ( 123 456 ) ) + ut1.push_back(ut); + BOOST_TEST(test("(123,456) (123,456)", r1 << ' ' << r1, ut1)); + + // ( 1.23 4.56 ) + ut.clear(); + ut.push_back(1.23); + ut.push_back(4.56); + BOOST_TEST(test("1.23,4.56", double_ % ',', ut)); + BOOST_TEST(test("(1.23,4.56)", r1, ut)); + + // ( ( 1.23 4.56 ) ) + ut1.clear(); + ut1.push_back(ut); + BOOST_TEST(test("((1.23,4.56))", r1, ut1)); + +// rule<output_iterator, std::vector<double>()> r6 = double_ % ','; +// BOOST_TEST(test("1.23,4.56", r6, ut)); +// BOOST_TEST(test("1.23,4.56", r6, ut1)); + + // ( ( 1.23 4.56 ) ( 1.23 4.56 ) ) + ut1.push_back(ut); + BOOST_TEST(test("(1.23,4.56) (1.23,4.56)", r1 <<' ' << r1, ut1)); + } + + // alternatives + { + rule<output_iterator, utree()> r1 = int_ | double_; + utree ut(10); + BOOST_TEST(test("10", int_ | double_, ut)); + BOOST_TEST(test("10", r1, ut)); + + ut = 10.2; + BOOST_TEST(test("10.2", int_ | double_, ut)); + BOOST_TEST(test("10.2", r1, ut)); + } + + // optionals + { + utree ut('x'); + BOOST_TEST(test("x", -char_, ut)); + + ut.clear(); + BOOST_TEST(test("", -char_, ut)); + } + + return boost::report_errors(); +} diff --git a/src/boost/libs/spirit/test/karma/utree3.cpp b/src/boost/libs/spirit/test/karma/utree3.cpp new file mode 100644 index 00000000..96f84e31 --- /dev/null +++ b/src/boost/libs/spirit/test/karma/utree3.cpp @@ -0,0 +1,134 @@ +// 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/karma.hpp> +#include <boost/spirit/include/support_utree.hpp> + +#include <sstream> + +#include "test.hpp" + +int main() +{ + using spirit_test::test; + using spirit_test::test_delimited; + using boost::spirit::utree; + using boost::spirit::utree_type; + using boost::spirit::utf8_string_range_type; + using boost::spirit::utf8_string_type; + using boost::spirit::utf8_symbol_type; + + using boost::spirit::karma::char_; + using boost::spirit::karma::bool_; + using boost::spirit::karma::int_; + using boost::spirit::karma::double_; + using boost::spirit::karma::string; + using boost::spirit::karma::space; + using boost::spirit::karma::rule; + + typedef spirit_test::output_iterator<char>::type output_iterator; + + // as_string + { + using boost::spirit::karma::digit; + using boost::spirit::karma::as_string; + + utree ut("xy"); + BOOST_TEST(test("xy", string, ut)); + BOOST_TEST(test("xy", as_string[*char_], ut)); + BOOST_TEST(test("x,y", as_string[char_ << ',' << char_], ut)); + + ut.clear(); + ut.push_back("ab"); + ut.push_back(1.2); + BOOST_TEST(test("ab1.2", as_string[*~digit] << double_, ut)); + BOOST_TEST(test("a,b1.2", as_string[~digit % ','] << double_, ut)); + } + + // as + { + using boost::spirit::karma::digit; + using boost::spirit::karma::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("xy"); + BOOST_TEST(test("xy", string, ut)); + BOOST_TEST(test("xy", as_string[*char_], ut)); + BOOST_TEST(test("x,y", as_string[char_ << ',' << char_], ut)); + + ut.clear(); + ut.push_back("ab"); + ut.push_back(1.2); + BOOST_TEST(test("ab1.2", as_string[*~digit] << double_, ut)); + BOOST_TEST(test("a,b1.2", as_string[~digit % ','] << double_, ut)); + + ut = utf8_symbol_type("xy"); + BOOST_TEST(test("xy", string, ut)); + BOOST_TEST(test("xy", as_symbol[*char_], ut)); + BOOST_TEST(test("x,y", as_symbol[char_ << ',' << char_], ut)); + + ut.clear(); + ut.push_back(utf8_symbol_type("ab")); + ut.push_back(1.2); + BOOST_TEST(test("ab1.2", as_symbol[*~digit] << double_, ut)); + BOOST_TEST(test("a,b1.2", as_symbol[~digit % ','] << double_, ut)); + } + + // typed basic_string rules + { + utree ut("buzz"); + + rule<output_iterator, utf8_string_type()> r1 = string; + rule<output_iterator, utf8_symbol_type()> r2 = string; + + BOOST_TEST(test("buzz", r1, ut)); + + ut = utf8_symbol_type("bar"); + BOOST_TEST(test("bar", r2, ut)); + } + + // parameterized karma::string + { + utree ut("foo"); + + rule<output_iterator, utf8_string_type()> r1 = string("foo"); + BOOST_TEST(test("foo", string("foo"), ut)); + BOOST_TEST(test("foo", r1, ut)); + } + + { + using boost::spirit::karma::verbatim; + using boost::spirit::karma::repeat; + using boost::spirit::karma::space; + using boost::spirit::karma::digit; + + utree ut; + ut.push_back('x'); + ut.push_back('y'); + ut.push_back('c'); + BOOST_TEST(test_delimited("xy c ", verbatim[repeat(2)[char_]] << char_, ut, space)); + BOOST_TEST(test_delimited("x yc ", char_ << verbatim[*char_], ut, space)); + + ut.clear(); + ut.push_back('a'); + ut.push_back('b'); + ut.push_back(1.2); + BOOST_TEST(test_delimited("ab 1.2 ", verbatim[repeat(2)[~digit]] << double_, ut, space)); + } + + return boost::report_errors(); +} diff --git a/src/boost/libs/spirit/test/karma/wstream.cpp b/src/boost/libs/spirit/test/karma/wstream.cpp new file mode 100644 index 00000000..1f4ba199 --- /dev/null +++ b/src/boost/libs/spirit/test/karma/wstream.cpp @@ -0,0 +1,115 @@ +// 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 <cwchar> +#include <streambuf> +#include <iostream> + +#include <boost/config/warning_disable.hpp> +#include <boost/detail/lightweight_test.hpp> +#include <boost/cstdint.hpp> + +#include <boost/spirit/include/karma_char.hpp> +#include <boost/spirit/include/karma_string.hpp> +#include <boost/spirit/include/karma_stream.hpp> +#include <boost/spirit/include/karma_directive.hpp> +#include <boost/spirit/include/phoenix_core.hpp> +#include <boost/spirit/include/phoenix_operator.hpp> + +#include "test.hpp" + +using namespace spirit_test; + +// a simple complex number representation z = a + bi +struct complex +{ + complex (double a, double b) + : a(a), b(b) + {} + + double a; + double b; + + template <typename Char> + friend std::basic_ostream<Char>& + operator<< (std::basic_ostream<Char>& os, complex z) + { + os << "{" << z.a << "," << z.b << "}"; + return os; + } +}; + +/////////////////////////////////////////////////////////////////////////////// +int +main() +{ + using namespace boost::spirit; + + { + BOOST_TEST(test(L"x", wstream, L'x')); + BOOST_TEST(test(L"xyz", wstream, L"xyz")); + BOOST_TEST(test(L"xyz", wstream, std::basic_string<wchar_t>(L"xyz"))); + BOOST_TEST(test(L"1", wstream, 1)); + BOOST_TEST(test(L"1.1", wstream, 1.1)); + BOOST_TEST(test(L"{1.2,2.4}", wstream, complex(1.2, 2.4))); + } + + { + BOOST_TEST(test(L"x", wstream(L'x'))); + BOOST_TEST(test(L"xyz", wstream(L"xyz"))); + BOOST_TEST(test(L"xyz", wstream(std::basic_string<wchar_t>(L"xyz")))); + BOOST_TEST(test(L"1", wstream(1))); + BOOST_TEST(test(L"1.1", wstream(1.1))); + BOOST_TEST(test(L"{1.2,2.4}", wstream(complex(1.2, 2.4)))); + } + + { + using namespace boost::spirit::ascii; + + BOOST_TEST(test(L"x", lower[wstream], L'X')); + BOOST_TEST(test(L"xyz", lower[wstream], L"XYZ")); + BOOST_TEST(test(L"xyz", lower[wstream], std::basic_string<wchar_t>(L"XYZ"))); + BOOST_TEST(test(L"X", upper[wstream], L'x')); + BOOST_TEST(test(L"XYZ", upper[wstream], L"xyz")); + BOOST_TEST(test(L"XYZ", upper[wstream], std::basic_string<wchar_t>(L"xyz"))); + } + + { + BOOST_TEST(test_delimited(L"x ", wstream, L'x', L' ')); + BOOST_TEST(test_delimited(L"xyz ", wstream, L"xyz", L' ')); + BOOST_TEST(test_delimited(L"xyz ", wstream, std::basic_string<wchar_t>(L"xyz"), L' ')); + BOOST_TEST(test_delimited(L"1 ", wstream, 1, ' ')); + BOOST_TEST(test_delimited(L"1.1 ", wstream, 1.1, ' ')); + BOOST_TEST(test_delimited(L"{1.2,2.4} ", wstream, complex(1.2, 2.4), ' ')); + } + + { + using namespace boost::spirit::ascii; + + BOOST_TEST(test_delimited(L"x ", lower[wstream], L'X', L' ')); + BOOST_TEST(test_delimited(L"xyz ", lower[wstream], L"XYZ", L' ')); + BOOST_TEST(test_delimited(L"xyz ", lower[wstream], std::basic_string<wchar_t>(L"XYZ"), L' ')); + BOOST_TEST(test_delimited(L"X ", upper[wstream], L'x', L' ')); + BOOST_TEST(test_delimited(L"XYZ ", upper[wstream], L"xyz", ' ')); + BOOST_TEST(test_delimited(L"XYZ ", upper[wstream], std::basic_string<wchar_t>(L"xyz"), L' ')); + } + + { // lazy streams + namespace phx = boost::phoenix; + + std::basic_string<wchar_t> ws(L"abc"); + BOOST_TEST((test(L"abc", wstream(phx::val(ws))))); + BOOST_TEST((test(L"abc", wstream(phx::ref(ws))))); + } + + { + boost::optional<wchar_t> c; + BOOST_TEST(!test(L"", wstream, c)); + c = L'x'; + BOOST_TEST(test(L"x", wstream, c)); + } + + return boost::report_errors(); +} diff --git a/src/boost/libs/spirit/test/lex/Jamfile b/src/boost/libs/spirit/test/lex/Jamfile new file mode 100644 index 00000000..250656f1 --- /dev/null +++ b/src/boost/libs/spirit/test/lex/Jamfile @@ -0,0 +1,101 @@ +#============================================================================== +# 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 modules ; +import path ; +import testing ; + +############################################################################### + +project spirit-lex + : requirements + <include>. + <c++-template-depth>512 + ; + +############################################################################### + +cpp-pch pch : pch.hpp : : : <include>. <toolset>msvc:<cxxflags>"/FIpch.hpp" ; + +explicit pch ; + +############################################################################### + +local subproject-name = lex ; + +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) ] ; +} + +############################################################################### + +rule location ( name ) +{ + local this = [ modules.binding $(__name__) ] ; + local here = [ path.parent [ path.make $(this) ] ] ; + return [ path.join $(here) $(name) ] ; +} + +############################################################################### + +run auto_switch_lexerstate.cpp ; +run dedent_handling_phoenix.cpp ; +run id_type_enum.cpp ; +run lexertl1.cpp ; +run lexertl2.cpp ; +run lexertl3.cpp ; +run lexertl4.cpp ; +run lexertl5.cpp ; +run lexer_state_switcher.cpp ; +run semantic_actions.cpp ; +run set_token_value.cpp ; +run set_token_value_phoenix.cpp ; +run state_switcher.cpp ; +run string_token_id.cpp ; +run token_iterpair.cpp ; +run token_moretypes.cpp ; +run token_omit.cpp ; +run token_onetype.cpp ; +run plain_token.cpp ; + +run regression_basic_lexer.cpp ; +run regression_matlib_dynamic.cpp ; +run regression_matlib_generate.cpp : [ location matlib_static.h ] ; +run regression_matlib_static.cpp : : : <dependency>lex_regression_matlib_generate ; +run regression_matlib_generate_switch.cpp : [ location matlib_static_switch.h ] ; +run regression_matlib_switch.cpp : : : <dependency>lex_regression_matlib_generate_switch ; +run regression_word_count.cpp ; +run regression_syntax_error.cpp ; +run regression_wide.cpp ; +run regression_file_iterator1.cpp ; +run regression_file_iterator2.cpp ; +run regression_file_iterator3.cpp : : : <pch>off ; +run regression_file_iterator4.cpp ; +run regression_static_wide_6253.cpp ; +run regression_less_8563.cpp ; diff --git a/src/boost/libs/spirit/test/lex/auto_switch_lexerstate.cpp b/src/boost/libs/spirit/test/lex/auto_switch_lexerstate.cpp new file mode 100644 index 00000000..6ba8bd86 --- /dev/null +++ b/src/boost/libs/spirit/test/lex/auto_switch_lexerstate.cpp @@ -0,0 +1,89 @@ +// Copyright (c) 2001-2010 Hartmut Kaiser +// Copyright (c) 2010 Mathias Gaunard +// +// Distributed under the 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 test makes sure that the BOL state (begin of line) is properly reset +// if a token matched at the beginning of a line is discarded using +// lex::pass_fail. +// Additionally this test makes sure the syntax 'self("state", "targetstate")' +// works properly. + +#include <boost/config/warning_disable.hpp> +#include <boost/detail/lightweight_test.hpp> + +#include <boost/spirit/include/support_multi_pass.hpp> +#include <boost/spirit/include/classic_position_iterator.hpp> +#include <boost/spirit/include/lex_lexertl.hpp> + +namespace spirit = boost::spirit; +namespace lex = spirit::lex; + +typedef spirit::classic::position_iterator2< + spirit::multi_pass<std::istreambuf_iterator<char> > +> file_iterator; + +inline file_iterator +make_file_iterator(std::istream& input, const std::string& filename) +{ + return file_iterator( + spirit::make_default_multi_pass( + std::istreambuf_iterator<char>(input)), + spirit::multi_pass<std::istreambuf_iterator<char> >(), + filename); +} + +typedef lex::lexertl::token<file_iterator> token_type; + +struct lexer + : lex::lexer<lex::lexertl::actor_lexer<token_type> > +{ + lexer() : word("^[a-zA-Z0-9]+$", 1) + { + self("INITIAL", "O") = + word + | lex::string("!.*$") [ + lex::_pass = lex::pass_flags::pass_ignore + ] + | lex::token_def<>('\n', 2) + ; + + self("O", "INITIAL") = + lex::string(".") [ + lex::_pass = lex::pass_flags::pass_fail + ] + ; + } + + lex::token_def<> word; +}; + +typedef lexer::iterator_type token_iterator; + +int main() +{ + std::stringstream ss; + ss << "!foo\nbar\n!baz"; + + file_iterator begin = make_file_iterator(ss, "SS"); + file_iterator end; + + lexer l; + token_iterator begin2 = l.begin(begin, end); + token_iterator end2 = l.end(); + + std::size_t test_data[] = { 2, 1, 2 }; + std::size_t const test_data_size = sizeof(test_data)/sizeof(test_data[0]); + + token_iterator it = begin2; + std::size_t i = 0; + for (/**/; it != end2 && i < test_data_size; ++it, ++i) + { + BOOST_TEST(it->id() == test_data[i]); + } + BOOST_TEST(it == end2); + BOOST_TEST(i == test_data_size); + + return boost::report_errors(); +} diff --git a/src/boost/libs/spirit/test/lex/dedent_handling_phoenix.cpp b/src/boost/libs/spirit/test/lex/dedent_handling_phoenix.cpp new file mode 100644 index 00000000..adffb3ab --- /dev/null +++ b/src/boost/libs/spirit/test/lex/dedent_handling_phoenix.cpp @@ -0,0 +1,98 @@ +// Copyright (c) 2009 Carl Barron +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#include <iostream> +#include <sstream> + +#include <boost/detail/lightweight_test.hpp> +#include <boost/spirit/include/lex.hpp> +#include <boost/spirit/include/lex_lexertl.hpp> +#include <boost/spirit/include/phoenix_core.hpp> +#include <boost/spirit/include/phoenix_operator.hpp> +#include <boost/spirit/include/phoenix_statement.hpp> + +namespace lex = boost::spirit::lex; +namespace phoenix = boost::phoenix; + +/////////////////////////////////////////////////////////////////////////////// +template <typename Lexer> +struct multi_tokens : lex::lexer<Lexer> +{ + int level; + + multi_tokens() : level(0) + { + using lex::_state; + using lex::_start; + using lex::_end; + using lex::_pass; + using lex::pass_flags; + + a = "A"; + b = "B"; + c = "C"; + this->self = + a [ ++phoenix::ref(level) ] + | b + | c [ + _state = "in_dedenting", + _end = _start, + _pass = pass_flags::pass_ignore + ] + ; + + d = "."; + this->self("in_dedenting") = + d [ + if_(--phoenix::ref(level)) [ + _end = _start + ] + .else_ [ + _state = "INITIAL" + ] + ] + ; + } + + lex::token_def<> a, b, c, d; +}; + +struct dumper +{ + typedef bool result_type; + + dumper(std::stringstream& strm) : strm(strm) {} + + template <typename Token> + bool operator () (Token const &t) + { + strm << (char)(t.id() - lex::min_token_id + 'a'); + return true; + } + + std::stringstream& strm; + + // silence MSVC warning C4512: assignment operator could not be generated + BOOST_DELETED_FUNCTION(dumper& operator= (dumper const&)); +}; + +/////////////////////////////////////////////////////////////////////////////// +int main() +{ + typedef lex::lexertl::token<std::string::iterator> token_type; + typedef lex::lexertl::actor_lexer<token_type> base_lexer_type; + typedef multi_tokens<base_lexer_type> lexer_type; + + std::string in("AAABBC"); + std::string::iterator first(in.begin()); + std::stringstream strm; + + lexer_type the_lexer; + BOOST_TEST(lex::tokenize(first, in.end(), the_lexer, dumper(strm))); + BOOST_TEST(strm.str() == "aaabbddd"); + + return boost::report_errors(); +} + diff --git a/src/boost/libs/spirit/test/lex/id_type_enum.cpp b/src/boost/libs/spirit/test/lex/id_type_enum.cpp new file mode 100644 index 00000000..b3a5cf72 --- /dev/null +++ b/src/boost/libs/spirit/test/lex/id_type_enum.cpp @@ -0,0 +1,93 @@ +// Copyright (c) 2001-2010 Hartmut Kaiser +// Copyright (c) 2010 Mathias Gaunard +// +// Distributed under the 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/support_multi_pass.hpp> +#include <boost/spirit/include/classic_position_iterator.hpp> +#include <boost/spirit/include/lex_lexertl.hpp> + +namespace spirit = boost::spirit; +namespace lex = spirit::lex; + +typedef spirit::classic::position_iterator2< + spirit::multi_pass<std::istreambuf_iterator<char> > +> file_iterator; + +inline file_iterator +make_file_iterator(std::istream& input, const std::string& filename) +{ + return file_iterator( + spirit::make_default_multi_pass( + std::istreambuf_iterator<char>(input)), + spirit::multi_pass<std::istreambuf_iterator<char> >(), + filename); +} + +enum token_id +{ + ID_WORD = lex::min_token_id + 1, + ID_EOL +}; + +typedef lex::lexertl::token< + file_iterator, boost::mpl::vector<>, boost::mpl::true_, token_id +> token_type; + +struct lexer + : lex::lexer<lex::lexertl::actor_lexer<token_type> > +{ + lexer() : word("^[a-zA-Z0-9]+$", ID_WORD) + { + typedef lex::token_def<lex::unused_type, char, token_id> toked_def; + + self("INITIAL", "O") = + word + | toked_def("!.*$") [ + lex::_pass = lex::pass_flags::pass_ignore + ] + | toked_def('\n', ID_EOL) + ; + + self("O", "INITIAL") = + toked_def(".") [ + lex::_pass = lex::pass_flags::pass_fail + ] + ; + } + + lex::token_def<lex::unused_type, char, token_id> word; +}; + +typedef lexer::iterator_type token_iterator; + +int main() +{ + std::stringstream ss; + ss << "!foo\nbar\n!baz"; + + file_iterator begin = make_file_iterator(ss, "SS"); + file_iterator end; + + lexer l; + token_iterator begin2 = l.begin(begin, end); + token_iterator end2 = l.end(); + + token_id test_data[] = { ID_EOL, ID_WORD, ID_EOL }; + std::size_t const test_data_size = sizeof(test_data)/sizeof(test_data[0]); + + token_iterator it = begin2; + std::size_t i = 0; + for (/**/; it != end2 && i < test_data_size; ++it, ++i) + { + BOOST_TEST(it->id() == test_data[i]); + } + BOOST_TEST(it == end2); + BOOST_TEST(i == test_data_size); + + return boost::report_errors(); +} diff --git a/src/boost/libs/spirit/test/lex/lexer_state_switcher.cpp b/src/boost/libs/spirit/test/lex/lexer_state_switcher.cpp new file mode 100644 index 00000000..97e5b1eb --- /dev/null +++ b/src/boost/libs/spirit/test/lex/lexer_state_switcher.cpp @@ -0,0 +1,66 @@ +// 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/mpl/print.hpp> +#include <boost/detail/lightweight_test.hpp> +#include <boost/spirit/include/phoenix_object.hpp> +#include <boost/spirit/include/phoenix_operator.hpp> +#include <boost/spirit/include/lex_lexertl.hpp> + +/////////////////////////////////////////////////////////////////////////////// +// Token definition +/////////////////////////////////////////////////////////////////////////////// +template <typename Lexer> +struct switch_state_tokens : boost::spirit::lex::lexer<Lexer> +{ + // define tokens and associate them with the lexer + switch_state_tokens() + { + namespace phoenix = boost::phoenix; + using boost::spirit::lex::_state; + + identifier = "[a-zA-Z_][a-zA-Z0-9_]*"; + this->self = identifier [ phoenix::ref(state_) = _state ]; + + integer = "[0-9]+"; + this->self("INT") = integer [ _state = "INITIAL" ]; + } + + std::string state_; + boost::spirit::lex::token_def<> identifier, integer; +}; + +/////////////////////////////////////////////////////////////////////////////// +int main() +{ + using namespace boost::spirit; + using namespace boost::spirit::lex; + + typedef std::string::iterator base_iterator_type; + typedef boost::spirit::lex::lexertl::token<base_iterator_type> token_type; + typedef boost::spirit::lex::lexertl::actor_lexer<token_type> lexer_type; + + { + switch_state_tokens<lexer_type> lex; + + { + // verify whether using _state as an rvalue works + std::string input("abc123"); + base_iterator_type first = input.begin(); + BOOST_TEST(boost::spirit::lex::tokenize(first, input.end(), lex) && + lex.state_ == "INITIAL"); + } + { + // verify whether using _state as an lvalue works + std::string input("123abc123"); + base_iterator_type first = input.begin(); + BOOST_TEST(boost::spirit::lex::tokenize(first, input.end(), lex, "INT") && + lex.state_ == "INITIAL"); + } + } + + return boost::report_errors(); +} + diff --git a/src/boost/libs/spirit/test/lex/lexertl1.cpp b/src/boost/libs/spirit/test/lex/lexertl1.cpp new file mode 100644 index 00000000..edbeb26d --- /dev/null +++ b/src/boost/libs/spirit/test/lex/lexertl1.cpp @@ -0,0 +1,113 @@ +// 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/lex_lexertl.hpp> +#include <boost/spirit/include/lex_lexertl_position_token.hpp> +#include "test.hpp" + +/////////////////////////////////////////////////////////////////////////////// +int main() +{ + using namespace boost::spirit; + using namespace spirit_test; + + // the following test aims at the low level lexer and token_def objects, + // normally not visible to/directly used by the user + + // initialize tokens + typedef lex::token_def<std::string> token_def; + + std::size_t const CCOMMENT = 1; + std::size_t const CPPCOMMENT = 2; + token_def c_comment ("\\/\\*[^*]*\\*+([^/*][^*]*\\*+)*\\/", CCOMMENT); + token_def cpp_comment ("\\/\\/[^\\n\\r]*(\\n|\\r|\\r\\n)", CPPCOMMENT); + + typedef std::string::iterator base_iterator_type; + + // test with default token type + typedef lex::lexertl::token<base_iterator_type> token_type; + typedef lex::lexertl::lexer<token_type> lexer_type; + typedef lex::lexer<lexer_type> lexer_def; + + { + // initialize lexer + lexer_def lex; + lex.self = c_comment; + lex.self += cpp_comment; + + // test lexer for two different input strings + BOOST_TEST(test (lex, "/* this is a comment */", CCOMMENT)); + BOOST_TEST(test (lex, "// this is a comment as well\n", CPPCOMMENT)); + } + + { + // initialize lexer + lexer_def lex; + lex.self = c_comment | cpp_comment; + + // test lexer for two different input strings + BOOST_TEST(test (lex, "/* this is a comment */", CCOMMENT)); + BOOST_TEST(test (lex, "// this is a comment as well\n", CPPCOMMENT)); + } + + { + // initialize lexer + lexer_def lex; + lex.self = token_def('+') | '-' | c_comment; + lex.self += lex::char_('*') | '/' | cpp_comment; + + // test lexer for two different input strings + BOOST_TEST(test (lex, "/* this is a comment */", CCOMMENT)); + BOOST_TEST(test (lex, "// this is a comment as well\n", CPPCOMMENT)); + BOOST_TEST(test (lex, "+", '+')); + BOOST_TEST(test (lex, "-", '-')); + BOOST_TEST(test (lex, "*", '*')); + BOOST_TEST(test (lex, "/", '/')); + } + + // test with position_token + typedef lex::lexertl::position_token<base_iterator_type> position_token_type; + typedef lex::lexertl::lexer<position_token_type> position_lexer_type; + typedef lex::lexer<position_lexer_type> position_lexer_def; + + { + // initialize lexer + position_lexer_def lex; + lex.self = c_comment; + lex.self += cpp_comment; + + // test lexer for two different input strings + BOOST_TEST(test (lex, "/* this is a comment */", CCOMMENT)); + BOOST_TEST(test (lex, "// this is a comment as well\n", CPPCOMMENT)); + } + + { + // initialize lexer + position_lexer_def lex; + lex.self = c_comment | cpp_comment; + + // test lexer for two different input strings + BOOST_TEST(test (lex, "/* this is a comment */", CCOMMENT)); + BOOST_TEST(test (lex, "// this is a comment as well\n", CPPCOMMENT)); + } + + { + // initialize lexer + position_lexer_def lex; + lex.self = token_def('+') | '-' | c_comment; + lex.self += lex::char_('*') | '/' | cpp_comment; + + // test lexer for two different input strings + BOOST_TEST(test (lex, "/* this is a comment */", CCOMMENT)); + BOOST_TEST(test (lex, "// this is a comment as well\n", CPPCOMMENT)); + BOOST_TEST(test (lex, "+", '+')); + BOOST_TEST(test (lex, "-", '-')); + BOOST_TEST(test (lex, "*", '*')); + BOOST_TEST(test (lex, "/", '/')); + } + + return boost::report_errors(); +} diff --git a/src/boost/libs/spirit/test/lex/lexertl2.cpp b/src/boost/libs/spirit/test/lex/lexertl2.cpp new file mode 100644 index 00000000..59fafbd0 --- /dev/null +++ b/src/boost/libs/spirit/test/lex/lexertl2.cpp @@ -0,0 +1,91 @@ +// 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/lex_lexertl.hpp> +#include <string> + +#include "test.hpp" + +/////////////////////////////////////////////////////////////////////////////// +// a simple lexer class +template <typename Lexer> +struct lexertl_test + : boost::spirit::lex::lexer<Lexer> +{ + typedef boost::spirit::lex::token_def<std::string> token_def; + + static std::size_t const CCOMMENT = 1; + static std::size_t const CPPCOMMENT = 2; + + lexertl_test() + : c_comment("\\/\\*[^*]*\\*+([^/*][^*]*\\*+)*\\/", CCOMMENT) + , cpp_comment("\\/\\/[^\\n\\r]*(\\n|\\r|\\r\\n)", CPPCOMMENT) + { + this->self = c_comment; + this->self += cpp_comment; + } + + token_def c_comment, cpp_comment; +}; + +template <typename Lexer> +struct wlexertl_test + : boost::spirit::lex::lexer<Lexer> +{ + typedef boost::spirit::lex::token_def<std::basic_string<wchar_t>, wchar_t> + token_def; + + static std::size_t const CCOMMENT = 1; + static std::size_t const CPPCOMMENT = 2; + + wlexertl_test() + : c_comment(L"\\/\\*[^*]*\\*+([^/*][^*]*\\*+)*\\/", CCOMMENT) + , cpp_comment(L"\\/\\/[^\\n\\r]*(\\n|\\r|\\r\\n)", CPPCOMMENT) + { + this->self = c_comment; + this->self += cpp_comment; + } + + token_def c_comment, cpp_comment; +}; + +/////////////////////////////////////////////////////////////////////////////// +int main() +{ + using namespace boost::spirit; + using namespace spirit_test; + + // the following test aims at the low level lexer_ and token_ objects, + // normally not visible/used by the user + { + // initialize lexer + typedef std::string::iterator base_iterator_type; + typedef lex::lexertl::token<base_iterator_type> token_type; + typedef lex::lexertl::lexer<token_type> lexer_type; + typedef lexertl_test<lexer_type> lexer_def; + + // test lexer for two different input strings + lexer_def lex; + BOOST_TEST(test (lex, "/* this is a comment */", lexer_def::CCOMMENT)); + BOOST_TEST(test (lex, "// this is a comment as well\n", lexer_def::CPPCOMMENT)); + } + + { + // initialize lexer + typedef std::basic_string<wchar_t>::iterator base_iterator_type; + typedef lex::lexertl::token<base_iterator_type> token_type; + typedef lex::lexertl::lexer<token_type> lexer_type; + typedef wlexertl_test<lexer_type> lexer_def; + + // test lexer for two different input strings + lexer_def lex; + BOOST_TEST(test (lex, L"/* this is a comment */", lexer_def::CCOMMENT)); + BOOST_TEST(test (lex, L"// this is a comment as well\n", lexer_def::CPPCOMMENT)); + } + + return boost::report_errors(); +} + diff --git a/src/boost/libs/spirit/test/lex/lexertl3.cpp b/src/boost/libs/spirit/test/lex/lexertl3.cpp new file mode 100644 index 00000000..9ff70974 --- /dev/null +++ b/src/boost/libs/spirit/test/lex/lexertl3.cpp @@ -0,0 +1,68 @@ +// 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/lex_lexertl.hpp> +#include "test.hpp" + +/////////////////////////////////////////////////////////////////////////////// +int main() +{ + using namespace boost::spirit; + using namespace boost::spirit::lex; + using namespace spirit_test; + + // initialize tokens + typedef lex::token_def<std::string> token_def; + + std::size_t const CCOMMENT = 1; + std::size_t const CPPCOMMENT = 2; + token_def c_comment ("\\/\\*[^*]*\\*+([^/*][^*]*\\*+)*\\/", CCOMMENT); + token_def cpp_comment ("\\/\\/[^\\n\\r]*(\\n|\\r|\\r\\n)", CPPCOMMENT); + + typedef std::string::iterator base_iterator_type; + typedef lex::lexertl::token<base_iterator_type> token_type; + typedef lex::lexertl::lexer<token_type> lexer_type; + + typedef lex::lexer<lexer_type> lexer_def; + + { + // initialize lexer + std::string str("def"); + token_def ws_tok ("[\\v\\f\\n\\r]+"); + lexer_def lex; + lex.self = c_comment; + lex.self += cpp_comment | '1' | '2' | '3' | "abc" | str; + lex.self += token_def(' ') | '\t' | ws_tok; + + // test lexer for two different input strings + BOOST_TEST(test (lex, "/* this is a comment */", CCOMMENT)); + BOOST_TEST(test (lex, "// this is a comment as well\n", CPPCOMMENT)); + BOOST_TEST(test (lex, "\n\n\v\f\r", ws_tok.id())); + BOOST_TEST(test (lex, " ", ' ')); + BOOST_TEST(test (lex, "2", '2')); + BOOST_TEST(test (lex, "abc")); + BOOST_TEST(test (lex, "def")); + } + + { + // initialize lexer + lexer_def lex; + token_def ws_tok ("[\\v\\f\\n\\r]+"); + lex.self = c_comment; + lex.self += cpp_comment | '1' | '2' | '3'; + lex.self("WHITESPACE") = token_def(' ') | '\t' | ws_tok; + + // test lexer for two different input strings + BOOST_TEST(test (lex, "/* this is a comment */", CCOMMENT)); + BOOST_TEST(test (lex, "// this is a comment as well\n", CPPCOMMENT)); + BOOST_TEST(test (lex, "2", '2')); + BOOST_TEST(!test (lex, "\n\n\v\f\r", ws_tok.id())); + BOOST_TEST(test (lex, " ", ' ', "WHITESPACE")); + BOOST_TEST(test (lex, "\n\n\v\f\r", ws_tok.id(), "WHITESPACE")); + } + + return boost::report_errors(); +} diff --git a/src/boost/libs/spirit/test/lex/lexertl4.cpp b/src/boost/libs/spirit/test/lex/lexertl4.cpp new file mode 100644 index 00000000..80730528 --- /dev/null +++ b/src/boost/libs/spirit/test/lex/lexertl4.cpp @@ -0,0 +1,90 @@ +// 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/lex_lexertl.hpp> +#include "test.hpp" + +/////////////////////////////////////////////////////////////////////////////// +int main() +{ + using namespace boost::spirit; + using namespace boost::spirit::lex; + using namespace spirit_test; + + // initialize tokens + typedef lex::token_def<std::string> token_def; + + std::size_t const CCOMMENT = 1; + std::size_t const CPPCOMMENT = 2; + std::size_t const TOKEN_ID_ABC = 1000; + std::size_t const TOKEN_ID_STR = 1001; + std::size_t const TOKEN_ID_WS = 1002; + + token_def c_comment ("\\/\\*[^*]*\\*+([^/*][^*]*\\*+)*\\/", CCOMMENT); + token_def cpp_comment ("\\/\\/[^\\n\\r]*(\\n|\\r|\\r\\n)", CPPCOMMENT); + token_def ws_tok ("[\\v\\f\\n\\r]+", TOKEN_ID_WS); + + typedef std::string::iterator base_iterator_type; + typedef lex::lexertl::token<base_iterator_type> token_type; + typedef lex::lexertl::lexer<token_type> lexer_type; + + typedef lex::lexer<lexer_type> lexer_def; + + std::string str("def"); + + { + // initialize lexer + lexer_def lex; + token_def ws_tok ("[\\v\\f\\n\\r]+", TOKEN_ID_WS); + lex.self.add + (c_comment)(cpp_comment) + ('1')('2')('3') + ("abc", TOKEN_ID_ABC) + (str, TOKEN_ID_STR) + ; + lex.self += token_def(' ') | '\t' | ws_tok; + + // test lexer for different input strings + BOOST_TEST(test (lex, "/* this is a comment */", CCOMMENT)); + BOOST_TEST(test (lex, "// this is a comment as well\n", CPPCOMMENT)); + BOOST_TEST(test (lex, "\n\n\v\f\r", ws_tok.id())); + BOOST_TEST(test (lex, " ", ' ')); + BOOST_TEST(test (lex, "2", '2')); + BOOST_TEST(test (lex, "abc", TOKEN_ID_ABC)); + BOOST_TEST(test (lex, "def", TOKEN_ID_STR)); + } + + { + // initialize lexer + lexer_def lex; + token_def ws_tok ("[\\v\\f\\n\\r]+", TOKEN_ID_WS); + + lex.self.add + (c_comment)(cpp_comment) + ('1')('2')('3') + ("abc", TOKEN_ID_ABC) + (str, TOKEN_ID_STR) + ; + + lex.self("WHITESPACE").add + (' ')('\t') + (ws_tok) + ; + + // test lexer for different input strings + BOOST_TEST(test (lex, "/* this is a comment */", CCOMMENT)); + BOOST_TEST(test (lex, "// this is a comment as well\n", CPPCOMMENT)); + BOOST_TEST(test (lex, "2", '2')); + BOOST_TEST(test (lex, "abc", TOKEN_ID_ABC)); + BOOST_TEST(test (lex, "def", TOKEN_ID_STR)); + + BOOST_TEST(!test (lex, "\n\n\v\f\r", TOKEN_ID_WS)); + BOOST_TEST(test (lex, " ", ' ', "WHITESPACE")); + BOOST_TEST(test (lex, "\n\n\v\f\r", TOKEN_ID_WS, "WHITESPACE")); + } + + return boost::report_errors(); +} diff --git a/src/boost/libs/spirit/test/lex/lexertl5.cpp b/src/boost/libs/spirit/test/lex/lexertl5.cpp new file mode 100644 index 00000000..33c3b3cd --- /dev/null +++ b/src/boost/libs/spirit/test/lex/lexertl5.cpp @@ -0,0 +1,107 @@ +// 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/lex_lexertl.hpp> +#include "test.hpp" + +/////////////////////////////////////////////////////////////////////////////// +// test pattern definition capabilities +int main() +{ + using namespace boost::spirit; + using namespace boost::spirit::lex; + using namespace spirit_test; + + // initialize tokens + typedef lex::token_def<std::string> token_def; + + std::size_t const CCOMMENT = 1; + std::size_t const CPPCOMMENT = 2; + std::size_t const TOKEN_ID_ABC = 1000; + std::size_t const TOKEN_ID_STR = 1001; + std::size_t const TOKEN_ID_WS = 1002; + + typedef std::string::iterator base_iterator_type; + typedef lex::lexertl::token<base_iterator_type> token_type; + typedef lex::lexertl::lexer<token_type> lexer_type; + + typedef lex::lexer<lexer_type> lexer_def; + + std::string str("def"); + + { + // initialize lexer + lexer_def lex; + + lex.self.add_pattern + ("CCOMMENT", "\\/\\*[^*]*\\*+([^/*][^*]*\\*+)*\\/") + ("CPPCOMMENT", "\\/\\/[^\\n\\r]*(\\n|\\r|\\r\\n)") + ("WS", "[\\v\\f\\n\\r]+") + ; + + token_def c_comment ("{CCOMMENT}", CCOMMENT); + token_def cpp_comment ("{CPPCOMMENT}", CPPCOMMENT); + token_def ws_tok ("{WS}"); + + lex.self.add + (c_comment)(cpp_comment) + ('1')('2')('3') + ("abc", TOKEN_ID_ABC) + (str, TOKEN_ID_STR) + ; + lex.self += token_def(' ') | '\t' | ws_tok; + + // test lexer for different input strings + BOOST_TEST(test (lex, "/* this is a comment */", CCOMMENT)); + BOOST_TEST(test (lex, "// this is a comment as well\n", CPPCOMMENT)); + BOOST_TEST(test (lex, "\n\n\v\f\r", ws_tok.id())); + BOOST_TEST(test (lex, " ", ' ')); + BOOST_TEST(test (lex, "2", '2')); + BOOST_TEST(test (lex, "abc", TOKEN_ID_ABC)); + BOOST_TEST(test (lex, "def", TOKEN_ID_STR)); + } + + { + // initialize lexer + lexer_def lex; + + lex.self.add_pattern + ("CCOMMENT", "\\/\\*[^*]*\\*+([^/*][^*]*\\*+)*\\/") + ("CPPCOMMENT", "\\/\\/[^\\n\\r]*(\\n|\\r|\\r\\n)") + ("WS", "[\\v\\f\\n\\r]+") + ; + + token_def c_comment ("{CCOMMENT}", CCOMMENT); + token_def cpp_comment ("{CPPCOMMENT}", CPPCOMMENT); + token_def ws_tok ("{WS}"); + + // init lexer + lex.self.add + (c_comment)(cpp_comment) + ('1')('2')('3') + ("abc", TOKEN_ID_ABC) + (str, TOKEN_ID_STR) + ; + + lex.self("WHITESPACE").add + (' ')('\t') + (ws_tok, TOKEN_ID_WS) + ; + + // test lexer for different input strings + BOOST_TEST(test (lex, "/* this is a comment */", CCOMMENT)); + BOOST_TEST(test (lex, "// this is a comment as well\n", CPPCOMMENT)); + BOOST_TEST(test (lex, "2", '2')); + BOOST_TEST(test (lex, "abc", TOKEN_ID_ABC)); + BOOST_TEST(test (lex, "def", TOKEN_ID_STR)); + + BOOST_TEST(!test (lex, "\n\n\v\f\r", TOKEN_ID_WS)); + BOOST_TEST(test (lex, " ", ' ', "WHITESPACE")); + BOOST_TEST(test (lex, "\n\n\v\f\r", TOKEN_ID_WS, "WHITESPACE")); + } + + return boost::report_errors(); +} diff --git a/src/boost/libs/spirit/test/lex/matlib.h b/src/boost/libs/spirit/test/lex/matlib.h new file mode 100644 index 00000000..defa4332 --- /dev/null +++ b/src/boost/libs/spirit/test/lex/matlib.h @@ -0,0 +1,100 @@ +// Copyright (c) 2001-2009 Hartmut Kaiser +// Copyright (c) 2009 Carl Barron +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#ifndef MATLIB_H_05102009 +#define MATLIB_H_05102009 +#include <boost/spirit/include/lex.hpp> +#include <vector> +#include <string> + +struct set_lexer_state +{ + std::string state; + set_lexer_state(const std::string &a):state(a){} + template <class Iterator,class Context> + void operator () (Iterator const&, Iterator const& + , BOOST_SCOPED_ENUM(boost::spirit::lex::pass_flags)&, std::size_t + , Context &ctx) const + { + ctx.set_state_name(state.c_str()); + } +}; + +struct store_double +{ + std::vector<double> &out; + store_double(std::vector<double> &a):out(a){} + template <class Iterator,class LexerContext> + void operator () (Iterator const& start, Iterator const& end + , BOOST_SCOPED_ENUM(boost::spirit::lex::pass_flags)&, std::size_t + , LexerContext &) const + { + std::string work(start, end); + out.push_back(std::atof(work.c_str())); + } + + // silence MSVC warning C4512: assignment operator could not be generated + BOOST_DELETED_FUNCTION(store_double& operator= (store_double const&)); +}; + +struct add_row +{ + std::vector<std::vector<double> > &matrix; + std::vector<double> &row; + + add_row(std::vector<std::vector<double> > &a,std::vector<double> &b) + :matrix(a),row(b) {} + template <class Iterator,class Context> + void operator () (Iterator const&, Iterator const& + , BOOST_SCOPED_ENUM(boost::spirit::lex::pass_flags)&, std::size_t + , Context &ctx) const + { + matrix.push_back(std::vector<double>()); + matrix.back().swap(row); + ctx.set_state_name("A"); + } + + // silence MSVC warning C4512: assignment operator could not be generated + BOOST_DELETED_FUNCTION(add_row& operator= (add_row const&)); +}; + +template <class Lexer> +struct matlib_tokens : boost::spirit::lex::lexer<Lexer> +{ + matlib_tokens(std::vector<std::vector<double> > &a) + : matrix(a) + { + typedef boost::spirit::lex::token_def<> token_def_; + + this->self.add_pattern("REAL1", "[0-9]+(\\.[0-9]*)?"); + this->self.add_pattern("REAL2", "\\.[0-9]+"); + + number = "[-+]?({REAL1}|{REAL2})([eE][-+]?[0-9]+)?"; + + this->self + = token_def_('[') [set_lexer_state("A")] + ; + + this->self("A") + = token_def_('[') [set_lexer_state("B")] + | ',' + | token_def_(']') [set_lexer_state("INITIAL")] + ; + + this->self("B") + = number [store_double(row)] + | ',' + | token_def_(']') [add_row(matrix,row)] + ; + } + + boost::spirit::lex::token_def<> number; + std::vector<std::vector<double> > &matrix; + std::vector<double> row; +}; + +#endif + diff --git a/src/boost/libs/spirit/test/lex/pch.hpp b/src/boost/libs/spirit/test/lex/pch.hpp new file mode 100644 index 00000000..ba5c72dd --- /dev/null +++ b/src/boost/libs/spirit/test/lex/pch.hpp @@ -0,0 +1,17 @@ +/*============================================================================= + 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/lex.hpp> +#include <boost/spirit/include/lex_lexertl.hpp> +#include <boost/spirit/include/phoenix_core.hpp> +#include <boost/spirit/include/phoenix_operator.hpp> +#include <boost/core/lightweight_test.hpp> +#include <string> +#include <iostream> + +#endif diff --git a/src/boost/libs/spirit/test/lex/plain_token.cpp b/src/boost/libs/spirit/test/lex/plain_token.cpp new file mode 100644 index 00000000..4ca79b83 --- /dev/null +++ b/src/boost/libs/spirit/test/lex/plain_token.cpp @@ -0,0 +1,91 @@ +// Copyright (c) 2001-2010 Hartmut Kaiser +// Copyright (c) 2016 Jeffrey E. Trull +// Distributed under the 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/lex_lexertl.hpp> +#include <boost/spirit/include/qi_parse.hpp> +#include <boost/spirit/include/qi_operator.hpp> + +#include <string> + +namespace qi = boost::spirit::qi; +namespace lex = boost::spirit::lex; + +enum tokenids +{ + // left tokens + IDLPAREN = lex::min_token_id, + IDLANGLE, + IDLBRACE, + IDLSQUARE, + // right tokens + IDRPAREN, + IDRANGLE, + IDRBRACE, + IDRSQUARE, + IDANY +}; + +template <typename Lexer> +struct delimiter_tokens : lex::lexer<Lexer> +{ + delimiter_tokens() + { + this->self = + lex::char_('(', IDLPAREN) + | lex::char_(')', IDRPAREN) + | lex::char_('<', IDLANGLE) + | lex::char_('>', IDRANGLE) + | lex::char_('{', IDLBRACE) + | lex::char_('}', IDRBRACE) + | lex::char_('[', IDLSQUARE) + | lex::char_(']', IDRSQUARE) + | lex::string(".", IDANY) + ; + } +}; + +int main() +{ + typedef lex::lexertl::token< + std::string::iterator, boost::mpl::vector<std::string> + > token_type; + + typedef lex::lexertl::lexer<token_type> lexer_type; + delimiter_tokens<lexer_type> delims; + + // two test cases for the token range + std::string angled_delimiter_str("<canvas>"); + + using qi::token; + // angle brackets + std::string::iterator beg = angled_delimiter_str.begin(); + BOOST_TEST(lex::tokenize_and_parse( + beg, angled_delimiter_str.end(), + delims, + token(IDLPAREN, IDLSQUARE) + >> +token(IDANY) + >> token(IDRPAREN, IDRSQUARE))); + + std::string paren_delimiter_str("(setq foo nil)"); + beg = paren_delimiter_str.begin(); + BOOST_TEST(lex::tokenize_and_parse( + beg, paren_delimiter_str.end(), + delims, + token(IDLPAREN, IDLSQUARE) + >> +token(IDANY) + >> token(IDRPAREN, IDRSQUARE))); + + // reset and use a regular plain token + beg = paren_delimiter_str.begin(); + BOOST_TEST(lex::tokenize_and_parse( + beg, paren_delimiter_str.end(), + delims, + token(IDLPAREN) >> +token(IDANY) >> token(IDRPAREN))); + + return boost::report_errors(); +} diff --git a/src/boost/libs/spirit/test/lex/regression_basic_lexer.cpp b/src/boost/libs/spirit/test/lex/regression_basic_lexer.cpp new file mode 100644 index 00000000..214e08c2 --- /dev/null +++ b/src/boost/libs/spirit/test/lex/regression_basic_lexer.cpp @@ -0,0 +1,64 @@ +// Copyright (c) 2001-2011 Hartmut Kaiser +// Copyright (c) 2009 Pavel Baranov +// +// Distributed under the 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/lex_lexertl.hpp> + +#include <iostream> +#include <string> + +using namespace boost::spirit; +using namespace boost::spirit::lex; + +typedef const char * base_iterator; + +/////////////////////////////////////////////////////////////////////////////// +// Token definition +/////////////////////////////////////////////////////////////////////////////// +template <typename Lexer> +struct position_helper_tokens : lexer<Lexer> +{ + position_helper_tokens() + { + // define tokens and associate them with the lexer + eol = "\n"; + any = "[^\n]+"; + + // associate tokens with the lexer + this->self + = eol + | any + ; + } + + token_def<> any, eol; +}; + +int main() +{ + // read input from the given file + std::string str ("test"); + + // token type + typedef lexertl::token<base_iterator, lex::omit, boost::mpl::false_> token_type; + + // lexer type + typedef lexertl::actor_lexer<token_type> lexer_type; + + // create the lexer object instance needed to invoke the lexical analysis + position_helper_tokens<lexer_type> position_helper_lexer; + + // tokenize the given string, all generated tokens are discarded + base_iterator first = str.c_str(); + base_iterator last = &first[str.size()]; + + for(lexer_type::iterator_type i = position_helper_lexer.begin(first, last); + i != position_helper_lexer.end() && (*i).is_valid(); i++ ) + { + } + return boost::report_errors(); +} + diff --git a/src/boost/libs/spirit/test/lex/regression_file_iterator1.cpp b/src/boost/libs/spirit/test/lex/regression_file_iterator1.cpp new file mode 100644 index 00000000..677f9c04 --- /dev/null +++ b/src/boost/libs/spirit/test/lex/regression_file_iterator1.cpp @@ -0,0 +1,99 @@ +// Copyright (c) 2001-2011 Hartmut Kaiser +// Copyright (c) 2010 Mathias Gaunard +// +// Distributed under the 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/support_multi_pass.hpp> +#include <boost/spirit/include/classic_position_iterator.hpp> +#include <boost/spirit/include/lex_lexertl.hpp> + +namespace spirit = boost::spirit; +namespace lex = spirit::lex; + +typedef spirit::classic::position_iterator2< + spirit::multi_pass<std::istreambuf_iterator<char> > +> file_iterator; + +typedef boost::iterator_range<file_iterator> file_range; + +inline file_iterator +make_file_iterator(std::istream& input, const std::string& filename) +{ + return file_iterator( + spirit::make_default_multi_pass( + std::istreambuf_iterator<char>(input)), + spirit::multi_pass<std::istreambuf_iterator<char> >(), + filename); +} + +struct identifier +{ + identifier(file_iterator, file_iterator) + { + } +}; + +struct string_literal +{ + string_literal(file_iterator, file_iterator) + { + } +}; + +typedef lex::lexertl::token< + file_iterator, boost::mpl::vector<identifier, string_literal> +> token_type; + +struct lexer + : lex::lexer<lex::lexertl::actor_lexer<token_type> > +{ + lexer() + : id("[a-zA-Z0-9]+", 1) + , st("'[^'\\n]*'", 2) + { + self("ST") = + st [ lex::_state = "INITIAL" ] + ; + + self("*") = + id [ lex::_state = "ST" ] + | lex::token_def<>(".", 3) [ lex::_state = "ST" ] + ; + } + + lex::token_def<identifier> id; + lex::token_def<string_literal> st; +}; + +typedef lexer::iterator_type token_iterator; + +int main() +{ + std::stringstream ss; + ss << "foo 'bar'"; + + file_iterator begin = make_file_iterator(ss, "SS"); + file_iterator end; + + lexer l; + token_iterator begin2 = l.begin(begin, end, "ST"); + token_iterator end2 = l.end(); + + std::size_t test_data[] = { 1, 3, 2 }; + std::size_t const test_data_size = sizeof(test_data)/sizeof(test_data[0]); + + token_iterator it = begin2; + std::size_t i = 0; + for (/**/; it != end2 && i < test_data_size; ++it, ++i) + { + BOOST_TEST(it->id() == test_data[i]); + } + BOOST_TEST(it == end2); + BOOST_TEST(i == test_data_size); + + return boost::report_errors(); +} diff --git a/src/boost/libs/spirit/test/lex/regression_file_iterator2.cpp b/src/boost/libs/spirit/test/lex/regression_file_iterator2.cpp new file mode 100644 index 00000000..aca7f5ce --- /dev/null +++ b/src/boost/libs/spirit/test/lex/regression_file_iterator2.cpp @@ -0,0 +1,106 @@ +// Copyright (c) 2001-2010 Hartmut Kaiser +// Copyright (c) 2010 Mathias Gaunard +// +// Distributed under the 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/support_multi_pass.hpp> +#include <boost/spirit/include/classic_position_iterator.hpp> +#include <boost/spirit/include/lex_lexertl.hpp> + +namespace spirit = boost::spirit; +namespace lex = spirit::lex; + +typedef spirit::classic::position_iterator2< + spirit::multi_pass<std::istreambuf_iterator<char> > +> file_iterator; + +inline file_iterator +make_file_iterator(std::istream& input, const std::string& filename) +{ + return file_iterator( + spirit::make_default_multi_pass( + std::istreambuf_iterator<char>(input)), + spirit::multi_pass<std::istreambuf_iterator<char> >(), + filename); +} + +struct identifier +{ + identifier(file_iterator, file_iterator) + { + } +}; + +struct string_literal +{ + string_literal(file_iterator, file_iterator) + { + } +}; + +typedef lex::lexertl::token< + file_iterator, boost::mpl::vector<identifier, string_literal> +> token_type; + +struct lexer + : lex::lexer<lex::lexertl::actor_lexer<token_type> > +{ + lexer() + : id("[a-zA-Z0-9]+", 1) + , st("'[^'\\n]*'", 2) + { + self = id [ + lex::_state = "ST" + ] + | lex::token_def<>(".", 3) [ + lex::_state = "ST" + ] + ; + + self("ST") = + st [ + lex::_state = "INITIAL" + ] + | lex::token_def<>(".", 4) [ + lex::_state = "INITIAL" + , lex::_pass = lex::pass_flags::pass_fail + ] + ; + } + + lex::token_def<identifier> id; + lex::token_def<string_literal> st; +}; + +typedef lexer::iterator_type token_iterator; + +int main() +{ + std::stringstream ss; + ss << "foo 'bar'"; + + file_iterator begin = make_file_iterator(ss, "SS"); + file_iterator end; + + lexer l; + token_iterator begin2 = l.begin(begin, end, "ST"); + token_iterator end2 = l.end(); + + std::size_t test_data[] = { 1, 3, 2 }; + std::size_t const test_data_size = sizeof(test_data)/sizeof(test_data[0]); + + token_iterator it = begin2; + std::size_t i = 0; + for (/**/; it != end2 && i < test_data_size; ++it, ++i) + { + BOOST_TEST(it->id() == test_data[i]); + } + BOOST_TEST(it == end2); + BOOST_TEST(i == test_data_size); + + return boost::report_errors(); +} diff --git a/src/boost/libs/spirit/test/lex/regression_file_iterator3.cpp b/src/boost/libs/spirit/test/lex/regression_file_iterator3.cpp new file mode 100644 index 00000000..cb38cf3f --- /dev/null +++ b/src/boost/libs/spirit/test/lex/regression_file_iterator3.cpp @@ -0,0 +1,102 @@ +// Copyright (c) 2001-2011 Hartmut Kaiser +// Copyright (c) 2010 Mathias Gaunard +// +// Distributed under the 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 1 // required for token streaming +// #define BOOST_SPIRIT_LEXERTL_DEBUG 1 + +#include <boost/config/warning_disable.hpp> +#include <boost/detail/lightweight_test.hpp> + +#include <boost/spirit/include/support_multi_pass.hpp> +#include <boost/spirit/include/classic_position_iterator.hpp> +#include <boost/spirit/include/lex_lexertl.hpp> + +#include <boost/spirit/include/phoenix_core.hpp> +#include <boost/spirit/include/phoenix_operator.hpp> +#include <boost/spirit/include/phoenix_statement.hpp> + +#include <sstream> + +namespace spirit = boost::spirit; +namespace lex = spirit::lex; +namespace phoenix = boost::phoenix; + +typedef spirit::classic::position_iterator2< + spirit::multi_pass<std::istreambuf_iterator<char> > +> file_iterator; + +typedef boost::iterator_range<file_iterator> file_range; + +inline file_iterator +make_file_iterator(std::istream& input, const std::string& filename) +{ + return file_iterator( + spirit::make_default_multi_pass( + std::istreambuf_iterator<char>(input)), + spirit::multi_pass<std::istreambuf_iterator<char> >(), + filename); +} + +struct string_literal +{ + string_literal(file_iterator, file_iterator) + { + } +}; + +typedef lex::lexertl::token< + file_iterator, boost::mpl::vector<string_literal> +> token_type; + +struct lexer + : lex::lexer<lex::lexertl::actor_lexer<token_type> > +{ + lexer() : st("'[^'\\n]*'", 1) + { + lex::token_def<> string_lookahead('\''); + self("LA") = string_lookahead; + + // make sure lookahead is implicitly evaluated using the lexer state + // the token_def has been associated with + self = st [ + phoenix::if_(lex::lookahead(string_lookahead)) [ lex::more() ] + ] + ; + } + + lex::token_def<string_literal> st; +}; + +typedef lexer::iterator_type token_iterator; + +int main() +{ + std::stringstream ss; + ss << "'foo''bar'"; + + file_iterator begin = make_file_iterator(ss, "SS"); + file_iterator end; + + lexer l; + token_iterator begin2 = l.begin(begin, end); + token_iterator end2 = l.end(); + + char const* test_data[] = { "1,'foo'", "1,'foo''bar'" }; + std::size_t const test_data_size = sizeof(test_data)/sizeof(test_data[0]); + + token_iterator it = begin2; + std::size_t i = 0; + for (/**/; it != end2 && i < test_data_size; ++it, ++i) + { + std::stringstream ss; + ss << it->id() << "," << *it; + BOOST_TEST(ss.str() == test_data[i]); + } + BOOST_TEST(it == end2); + BOOST_TEST(i == test_data_size); + + return boost::report_errors(); +} diff --git a/src/boost/libs/spirit/test/lex/regression_file_iterator4.cpp b/src/boost/libs/spirit/test/lex/regression_file_iterator4.cpp new file mode 100644 index 00000000..6212c203 --- /dev/null +++ b/src/boost/libs/spirit/test/lex/regression_file_iterator4.cpp @@ -0,0 +1,92 @@ +// Copyright (c) 2001-2010 Hartmut Kaiser +// Copyright (c) 2010 Mathias Gaunard +// +// Distributed under the 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 test makes sure that the BOL state (begin of line) is properly reset +// if a token matched at the beginning of a line is discarded using +// lex::pass_fail. + +#include <boost/config/warning_disable.hpp> +#include <boost/detail/lightweight_test.hpp> + +#include <boost/spirit/include/support_multi_pass.hpp> +#include <boost/spirit/include/classic_position_iterator.hpp> +#include <boost/spirit/include/lex_lexertl.hpp> + +namespace spirit = boost::spirit; +namespace lex = spirit::lex; + +typedef spirit::classic::position_iterator2< + spirit::multi_pass<std::istreambuf_iterator<char> > +> file_iterator; + +inline file_iterator +make_file_iterator(std::istream& input, const std::string& filename) +{ + return file_iterator( + spirit::make_default_multi_pass( + std::istreambuf_iterator<char>(input)), + spirit::multi_pass<std::istreambuf_iterator<char> >(), + filename); +} + +typedef lex::lexertl::token<file_iterator> token_type; + +struct lexer + : lex::lexer<lex::lexertl::actor_lexer<token_type> > +{ + lexer() : word("^[a-zA-Z0-9]+$", 1) + { + self = word [ + lex::_state = "O" + ] + | lex::token_def<>("!.*$") [ + lex::_state = "O" + , lex::_pass = lex::pass_flags::pass_ignore + ] + | lex::token_def<>('\n', 2) [ + lex::_state = "O" + ] + ; + + self("O") = + lex::token_def<>(".") [ + lex::_state = "INITIAL" + , lex::_pass = lex::pass_flags::pass_fail + ] + ; + } + + lex::token_def<> word; +}; + +typedef lexer::iterator_type token_iterator; + +int main() +{ + std::stringstream ss; + ss << "!foo\nbar\n!baz"; + + file_iterator begin = make_file_iterator(ss, "SS"); + file_iterator end; + + lexer l; + token_iterator begin2 = l.begin(begin, end); + token_iterator end2 = l.end(); + + std::size_t test_data[] = { 2, 1, 2 }; + std::size_t const test_data_size = sizeof(test_data)/sizeof(test_data[0]); + + token_iterator it = begin2; + std::size_t i = 0; + for (/**/; it != end2 && i < test_data_size; ++it, ++i) + { + BOOST_TEST(it->id() == test_data[i]); + } + BOOST_TEST(it == end2); + BOOST_TEST(i == test_data_size); + + return boost::report_errors(); +} diff --git a/src/boost/libs/spirit/test/lex/regression_less_8563.cpp b/src/boost/libs/spirit/test/lex/regression_less_8563.cpp new file mode 100644 index 00000000..85858ca6 --- /dev/null +++ b/src/boost/libs/spirit/test/lex/regression_less_8563.cpp @@ -0,0 +1,39 @@ +// Copyright (c) 2013 Andreas Pokorny +// +// Distributed under the 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/lex_lexertl.hpp> +#include <boost/spirit/include/phoenix_core.hpp> +#include <boost/spirit/include/phoenix_operator.hpp> + +#include <fstream> + +using namespace std; +using namespace boost::spirit; + +template <typename BaseLexer> +struct test_lexer : boost::spirit::lex::lexer<BaseLexer> +{ + test_lexer() + { + this->self = lex::string("just something") + [ + lex::_end = lex::less(boost::phoenix::val(1)) + ] + ; + } +}; + +int main() +{ + typedef lex::lexertl::token<char const*> token_type; + typedef lex::lexertl::actor_lexer<token_type> lexer_type; + + test_lexer<lexer_type> lexer; + + return boost::report_errors(); +} diff --git a/src/boost/libs/spirit/test/lex/regression_matlib_dynamic.cpp b/src/boost/libs/spirit/test/lex/regression_matlib_dynamic.cpp new file mode 100644 index 00000000..cbeab1f5 --- /dev/null +++ b/src/boost/libs/spirit/test/lex/regression_matlib_dynamic.cpp @@ -0,0 +1,44 @@ +// Copyright (c) 2001-2011 Hartmut Kaiser +// Copyright (c) 2009 Carl Barron +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#include <boost/detail/lightweight_test.hpp> +#include <boost/spirit/include/lex_lexertl.hpp> +#include <iostream> +#include <algorithm> +#include "matlib.h" + +void test_matrix(std::vector<std::vector<double> > const& x) +{ + BOOST_TEST(x.size() == 3); + BOOST_TEST(x[0].size() == 2 && x[0][0] == 1 && x[0][1] == 2); + BOOST_TEST(x[1].size() == 1 && x[1][0] == 3); + BOOST_TEST(x[2].size() == 3 && x[2][0] == 4 && x[2][1] == 5 && x[2][2] == 6); +} + +int main () +{ + std::string input("[[1,2][3][4,5,6]]"); + + std::vector<std::vector<double> > results; + typedef std::string::iterator iter; + typedef boost::spirit::lex::lexertl::actor_lexer< + boost::spirit::lex::lexertl::token<iter> + > lexer_type; + + typedef matlib_tokens<lexer_type> matlib_type; + matlib_type matrix(results); + iter first = input.begin(); + + try { + BOOST_TEST(boost::spirit::lex::tokenize(first, input.end(), matrix)); + test_matrix(results); + } + catch (std::runtime_error const& e) { + std::cerr << "caught exception: " << e.what() << std::endl; + BOOST_TEST(false); + } + return boost::report_errors(); +} diff --git a/src/boost/libs/spirit/test/lex/regression_matlib_generate.cpp b/src/boost/libs/spirit/test/lex/regression_matlib_generate.cpp new file mode 100644 index 00000000..b152b9ae --- /dev/null +++ b/src/boost/libs/spirit/test/lex/regression_matlib_generate.cpp @@ -0,0 +1,32 @@ +// Copyright (c) 2001-2011 Hartmut Kaiser +// Copyright (c) 2009 Carl Barron +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#include <boost/detail/lightweight_test.hpp> +#include <boost/spirit/include/lex_lexertl.hpp> +#include <boost/spirit/include/lex_generate_static_lexertl.hpp> + +#include <fstream> +#include <vector> + +#include "matlib.h" + +int main(int argc, char* argv[]) +{ + std::vector<std::vector<double> > results; + + typedef std::string::iterator iter; + typedef boost::spirit::lex::lexertl::actor_lexer< + boost::spirit::lex::lexertl::token<iter> + > lexer_type; + + typedef matlib_tokens<lexer_type> matlib_type; + matlib_type matrix(results); + + std::ofstream out(argc < 2 ? "matlib_static.h" : argv[1]); + BOOST_TEST(boost::spirit::lex::lexertl::generate_static_dfa(matrix, out, "matlib")); + return boost::report_errors(); +} + diff --git a/src/boost/libs/spirit/test/lex/regression_matlib_generate_switch.cpp b/src/boost/libs/spirit/test/lex/regression_matlib_generate_switch.cpp new file mode 100644 index 00000000..c5003759 --- /dev/null +++ b/src/boost/libs/spirit/test/lex/regression_matlib_generate_switch.cpp @@ -0,0 +1,33 @@ +// Copyright (c) 2001-2011 Hartmut Kaiser +// Copyright (c) 2009 Carl Barron +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#include <boost/detail/lightweight_test.hpp> +#include <boost/spirit/include/lex_lexertl.hpp> +#include <boost/spirit/include/lex_generate_static_lexertl.hpp> + +#include <fstream> +#include <vector> + +#include "matlib.h" + +int main(int argc, char* argv[]) +{ + std::vector<std::vector<double> > results; + + typedef std::string::iterator iter; + typedef boost::spirit::lex::lexertl::actor_lexer< + boost::spirit::lex::lexertl::token<iter> + > lexer_type; + + typedef matlib_tokens<lexer_type> matlib_type; + matlib_type matrix(results); + + std::ofstream out(argc < 2 ? "matlib_static_switch.h" : argv[1]); + BOOST_TEST(boost::spirit::lex::lexertl::generate_static_switch( + matrix, out, "matlib_switch")); + return boost::report_errors(); +} + diff --git a/src/boost/libs/spirit/test/lex/regression_matlib_static.cpp b/src/boost/libs/spirit/test/lex/regression_matlib_static.cpp new file mode 100644 index 00000000..9512888e --- /dev/null +++ b/src/boost/libs/spirit/test/lex/regression_matlib_static.cpp @@ -0,0 +1,50 @@ +// Copyright (c) 2001-2010 Hartmut Kaiser +// Copyright (c) 2009 Carl Barron +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#include <boost/detail/lightweight_test.hpp> +#include <boost/spirit/include/lex_static_lexertl.hpp> + +#include <iostream> +#include <string> +#include <vector> +#include <exception> + +#include "matlib_static.h" +#include "matlib.h" + +void test_matrix(std::vector<std::vector<double> > const& x) +{ + BOOST_TEST(x.size() == 3); + BOOST_TEST(x[0].size() == 2 && x[0][0] == 1 && x[0][1] == 2); + BOOST_TEST(x[1].size() == 1 && x[1][0] == 3); + BOOST_TEST(x[2].size() == 3 && x[2][0] == 4 && x[2][1] == 5 && x[2][2] == 6); +} + +int main() +{ + std::string input("[[1,2][3][4,5,6]]"); + std::vector<std::vector<double> > results; + + typedef std::string::iterator iter; + typedef boost::spirit::lex::lexertl::static_actor_lexer< + boost::spirit::lex::lexertl::token<iter>, + boost::spirit::lex::lexertl::static_::lexer_matlib + > lexer_type; + + typedef matlib_tokens<lexer_type> matlib_type; + matlib_type matrix(results); + iter first = input.begin(); + + try { + BOOST_TEST(boost::spirit::lex::tokenize(first, input.end(), matrix)); + test_matrix(results); + } + catch (std::runtime_error const& e) { + std::cerr << e.what() << '\n'; + BOOST_TEST(false); + } + return boost::report_errors(); +} diff --git a/src/boost/libs/spirit/test/lex/regression_matlib_switch.cpp b/src/boost/libs/spirit/test/lex/regression_matlib_switch.cpp new file mode 100644 index 00000000..dc8e315b --- /dev/null +++ b/src/boost/libs/spirit/test/lex/regression_matlib_switch.cpp @@ -0,0 +1,50 @@ +// Copyright (c) 2001-2010 Hartmut Kaiser +// Copyright (c) 2009 Carl Barron +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#include <boost/detail/lightweight_test.hpp> +#include <boost/spirit/include/lex_static_lexertl.hpp> + +#include <iostream> +#include <string> +#include <vector> +#include <exception> + +#include "matlib_static_switch.h" +#include "matlib.h" + +void test_matrix(std::vector<std::vector<double> > const& x) +{ + BOOST_TEST(x.size() == 3); + BOOST_TEST(x[0].size() == 2 && x[0][0] == 1 && x[0][1] == 2); + BOOST_TEST(x[1].size() == 1 && x[1][0] == 3); + BOOST_TEST(x[2].size() == 3 && x[2][0] == 4 && x[2][1] == 5 && x[2][2] == 6); +} + +int main() +{ + std::string input("[[1,2][3][4,5,6]]"); + std::vector<std::vector<double> > results; + + typedef std::string::iterator iter; + typedef boost::spirit::lex::lexertl::static_actor_lexer< + boost::spirit::lex::lexertl::token<iter>, + boost::spirit::lex::lexertl::static_::lexer_matlib_switch + > lexer_type; + + typedef matlib_tokens<lexer_type> matlib_type; + matlib_type matrix(results); + iter first = input.begin(); + + try { + BOOST_TEST(boost::spirit::lex::tokenize(first, input.end(), matrix)); + test_matrix(results); + } + catch (std::runtime_error const& e) { + std::cerr << e.what() << '\n'; + BOOST_TEST(false); + } + return boost::report_errors(); +} diff --git a/src/boost/libs/spirit/test/lex/regression_static_wide_6253.cpp b/src/boost/libs/spirit/test/lex/regression_static_wide_6253.cpp new file mode 100644 index 00000000..816fe98c --- /dev/null +++ b/src/boost/libs/spirit/test/lex/regression_static_wide_6253.cpp @@ -0,0 +1,44 @@ +// Copyright (c) 2001-2011 Hartmut Kaiser +// Copyright (c) 2011 Ryan Molden +// +// Distributed under the 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/lex_lexertl.hpp> +#include <boost/spirit/include/lex_generate_static_lexertl.hpp> +#include <boost/spirit/include/lex_static_lexertl.hpp> + +#include <fstream> + +using namespace std; +using namespace boost::spirit; + +template <typename BaseLexer> +struct my_lexer : boost::spirit::lex::lexer<BaseLexer> +{ + my_lexer() + { + token = L"Yay winning!"; + this->self = token; + } + + lex::token_def<lex::unused_type, wchar_t> token; +}; + +int main() +{ + typedef lex::lexertl::token<wchar_t const*> token_type; + typedef lex::lexertl::lexer<token_type> lexer_type; + + my_lexer<lexer_type> lexer; + + basic_ofstream<wchar_t> output_dfa("test_dfa.hpp"); + BOOST_TEST(lex::lexertl::generate_static_dfa(lexer, output_dfa, L"test_dfa")); + + basic_ofstream<wchar_t> output_switch("test_switch.hpp"); + BOOST_TEST(lex::lexertl::generate_static_switch(lexer, output_switch, L"test_switch")); + return boost::report_errors(); +} diff --git a/src/boost/libs/spirit/test/lex/regression_syntax_error.cpp b/src/boost/libs/spirit/test/lex/regression_syntax_error.cpp new file mode 100644 index 00000000..eb3decba --- /dev/null +++ b/src/boost/libs/spirit/test/lex/regression_syntax_error.cpp @@ -0,0 +1,96 @@ +// Copyright (c) 2001-2011 Hartmut Kaiser +// Copyright (c) 2009 Jean-Francois Ostiguy +// +// Distributed under the 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/lex_lexertl.hpp> +#include <boost/spirit/include/qi_parse.hpp> +#include <boost/spirit/include/qi_operator.hpp> +#include <boost/spirit/include/qi_char.hpp> +#include <boost/spirit/include/qi_grammar.hpp> +#include <boost/spirit/include/qi_eoi.hpp> + +#include <string> +#include <iostream> +#include <sstream> + +namespace lex = boost::spirit::lex; +namespace qi = boost::spirit::qi; +namespace mpl = boost::mpl; + +template <typename Lexer> +struct my_lexer : lex::lexer<Lexer> +{ + my_lexer() + { + delimiter = "BEGIN|END"; + identifier = "[a-zA-Z][_\\.a-zA-Z0-9]*"; + ws = "[ \\t\\n]+"; + real = "([0-9]*\\.?[0-9]+([eE][-+]?[0-9]+)?)|([-+]?[1-9]+\\.?([eE][-+]?[0-9]+))"; + integer = "[0-9]+"; + + this->self += ws[lex::_pass = lex::pass_flags::pass_ignore]; + this->self += delimiter; + this->self += identifier; + this->self += real; + this->self += integer; + this->self += '='; + this->self += ';'; + } + + lex::token_def<> ws; + lex::token_def<std::string> identifier; + lex::token_def<int> integer; + lex::token_def<double> real; + lex::token_def<> delimiter; +}; + +template <typename Iterator> +struct my_grammar : qi::grammar<Iterator> +{ + template <typename TokenDef> + my_grammar( TokenDef const& tok ) + : my_grammar::base_type(statement) + { + statement + = qi::eoi + | *(delimiter | declaration) + ; + + delimiter = tok.delimiter >> tok.identifier; + declaration = tok.identifier >> option >> ';'; + option = *(tok.identifier >> '=' >> (tok.real | tok.integer)); + } + + qi::rule<Iterator> statement, delimiter, declaration, option; +}; + +typedef lex::lexertl::token<char const* + , mpl::vector<std::string, double, int> > token_type; +typedef lex::lexertl::actor_lexer<token_type> lexer_type; +typedef my_lexer<lexer_type>::iterator_type iterator_type; + +int main() +{ + std::string test_string ("BEGIN section\n"); + // we introduce a syntax error: ";;" instead of ";" as a terminator. + test_string += "Identity;;\n"; // this will make the parser fail + test_string += "END section\n" ; + + char const* first = &test_string[0]; + char const* last = &first[test_string.size()]; + + my_lexer<lexer_type> lexer; + my_grammar<iterator_type> grammar(lexer); + + BOOST_TEST(lex::tokenize_and_parse(first, last, lexer, grammar)); + BOOST_TEST(first != last); + + return boost::report_errors(); +} + + diff --git a/src/boost/libs/spirit/test/lex/regression_wide.cpp b/src/boost/libs/spirit/test/lex/regression_wide.cpp new file mode 100644 index 00000000..11e7c3a4 --- /dev/null +++ b/src/boost/libs/spirit/test/lex/regression_wide.cpp @@ -0,0 +1,131 @@ +// Copyright (c) 2001-2010 Hartmut Kaiser +// Copyright (c) 2010 Sergey "GooRoo" Olendarenko +// +// Distributed under the 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 <cstdlib> +#include <iostream> +#include <locale> +#include <string> + +#include <boost/spirit/include/lex_lexertl.hpp> +#include <boost/spirit/include/phoenix_function.hpp> +#include <boost/spirit/include/phoenix_operator.hpp> + +namespace lex = boost::spirit::lex; +namespace phoenix = boost::phoenix; + +typedef std::basic_string<wchar_t> wstring_type; + +/////////////////////////////////////////////////////////////////////////////// +enum tokenids +{ + ID_IDENT = 1, + ID_CONSTANT, + ID_OPERATION, + ID_BRACKET +}; + +/////////////////////////////////////////////////////////////////////////////// +struct test_data +{ + tokenids tokenid; + wstring_type value; +}; + +// alpha+x1*(2.836-x2[i]) +test_data data[] = +{ + { ID_IDENT, L"alpha" }, + { ID_OPERATION, L"+" }, + { ID_IDENT, L"x1" }, + { ID_OPERATION, L"*" }, + { ID_BRACKET, L"(" }, + { ID_CONSTANT, L"2.836" }, + { ID_OPERATION, L"-" }, + { ID_IDENT, L"x2" }, + { ID_BRACKET, L"[" }, + { ID_IDENT, L"i" }, + { ID_BRACKET, L"]" }, + { ID_BRACKET, L")" } +}; + +/////////////////////////////////////////////////////////////////////////////// +struct test_impl +{ + typedef void result_type; + template <typename TokenId, typename Value> + struct result { typedef void type; }; + + template <typename TokenId, typename Value> + void operator()(TokenId const& tokenid, Value const& val) const + { + BOOST_TEST(sequence_counter < sizeof(data)/sizeof(data[0])); + BOOST_TEST(data[sequence_counter].tokenid == tokenids(tokenid)); + BOOST_TEST(0 == val.which()); + + typedef boost::iterator_range<wstring_type::iterator> iterator_range; + iterator_range r = boost::get<iterator_range>(val); + BOOST_TEST(data[sequence_counter].value == + wstring_type(r.begin(), r.end())); + + ++sequence_counter; + } + + static std::size_t sequence_counter; +}; +std::size_t test_impl::sequence_counter = 0; + +phoenix::function<test_impl> const test = test_impl(); + +/////////////////////////////////////////////////////////////////////////////// +template <typename Lexer> +struct mega_tokens : lex::lexer<Lexer> +{ + mega_tokens() + : identifier(L"[a-zA-Z_][a-zA-Z0-9_]*", ID_IDENT) + , constant (L"[0-9]+(\\.[0-9]+)?", ID_CONSTANT) + , operation (L"[\\+\\-\\*/]", ID_OPERATION) + , bracket (L"[\\(\\)\\[\\]]", ID_BRACKET) + { + using lex::_tokenid; + using lex::_val; + + this->self + = operation [ test(_tokenid, _val) ] + | identifier [ test(_tokenid, _val) ] + | constant [ test(_tokenid, _val) ] + | bracket [ test(_tokenid, _val) ] + ; + } + + lex::token_def<wstring_type, wchar_t, tokenids> identifier; + lex::token_def<double, wchar_t, tokenids> constant; + lex::token_def<wchar_t, wchar_t, tokenids> operation; + lex::token_def<wchar_t, wchar_t, tokenids> bracket; +}; + +/////////////////////////////////////////////////////////////////////////////// +int main() +{ + typedef wstring_type::iterator base_iterator; + typedef lex::lexertl::token< + base_iterator, boost::mpl::vector<wchar_t, wstring_type, double> + , boost::mpl::true_, tokenids + > token_type; + typedef lex::lexertl::actor_lexer<token_type> lexer_type; + + mega_tokens<lexer_type> mega_lexer; + + wstring_type exampleStr = L"alpha+x1*(2.836-x2[i])"; + base_iterator first = exampleStr.begin(); + + BOOST_TEST(lex::tokenize(first, exampleStr.end(), mega_lexer)); + BOOST_TEST(test_impl::sequence_counter == sizeof(data)/sizeof(data[0])); + + return boost::report_errors(); +} diff --git a/src/boost/libs/spirit/test/lex/regression_word_count.cpp b/src/boost/libs/spirit/test/lex/regression_word_count.cpp new file mode 100644 index 00000000..0536d5f0 --- /dev/null +++ b/src/boost/libs/spirit/test/lex/regression_word_count.cpp @@ -0,0 +1,89 @@ +// Copyright (c) 2001-2010 Hartmut Kaiser +// Copyright (c) 2009 Tor Brede Vekterli +// +// Distributed under the 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/lex_lexertl.hpp> +#include <boost/spirit/include/qi_parse.hpp> +#include <boost/spirit/include/qi_operator.hpp> +#include <boost/spirit/include/qi_action.hpp> +#include <boost/spirit/include/qi_char.hpp> +#include <boost/spirit/include/qi_grammar.hpp> +#include <boost/spirit/include/phoenix_operator.hpp> + +#include <iostream> +#include <string> + +namespace qi = boost::spirit::qi; +namespace lex = boost::spirit::lex; + +enum tokenids +{ + IDANY = lex::min_token_id + 10 // Lower 8 bits is 0x0a, same as '\n' +}; + +template <typename Lexer> +struct word_count_tokens : lex::lexer<Lexer> +{ + word_count_tokens() + { + this->self.add_pattern + ("TEST", "A") + ; + word = "{TEST}"; + this->self.add + (word) + ('\n') + (".", IDANY) + ; + } + lex::token_def<std::string> word; +}; + +template <typename Iterator> +struct word_count_grammar : qi::grammar<Iterator> +{ + template <typename TokenDef> + word_count_grammar(TokenDef const& tok) + : word_count_grammar::base_type(start) + , c(0), w(0), l(0) + { + using boost::phoenix::ref; + using qi::lit; + using qi::token; + + start = *( tok.word [++ref(w)] + | lit('\n') [++ref(l)] + | token(IDANY) [++ref(c)] + ) + ; + } + std::size_t c, w, l; + qi::rule<Iterator> start; +}; + + +int main() +{ + typedef lex::lexertl::token< + const char*, boost::mpl::vector<std::string> + > token_type; + + typedef lex::lexertl::lexer<token_type> lexer_type; + typedef word_count_tokens<lexer_type>::iterator_type iterator_type; + word_count_tokens<lexer_type> word_count; // Our lexer + word_count_grammar<iterator_type> g (word_count); // Our parser + + std::string str ("A\nBCDEFGHI"); + char const* first = str.c_str(); + char const* last = &first[str.size()]; + + BOOST_TEST(lex::tokenize_and_parse(first, last, word_count, g)); + BOOST_TEST(g.l == 1 && g.w == 1 && g.c == 8); + + return boost::report_errors(); +} diff --git a/src/boost/libs/spirit/test/lex/semantic_actions.cpp b/src/boost/libs/spirit/test/lex/semantic_actions.cpp new file mode 100644 index 00000000..129bc075 --- /dev/null +++ b/src/boost/libs/spirit/test/lex/semantic_actions.cpp @@ -0,0 +1,300 @@ +// 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/config/warning_disable.hpp> + +#include <boost/spirit/include/lex_lexertl.hpp> + +namespace lex = boost::spirit::lex; + +typedef lex::lexertl::token<std::string::iterator> token_type; +typedef lex::lexertl::actor_lexer<token_type> lexer_type; + +/////////////////////////////////////////////////////////////////////////////// +static bool found_identifier_flag = false; + +/////////////////////////////////////////////////////////////////////////////// +void found_identifier_sa0() +{ + found_identifier_flag = true; +} + +template <typename Lexer> +struct lexer_sa0 : lex::lexer<Lexer> +{ + lexer_sa0() + { + identifier = "[a-zA-Z][_a-zA-Z0-9]*"; + this->self += identifier [&found_identifier_sa0]; + } + lex::token_def<> identifier; +}; + +/////////////////////////////////////////////////////////////////////////////// +static std::string found_identifier_str; + +void found_identifier_sa2(std::string::iterator& start + , std::string::iterator& end) +{ + found_identifier_flag = true; + found_identifier_str = std::string(start, end); +} + +template <typename Lexer> +struct lexer_sa2 : lex::lexer<Lexer> +{ + lexer_sa2() + { + identifier = "[a-zA-Z][_a-zA-Z0-9]*"; + this->self += identifier [&found_identifier_sa2]; + } + lex::token_def<> identifier; +}; + +/////////////////////////////////////////////////////////////////////////////// +void found_identifier_sa3_normal(std::string::iterator& start + , std::string::iterator& end, BOOST_SCOPED_ENUM(lex::pass_flags)& pass) +{ + BOOST_TEST(pass == lex::pass_flags::pass_normal); + + found_identifier_flag = true; + found_identifier_str = std::string(start, end); +} + +template <typename Lexer> +struct lexer_sa3_normal : lex::lexer<Lexer> +{ + lexer_sa3_normal() + { + identifier = "[a-zA-Z][_a-zA-Z0-9]*"; + this->self += identifier [&found_identifier_sa3_normal]; + } + lex::token_def<> identifier; +}; + +void found_identifier_sa3_fail(std::string::iterator&, std::string::iterator& + , BOOST_SCOPED_ENUM(lex::pass_flags)& pass) +{ + pass = lex::pass_flags::pass_fail; +} + +template <typename Lexer> +struct lexer_sa3_fail : lex::lexer<Lexer> +{ + lexer_sa3_fail() + { + identifier = "[a-zA-Z][_a-zA-Z0-9]*"; + this->self += identifier [&found_identifier_sa3_fail]; + } + lex::token_def<> identifier; +}; + +void found_identifier_sa3_ignore(std::string::iterator&, std::string::iterator& + , BOOST_SCOPED_ENUM(lex::pass_flags)& pass) +{ + pass = lex::pass_flags::pass_ignore; +} + +template <typename Lexer> +struct lexer_sa3_ignore : lex::lexer<Lexer> +{ + lexer_sa3_ignore() + { + identifier = "[a-zA-Z][_a-zA-Z0-9]*"; + this->self += identifier [&found_identifier_sa3_ignore]; + } + lex::token_def<> identifier; +}; + +/////////////////////////////////////////////////////////////////////////////// +static std::size_t found_identifier_id = 0; + +void found_identifier_sa4(std::string::iterator& start + , std::string::iterator& end, BOOST_SCOPED_ENUM(lex::pass_flags)& pass + , std::size_t id) +{ + BOOST_TEST(pass == lex::pass_flags::pass_normal); + + found_identifier_flag = true; + found_identifier_str = std::string(start, end); + found_identifier_id = id; +} + +template <typename Lexer> +struct lexer_sa4 : lex::lexer<Lexer> +{ + lexer_sa4() + { + identifier = "[a-zA-Z][_a-zA-Z0-9]*"; + this->self += identifier [&found_identifier_sa4]; + } + lex::token_def<> identifier; +}; + +void found_identifier_sa4_id(std::string::iterator& start + , std::string::iterator& end, BOOST_SCOPED_ENUM(lex::pass_flags)& pass + , std::size_t& id) +{ + BOOST_TEST(pass == lex::pass_flags::pass_normal); + + found_identifier_flag = true; + found_identifier_str = std::string(start, end); + found_identifier_id = id; + id = 1; +} + +template <typename Lexer> +struct lexer_sa4_id : lex::lexer<Lexer> +{ + lexer_sa4_id() + { + identifier = "[a-zA-Z][_a-zA-Z0-9]*"; + this->self += identifier [&found_identifier_sa4_id]; + } + lex::token_def<> identifier; +}; + +static std::size_t found_identifier_id2 = 0; + +bool identifier_token(token_type const& t) +{ + found_identifier_id2 = t.id(); + return true; +} + +/////////////////////////////////////////////////////////////////////////////// +struct found_identifier_sa5 +{ + template <typename Context> + void operator()(std::string::iterator& /*start*/ + , std::string::iterator& /*end*/, BOOST_SCOPED_ENUM(lex::pass_flags)& pass + , std::size_t& /*id*/, Context& ctx) + { + BOOST_TEST(pass == lex::pass_flags::pass_normal); + + found_identifier_flag = true; + found_identifier_str = std::string(ctx.get_value().begin(), ctx.get_value().end()); + } +}; + +template <typename Lexer> +struct lexer_sa5 : lex::lexer<Lexer> +{ + lexer_sa5() + { + identifier = "[a-zA-Z][_a-zA-Z0-9]*"; + this->self += identifier [found_identifier_sa5()]; + } + lex::token_def<> identifier; +}; + +/////////////////////////////////////////////////////////////////////////////// +int main() +{ + std::string identifier ("id_1234"); + std::string::iterator first = identifier.begin(); + std::string::iterator last = identifier.end(); + + // test semantic action taking no arguments + found_identifier_flag = false; + { + lexer_sa0<lexer_type> sa0; + BOOST_TEST(lex::tokenize(first, last, sa0)); + BOOST_TEST(first == last); + BOOST_TEST(found_identifier_flag); + } + + // test semantic action taking two arguments (iterator pair for matched + // sequence) + found_identifier_flag = false; + found_identifier_str.clear(); + first = identifier.begin(); + { + lexer_sa2<lexer_type> sa2; + BOOST_TEST(lex::tokenize(first, last, sa2)); + BOOST_TEST(first == last); + BOOST_TEST(found_identifier_flag); + BOOST_TEST(found_identifier_str == identifier); + } + + // test semantic action taking three arguments (iterator pair for matched + // sequence and pass_flags) - pass_flags::pass_normal + found_identifier_flag = false; + found_identifier_str.clear(); + first = identifier.begin(); + { + lexer_sa3_normal<lexer_type> sa3; + BOOST_TEST(lex::tokenize(first, last, sa3)); + BOOST_TEST(first == last); + BOOST_TEST(found_identifier_flag); + BOOST_TEST(found_identifier_str == identifier); + } + + // test semantic action taking three arguments (iterator pair for matched + // sequence and pass_flags) - pass_flags::pass_fail + first = identifier.begin(); + { + lexer_sa3_fail<lexer_type> sa3; + BOOST_TEST(!lex::tokenize(first, last, sa3)); + BOOST_TEST(first != last); + } + + // test semantic action taking three arguments (iterator pair for matched + // sequence and pass_flags) - pass_flags::pass_ignore + first = identifier.begin(); + { + lexer_sa3_ignore<lexer_type> sa3; + BOOST_TEST(lex::tokenize(first, last, sa3)); + BOOST_TEST(first == last); + } + + // test semantic action taking four arguments (iterator pair for matched + // sequence and pass_flags, and token id) + found_identifier_flag = false; + found_identifier_str.clear(); + first = identifier.begin(); + found_identifier_id = 0; + { + lexer_sa4<lexer_type> sa4; + BOOST_TEST(lex::tokenize(first, last, sa4)); + BOOST_TEST(first == last); + BOOST_TEST(found_identifier_flag); + BOOST_TEST(found_identifier_str == identifier); + BOOST_TEST(found_identifier_id == lex::min_token_id); + } + + found_identifier_flag = false; + found_identifier_str.clear(); + first = identifier.begin(); + found_identifier_id = 0; + found_identifier_id2 = 0; + { + lexer_sa4_id<lexer_type> sa4; + BOOST_TEST(lex::tokenize(first, last, sa4, identifier_token)); + BOOST_TEST(first == last); + BOOST_TEST(found_identifier_flag); + BOOST_TEST(found_identifier_str == identifier); + BOOST_TEST(found_identifier_id == lex::min_token_id); + BOOST_TEST(found_identifier_id2 == 1); + } + + // test semantic action taking four arguments (iterator pair for matched + // sequence and pass_flags, token id, and context) + found_identifier_flag = false; + found_identifier_str.clear(); + first = identifier.begin(); + found_identifier_id = 0; + found_identifier_id2 = 0; + { + lexer_sa5<lexer_type> sa5; + BOOST_TEST(lex::tokenize(first, last, sa5)); + BOOST_TEST(first == last); + BOOST_TEST(found_identifier_flag); + BOOST_TEST(found_identifier_str == identifier); + } + + return boost::report_errors(); +} diff --git a/src/boost/libs/spirit/test/lex/set_token_value.cpp b/src/boost/libs/spirit/test/lex/set_token_value.cpp new file mode 100644 index 00000000..1cb32206 --- /dev/null +++ b/src/boost/libs/spirit/test/lex/set_token_value.cpp @@ -0,0 +1,255 @@ +// 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/phoenix_object.hpp> +#include <boost/spirit/include/phoenix_operator.hpp> +#include <boost/spirit/include/phoenix_container.hpp> +#include <boost/spirit/include/lex_lexertl.hpp> +#include <boost/foreach.hpp> + +using namespace boost::spirit; + +/////////////////////////////////////////////////////////////////////////////// +// semantic action analyzing leading whitespace +enum tokenids +{ + ID_INDENT = 1000, + ID_DEDENT +}; + +struct handle_whitespace +{ + handle_whitespace(std::stack<unsigned int>& indents) + : indents_(indents) {} + + template <typename Iterator, typename IdType, typename Context> + void operator()(Iterator& start, Iterator& end + , BOOST_SCOPED_ENUM(lex::pass_flags)& pass, IdType& id + , Context& ctx) + { + unsigned int level = 0; + if (is_indent(start, end, level)) { + id = ID_INDENT; + ctx.set_value(level); + } + else if (is_dedent(start, end, level)) { + id = ID_DEDENT; + ctx.set_value(level); + } + else { + pass = lex::pass_flags::pass_ignore; + } + } + + // Get indentation level, for now (no tabs) we just count the spaces + // once we allow tabs in the regex this needs to be expanded + template <typename Iterator> + unsigned int get_indent(Iterator& start, Iterator& end) + { + return static_cast<unsigned int>(std::distance(start, end)); + } + + template <typename Iterator> + bool is_dedent(Iterator& start, Iterator& end, unsigned int& level) + { + unsigned int newindent = get_indent(start, end); + while (!indents_.empty() && newindent < indents_.top()) { + level++; // dedent one more level + indents_.pop(); + } + return level > 0; + } + + // Handle additional indentation + template <typename Iterator> + bool is_indent(Iterator& start, Iterator& end, unsigned int& level) + { + unsigned int newindent = get_indent(start, end); + if (indents_.empty() || newindent > indents_.top()) { + level = 1; // indent one more level + indents_.push(newindent); + return true; + } + return false; + } + + std::stack<unsigned int>& indents_; + + // silence MSVC warning C4512: assignment operator could not be generated + BOOST_DELETED_FUNCTION(handle_whitespace& operator= (handle_whitespace const&)); +}; + +/////////////////////////////////////////////////////////////////////////////// +// Token definition +template <typename Lexer> +struct set_token_value : boost::spirit::lex::lexer<Lexer> +{ + set_token_value() + { + using lex::_pass; + + // define tokens and associate them with the lexer + whitespace = "^[ ]+"; + newline = '\n'; + + this->self = whitespace[ handle_whitespace(indents) ]; + this->self += newline[ _pass = lex::pass_flags::pass_ignore ]; + } + + lex::token_def<unsigned int> whitespace; + lex::token_def<> newline; + std::stack<unsigned int> indents; +}; + +/////////////////////////////////////////////////////////////////////////////// +struct token_data +{ + int id; + unsigned int value; +}; + +template <typename Token> +inline +bool test_tokens(token_data const* d, std::vector<Token> const& tokens) +{ + BOOST_FOREACH(Token const& t, tokens) + { + if (d->id == -1) + return false; // reached end of expected data + + typename Token::token_value_type const& value (t.value()); + if (t.id() != static_cast<std::size_t>(d->id)) // token id must match + return false; + if (value.which() != 1) // must have an integer value + return false; + if (boost::get<unsigned int>(value) != d->value) // value must match + return false; + ++d; + } + + return (d->id == -1) ? true : false; +} + +inline +bool test_indents(int *i, std::stack<unsigned int>& indents) +{ + while (!indents.empty()) + { + if (*i == -1) + return false; // reached end of expected data + if (indents.top() != static_cast<unsigned int>(*i)) + return false; // value must match + + ++i; + indents.pop(); + } + + return (*i == -1) ? true : false; +} + +/////////////////////////////////////////////////////////////////////////////// +int main() +{ + namespace lex = boost::spirit::lex; + namespace phoenix = boost::phoenix; + + typedef std::string::iterator base_iterator_type; + typedef boost::mpl::vector<unsigned int> token_value_types; + typedef lex::lexertl::token<base_iterator_type, token_value_types> token_type; + typedef lex::lexertl::actor_lexer<token_type> lexer_type; + + // test simple indent + { + set_token_value<lexer_type> lexer; + std::vector<token_type> tokens; + std::string input(" "); + base_iterator_type first = input.begin(); + + using phoenix::arg_names::_1; + BOOST_TEST(lex::tokenize(first, input.end(), lexer + , phoenix::push_back(phoenix::ref(tokens), _1))); + + int i[] = { 4, -1 }; + BOOST_TEST(test_indents(i, lexer.indents)); + + token_data d[] = { { ID_INDENT, 1 }, { -1, 0 } }; + BOOST_TEST(test_tokens(d, tokens)); + } + + // test two indents + { + set_token_value<lexer_type> lexer; + std::vector<token_type> tokens; + std::string input( + " \n" + " \n"); + base_iterator_type first = input.begin(); + + using phoenix::arg_names::_1; + BOOST_TEST(lex::tokenize(first, input.end(), lexer + , phoenix::push_back(phoenix::ref(tokens), _1))); + + int i[] = { 8, 4, -1 }; + BOOST_TEST(test_indents(i, lexer.indents)); + + token_data d[] = { + { ID_INDENT, 1 }, { ID_INDENT, 1 } + , { -1, 0 } }; + BOOST_TEST(test_tokens(d, tokens)); + } + + // test one dedent + { + set_token_value<lexer_type> lexer; + std::vector<token_type> tokens; + std::string input( + " \n" + " \n" + " \n"); + base_iterator_type first = input.begin(); + + using phoenix::arg_names::_1; + BOOST_TEST(lex::tokenize(first, input.end(), lexer + , phoenix::push_back(phoenix::ref(tokens), _1))); + + int i[] = { 4, -1 }; + BOOST_TEST(test_indents(i, lexer.indents)); + + token_data d[] = { + { ID_INDENT, 1 }, { ID_INDENT, 1 } + , { ID_DEDENT, 1 } + , { -1, 0 } }; + BOOST_TEST(test_tokens(d, tokens)); + } + + // test two dedents + { + set_token_value<lexer_type> lexer; + std::vector<token_type> tokens; + std::string input( + " \n" + " \n" + " \n" + " \n"); + base_iterator_type first = input.begin(); + + using phoenix::arg_names::_1; + BOOST_TEST(lex::tokenize(first, input.end(), lexer + , phoenix::push_back(phoenix::ref(tokens), _1))); + + int i[] = { 4, -1 }; + BOOST_TEST(test_indents(i, lexer.indents)); + + token_data d[] = { + { ID_INDENT, 1 }, { ID_INDENT, 1 }, { ID_INDENT, 1 } + , { ID_DEDENT, 2 } + , { -1, 0 } }; + BOOST_TEST(test_tokens(d, tokens)); + } + + return boost::report_errors(); +} + diff --git a/src/boost/libs/spirit/test/lex/set_token_value_phoenix.cpp b/src/boost/libs/spirit/test/lex/set_token_value_phoenix.cpp new file mode 100644 index 00000000..c55ba543 --- /dev/null +++ b/src/boost/libs/spirit/test/lex/set_token_value_phoenix.cpp @@ -0,0 +1,68 @@ +// Copyright (c) 2009 Carl Barron +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#include <string> +#include <iostream> + +#include <boost/detail/lightweight_test.hpp> +#include <boost/spirit/include/lex.hpp> +#include <boost/spirit/include/lex_lexertl.hpp> +#include <boost/spirit/include/phoenix_core.hpp> +#include <boost/spirit/include/phoenix_function.hpp> + +namespace lex = boost::spirit::lex; +namespace phoenix = boost::phoenix; + +/////////////////////////////////////////////////////////////////////////////// +struct square_impl +{ + template <class> + struct result { typedef int type; }; + + template <class A> + int operator () (const A &x) const + { return (x) * (x); } +}; + +phoenix::function<square_impl> const square = square_impl(); + +/////////////////////////////////////////////////////////////////////////////// +template <class Lexer> +struct test_tokens : lex::lexer<Lexer> +{ + test_tokens() + { + a = "a"; + this->self = a [lex::_val = square(*lex::_start)]; + } + + lex::token_def<int> a; +}; + +struct catch_result +{ + template <class Token> + bool operator() (Token const& x) const + { + BOOST_TEST(x.value().which() == 1); + BOOST_TEST(boost::get<int>(x.value()) == 9409); // 9409 == 'a' * 'a' + return true; + } +}; + +/////////////////////////////////////////////////////////////////////////////// +int main() +{ + typedef lex::lexertl::token<std::string::iterator + , boost::mpl::vector<int> > token_type; + + std::string in = "a"; + std::string::iterator first(in.begin()); + + test_tokens<lex::lexertl::actor_lexer<token_type> > the_lexer; + BOOST_TEST(lex::tokenize(first, in.end(), the_lexer, catch_result())); + + return boost::report_errors(); +} diff --git a/src/boost/libs/spirit/test/lex/state_switcher.cpp b/src/boost/libs/spirit/test/lex/state_switcher.cpp new file mode 100644 index 00000000..855e5cb2 --- /dev/null +++ b/src/boost/libs/spirit/test/lex/state_switcher.cpp @@ -0,0 +1,91 @@ +// 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/lex_lexertl.hpp> +#include <boost/spirit/include/qi_parse.hpp> +#include <boost/spirit/include/qi_operator.hpp> +#include "test_parser.hpp" + +/////////////////////////////////////////////////////////////////////////////// +// Token definition +/////////////////////////////////////////////////////////////////////////////// +template <typename Lexer> +struct switch_state_tokens : boost::spirit::lex::lexer<Lexer> +{ + switch_state_tokens() + { + // define tokens and associate them with the lexer + identifier = "[a-zA-Z_][a-zA-Z0-9_]*"; + this->self = identifier; + + // any token definition to be used as the skip parser during parsing + // has to be associated with a separate lexer state (here 'WS') + white_space = "[ \\t\\n]+"; + this->self("WS") = white_space; + + separators = "[,;]"; + this->self("SEP") = separators; + } + + boost::spirit::lex::token_def<> identifier, white_space, separators; +}; + +/////////////////////////////////////////////////////////////////////////////// +int main() +{ + using namespace boost::spirit; + using namespace boost::spirit::qi; + using namespace spirit_test; + + typedef std::string::iterator base_iterator_type; + typedef boost::spirit::lex::lexertl::token<base_iterator_type> token_type; + typedef boost::spirit::lex::lexertl::lexer<token_type> lexer_type; + + { + // the tokens class will be initialized inside the test_parser function + switch_state_tokens<lexer_type> lex; + + BOOST_TEST(test_parser("ident", lex.identifier, lex)); + BOOST_TEST(!test_parser("ident", set_state("WS") >> lex.identifier, lex)); + BOOST_TEST(!test_parser("ident", in_state("WS")[lex.identifier], lex)); + + BOOST_TEST(test_parser("\t \n", set_state("WS") >> lex.white_space, lex)); + BOOST_TEST(test_parser("\t \n", in_state("WS")[lex.white_space], lex)); + BOOST_TEST(!test_parser("\t \n", lex.white_space, lex)); + } + + { + // the tokens class will be initialized inside the test_parser function + switch_state_tokens<lexer_type> lex; + + BOOST_TEST(test_parser(",ident", lex.identifier, lex, + in_state("SEP")[lex.separators])); + BOOST_TEST(!test_parser(";ident", set_state("WS") >> lex.identifier, + lex, in_state("SEP")[lex.separators])); + BOOST_TEST(!test_parser(",ident", in_state("WS")[lex.identifier], + lex, in_state("SEP")[lex.separators])); + + BOOST_TEST(test_parser(",\t \n", set_state("WS") >> lex.white_space, + lex, in_state("SEP")[lex.separators])); + BOOST_TEST(test_parser(";\t \n", in_state("WS")[lex.white_space], + lex, in_state("SEP")[lex.separators])); + BOOST_TEST(!test_parser(",\t \n", lex.white_space, lex, + in_state("SEP")[lex.separators])); + } + + { + // the tokens class will be initialized inside the test_parser function + switch_state_tokens<lexer_type> lex; + + BOOST_TEST(test_parser("ident\t \n", + lex.identifier >> set_state("WS") >> lex.white_space, lex)); + BOOST_TEST(test_parser("\t \nident", + in_state("WS")[lex.white_space] >> lex.identifier, lex)); + } + + return boost::report_errors(); +} + diff --git a/src/boost/libs/spirit/test/lex/string_token_id.cpp b/src/boost/libs/spirit/test/lex/string_token_id.cpp new file mode 100644 index 00000000..4c9954b4 --- /dev/null +++ b/src/boost/libs/spirit/test/lex/string_token_id.cpp @@ -0,0 +1,87 @@ +// 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/config/warning_disable.hpp> + +#include <boost/spirit/include/lex_lexertl.hpp> +#include <boost/spirit/include/qi_parse.hpp> +#include <boost/spirit/include/qi_operator.hpp> +#include <boost/spirit/include/qi_action.hpp> +#include <boost/spirit/include/qi_grammar.hpp> +#include <boost/spirit/include/phoenix_operator.hpp> + +#include <iostream> +#include <string> + +namespace qi = boost::spirit::qi; +namespace lex = boost::spirit::lex; + +enum tokenids +{ + IDWORD = lex::min_token_id, + IDCHAR, + IDANY +}; + +template <typename Lexer> +struct word_count_tokens : lex::lexer<Lexer> +{ + word_count_tokens() + { + this->self.add_pattern + ("TEST", "A") + ; + + this->self = + lex::string("{TEST}", IDWORD) + | lex::char_('a', IDCHAR) + | lex::string(".", IDANY) + ; + } +}; + +template <typename Iterator> +struct word_count_grammar : qi::grammar<Iterator> +{ + template <typename TokenDef> + word_count_grammar(TokenDef const&) + : word_count_grammar::base_type(start) + , w(0), c(0), a(0) + { + using boost::phoenix::ref; + using qi::token; + + start = *( token(IDWORD) [++ref(w)] + | token(IDCHAR) [++ref(c)] + | token(IDANY) [++ref(a)] + ) + ; + } + std::size_t w, c, a; + qi::rule<Iterator> start; +}; + + +int main() +{ + typedef lex::lexertl::token< + const char*, boost::mpl::vector<std::string> + > token_type; + + typedef lex::lexertl::lexer<token_type> lexer_type; + typedef word_count_tokens<lexer_type>::iterator_type iterator_type; + word_count_tokens<lexer_type> word_count; // Our lexer + word_count_grammar<iterator_type> g (word_count); // Our parser + + std::string str ("AaBCD"); + char const* first = str.c_str(); + char const* last = &first[str.size()]; + + BOOST_TEST(lex::tokenize_and_parse(first, last, word_count, g)); + BOOST_TEST(g.w == 1 && g.c == 1 && g.a == 3); + + return boost::report_errors(); +} diff --git a/src/boost/libs/spirit/test/lex/test.hpp b/src/boost/libs/spirit/test/lex/test.hpp new file mode 100644 index 00000000..f8c48273 --- /dev/null +++ b/src/boost/libs/spirit/test/lex/test.hpp @@ -0,0 +1,92 @@ +// Copyright (c) 2001-2011 Hartmut Kaiser +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#if !defined(BOOST_SPIRIT_LEX_TEST_MAR_23_2007_0721PM) +#define BOOST_SPIRIT_LEX_TEST_MAR_23_2007_0721PM + +#include <boost/variant.hpp> +#include <boost/range/iterator_range.hpp> + +namespace spirit_test +{ + /////////////////////////////////////////////////////////////////////////// + struct display_type + { + template<typename T> + void operator()(T const &) const + { + std::cout << typeid(T).name() << std::endl; + } + + template<typename T> + static void print() + { + std::cout << typeid(T).name() << std::endl; + } + }; + + /////////////////////////////////////////////////////////////////////////// + display_type const display = {}; + + /////////////////////////////////////////////////////////////////////////// + template <typename Iterator> + inline boost::iterator_range<Iterator> const& + get_iterpair(boost::iterator_range<Iterator> const& itp) + { + return itp; + } + + template <typename Iterator, BOOST_VARIANT_ENUM_PARAMS(typename T)> + inline boost::iterator_range<Iterator> const& + get_iterpair(boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> const& v) + { + return boost::get<boost::iterator_range<Iterator> >(v); + } + + /////////////////////////////////////////////////////////////////////////// + template <typename Lexer, typename Char> + inline bool + test(Lexer& lex, Char const* input, std::size_t token_id = 0, + Char const* state = NULL) + { + typedef typename Lexer::iterator_type iterator_type; + typedef std::basic_string<Char> string_type; + + string_type str(input); + typename string_type::iterator it = str.begin(); + + iterator_type first = lex.begin(it, str.end()); + iterator_type last = lex.end(); + + bool r = true; + + if (NULL != state) { + std::size_t stateid = lex.map_state(state); + r = r && (static_cast<unsigned>(~0) != stateid); + first.set_state(stateid); + } + + r = r && lex; + r = r && first != last; + + if (token_id != 0) + r = r && (*first).id() == token_id; + else + r = r && (*first).id() != 0; + + using namespace boost; + + typedef typename Lexer::iterator_type::base_iterator_type iterator; + typedef iterator_range<iterator> iterpair_type; + iterpair_type const& ip = get_iterpair<iterator>((*first).value()); + + r = r && string_type(ip.begin(), ip.end()) == str; + return r && first != last && ++first == last; + } +} + +#endif + + diff --git a/src/boost/libs/spirit/test/lex/test_parser.hpp b/src/boost/libs/spirit/test/lex/test_parser.hpp new file mode 100644 index 00000000..6a23cb34 --- /dev/null +++ b/src/boost/libs/spirit/test/lex/test_parser.hpp @@ -0,0 +1,59 @@ +/*============================================================================= + Copyright (c) 2001-2011 Hartmut Kaiser + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +=============================================================================*/ +#if !defined(BOOST_SPIRIT_TEST_PARSER_SEP_24_2007_0558PM) +#define BOOST_SPIRIT_TEST_PARSER_SEP_24_2007_0558PM + +#include <boost/spirit/include/qi_parse.hpp> +#include <boost/spirit/include/qi_what.hpp> + +namespace spirit_test +{ + template <typename Char, typename Parser, typename Lexer> + inline bool test_parser(Char const* in, Parser const& p, Lexer& lex, + 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); + + std::string str (in); + std::string::iterator it_in = str.begin(); + std::string::iterator end_in = str.end(); + + typedef typename Lexer::iterator_type iterator_type; + + iterator_type iter = lex.begin(it_in, end_in); + iterator_type end = lex.end(); + + return boost::spirit::qi::parse(iter, end, p) + && (!full_match || (iter == end)); + } + + template <typename Char, typename Parser, typename Lexer, typename Skipper> + inline bool test_parser(Char const* in, Parser const& p, Lexer& lex, + 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); + + std::string str (in); + std::string::iterator it_in = str.begin(); + std::string::iterator end_in = str.end(); + + typedef typename Lexer::iterator_type iterator_type; + + iterator_type iter = lex.begin(it_in, end_in); + iterator_type end = lex.end(); + + return boost::spirit::qi::phrase_parse(iter, end, p, s) + && (!full_match || (iter == end)); + } + +} + +#endif diff --git a/src/boost/libs/spirit/test/lex/token_iterpair.cpp b/src/boost/libs/spirit/test/lex/token_iterpair.cpp new file mode 100644 index 00000000..4e05b8e5 --- /dev/null +++ b/src/boost/libs/spirit/test/lex/token_iterpair.cpp @@ -0,0 +1,251 @@ +// 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/lex_lexertl.hpp> +#include <boost/spirit/include/lex_lexertl_position_token.hpp> +#include <boost/spirit/include/phoenix_object.hpp> +#include <boost/spirit/include/phoenix_operator.hpp> +#include <boost/spirit/include/phoenix_container.hpp> + +namespace lex = boost::spirit::lex; +namespace phoenix = boost::phoenix; +namespace mpl = boost::mpl; + +/////////////////////////////////////////////////////////////////////////////// +enum tokenids +{ + ID_INT = 1000, + ID_DOUBLE +}; + +template <typename Lexer> +struct token_definitions : lex::lexer<Lexer> +{ + token_definitions() + { + this->self.add_pattern("HEXDIGIT", "[0-9a-fA-F]"); + this->self.add_pattern("OCTALDIGIT", "[0-7]"); + this->self.add_pattern("DIGIT", "[0-9]"); + + this->self.add_pattern("OPTSIGN", "[-+]?"); + this->self.add_pattern("EXPSTART", "[eE][-+]"); + this->self.add_pattern("EXPONENT", "[eE]{OPTSIGN}{DIGIT}+"); + + // define tokens and associate them with the lexer + int_ = "(0x|0X){HEXDIGIT}+|0{OCTALDIGIT}*|{OPTSIGN}[1-9]{DIGIT}*"; + int_.id(ID_INT); + + double_ = "{OPTSIGN}({DIGIT}*\\.{DIGIT}+|{DIGIT}+\\.){EXPONENT}?|{DIGIT}+{EXPONENT}"; + double_.id(ID_DOUBLE); + + whitespace = "[ \t\n]+"; + + this->self = + double_ + | int_ + | whitespace[ lex::_pass = lex::pass_flags::pass_ignore ] + ; + } + + lex::token_def<lex::omit> int_; + lex::token_def<lex::omit> double_; + lex::token_def<lex::omit> whitespace; +}; + +template <typename Lexer> +struct token_definitions_with_state : lex::lexer<Lexer> +{ + token_definitions_with_state() + { + this->self.add_pattern("HEXDIGIT", "[0-9a-fA-F]"); + this->self.add_pattern("OCTALDIGIT", "[0-7]"); + this->self.add_pattern("DIGIT", "[0-9]"); + + this->self.add_pattern("OPTSIGN", "[-+]?"); + this->self.add_pattern("EXPSTART", "[eE][-+]"); + this->self.add_pattern("EXPONENT", "[eE]{OPTSIGN}{DIGIT}+"); + + this->self.add_state(); + this->self.add_state("INT"); + this->self.add_state("DOUBLE"); + + // define tokens and associate them with the lexer + int_ = "(0x|0X){HEXDIGIT}+|0{OCTALDIGIT}*|{OPTSIGN}[1-9]{DIGIT}*"; + int_.id(ID_INT); + + double_ = "{OPTSIGN}({DIGIT}*\\.{DIGIT}+|{DIGIT}+\\.){EXPONENT}?|{DIGIT}+{EXPONENT}"; + double_.id(ID_DOUBLE); + + whitespace = "[ \t\n]+"; + + this->self("*") = + double_ [ lex::_state = "DOUBLE"] + | int_ [ lex::_state = "INT" ] + | whitespace[ lex::_pass = lex::pass_flags::pass_ignore ] + ; + } + + lex::token_def<lex::omit> int_; + lex::token_def<lex::omit> double_; + lex::token_def<lex::omit> whitespace; +}; + +/////////////////////////////////////////////////////////////////////////////// +template <typename Token> +inline bool +test_token_ids(int const* ids, std::vector<Token> const& tokens) +{ + BOOST_FOREACH(Token const& t, tokens) + { + if (*ids == -1) + return false; // reached end of expected data + + if (t.id() != static_cast<std::size_t>(*ids)) // token id must match + return false; + ++ids; + } + + return (*ids == -1) ? true : false; +} + +template <typename Token> +inline bool +test_token_states(std::size_t const* states, std::vector<Token> const& tokens) +{ + BOOST_FOREACH(Token const& t, tokens) + { + if (*states == std::size_t(-1)) + return false; // reached end of expected data + + if (t.state() != *states) // token state must match + return false; + ++states; + } + + return (*states == std::size_t(-1)) ? true : false; +} + +/////////////////////////////////////////////////////////////////////////////// +struct position_type +{ + std::size_t begin, end; +}; + +template <typename Iterator, typename Token> +inline bool +test_token_positions(Iterator begin, position_type const* positions, + std::vector<Token> const& tokens) +{ + BOOST_FOREACH(Token const& t, tokens) + { + if (positions->begin == std::size_t(-1) && + positions->end == std::size_t(-1)) + { + return false; // reached end of expected data + } + + boost::iterator_range<Iterator> matched = t.matched(); + std::size_t start = std::distance(begin, matched.begin()); + std::size_t end = std::distance(begin, matched.end()); + + // position must match + if (start != positions->begin || end != positions->end) + return false; + + ++positions; + } + + return (positions->begin == std::size_t(-1) && + positions->end == std::size_t(-1)) ? true : false; +} + +/////////////////////////////////////////////////////////////////////////////// +int main() +{ + typedef std::string::iterator base_iterator_type; + std::string input(" 01 1.2 -2 0x3 2.3e6 -3.4"); + int ids[] = { ID_INT, ID_DOUBLE, ID_INT, ID_INT, ID_DOUBLE, ID_DOUBLE, -1 }; + std::size_t states[] = { 0, 1, 2, 1, 1, 2, std::size_t(-1) }; + position_type positions[] = + { + { 1, 3 }, { 4, 7 }, { 8, 10 }, { 11, 14 }, { 15, 20 }, { 21, 25 }, + { std::size_t(-1), std::size_t(-1) } + }; + + // token type: token id, iterator_pair as token value, no state + { + typedef lex::lexertl::token< + base_iterator_type, mpl::vector<>, mpl::false_> token_type; + typedef lex::lexertl::actor_lexer<token_type> lexer_type; + + token_definitions<lexer_type> lexer; + std::vector<token_type> tokens; + base_iterator_type first = input.begin(); + + using phoenix::arg_names::_1; + BOOST_TEST(lex::tokenize(first, input.end(), lexer + , phoenix::push_back(phoenix::ref(tokens), _1))); + + BOOST_TEST(test_token_ids(ids, tokens)); + } + + { + typedef lex::lexertl::position_token< + base_iterator_type, mpl::vector<>, mpl::false_> token_type; + typedef lex::lexertl::actor_lexer<token_type> lexer_type; + + token_definitions<lexer_type> lexer; + std::vector<token_type> tokens; + base_iterator_type first = input.begin(); + + using phoenix::arg_names::_1; + BOOST_TEST(lex::tokenize(first, input.end(), lexer + , phoenix::push_back(phoenix::ref(tokens), _1))); + + BOOST_TEST(test_token_ids(ids, tokens)); + BOOST_TEST(test_token_positions(input.begin(), positions, tokens)); + } + + // token type: holds token id, state, iterator_pair as token value + { + typedef lex::lexertl::token< + base_iterator_type, mpl::vector<>, mpl::true_> token_type; + typedef lex::lexertl::actor_lexer<token_type> lexer_type; + + token_definitions_with_state<lexer_type> lexer; + std::vector<token_type> tokens; + base_iterator_type first = input.begin(); + + using phoenix::arg_names::_1; + BOOST_TEST(lex::tokenize(first, input.end(), lexer + , phoenix::push_back(phoenix::ref(tokens), _1))); + + BOOST_TEST(test_token_ids(ids, tokens)); + BOOST_TEST(test_token_states(states, tokens)); + } + + { + typedef lex::lexertl::position_token< + base_iterator_type, mpl::vector<>, mpl::true_> token_type; + typedef lex::lexertl::actor_lexer<token_type> lexer_type; + + token_definitions_with_state<lexer_type> lexer; + std::vector<token_type> tokens; + base_iterator_type first = input.begin(); + + using phoenix::arg_names::_1; + BOOST_TEST(lex::tokenize(first, input.end(), lexer + , phoenix::push_back(phoenix::ref(tokens), _1))); + + BOOST_TEST(test_token_ids(ids, tokens)); + BOOST_TEST(test_token_states(states, tokens)); + BOOST_TEST(test_token_positions(input.begin(), positions, tokens)); + } + + return boost::report_errors(); +} diff --git a/src/boost/libs/spirit/test/lex/token_moretypes.cpp b/src/boost/libs/spirit/test/lex/token_moretypes.cpp new file mode 100644 index 00000000..7f50527d --- /dev/null +++ b/src/boost/libs/spirit/test/lex/token_moretypes.cpp @@ -0,0 +1,298 @@ +// 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/lex_lexertl.hpp> +#include <boost/spirit/include/lex_lexertl_position_token.hpp> +#include <boost/spirit/include/phoenix_object.hpp> +#include <boost/spirit/include/phoenix_operator.hpp> +#include <boost/spirit/include/phoenix_container.hpp> +#include <boost/spirit/include/qi_numeric.hpp> + +namespace spirit = boost::spirit; +namespace lex = boost::spirit::lex; +namespace phoenix = boost::phoenix; +namespace mpl = boost::mpl; + +/////////////////////////////////////////////////////////////////////////////// +enum tokenids +{ + ID_INT = 1000, + ID_DOUBLE +}; + +template <typename Lexer> +struct token_definitions : lex::lexer<Lexer> +{ + token_definitions() + { + this->self.add_pattern("HEXDIGIT", "[0-9a-fA-F]"); + this->self.add_pattern("OCTALDIGIT", "[0-7]"); + this->self.add_pattern("DIGIT", "[0-9]"); + + this->self.add_pattern("OPTSIGN", "[-+]?"); + this->self.add_pattern("EXPSTART", "[eE][-+]"); + this->self.add_pattern("EXPONENT", "[eE]{OPTSIGN}{DIGIT}+"); + + // define tokens and associate them with the lexer + int_ = "(0x|0X){HEXDIGIT}+|0{OCTALDIGIT}*|{OPTSIGN}[1-9]{DIGIT}*"; + int_.id(ID_INT); + + double_ = "{OPTSIGN}({DIGIT}*\\.{DIGIT}+|{DIGIT}+\\.){EXPONENT}?|{DIGIT}+{EXPONENT}"; + double_.id(ID_DOUBLE); + + whitespace = "[ \t\n]+"; + + this->self = + double_ + | int_ + | whitespace[ lex::_pass = lex::pass_flags::pass_ignore ] + ; + } + + lex::token_def<int> int_; + lex::token_def<double> double_; + lex::token_def<lex::omit> whitespace; +}; + +template <typename Lexer> +struct token_definitions_with_state : lex::lexer<Lexer> +{ + token_definitions_with_state() + { + this->self.add_pattern("HEXDIGIT", "[0-9a-fA-F]"); + this->self.add_pattern("OCTALDIGIT", "[0-7]"); + this->self.add_pattern("DIGIT", "[0-9]"); + + this->self.add_pattern("OPTSIGN", "[-+]?"); + this->self.add_pattern("EXPSTART", "[eE][-+]"); + this->self.add_pattern("EXPONENT", "[eE]{OPTSIGN}{DIGIT}+"); + + this->self.add_state(); + this->self.add_state("INT"); + this->self.add_state("DOUBLE"); + + // define tokens and associate them with the lexer + int_ = "(0x|0X){HEXDIGIT}+|0{OCTALDIGIT}*|{OPTSIGN}[1-9]{DIGIT}*"; + int_.id(ID_INT); + + double_ = "{OPTSIGN}({DIGIT}*\\.{DIGIT}+|{DIGIT}+\\.){EXPONENT}?|{DIGIT}+{EXPONENT}"; + double_.id(ID_DOUBLE); + + whitespace = "[ \t\n]+"; + + this->self("*") = + double_ [ lex::_state = "DOUBLE"] + | int_ [ lex::_state = "INT" ] + | whitespace[ lex::_pass = lex::pass_flags::pass_ignore ] + ; + } + + lex::token_def<int> int_; + lex::token_def<double> double_; + lex::token_def<lex::omit> whitespace; +}; + +/////////////////////////////////////////////////////////////////////////////// +template <typename Token> +inline bool +test_token_ids(int const* ids, std::vector<Token> const& tokens) +{ + BOOST_FOREACH(Token const& t, tokens) + { + if (*ids == -1) + return false; // reached end of expected data + + if (t.id() != static_cast<std::size_t>(*ids)) // token id must match + return false; + + ++ids; + } + + return (*ids == -1) ? true : false; +} + +/////////////////////////////////////////////////////////////////////////////// +template <typename Token> +inline bool +test_token_states(std::size_t const* states, std::vector<Token> const& tokens) +{ + BOOST_FOREACH(Token const& t, tokens) + { + if (*states == std::size_t(-1)) + return false; // reached end of expected data + + if (t.state() != *states) // token state must match + return false; + + ++states; + } + + return (*states == std::size_t(-1)) ? true : false; +} + +/////////////////////////////////////////////////////////////////////////////// +struct position_type +{ + std::size_t begin, end; +}; + +template <typename Iterator, typename Token> +inline bool +test_token_positions(Iterator begin, position_type const* positions, + std::vector<Token> const& tokens) +{ + BOOST_FOREACH(Token const& t, tokens) + { + if (positions->begin == std::size_t(-1) && + positions->end == std::size_t(-1)) + { + return false; // reached end of expected data + } + + boost::iterator_range<Iterator> matched = t.matched(); + std::size_t start = std::distance(begin, matched.begin()); + std::size_t end = std::distance(begin, matched.end()); + + // position must match + if (start != positions->begin || end != positions->end) + return false; + + ++positions; + } + + return (positions->begin == std::size_t(-1) && + positions->end == std::size_t(-1)) ? true : false; +} + +/////////////////////////////////////////////////////////////////////////////// +template <typename T, typename Token> +inline bool +test_token_values(boost::optional<T> const* values, std::vector<Token> const& tokens) +{ + BOOST_FOREACH(Token const& t, tokens) + { + if (values->is_initialized() && values->get() == 0) + return false; // reached end of expected data + + if (values->is_initialized()) { + T val; + spirit::traits::assign_to(t, val); + if (val != values->get()) // token value must match + return false; + } + + ++values; + } + + return (values->is_initialized() && values->get() == 0) ? true : false; +} + +/////////////////////////////////////////////////////////////////////////////// +int main() +{ + using boost::none; + typedef std::string::iterator base_iterator_type; + std::string input(" 01 1.2 -2 03 2.3e6 -3.4"); + int ids[] = { ID_INT, ID_DOUBLE, ID_INT, ID_INT, ID_DOUBLE, ID_DOUBLE, -1 }; + std::size_t states[] = { 0, 1, 2, 1, 1, 2, std::size_t(-1) }; + position_type positions[] = + { + { 1, 3 }, { 4, 7 }, { 8, 10 }, { 11, 13 }, { 15, 20 }, { 21, 25 }, + { std::size_t(-1), std::size_t(-1) } + }; + boost::optional<int> ivalues[] = { + 1, none, -2, + 3, none, none, + 0 + }; + boost::optional<double> dvalues[] = { + none, 1.2, none, + none, 2.3e6, -3.4, + 0.0 + }; + + // token type: token id, iterator_pair as token value, no state + { + typedef lex::lexertl::token< + base_iterator_type, mpl::vector<double, int>, mpl::false_> token_type; + typedef lex::lexertl::actor_lexer<token_type> lexer_type; + + token_definitions<lexer_type> lexer; + std::vector<token_type> tokens; + base_iterator_type first = input.begin(); + + using phoenix::arg_names::_1; + BOOST_TEST(lex::tokenize(first, input.end(), lexer + , phoenix::push_back(phoenix::ref(tokens), _1))); + + BOOST_TEST(test_token_ids(ids, tokens)); + BOOST_TEST(test_token_values(ivalues, tokens)); + BOOST_TEST(test_token_values(dvalues, tokens)); + } + + { + typedef lex::lexertl::position_token< + base_iterator_type, mpl::vector<double, int>, mpl::false_> token_type; + typedef lex::lexertl::actor_lexer<token_type> lexer_type; + + token_definitions<lexer_type> lexer; + std::vector<token_type> tokens; + base_iterator_type first = input.begin(); + + using phoenix::arg_names::_1; + BOOST_TEST(lex::tokenize(first, input.end(), lexer + , phoenix::push_back(phoenix::ref(tokens), _1))); + + BOOST_TEST(test_token_ids(ids, tokens)); + BOOST_TEST(test_token_positions(input.begin(), positions, tokens)); + BOOST_TEST(test_token_values(ivalues, tokens)); + BOOST_TEST(test_token_values(dvalues, tokens)); + } + + // token type: holds token id, state, iterator_pair as token value + { + typedef lex::lexertl::token< + base_iterator_type, mpl::vector<double, int>, mpl::true_> token_type; + typedef lex::lexertl::actor_lexer<token_type> lexer_type; + + token_definitions_with_state<lexer_type> lexer; + std::vector<token_type> tokens; + base_iterator_type first = input.begin(); + + using phoenix::arg_names::_1; + BOOST_TEST(lex::tokenize(first, input.end(), lexer + , phoenix::push_back(phoenix::ref(tokens), _1))); + + BOOST_TEST(test_token_ids(ids, tokens)); + BOOST_TEST(test_token_states(states, tokens)); + BOOST_TEST(test_token_values(ivalues, tokens)); + BOOST_TEST(test_token_values(dvalues, tokens)); + } + + { + typedef lex::lexertl::position_token< + base_iterator_type, mpl::vector<double, int>, mpl::true_> token_type; + typedef lex::lexertl::actor_lexer<token_type> lexer_type; + + token_definitions_with_state<lexer_type> lexer; + std::vector<token_type> tokens; + base_iterator_type first = input.begin(); + + using phoenix::arg_names::_1; + BOOST_TEST(lex::tokenize(first, input.end(), lexer + , phoenix::push_back(phoenix::ref(tokens), _1))); + + BOOST_TEST(test_token_ids(ids, tokens)); + BOOST_TEST(test_token_states(states, tokens)); + BOOST_TEST(test_token_positions(input.begin(), positions, tokens)); + BOOST_TEST(test_token_values(ivalues, tokens)); + BOOST_TEST(test_token_values(dvalues, tokens)); + } + + return boost::report_errors(); +} diff --git a/src/boost/libs/spirit/test/lex/token_omit.cpp b/src/boost/libs/spirit/test/lex/token_omit.cpp new file mode 100644 index 00000000..9b38591a --- /dev/null +++ b/src/boost/libs/spirit/test/lex/token_omit.cpp @@ -0,0 +1,254 @@ +// 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/lex_lexertl.hpp> +#include <boost/spirit/include/lex_lexertl_position_token.hpp> +#include <boost/spirit/include/phoenix_object.hpp> +#include <boost/spirit/include/phoenix_operator.hpp> +#include <boost/spirit/include/phoenix_container.hpp> + +namespace lex = boost::spirit::lex; +namespace phoenix = boost::phoenix; +namespace mpl = boost::mpl; + +/////////////////////////////////////////////////////////////////////////////// +enum tokenids +{ + ID_INT = 1000, + ID_DOUBLE +}; + +template <typename Lexer> +struct token_definitions : lex::lexer<Lexer> +{ + token_definitions() + { + this->self.add_pattern("HEXDIGIT", "[0-9a-fA-F]"); + this->self.add_pattern("OCTALDIGIT", "[0-7]"); + this->self.add_pattern("DIGIT", "[0-9]"); + + this->self.add_pattern("OPTSIGN", "[-+]?"); + this->self.add_pattern("EXPSTART", "[eE][-+]"); + this->self.add_pattern("EXPONENT", "[eE]{OPTSIGN}{DIGIT}+"); + + // define tokens and associate them with the lexer + int_ = "(0x|0X){HEXDIGIT}+|0{OCTALDIGIT}*|{OPTSIGN}[1-9]{DIGIT}*"; + int_.id(ID_INT); + + double_ = "{OPTSIGN}({DIGIT}*\\.{DIGIT}+|{DIGIT}+\\.){EXPONENT}?|{DIGIT}+{EXPONENT}"; + double_.id(ID_DOUBLE); + + whitespace = "[ \t\n]+"; + + this->self = + double_ + | int_ + | whitespace[ lex::_pass = lex::pass_flags::pass_ignore ] + ; + } + + lex::token_def<lex::omit> int_; + lex::token_def<lex::omit> double_; + lex::token_def<lex::omit> whitespace; +}; + +template <typename Lexer> +struct token_definitions_with_state : lex::lexer<Lexer> +{ + token_definitions_with_state() + { + this->self.add_pattern("HEXDIGIT", "[0-9a-fA-F]"); + this->self.add_pattern("OCTALDIGIT", "[0-7]"); + this->self.add_pattern("DIGIT", "[0-9]"); + + this->self.add_pattern("OPTSIGN", "[-+]?"); + this->self.add_pattern("EXPSTART", "[eE][-+]"); + this->self.add_pattern("EXPONENT", "[eE]{OPTSIGN}{DIGIT}+"); + + this->self.add_state(); + this->self.add_state("INT"); + this->self.add_state("DOUBLE"); + + // define tokens and associate them with the lexer + int_ = "(0x|0X){HEXDIGIT}+|0{OCTALDIGIT}*|{OPTSIGN}[1-9]{DIGIT}*"; + int_.id(ID_INT); + + double_ = "{OPTSIGN}({DIGIT}*\\.{DIGIT}+|{DIGIT}+\\.){EXPONENT}?|{DIGIT}+{EXPONENT}"; + double_.id(ID_DOUBLE); + + whitespace = "[ \t\n]+"; + + this->self("*") = + double_ [ lex::_state = "DOUBLE"] + | int_ [ lex::_state = "INT" ] + | whitespace[ lex::_pass = lex::pass_flags::pass_ignore ] + ; + } + + lex::token_def<lex::omit> int_; + lex::token_def<lex::omit> double_; + lex::token_def<lex::omit> whitespace; +}; + +/////////////////////////////////////////////////////////////////////////////// +template <typename Token> +inline bool +test_token_ids(int const* ids, std::vector<Token> const& tokens) +{ + BOOST_FOREACH(Token const& t, tokens) + { + if (*ids == -1) + return false; // reached end of expected data + + if (t.id() != static_cast<std::size_t>(*ids)) // token id must match + return false; + + ++ids; + } + + return (*ids == -1) ? true : false; +} + +/////////////////////////////////////////////////////////////////////////////// +template <typename Token> +inline bool +test_token_states(std::size_t const* states, std::vector<Token> const& tokens) +{ + BOOST_FOREACH(Token const& t, tokens) + { + if (*states == std::size_t(-1)) + return false; // reached end of expected data + + if (t.state() != *states) // token state must match + return false; + + ++states; + } + + return (*states == std::size_t(-1)) ? true : false; +} + +/////////////////////////////////////////////////////////////////////////////// +struct position_type +{ + std::size_t begin, end; +}; + +template <typename Iterator, typename Token> +inline bool +test_token_positions(Iterator begin, position_type const* positions, + std::vector<Token> const& tokens) +{ + BOOST_FOREACH(Token const& t, tokens) + { + if (positions->begin == std::size_t(-1) && + positions->end == std::size_t(-1)) + { + return false; // reached end of expected data + } + + boost::iterator_range<Iterator> matched = t.matched(); + std::size_t start = std::distance(begin, matched.begin()); + std::size_t end = std::distance(begin, matched.end()); + + // position must match + if (start != positions->begin || end != positions->end) + return false; + + ++positions; + } + + return (positions->begin == std::size_t(-1) && + positions->end == std::size_t(-1)) ? true : false; +} + +/////////////////////////////////////////////////////////////////////////////// +int main() +{ + typedef std::string::iterator base_iterator_type; + std::string input(" 01 1.2 -2 0x3 2.3e6 -3.4"); + int ids[] = { ID_INT, ID_DOUBLE, ID_INT, ID_INT, ID_DOUBLE, ID_DOUBLE, -1 }; + std::size_t states[] = { 0, 1, 2, 1, 1, 2, std::size_t(-1) }; + position_type positions[] = + { + { 1, 3 }, { 4, 7 }, { 8, 10 }, { 11, 14 }, { 15, 20 }, { 21, 25 }, + { std::size_t(-1), std::size_t(-1) } + }; + + // minimal token type: holds just token id, no state, no value + { + typedef lex::lexertl::token< + base_iterator_type, lex::omit, mpl::false_> token_type; + typedef lex::lexertl::actor_lexer<token_type> lexer_type; + + token_definitions<lexer_type> lexer; + std::vector<token_type> tokens; + base_iterator_type first = input.begin(); + + using phoenix::arg_names::_1; + BOOST_TEST(lex::tokenize(first, input.end(), lexer + , phoenix::push_back(phoenix::ref(tokens), _1))); + + BOOST_TEST(test_token_ids(ids, tokens)); + } + + { + typedef lex::lexertl::position_token< + base_iterator_type, lex::omit, mpl::false_> token_type; + typedef lex::lexertl::actor_lexer<token_type> lexer_type; + + token_definitions<lexer_type> lexer; + std::vector<token_type> tokens; + base_iterator_type first = input.begin(); + + using phoenix::arg_names::_1; + BOOST_TEST(lex::tokenize(first, input.end(), lexer + , phoenix::push_back(phoenix::ref(tokens), _1))); + + BOOST_TEST(test_token_ids(ids, tokens)); + BOOST_TEST(test_token_positions(input.begin(), positions, tokens)); + } + + // minimal token type: holds just token id and state, no value + { + typedef lex::lexertl::token< + base_iterator_type, lex::omit, mpl::true_> token_type; + typedef lex::lexertl::actor_lexer<token_type> lexer_type; + + token_definitions_with_state<lexer_type> lexer; + std::vector<token_type> tokens; + base_iterator_type first = input.begin(); + + using phoenix::arg_names::_1; + BOOST_TEST(lex::tokenize(first, input.end(), lexer + , phoenix::push_back(phoenix::ref(tokens), _1))); + + BOOST_TEST(test_token_ids(ids, tokens)); + BOOST_TEST(test_token_states(states, tokens)); + } + + { + typedef lex::lexertl::position_token< + base_iterator_type, lex::omit, mpl::true_> token_type; + typedef lex::lexertl::actor_lexer<token_type> lexer_type; + + token_definitions_with_state<lexer_type> lexer; + std::vector<token_type> tokens; + base_iterator_type first = input.begin(); + + using phoenix::arg_names::_1; + BOOST_TEST(lex::tokenize(first, input.end(), lexer + , phoenix::push_back(phoenix::ref(tokens), _1))); + + BOOST_TEST(test_token_ids(ids, tokens)); + BOOST_TEST(test_token_states(states, tokens)); + BOOST_TEST(test_token_positions(input.begin(), positions, tokens)); + } + + return boost::report_errors(); +} diff --git a/src/boost/libs/spirit/test/lex/token_onetype.cpp b/src/boost/libs/spirit/test/lex/token_onetype.cpp new file mode 100644 index 00000000..62f0f18b --- /dev/null +++ b/src/boost/libs/spirit/test/lex/token_onetype.cpp @@ -0,0 +1,282 @@ +// 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/lex_lexertl.hpp> +#include <boost/spirit/include/lex_lexertl_position_token.hpp> +#include <boost/spirit/include/phoenix_object.hpp> +#include <boost/spirit/include/phoenix_operator.hpp> +#include <boost/spirit/include/phoenix_container.hpp> +#include <boost/spirit/include/qi_numeric.hpp> + +namespace spirit = boost::spirit; +namespace lex = boost::spirit::lex; +namespace phoenix = boost::phoenix; +namespace mpl = boost::mpl; + +/////////////////////////////////////////////////////////////////////////////// +enum tokenids +{ + ID_INT = 1000, + ID_DOUBLE +}; + +template <typename Lexer> +struct token_definitions : lex::lexer<Lexer> +{ + token_definitions() + { + this->self.add_pattern("HEXDIGIT", "[0-9a-fA-F]"); + this->self.add_pattern("OCTALDIGIT", "[0-7]"); + this->self.add_pattern("DIGIT", "[0-9]"); + + this->self.add_pattern("OPTSIGN", "[-+]?"); + this->self.add_pattern("EXPSTART", "[eE][-+]"); + this->self.add_pattern("EXPONENT", "[eE]{OPTSIGN}{DIGIT}+"); + + // define tokens and associate them with the lexer + int_ = "{OPTSIGN}[1-9]{DIGIT}*"; + int_.id(ID_INT); + + double_ = "{OPTSIGN}({DIGIT}*\\.{DIGIT}+|{DIGIT}+\\.){EXPONENT}?|{DIGIT}+{EXPONENT}"; + double_.id(ID_DOUBLE); + + whitespace = "[ \t\n]+"; + + this->self = + double_ + | int_ + | whitespace[ lex::_pass = lex::pass_flags::pass_ignore ] + ; + } + + lex::token_def<double> int_; + lex::token_def<double> double_; + lex::token_def<lex::omit> whitespace; +}; + +template <typename Lexer> +struct token_definitions_with_state : lex::lexer<Lexer> +{ + token_definitions_with_state() + { + this->self.add_pattern("HEXDIGIT", "[0-9a-fA-F]"); + this->self.add_pattern("OCTALDIGIT", "[0-7]"); + this->self.add_pattern("DIGIT", "[0-9]"); + + this->self.add_pattern("OPTSIGN", "[-+]?"); + this->self.add_pattern("EXPSTART", "[eE][-+]"); + this->self.add_pattern("EXPONENT", "[eE]{OPTSIGN}{DIGIT}+"); + + this->self.add_state(); + this->self.add_state("INT"); + this->self.add_state("DOUBLE"); + + // define tokens and associate them with the lexer + int_ = "{OPTSIGN}[1-9]{DIGIT}*"; + int_.id(ID_INT); + + double_ = "{OPTSIGN}({DIGIT}*\\.{DIGIT}+|{DIGIT}+\\.){EXPONENT}?|{DIGIT}+{EXPONENT}"; + double_.id(ID_DOUBLE); + + whitespace = "[ \t\n]+"; + + this->self("*") = + double_ [ lex::_state = "DOUBLE"] + | int_ [ lex::_state = "INT" ] + | whitespace[ lex::_pass = lex::pass_flags::pass_ignore ] + ; + } + + lex::token_def<double> int_; + lex::token_def<double> double_; + lex::token_def<lex::omit> whitespace; +}; + +/////////////////////////////////////////////////////////////////////////////// +template <typename Token> +inline bool +test_token_ids(int const* ids, std::vector<Token> const& tokens) +{ + BOOST_FOREACH(Token const& t, tokens) + { + if (*ids == -1) + return false; // reached end of expected data + + if (t.id() != static_cast<std::size_t>(*ids)) // token id must match + return false; + + ++ids; + } + + return (*ids == -1) ? true : false; +} + +/////////////////////////////////////////////////////////////////////////////// +template <typename Token> +inline bool +test_token_states(std::size_t const* states, std::vector<Token> const& tokens) +{ + BOOST_FOREACH(Token const& t, tokens) + { + if (*states == std::size_t(-1)) + return false; // reached end of expected data + + if (t.state() != *states) // token state must match + return false; + + ++states; + } + + return (*states == std::size_t(-1)) ? true : false; +} + +/////////////////////////////////////////////////////////////////////////////// +struct position_type +{ + std::size_t begin, end; +}; + +template <typename Iterator, typename Token> +inline bool +test_token_positions(Iterator begin, position_type const* positions, + std::vector<Token> const& tokens) +{ + BOOST_FOREACH(Token const& t, tokens) + { + if (positions->begin == std::size_t(-1) && + positions->end == std::size_t(-1)) + { + return false; // reached end of expected data + } + + boost::iterator_range<Iterator> matched = t.matched(); + std::size_t start = std::distance(begin, matched.begin()); + std::size_t end = std::distance(begin, matched.end()); + + // position must match + if (start != positions->begin || end != positions->end) + return false; + + ++positions; + } + + return (positions->begin == std::size_t(-1) && + positions->end == std::size_t(-1)) ? true : false; +} + +/////////////////////////////////////////////////////////////////////////////// +template <typename Token> +inline bool +test_token_values(double const* values, std::vector<Token> const& tokens) +{ + BOOST_FOREACH(Token const& t, tokens) + { + if (*values == 0.0) + return false; // reached end of expected data + + double val; + spirit::traits::assign_to(t, val); + if (val != *values) // token value must match + return false; + + ++values; + } + + return (*values == 0.0) ? true : false; +} + +/////////////////////////////////////////////////////////////////////////////// +int main() +{ + typedef std::string::iterator base_iterator_type; + std::string input(" 1 1.2 -2 3 2.3e6 -3.4"); + int ids[] = { ID_INT, ID_DOUBLE, ID_INT, ID_INT, ID_DOUBLE, ID_DOUBLE, -1 }; + std::size_t states[] = { 0, 1, 2, 1, 1, 2, std::size_t(-1) }; + position_type positions[] = + { + { 2, 3 }, { 4, 7 }, { 8, 10 }, { 13, 14 }, { 15, 20 }, { 21, 25 }, + { std::size_t(-1), std::size_t(-1) } + }; + double values[] = { 1.0, 1.2, -2.0, 3.0, 2.3e6, -3.4, 0.0 }; + + // token type: token id, iterator_pair as token value, no state + { + typedef lex::lexertl::token< + base_iterator_type, mpl::vector<double>, mpl::false_> token_type; + typedef lex::lexertl::actor_lexer<token_type> lexer_type; + + token_definitions<lexer_type> lexer; + std::vector<token_type> tokens; + base_iterator_type first = input.begin(); + + using phoenix::arg_names::_1; + BOOST_TEST(lex::tokenize(first, input.end(), lexer + , phoenix::push_back(phoenix::ref(tokens), _1))); + + BOOST_TEST(test_token_ids(ids, tokens)); + BOOST_TEST(test_token_values(values, tokens)); + } + + { + typedef lex::lexertl::position_token< + base_iterator_type, mpl::vector<double>, mpl::false_> token_type; + typedef lex::lexertl::actor_lexer<token_type> lexer_type; + + token_definitions<lexer_type> lexer; + std::vector<token_type> tokens; + base_iterator_type first = input.begin(); + + using phoenix::arg_names::_1; + BOOST_TEST(lex::tokenize(first, input.end(), lexer + , phoenix::push_back(phoenix::ref(tokens), _1))); + + BOOST_TEST(test_token_ids(ids, tokens)); + BOOST_TEST(test_token_positions(input.begin(), positions, tokens)); + BOOST_TEST(test_token_values(values, tokens)); + } + + // token type: holds token id, state, iterator_pair as token value + { + typedef lex::lexertl::token< + base_iterator_type, mpl::vector<double>, mpl::true_> token_type; + typedef lex::lexertl::actor_lexer<token_type> lexer_type; + + token_definitions_with_state<lexer_type> lexer; + std::vector<token_type> tokens; + base_iterator_type first = input.begin(); + + using phoenix::arg_names::_1; + BOOST_TEST(lex::tokenize(first, input.end(), lexer + , phoenix::push_back(phoenix::ref(tokens), _1))); + + BOOST_TEST(test_token_ids(ids, tokens)); + BOOST_TEST(test_token_states(states, tokens)); + BOOST_TEST(test_token_values(values, tokens)); + } + + { + typedef lex::lexertl::position_token< + base_iterator_type, mpl::vector<double>, mpl::true_> token_type; + typedef lex::lexertl::actor_lexer<token_type> lexer_type; + + token_definitions_with_state<lexer_type> lexer; + std::vector<token_type> tokens; + base_iterator_type first = input.begin(); + + using phoenix::arg_names::_1; + BOOST_TEST(lex::tokenize(first, input.end(), lexer + , phoenix::push_back(phoenix::ref(tokens), _1))); + + BOOST_TEST(test_token_ids(ids, tokens)); + BOOST_TEST(test_token_states(states, tokens)); + BOOST_TEST(test_token_positions(input.begin(), positions, tokens)); + BOOST_TEST(test_token_values(values, tokens)); + } + + return boost::report_errors(); +} 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(); +} diff --git a/src/boost/libs/spirit/test/support/Jamfile b/src/boost/libs/spirit/test/support/Jamfile new file mode 100644 index 00000000..cd928e94 --- /dev/null +++ b/src/boost/libs/spirit/test/support/Jamfile @@ -0,0 +1,58 @@ +#============================================================================== +# Copyright (c) 2001-2011 Joel de Guzman +# Copyright (c) 2001-2012 Hartmut Kaiser +# Copyright (c) 2011 Bryce Lelbach +# +# Use, modification and distribution is subject to the Boost Software +# License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +# http://www.boost.org/LICENSE_1_0.txt) +#============================================================================== + +import testing ; + +############################################################################### + +project spirit-support + : requirements + <include>. + <c++-template-depth>512 + ; + +############################################################################### + +local subproject-name = support ; + +rule run ( sources + : args * : input-files * + : requirements * : target-name ? : default-build * ) +{ + target-name ?= $(subproject-name)_$(sources[1]:D=:S=) ; + return [ testing.run $(sources) : $(args) : $(input-files) + : $(requirements) : $(target-name) : $(default-build) ] ; +} + +rule compile ( sources + : requirements * : target-name ? ) +{ + target-name ?= $(subproject-name)_$(sources[1]:D=:S=) ; + return [ testing.compile $(sources) + : $(requirements) : $(target-name) ] ; +} + +rule compile-fail ( sources + : requirements * : target-name ? ) +{ + target-name ?= $(subproject-name)_$(sources[1]:D=:S=) ; + return [ testing.compile-fail $(sources) + : $(requirements) : $(target-name) ] ; +} + +############################################################################### + +run istream_iterator_basic.cpp ; +run unused_type.cpp ; +run utree.cpp ; +run utree_debug.cpp ; + +compile regression_multi_pass_functor.cpp ; +compile regression_multi_pass_position_iterator.cpp ; +run regression_multi_pass_error_handler.cpp ; +run regression_multi_pass_parse.cpp ; +run regression_line_pos_iterator.cpp ; diff --git a/src/boost/libs/spirit/test/support/istream_iterator_basic.cpp b/src/boost/libs/spirit/test/support/istream_iterator_basic.cpp new file mode 100644 index 00000000..136a38f1 --- /dev/null +++ b/src/boost/libs/spirit/test/support/istream_iterator_basic.cpp @@ -0,0 +1,60 @@ +// Copyright (c) 2016 Jeffrey E. Trull +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// A series of simple tests for the istream_iterator + +#include <boost/detail/lightweight_test.hpp> + +#include <sstream> + +#include <boost/spirit/include/support_istream_iterator.hpp> + +int main() +{ + std::stringstream ss("HELO\n"); + boost::spirit::istream_iterator it(ss); + + // Check iterator concepts + boost::spirit::istream_iterator it2(it); // CopyConstructible + BOOST_TEST( it2 == it ); // EqualityComparable + BOOST_TEST( *it2 == 'H' ); + + boost::spirit::istream_iterator end; // DefaultConstructible + BOOST_TEST( it != end ); + it = end; // CopyAssignable + BOOST_TEST( it == end ); + + std::swap(it, it2); // Swappable + BOOST_TEST( it2 == end ); + BOOST_TEST( *it == 'H' ); + + ++it; + BOOST_TEST( *it == 'E' ); + BOOST_TEST( *it++ == 'E' ); + + // "Incrementing a copy of a does not change the value read from a" + boost::spirit::istream_iterator it3 = it; + BOOST_TEST( *it == 'L' ); + BOOST_TEST( *it3 == 'L' ); + ++it; + BOOST_TEST( *it == 'O' ); + BOOST_TEST( *it3 == 'L' ); + + it3 = it; + // "a == b implies ++a == ++b" + BOOST_TEST( ++it3 == ++it ); + + // Usage of const iterators + boost::spirit::istream_iterator const itc = it; + BOOST_TEST( itc == it ); + BOOST_TEST( *itc == *it ); + ++it; + BOOST_TEST( itc != it ); + + // Skipping le/gt comparisons as unclear what they are for in forward iterators... + + return boost::report_errors(); +} +// Destructible diff --git a/src/boost/libs/spirit/test/support/regression_line_pos_iterator.cpp b/src/boost/libs/spirit/test/support/regression_line_pos_iterator.cpp new file mode 100644 index 00000000..4c6ca79f --- /dev/null +++ b/src/boost/libs/spirit/test/support/regression_line_pos_iterator.cpp @@ -0,0 +1,149 @@ +// Copyright (c) 2014 Tomoki Imai +// +// Distributed under the 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/support_line_pos_iterator.hpp> +#include <boost/detail/lightweight_test.hpp> +#include <boost/assign.hpp> +#include <iostream> +#include <string> +#include <vector> + +struct validation { + validation() + : line(), column(), current(), is_defined(false) { + } + + validation(size_t line, size_t column, std::string current) + : line(line), column(column), current(current), is_defined(true) { + } + + size_t line; + size_t column; + std::string current; + bool is_defined; +}; + +typedef std::vector<validation> validations; + +void test(std::string const& input, validations const& validations) { + typedef boost::spirit::line_pos_iterator<std::string::const_iterator> pos_iterator_t; + + pos_iterator_t const input_begin(input.begin()); + pos_iterator_t const input_end(input.end()); + pos_iterator_t position(input_begin); + validations::const_iterator expected = validations.begin(); + + for (; position != input_end && expected != validations.end(); ++position, ++expected) { + if (!expected->is_defined) + continue; + + boost::iterator_range<pos_iterator_t> const range = get_current_line(input_begin, position, input_end); + std::string const current(range.begin(), range.end()); + + BOOST_TEST_EQ(expected->line, get_line(position)); + BOOST_TEST_EQ(expected->column, get_column(input_begin, position)); + BOOST_TEST_EQ(expected->current, current); + } + + BOOST_TEST(position == input_end); + BOOST_TEST(expected == validations.end()); +} + +// LR and CR + +void testLRandCR(std::string const& line_break) { + std::string const input = line_break + line_break; + validations const validations = boost::assign::list_of<validation> + (1,1,"")() + (2,1,"")(); + test(input, validations); +} + +void testLRandCR_foo_bar_git(std::string const& line_break) { + std::string const input = "foo" + line_break + "bar" + line_break + "git"; + validations const validations = boost::assign::list_of<validation> + (1,1,"foo")(1,2,"foo")(1,3,"foo")(1,4,"foo")() + (2,1,"bar")(2,2,"bar")(2,3,"bar")(2,4,"bar")() + (3,1,"git")(3,2,"git")(3,3,"git"); + test(input, validations); +} + +void testLRandCR_bar_git(std::string const& line_break) { + std::string const input = line_break + "bar" + line_break + "git"; + validations const validations = boost::assign::list_of<validation> + (1,1,"")() + (2,1,"bar")(2,2,"bar")(2,3,"bar")(2,4,"bar")() + (3,1,"git")(3,2,"git")(3,3,"git"); + test(input, validations); +} + +void testLRandCR_foo_bar(std::string const& line_break) { + std::string const input = "foo" + line_break + "bar" + line_break; + validations const validations = boost::assign::list_of<validation> + (1,1,"foo")(1,2,"foo")(1,3,"foo")(1,4,"foo")() + (2,1,"bar")(2,2,"bar")(2,3,"bar")(2,4,"bar")(); + test(input, validations); +} + +// LR or CR + +void testLRorCR(std::string const& line_break) { + std::string const input = line_break + line_break; + validations const validations = boost::assign::list_of<validation> + (1,1,"") + (2,1,""); + test(input, validations); +} + +void testLRorCR_foo_bar_git(std::string const& line_break) { + std::string const input = "foo" + line_break + "bar" + line_break + "git"; + validations const validations = boost::assign::list_of<validation> + (1,1,"foo")(1,2,"foo")(1,3,"foo")(1,4,"foo") + (2,1,"bar")(2,2,"bar")(2,3,"bar")(2,4,"bar") + (3,1,"git")(3,2,"git")(3,3,"git"); + test(input, validations); +} + +void testLRorCR_bar_git(std::string const& line_break) { + std::string const input = line_break + "bar" + line_break + "git"; + validations const validations = boost::assign::list_of<validation> + (1,1,"") + (2,1,"bar")(2,2,"bar")(2,3,"bar")(2,4,"bar") + (3,1,"git")(3,2,"git")(3,3,"git"); + test(input, validations); +} + +void testLRorCR_foo_bar(std::string const& line_break) { + std::string const input = "foo" + line_break + "bar" + line_break; + validations const validations = boost::assign::list_of<validation> + (1,1,"foo")(1,2,"foo")(1,3,"foo")(1,4,"foo") + (2,1,"bar")(2,2,"bar")(2,3,"bar")(2,4,"bar"); + test(input, validations); +} + +int main() +{ + testLRandCR("\r\n"); + testLRandCR_foo_bar_git("\r\n"); + testLRandCR_bar_git("\r\n"); + testLRandCR_foo_bar("\r\n"); + + testLRandCR("\n\r"); + testLRandCR_foo_bar_git("\n\r"); + testLRandCR_bar_git("\n\r"); + testLRandCR_foo_bar("\n\r"); + + testLRorCR("\r"); + testLRorCR_foo_bar_git("\r"); + testLRorCR_bar_git("\r"); + testLRorCR_foo_bar("\r"); + + testLRorCR("\n"); + testLRorCR_foo_bar_git("\n"); + testLRorCR_bar_git("\n"); + testLRorCR_foo_bar("\n"); + + return boost::report_errors(); +} diff --git a/src/boost/libs/spirit/test/support/regression_multi_pass_error_handler.cpp b/src/boost/libs/spirit/test/support/regression_multi_pass_error_handler.cpp new file mode 100644 index 00000000..dd2eb9c6 --- /dev/null +++ b/src/boost/libs/spirit/test/support/regression_multi_pass_error_handler.cpp @@ -0,0 +1,65 @@ +// Copyright (c) 2001-2010 Hartmut Kaiser +// Copyright (c) 2011 Laurent Gomila +// +// Distributed under the 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/phoenix_operator.hpp> +#include <boost/spirit/include/support_multi_pass.hpp> +#include <sstream> +#include <iostream> +#include <iterator> +#include <string> + +using namespace boost::spirit; +using namespace boost; + +int main() +{ + { + std::string input("5x"); + std::istringstream iss(input); + + typedef std::istreambuf_iterator<char> base_iterator_type; + typedef multi_pass<base_iterator_type> iterator_type; + + iterator_type first = make_default_multi_pass(base_iterator_type(iss)); + iterator_type last = make_default_multi_pass(base_iterator_type()); + + std::ostringstream oss; + + qi::rule<iterator_type> r = qi::int_ > qi::int_; + qi::on_error<qi::fail>(r, phoenix::ref(oss) << phoenix::val("error")); + + BOOST_TEST(!qi::parse(first, last, r)); + BOOST_TEST(oss.str() == "error"); + } + + { + std::string input("5x"); + std::istringstream iss(input); + + typedef std::istreambuf_iterator<char> base_iterator_type; + typedef multi_pass<base_iterator_type> iterator_type; + + iterator_type first = make_default_multi_pass(base_iterator_type(iss)); + iterator_type last = make_default_multi_pass(base_iterator_type()); + + std::ostringstream oss; + + qi::rule<iterator_type> r1 = qi::int_ > qi::int_; + qi::rule<iterator_type> r2 = qi::int_ > qi::char_; + qi::on_error<qi::fail>(r1, phoenix::ref(oss) << phoenix::val("error in r1")); + qi::on_error<qi::fail>(r2, phoenix::ref(oss) << phoenix::val("error in r2")); + + BOOST_TEST(qi::parse(first, last, r1 | r2)); + BOOST_TEST(oss.str() == "error in r1"); + } + + return boost::report_errors(); +} + diff --git a/src/boost/libs/spirit/test/support/regression_multi_pass_functor.cpp b/src/boost/libs/spirit/test/support/regression_multi_pass_functor.cpp new file mode 100644 index 00000000..d95ac258 --- /dev/null +++ b/src/boost/libs/spirit/test/support/regression_multi_pass_functor.cpp @@ -0,0 +1,107 @@ +// Copyright (c) 2010 Larry Evans +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +//Purpose: +// Demonstrate error in non-classic multi_pass iterator compilation. +// + +#include <boost/spirit/home/qi.hpp> +#include <boost/spirit/home/support.hpp> +#include <boost/spirit/home/support/multi_pass.hpp> +#include <boost/spirit/home/support/iterators/detail/functor_input_policy.hpp> + +#include <fstream> + +//[iterate_a2m: +// copied from: +// http://www.boost.org/doc/libs/1_41_0/libs/spirit/doc/html/spirit/support/multi_pass.html + +// define the function object +template<typename CharT=char> +class istreambuf_functor +{ +public: + typedef + std::istreambuf_iterator<CharT> + buf_iterator_type; + typedef + typename buf_iterator_type::int_type + result_type; + static + result_type + eof; + + istreambuf_functor(void) + : current_chr(eof) + {} + + istreambuf_functor(std::ifstream& input) + : my_first(input) + , current_chr(eof) + {} + + result_type operator()() + { + buf_iterator_type last; + if (my_first == last) + { + return eof; + } + current_chr=*my_first; + ++my_first; + return current_chr; + } + +private: + buf_iterator_type my_first; + result_type current_chr; +}; + +template<typename CharT> + typename istreambuf_functor<CharT>::result_type + istreambuf_functor<CharT>:: +eof +( istreambuf_functor<CharT>::buf_iterator_type::traits_type::eof() +) +; + +//]iterate_a2m: + +typedef istreambuf_functor<char> base_iterator_type; + +typedef + boost::spirit::multi_pass + < base_iterator_type + , boost::spirit::iterator_policies::default_policy + < boost::spirit::iterator_policies::first_owner + , boost::spirit::iterator_policies::no_check + , boost::spirit::iterator_policies::functor_input + , boost::spirit::iterator_policies::split_std_deque + > + > +chr_iterator_type; + +// ====================================================================== +// Main +int main() +{ + std::ifstream in("multi_pass.txt"); + + unsigned num_toks=0; + unsigned const max_toks=10; + + base_iterator_type base_first(in); + chr_iterator_type chr_first(base_first); + chr_iterator_type chr_last; + for + ( + ; (chr_first != chr_last && ++num_toks < max_toks) + ; ++chr_first + ) + { + std::cout<<":num_toks="<<num_toks<<":chr="<<*chr_first<<"\n"; + } + return 0; +} diff --git a/src/boost/libs/spirit/test/support/regression_multi_pass_parse.cpp b/src/boost/libs/spirit/test/support/regression_multi_pass_parse.cpp new file mode 100644 index 00000000..1ccbf1d6 --- /dev/null +++ b/src/boost/libs/spirit/test/support/regression_multi_pass_parse.cpp @@ -0,0 +1,61 @@ +// Copyright (c) 2010 Peter Schueller +// 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 <vector> +#include <istream> +#include <sstream> +#include <iostream> + +#include <boost/spirit/include/qi.hpp> +#include <boost/spirit/include/support_multi_pass.hpp> + +namespace qi = boost::spirit::qi; +namespace ascii = boost::spirit::ascii; + +std::vector<double> parse(std::istream& input) +{ + // iterate over stream input + typedef std::istreambuf_iterator<char> base_iterator_type; + base_iterator_type in_begin(input); + + // convert input iterator to forward iterator, usable by spirit parser + typedef boost::spirit::multi_pass<base_iterator_type> forward_iterator_type; + forward_iterator_type fwd_begin = boost::spirit::make_default_multi_pass(in_begin); + forward_iterator_type fwd_end; + + // prepare output + std::vector<double> output; + + // parse + bool r = qi::phrase_parse( + fwd_begin, fwd_end, // iterators over input + qi::double_ >> *(',' >> qi::double_) >> qi::eoi, // recognize list of doubles + ascii::space | '#' >> *(ascii::char_ - qi::eol) >> qi::eol, // comment skipper + output); // doubles are stored into this object + + // error detection + if( !r || fwd_begin != fwd_end ) + throw std::runtime_error("parse error"); + + // return result + return output; +} + +int main() +{ + try { + std::stringstream str("1.0,2.0\n"); + std::vector<double> values = parse(str); + BOOST_TEST(values.size() == 2 && values[0] == 1.0 && values[1] == 2.0); + } + catch(std::exception const&) { + BOOST_TEST(false); + } + return boost::report_errors(); +} diff --git a/src/boost/libs/spirit/test/support/regression_multi_pass_position_iterator.cpp b/src/boost/libs/spirit/test/support/regression_multi_pass_position_iterator.cpp new file mode 100644 index 00000000..6df9d2f4 --- /dev/null +++ b/src/boost/libs/spirit/test/support/regression_multi_pass_position_iterator.cpp @@ -0,0 +1,31 @@ +// Copyright (c) 2010 Chris Hoeppler +// +// Distributed under the 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 code below failed to compile with MSVC starting with Boost V1.42 + +#include <vector> +#include <boost/spirit/include/classic_position_iterator.hpp> +#include <boost/spirit/include/qi.hpp> + +namespace char_enc = boost::spirit::ascii; +namespace qi = boost::spirit::qi; + +int main() +{ + typedef std::vector<char> file_storage; + typedef boost::spirit::classic::position_iterator< + file_storage::const_iterator> iterator_type; + + qi::rule<iterator_type, std::string(), qi::blank_type> top = + qi::lexeme[+char_enc::alpha]; + + // I do not know what the hell is going under the hood of MSVC 9, + // but the next line fixes compilation error. + // error C3767: '!=': candidate function(s) not accessible + iterator_type first, last; + + return first == last; // just to silence unused variable warnings +} + diff --git a/src/boost/libs/spirit/test/support/unused_type.cpp b/src/boost/libs/spirit/test/support/unused_type.cpp new file mode 100644 index 00000000..84520532 --- /dev/null +++ b/src/boost/libs/spirit/test/support/unused_type.cpp @@ -0,0 +1,45 @@ +/*============================================================================= + Copyright (c) 2019 Nikita Kniazev + + Use, modification and distribution is subject to the Boost Software + License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at + http://www.boost.org/LICENSE_1_0.txt) +=============================================================================*/ + +#include <boost/spirit/home/support/unused.hpp> +#include <boost/static_assert.hpp> +#include <boost/type_traits/is_same.hpp> + +#if !defined(BOOST_NO_CXX11_DEFAULTED_FUNCTIONS) && \ + !defined(BOOST_NO_CXX11_HDR_TYPE_TRAITS) +#include <type_traits> +static_assert(std::is_trivial<boost::spirit::unused_type>::value, ""); +#endif + +void test_use(boost::spirit::unused_type) {} + +template <typename Expected, typename T> +void test(T&) +{ + BOOST_STATIC_ASSERT((boost::is_same<T&, Expected>::value)); +} + +int main() +{ + using boost::spirit::unused; + using boost::spirit::unused_type; + + unused_type unused_mut; + test<unused_type const&>(unused); + test<unused_type&>(unused_mut); + test<unused_type const&>(unused = 123); + test<unused_type const&>(unused = *&unused); + test<unused_type const&>(unused = unused_mut); + test<unused_type&>(unused_mut = 123); + test<unused_type&>(unused_mut = unused); + test<unused_type&>(unused_mut = *&unused_mut); + + test_use(0); + test_use(unused); + test_use(unused_mut); +} diff --git a/src/boost/libs/spirit/test/support/utree.cpp b/src/boost/libs/spirit/test/support/utree.cpp new file mode 100644 index 00000000..2b9b038c --- /dev/null +++ b/src/boost/libs/spirit/test/support/utree.cpp @@ -0,0 +1,501 @@ +/*============================================================================= + Copyright (c) 2001-2011 Joel de Guzman + Copyright (c) 2001-2011 Hartmut Kaiser + Copyright (c) 2010 Bryce Lelbach + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +=============================================================================*/ + +#include <boost/config/warning_disable.hpp> +#include <boost/detail/lightweight_test.hpp> + +#include <boost/functional/hash.hpp> +#include <boost/spirit/include/support_utree.hpp> + +#include <iostream> +#include <sstream> +#include <cstdlib> + +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; +} + +struct one_two_three +{ + boost::spirit::utree operator()(boost::spirit::utree) const + { + return boost::spirit::utree(123); + } +}; + +struct this_ +{ + boost::spirit::utree operator()(boost::spirit::utree) const + { + return boost::spirit::utree(static_cast<int>(boost::hash_value(this))); + } +}; + +int main() +{ + using boost::spirit::utree; + using boost::spirit::get; + using boost::spirit::utf8_symbol_type; + using boost::spirit::binary_string_type; + + { + // test the size + std::cout << "size of utree is: " + << sizeof(utree) << " bytes" << std::endl; + BOOST_TEST_EQ(sizeof(utree), sizeof(void*[4])); + } + + { + using boost::spirit::nil; + + utree val(nil); + BOOST_TEST(check(val, "<nil>")); + } + + { + using boost::spirit::empty_list; + + utree val(empty_list); + BOOST_TEST(check(val, "( )")); + } + + { + utree val(true); + BOOST_TEST(check(val, "true")); + } + + { + utree val(123); + BOOST_TEST(check(val, "123")); + } + + { + // single element string + utree val('x'); + BOOST_TEST(check(val, "\"x\"")); + + // empty string + utree val1(""); + BOOST_TEST(check(val1, "\"\"")); + } + + { + utree val(123.456); + BOOST_TEST(check(val, "123.456")); + } + + { // strings + utree val("Hello, World"); + BOOST_TEST(check(val, "\"Hello, World\"")); + utree val2; + val2 = val; + BOOST_TEST(check(val2, "\"Hello, World\"")); + utree val3("Hello, World. Chuckie is back!!!"); + val = val3; + BOOST_TEST(check(val, "\"Hello, World. Chuckie is back!!!\"")); + + utree val4("Apple"); + utree val5("Apple"); + BOOST_TEST_EQ(val4, val5); + + utree val6("ApplePie"); + BOOST_TEST(val4 < val6); + } + + { // symbols + utree val(utf8_symbol_type("Hello, World")); + BOOST_TEST(check(val, "Hello, World")); + utree val2; + val2 = val; + BOOST_TEST(check(val2, "Hello, World")); + utree val3(utf8_symbol_type("Hello, World. Chuckie is back!!!")); + val = val3; + BOOST_TEST(check(val, "Hello, World. Chuckie is back!!!")); + + utree val4(utf8_symbol_type("Apple")); + utree val5(utf8_symbol_type("Apple")); + BOOST_TEST_EQ(val4, val5); + + utree val6(utf8_symbol_type("ApplePie")); + BOOST_TEST(val4 < val6); + } + + { // binary_strings + utree val(binary_string_type("\xDE#\xAD")); + BOOST_TEST(check(val, "#de23ad#" /* FIXME?: "#\xDE#\xAD#" */)); + utree val2; + val2 = val; + BOOST_TEST(check(val2, "#de23ad#" /* FIXME?: "#\xDE#\xAD#" */)); + utree val3(binary_string_type("\xDE\xAD\xBE\xEF")); + val = val3; + BOOST_TEST(check(val, "#deadbeef#" /* FIXME?: "#\xDE\xAD\xBE\xEF#" */)); + + utree val4(binary_string_type("\x01")); + utree val5(binary_string_type("\x01")); + BOOST_TEST_EQ(val4, val5); + + utree val6(binary_string_type("\x01\x02")); + BOOST_TEST(val4 < val6); + } + + { + using boost::spirit::nil; + + utree val; + val.push_back(123); + val.push_back("Chuckie"); + BOOST_TEST_EQ(val.size(), 2U); + utree val2; + val2.push_back(123.456); + val2.push_back("Mah Doggie"); + val.push_back(val2); + BOOST_TEST_EQ(val.size(), 3U); + BOOST_TEST(check(val, "( 123 \"Chuckie\" ( 123.456 \"Mah Doggie\" ) )")); + BOOST_TEST(check(val.front(), "123")); + + utree val3(nil); + val3.swap(val); + BOOST_TEST_EQ(val3.size(), 3U); + BOOST_TEST(check(val, "<nil>")); + val3.swap(val); + BOOST_TEST(check(val, "( 123 \"Chuckie\" ( 123.456 \"Mah Doggie\" ) )")); + val.push_back("another string"); + BOOST_TEST_EQ(val.size(), 4U); + BOOST_TEST(check(val, "( 123 \"Chuckie\" ( 123.456 \"Mah Doggie\" ) \"another string\" )")); + val.pop_front(); + BOOST_TEST(check(val, "( \"Chuckie\" ( 123.456 \"Mah Doggie\" ) \"another string\" )")); + utree::iterator i = val.begin(); + ++++i; + val.insert(i, "Right in the middle"); + BOOST_TEST_EQ(val.size(), 4U); + BOOST_TEST(check(val, "( \"Chuckie\" ( 123.456 \"Mah Doggie\" ) \"Right in the middle\" \"another string\" )")); + val.pop_back(); + BOOST_TEST(check(val, "( \"Chuckie\" ( 123.456 \"Mah Doggie\" ) \"Right in the middle\" )")); + BOOST_TEST_EQ(val.size(), 3U); + utree::iterator it = val.end(); --it; + val.erase(it); + BOOST_TEST(check(val, "( \"Chuckie\" ( 123.456 \"Mah Doggie\" ) )")); + BOOST_TEST_EQ(val.size(), 2U); + + val.insert(val.begin(), val2.begin(), val2.end()); + BOOST_TEST(check(val, "( 123.456 \"Mah Doggie\" \"Chuckie\" ( 123.456 \"Mah Doggie\" ) )")); + BOOST_TEST_EQ(val.size(), 4U); + + // Regeression Ticket #6714 + it = val.insert(val.end(), 111); + BOOST_TEST(it != val.begin()); + BOOST_TEST(it == --val.end()); + BOOST_TEST(*it == 111); + + val.clear(); + it = val.insert(val.begin(), 222); + BOOST_TEST(it == val.begin()); + BOOST_TEST(it == --val.end()); + BOOST_TEST(*it == 222); + // Regeression Ticket #6714 + } + + { + utree val; + val.insert(val.end(), 123); + val.insert(val.end(), "Mia"); + val.insert(val.end(), "Chuckie"); + val.insert(val.end(), "Poly"); + val.insert(val.end(), "Mochi"); + BOOST_TEST(check(val, "( 123 \"Mia\" \"Chuckie\" \"Poly\" \"Mochi\" )")); + } + + { + using boost::spirit::nil; + using boost::spirit::invalid; + + utree a(nil), b(nil); + BOOST_TEST_EQ(a, b); + a = 123; + BOOST_TEST(a != b); + b = 123; + BOOST_TEST_EQ(a, b); + a = 100.00; + BOOST_TEST(a < b); + + b = a = utree(invalid); + BOOST_TEST_EQ(a, b); + a.push_back(1); + a.push_back("two"); + a.push_back(3.0); + b.push_back(1); + b.push_back("two"); + b.push_back(3.0); + BOOST_TEST_EQ(a, b); + b.push_back(4); + BOOST_TEST(a != b); + BOOST_TEST(a < b); + } + + { + using boost::spirit::empty_list; + + utree a(empty_list); + a.push_back(0); + a.push_back(0); + a.push_back(0); + a.push_back(0); + a.push_back(0); + a.push_back(0); + a.push_back(0); + a.push_back(0); + a.push_back(0); + a.push_back(0); + a.push_back(0); + a.push_back(0); + + for (utree::size_type i = 0; i < a.size(); ++i) + get(a, i) = int(i + 1); + + BOOST_TEST_EQ(get(a, 0), utree(1)); + BOOST_TEST_EQ(get(a, 1), utree(2)); + BOOST_TEST_EQ(get(a, 2), utree(3)); + BOOST_TEST_EQ(get(a, 3), utree(4)); + BOOST_TEST_EQ(get(a, 4), utree(5)); + BOOST_TEST_EQ(get(a, 5), utree(6)); + BOOST_TEST_EQ(get(a, 6), utree(7)); + BOOST_TEST_EQ(get(a, 7), utree(8)); + BOOST_TEST_EQ(get(a, 8), utree(9)); + BOOST_TEST_EQ(get(a, 9), utree(10)); + BOOST_TEST_EQ(get(a, 10), utree(11)); + BOOST_TEST_EQ(get(a, 11), utree(12)); + } + + { + // test empty list + utree a; + a.push_back(1); + a.pop_front(); + BOOST_TEST(check(a, "( )")); + + // the other way around + utree b; + b.push_front(1); + b.pop_back(); + BOOST_TEST(check(b, "( )")); + } + + { // test references + utree val(123); + utree ref(boost::ref(val)); + BOOST_TEST(check(ref, "123")); + BOOST_TEST_EQ(ref, utree(123)); + + val.clear(); + val.push_back(1); + val.push_back(2); + val.push_back(3); + val.push_back(4); + BOOST_TEST(check(ref, "( 1 2 3 4 )")); + BOOST_TEST_EQ(get(ref, 0), utree(1)); + BOOST_TEST_EQ(get(ref, 1), utree(2)); + BOOST_TEST_EQ(get(ref, 2), utree(3)); + BOOST_TEST_EQ(get(ref, 3), utree(4)); + } + + { // put it in an array + + utree vals[] = { + utree(123), + utree("Hello, World"), + utree(123.456) + }; + + BOOST_TEST(check(vals[0], "123")); + BOOST_TEST(check(vals[1], "\"Hello, World\"")); + BOOST_TEST(check(vals[2], "123.456")); + } + + { // operators + + BOOST_TEST((utree(false) && utree(false)) == utree(false)); + BOOST_TEST((utree(false) && utree(true)) == utree(false)); + BOOST_TEST((utree(true) && utree(false)) == utree(false)); + BOOST_TEST((utree(true) && utree(true)) == utree(true)); + + BOOST_TEST((utree(0) && utree(0)) == utree(false)); + BOOST_TEST((utree(0) && utree(1)) == utree(false)); + BOOST_TEST((utree(1) && utree(0)) == utree(false)); + BOOST_TEST((utree(1) && utree(1)) == utree(true)); + + BOOST_TEST((utree(false) || utree(false)) == utree(false)); + BOOST_TEST((utree(false) || utree(true)) == utree(true)); + BOOST_TEST((utree(true) || utree(false)) == utree(true)); + BOOST_TEST((utree(true) || utree(true)) == utree(true)); + + BOOST_TEST((utree(0) || utree(0)) == utree(false)); + BOOST_TEST((utree(0) || utree(1)) == utree(true)); + BOOST_TEST((utree(1) || utree(0)) == utree(true)); + BOOST_TEST((utree(1) || utree(1)) == utree(true)); + + BOOST_TEST((!utree(true)) == utree(false)); + BOOST_TEST((!utree(false)) == utree(true)); + BOOST_TEST((!utree(1)) == utree(false)); + BOOST_TEST((!utree(0)) == utree(true)); + + BOOST_TEST((utree(456) + utree(123)) == utree(456 + 123)); + BOOST_TEST((utree(456) + utree(123.456)) == utree(456 + 123.456)); + BOOST_TEST((utree(456) - utree(123)) == utree(456 - 123)); + BOOST_TEST((utree(456) - utree(123.456)) == utree(456 - 123.456)); + BOOST_TEST((utree(456) * utree(123)) == utree(456 * 123)); + BOOST_TEST((utree(456) * utree(123.456)) == utree(456 * 123.456)); + BOOST_TEST((utree(456) / utree(123)) == utree(456 / 123)); + BOOST_TEST((utree(456) / utree(123.456)) == utree(456 / 123.456)); + BOOST_TEST((utree(456) % utree(123)) == utree(456 % 123)); + BOOST_TEST(-utree(456) == utree(-456)); + + BOOST_TEST((utree(456) & utree(123)) == utree(456 & 123)); + BOOST_TEST((utree(456) | utree(123)) == utree(456 | 123)); + BOOST_TEST((utree(456) ^ utree(123)) == utree(456 ^ 123)); + BOOST_TEST((utree(456) << utree(3)) == utree(456 << 3)); + BOOST_TEST((utree(456) >> utree(2)) == utree(456 >> 2)); + BOOST_TEST(~utree(456) == utree(~456)); + } + + { // test reference iterator + utree val; + val.push_back(1); + val.push_back(2); + val.push_back(3); + val.push_back(4); + BOOST_TEST(check(val, "( 1 2 3 4 )")); + + utree::ref_iterator b = val.ref_begin(); + utree::ref_iterator e = val.ref_end(); + + utree ref(boost::make_iterator_range(b, e)); + BOOST_TEST_EQ(get(ref, 0), utree(1)); + BOOST_TEST_EQ(get(ref, 1), utree(2)); + BOOST_TEST_EQ(get(ref, 2), utree(3)); + BOOST_TEST_EQ(get(ref, 3), utree(4)); + BOOST_TEST(check(ref, "( 1 2 3 4 )")); + } + + { + // check the tag + // TODO: test tags on all utree types + utree x; + x.tag(123); + BOOST_TEST_EQ(x.tag(), 123); + + x = "hello world! my name is bob the builder"; + x.tag(123); + BOOST_TEST_EQ(x.tag(), 123); + + x.tag(456); + BOOST_TEST_EQ(x.tag(), 456); + BOOST_TEST_EQ(x.size(), 39U); + BOOST_TEST(check(x, "\"hello world! my name is bob the builder\"")); + + x = "hello"; + x.tag(456); + BOOST_TEST_EQ(x.tag(), 456); + + x.tag(789); + BOOST_TEST_EQ(x.tag(), 789); + BOOST_TEST_EQ(x.size(), 5U); + BOOST_TEST(check(x, "\"hello\"")); + } + + { + // test functions + using boost::spirit::stored_function; + + utree f = stored_function<one_two_three>(); + f.eval(utree()); + } + + { + // test referenced functions + using boost::spirit::referenced_function; + + one_two_three f; + utree ff = referenced_function<one_two_three>(f); + BOOST_TEST_EQ(ff.eval(utree()), f(utree())); + } + + { + // shallow ranges + using boost::spirit::shallow; + + utree val; + val.push_back(1); + val.push_back(2); + val.push_back(3); + val.push_back(4); + + utree::iterator i = val.begin(); ++i; + utree alias(utree::range(i, val.end()), shallow); + + BOOST_TEST(check(alias, "( 2 3 4 )")); + BOOST_TEST_EQ(alias.size(), 3U); + BOOST_TEST_EQ(alias.front(), 2); + BOOST_TEST_EQ(alias.back(), 4); + BOOST_TEST(!alias.empty()); + BOOST_TEST_EQ(get(alias, 1), 3); + } + + { + // shallow string ranges + using boost::spirit::utf8_string_range_type; + using boost::spirit::shallow; + + char const* s = "Hello, World"; + utree val(utf8_string_range_type(s, s + strlen(s)), shallow); + BOOST_TEST(check(val, "\"Hello, World\"")); + + utf8_string_range_type r = val.get<utf8_string_range_type>(); + utf8_string_range_type pf(r.begin()+1, r.end()-1); + val = utree(pf, shallow); + BOOST_TEST(check(val, "\"ello, Worl\"")); + } + + { + // any pointer + using boost::spirit::any_ptr; + + int n = 123; + utree up = any_ptr(&n); + BOOST_TEST(*up.get<int*>() == 123); + } + + // tags + { + short min = (std::numeric_limits<short>::min)(); + short max = (std::numeric_limits<short>::max)(); + + utree::list_type u; + utree u2; + bool ok = true; + + for (int t = min ; ok && t <= max ; ++t) { + u.tag(t); + u2 = u; + BOOST_TEST_EQ(t, u.tag()); + BOOST_TEST_EQ(t, u2.tag()); + ok = t == u.tag() && t == u2.tag(); + u2 = utree("12"); + } + } + + return boost::report_errors(); +} diff --git a/src/boost/libs/spirit/test/support/utree_debug.cpp b/src/boost/libs/spirit/test/support/utree_debug.cpp new file mode 100644 index 00000000..ebf44c4a --- /dev/null +++ b/src/boost/libs/spirit/test/support/utree_debug.cpp @@ -0,0 +1,29 @@ +// 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> + +#define BOOST_SPIRIT_DEBUG 1 + +#include <boost/spirit/include/qi.hpp> +#include <boost/spirit/include/support_utree.hpp> + +#include <string> + +namespace qi = boost::spirit::qi; +namespace spirit = boost::spirit; + +int main() +{ + qi::rule<std::string::iterator, spirit::utree()> r = qi::int_; + BOOST_SPIRIT_DEBUG_NODE(r); + + spirit::utree ut; + std::string input("1"); + BOOST_TEST(qi::parse(input.begin(), input.end(), r, ut)); + BOOST_TEST(ut.which() == spirit::utree_type::int_type && ut.get<int>() == 1); + + return boost::report_errors(); +} diff --git a/src/boost/libs/spirit/test/test_headers/Jamfile b/src/boost/libs/spirit/test/test_headers/Jamfile new file mode 100644 index 00000000..cddbc19b --- /dev/null +++ b/src/boost/libs/spirit/test/test_headers/Jamfile @@ -0,0 +1,76 @@ +# Jamfile +# +# Copyright (c) 2007-2008 Steven Watanabe +# Copyright (c) 2009 Joel de Guzman +# Copyright (c) 2009 Hartmut Kaiser +# Copyright (c) 2009 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 + +import testing ; +import path ; +import regex ; +import print ; +import sequence ; +import feature ; + +project boost/spirit/test/test_headers + : requirements + <include>$(BOOST_ROOT) + <include>../../../.. + <c++-template-depth>300 + ; + +headers = +[ + path.glob-tree ../../../../boost/spirit/include : *.hpp : classic* phoenix1* +] ; + +for local file in $(headers) +{ + compile test.cpp + : # requirements + <define>BOOST_SPIRIT_HEADER_NAME=$(file) + <dependency>$(file) + : # test name + [ regex.replace [ path.relative-to ../../../../boost/spirit $(file) ] "/" "_" ] + ; +} + +feature.feature <generate-include-all-order> : forward reverse : incidental ; + +rule generate-include-all ( target : sources * : properties * ) +{ + print.output $(target) ; + + if <generate-include-all-order>reverse in $(properties) + { + sources = [ sequence.reverse $(sources) ] ; + } + + for local file in $(sources) + { + print.text "#include <$(file:G=)> +" : overwrite ; + } + +} + +make auto_all1.cpp + : $(headers) + : @generate-include-all + ; + +make auto_all2.cpp + : $(headers) + : @generate-include-all + : <generate-include-all-order>reverse + ; + +# this ought to catch non-inlined functions and other duplicate definitions +link auto_all1.cpp auto_all2.cpp main.cpp + : <include>. + : auto_all_headers + ; diff --git a/src/boost/libs/spirit/test/test_headers/main.cpp b/src/boost/libs/spirit/test/test_headers/main.cpp new file mode 100644 index 00000000..99aacc62 --- /dev/null +++ b/src/boost/libs/spirit/test/test_headers/main.cpp @@ -0,0 +1,14 @@ +// Copyright (c) 2003-2008 Matthias Christian Schabel +// Copyright (c) 2007-2008 Steven Watanabe +// Copyright (c) 2010 Joel de Guzman +// Copyright (c) 2010 Hartmut Kaiser +// Copyright (c) 2009 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) + +int main() +{ + return 0; +} diff --git a/src/boost/libs/spirit/test/test_headers/test.cpp b/src/boost/libs/spirit/test/test_headers/test.cpp new file mode 100644 index 00000000..c6814198 --- /dev/null +++ b/src/boost/libs/spirit/test/test_headers/test.cpp @@ -0,0 +1,22 @@ +// Copyright (c) 2003-2008 Matthias Christian Schabel +// Copyright (c) 2007-2008 Steven Watanabe +// Copyright (c) 2010 Joel de Guzman +// Copyright (c) 2010 Hartmut Kaiser +// Copyright (c) 2009 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) + +#define BOOST_SPIRIT_STRINGIZE_IMPL(x) #x +#define BOOST_SPIRIT_STRINGIZE(x) BOOST_SPIRIT_STRINGIZE_IMPL(x) + +#define BOOST_SPIRIT_HEADER BOOST_SPIRIT_STRINGIZE(BOOST_SPIRIT_HEADER_NAME) + +#include BOOST_SPIRIT_HEADER +#include BOOST_SPIRIT_HEADER + +int main() +{ + return 0; +} diff --git a/src/boost/libs/spirit/test/x3/Jamfile b/src/boost/libs/spirit/test/x3/Jamfile new file mode 100644 index 00000000..875c06a3 --- /dev/null +++ b/src/boost/libs/spirit/test/x3/Jamfile @@ -0,0 +1,134 @@ +#============================================================================== +# Copyright (c) 2001-2013 Joel de Guzman +# Copyright (c) 2001-2012 Hartmut Kaiser +# Copyright (c) 2011 Bryce Lelbach +# +# Use, modification and distribution is subject to the Boost Software +# License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +# http://www.boost.org/LICENSE_1_0.txt) +#============================================================================== + +import config : requires ; +import modules ; +import feature ; +import testing ; + +############################################################################### + +project spirit-x3 + : requirements + <include>. + <c++-template-depth>512 + [ requires + # Assume all the cxx11 checks succeed if any of cxx14 does. + #cxx14_binary_literals # grep -Er "[0-9]+b[0-9]+" * + #cxx14_constexpr + cxx14_decltype_auto # grep -r "decltype(auto)" * + #cxx14_digit_separators # grep -Er "[0-9]+'[0-9]+" * + cxx14_generic_lambdas # grep -Er "]\s*\\([^\\)]*auto" * + #cxx14_hdr_shared_mutex # grep -r "shared_mutex" * + #cxx14_initialized_lambda_captures # grep -Er "\\[[^=\\]]+=" * + #cxx14_aggregate_nsdmi + cxx14_return_type_deduction # grep -Er "auto[^\\(=\\)]+\(" * + #cxx14_std_exchange # grep -r "exchange" * + cxx14_variable_templates + ] + ; + +############################################################################### + +local subproject-name = x3 ; + +rule run ( sources + : args * : input-files * + : requirements * : target-name ? : default-build * ) +{ + target-name ?= $(subproject-name)_$(sources[1]:D=:S=) ; + return [ testing.run $(sources) : $(args) : $(input-files) + : $(requirements) : $(target-name) : $(default-build) ] ; +} + +rule compile ( sources + : requirements * : target-name ? ) +{ + target-name ?= $(subproject-name)_$(sources[1]:D=:S=) ; + return [ testing.compile $(sources) + : $(requirements) : $(target-name) ] ; +} + +rule compile-fail ( sources + : requirements * : target-name ? ) +{ + target-name ?= $(subproject-name)_$(sources[1]:D=:S=) ; + return [ testing.compile-fail $(sources) + : $(requirements) : $(target-name) ] ; +} + +############################################################################### + +run actions.cpp ; +run alternative.cpp ; +run and_predicate.cpp ; +run any_parser.cpp ; +run attr.cpp ; +run binary.cpp ; +run bool.cpp ; +run char1.cpp ; +run char_class.cpp ; +run container_support.cpp ; +run debug.cpp ; +run difference.cpp ; +run eoi.cpp ; +run eol.cpp ; +run eps.cpp ; +run expect.cpp ; +run extract_int.cpp ; +run int1.cpp ; +run kleene.cpp ; +run lexeme.cpp ; +run lit1.cpp ; +run lit2.cpp ; +run list.cpp ; +run matches.cpp ; +run no_case.cpp ; +run no_skip.cpp ; +run not_predicate.cpp ; +run omit.cpp ; +run optional.cpp ; +run plus.cpp ; +run with.cpp ; + +run raw.cpp ; +run real1.cpp ; +run real2.cpp ; +run real3.cpp ; +run real4.cpp ; +run rule1.cpp ; +run rule2.cpp ; +run rule3.cpp ; +run rule4.cpp ; +run sequence.cpp ; +run skip.cpp ; +run symbols1.cpp ; +run symbols2.cpp ; +run symbols3.cpp ; +run tst.cpp ; + +run uint1.cpp ; +run uint_radix.cpp ; + +run confix.cpp ; +run repeat.cpp ; +run seek.cpp ; + +run unused_type.cpp ; +run attribute_type_check.cpp ; +run fusion_map.cpp ; +run x3_variant.cpp ; +run error_handler.cpp /boost//filesystem ; +run iterator_check.cpp ; + +run to_utf8.cpp ; + +obj rule_separate_tu_grammar : rule_separate_tu_grammar.cpp ; +run rule_separate_tu.cpp rule_separate_tu_grammar ; + +obj grammar_linker : grammar.cpp ; +run grammar_linker.cpp grammar_linker ; diff --git a/src/boost/libs/spirit/test/x3/actions.cpp b/src/boost/libs/spirit/test/x3/actions.cpp new file mode 100644 index 00000000..f033e27e --- /dev/null +++ b/src/boost/libs/spirit/test/x3/actions.cpp @@ -0,0 +1,108 @@ +/*============================================================================= + Copyright (c) 2001-2015 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +=============================================================================*/ +#include <boost/detail/lightweight_test.hpp> +#include <boost/spirit/home/x3.hpp> +#include <cstring> +#include <functional> + +#include "test.hpp" + + +namespace x3 = boost::spirit::x3; + +int x = 0; + +auto fun1 = + [](auto& ctx) + { + x += x3::_attr(ctx); + } +; + +struct fun_action +{ + template <typename Context> + void operator()(Context const& ctx) const + { + x += x3::_attr(ctx); + } +}; + +auto fail = + [](auto& ctx) + { + x3::_pass(ctx) = false; + } +; + +struct setnext +{ + setnext(char& next) : next(next) {} + + template <typename Context> + void operator()(Context const& ctx) const + { + next = x3::_attr(ctx); + } + + char& next; +}; + + +struct stationary : boost::noncopyable +{ + explicit stationary(int i) : val{i} {} + stationary& operator=(int i) { val = i; return *this; } + + int val; +}; + + +int main() +{ + using spirit_test::test; + using spirit_test::test_attr; + + using x3::int_; + + { + char const *s1 = "{42}", *e1 = s1 + std::strlen(s1); + x3::parse(s1, e1, '{' >> int_[fun1] >> '}'); + } + + + { + char const *s1 = "{42}", *e1 = s1 + std::strlen(s1); + x3::parse(s1, e1, '{' >> int_[fun_action()] >> '}'); + } + + { + using namespace std::placeholders; + char const *s1 = "{42}", *e1 = s1 + std::strlen(s1); + x3::parse(s1, e1, '{' >> int_[std::bind(fun_action(), _1)] >> '}'); + } + + BOOST_TEST(x == (42*3)); + + { + std::string input("1234 6543"); + char next = '\0'; + BOOST_TEST(x3::phrase_parse(input.begin(), input.end(), + x3::int_[fail] | x3::digit[setnext(next)], x3::space)); + BOOST_TEST(next == '1'); + } + + { // ensure no unneded synthesization, copying and moving occured + auto p = '{' >> int_ >> '}'; + + stationary st { 0 }; + BOOST_TEST(test_attr("{42}", p[([]{})], st)); + BOOST_TEST_EQ(st.val, 42); + } + + return boost::report_errors(); +} diff --git a/src/boost/libs/spirit/test/x3/alternative.cpp b/src/boost/libs/spirit/test/x3/alternative.cpp new file mode 100644 index 00000000..9162e943 --- /dev/null +++ b/src/boost/libs/spirit/test/x3/alternative.cpp @@ -0,0 +1,253 @@ +/*============================================================================= + Copyright (c) 2001-2015 Joel de Guzman + Copyright (c) 2001-2011 Hartmut Kaiser + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +=============================================================================*/ +#include <boost/detail/lightweight_test.hpp> +#include <boost/spirit/home/x3.hpp> +#include <boost/fusion/include/adapt_struct.hpp> +#include <boost/variant.hpp> +#include <boost/fusion/include/vector.hpp> +#include <boost/fusion/include/at.hpp> + +#include <string> +#include <iostream> +#include <vector> +#include "test.hpp" + +struct di_ignore +{ + std::string text; +}; + +struct di_include +{ + std::string FileName; +}; + +BOOST_FUSION_ADAPT_STRUCT(di_ignore, + text +) + +BOOST_FUSION_ADAPT_STRUCT(di_include, + FileName +) + +struct undefined {}; + + +struct stationary : boost::noncopyable +{ + explicit stationary(int i) : val{i} {} + // TODO: fix unneeded self move in alternative + stationary& operator=(stationary&&) { std::abort(); } + stationary& operator=(int i) { val = i; return *this; } + + int val; +}; + + +int +main() +{ + using spirit_test::test; + using spirit_test::test_attr; + + using boost::spirit::x3::attr; + using boost::spirit::x3::char_; + using boost::spirit::x3::int_; + using boost::spirit::x3::lit; + using boost::spirit::x3::unused_type; + using boost::spirit::x3::unused; + using boost::spirit::x3::omit; + using boost::spirit::x3::eps; + + + { + BOOST_TEST((test("a", char_ | char_))); + BOOST_TEST((test("x", lit('x') | lit('i')))); + BOOST_TEST((test("i", lit('x') | lit('i')))); + BOOST_TEST((!test("z", lit('x') | lit('o')))); + BOOST_TEST((test("rock", lit("rock") | lit("roll")))); + BOOST_TEST((test("roll", lit("rock") | lit("roll")))); + BOOST_TEST((test("rock", lit("rock") | int_))); + BOOST_TEST((test("12345", lit("rock") | int_))); + } + + { + typedef boost::variant<undefined, int, char> attr_type; + attr_type v; + + BOOST_TEST((test_attr("12345", int_ | char_, v))); + BOOST_TEST(boost::get<int>(v) == 12345); + + BOOST_TEST((test_attr("12345", lit("rock") | int_ | char_, v))); + BOOST_TEST(boost::get<int>(v) == 12345); + + v = attr_type(); + BOOST_TEST((test_attr("rock", lit("rock") | int_ | char_, v))); + BOOST_TEST(v.which() == 0); + + BOOST_TEST((test_attr("x", lit("rock") | int_ | char_, v))); + BOOST_TEST(boost::get<char>(v) == 'x'); + } + + { // Make sure that we are using the actual supplied attribute types + // from the variant and not the expected type. + boost::variant<int, std::string> v; + BOOST_TEST((test_attr("12345", int_ | +char_, v))); + BOOST_TEST(boost::get<int>(v) == 12345); + + BOOST_TEST((test_attr("abc", int_ | +char_, v))); + BOOST_TEST(boost::get<std::string>(v) == "abc"); + + BOOST_TEST((test_attr("12345", +char_ | int_, v))); + BOOST_TEST(boost::get<std::string>(v) == "12345"); + } + + { + unused_type x; + BOOST_TEST((test_attr("rock", lit("rock") | lit('x'), x))); + } + + { + // test if alternatives with all components having unused + // attributes have an unused attribute + + using boost::fusion::vector; + using boost::fusion::at_c; + + vector<char, char> v; + BOOST_TEST((test_attr("abc", + char_ >> (omit[char_] | omit[char_]) >> char_, v))); + BOOST_TEST((at_c<0>(v) == 'a')); + BOOST_TEST((at_c<1>(v) == 'c')); + } + + { + // Test that we can still pass a "compatible" attribute to + // an alternate even if its "expected" attribute is unused type. + + std::string s; + BOOST_TEST((test_attr("...", *(char_('.') | char_(',')), s))); + BOOST_TEST(s == "..."); + } + + { // make sure collapsing eps works as expected + // (compile check only) + + using boost::spirit::x3::rule; + using boost::spirit::x3::eps; + using boost::spirit::x3::_attr; + using boost::spirit::x3::_val; + + rule<class r1, wchar_t> r1; + rule<class r2, wchar_t> r2; + rule<class r3, wchar_t> r3; + + auto f = [&](auto& ctx){ _val(ctx) = _attr(ctx); }; + + r3 = ((eps >> r1))[f]; + r3 = ((r1) | r2)[f]; + r3 = ((eps >> r1) | r2); + } + + { + std::string s; + using boost::spirit::x3::eps; + + // test having a variant<container, ...> + BOOST_TEST( (test_attr("a,b", (char_ % ',') | eps, s )) ); + BOOST_TEST(s == "ab"); + } + + { + using boost::spirit::x3::eps; + + // testing a sequence taking a container as attribute + std::string s; + BOOST_TEST( (test_attr("abc,a,b,c", + char_ >> char_ >> (char_ % ','), s )) ); + BOOST_TEST(s == "abcabc"); + + // test having an optional<container> inside a sequence + s.erase(); + BOOST_TEST( (test_attr("ab", + char_ >> char_ >> -(char_ % ','), s )) ); + BOOST_TEST(s == "ab"); + + // test having a variant<container, ...> inside a sequence + s.erase(); + BOOST_TEST( (test_attr("ab", + char_ >> char_ >> ((char_ % ',') | eps), s )) ); + BOOST_TEST(s == "ab"); + s.erase(); + BOOST_TEST( (test_attr("abc", + char_ >> char_ >> ((char_ % ',') | eps), s )) ); + BOOST_TEST(s == "abc"); + } + + { + //compile test only (bug_march_10_2011_8_35_am) + typedef boost::variant<double, std::string> value_type; + + using boost::spirit::x3::rule; + using boost::spirit::x3::eps; + + rule<class r1, value_type> r1; + auto r1_ = r1 = r1 | eps; // left recursive! + + unused = r1_; // silence unused local warning + } + + { + using boost::spirit::x3::rule; + typedef boost::variant<di_ignore, di_include> d_line; + + rule<class ignore, di_ignore> ignore; + rule<class include, di_include> include; + rule<class line, d_line> line; + + auto start = + line = include | ignore; + + unused = start; // silence unused local warning + } + + // single-element fusion vector tests + { + boost::fusion::vector<boost::variant<int, std::string>> fv; + BOOST_TEST((test_attr("12345", int_ | +char_, fv))); + BOOST_TEST(boost::get<int>(boost::fusion::at_c<0>(fv)) == 12345); + + boost::fusion::vector<boost::variant<int, std::string>> fvi; + BOOST_TEST((test_attr("12345", int_ | int_, fvi))); + BOOST_TEST(boost::get<int>(boost::fusion::at_c<0>(fvi)) == 12345); + } + + // alternative over single element sequences as part of another sequence + { + auto key1 = lit("long") >> attr(long()); + auto key2 = lit("char") >> attr(char()); + auto keys = key1 | key2; + auto pair = keys >> lit("=") >> +char_; + + boost::fusion::deque<boost::variant<long, char>, std::string> attr_; + + BOOST_TEST(test_attr("long=ABC", pair, attr_)); + BOOST_TEST(boost::get<long>(&boost::fusion::front(attr_)) != nullptr); + BOOST_TEST(boost::get<char>(&boost::fusion::front(attr_)) == nullptr); + } + + { // ensure no unneded synthesization, copying and moving occured + auto p = '{' >> int_ >> '}'; + + stationary st { 0 }; + BOOST_TEST(test_attr("{42}", p | eps | p, st)); + BOOST_TEST_EQ(st.val, 42); + } + + return boost::report_errors(); +} diff --git a/src/boost/libs/spirit/test/x3/and_predicate.cpp b/src/boost/libs/spirit/test/x3/and_predicate.cpp new file mode 100644 index 00000000..b2a44d10 --- /dev/null +++ b/src/boost/libs/spirit/test/x3/and_predicate.cpp @@ -0,0 +1,25 @@ +/*============================================================================= + Copyright (c) 2001-2015 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +=============================================================================*/ +#include <boost/detail/lightweight_test.hpp> +#include <boost/spirit/home/x3.hpp> + +#include <iostream> +#include "test.hpp" + +int +main() +{ + using spirit_test::test; + using boost::spirit::x3::int_; + + { + BOOST_TEST((test("1234", &int_, false))); + BOOST_TEST((!test("abcd", &int_))); + } + + return boost::report_errors(); +} diff --git a/src/boost/libs/spirit/test/x3/any_parser.cpp b/src/boost/libs/spirit/test/x3/any_parser.cpp new file mode 100644 index 00000000..9f46492f --- /dev/null +++ b/src/boost/libs/spirit/test/x3/any_parser.cpp @@ -0,0 +1,159 @@ +/*============================================================================= + Copyright (c) 2001-2015 Joel de Guzman + Copyright (c) 2013-2014 Agustin Berge + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ + +#include <boost/detail/lightweight_test.hpp> +#include <boost/spirit/home/x3.hpp> + +#include <string> +#include <cstring> +#include <iostream> +#include "test.hpp" + +int +main() +{ + using spirit_test::test_attr; + using spirit_test::test; + + using namespace boost::spirit::x3::ascii; + using boost::spirit::x3::any_parser; + using boost::spirit::x3::make_context; + using boost::spirit::x3::lit; + using boost::spirit::x3::unused_type; + using boost::spirit::x3::phrase_parse; + using boost::spirit::x3::skip_flag; + using boost::spirit::x3::skipper_tag; + using boost::spirit::x3::_attr; + + typedef char const* iterator_type; + typedef decltype(make_context<skipper_tag>(space)) context_type; + { // basic tests + + auto a = lit('a'); + auto b = lit('b'); + auto c = lit('c'); + + { + any_parser<iterator_type> start = + *(a | b | c); + + BOOST_TEST(test("abcabcacb", start)); + } + } + + { // basic tests w/ skipper + + auto a = lit('a'); + auto b = lit('b'); + auto c = lit('c'); + + { + any_parser<iterator_type, unused_type, context_type> start = + *(a | b | c); + + BOOST_TEST(test(" a b c a b c a c b ", start, space)); + } + } + + { // basic tests w/ skipper but no final post-skip + + any_parser<iterator_type, unused_type, context_type> a = lit('a'); + any_parser<iterator_type, unused_type, context_type> b = lit('b'); + any_parser<iterator_type, unused_type, context_type> c = lit('c'); + + { + any_parser<iterator_type, unused_type, context_type> start = *(a | b) >> c; + + char const *s1 = " a b a a b b a c ... " + , *const e1 = s1 + std::strlen(s1); + BOOST_TEST(phrase_parse(s1, e1, start, space, skip_flag::dont_post_skip) + && s1 == e1 - 5); + } + } + + { // context tests + + char ch; + any_parser<iterator_type, char> a = alpha; + + // this semantic action requires both the context and attribute + //!!auto f = [&](auto&, char attr){ ch = attr; }; + //!!BOOST_TEST(test("x", a[f])); + //!!BOOST_TEST(ch == 'x'); + + // the semantic action may have the context passed + auto f2 = [&](auto&){ ch = 'y'; }; + BOOST_TEST(test("x", a[f2])); + BOOST_TEST(ch == 'y'); + + // the semantic action may optionally not have any arguments at all + auto f3 = [&]{ ch = 'z'; }; + BOOST_TEST(test("x", a[f3])); + BOOST_TEST(ch == 'z'); + + BOOST_TEST(test_attr("z", a, ch)); // attribute is given. + BOOST_TEST(ch == 'z'); + } + + { // auto rules tests + + char ch = '\0'; + any_parser<iterator_type, char> a = alpha; + auto f = [&](auto& ctx){ ch = _attr(ctx); }; + + BOOST_TEST(test("x", a[f])); + BOOST_TEST(ch == 'x'); + ch = '\0'; + BOOST_TEST(test_attr("z", a, ch)); // attribute is given. + BOOST_TEST(ch == 'z'); + + ch = '\0'; + BOOST_TEST(test("x", a[f])); + BOOST_TEST(ch == 'x'); + ch = '\0'; + BOOST_TEST(test_attr("z", a, ch)); // attribute is given. + BOOST_TEST(ch == 'z'); + } + + { // auto rules tests: allow stl containers as attributes to + // sequences (in cases where attributes of the elements + // are convertible to the value_type of the container or if + // the element itself is an stl container with value_type + // that is convertible to the value_type of the attribute). + + std::string s; + auto f = [&](auto& ctx){ s = _attr(ctx); }; + + { + any_parser<iterator_type, std::string> r + = char_ >> *(',' >> char_) + ; + + BOOST_TEST(test("a,b,c,d,e,f", r[f])); + BOOST_TEST(s == "abcdef"); + } + + { + any_parser<iterator_type, std::string> r + = char_ >> *(',' >> char_); + s.clear(); + BOOST_TEST(test("a,b,c,d,e,f", r[f])); + BOOST_TEST(s == "abcdef"); + } + + { + any_parser<iterator_type, std::string> r + = char_ >> char_ >> char_ >> char_ >> char_ >> char_; + s.clear(); + BOOST_TEST(test("abcdef", r[f])); + BOOST_TEST(s == "abcdef"); + } + } + + return boost::report_errors(); +} diff --git a/src/boost/libs/spirit/test/x3/attr.cpp b/src/boost/libs/spirit/test/x3/attr.cpp new file mode 100644 index 00000000..ead8d49f --- /dev/null +++ b/src/boost/libs/spirit/test/x3/attr.cpp @@ -0,0 +1,53 @@ +/*============================================================================= + Copyright (c) 2001-2015 Joel de Guzman + + Distributed under the Boost Software License, Version 1. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +=============================================================================*/ +#include <boost/detail/lightweight_test.hpp> +#include <boost/spirit/home/x3.hpp> + +#include <boost/fusion/include/std_pair.hpp> +#include <vector> + +#include "test.hpp" + +int main() +{ + using spirit_test::test_attr; + using boost::spirit::x3::attr; + using boost::spirit::x3::int_; + + { + int d = 0; + BOOST_TEST(test_attr("", attr(1), d) && d == 1); + + int d1 = 1; + BOOST_TEST(test_attr("", attr(d1), d) && d == 1); + + std::pair<int, int> p; + BOOST_TEST(test_attr("1", int_ >> attr(1), p) && + p.first == 1 && p.second == 1); + + char c = '\0'; + BOOST_TEST(test_attr("", attr('a'), c) && c == 'a'); + + // $$$ Needs some special is_convertible support, or + // str ends up with an explicit null-terminator... $$$ + //~ std::string str; + //~ BOOST_TEST(test_attr("", attr("test"), str) && str == "test"); + + int array[] = {0, 1, 2}; + std::vector<int> vec; + BOOST_TEST(test_attr("", attr(array), vec) && vec.size() == 3 && + vec[0] == 0 && vec[1] == 1 && vec[2] == 2); + } + + { + std::string s; + BOOST_TEST(test_attr("s", "s" >> attr(std::string("123")), s) && + s == "123"); + } + + return boost::report_errors(); +} diff --git a/src/boost/libs/spirit/test/x3/attribute_type_check.cpp b/src/boost/libs/spirit/test/x3/attribute_type_check.cpp new file mode 100644 index 00000000..26f028a3 --- /dev/null +++ b/src/boost/libs/spirit/test/x3/attribute_type_check.cpp @@ -0,0 +1,113 @@ +#include <boost/detail/lightweight_test.hpp> +#include <boost/spirit/home/x3.hpp> +#include <boost/fusion/include/vector.hpp> +#include <boost/fusion/include/make_vector.hpp> +#include <boost/fusion/include/equal_to.hpp> +#include <boost/type_traits/is_same.hpp> +#include <boost/optional.hpp> +#include <string> + +namespace x3 = boost::spirit::x3; + +// just an `attr` with added type checker +template <typename Value, typename Expected> +struct checked_attr_parser : x3::attr_parser<Value> +{ + using base_t = x3::attr_parser<Value>; + + checked_attr_parser(Value const& value) : base_t(value) {} + checked_attr_parser(Value&& value) : base_t(std::move(value)) {} + + template <typename Iterator, typename Context + , typename RuleContext, typename Attribute> + bool parse(Iterator& first, Iterator const& last + , Context const& ctx, RuleContext& rctx, Attribute& attr_) const + { + static_assert(boost::is_same<Expected, Attribute>::value, + "attribute type check failed"); + return base_t::parse(first, last, ctx, rctx, attr_); + } +}; + +template <typename Expected, typename Value> +static inline checked_attr_parser<boost::decay_t<Value>, Expected> +checked_attr(Value&& value) { return { std::forward<Value>(value) }; } + +// instantiate our type checker +// (checks attribute value just to be sure we are ok) +template <typename Value, typename Expr> +static void test_expr(Value const& v, Expr&& expr) +{ + char const* it = ""; + Value r; + BOOST_TEST((x3::parse(it, it, std::forward<Expr>(expr), r))); + BOOST_TEST((r == v)); +} + +template <typename Expr, typename Attribute> +static void gen_sequence(Attribute const& attribute, Expr&& expr) +{ + test_expr(attribute, expr); + test_expr(attribute, expr >> x3::eps); +} + +template <typename Expected, typename... ExpectedTail, typename Attribute, typename Expr, typename Value, typename... Tail> +static void gen_sequence(Attribute const& attribute, Expr&& expr, Value const& v, Tail const&... tail) +{ + gen_sequence<ExpectedTail...>(attribute, expr >> checked_attr<Expected>(v), tail...); + gen_sequence<ExpectedTail...>(attribute, expr >> x3::eps >> checked_attr<Expected>(v), tail...); + gen_sequence<ExpectedTail...>(attribute, expr >> (x3::eps >> checked_attr<Expected>(v)), tail...); +} + +template <typename Expected, typename... ExpectedTail, typename Attribute, typename Value, typename... Tail> +static void gen_sequence_tests(Attribute const& attribute, Value const& v, Tail const&... tail) +{ + gen_sequence<ExpectedTail...>(attribute, checked_attr<Expected>(v), tail...); + gen_sequence<ExpectedTail...>(attribute, x3::eps >> checked_attr<Expected>(v), tail...); +} + +template <typename Expected, typename Value> +static void gen_single_item_tests(Value const& v) +{ + Expected attribute(v); + gen_sequence(attribute, checked_attr<Expected>(v)); + gen_sequence(attribute, x3::eps >> checked_attr<Expected>(v)); +} + +template <typename Expected, typename... ExpectedTail, typename Value, typename... Tail> +static void gen_single_item_tests(Value const& v, Tail const&... tail) +{ + gen_single_item_tests<Expected>(v); + gen_single_item_tests<ExpectedTail...>(tail...); +} + +template <typename... Expected, typename... Values> +static void gen_tests(Values const&... values) +{ + gen_single_item_tests<Expected...>(values...); + + boost::fusion::vector<Expected...> attribute = boost::fusion::make_vector(values...); + gen_sequence_tests<Expected...>(attribute, values...); +} + +template <typename... Attributes> +void make_test(Attributes const&... attrs) +{ + // I would like to place all of this in a single call + // but it requires tremendous amount of heap to compile + gen_tests<Attributes...>(attrs...); + gen_tests< + boost::optional<Attributes>... + , boost::fusion::vector<Attributes>... + >(attrs..., attrs...); + gen_tests< + boost::optional<boost::fusion::vector<Attributes>>... + , boost::fusion::vector<boost::optional<Attributes>>... + >(boost::fusion::vector<Attributes>(attrs)..., attrs...); +} + +int main() +{ + make_test<int, std::string>(123, "hello"); + return boost::report_errors(); +} diff --git a/src/boost/libs/spirit/test/x3/binary.cpp b/src/boost/libs/spirit/test/x3/binary.cpp new file mode 100644 index 00000000..12878429 --- /dev/null +++ b/src/boost/libs/spirit/test/x3/binary.cpp @@ -0,0 +1,155 @@ +/*============================================================================= + Copyright (c) 2001-2011 Hartmut Kaiser + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#include <boost/detail/lightweight_test.hpp> + +#include <boost/spirit/home/x3/binary.hpp> +#include <boost/cstdint.hpp> +#include <boost/predef/other/endian.h> +#include "test.hpp" + +/////////////////////////////////////////////////////////////////////////////// +int main() +{ + using spirit_test::test_attr; + using spirit_test::test; + using spirit_test::binary_test; + using spirit_test::binary_test_attr; + + using boost::spirit::x3::byte_; + using boost::spirit::x3::word; + using boost::spirit::x3::dword; + using boost::spirit::x3::big_word; + using boost::spirit::x3::big_dword; + using boost::spirit::x3::little_word; + using boost::spirit::x3::little_dword; +#ifdef BOOST_HAS_LONG_LONG + using boost::spirit::x3::qword; + using boost::spirit::x3::big_qword; + using boost::spirit::x3::little_qword; +#endif +// using boost::spirit::x3::bin_float; +// using boost::spirit::x3::big_bin_float; +// using boost::spirit::x3::little_bin_float; +// using boost::spirit::x3::bin_double; +// using boost::spirit::x3::big_bin_double; +// using boost::spirit::x3::little_bin_double; + + boost::uint8_t uc; + boost::uint16_t us; + boost::uint32_t ui; +#ifdef BOOST_HAS_LONG_LONG + boost::uint64_t ul; +#endif +// float f; +// double d; + + { // test native endian binaries +#if BOOST_ENDIAN_LITTLE_BYTE + BOOST_TEST(test_attr("\x01", byte_, uc) && uc == 0x01); + BOOST_TEST(test_attr("\x01\x02", word, us) && us == 0x0201); + BOOST_TEST(test_attr("\x01\x02\x03\x04", dword, ui) && ui == 0x04030201); +#ifdef BOOST_HAS_LONG_LONG + BOOST_TEST(test_attr("\x01\x02\x03\x04\x05\x06\x07\x08", qword, ul) && + ul == 0x0807060504030201LL); +#endif +// BOOST_TEST(binary_test_attr("\x00\x00\x80\x3f", 4, bin_float, f) && +// f == 1.0f); +// BOOST_TEST(binary_test_attr("\x00\x00\x00\x00\x00\x00\xf0\x3f", +// 8, bin_double, d) && f == 1.0); +#else + BOOST_TEST(test_attr("\x01", byte_, uc) && uc == 0x01); + BOOST_TEST(test_attr("\x01\x02", word, us) && us == 0x0102); + BOOST_TEST(test_attr("\x01\x02\x03\x04", dword, ui) && ui == 0x01020304); +#ifdef BOOST_HAS_LONG_LONG + BOOST_TEST(test_attr("\x01\x02\x03\x04\x05\x06\x07\x08", qword, ul) && + ul == 0x0102030405060708LL); +#endif +// BOOST_TEST(binary_test_attr("\x3f\x80\x00\x00", 4, bin_float, f) && +// f == 1.0f); +// BOOST_TEST(binary_test_attr("\x3f\xf0\x00\x00\x00\x00\x00\x00", +// 8, bin_double, d) && f == 1.0); +#endif + } + + { // test native endian binaries +#if BOOST_ENDIAN_LITTLE_BYTE + BOOST_TEST(test("\x01", byte_(0x01))); + BOOST_TEST(test("\x01\x02", word(0x0201))); + BOOST_TEST(test("\x01\x02\x03\x04", dword(0x04030201))); +#ifdef BOOST_HAS_LONG_LONG + BOOST_TEST(test("\x01\x02\x03\x04\x05\x06\x07\x08", + qword(0x0807060504030201LL))); +#endif +// BOOST_TEST(binary_test("\x00\x00\x80\x3f", 4, bin_float(1.0f))); +// BOOST_TEST(binary_test("\x00\x00\x00\x00\x00\x00\xf0\x3f", 8, +// bin_double(1.0))); +#else + BOOST_TEST(test("\x01", byte_(0x01))); + BOOST_TEST(test("\x01\x02", word(0x0102))); + BOOST_TEST(test("\x01\x02\x03\x04", dword(0x01020304))); +#ifdef BOOST_HAS_LONG_LONG + BOOST_TEST(test("\x01\x02\x03\x04\x05\x06\x07\x08", + qword(0x0102030405060708LL))); +#endif +// BOOST_TEST(binary_test("\x3f\x80\x00\x00", 4, bin_float(1.0f))); +// BOOST_TEST(binary_test("\x3f\x80\x00\x00\x00\x00\x00\x00", 8, +// bin_double(1.0))); +#endif + } + + { // test big endian binaries + BOOST_TEST(test_attr("\x01\x02", big_word, us) && us == 0x0102); + BOOST_TEST(test_attr("\x01\x02\x03\x04", big_dword, ui) && ui == 0x01020304); +#ifdef BOOST_HAS_LONG_LONG + BOOST_TEST(test_attr("\x01\x02\x03\x04\x05\x06\x07\x08", big_qword, ul) + && ul == 0x0102030405060708LL); +#endif +// BOOST_TEST(binary_test_attr("\x3f\x80\x00\x00", 4, big_bin_float, f) && +// f == 1.0f); +// BOOST_TEST(binary_test_attr("\x3f\xf0\x00\x00\x00\x00\x00\x00", +// 8, big_bin_double, d) && f == 1.0); + } + + { + BOOST_TEST(test("\x01\x02", big_word(0x0102))); + BOOST_TEST(test("\x01\x02\x03\x04", big_dword(0x01020304))); +#ifdef BOOST_HAS_LONG_LONG + BOOST_TEST(test("\x01\x02\x03\x04\x05\x06\x07\x08", + big_qword(0x0102030405060708LL))); +#endif +// BOOST_TEST(binary_test("\x3f\x80\x00\x00", 4, big_bin_float(1.0f))); +// BOOST_TEST(binary_test("\x3f\xf0\x00\x00\x00\x00\x00\x00", 8, +// big_bin_double(1.0))); + } + + { // test little endian binaries + BOOST_TEST(test_attr("\x01\x02", little_word, us) && us == 0x0201); + BOOST_TEST(test_attr("\x01\x02\x03\x04", little_dword, ui) && ui == 0x04030201); +#ifdef BOOST_HAS_LONG_LONG + BOOST_TEST(test_attr("\x01\x02\x03\x04\x05\x06\x07\x08", little_qword, ul) + && ul == 0x0807060504030201LL); +#endif +// BOOST_TEST(binary_test_attr("\x00\x00\x80\x3f", 4, +// little_bin_float, f) && f == 1.0f); +// BOOST_TEST(binary_test_attr("\x00\x00\x00\x00\x00\x00\xf0\x3f", +// 8, little_bin_double, d) && f == 1.0); + } + + { + BOOST_TEST(test("\x01\x02", little_word(0x0201))); + BOOST_TEST(test("\x01\x02\x03\x04", little_dword(0x04030201))); +#ifdef BOOST_HAS_LONG_LONG + BOOST_TEST(test("\x01\x02\x03\x04\x05\x06\x07\x08", + little_qword(0x0807060504030201LL))); +#endif +// BOOST_TEST(binary_test("\x00\x00\x80\x3f", 4, little_bin_float(1.0f))); +// BOOST_TEST(binary_test("\x00\x00\x00\x00\x00\x00\xf0\x3f", 8, +// little_bin_double(1.0))); + } + + return boost::report_errors(); +} diff --git a/src/boost/libs/spirit/test/x3/bool.cpp b/src/boost/libs/spirit/test/x3/bool.cpp new file mode 100644 index 00000000..61c357f8 --- /dev/null +++ b/src/boost/libs/spirit/test/x3/bool.cpp @@ -0,0 +1,83 @@ +/*============================================================================= + Copyright (c) 2001-2011 Hartmut Kaiser + Copyright (c) 2011 Bryce Lelbach + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#include "bool.hpp" + +int main() +{ + using spirit_test::test_attr; + using spirit_test::test; + using boost::spirit::x3::bool_; + + { + BOOST_TEST(test("true", bool_)); + BOOST_TEST(test("false", bool_)); + BOOST_TEST(!test("fasle", bool_)); + } + + { + using boost::spirit::x3::true_; + using boost::spirit::x3::false_; + + BOOST_TEST(test("true", true_)); + BOOST_TEST(!test("true", false_)); + BOOST_TEST(test("false", false_)); + BOOST_TEST(!test("false", true_)); + } + + { + using boost::spirit::x3::true_; + using boost::spirit::x3::false_; + using boost::spirit::x3::no_case; + + BOOST_TEST(test("True", no_case[bool_])); + BOOST_TEST(test("False", no_case[bool_])); + BOOST_TEST(test("True", no_case[true_])); + BOOST_TEST(test("False", no_case[false_])); + } + + { + bool b = false; + BOOST_TEST(test_attr("true", bool_, b) && b); + BOOST_TEST(test_attr("false", bool_, b) && !b); + BOOST_TEST(!test_attr("fasle", bool_, b)); + } + + { + typedef boost::spirit::x3::bool_parser<bool, boost::spirit::char_encoding::standard, backwards_bool_policies> + backwards_bool_type; + backwards_bool_type const backwards_bool = backwards_bool_type(); + + BOOST_TEST(test("true", backwards_bool)); + BOOST_TEST(test("eurt", backwards_bool)); + BOOST_TEST(!test("false", backwards_bool)); + BOOST_TEST(!test("fasle", backwards_bool)); + + bool b = false; + BOOST_TEST(test_attr("true", backwards_bool, b) && b); + BOOST_TEST(test_attr("eurt", backwards_bool, b) && !b); + BOOST_TEST(!test_attr("false", backwards_bool, b)); + BOOST_TEST(!test_attr("fasle", backwards_bool, b)); + } + + { + typedef boost::spirit::x3::bool_parser<test_bool_type, boost::spirit::char_encoding::standard> + bool_test_type; + bool_test_type const test_bool = bool_test_type(); + + BOOST_TEST(test("true", test_bool)); + BOOST_TEST(test("false", test_bool)); + BOOST_TEST(!test("fasle", test_bool)); + + test_bool_type b = false; + BOOST_TEST(test_attr("true", test_bool, b) && b.b); + BOOST_TEST(test_attr("false", test_bool, b) && !b.b); + BOOST_TEST(!test_attr("fasle", test_bool, b)); + } + + return boost::report_errors(); +} diff --git a/src/boost/libs/spirit/test/x3/bool.hpp b/src/boost/libs/spirit/test/x3/bool.hpp new file mode 100644 index 00000000..f06b884c --- /dev/null +++ b/src/boost/libs/spirit/test/x3/bool.hpp @@ -0,0 +1,41 @@ +/*============================================================================= + Copyright (c) 2001-2011 Hartmut Kaiser + Copyright (c) 2011 Bryce Lelbach + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(BOOST_SPIRIT_TEST_QI_BOOL) +#define BOOST_SPIRIT_TEST_QI_BOOL + +#include <boost/detail/lightweight_test.hpp> +#include <boost/spirit/home/x3.hpp> +#include "test.hpp" + +/////////////////////////////////////////////////////////////////////////////// +struct backwards_bool_policies : boost::spirit::x3::bool_policies<> +{ + // we want to interpret a 'true' spelled backwards as 'false' + template <typename Iterator, typename Attribute, typename CaseCompare> + static bool + parse_false(Iterator& first, Iterator const& last, Attribute& attr, CaseCompare const& case_compare) + { + namespace spirit = boost::spirit; + namespace x3 = boost::spirit::x3; + if (x3::detail::string_parse("eurt", first, last, x3::unused, case_compare)) + { + x3::traits::move_to(false, attr); // result is false + return true; + } + return false; + } +}; + +/////////////////////////////////////////////////////////////////////////////// +struct test_bool_type +{ + test_bool_type(bool b = false) : b(b) {} // provide conversion + bool b; +}; + +#endif diff --git a/src/boost/libs/spirit/test/x3/char1.cpp b/src/boost/libs/spirit/test/x3/char1.cpp new file mode 100644 index 00000000..b835e48d --- /dev/null +++ b/src/boost/libs/spirit/test/x3/char1.cpp @@ -0,0 +1,198 @@ +/*============================================================================= + Copyright (c) 2001-2015 Joel de Guzman + Copyright (c) 2001-2011 Hartmut Kaiser + Copyright (c) 2019 Christian Mazakas + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +=============================================================================*/ + +#define BOOST_SPIRIT_X3_UNICODE + +#include <boost/detail/lightweight_test.hpp> +#include <boost/spirit/home/x3.hpp> + +#include <boost/utility/string_view.hpp> + +#include <iostream> +#include <vector> +#include <algorithm> + +#include "test.hpp" + +int +main() +{ + using spirit_test::test; + + { + using namespace boost::spirit::x3::ascii; + + BOOST_TEST(test("x", 'x')); + BOOST_TEST(test(L"x", L'x')); + BOOST_TEST(!test("y", 'x')); + BOOST_TEST(!test(L"y", L'x')); + + BOOST_TEST(test("x", char_)); + BOOST_TEST(test("x", char_('x'))); + BOOST_TEST(!test("x", char_('y'))); + BOOST_TEST(test("x", char_('a', 'z'))); + BOOST_TEST(!test("x", char_('0', '9'))); + + BOOST_TEST(test("0", char_('0', '9'))); + BOOST_TEST(test("9", char_('0', '9'))); + BOOST_TEST(!test("0", ~char_('0', '9'))); + BOOST_TEST(!test("9", ~char_('0', '9'))); + + BOOST_TEST(!test("x", ~char_)); + BOOST_TEST(!test("x", ~char_('x'))); + BOOST_TEST(test(" ", ~char_('x'))); + BOOST_TEST(test("X", ~char_('x'))); + BOOST_TEST(!test("x", ~char_('b', 'y'))); + BOOST_TEST(test("a", ~char_('b', 'y'))); + BOOST_TEST(test("z", ~char_('b', 'y'))); + + BOOST_TEST(test("x", ~~char_)); + BOOST_TEST(test("x", ~~char_('x'))); + BOOST_TEST(!test(" ", ~~char_('x'))); + BOOST_TEST(!test("X", ~~char_('x'))); + BOOST_TEST(test("x", ~~char_('b', 'y'))); + BOOST_TEST(!test("a", ~~char_('b', 'y'))); + BOOST_TEST(!test("z", ~~char_('b', 'y'))); + } + + { + using namespace boost::spirit::x3::ascii; + + BOOST_TEST(test(" x", 'x', space)); + BOOST_TEST(test(L" x", L'x', space)); + + BOOST_TEST(test(" x", char_, space)); + BOOST_TEST(test(" x", char_('x'), space)); + BOOST_TEST(!test(" x", char_('y'), space)); + BOOST_TEST(test(" x", char_('a', 'z'), space)); + BOOST_TEST(!test(" x", char_('0', '9'), space)); + } + + { + using namespace boost::spirit::x3::standard_wide; + + BOOST_TEST(test(L"x", char_)); + BOOST_TEST(test(L"x", char_(L'x'))); + BOOST_TEST(!test(L"x", char_(L'y'))); + BOOST_TEST(test(L"x", char_(L'a', L'z'))); + BOOST_TEST(!test(L"x", char_(L'0', L'9'))); + + BOOST_TEST(!test(L"x", ~char_)); + BOOST_TEST(!test(L"x", ~char_(L'x'))); + BOOST_TEST(test(L" ", ~char_(L'x'))); + BOOST_TEST(test(L"X", ~char_(L'x'))); + BOOST_TEST(!test(L"x", ~char_(L'b', L'y'))); + BOOST_TEST(test(L"a", ~char_(L'b', L'y'))); + BOOST_TEST(test(L"z", ~char_(L'b', L'y'))); + + BOOST_TEST(test(L"x", ~~char_)); + BOOST_TEST(test(L"x", ~~char_(L'x'))); + BOOST_TEST(!test(L" ", ~~char_(L'x'))); + BOOST_TEST(!test(L"X", ~~char_(L'x'))); + BOOST_TEST(test(L"x", ~~char_(L'b', L'y'))); + BOOST_TEST(!test(L"a", ~~char_(L'b', L'y'))); + BOOST_TEST(!test(L"z", ~~char_(L'b', L'y'))); + } + + // unicode (normal ASCII) + { + using namespace boost::spirit::x3::unicode; + + BOOST_TEST(test(U"abcd", +char_(U"abcd"))); + BOOST_TEST(!test(U"abcd", +char_(U"qwer"))); + + auto const sub_delims = char_(U"!$&'()*+,;="); + + auto const delims = + std::vector<boost::u32string_view>{U"!", U"$", U"&", U"'", U"(", U")", U"*", U"+", + U",", U";", U"="}; + + auto const matched_all_sub_delims = + std::all_of(delims.begin(), delims.end(), [&](auto const delim) -> bool { + return test(delim, sub_delims); + }); + + BOOST_TEST(matched_all_sub_delims); + } + + // unicode (escaped Unicode char literals) + { + using namespace boost::spirit::x3::unicode; + + auto const chars = char_(U"\u0024\u00a2\u0939\u20ac\U00010348"); + + auto const test_strings = + std::vector<boost::u32string_view>{U"\u0024", U"\u00a2", U"\u0939", U"\u20ac", + U"\U00010348"}; + + auto const bad_test_strings = std::vector<boost::u32string_view>{U"a", U"B", U"c", U"\u0409"}; + + auto const all_matched = + std::all_of(test_strings.begin(), test_strings.end(), [&](auto const test_str) -> bool { + return test(test_str, chars); + }); + + auto const none_matched = + std::all_of(bad_test_strings.begin(), bad_test_strings.end(), [&](auto const bad_test_str) -> bool { + return !test(bad_test_str, chars); + }); + + BOOST_TEST(all_matched); + BOOST_TEST(none_matched); + } + + + { // single char strings! + namespace ascii = boost::spirit::x3::ascii; + namespace wide = boost::spirit::x3::standard_wide; + + BOOST_TEST(test("x", "x")); + BOOST_TEST(test(L"x", L"x")); + BOOST_TEST(test("x", ascii::char_("x"))); + BOOST_TEST(test(L"x", wide::char_(L"x"))); + + BOOST_TEST(test("x", ascii::char_("a", "z"))); + BOOST_TEST(test(L"x", wide::char_(L"a", L"z"))); + } + + { + // chsets + namespace ascii = boost::spirit::x3::ascii; + namespace wide = boost::spirit::x3::standard_wide; + + BOOST_TEST(test("x", ascii::char_("a-z"))); + BOOST_TEST(!test("1", ascii::char_("a-z"))); + BOOST_TEST(test("1", ascii::char_("a-z0-9"))); + + BOOST_TEST(test("x", wide::char_(L"a-z"))); + BOOST_TEST(!test("1", wide::char_(L"a-z"))); + BOOST_TEST(test("1", wide::char_(L"a-z0-9"))); + + std::string set = "a-z0-9"; + BOOST_TEST(test("x", ascii::char_(set))); + +#ifdef SPIRIT_NO_COMPILE_CHECK + test("", ascii::char_(L"a-z0-9")); +#endif + } + + { + namespace ascii = boost::spirit::x3::ascii; + char const* input = "\x80"; + + // ascii > 7 bits (this should fail, not assert!) + BOOST_TEST(!test(input, ascii::char_)); + BOOST_TEST(!test(input, ascii::char_('a'))); + BOOST_TEST(!test(input, ascii::alnum)); + BOOST_TEST(!test(input, ascii::char_("a-z"))); + BOOST_TEST(!test(input, ascii::char_('0', '9'))); + } + + return boost::report_errors(); +} diff --git a/src/boost/libs/spirit/test/x3/char_class.cpp b/src/boost/libs/spirit/test/x3/char_class.cpp new file mode 100644 index 00000000..a151d5c8 --- /dev/null +++ b/src/boost/libs/spirit/test/x3/char_class.cpp @@ -0,0 +1,248 @@ +/*============================================================================= + Copyright (c) 2001-2015 Joel de Guzman + Copyright (c) 2001-2010 Hartmut Kaiser + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +=============================================================================*/ + +#define BOOST_SPIRIT_X3_UNICODE + +#include <boost/detail/lightweight_test.hpp> +#include <boost/spirit/home/x3.hpp> +#include <boost/type_traits/is_same.hpp> + +#include <iostream> +#include "test.hpp" + +int +main() +{ + using spirit_test::test; + using spirit_test::test_failure; + using spirit_test::test_attr; + + using boost::spirit::x3::unused_type; + + { + using namespace boost::spirit::x3::ascii; + BOOST_TEST(test("1", alnum)); + BOOST_TEST(!test(" ", alnum)); + BOOST_TEST(!test("1", alpha)); + BOOST_TEST(test("x", alpha)); + BOOST_TEST(test(" ", blank)); + BOOST_TEST(!test("x", blank)); + BOOST_TEST(test("1", digit)); + BOOST_TEST(!test("x", digit)); + BOOST_TEST(test("a", lower)); + BOOST_TEST(!test("A", lower)); + BOOST_TEST(test("!", punct)); + BOOST_TEST(!test("x", punct)); + BOOST_TEST(test(" ", space)); + BOOST_TEST(test("\n", space)); + BOOST_TEST(test("\r", space)); + BOOST_TEST(test("\t", space)); + BOOST_TEST(test("A", upper)); + BOOST_TEST(!test("a", upper)); + BOOST_TEST(test("A", xdigit)); + BOOST_TEST(test("0", xdigit)); + BOOST_TEST(test("f", xdigit)); + BOOST_TEST(!test("g", xdigit)); + } + + { + using namespace boost::spirit::x3::ascii; + BOOST_TEST(!test("1", ~alnum)); + BOOST_TEST(test(" ", ~alnum)); + BOOST_TEST(test("1", ~alpha)); + BOOST_TEST(!test("x", ~alpha)); + BOOST_TEST(!test(" ", ~blank)); + BOOST_TEST(test("x", ~blank)); + BOOST_TEST(!test("1", ~digit)); + BOOST_TEST(test("x", ~digit)); + BOOST_TEST(!test("a", ~lower)); + BOOST_TEST(test("A", ~lower)); + BOOST_TEST(!test("!", ~punct)); + BOOST_TEST(test("x", ~punct)); + BOOST_TEST(!test(" ", ~space)); + BOOST_TEST(!test("\n", ~space)); + BOOST_TEST(!test("\r", ~space)); + BOOST_TEST(!test("\t", ~space)); + BOOST_TEST(!test("A", ~upper)); + BOOST_TEST(test("a", ~upper)); + BOOST_TEST(!test("A", ~xdigit)); + BOOST_TEST(!test("0", ~xdigit)); + BOOST_TEST(!test("f", ~xdigit)); + BOOST_TEST(test("g", ~xdigit)); + } + + { + using namespace boost::spirit::x3::iso8859_1; + BOOST_TEST(test("1", alnum)); + BOOST_TEST(!test(" ", alnum)); + BOOST_TEST(!test("1", alpha)); + BOOST_TEST(test("x", alpha)); + BOOST_TEST(test(" ", blank)); + BOOST_TEST(!test("x", blank)); + BOOST_TEST(test("1", digit)); + BOOST_TEST(!test("x", digit)); + BOOST_TEST(test("a", lower)); + BOOST_TEST(!test("A", lower)); + BOOST_TEST(test("!", punct)); + BOOST_TEST(!test("x", punct)); + BOOST_TEST(test(" ", space)); + BOOST_TEST(test("\n", space)); + BOOST_TEST(test("\r", space)); + BOOST_TEST(test("\t", space)); + BOOST_TEST(test("A", upper)); + BOOST_TEST(!test("a", upper)); + BOOST_TEST(test("A", xdigit)); + BOOST_TEST(test("0", xdigit)); + BOOST_TEST(test("f", xdigit)); + BOOST_TEST(!test("g", xdigit)); + + // test extended ASCII characters + BOOST_TEST(test("\xE9", alpha)); + BOOST_TEST(test("\xE9", lower)); + BOOST_TEST(!test("\xE9", upper)); + } + + { + using namespace boost::spirit::x3::standard; + BOOST_TEST(test("1", alnum)); + BOOST_TEST(!test(" ", alnum)); + BOOST_TEST(!test("1", alpha)); + BOOST_TEST(test("x", alpha)); + BOOST_TEST(test(" ", blank)); + BOOST_TEST(!test("x", blank)); + BOOST_TEST(test("1", digit)); + BOOST_TEST(!test("x", digit)); + BOOST_TEST(test("a", lower)); + BOOST_TEST(!test("A", lower)); + BOOST_TEST(test("!", punct)); + BOOST_TEST(!test("x", punct)); + BOOST_TEST(test(" ", space)); + BOOST_TEST(test("\n", space)); + BOOST_TEST(test("\r", space)); + BOOST_TEST(test("\t", space)); + BOOST_TEST(test("A", upper)); + BOOST_TEST(!test("a", upper)); + BOOST_TEST(test("A", xdigit)); + BOOST_TEST(test("0", xdigit)); + BOOST_TEST(test("f", xdigit)); + BOOST_TEST(!test("g", xdigit)); + } + + { + using namespace boost::spirit::x3::standard_wide; + BOOST_TEST(test(L"1", alnum)); + BOOST_TEST(!test(L" ", alnum)); + BOOST_TEST(!test(L"1", alpha)); + BOOST_TEST(test(L"x", alpha)); + BOOST_TEST(test(L" ", blank)); + BOOST_TEST(!test(L"x", blank)); + BOOST_TEST(test(L"1", digit)); + BOOST_TEST(!test(L"x", digit)); + BOOST_TEST(test(L"a", lower)); + BOOST_TEST(!test(L"A", lower)); + BOOST_TEST(test(L"!", punct)); + BOOST_TEST(!test(L"x", punct)); + BOOST_TEST(test(L" ", space)); + BOOST_TEST(test(L"\n", space)); + BOOST_TEST(test(L"\r", space)); + BOOST_TEST(test(L"\t", space)); + BOOST_TEST(test(L"A", upper)); + BOOST_TEST(!test(L"a", upper)); + BOOST_TEST(test(L"A", xdigit)); + BOOST_TEST(test(L"0", xdigit)); + BOOST_TEST(test(L"f", xdigit)); + BOOST_TEST(!test(L"g", xdigit)); + } + + { + using namespace boost::spirit::x3::unicode; + BOOST_TEST(test(L"1", alnum)); + BOOST_TEST(!test(L" ", alnum)); + BOOST_TEST(!test(L"1", alpha)); + BOOST_TEST(test(L"x", alpha)); + BOOST_TEST(test(L" ", blank)); + BOOST_TEST(!test(L"x", blank)); + BOOST_TEST(test(L"1", digit)); + BOOST_TEST(!test(L"x", digit)); + BOOST_TEST(test(L"a", lower)); + BOOST_TEST(!test(L"A", lower)); + BOOST_TEST(test(L"!", punct)); + BOOST_TEST(!test(L"x", punct)); + BOOST_TEST(test(L" ", space)); + BOOST_TEST(test(L"\n", space)); + BOOST_TEST(test(L"\r", space)); + BOOST_TEST(test(L"\t", space)); + BOOST_TEST(test(L"A", upper)); + BOOST_TEST(!test(L"a", upper)); + BOOST_TEST(test(L"A", xdigit)); + BOOST_TEST(test(L"0", xdigit)); + BOOST_TEST(test(L"f", xdigit)); + BOOST_TEST(!test(L"g", xdigit)); + + BOOST_TEST(test(L"A", alphabetic)); + BOOST_TEST(test(L"9", decimal_number)); + BOOST_TEST(test(L"\u2800", braille)); + BOOST_TEST(!test(L" ", braille)); + BOOST_TEST(test(L" ", ~braille)); + // $$$ TODO $$$ Add more unicode tests + } + + { // test invalid unicode literals + using namespace boost::spirit::x3::unicode; + + auto const invalid_unicode = char32_t{0x7FFFFFFF}; + auto const input = boost::u32string_view(&invalid_unicode, 1); + + BOOST_TEST(test_failure(input, char_)); + + // force unicode category lookup + // related issue: https://github.com/boostorg/spirit/issues/524 + BOOST_TEST(test_failure(input, alpha)); + BOOST_TEST(test_failure(input, upper)); + BOOST_TEST(test_failure(input, lower)); + } + + { // test attribute extraction + using boost::spirit::x3::traits::attribute_of; + using boost::spirit::x3::iso8859_1::alpha; + using boost::spirit::x3::iso8859_1::alpha_type; + + static_assert( + boost::is_same< + attribute_of<alpha_type, unused_type>::type + , unsigned char>::value + , "Wrong attribute type!" + ); + + int attr = 0; + BOOST_TEST(test_attr("a", alpha, attr)); + BOOST_TEST(attr == 'a'); + } + + { // test attribute extraction + using boost::spirit::x3::iso8859_1::alpha; + using boost::spirit::x3::iso8859_1::space; + char attr = 0; + BOOST_TEST(test_attr(" a", alpha, attr, space)); + BOOST_TEST(attr == 'a'); + } + + { // test action + using namespace boost::spirit::x3::ascii; + using boost::spirit::x3::_attr; + char ch; + auto f = [&](auto& ctx){ ch = _attr(ctx); }; + + BOOST_TEST(test("x", alnum[f])); + BOOST_TEST(ch == 'x'); + BOOST_TEST(test(" A", alnum[f], space)); + BOOST_TEST(ch == 'A'); + } + + return boost::report_errors(); +} diff --git a/src/boost/libs/spirit/test/x3/confix.cpp b/src/boost/libs/spirit/test/x3/confix.cpp new file mode 100644 index 00000000..40bce11b --- /dev/null +++ b/src/boost/libs/spirit/test/x3/confix.cpp @@ -0,0 +1,84 @@ +/*============================================================================= + Copyright (c) 2009 Chris Hoeppler + Copyright (c) 2014 Lee Clagett + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +=============================================================================*/ +#include <boost/detail/lightweight_test.hpp> + +#include <boost/spirit/home/x3/char.hpp> +#include <boost/spirit/home/x3/core.hpp> +#include <boost/spirit/home/x3/numeric.hpp> +#include <boost/spirit/home/x3/operator.hpp> +#include <boost/spirit/home/x3/string.hpp> +#include <boost/spirit/home/x3/directive/confix.hpp> + +#include "test.hpp" + +int main() +{ + namespace x3 = boost::spirit::x3; + using namespace spirit_test; + + { + const auto comment = x3::confix("/*", "*/"); + + BOOST_TEST(test_failure("/abcdef*/", comment["abcdef"])); + BOOST_TEST(test_failure("/* abcdef*/", comment["abcdef"])); + BOOST_TEST(test_failure("/*abcdef */", comment["abcdef"])); + BOOST_TEST(test("/*abcdef*/", comment["abcdef"])); + + { + unsigned value = 0; + BOOST_TEST( + test_attr(" /* 123 */ ", comment[x3::uint_], value, x3::space)); + BOOST_TEST(value == 123); + + using x3::_attr; + value = 0; + const auto lambda = [&value](auto& ctx ){ value = _attr(ctx) + 1; }; + BOOST_TEST(test_attr("/*123*/", comment[x3::uint_][lambda], value)); + BOOST_TEST(value == 124); + } + } + { + const auto array = x3::confix('[', ']'); + + { + std::vector<unsigned> values; + + BOOST_TEST(test("[0,2,4,6,8]", array[x3::uint_ % ','])); + BOOST_TEST(test_attr("[0,2,4,6,8]", array[x3::uint_ % ','], values)); + BOOST_TEST( + values.size() == 5 && + values[0] == 0 && + values[1] == 2 && + values[2] == 4 && + values[3] == 6 && + values[4] == 8); + } + { + std::vector<std::vector<unsigned>> values; + BOOST_TEST( + test("[[1,3,5],[0,2,4]]", array[array[x3::uint_ % ','] % ','])); + BOOST_TEST( + test_attr( + "[[1,3,5],[0,2,4]]", + array[array[x3::uint_ % ','] % ','], + values)); + BOOST_TEST( + values.size() == 2 && + values[0].size() == 3 && + values[0][0] == 1 && + values[0][1] == 3 && + values[0][2] == 5 && + values[1].size() == 3 && + values[1][0] == 0 && + values[1][1] == 2 && + values[1][2] == 4); + } + } + + return boost::report_errors(); +} diff --git a/src/boost/libs/spirit/test/x3/container_support.cpp b/src/boost/libs/spirit/test/x3/container_support.cpp new file mode 100644 index 00000000..f8c79f1d --- /dev/null +++ b/src/boost/libs/spirit/test/x3/container_support.cpp @@ -0,0 +1,248 @@ +/*============================================================================= + Copyright (c) 2001-2015 Joel de Guzman + Copyright (c) 2001-2011 Hartmut Kaiser + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +=============================================================================*/ +#include <boost/detail/lightweight_test.hpp> +#include <boost/spirit/home/x3.hpp> +#include <boost/fusion/include/std_pair.hpp> + +#include <iostream> +#include <map> +#include <unordered_map> +#include <boost/unordered_map.hpp> +#include <vector> +#include <list> +#include <deque> +#include <set> +#include <unordered_set> +#include <boost/unordered_set.hpp> +#include <string> +#include "test.hpp" + +namespace x3 = boost::spirit::x3; + +x3::rule<class pair_rule, std::pair<std::string,std::string>> const pair_rule("pair"); +x3::rule<class string_rule, std::string> const string_rule("string"); + +auto const pair_rule_def = string_rule > x3::lit('=') > string_rule; +auto const string_rule_def = x3::lexeme[*x3::alnum]; + +BOOST_SPIRIT_DEFINE(pair_rule, string_rule) + +template <typename Container> +void test_map_support() +{ + using spirit_test::test_attr; + + Container container; + Container const compare {{"k1", "v1"}, {"k2", "v2"}}; + auto const rule = pair_rule % x3::lit(','); + + BOOST_TEST(test_attr("k1=v1,k2=v2,k2=v3", rule, container)); + BOOST_TEST(container.size() == 2); + BOOST_TEST(container == compare); + + // test sequences parsing into containers + auto const seq_rule = pair_rule >> ',' >> pair_rule >> ',' >> pair_rule; + container.clear(); + BOOST_TEST(test_attr("k1=v1,k2=v2,k2=v3", seq_rule, container)); + + // test parsing container into container + auto const cic_rule = pair_rule >> +(',' >> pair_rule); + container.clear(); + BOOST_TEST(test_attr("k1=v1,k2=v2,k2=v3", cic_rule, container)); +} + +template <typename Container> +void test_multimap_support() +{ + using spirit_test::test_attr; + + Container container; + Container const compare {{"k1", "v1"}, {"k2", "v2"}, {"k2", "v3"}}; + auto const rule = pair_rule % x3::lit(','); + + BOOST_TEST(test_attr("k1=v1,k2=v2,k2=v3", rule, container)); + BOOST_TEST(container.size() == 3); + BOOST_TEST(container == compare); + + // test sequences parsing into containers + auto const seq_rule = pair_rule >> ',' >> pair_rule >> ',' >> pair_rule; + container.clear(); + BOOST_TEST(test_attr("k1=v1,k2=v2,k2=v3", seq_rule, container)); + + // test parsing container into container + auto const cic_rule = pair_rule >> +(',' >> pair_rule); + container.clear(); + BOOST_TEST(test_attr("k1=v1,k2=v2,k2=v3", cic_rule, container)); +} + +template <typename Container> +void test_sequence_support() +{ + using spirit_test::test_attr; + + Container container; + Container const compare {"e1", "e2", "e2"}; + auto const rule = string_rule % x3::lit(','); + + BOOST_TEST(test_attr("e1,e2,e2", rule, container)); + BOOST_TEST(container.size() == 3); + BOOST_TEST(container == compare); + + // test sequences parsing into containers + auto const seq_rule = string_rule >> ',' >> string_rule >> ',' >> string_rule; + container.clear(); + BOOST_TEST(test_attr("e1,e2,e2", seq_rule, container)); + + // test parsing container into container + auto const cic_rule = string_rule >> +(',' >> string_rule); + container.clear(); + BOOST_TEST(test_attr("e1,e2,e2", cic_rule, container)); +} + +template <typename Container> +void test_set_support() +{ + using spirit_test::test_attr; + + Container container; + Container const compare {"e1", "e2"}; + auto const rule = string_rule % x3::lit(','); + + BOOST_TEST(test_attr("e1,e2,e2", rule, container)); + BOOST_TEST(container.size() == 2); + BOOST_TEST(container == compare); + + // test sequences parsing into containers + auto const seq_rule = string_rule >> ',' >> string_rule >> ',' >> string_rule; + container.clear(); + BOOST_TEST(test_attr("e1,e2,e2", seq_rule, container)); + + // test parsing container into container + auto const cic_rule = string_rule >> +(',' >> string_rule); + container.clear(); + BOOST_TEST(test_attr("e1,e2,e2", cic_rule, container)); +} + +template <typename Container> +void test_multiset_support() +{ + using spirit_test::test_attr; + + Container container; + Container const compare {"e1", "e2", "e2"}; + auto const rule = string_rule % x3::lit(','); + + BOOST_TEST(test_attr("e1,e2,e2", rule, container)); + BOOST_TEST(container.size() == 3); + BOOST_TEST(container == compare); + + // test sequences parsing into containers + auto const seq_rule = string_rule >> ',' >> string_rule >> ',' >> string_rule; + container.clear(); + BOOST_TEST(test_attr("e1,e2,e2", seq_rule, container)); + + // test parsing container into container + auto const cic_rule = string_rule >> +(',' >> string_rule); + container.clear(); + BOOST_TEST(test_attr("e1,e2,e2", cic_rule, container)); +} + +template <typename Container> +void test_string_support() +{ + using spirit_test::test_attr; + + Container container; + Container const compare {"e1e2e2"}; + auto const rule = string_rule % x3::lit(','); + + BOOST_TEST(test_attr("e1,e2,e2", rule, container)); + BOOST_TEST(container.size() == 6); + BOOST_TEST(container == compare); + + // test sequences parsing into containers + auto const seq_rule = string_rule >> ',' >> string_rule >> ',' >> string_rule; + container.clear(); + BOOST_TEST(test_attr("e1,e2,e2", seq_rule, container)); + + // test parsing container into container + auto const cic_rule = string_rule >> +(',' >> string_rule); + container.clear(); + BOOST_TEST(test_attr("e1,e2,e2", cic_rule, container)); +} + +int +main() +{ + using x3::traits::is_associative; + using x3::traits::is_reservable; + + static_assert(is_reservable<std::vector<int>>::value, "is_reservable problem"); + static_assert(is_reservable<std::string>::value, "is_reservable problem"); + static_assert(is_reservable<std::unordered_set<int>>::value, "is_reservable problem"); + static_assert(is_reservable<boost::unordered_set<int>>::value, "is_reservable problem"); + static_assert(is_reservable<std::unordered_multiset<int>>::value, "is_reservable problem"); + static_assert(is_reservable<boost::unordered_multiset<int>>::value, "is_reservable problem"); + static_assert(is_reservable<std::unordered_map<int,int>>::value, "is_reservable problem"); + static_assert(is_reservable<boost::unordered_map<int,int>>::value, "is_reservable problem"); + static_assert(is_reservable<std::unordered_multimap<int,int>>::value, "is_reservable problem"); + static_assert(is_reservable<boost::unordered_multimap<int,int>>::value, "is_reservable problem"); + + static_assert(!is_reservable<std::deque<int>>::value, "is_reservable problem"); + static_assert(!is_reservable<std::list<int>>::value, "is_reservable problem"); + static_assert(!is_reservable<std::set<int>>::value, "is_reservable problem"); + static_assert(!is_reservable<std::multiset<int>>::value, "is_reservable problem"); + static_assert(!is_reservable<std::map<int,int>>::value, "is_reservable problem"); + static_assert(!is_reservable<std::multimap<int,int>>::value, "is_reservable problem"); + + // ------------------------------------------------------------------ + + static_assert(is_associative<std::set<int>>::value, "is_associative problem"); + static_assert(is_associative<std::unordered_set<int>>::value, "is_associative problem"); + static_assert(is_associative<boost::unordered_set<int>>::value, "is_associative problem"); + static_assert(is_associative<std::multiset<int>>::value, "is_associative problem"); + static_assert(is_associative<std::unordered_multiset<int>>::value, "is_associative problem"); + static_assert(is_associative<boost::unordered_multiset<int>>::value, "is_associative problem"); + static_assert(is_associative<std::map<int,int>>::value, "is_associative problem"); + static_assert(is_associative<std::unordered_map<int,int>>::value, "is_associative problem"); + static_assert(is_associative<boost::unordered_map<int,int>>::value, "is_associative problem"); + static_assert(is_associative<std::multimap<int,int>>::value, "is_associative problem"); + static_assert(is_associative<std::unordered_multimap<int,int>>::value, "is_associative problem"); + static_assert(is_associative<boost::unordered_multimap<int,int>>::value, "is_associative problem"); + + static_assert(!is_associative<std::vector<int>>::value, "is_associative problem"); + static_assert(!is_associative<std::string>::value, "is_associative problem"); + static_assert(!is_associative<std::deque<int>>::value, "is_associative problem"); + static_assert(!is_associative<std::list<int>>::value, "is_associative problem"); + + // ------------------------------------------------------------------ + + test_string_support<std::string>(); + + test_sequence_support<std::vector<std::string>>(); + test_sequence_support<std::list<std::string>>(); + test_sequence_support<std::deque<std::string>>(); + + test_set_support<std::set<std::string>>(); + test_set_support<std::unordered_set<std::string>>(); + test_set_support<boost::unordered_set<std::string>>(); + + test_multiset_support<std::multiset<std::string>>(); + test_multiset_support<std::unordered_multiset<std::string>>(); + test_multiset_support<boost::unordered_multiset<std::string>>(); + + test_map_support<std::map<std::string,std::string>>(); + test_map_support<std::unordered_map<std::string,std::string>>(); + test_map_support<boost::unordered_map<std::string,std::string>>(); + + test_multimap_support<std::multimap<std::string,std::string>>(); + test_multimap_support<std::unordered_multimap<std::string,std::string>>(); + test_multimap_support<boost::unordered_multimap<std::string,std::string>>(); + + return boost::report_errors(); +} diff --git a/src/boost/libs/spirit/test/x3/debug.cpp b/src/boost/libs/spirit/test/x3/debug.cpp new file mode 100644 index 00000000..5d3508ac --- /dev/null +++ b/src/boost/libs/spirit/test/x3/debug.cpp @@ -0,0 +1,144 @@ +/*============================================================================= + Copyright (c) 2001-2015 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +=============================================================================*/ +#define BOOST_SPIRIT_X3_DEBUG + +#include <boost/detail/lightweight_test.hpp> +#include <boost/spirit/home/x3.hpp> +#include <boost/fusion/include/std_pair.hpp> +#include <boost/fusion/include/vector.hpp> + +#include <vector> +#include <string> +#include <cstring> +#include <iostream> +#include "test.hpp" + +struct my_error_handler +{ + template <typename Iterator, typename Exception, typename Context> + boost::spirit::x3::error_handler_result + operator()(Iterator&, Iterator const& last, Exception const& x, Context const&) const + { + std::cout + << "Error! Expecting: " + << x.which() + << ", got: \"" + << std::string(x.where(), last) + << "\"" + << std::endl; + return boost::spirit::x3::error_handler_result::fail; + } +}; + +struct my_attribute +{ + bool alive = true; + + void access() const + { + BOOST_TEST(alive); + } + ~my_attribute() + { + alive = false; + } + + friend std::ostream & operator << (std::ostream & os, my_attribute const & attr) + { + attr.access(); + return os << "my_attribute"; + } +}; + +int +main() +{ + using spirit_test::test_attr; + using spirit_test::test; + + using namespace boost::spirit::x3::ascii; + using boost::spirit::x3::rule; + using boost::spirit::x3::symbols; + using boost::spirit::x3::int_; + using boost::spirit::x3::alpha; + + { // basic tests + + auto a = rule<class a>("a") = 'a'; + auto b = rule<class b>("b") = 'b'; + auto c = rule<class c>("c") = 'c'; + + { + auto start = *(a | b | c); + BOOST_TEST(test("abcabcacb", start)); + } + + { + rule<class start> start("start"); + auto start_def = + start = (a | b) >> (start | b); + + BOOST_TEST(test("aaaabababaaabbb", start_def)); + BOOST_TEST(test("aaaabababaaabba", start_def, false)); + } + } + + { // basic tests w/ skipper + + auto a = rule<class a>("a") = 'a'; + auto b = rule<class b>("b") = 'b'; + auto c = rule<class c>("c") = 'c'; + + { + auto start = *(a | b | c); + BOOST_TEST(test(" a b c a b c a c b ", start, space)); + } + + { + rule<class start> start("start"); + auto start_def = + start = (a | b) >> (start | b); + + BOOST_TEST(test(" a a a a b a b a b a a a b b b ", start_def, space)); + BOOST_TEST(test(" a a a a b a b a b a a a b b a ", start_def, space, false)); + } + } + + { // std::container attributes + + typedef boost::fusion::vector<int, char> fs; + rule<class start, std::vector<fs>> start("start"); + auto start_def = + start = *(int_ >> alpha); + + BOOST_TEST(test("1 a 2 b 3 c", start_def, space)); + } + + { // error handling + + auto r_def = '(' > int_ > ',' > int_ > ')'; + auto r = r_def.on_error(my_error_handler()); + + BOOST_TEST(test("(123,456)", r)); + BOOST_TEST(!test("(abc,def)", r)); + BOOST_TEST(!test("(123,456]", r)); + BOOST_TEST(!test("(123;456)", r)); + BOOST_TEST(!test("[123,456]", r)); + } + + { + symbols<my_attribute> a{{{ "a", my_attribute{} }}}; + + auto b = rule<struct b, my_attribute>("b") = a; + + my_attribute attr; + + BOOST_TEST(test_attr("a", b, attr)); + } + + return boost::report_errors(); +} diff --git a/src/boost/libs/spirit/test/x3/difference.cpp b/src/boost/libs/spirit/test/x3/difference.cpp new file mode 100644 index 00000000..5581cdea --- /dev/null +++ b/src/boost/libs/spirit/test/x3/difference.cpp @@ -0,0 +1,66 @@ +/*============================================================================= + Copyright (c) 2001-2015 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +=============================================================================*/ +#include <boost/detail/lightweight_test.hpp> +#include <boost/spirit/home/x3.hpp> + +#include <string> +#include <iostream> +#include "test.hpp" + +int +main() +{ + using boost::spirit::x3::ascii::char_; + using boost::spirit::x3::ascii::space; + using boost::spirit::x3::lit; + using spirit_test::test; + using spirit_test::test_attr; + + // Basic tests + { + BOOST_TEST(test("b", char_ - 'a')); + BOOST_TEST(!test("a", char_ - 'a')); + BOOST_TEST(test("/* abcdefghijk */", "/*" >> *(char_ - "*/") >> "*/")); + BOOST_TEST(!test("switch", lit("switch") - "switch")); + } + + // Test attributes + { + char attr; + BOOST_TEST(test_attr("xg", (char_ - 'g') >> 'g', attr)); + BOOST_TEST(attr == 'x'); + } + + // Test handling of container attributes + { + std::string attr; + BOOST_TEST(test_attr("abcdefg", *(char_ - 'g') >> 'g', attr)); + BOOST_TEST(attr == "abcdef"); + } + + { + using boost::spirit::x3::_attr; + + std::string s; + + BOOST_TEST(test( + "/*abcdefghijk*/" + , "/*" >> *(char_ - "*/")[([&](auto& ctx){ s += _attr(ctx); })] >> "*/" + )); + BOOST_TEST(s == "abcdefghijk"); + s.clear(); + + BOOST_TEST(test( + " /*abcdefghijk*/" + , "/*" >> *(char_ - "*/")[([&](auto& ctx){ s += _attr(ctx); })] >> "*/" + , space + )); + BOOST_TEST(s == "abcdefghijk"); + } + + return boost::report_errors(); +} diff --git a/src/boost/libs/spirit/test/x3/eoi.cpp b/src/boost/libs/spirit/test/x3/eoi.cpp new file mode 100644 index 00000000..41de6d04 --- /dev/null +++ b/src/boost/libs/spirit/test/x3/eoi.cpp @@ -0,0 +1,29 @@ +/*============================================================================= + Copyright (c) 2001-2015 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +=============================================================================*/ +#include <boost/detail/lightweight_test.hpp> +#include <boost/spirit/home/x3.hpp> + +#include <iostream> +#include "test.hpp" + +int +main() +{ + using spirit_test::test; + using boost::spirit::x3::eoi; + + { + BOOST_TEST((test("", eoi))); + BOOST_TEST(!(test("x", eoi))); + } + + { + BOOST_TEST(what(eoi) == "eoi"); + } + + return boost::report_errors(); +} diff --git a/src/boost/libs/spirit/test/x3/eol.cpp b/src/boost/libs/spirit/test/x3/eol.cpp new file mode 100644 index 00000000..d363a621 --- /dev/null +++ b/src/boost/libs/spirit/test/x3/eol.cpp @@ -0,0 +1,32 @@ +/*============================================================================= + Copyright (c) 2001-2015 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +=============================================================================*/ +#include <boost/detail/lightweight_test.hpp> +#include <boost/spirit/home/x3.hpp> + +#include <iostream> +#include "test.hpp" + +int +main() +{ + using spirit_test::test; + using boost::spirit::x3::eol; + + { + BOOST_TEST((test("\r\n", eol))); + BOOST_TEST((test("\r", eol))); + BOOST_TEST((test("\n", eol))); + BOOST_TEST((!test("\n\r", eol))); + BOOST_TEST((!test("", eol))); + } + + { + BOOST_TEST(what(eol) == "eol"); + } + + return boost::report_errors(); +} diff --git a/src/boost/libs/spirit/test/x3/eps.cpp b/src/boost/libs/spirit/test/x3/eps.cpp new file mode 100644 index 00000000..d4bfac28 --- /dev/null +++ b/src/boost/libs/spirit/test/x3/eps.cpp @@ -0,0 +1,44 @@ +/*============================================================================= + Copyright (c) 2001-2015 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +=============================================================================*/ +#include <boost/detail/lightweight_test.hpp> +#include <boost/spirit/home/x3.hpp> + +#include <iostream> +#include "test.hpp" + +int +main() +{ + using spirit_test::test; + using boost::spirit::x3::eps; + using boost::spirit::x3::unused_type; + + { + BOOST_TEST((test("", eps))); + BOOST_TEST((test("xxx", eps, false))); + //~ BOOST_TEST((!test("", !eps))); // not predicate $$$ Implement me! $$$ + } + + { // test non-lazy semantic predicate + + BOOST_TEST((test("", eps(true)))); + BOOST_TEST((!test("", eps(false)))); + BOOST_TEST((test("", !eps(false)))); + } + + { // test lazy semantic predicate + + auto true_ = [](unused_type) { return true; }; + auto false_ = [](unused_type) { return false; }; + + BOOST_TEST((test("", eps(true_)))); + BOOST_TEST((!test("", eps(false_)))); + BOOST_TEST((test("", !eps(false_)))); + } + + return boost::report_errors(); +} diff --git a/src/boost/libs/spirit/test/x3/error_handler.cpp b/src/boost/libs/spirit/test/x3/error_handler.cpp new file mode 100644 index 00000000..d22949fd --- /dev/null +++ b/src/boost/libs/spirit/test/x3/error_handler.cpp @@ -0,0 +1,57 @@ +/*============================================================================= + Copyright (c) 2001-2015 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +=============================================================================*/ + +#include <boost/detail/lightweight_test.hpp> +#include <boost/spirit/home/x3.hpp> +#include <boost/spirit/home/x3/support/utility/annotate_on_success.hpp> +#include <string> +#include <sstream> + +namespace x3 = boost::spirit::x3; + +struct error_handler_base +{ + template <typename Iterator, typename Exception, typename Context> + x3::error_handler_result on_error( + Iterator&, Iterator const& + , Exception const& x, Context const& context) const + { + std::string message = "Error! Expecting: " + x.which() + " here:"; + auto& error_handler = x3::get<x3::error_handler_tag>(context).get(); + error_handler(x.where(), message); + return x3::error_handler_result::fail; + } +}; + +struct test_rule_class : x3::annotate_on_success, error_handler_base {}; + +x3::rule<test_rule_class> const test_rule; +auto const test_rule_def = x3::lit("foo") > x3::lit("bar") > x3::lit("git"); + +BOOST_SPIRIT_DEFINE(test_rule) + +void test(std::string const& line_break) { + std::string const input("foo" + line_break + " foo" + line_break + "git"); + auto const begin = std::begin(input); + auto const end = std::end(input); + + std::stringstream stream; + x3::error_handler<std::string::const_iterator> error_handler{begin, end, stream}; + + auto const parser = x3::with<x3::error_handler_tag>(std::ref(error_handler))[test_rule]; + x3::phrase_parse(begin, end, parser, x3::space); + + BOOST_TEST_EQ(stream.str(), "In line 2:\nError! Expecting: \"bar\" here:\n foo\n__^_\n"); +} + +int main() { + test("\n"); + test("\r"); + test("\r\n"); + + return boost::report_errors(); +} diff --git a/src/boost/libs/spirit/test/x3/expect.cpp b/src/boost/libs/spirit/test/x3/expect.cpp new file mode 100644 index 00000000..82422a3b --- /dev/null +++ b/src/boost/libs/spirit/test/x3/expect.cpp @@ -0,0 +1,147 @@ +/*============================================================================= + Copyright (c) 2001-2013 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +=============================================================================*/ +#include <boost/detail/lightweight_test.hpp> +#include <boost/spirit/home/x3.hpp> +#include <boost/fusion/include/vector.hpp> +#include <boost/fusion/include/at.hpp> + +#include <string> +#include <iostream> +#include "test.hpp" + +int +main() +{ + using namespace boost::spirit; + using namespace boost::spirit::x3::ascii; + using boost::spirit::x3::lit; + using boost::spirit::x3::expect; + using spirit_test::test; + using spirit_test::test_attr; + using boost::spirit::x3::expectation_failure; + + { + try + { + BOOST_TEST((test("aa", char_ >> expect[char_]))); + BOOST_TEST((test("aaa", char_ >> expect[char_ >> char_('a')]))); + BOOST_TEST((test("xi", char_('x') >> expect[char_('i')]))); + BOOST_TEST((!test("xi", char_('y') >> expect[char_('o')]))); // should not throw! + BOOST_TEST((test("xin", char_('x') >> expect[char_('i') >> char_('n')]))); + BOOST_TEST((!test("xi", char_('x') >> expect[char_('o')]))); + } + catch (expectation_failure<char const*> const& x) + { + std::cout << "expected: " << x.which(); + std::cout << " got: \"" << x.where() << '"' << std::endl; + } + } + + { + try + { + BOOST_TEST((test("aa", char_ > char_))); + BOOST_TEST((test("aaa", char_ > char_ > char_('a')))); + BOOST_TEST((test("xi", char_('x') > char_('i')))); + BOOST_TEST((!test("xi", char_('y') > char_('o')))); // should not throw! + BOOST_TEST((test("xin", char_('x') > char_('i') > char_('n')))); + BOOST_TEST((!test("xi", char_('x') > char_('o')))); + } + catch (expectation_failure<char const*> const& x) + { + std::cout << "expected: " << x.which(); + std::cout << " got: \"" << x.where() << '"' << std::endl; + } + } + + { + try + { + BOOST_TEST((!test("ay:a", char_ > char_('x') >> ':' > 'a'))); + } + catch (expectation_failure<char const*> const& x) + { + std::cout << "expected: " << x.which(); + std::cout << " got: \"" << x.where() << '"' << std::endl; + } + } + +#if defined(BOOST_CLANG) +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Woverloaded-shift-op-parentheses" +#endif + { // Test that attributes with > (sequences) work just like >> (sequences) + + using boost::fusion::vector; + using boost::fusion::at_c; + + { + vector<char, char, char> attr; + BOOST_TEST((test_attr(" a\n b\n c", + char_ > char_ > char_, attr, space))); + BOOST_TEST((at_c<0>(attr) == 'a')); + BOOST_TEST((at_c<1>(attr) == 'b')); + BOOST_TEST((at_c<2>(attr) == 'c')); + } + + { + vector<char, char, char> attr; + BOOST_TEST((test_attr(" a\n b\n c", + char_ > char_ >> char_, attr, space))); + BOOST_TEST((at_c<0>(attr) == 'a')); + BOOST_TEST((at_c<1>(attr) == 'b')); + BOOST_TEST((at_c<2>(attr) == 'c')); + } + + { + vector<char, char, char> attr; + BOOST_TEST((test_attr(" a, b, c", + char_ >> ',' > char_ >> ',' > char_, attr, space))); + BOOST_TEST((at_c<0>(attr) == 'a')); + BOOST_TEST((at_c<1>(attr) == 'b')); + BOOST_TEST((at_c<2>(attr) == 'c')); + } + + { + std::string attr; + BOOST_TEST((test_attr("'azaaz'", + "'" > *(char_("a") | char_("z")) > "'", attr, space))); + BOOST_TEST(attr == "azaaz"); + } + } +#if defined(BOOST_CLANG) +#pragma clang diagnostic pop +#endif + + { + try + { + BOOST_TEST((test(" a a", char_ > char_, space))); + BOOST_TEST((test(" x i", char_('x') > char_('i'), space))); + BOOST_TEST((!test(" x i", char_('x') > char_('o'), space))); + } + catch (expectation_failure<char const*> const& x) + { + std::cout << "expected: " << x.which(); + std::cout << " got: \"" << x.where() << '"' << std::endl; + } + } + + { + try + { + BOOST_TEST((test("bar", expect[lit("foo")]))); + } + catch (expectation_failure<char const*> const& x) + { + std::cout << "expected: " << x.which(); + std::cout << " got: \"" << x.where() << '"' << std::endl; + } + } + + return boost::report_errors(); +} diff --git a/src/boost/libs/spirit/test/x3/extract_int.cpp b/src/boost/libs/spirit/test/x3/extract_int.cpp new file mode 100644 index 00000000..f7b97cde --- /dev/null +++ b/src/boost/libs/spirit/test/x3/extract_int.cpp @@ -0,0 +1,162 @@ +/*============================================================================= + Copyright (c) 2018 Nikita Kniazev + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +=============================================================================*/ + +#include <boost/detail/lightweight_test.hpp> +#include <boost/spirit/home/x3/support/numeric_utils/extract_int.hpp> +#include <cmath> // for std::pow +#include <cstdio> +#include <iosfwd> +#include <limits> + +#ifdef _MSC_VER +# pragma warning(disable: 4127) // conditional expression is constant +#endif + +template <int Min, int Max> +struct custom_int +{ + custom_int() = default; + constexpr custom_int(int value) : value_{value} {} + + custom_int operator+(custom_int x) const { return value_ + x.value_; } + custom_int operator-(custom_int x) const { return value_ - x.value_; } + custom_int operator*(custom_int x) const { return value_ * x.value_; } + custom_int operator/(custom_int x) const { return value_ / x.value_; } + + custom_int& operator+=(custom_int x) { value_ += x.value_; return *this; } + custom_int& operator-=(custom_int x) { value_ -= x.value_; return *this; } + custom_int& operator*=(custom_int x) { value_ *= x.value_; return *this; } + custom_int& operator/=(custom_int x) { value_ /= x.value_; return *this; } + custom_int& operator++() { ++value_; return *this; } + custom_int& operator--() { --value_; return *this; } + custom_int operator++(int) { return value_++; } + custom_int operator--(int) { return value_--; } + + custom_int operator+() { return +value_; } + custom_int operator-() { return -value_; } + + bool operator< (custom_int x) const { return value_ < x.value_; } + bool operator> (custom_int x) const { return value_ > x.value_; } + bool operator<=(custom_int x) const { return value_ <= x.value_; } + bool operator>=(custom_int x) const { return value_ >= x.value_; } + bool operator==(custom_int x) const { return value_ == x.value_; } + bool operator!=(custom_int x) const { return value_ != x.value_; } + + template <typename Char, typename Traits> + friend std::basic_ostream<Char, Traits>& + operator<<(std::basic_ostream<Char, Traits>& os, custom_int x) { + return os << x.value_; + } + + static constexpr int max = Max; + static constexpr int min = Min; + +private: + int value_; +}; + +namespace utils { + +template <int Min, int Max> struct digits; +template <> struct digits<-9, 9> { static constexpr int r2 = 3, r10 = 1; }; +template <> struct digits<-10, 10> { static constexpr int r2 = 3, r10 = 1; }; +template <> struct digits<-15, 15> { static constexpr int r2 = 3, r10 = 1; }; + +} + +namespace std { + +template <int Min, int Max> +class numeric_limits<custom_int<Min, Max>> : public numeric_limits<int> +{ +public: + static constexpr custom_int<Min, Max> max() noexcept { return Max; } + static constexpr custom_int<Min, Max> min() noexcept { return Min; } + static constexpr custom_int<Min, Max> lowest() noexcept { return min(); } + static_assert(numeric_limits<int>::radix == 2, "hardcoded for digits of radix 2"); + static constexpr int digits = utils::digits<Min, Max>::r2; + static constexpr int digits10 = utils::digits<Min, Max>::r10; +}; + +} + +namespace x3 = boost::spirit::x3; + +template <typename T, int Base, int MaxDigits> +void test_overflow_handling(char const* begin, char const* end, int i) +{ + // Check that parser fails on overflow + static_assert(std::numeric_limits<T>::is_bounded, "tests prerequest"); + BOOST_ASSERT_MSG(MaxDigits == -1 || static_cast<int>(std::pow(float(Base), MaxDigits)) > T::max, + "test prerequest"); + int initial = Base - i % Base; // just a 'random' non-equal to i number + T x { initial }; + char const* it = begin; + bool r = x3::extract_int<T, Base, 1, MaxDigits>::call(it, end, x); + if (T::min <= i && i <= T::max) { + BOOST_TEST(r); + BOOST_TEST(it == end); + BOOST_TEST_EQ(x, i); + } + else + if (MaxDigits == -1) // TODO: Looks like a regression. See #430 + { + BOOST_TEST(!r); + BOOST_TEST(it == begin); + } +} + +template <typename T, int Base> +void test_unparsed_digits_are_not_consumed(char const* it, char const* end, int i) +{ + // Check that unparsed digits are not consumed + static_assert(T::min <= -Base+1, "test prerequest"); + static_assert(T::max >= Base-1, "test prerequest"); + bool has_sign = *it == '+' || *it == '-'; + auto len = end - it; + int initial = Base - i % Base; // just a 'random' non-equal to i number + T x { initial }; + bool r = x3::extract_int<T, Base, 1, 1>::call(it, end, x); + BOOST_TEST(r); + if (-Base < i && i < Base) { + BOOST_TEST(it == end); + BOOST_TEST_EQ(x, i); + } + else { + BOOST_TEST_EQ(end - it, len - 1 - has_sign); + BOOST_TEST_EQ(x, i / Base); + } +} + +template <typename T, int Base> +void run_tests(char const* begin, char const* end, int i) +{ + // Check that parser fails on overflow + test_overflow_handling<T, Base, -1>(begin, end, i); + // Check that MaxDigits > digits10 behave like MaxDigits=-1 + test_overflow_handling<T, Base, 2>(begin, end, i); + // Check that unparsed digits are not consumed + test_unparsed_digits_are_not_consumed<T, Base>(begin, end, i); +} + +int main() +{ + for (int i = -30; i <= 30; ++i) { + char s[4]; + std::snprintf(s, 4, "%d", i); + auto begin = &s[0], end = begin + std::strlen(begin); + + // log(Base, abs(MinOrMax) + 1) == digits + run_tests<custom_int<-9, 9>, 10>(begin, end, i); + // (MinOrMax % Base) == 0 + run_tests<custom_int<-10, 10>, 10>(begin, end, i); + // (MinOrMax % Base) != 0 + run_tests<custom_int<-15, 15>, 10>(begin, end, i); + } + + return boost::report_errors(); +} diff --git a/src/boost/libs/spirit/test/x3/fusion_map.cpp b/src/boost/libs/spirit/test/x3/fusion_map.cpp new file mode 100644 index 00000000..719b5e30 --- /dev/null +++ b/src/boost/libs/spirit/test/x3/fusion_map.cpp @@ -0,0 +1,138 @@ +/*============================================================================= + Copyright (c) 2001-2015 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + =============================================================================*/ +#include <boost/detail/lightweight_test.hpp> +#include <boost/spirit/home/x3.hpp> +#include <boost/fusion/include/at_key.hpp> +#include <boost/fusion/include/make_map.hpp> +#include <boost/fusion/adapted/struct.hpp> + +#include <string> +#include <iostream> +#include "test.hpp" + +struct AdaptedStruct { + std::string key1; + std::string key2; +}; + +class key1_attr {}; +class key2_attr {}; + +BOOST_FUSION_ADAPT_ASSOC_STRUCT( + AdaptedStruct, + (std::string, key1, class key1_attr) + (std::string, key2, class key2_attr) + ) + +template <class Parser, class Attribute> +bool test_attr(const std::string in,Parser const& p, Attribute& attr) { + auto it = in.begin(); + return boost::spirit::x3::parse(it,in.end(), p, attr); +} + +int +main() +{ + using spirit_test::test; + using boost::spirit::x3::lit; + using boost::spirit::x3::attr; + using boost::spirit::x3::char_; + using boost::spirit::x3::eps; + namespace fusion = boost::fusion; + + { // parsing sequence directly into fusion map + + auto const key1 = lit("key1") >> attr(key1_attr()); + auto const kv1 = key1 >> lit("=") >> +char_; + + { + auto attr_ = fusion::make_map<key1_attr>(std::string()); + BOOST_TEST(test_attr("key1=ABC", kv1, attr_)); + BOOST_TEST(fusion::at_key<key1_attr>(attr_) == "ABC"); + } + { + AdaptedStruct attr_; + BOOST_TEST(test_attr("key1=ABC", kv1, attr_)); + BOOST_TEST(attr_.key1 == "ABC"); + BOOST_TEST(attr_.key2 == ""); + } + } + { // case when parser handling fusion assoc sequence + // is on one side of another sequence + auto const key1 = lit("key1") >> attr(key1_attr()); + auto const kv1 = key1 >> lit("=") >> +~char_(';'); + + AdaptedStruct attr_; + BOOST_TEST(test_attr("key1=ABC", eps >> (kv1 % ';') , attr_)); + BOOST_TEST(attr_.key1 == "ABC"); + BOOST_TEST(attr_.key2 == ""); + } + { // parsing repeated sequence directly into fusion map (overwrite) + auto const key1 = lit("key1") >> attr(key1_attr()); + auto const kv1 = key1 >> lit("=") >> +~char_(';'); + + { + auto attr_ = fusion::make_map<key1_attr>(std::string()); + BOOST_TEST(test_attr("key1=ABC;key1=XYZ", kv1 % ';', attr_)); + BOOST_TEST(fusion::at_key<key1_attr>(attr_) == "XYZ"); + } + { + AdaptedStruct attr_; + BOOST_TEST(test_attr("key1=ABC;key1=XYZ", kv1 % ';', attr_)); + BOOST_TEST(attr_.key1 == "XYZ"); + } + } + + { // parsing repeated sequence directly into fusion map (append) + + /* NOT IMPLEMENTED + auto const key1 = lit("key1") >> attr(key1_attr()); + auto const kv1 = key1 >> lit("=") >> +char_; + auto attr_ = fusion::make_map<key1_attr>(std::vector<std::string>()); + + BOOST_TEST(test_attr("key1=ABC;key1=XYZ", kv1 % ";", attr_)); + BOOST_TEST(fusion::at_key<key1_attr>(attr_) == {"ABC","XYZ"}); + */ + } + + { // alternative over key-value pairs + + auto const key1 = lit("key1") >> attr(key1_attr()); + auto const key2 = lit("key2") >> attr(key2_attr()); + auto const kv1 = key1 >> lit("=") >> +~char_(';'); + auto const kv2 = key2 >> lit("=") >> +~char_(';'); + + auto attr_ = fusion::make_map<key1_attr, key2_attr>(std::string(),std::string()); + BOOST_TEST(test_attr("key2=XYZ;key1=ABC", (kv1|kv2) % ';', attr_)); + BOOST_TEST(fusion::at_key<key1_attr>(attr_) == "ABC"); + BOOST_TEST(fusion::at_key<key2_attr>(attr_) == "XYZ"); + } + + { // parsing sequence where key is a variant + + namespace x3 = boost::spirit::x3; + auto key1 = lit("key1") >> attr(key1_attr()); + auto key2 = lit("key2") >> attr(key2_attr()); + auto keys = key1 | key2; + auto pair = keys >> lit("=") >> +~char_(';'); + + { + auto attr_ = fusion::make_map<key1_attr,key2_attr>(std::string(),std::string()); + BOOST_TEST(test_attr("key1=ABC;key2=XYZ", pair % ';', attr_)); + BOOST_TEST(fusion::at_key<key1_attr>(attr_) == "ABC"); + BOOST_TEST(fusion::at_key<key2_attr>(attr_) == "XYZ"); + } + { + AdaptedStruct attr_; + BOOST_TEST(test_attr("key1=ABC;key2=XYZ", pair % ';', attr_)); + BOOST_TEST(fusion::at_key<key1_attr>(attr_) == "ABC"); + BOOST_TEST(fusion::at_key<key2_attr>(attr_) == "XYZ"); + } + } + + return boost::report_errors(); +} diff --git a/src/boost/libs/spirit/test/x3/grammar.cpp b/src/boost/libs/spirit/test/x3/grammar.cpp new file mode 100644 index 00000000..519e15cc --- /dev/null +++ b/src/boost/libs/spirit/test/x3/grammar.cpp @@ -0,0 +1,6 @@ +#include "grammar.hpp" + +auto const grammar_def = x3::int_; + +BOOST_SPIRIT_DEFINE(grammar) +BOOST_SPIRIT_INSTANTIATE(grammar_type, char const*, x3::unused_type) diff --git a/src/boost/libs/spirit/test/x3/grammar.hpp b/src/boost/libs/spirit/test/x3/grammar.hpp new file mode 100644 index 00000000..14b9402a --- /dev/null +++ b/src/boost/libs/spirit/test/x3/grammar.hpp @@ -0,0 +1,7 @@ +#include <boost/spirit/home/x3.hpp> + +namespace x3 = boost::spirit::x3; + +x3::rule<struct grammar_r, int> const grammar; +using grammar_type = decltype(grammar); +BOOST_SPIRIT_DECLARE(grammar_type) diff --git a/src/boost/libs/spirit/test/x3/grammar_linker.cpp b/src/boost/libs/spirit/test/x3/grammar_linker.cpp new file mode 100644 index 00000000..00a6fcf1 --- /dev/null +++ b/src/boost/libs/spirit/test/x3/grammar_linker.cpp @@ -0,0 +1,24 @@ +/*============================================================================= + Copyright (c) 2019 Nikita Kniazev + Copyright (c) 2019 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +=============================================================================*/ +#include "grammar.hpp" +#include <boost/detail/lightweight_test.hpp> + +int main() +{ + char const* s = "123", * e = s + std::strlen(s); +#if 1 + auto r = parse(s, e, grammar); +#else + int i = 0; + auto r = parse(s, e, grammar, i); +#endif + + BOOST_TEST(r); + return boost::report_errors(); +} + diff --git a/src/boost/libs/spirit/test/x3/int.hpp b/src/boost/libs/spirit/test/x3/int.hpp new file mode 100644 index 00000000..21c92504 --- /dev/null +++ b/src/boost/libs/spirit/test/x3/int.hpp @@ -0,0 +1,61 @@ +/*============================================================================= + Copyright (c) 2001-2012 Joel de Guzman + Copyright (c) 2001-2011 Hartmut Kaiser + Copyright (c) 2011 Bryce Lelbach + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +=============================================================================*/ +#if !defined(BOOST_SPIRIT_TEST_X3_INT_HPP) +#define BOOST_SPIRIT_TEST_X3_INT_HPP + +#include <climits> +#include <boost/detail/lightweight_test.hpp> +#include <boost/spirit/home/x3/numeric/int.hpp> +#include "test.hpp" + +/////////////////////////////////////////////////////////////////////////////// +// +// *** BEWARE PLATFORM DEPENDENT!!! *** +// *** The following assumes 32 bit or 64 bit integers and 64 bit long longs. +// *** Modify these constant strings when appropriate. +// +/////////////////////////////////////////////////////////////////////////////// + + static_assert(sizeof(long long) == 8, "unexpected long long size"); + +#if INT_MAX != LLONG_MAX + static_assert(sizeof(int) == 4, "unexpected int size"); + char const* max_int = "2147483647"; + char const* int_overflow = "2147483648"; + char const* min_int = "-2147483648"; + char const* int_underflow = "-2147483649"; +#else + static_assert(sizeof(int) == 8, "unexpected int size"); + char const* max_int = "9223372036854775807"; + char const* int_overflow = "9223372036854775808"; + char const* min_int = "-9223372036854775808"; + char const* int_underflow = "-9223372036854775809"; +#endif + + char const* max_long_long = "9223372036854775807"; + char const* long_long_overflow = "9223372036854775808"; + char const* min_long_long = "-9223372036854775808"; + char const* long_long_underflow = "-9223372036854775809"; + +/////////////////////////////////////////////////////////////////////////////// +// A custom int type +struct custom_int +{ + int n; + custom_int() : n(0) {} + explicit custom_int(int n_) : n(n_) {} + custom_int& operator=(int n_) { n = n_; return *this; } + friend bool operator==(custom_int a, custom_int b) { return a.n == b.n; } + friend bool operator==(custom_int a, int b) { return a.n == b; } + friend custom_int operator*(custom_int a, custom_int b) { return custom_int(a.n * b.n); } + friend custom_int operator+(custom_int a, custom_int b) { return custom_int(a.n + b.n); } + friend custom_int operator-(custom_int a, custom_int b) { return custom_int(a.n - b.n); } +}; + +#endif diff --git a/src/boost/libs/spirit/test/x3/int1.cpp b/src/boost/libs/spirit/test/x3/int1.cpp new file mode 100644 index 00000000..cf42d511 --- /dev/null +++ b/src/boost/libs/spirit/test/x3/int1.cpp @@ -0,0 +1,186 @@ +/*============================================================================= + Copyright (c) 2001-2015 Joel de Guzman + Copyright (c) 2001-2011 Hartmut Kaiser + Copyright (c) 2011 Bryce Lelbach + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +=============================================================================*/ +#include "int.hpp" +#include <boost/spirit/home/x3.hpp> +#include <boost/fusion/include/vector.hpp> +#include <boost/fusion/include/at.hpp> + +int +main() +{ + using spirit_test::test; + using spirit_test::test_attr; + + /////////////////////////////////////////////////////////////////////////// + // signed integer tests + /////////////////////////////////////////////////////////////////////////// + { + using boost::spirit::x3::int_; + int i; + + BOOST_TEST(test("123456", int_)); + BOOST_TEST(test_attr("123456", int_, i)); + BOOST_TEST(i == 123456); + + BOOST_TEST(test("+123456", int_)); + BOOST_TEST(test_attr("+123456", int_, i)); + BOOST_TEST(i == 123456); + + BOOST_TEST(test("-123456", int_)); + BOOST_TEST(test_attr("-123456", int_, i)); + BOOST_TEST(i == -123456); + + BOOST_TEST(test(max_int, int_)); + BOOST_TEST(test_attr(max_int, int_, i)); + BOOST_TEST(i == INT_MAX); + + BOOST_TEST(test(min_int, int_)); + BOOST_TEST(test_attr(min_int, int_, i)); + BOOST_TEST(i == INT_MIN); + + BOOST_TEST(!test(int_overflow, int_)); + BOOST_TEST(!test_attr(int_overflow, int_, i)); + BOOST_TEST(!test(int_underflow, int_)); + BOOST_TEST(!test_attr(int_underflow, int_, i)); + + BOOST_TEST(!test("-", int_)); + BOOST_TEST(!test_attr("-", int_, i)); + + BOOST_TEST(!test("+", int_)); + BOOST_TEST(!test_attr("+", int_, i)); + + // Bug report from Steve Nutt + BOOST_TEST(!test_attr("5368709120", int_, i)); + + // with leading zeros + BOOST_TEST(test("0000000000123456", int_)); + BOOST_TEST(test_attr("0000000000123456", int_, i)); + BOOST_TEST(i == 123456); + } + + /////////////////////////////////////////////////////////////////////////// + // long long tests + /////////////////////////////////////////////////////////////////////////// + { + using boost::spirit::x3::long_long; + boost::long_long_type ll; + + BOOST_TEST(test("1234567890123456789", long_long)); + BOOST_TEST(test_attr("1234567890123456789", long_long, ll)); + BOOST_TEST(ll == 1234567890123456789LL); + + BOOST_TEST(test("-1234567890123456789", long_long)); + BOOST_TEST(test_attr("-1234567890123456789", long_long, ll)); + BOOST_TEST(ll == -1234567890123456789LL); + + BOOST_TEST(test(max_long_long, long_long)); + BOOST_TEST(test_attr(max_long_long, long_long, ll)); + BOOST_TEST(ll == LLONG_MAX); + + BOOST_TEST(test(min_long_long, long_long)); + BOOST_TEST(test_attr(min_long_long, long_long, ll)); + BOOST_TEST(ll == LLONG_MIN); + + BOOST_TEST(!test(long_long_overflow, long_long)); + BOOST_TEST(!test_attr(long_long_overflow, long_long, ll)); + BOOST_TEST(!test(long_long_underflow, long_long)); + BOOST_TEST(!test_attr(long_long_underflow, long_long, ll)); + } + + /////////////////////////////////////////////////////////////////////////// + // short_ and long_ tests + /////////////////////////////////////////////////////////////////////////// + { + using boost::spirit::x3::short_; + using boost::spirit::x3::long_; + int i; + + BOOST_TEST(test("12345", short_)); + BOOST_TEST(test_attr("12345", short_, i)); + BOOST_TEST(i == 12345); + + BOOST_TEST(test("1234567890", long_)); + BOOST_TEST(test_attr("1234567890", long_, i)); + BOOST_TEST(i == 1234567890); + } + + /////////////////////////////////////////////////////////////////////////// + // Check overflow is parse error + /////////////////////////////////////////////////////////////////////////// + { + boost::spirit::x3::int_parser<boost::int8_t> int8_; + char c; + + BOOST_TEST(!test_attr("999", int8_, c)); + + int i; + using boost::spirit::x3::short_; + BOOST_TEST(!test_attr("32769", short_, i, false)); + BOOST_TEST(!test_attr("41234", short_, i, false)); + } + + /////////////////////////////////////////////////////////////////////////// + // int_parser<unused_type> tests + /////////////////////////////////////////////////////////////////////////// + { + using boost::spirit::x3::int_parser; + using boost::spirit::x3::unused_type; + int_parser<unused_type> any_int; + + BOOST_TEST(test("123456", any_int)); + BOOST_TEST(test("-123456", any_int)); + BOOST_TEST(test("-1234567890123456789", any_int)); + } + + /////////////////////////////////////////////////////////////////////////// + // action tests + /////////////////////////////////////////////////////////////////////////// + { + using boost::spirit::x3::_attr; + using boost::spirit::x3::ascii::space; + using boost::spirit::x3::int_; + int n = 0, m = 0; + + auto f = [&](auto& ctx){ n = _attr(ctx); }; + + BOOST_TEST(test("123", int_[f])); + BOOST_TEST(n == 123); + BOOST_TEST(test_attr("789", int_[f], m)); + BOOST_TEST(n == 789 && m == 789); + BOOST_TEST(test(" 456", int_[f], space)); + BOOST_TEST(n == 456); + } + + /////////////////////////////////////////////////////////////////////////// + // custom int tests + /////////////////////////////////////////////////////////////////////////// + { + using boost::spirit::x3::int_; + using boost::spirit::x3::int_parser; + custom_int i; + + BOOST_TEST(test_attr("-123456", int_, i)); + int_parser<custom_int, 10, 1, 2> int2; + BOOST_TEST(test_attr("-12", int2, i)); + } + + /////////////////////////////////////////////////////////////////////////// + // single-element fusion vector tests + /////////////////////////////////////////////////////////////////////////// + { + using boost::spirit::x3::int_; + using boost::spirit::x3::int_parser; + boost::fusion::vector<int> i; + + BOOST_TEST(test_attr("-123456", int_, i)); + BOOST_TEST(boost::fusion::at_c<0>(i) == -123456); + } + + return boost::report_errors(); +} diff --git a/src/boost/libs/spirit/test/x3/iterator_check.cpp b/src/boost/libs/spirit/test/x3/iterator_check.cpp new file mode 100644 index 00000000..70a8a176 --- /dev/null +++ b/src/boost/libs/spirit/test/x3/iterator_check.cpp @@ -0,0 +1,49 @@ +/*============================================================================= + Copyright (c) 2001-2017 Joel de Guzman + Copyright (c) 2017 think-cell GmbH + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +=============================================================================*/ +#include <boost/detail/lightweight_test.hpp> +#include <boost/spirit/home/x3.hpp> +#include <boost/range/adaptor/transformed.hpp> + +#include <iostream> +#include <string> +#include <functional> + +int main() +{ + using boost::adaptors::transform; + using boost::spirit::x3::raw; + using boost::spirit::x3::eps; + using boost::spirit::x3::eoi; + using boost::spirit::x3::upper; + using boost::spirit::x3::repeat; + using boost::spirit::x3::parse; + + std::string input = "abcde"; + std::function<char(char)> func = [](char c) { + return c < 'a' || 'z' < c ? c : static_cast<char>(c - 'a' + 'A'); + }; + auto const rng = transform(input, func); + + { + std::string str; + BOOST_TEST((parse(boost::begin(rng), boost::end(rng), +upper >> eoi, str))); + BOOST_TEST(("ABCDE"==str)); + } + + { + boost::iterator_range<decltype(boost::begin(rng))> str; + BOOST_TEST((parse(boost::begin(rng), boost::end(rng), raw[+upper >> eoi], str))); + BOOST_TEST((boost::equal(std::string("ABCDE"), str))); + } + + { + BOOST_TEST((parse(boost::begin(rng), boost::end(rng), (repeat(6)[upper] | repeat(5)[upper]) >> eoi))); + } + + return boost::report_errors(); +} diff --git a/src/boost/libs/spirit/test/x3/kleene.cpp b/src/boost/libs/spirit/test/x3/kleene.cpp new file mode 100644 index 00000000..67f59d28 --- /dev/null +++ b/src/boost/libs/spirit/test/x3/kleene.cpp @@ -0,0 +1,126 @@ +/*============================================================================= + Copyright (c) 2001-2015 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +=============================================================================*/ +#include <string> +#include <vector> + +#include <boost/detail/lightweight_test.hpp> +#include <boost/spirit/home/x3.hpp> + +#include <string> +#include <iostream> +#include "test.hpp" +#include "utils.hpp" + +struct x_attr +{ +}; + +namespace boost { namespace spirit { namespace x3 { namespace traits +{ + template <> + struct container_value<x_attr> + { + typedef char type; // value type of container + }; + + template <> + struct push_back_container<x_attr> + { + static bool call(x_attr& /*c*/, char /*val*/) + { + // push back value type into container + return true; + } + }; +}}}} + +int +main() +{ + using spirit_test::test; + using spirit_test::test_attr; + using boost::spirit::x3::char_; + using boost::spirit::x3::alpha; + using boost::spirit::x3::upper; + using boost::spirit::x3::space; + using boost::spirit::x3::digit; + using boost::spirit::x3::int_; + using boost::spirit::x3::lexeme; + + { + BOOST_TEST(test("aaaaaaaa", *char_)); + BOOST_TEST(test("a", *char_)); + BOOST_TEST(test("", *char_)); + BOOST_TEST(test("aaaaaaaa", *alpha)); + BOOST_TEST(!test("aaaaaaaa", *upper)); + } + + { + BOOST_TEST(test(" a a aaa aa", *char_, space)); + BOOST_TEST(test("12345 678 9", *digit, space)); + } + + { + std::string s; + BOOST_TEST(test_attr("bbbb", *char_, s) && 4 == s.size() && s == "bbbb"); + + s.clear(); + BOOST_TEST(test_attr("b b b b ", *char_, s, space) && s == "bbbb"); + } + + { + std::vector<int> v; + BOOST_TEST(test_attr("123 456 789 10", *int_, v, space) && 4 == v.size() && + v[0] == 123 && v[1] == 456 && v[2] == 789 && v[3] == 10); + } + + { + std::vector<std::string> v; + BOOST_TEST(test_attr("a b c d", *lexeme[+alpha], v, space) && 4 == v.size() && + v[0] == "a" && v[1] == "b" && v[2] == "c" && v[3] == "d"); + } + + { + std::vector<int> v; + BOOST_TEST(test_attr("123 456 789", *int_, v, space) && 3 == v.size() && + v[0] == 123 && v[1] == 456 && v[2] == 789); + } + + { // actions + using boost::spirit::x3::_attr; + + std::string v; + auto f = [&](auto& ctx){ v = _attr(ctx); }; + + BOOST_TEST(test("bbbb", (*char_)[f]) && 4 == v.size() && + v[0] == 'b' && v[1] == 'b' && v[2] == 'b' && v[3] == 'b'); + } + + { // more actions + using boost::spirit::x3::_attr; + + std::vector<int> v; + auto f = [&](auto& ctx){ v = _attr(ctx); }; + + BOOST_TEST(test("123 456 789", (*int_)[f], space) && 3 == v.size() && + v[0] == 123 && v[1] == 456 && v[2] == 789); + } + + { // attribute customization + + x_attr x; + test_attr("abcde", *char_, x); + } + + { // test move only types + std::vector<move_only> v; + BOOST_TEST(test_attr("sss", *synth_move_only, v)); + BOOST_TEST_EQ(v.size(), 3); + } + + return boost::report_errors(); +} diff --git a/src/boost/libs/spirit/test/x3/lexeme.cpp b/src/boost/libs/spirit/test/x3/lexeme.cpp new file mode 100644 index 00000000..f8962e52 --- /dev/null +++ b/src/boost/libs/spirit/test/x3/lexeme.cpp @@ -0,0 +1,42 @@ +/*============================================================================= + Copyright (c) 2001-2015 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +=============================================================================*/ +#include <boost/detail/lightweight_test.hpp> +#include <boost/spirit/home/x3.hpp> + +#include <iostream> +#include "test.hpp" + +int +main() +{ + using spirit_test::test; + using boost::spirit::x3::ascii::space; + using boost::spirit::x3::ascii::space_type; + using boost::spirit::x3::ascii::digit; + using boost::spirit::x3::lexeme; + using boost::spirit::x3::rule; + + { + BOOST_TEST((test(" 1 2 3 4 5", +digit, space))); + BOOST_TEST((!test(" 1 2 3 4 5", lexeme[+digit], space))); + BOOST_TEST((test(" 12345", lexeme[+digit], space))); + BOOST_TEST((test(" 12345 ", lexeme[+digit], space, false))); + + // lexeme collapsing + BOOST_TEST((!test(" 1 2 3 4 5", lexeme[lexeme[+digit]], space))); + BOOST_TEST((test(" 12345", lexeme[lexeme[+digit]], space))); + BOOST_TEST((test(" 12345 ", lexeme[lexeme[+digit]], space, false))); + + auto r = +digit; + auto rr = lexeme[r]; + + BOOST_TEST((!test(" 1 2 3 4 5", rr, space))); + BOOST_TEST((test(" 12345", rr, space))); + } + + return boost::report_errors(); +} diff --git a/src/boost/libs/spirit/test/x3/list.cpp b/src/boost/libs/spirit/test/x3/list.cpp new file mode 100644 index 00000000..ff41de0e --- /dev/null +++ b/src/boost/libs/spirit/test/x3/list.cpp @@ -0,0 +1,109 @@ +/*============================================================================= + Copyright (c) 2001-2013 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +=============================================================================*/ +#include <string> +#include <vector> +#include <set> +#include <map> + +#include <boost/detail/lightweight_test.hpp> +#include <boost/spirit/home/x3.hpp> + +#include <string> +#include <iostream> +#include "test.hpp" +#include "utils.hpp" + +using namespace spirit_test; + +int +main() +{ + using namespace boost::spirit::x3::ascii; + + { + BOOST_TEST(test("a,b,c,d,e,f,g,h", char_ % ',')); + BOOST_TEST(test("a,b,c,d,e,f,g,h,", char_ % ',', false)); + } + + { + BOOST_TEST(test("a, b, c, d, e, f, g, h", char_ % ',', space)); + BOOST_TEST(test("a, b, c, d, e, f, g, h,", char_ % ',', space, false)); + } + + { + std::string s; + BOOST_TEST(test_attr("a,b,c,d,e,f,g,h", char_ % ',', s)); + BOOST_TEST(s == "abcdefgh"); + + BOOST_TEST(!test("a,b,c,d,e,f,g,h,", char_ % ',')); + } + + { + std::string s; + BOOST_TEST(test_attr("ab,cd,ef,gh", (char_ >> char_) % ',', s)); + BOOST_TEST(s == "abcdefgh"); + + BOOST_TEST(!test("ab,cd,ef,gh,", (char_ >> char_) % ',')); + BOOST_TEST(!test("ab,cd,ef,g", (char_ >> char_) % ',')); + + s.clear(); + BOOST_TEST(test_attr("ab,cd,efg", (char_ >> char_) % ',' >> char_, s)); + BOOST_TEST(s == "abcdefg"); + } + + { + using boost::spirit::x3::int_; + + std::vector<int> v; + BOOST_TEST(test_attr("1,2", int_ % ',', v)); + BOOST_TEST(2 == v.size() && 1 == v[0] && 2 == v[1]); + } + + { + using boost::spirit::x3::int_; + + std::vector<int> v; + BOOST_TEST(test_attr("(1,2)", '(' >> int_ % ',' >> ')', v)); + BOOST_TEST(2 == v.size() && 1 == v[0] && 2 == v[1]); + } + + { + std::vector<std::string> v; + BOOST_TEST(test_attr("a,b,c,d", +alpha % ',', v)); + BOOST_TEST(4 == v.size() && "a" == v[0] && "b" == v[1] + && "c" == v[2] && "d" == v[3]); + } + + { + std::vector<boost::optional<char> > v; + BOOST_TEST(test_attr("#a,#", ('#' >> -alpha) % ',', v)); + BOOST_TEST(2 == v.size() && + !!v[0] && 'a' == boost::get<char>(v[0]) && !v[1]); + + std::vector<char> v2; + BOOST_TEST(test_attr("#a,#", ('#' >> -alpha) % ',', v2)); + BOOST_TEST(1 == v2.size() && 'a' == v2[0]); + } + + { // actions + using boost::spirit::x3::_attr; + + std::string s; + auto f = [&](auto& ctx){ s = std::string(_attr(ctx).begin(), _attr(ctx).end()); }; + + BOOST_TEST(test("a,b,c,d,e,f,g,h", (char_ % ',')[f])); + BOOST_TEST(s == "abcdefgh"); + } + + { // test move only types + std::vector<move_only> v; + BOOST_TEST(test_attr("s.s.s.s", synth_move_only % '.', v)); + BOOST_TEST_EQ(v.size(), 4); + } + + return boost::report_errors(); +} diff --git a/src/boost/libs/spirit/test/x3/lit.cpp b/src/boost/libs/spirit/test/x3/lit.cpp new file mode 100644 index 00000000..2a9abc98 --- /dev/null +++ b/src/boost/libs/spirit/test/x3/lit.cpp @@ -0,0 +1,53 @@ +/*============================================================================= + Copyright (c) 2001-2015 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +=============================================================================*/ +#include <boost/detail/lightweight_test.hpp> +#include <boost/spirit/home/x3.hpp> + +#include <string> + +#include "test.hpp" + +int +main() +{ + using spirit_test::test_attr; + using boost::spirit::x3::lit; + using boost::spirit::x3::char_; + + { + std::string attr; + auto p = char_ >> lit("\n"); + BOOST_TEST(test_attr("A\n", p, attr)); + BOOST_TEST(attr == "A"); + } + + { + using namespace boost::spirit::x3::ascii; + std::string attr; + auto p = char_ >> lit("\n"); + BOOST_TEST(test_attr("A\n", p, attr)); + BOOST_TEST(attr == "A"); + } + + { + using namespace boost::spirit::x3::iso8859_1; + std::string attr; + auto p = char_ >> lit("\n"); + BOOST_TEST(test_attr("É\n", p, attr)); + BOOST_TEST(attr == "É"); + } + + { + using namespace boost::spirit::x3::standard_wide; + std::wstring attr; + auto p = char_ >> lit("\n"); + BOOST_TEST(test_attr(l"É\n", p, attr)); + BOOST_TEST(attr == "A"); + } + + return boost::report_errors(); +} diff --git a/src/boost/libs/spirit/test/x3/lit1.cpp b/src/boost/libs/spirit/test/x3/lit1.cpp new file mode 100644 index 00000000..7eefba6c --- /dev/null +++ b/src/boost/libs/spirit/test/x3/lit1.cpp @@ -0,0 +1,85 @@ +/*============================================================================= + Copyright (c) 2001-2015 Joel de Guzman + http://spirit.sourceforge.net/ + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +=============================================================================*/ +#include <boost/detail/lightweight_test.hpp> +#include <boost/spirit/home/x3.hpp> +#include <boost/fusion/include/vector.hpp> + +#include <string> +#include "test.hpp" + +int +main() +{ + using spirit_test::test; + using spirit_test::test_attr; + using boost::spirit::x3::string; + + { + BOOST_TEST((test("kimpo", "kimpo"))); + BOOST_TEST((test("kimpo", string("kimpo")))); + + BOOST_TEST((test("x", string("x")))); + BOOST_TEST((test(L"x", string(L"x")))); + + std::basic_string<char> s("kimpo"); + std::basic_string<wchar_t> ws(L"kimpo"); + BOOST_TEST((test("kimpo", s))); + BOOST_TEST((test(L"kimpo", ws))); + BOOST_TEST((test("kimpo", string(s)))); + BOOST_TEST((test(L"kimpo", string(ws)))); + } + + { + BOOST_TEST((test(L"kimpo", L"kimpo"))); + BOOST_TEST((test(L"kimpo", string(L"kimpo")))); + BOOST_TEST((test(L"x", string(L"x")))); + } + + { + std::basic_string<char> s("kimpo"); + BOOST_TEST((test("kimpo", string(s)))); + + std::basic_string<wchar_t> ws(L"kimpo"); + BOOST_TEST((test(L"kimpo", string(ws)))); + } + + { + using namespace boost::spirit::x3::ascii; + BOOST_TEST((test(" kimpo", string("kimpo"), space))); + BOOST_TEST((test(L" kimpo", string(L"kimpo"), space))); + BOOST_TEST((test(" x", string("x"), space))); + } + + { + using namespace boost::spirit::x3::ascii; + BOOST_TEST((test(" kimpo", string("kimpo"), space))); + BOOST_TEST((test(L" kimpo", string(L"kimpo"), space))); + BOOST_TEST((test(" x", string("x"), space))); + } + + { + using namespace boost::spirit::x3::ascii; + std::string s; + BOOST_TEST((test_attr("kimpo", string("kimpo"), s))); + BOOST_TEST(s == "kimpo"); + s.clear(); + BOOST_TEST((test_attr(L"kimpo", string(L"kimpo"), s))); + BOOST_TEST(s == "kimpo"); + s.clear(); + BOOST_TEST((test_attr("x", string("x"), s))); + BOOST_TEST(s == "x"); + } + + { // single-element fusion vector tests + boost::fusion::vector<std::string> s; + BOOST_TEST(test_attr("kimpo", string("kimpo"), s)); + BOOST_TEST(boost::fusion::at_c<0>(s) == "kimpo"); + } + + return boost::report_errors(); +} diff --git a/src/boost/libs/spirit/test/x3/lit2.cpp b/src/boost/libs/spirit/test/x3/lit2.cpp new file mode 100644 index 00000000..947837f9 --- /dev/null +++ b/src/boost/libs/spirit/test/x3/lit2.cpp @@ -0,0 +1,52 @@ +/*============================================================================= + Copyright (c) 2001-2015 Joel de Guzman + Copyright (c) 2001-2011 Hartmut Kaiser + http://spirit.sourceforge.net/ + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +=============================================================================*/ +#include <boost/detail/lightweight_test.hpp> +#include <boost/spirit/home/x3.hpp> + +#include <iostream> +#include "test.hpp" + +int +main() +{ + using spirit_test::test; + using spirit_test::test_attr; + using boost::spirit::x3::lit; + + { + BOOST_TEST((test("kimpo", lit("kimpo")))); + + std::basic_string<char> s("kimpo"); + std::basic_string<wchar_t> ws(L"kimpo"); + BOOST_TEST((test("kimpo", lit(s)))); + BOOST_TEST((test(L"kimpo", lit(ws)))); + } + + { + std::basic_string<char> s("kimpo"); + BOOST_TEST((test("kimpo", lit(s)))); + + std::basic_string<wchar_t> ws(L"kimpo"); + BOOST_TEST((test(L"kimpo", lit(ws)))); + } + + { + using namespace boost::spirit::x3::ascii; + BOOST_TEST((test(" kimpo", lit("kimpo"), space))); + BOOST_TEST((test(L" kimpo", lit(L"kimpo"), space))); + } + + { + using namespace boost::spirit::x3::iso8859_1; + BOOST_TEST((test(" kimpo", lit("kimpo"), space))); + BOOST_TEST((test(L" kimpo", lit(L"kimpo"), space))); + } + + return boost::report_errors(); +} diff --git a/src/boost/libs/spirit/test/x3/matches.cpp b/src/boost/libs/spirit/test/x3/matches.cpp new file mode 100644 index 00000000..58923b72 --- /dev/null +++ b/src/boost/libs/spirit/test/x3/matches.cpp @@ -0,0 +1,37 @@ +/*============================================================================= + Copyright (c) 2001-2015 Joel de Guzman + Copyright (c) 2001-2010 Hartmut Kaiser + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +=============================================================================*/ +#include <boost/detail/lightweight_test.hpp> +#include <boost/spirit/home/x3.hpp> +#include <iostream> +#include "test.hpp" + +int +main() +{ + using spirit_test::test; + using spirit_test::test_attr; + using boost::spirit::x3::matches; + using boost::spirit::x3::char_; + + { + BOOST_TEST(test("x", matches[char_])); + bool result = false; + BOOST_TEST(test_attr("x", matches[char_], result) && result); + } + + { + BOOST_TEST(!test("y", matches[char_('x')])); + BOOST_TEST(!test("y", matches['x'])); + bool result = true; + BOOST_TEST(test_attr("y", matches[char_('x')], result, false) && !result); + result = true; + BOOST_TEST(test_attr("y", matches['x'], result, false) && !result); + } + + return boost::report_errors(); +} diff --git a/src/boost/libs/spirit/test/x3/no_case.cpp b/src/boost/libs/spirit/test/x3/no_case.cpp new file mode 100644 index 00000000..cbf6c9dd --- /dev/null +++ b/src/boost/libs/spirit/test/x3/no_case.cpp @@ -0,0 +1,148 @@ +/*============================================================================= + Copyright (c) 2001-2015 Joel de Guzman + http://spirit.sourceforge.net/ + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +=============================================================================*/ + +#include <boost/detail/lightweight_test.hpp> +#include <boost/spirit/home/x3.hpp> + +#include <iostream> +#include "test.hpp" + +int +main() +{ + using spirit_test::test; + using spirit_test::test_attr; + using boost::spirit::x3::no_case; + + { + using namespace boost::spirit::x3::ascii; + BOOST_TEST(test("x", no_case[char_])); + BOOST_TEST(test("X", no_case[char_('x')])); + BOOST_TEST(test("X", no_case[char_('X')])); + BOOST_TEST(test("x", no_case[char_('X')])); + BOOST_TEST(test("x", no_case[char_('x')])); + BOOST_TEST(!test("z", no_case[char_('X')])); + BOOST_TEST(!test("z", no_case[char_('x')])); + BOOST_TEST(test("x", no_case[char_('a', 'z')])); + BOOST_TEST(test("X", no_case[char_('a', 'z')])); + BOOST_TEST(!test("a", no_case[char_('b', 'z')])); + BOOST_TEST(!test("z", no_case[char_('a', 'y')])); + } + { + using namespace boost::spirit::x3::ascii; + BOOST_TEST(test("X", no_case['x'])); + BOOST_TEST(test("X", no_case['X'])); + BOOST_TEST(test("x", no_case['X'])); + BOOST_TEST(test("x", no_case['x'])); + BOOST_TEST(!test("z", no_case['X'])); + BOOST_TEST(!test("z", no_case['x'])); + } + + { + using namespace boost::spirit::x3::iso8859_1; + BOOST_TEST(test("X", no_case[char_("a-z")])); + BOOST_TEST(!test("1", no_case[char_("a-z")])); + } + + { // test extended ASCII characters + using namespace boost::spirit::x3::iso8859_1; + BOOST_TEST(test("\xC1", no_case[char_('\xE1')])); + + BOOST_TEST(test("\xC9", no_case[char_("\xE5-\xEF")])); + BOOST_TEST(!test("\xFF", no_case[char_("\xE5-\xEF")])); + + BOOST_TEST(test("\xC1\xE1", no_case[lit("\xE1\xC1")])); + BOOST_TEST(test("\xE1\xE1", no_case[no_case[lit("\xE1\xC1")]])); + } + + { + using namespace boost::spirit::x3::ascii; + BOOST_TEST(test("Bochi Bochi", no_case[lit("bochi bochi")])); + BOOST_TEST(test("BOCHI BOCHI", no_case[lit("bochi bochi")])); + BOOST_TEST(!test("Vavoo", no_case[lit("bochi bochi")])); + } + + { + // should work! + using namespace boost::spirit::x3::ascii; + BOOST_TEST(test("x", no_case[no_case[char_]])); + BOOST_TEST(test("x", no_case[no_case[char_('x')]])); + BOOST_TEST(test("yabadabadoo", no_case[no_case[lit("Yabadabadoo")]])); + } + + { + using namespace boost::spirit::x3::ascii; + BOOST_TEST(test("X", no_case[alnum])); + BOOST_TEST(test("6", no_case[alnum])); + BOOST_TEST(!test(":", no_case[alnum])); + + BOOST_TEST(test("X", no_case[lower])); + BOOST_TEST(test("x", no_case[lower])); + BOOST_TEST(test("X", no_case[upper])); + BOOST_TEST(test("x", no_case[upper])); + BOOST_TEST(!test(":", no_case[lower])); + BOOST_TEST(!test(":", no_case[upper])); + } + + { + using namespace boost::spirit::x3::iso8859_1; + BOOST_TEST(test("X", no_case[alnum])); + BOOST_TEST(test("6", no_case[alnum])); + BOOST_TEST(!test(":", no_case[alnum])); + + BOOST_TEST(test("X", no_case[lower])); + BOOST_TEST(test("x", no_case[lower])); + BOOST_TEST(test("X", no_case[upper])); + BOOST_TEST(test("x", no_case[upper])); + BOOST_TEST(!test(":", no_case[lower])); + BOOST_TEST(!test(":", no_case[upper])); + } + + { + using namespace boost::spirit::x3::standard; + BOOST_TEST(test("X", no_case[alnum])); + BOOST_TEST(test("6", no_case[alnum])); + BOOST_TEST(!test(":", no_case[alnum])); + + BOOST_TEST(test("X", no_case[lower])); + BOOST_TEST(test("x", no_case[lower])); + BOOST_TEST(test("X", no_case[upper])); + BOOST_TEST(test("x", no_case[upper])); + BOOST_TEST(!test(":", no_case[lower])); + BOOST_TEST(!test(":", no_case[upper])); + } + + { + // chsets + namespace standard = boost::spirit::x3::standard; + namespace standard_wide = boost::spirit::x3::standard_wide; + + BOOST_TEST(test("x", no_case[standard::char_("a-z")])); + BOOST_TEST(test("X", no_case[standard::char_("a-z")])); + BOOST_TEST(test(L"X", no_case[standard_wide::char_(L"a-z")])); + BOOST_TEST(test(L"X", no_case[standard_wide::char_(L"X")])); + } + + { + using namespace boost::spirit::x3::standard; + std::string s("bochi bochi"); + BOOST_TEST(test("Bochi Bochi", no_case[lit(s.c_str())])); + BOOST_TEST(test("Bochi Bochi", no_case[lit(s)])); + BOOST_TEST(test("Bochi Bochi", no_case[s.c_str()])); + BOOST_TEST(test("Bochi Bochi", no_case[s])); + } + + { + { + using namespace boost::spirit::x3::standard; + BOOST_TEST(!test("ą", no_case['a'])); + } + } + + return boost::report_errors(); +} diff --git a/src/boost/libs/spirit/test/x3/no_skip.cpp b/src/boost/libs/spirit/test/x3/no_skip.cpp new file mode 100644 index 00000000..b64a4a6e --- /dev/null +++ b/src/boost/libs/spirit/test/x3/no_skip.cpp @@ -0,0 +1,50 @@ +/*============================================================================= + Copyright (c) 2001-2015 Joel de Guzman + Copyright (c) 2013 Agustin Berge + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +=============================================================================*/ +#include <boost/detail/lightweight_test.hpp> +#include <boost/spirit/home/x3.hpp> + +#include <iostream> +#include "test.hpp" + +int +main() +{ + using spirit_test::test; + using spirit_test::test_attr; + using boost::spirit::x3::ascii::space; + using boost::spirit::x3::ascii::space_type; + using boost::spirit::x3::ascii::char_; + using boost::spirit::x3::lexeme; + using boost::spirit::x3::no_skip; + + // without skipping no_skip is equivalent to lexeme + { + std::string str; + BOOST_TEST((test_attr("' abc '", '\'' >> no_skip[+~char_('\'')] >> '\'', str))); + BOOST_TEST(str == " abc "); + } + { + std::string str; + BOOST_TEST((test_attr("' abc '", '\'' >> lexeme[+~char_('\'')] >> '\'', str))); + BOOST_TEST(str == " abc "); + } + + // with skipping, no_skip allows to match a leading skipper + { + std::string str; + BOOST_TEST((test_attr("' abc '", '\'' >> no_skip[+~char_('\'')] >> '\'', str, space))); + BOOST_TEST(str == " abc "); + } + { + std::string str; + BOOST_TEST((test_attr("' abc '", '\'' >> lexeme[+~char_('\'')] >> '\'', str, space))); + BOOST_TEST(str == "abc "); + } + + return boost::report_errors(); +} diff --git a/src/boost/libs/spirit/test/x3/not_predicate.cpp b/src/boost/libs/spirit/test/x3/not_predicate.cpp new file mode 100644 index 00000000..d5b962a4 --- /dev/null +++ b/src/boost/libs/spirit/test/x3/not_predicate.cpp @@ -0,0 +1,26 @@ +/*============================================================================= + Copyright (c) 2001-2015 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +=============================================================================*/ +#include <boost/detail/lightweight_test.hpp> +#include <boost/spirit/home/x3.hpp> + +#include <iostream> +#include "test.hpp" + +int +main() +{ + using spirit_test::test; + using boost::spirit::x3::int_; + + { + BOOST_TEST((!test("1234", !int_))); + BOOST_TEST((test("abcd", !int_, false))); + BOOST_TEST((!test("abcd", !!int_, false))); + } + + return boost::report_errors(); +} diff --git a/src/boost/libs/spirit/test/x3/omit.cpp b/src/boost/libs/spirit/test/x3/omit.cpp new file mode 100644 index 00000000..f89a4851 --- /dev/null +++ b/src/boost/libs/spirit/test/x3/omit.cpp @@ -0,0 +1,114 @@ +/*============================================================================= + Copyright (c) 2001-2015 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +=============================================================================*/ +#include <boost/detail/lightweight_test.hpp> +#include <boost/spirit/home/x3.hpp> +#include <boost/fusion/include/vector.hpp> +#include <boost/fusion/include/at.hpp> + +#include <string> +#include <iostream> +#include "test.hpp" + +int +main() +{ + using namespace boost::spirit::x3::ascii; + using boost::spirit::x3::omit; + using boost::spirit::x3::unused_type; + using boost::spirit::x3::unused; + using boost::spirit::x3::int_; + + using boost::fusion::vector; + using boost::fusion::at_c; + + using spirit_test::test; + using spirit_test::test_attr; + + { + BOOST_TEST(test("a", omit['a'])); + } + + { + // omit[] means we don't receive the attribute + char attr; + BOOST_TEST((test_attr("abc", omit[char_] >> omit['b'] >> char_, attr))); + BOOST_TEST((attr == 'c')); + } + + { + // If all elements except 1 is omitted, the attribute is + // a single-element sequence. For this case alone, we allow + // naked attributes (unwrapped in a fusion sequence). + char attr; + BOOST_TEST((test_attr("abc", omit[char_] >> 'b' >> char_, attr))); + BOOST_TEST((attr == 'c')); + } + + { + // omit[] means we don't receive the attribute + vector<> attr; + BOOST_TEST((test_attr("abc", omit[char_] >> omit['b'] >> omit[char_], attr))); + } + + { + // omit[] means we don't receive the attribute + // this test is merely a compile test, because using a unused as the + // explicit attribute doesn't make any sense + unused_type attr; + BOOST_TEST((test_attr("abc", omit[char_ >> 'b' >> char_], attr))); + } + + { + // omit[] means we don't receive the attribute, if all elements of a + // sequence have unused attributes, the whole sequence has an unused + // attribute as well + vector<char, char> attr; + BOOST_TEST((test_attr("abcde", + char_ >> (omit[char_] >> omit['c'] >> omit[char_]) >> char_, attr))); + BOOST_TEST((at_c<0>(attr) == 'a')); + BOOST_TEST((at_c<1>(attr) == 'e')); + } + + { + // "hello" has an unused_type. unused attrubutes are not part of the sequence + vector<char, char> attr; + BOOST_TEST((test_attr("a hello c", char_ >> "hello" >> char_, attr, space))); + BOOST_TEST((at_c<0>(attr) == 'a')); + BOOST_TEST((at_c<1>(attr) == 'c')); + } + + { + // if only one node in a sequence is left (all the others are omitted), + // then we need "naked" attributes (not wraped in a tuple) + int attr; + BOOST_TEST((test_attr("a 123 c", omit['a'] >> int_ >> omit['c'], attr, space))); + BOOST_TEST((attr == 123)); + } + + { + // unused means we don't care about the attribute + BOOST_TEST((test_attr("abc", char_ >> 'b' >> char_, unused))); + } + + { // test action with omitted attribute + char c = 0; + auto f = [&](auto& ctx){ c = _attr(ctx); }; + + BOOST_TEST(test("x123\"a string\"", (char_ >> omit[int_] >> "\"a string\"")[f])); + BOOST_TEST(c == 'x'); + } + + { // test action with omitted attribute + int n = 0; + auto f = [&](auto& ctx){ n = _attr(ctx); }; + + BOOST_TEST(test("x 123 \"a string\"", (omit[char_] >> int_ >> "\"a string\"")[f], space)); + BOOST_TEST(n == 123); + } + + return boost::report_errors(); +} diff --git a/src/boost/libs/spirit/test/x3/optional.cpp b/src/boost/libs/spirit/test/x3/optional.cpp new file mode 100644 index 00000000..cd7f6d32 --- /dev/null +++ b/src/boost/libs/spirit/test/x3/optional.cpp @@ -0,0 +1,113 @@ +/*============================================================================= + Copyright (c) 2001-2015 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +=============================================================================*/ +#include <boost/detail/lightweight_test.hpp> +#include <boost/spirit/home/x3.hpp> +#include <boost/fusion/adapted/struct.hpp> +#include <boost/fusion/include/vector.hpp> + +#include <iostream> +#include "test.hpp" +#include "utils.hpp" + +struct adata +{ + int a; + boost::optional<int> b; +}; + +BOOST_FUSION_ADAPT_STRUCT(adata, + a, b +) + +struct test_attribute_type +{ + template <typename Context> + void operator()(Context& ctx) const + { + BOOST_TEST(typeid(decltype(_attr(ctx))).name() == typeid(boost::optional<int>).name()); + } +}; + +int +main() +{ + using boost::spirit::x3::traits::is_optional; + + static_assert(is_optional<boost::optional<int>>(), "is_optional problem"); + + using spirit_test::test; + using spirit_test::test_attr; + + using boost::spirit::x3::int_; + using boost::spirit::x3::omit; + using boost::spirit::x3::ascii::char_; + + { + BOOST_TEST((test("1234", -int_))); + BOOST_TEST((test("abcd", -int_, false))); + } + + { // test propagation of unused + using boost::fusion::at_c; + using boost::fusion::vector; + + vector<char, char> v; + BOOST_TEST((test_attr("a1234c", char_ >> -omit[int_] >> char_, v))); + BOOST_TEST((at_c<0>(v) == 'a')); + BOOST_TEST((at_c<1>(v) == 'c')); + + v = boost::fusion::vector<char, char>(); + BOOST_TEST((test_attr("a1234c", char_ >> omit[-int_] >> char_, v))); + BOOST_TEST((at_c<0>(v) == 'a')); + BOOST_TEST((at_c<1>(v) == 'c')); + + char ch; + BOOST_TEST((test_attr(",c", -(',' >> char_), ch))); + BOOST_TEST((ch == 'c')); + } + + { // test action + boost::optional<int> n = 0; + BOOST_TEST((test_attr("1234", (-int_)[test_attribute_type()], n))); + BOOST_TEST((n.get() == 1234)); + } + + { + std::string s; + BOOST_TEST((test_attr("abc", char_ >> -(char_ >> char_), s))); + BOOST_TEST(s == "abc"); + } + + { + boost::optional<int> n = 0; + auto f = [&](auto& ctx){ n = _attr(ctx); }; + + BOOST_TEST((test("1234", (-int_)[f]))); + BOOST_TEST(n.get() == 1234); + + n = boost::optional<int>(); + BOOST_TEST((test("abcd", (-int_)[f], false))); + BOOST_TEST(!n); + } + + { + std::vector<adata> v; + BOOST_TEST((test_attr("a 1 2 a 2", *('a' >> int_ >> -int_), v + , char_(' ')))); + BOOST_TEST(2 == v.size() && + 1 == v[0].a && v[0].b && 2 == *(v[0].b) && + 2 == v[1].a && !v[1].b); + } + + { // test move only types + boost::optional<move_only> o; + BOOST_TEST(test_attr("s", -synth_move_only, o)); + BOOST_TEST(o); + } + + return boost::report_errors(); +} diff --git a/src/boost/libs/spirit/test/x3/optional_ast_node.cpp b/src/boost/libs/spirit/test/x3/optional_ast_node.cpp new file mode 100644 index 00000000..036d6de4 --- /dev/null +++ b/src/boost/libs/spirit/test/x3/optional_ast_node.cpp @@ -0,0 +1,66 @@ +/*============================================================================= + Copyright (c) 2001-2015 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + + Duzy Chan: + This test addresses the usage of boost::optional<foo> as an ast node. +=============================================================================*/ +#include <boost/detail/lightweight_test.hpp> +#include <boost/spirit/home/x3.hpp> +#include <boost/fusion/adapted/struct.hpp> +#include <boost/fusion/include/vector.hpp> + +#include <iostream> +#include "test.hpp" +#include "utils.hpp" + +struct twoints +{ + int a; + int b; +}; + +struct adata +{ + twoints a; + boost::optional<twoints> b; + twoints c; +}; + +BOOST_FUSION_ADAPT_STRUCT(twoints, a, b) +BOOST_FUSION_ADAPT_STRUCT(adata, a, b, c) + +int +main() +{ + { + // Duzy Chan: This case addresses the usage of boost::optional<foo> + // as an ast node. Which should actually test the ability of + // boost::spirit::x3::traits::move_to to handle with optional source + // value. + boost::spirit::x3::rule<class twoints, adata> top = "top"; + boost::spirit::x3::rule<class twoints, boost::optional<twoints>> + twoints = "twoints"; + + using boost::spirit::x3::int_; + auto const top_def = twoints >> ',' >> -twoints >> ',' >> twoints; + auto const twoints_def = int_ >> int_; + + BOOST_SPIRIT_DEFINE(top, twoints); + + twoints a, b; + BOOST_TEST((test_attr("1 2,3 4,5 6", top, a))); + BOOST_TEST((a.a.a == 1 && a.a.b == 2)); + BOOST_TEST((a.b && a.b->a == 3 && a.b->b == 4)); + BOOST_TEST((a.c.a == 5 && a.c.b == 6)); + + BOOST_TEST((test_attr("1 2,,5 6", top), b)); + BOOST_TEST((b.a.a == 1 && b.a.b == 2)); + BOOST_TEST((!a.b)); + BOOST_TEST((b.c.a == 5 && b.c.b == 6)); + } + + return boost::report_errors(); +} diff --git a/src/boost/libs/spirit/test/x3/plus.cpp b/src/boost/libs/spirit/test/x3/plus.cpp new file mode 100644 index 00000000..7e27c84b --- /dev/null +++ b/src/boost/libs/spirit/test/x3/plus.cpp @@ -0,0 +1,140 @@ +/*============================================================================= + Copyright (c) 2001-2015 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +=============================================================================*/ +#include <string> +#include <vector> + +#include <boost/detail/lightweight_test.hpp> +#include <boost/spirit/home/x3.hpp> +#include <boost/fusion/include/vector.hpp> + +#include <string> +#include <iostream> +#include "test.hpp" +#include "utils.hpp" + +struct x_attr +{ +}; + +namespace boost { namespace spirit { namespace x3 { namespace traits +{ + template <> + struct container_value<x_attr> + { + typedef char type; // value type of container + }; + + template <> + struct push_back_container<x_attr> + { + static bool call(x_attr& /*c*/, char /*val*/) + { + // push back value type into container + return true; + } + }; +}}}} + +int +main() +{ + using spirit_test::test; + using spirit_test::test_attr; + using boost::spirit::x3::char_; + using boost::spirit::x3::alpha; + using boost::spirit::x3::upper; + using boost::spirit::x3::space; + using boost::spirit::x3::digit; + //~ using boost::spirit::x3::no_case; + using boost::spirit::x3::int_; + using boost::spirit::x3::omit; + using boost::spirit::x3::lit; + //~ using boost::spirit::x3::_1; + using boost::spirit::x3::lexeme; + + { + BOOST_TEST(test("aaaaaaaa", +char_)); + BOOST_TEST(test("a", +char_)); + BOOST_TEST(!test("", +char_)); + BOOST_TEST(test("aaaaaaaa", +alpha)); + BOOST_TEST(!test("aaaaaaaa", +upper)); + } + + { + BOOST_TEST(test(" a a aaa aa", +char_, space)); + BOOST_TEST(test("12345 678 9 ", +digit, space)); + } + + //~ { + //~ BOOST_TEST(test("aBcdeFGH", no_case[+char_])); + //~ BOOST_TEST(test("a B cde FGH ", no_case[+char_], space)); + //~ } + + { + std::vector<int> v; + BOOST_TEST(test_attr("123 456 789 10", +int_, v, space) && 4 == v.size() && + v[0] == 123 && v[1] == 456 && v[2] == 789 && v[3] == 10); + } + + { + std::vector<std::string> v; + BOOST_TEST(test_attr("a b c d", +lexeme[+alpha], v, space) && 4 == v.size() && + v[0] == "a" && v[1] == "b" && v[2] == "c" && v[3] == "d"); + } + + { + BOOST_TEST(test("Kim Kim Kim", +lit("Kim"), space)); + } + + // $$$ Fixme $$$ + /*{ + // The following 2 tests show that omit does not inhibit explicit attributes + + std::string s; + BOOST_TEST(test_attr("bbbb", omit[+char_('b')], s) && s == "bbbb"); + + s.clear(); + BOOST_TEST(test_attr("b b b b ", omit[+char_('b')], s, space) && s == "bbbb"); + }*/ + + { // actions + std::string v; + auto f = [&](auto& ctx){ v = _attr(ctx); }; + + BOOST_TEST(test("bbbb", (+char_)[f]) && 4 == v.size() && + v[0] == 'b' && v[1] == 'b' && v[2] == 'b' && v[3] == 'b'); + } + + { // more actions + std::vector<int> v; + auto f = [&](auto& ctx){ v = _attr(ctx); }; + + BOOST_TEST(test("1 2 3", (+int_)[f], space) && 3 == v.size() && + v[0] == 1 && v[1] == 2 && v[2] == 3); + } + + { // attribute customization + + x_attr x; + test_attr("abcde", +char_, x); + } + + // single-element fusion vector tests + { + boost::fusion::vector<std::string> fs; + BOOST_TEST((test_attr("12345", +char_, fs))); // ok + BOOST_TEST(boost::fusion::at_c<0>(fs) == "12345"); + } + + { // test move only types + std::vector<move_only> v; + BOOST_TEST(test_attr("sss", +synth_move_only, v)); + BOOST_TEST_EQ(v.size(), 3); + } + + return boost::report_errors(); +} diff --git a/src/boost/libs/spirit/test/x3/raw.cpp b/src/boost/libs/spirit/test/x3/raw.cpp new file mode 100644 index 00000000..78f025dd --- /dev/null +++ b/src/boost/libs/spirit/test/x3/raw.cpp @@ -0,0 +1,97 @@ +/*============================================================================= + Copyright (c) 2001-2014 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +=============================================================================*/ +#include <boost/detail/lightweight_test.hpp> +#include <boost/spirit/home/x3.hpp> +#include <boost/fusion/include/std_pair.hpp> + +#include <iostream> +#include <string> +#include "test.hpp" + +int main() +{ + using spirit_test::test; + using spirit_test::test_attr; + using namespace boost::spirit::x3::ascii; + using boost::spirit::x3::raw; + using boost::spirit::x3::eps; + using boost::spirit::x3::lit; + using boost::spirit::x3::_attr; + using boost::spirit::x3::parse; + using boost::spirit::x3::int_; + using boost::spirit::x3::char_; + + { + boost::iterator_range<char const*> range; + std::string str; + BOOST_TEST((test_attr("spirit_test_123", raw[alpha >> *(alnum | '_')], range))); + BOOST_TEST((std::string(range.begin(), range.end()) == "spirit_test_123")); + BOOST_TEST((test_attr(" spirit", raw[*alpha], range, space))); + BOOST_TEST((range.size() == 6)); + } + + { + std::string str; + BOOST_TEST((test_attr("spirit_test_123", raw[alpha >> *(alnum | '_')], str))); + BOOST_TEST((str == "spirit_test_123")); + } + + { + boost::iterator_range<char const*> range; + BOOST_TEST((test("x", raw[alpha]))); + BOOST_TEST((test_attr("x", raw[alpha], range))); + } + + { + boost::iterator_range<char const*> range; + BOOST_TEST((test("x", raw[alpha][ ([&](auto& ctx){ range = _attr(ctx); }) ]))); + BOOST_TEST(range.size() == 1 && *range.begin() == 'x'); + } + + { + boost::iterator_range<char const*> range; + BOOST_TEST((test("x123x", lit('x') >> raw[+digit] >> lit('x')))); + BOOST_TEST((test_attr("x123x", lit('x') >> raw[+digit] >> lit('x'), range))); + BOOST_TEST((std::string(range.begin(), range.end()) == "123")); + } + + { + using range = boost::iterator_range<std::string::iterator>; + boost::variant<int, range> attr; + + std::string str("test"); + parse(str.begin(), str.end(), (int_ | raw[*char_]), attr); + + auto rng = boost::get<range>(attr); + BOOST_TEST(std::string(rng.begin(), rng.end()) == "test"); + } + + { + std::vector<boost::iterator_range<std::string::iterator>> attr; + std::string str("123abcd"); + parse(str.begin(), str.end() + , (raw[int_] >> raw[*char_]) + , attr + ); + BOOST_TEST(attr.size() == 2); + BOOST_TEST(std::string(attr[0].begin(), attr[0].end()) == "123"); + BOOST_TEST(std::string(attr[1].begin(), attr[1].end()) == "abcd"); + } + + { + std::pair<int, boost::iterator_range<std::string::iterator>> attr; + std::string str("123abcd"); + parse(str.begin(), str.end() + , (int_ >> raw[*char_]) + , attr + ); + BOOST_TEST(attr.first == 123); + BOOST_TEST(std::string(attr.second.begin(), attr.second.end()) == "abcd"); + } + + return boost::report_errors(); +} diff --git a/src/boost/libs/spirit/test/x3/real.hpp b/src/boost/libs/spirit/test/x3/real.hpp new file mode 100644 index 00000000..7a680f73 --- /dev/null +++ b/src/boost/libs/spirit/test/x3/real.hpp @@ -0,0 +1,122 @@ +/*============================================================================= + Copyright (c) 2001-2010 Joel de Guzman + Copyright (c) 2001-2010 Hartmut Kaiser + + Use, modification and distribution is subject to the Boost Software + License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at + http://www.boost.org/LICENSE_1_0.txt) +=============================================================================*/ +#if !defined(BOOST_SPIRIT_TEST_X3_REAL_HPP) +#define BOOST_SPIRIT_TEST_X3_REAL_HPP + +#include <climits> +#include <boost/math/concepts/real_concept.hpp> +#include <boost/detail/lightweight_test.hpp> +#include <boost/spirit/home/x3/char.hpp> +#include <boost/spirit/home/x3/numeric.hpp> +#include <boost/spirit/home/x3/operator.hpp> +#include <boost/math/special_functions/fpclassify.hpp> +#include <boost/math/special_functions/sign.hpp> + +#include "test.hpp" + +/////////////////////////////////////////////////////////////////////////////// +// These policies can be used to parse thousand separated +// numbers with at most 2 decimal digits after the decimal +// point. e.g. 123,456,789.01 +/////////////////////////////////////////////////////////////////////////////// +template <typename T> +struct ts_real_policies : boost::spirit::x3::ureal_policies<T> +{ + // 2 decimal places Max + template <typename Iterator, typename Attribute> + static bool + parse_frac_n(Iterator& first, Iterator const& last, Attribute& attr) + { + namespace x3 = boost::spirit::x3; + return boost::spirit::x3::extract_uint<T, 10, 1, 2, true>::call(first, last, attr); + } + + // No exponent + template <typename Iterator> + static bool + parse_exp(Iterator&, Iterator const&) + { + return false; + } + + // No exponent + template <typename Iterator, typename Attribute> + static bool + parse_exp_n(Iterator&, Iterator const&, Attribute&) + { + return false; + } + + // Thousands separated numbers + template <typename Iterator, typename Accumulator> + static bool + parse_n(Iterator& first, Iterator const& last, Accumulator& result) + { + using boost::spirit::x3::uint_parser; + namespace x3 = boost::spirit::x3; + + uint_parser<unsigned, 10, 1, 3> uint3; + uint_parser<unsigned, 10, 3, 3> uint3_3; + + if (parse(first, last, uint3, result)) + { + Accumulator n; + Iterator iter = first; + + while (x3::parse(iter, last, ',') && x3::parse(iter, last, uint3_3, n)) + { + result = result * 1000 + n; + first = iter; + } + + return true; + } + return false; + } +}; + +template <typename T> +struct no_trailing_dot_policy : boost::spirit::x3::real_policies<T> +{ + static bool const allow_trailing_dot = false; +}; + +template <typename T> +struct no_leading_dot_policy : boost::spirit::x3::real_policies<T> +{ + static bool const allow_leading_dot = false; +}; + +template <typename T, typename T2> +bool +compare(T n, T2 expected) +{ + T const eps = std::pow(10.0, -std::numeric_limits<T>::digits10); + T delta = n - expected; + return (delta >= -eps) && (delta <= eps); +} + +/////////////////////////////////////////////////////////////////////////////// +// A custom real type +struct custom_real +{ + double n; + custom_real() : n(0) {} + custom_real(double n_) : n(n_) {} + friend bool operator==(custom_real a, custom_real b) + { return a.n == b.n; } + friend custom_real operator*(custom_real a, custom_real b) + { return custom_real(a.n * b.n); } + friend custom_real operator+(custom_real a, custom_real b) + { return custom_real(a.n + b.n); } + friend custom_real operator-(custom_real a, custom_real b) + { return custom_real(a.n - b.n); } +}; + +#endif diff --git a/src/boost/libs/spirit/test/x3/real1.cpp b/src/boost/libs/spirit/test/x3/real1.cpp new file mode 100644 index 00000000..f550a606 --- /dev/null +++ b/src/boost/libs/spirit/test/x3/real1.cpp @@ -0,0 +1,119 @@ +/*============================================================================= + Copyright (c) 2001-2015 Joel de Guzman + Copyright (c) 2001-2011 Hartmut Kaiser + Copyright (c) 2011 Bryce Lelbach + + Use, modification and distribution is subject to the Boost Software + License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at + http://www.boost.org/LICENSE_1_0.txt) +=============================================================================*/ + +#include "real.hpp" + +int +main() +{ + using spirit_test::test; + using spirit_test::test_attr; + + /////////////////////////////////////////////////////////////////////////// + // thousand separated numbers + /////////////////////////////////////////////////////////////////////////// + { + using boost::spirit::x3::uint_parser; + using boost::spirit::x3::parse; + + uint_parser<unsigned, 10, 1, 3> uint3; + uint_parser<unsigned, 10, 3, 3> uint3_3; + + #define r (uint3 >> *(',' >> uint3_3)) + + BOOST_TEST(test("1,234,567,890", r)); + BOOST_TEST(test("12,345,678,900", r)); + BOOST_TEST(test("123,456,789,000", r)); + BOOST_TEST(!test("1000,234,567,890", r)); + BOOST_TEST(!test("1,234,56,890", r)); + BOOST_TEST(!test("1,66", r)); + } + + /////////////////////////////////////////////////////////////////////////// + // unsigned real number tests + /////////////////////////////////////////////////////////////////////////// + { + using boost::spirit::x3::real_parser; + using boost::spirit::x3::parse; + using boost::spirit::x3::ureal_policies; + + real_parser<double, ureal_policies<double> > udouble; + double d; + + BOOST_TEST(test("1234", udouble)); + BOOST_TEST(test_attr("1234", udouble, d) && compare(d, 1234)); + + BOOST_TEST(test("1.2e3", udouble)); + BOOST_TEST(test_attr("1.2e3", udouble, d) && compare(d, 1.2e3)); + + BOOST_TEST(test("1.2e-3", udouble)); + BOOST_TEST(test_attr("1.2e-3", udouble, d) && compare(d, 1.2e-3)); + + BOOST_TEST(test("1.e2", udouble)); + BOOST_TEST(test_attr("1.e2", udouble, d) && compare(d, 1.e2)); + + BOOST_TEST(test("1.", udouble)); + BOOST_TEST(test_attr("1.", udouble, d) && compare(d, 1.)); + + BOOST_TEST(test(".2e3", udouble)); + BOOST_TEST(test_attr(".2e3", udouble, d) && compare(d, .2e3)); + + BOOST_TEST(test("2e3", udouble)); + BOOST_TEST(test_attr("2e3", udouble, d) && compare(d, 2e3)); + + BOOST_TEST(test("2", udouble)); + BOOST_TEST(test_attr("2", udouble, d) && compare(d, 2)); + + using boost::math::fpclassify; + BOOST_TEST(test("inf", udouble)); + BOOST_TEST(test("infinity", udouble)); + BOOST_TEST(test("INF", udouble)); + BOOST_TEST(test("INFINITY", udouble)); + + BOOST_TEST(test_attr("inf", udouble, d) + && FP_INFINITE == fpclassify(d)); + BOOST_TEST(test_attr("INF", udouble, d) + && FP_INFINITE == fpclassify(d)); + BOOST_TEST(test_attr("infinity", udouble, d) + && FP_INFINITE == fpclassify(d)); + BOOST_TEST(test_attr("INFINITY", udouble, d) + && FP_INFINITE == fpclassify(d)); + + BOOST_TEST(test("nan", udouble)); + BOOST_TEST(test_attr("nan", udouble, d) + && FP_NAN == fpclassify(d)); + BOOST_TEST(test("NAN", udouble)); + BOOST_TEST(test_attr("NAN", udouble, d) + && FP_NAN == fpclassify(d)); + BOOST_TEST(test("nan(...)", udouble)); + BOOST_TEST(test_attr("nan(...)", udouble, d) + && FP_NAN == fpclassify(d)); + BOOST_TEST(test("NAN(...)", udouble)); + BOOST_TEST(test_attr("NAN(...)", udouble, d) + && FP_NAN == fpclassify(d)); + + BOOST_TEST(!test("e3", udouble)); + BOOST_TEST(!test_attr("e3", udouble, d)); + + BOOST_TEST(!test("-1.2e3", udouble)); + BOOST_TEST(!test_attr("-1.2e3", udouble, d)); + + BOOST_TEST(!test("+1.2e3", udouble)); + BOOST_TEST(!test_attr("+1.2e3", udouble, d)); + + BOOST_TEST(!test("1.2e", udouble)); + BOOST_TEST(!test_attr("1.2e", udouble, d)); + + BOOST_TEST(!test("-.3", udouble)); + BOOST_TEST(!test_attr("-.3", udouble, d)); + } + + return boost::report_errors(); +} diff --git a/src/boost/libs/spirit/test/x3/real2.cpp b/src/boost/libs/spirit/test/x3/real2.cpp new file mode 100644 index 00000000..dc003f0d --- /dev/null +++ b/src/boost/libs/spirit/test/x3/real2.cpp @@ -0,0 +1,132 @@ +/*============================================================================= + Copyright (c) 2001-2015 Joel de Guzman + Copyright (c) 2001-2011 Hartmut Kaiser + Copyright (c) 2011 Bryce Lelbach + + Use, modification and distribution is subject to the Boost Software + License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at + http://www.boost.org/LICENSE_1_0.txt) +=============================================================================*/ + +#include "real.hpp" + +template <typename T, typename P> +void basic_real_parser_test(P parser) +{ + using spirit_test::test; + using spirit_test::test_attr; + + T attr; + + BOOST_TEST(test("-1234", parser)); + BOOST_TEST(test_attr("-1234", parser, attr) && compare(attr, T(-1234l))); + + BOOST_TEST(test("-1.2e3", parser)); + BOOST_TEST(test_attr("-1.2e3", parser, attr) && compare(attr, T(-1.2e3l))); + + BOOST_TEST(test("+1.2e3", parser)); + BOOST_TEST(test_attr("+1.2e3", parser, attr) && compare(attr, T(1.2e3l))); + + BOOST_TEST(test("-0.1", parser)); + BOOST_TEST(test_attr("-0.1", parser, attr) && compare(attr, T(-0.1l))); + + BOOST_TEST(test("-1.2e-3", parser)); + BOOST_TEST(test_attr("-1.2e-3", parser, attr) && compare(attr, T(-1.2e-3l))); + + BOOST_TEST(test("-1.e2", parser)); + BOOST_TEST(test_attr("-1.e2", parser, attr) && compare(attr, T(-1.e2l))); + + BOOST_TEST(test("-.2e3", parser)); + BOOST_TEST(test_attr("-.2e3", parser, attr) && compare(attr, T(-.2e3l))); + + BOOST_TEST(test("-2e3", parser)); + BOOST_TEST(test_attr("-2e3", parser, attr) && compare(attr, T(-2e3l))); + + BOOST_TEST(!test("-e3", parser)); + BOOST_TEST(!test_attr("-e3", parser, attr)); + + BOOST_TEST(!test("-1.2e", parser)); + BOOST_TEST(!test_attr("-1.2e", parser, attr)); +} + +int +main() +{ + using spirit_test::test; + using spirit_test::test_attr; + /////////////////////////////////////////////////////////////////////////// + // signed real number tests + /////////////////////////////////////////////////////////////////////////// + { + basic_real_parser_test<float>(boost::spirit::x3::float_); + basic_real_parser_test<double>(boost::spirit::x3::double_); + basic_real_parser_test<long double>(boost::spirit::x3::long_double); + } + + { + using boost::spirit::x3::double_; + double d; + +#if defined(BOOST_SPIRIT_TEST_REAL_PRECISION) + BOOST_TEST(test_attr("-5.7222349715140557e+307", double_, d)); + BOOST_TEST(d == -5.7222349715140557e+307); // exact! + + BOOST_TEST(test_attr("2.0332938517515416e-308", double_, d)); + BOOST_TEST(d == 2.0332938517515416e-308); // exact! + + BOOST_TEST(test_attr("20332938517515416e291", double_, d)); + BOOST_TEST(d == 20332938517515416e291); // exact! + + BOOST_TEST(test_attr("2.0332938517515416e307", double_, d)); + BOOST_TEST(d == 2.0332938517515416e307); // exact! +#endif + + using boost::math::fpclassify; + using boost::spirit::x3::signbit; // Boost version is broken + + BOOST_TEST(test("-inf", double_)); + BOOST_TEST(test("-infinity", double_)); + BOOST_TEST(test_attr("-inf", double_, d) && + FP_INFINITE == fpclassify(d) && signbit(d)); + BOOST_TEST(test_attr("-infinity", double_, d) && + FP_INFINITE == fpclassify(d) && signbit(d)); + BOOST_TEST(test("-INF", double_)); + BOOST_TEST(test("-INFINITY", double_)); + BOOST_TEST(test_attr("-INF", double_, d) && + FP_INFINITE == fpclassify(d) && signbit(d)); + BOOST_TEST(test_attr("-INFINITY", double_, d) && + FP_INFINITE == fpclassify(d) && signbit(d)); + + BOOST_TEST(test("-nan", double_)); + BOOST_TEST(test_attr("-nan", double_, d) && + FP_NAN == fpclassify(d) && signbit(d)); + BOOST_TEST(test("-NAN", double_)); + BOOST_TEST(test_attr("-NAN", double_, d) && + FP_NAN == fpclassify(d) && signbit(d)); + + BOOST_TEST(test("-nan(...)", double_)); + BOOST_TEST(test_attr("-nan(...)", double_, d) && + FP_NAN == fpclassify(d) && signbit(d)); + BOOST_TEST(test("-NAN(...)", double_)); + BOOST_TEST(test_attr("-NAN(...)", double_, d) && + FP_NAN == fpclassify(d) && signbit(d)); + + BOOST_TEST(!test("1e999", double_)); + BOOST_TEST(!test("1e-999", double_)); + BOOST_TEST(test_attr("2.1111111e-303", double_, d) && + compare(d, 2.1111111e-303)); + BOOST_TEST(!test_attr("1.1234e", double_, d) && compare(d, 1.1234)); + + // https://svn.boost.org/trac10/ticket/11608 + BOOST_TEST(test_attr("1267650600228229401496703205376", double_, d) && + compare(d, 1.2676506002282291E+30)); // Note Qi has better precision + + BOOST_TEST(test_attr("12676506.00228229401496703205376", double_, d) && + compare(d, 1.2676506002282292E7)); // Note Qi has better precision + + BOOST_TEST(test_attr("12676506.00228229401496703205376E6", double_, d) && + compare(d, 1.2676506002282291016E13)); // Note Qi has better precision + } + + return boost::report_errors(); +} diff --git a/src/boost/libs/spirit/test/x3/real3.cpp b/src/boost/libs/spirit/test/x3/real3.cpp new file mode 100644 index 00000000..09e11ad9 --- /dev/null +++ b/src/boost/libs/spirit/test/x3/real3.cpp @@ -0,0 +1,85 @@ +/*============================================================================= + Copyright (c) 2001-2015 Joel de Guzman + Copyright (c) 2001-2010 Hartmut Kaiser + + Use, modification and distribution is subject to the Boost Software + License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at + http://www.boost.org/LICENSE_1_0.txt) +=============================================================================*/ + +#include "real.hpp" + +int +main() +{ + using spirit_test::test; + using spirit_test::test_attr; + + /////////////////////////////////////////////////////////////////////////// + // strict real number tests + /////////////////////////////////////////////////////////////////////////// + { + using boost::spirit::x3::real_parser; + using boost::spirit::x3::parse; + using boost::spirit::x3::strict_ureal_policies; + using boost::spirit::x3::strict_real_policies; + + real_parser<double, strict_ureal_policies<double> > strict_udouble; + real_parser<double, strict_real_policies<double> > strict_double; + double d; + + BOOST_TEST(!test("1234", strict_udouble)); + BOOST_TEST(!test_attr("1234", strict_udouble, d)); + + BOOST_TEST(test("1.2", strict_udouble)); + BOOST_TEST(test_attr("1.2", strict_udouble, d) && compare(d, 1.2)); + + BOOST_TEST(!test("-1234", strict_double)); + BOOST_TEST(!test_attr("-1234", strict_double, d)); + + BOOST_TEST(test("123.", strict_double)); + BOOST_TEST(test_attr("123.", strict_double, d) && compare(d, 123)); + + BOOST_TEST(test("3.E6", strict_double)); + BOOST_TEST(test_attr("3.E6", strict_double, d) && compare(d, 3e6)); + + real_parser<double, no_trailing_dot_policy<double> > notrdot_real; + real_parser<double, no_leading_dot_policy<double> > nolddot_real; + + BOOST_TEST(!test("1234.", notrdot_real)); // Bad trailing dot + BOOST_TEST(!test(".1234", nolddot_real)); // Bad leading dot + } + + /////////////////////////////////////////////////////////////////////////// + // Special thousands separated numbers + /////////////////////////////////////////////////////////////////////////// + { + using boost::spirit::x3::real_parser; + using boost::spirit::x3::parse; + real_parser<double, ts_real_policies<double> > ts_real; + double d; + + BOOST_TEST(test("123.01", ts_real)); + BOOST_TEST(test_attr("123.01", ts_real, d) + && compare(d, 123.01)); + + BOOST_TEST(test("123,456,789.01", ts_real)); + BOOST_TEST(test_attr("123,456,789.01", ts_real, d) + && compare(d, 123456789.01)); + + BOOST_TEST(test("12,345,678.90", ts_real)); + BOOST_TEST(test_attr("12,345,678.90", ts_real, d) + && compare(d, 12345678.90)); + + BOOST_TEST(test("1,234,567.89", ts_real)); + BOOST_TEST(test_attr("1,234,567.89", ts_real, d) + && compare(d, 1234567.89)); + + BOOST_TEST(!test("1234,567,890", ts_real)); + BOOST_TEST(!test("1,234,5678,9", ts_real)); + BOOST_TEST(!test("1,234,567.89e6", ts_real)); + BOOST_TEST(!test("1,66", ts_real)); + } + + return boost::report_errors(); +} diff --git a/src/boost/libs/spirit/test/x3/real4.cpp b/src/boost/libs/spirit/test/x3/real4.cpp new file mode 100644 index 00000000..0b668c75 --- /dev/null +++ b/src/boost/libs/spirit/test/x3/real4.cpp @@ -0,0 +1,73 @@ +/*============================================================================= + Copyright (c) 2001-2015 Joel de Guzman + Copyright (c) 2001-2011 Hartmut Kaiser + Copyright (c) 2011 Bryce Lelbach + + Use, modification and distribution is subject to the Boost Software + License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at + http://www.boost.org/LICENSE_1_0.txt) +=============================================================================*/ + +#include "real.hpp" + +int +main() +{ + using spirit_test::test; + using spirit_test::test_attr; + + /////////////////////////////////////////////////////////////////////////// + // Custom data type + /////////////////////////////////////////////////////////////////////////// + { + using boost::math::concepts::real_concept; + using boost::spirit::x3::real_parser; + using boost::spirit::x3::real_policies; + using boost::spirit::x3::parse; + + real_parser<real_concept, real_policies<real_concept> > custom_real; + real_concept d; + + BOOST_TEST(test("-1234", custom_real)); + BOOST_TEST(test_attr("-1234", custom_real, d) && compare(d, -1234)); + + BOOST_TEST(test("-1.2e3", custom_real)); + BOOST_TEST(test_attr("-1.2e3", custom_real, d) && compare(d, -1.2e3)); + + BOOST_TEST(test("+1.2e3", custom_real)); + BOOST_TEST(test_attr("+1.2e3", custom_real, d) && compare(d, 1.2e3)); + + BOOST_TEST(test("-0.1", custom_real)); + BOOST_TEST(test_attr("-0.1", custom_real, d) && compare(d, -0.1)); + + BOOST_TEST(test("-1.2e-3", custom_real)); + BOOST_TEST(test_attr("-1.2e-3", custom_real, d) && compare(d, -1.2e-3)); + + BOOST_TEST(test("-1.e2", custom_real)); + BOOST_TEST(test_attr("-1.e2", custom_real, d) && compare(d, -1.e2)); + + BOOST_TEST(test("-.2e3", custom_real)); + BOOST_TEST(test_attr("-.2e3", custom_real, d) && compare(d, -.2e3)); + + BOOST_TEST(test("-2e3", custom_real)); + BOOST_TEST(test_attr("-2e3", custom_real, d) && compare(d, -2e3)); + + BOOST_TEST(!test("-e3", custom_real)); + BOOST_TEST(!test_attr("-e3", custom_real, d)); + + BOOST_TEST(!test("-1.2e", custom_real)); + BOOST_TEST(!test_attr("-1.2e", custom_real, d)); + } + + /////////////////////////////////////////////////////////////////////////// + // custom real tests + /////////////////////////////////////////////////////////////////////////// + { + using boost::spirit::x3::double_; + custom_real n; + + BOOST_TEST(test_attr("-123456e6", double_, n)); + } + + return boost::report_errors(); +} diff --git a/src/boost/libs/spirit/test/x3/repeat.cpp b/src/boost/libs/spirit/test/x3/repeat.cpp new file mode 100644 index 00000000..99c080fe --- /dev/null +++ b/src/boost/libs/spirit/test/x3/repeat.cpp @@ -0,0 +1,152 @@ +/*============================================================================= + Copyright (c) 2001-2011 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +=============================================================================*/ +#include <string> +#include <vector> + +#include <boost/detail/lightweight_test.hpp> +#include <boost/utility/enable_if.hpp> + +#include <boost/spirit/home/x3.hpp> +#include <string> +#include <iostream> +#include "test.hpp" +#include "utils.hpp" + +int +main() +{ + using spirit_test::test_attr; + using spirit_test::test; + + using namespace boost::spirit::x3::ascii; + using boost::spirit::x3::repeat; + using boost::spirit::x3::inf; + using boost::spirit::x3::omit; + using boost::spirit::x3::int_; + using boost::spirit::x3::lexeme; + using boost::spirit::x3::char_; + { + BOOST_TEST(test("aaaaaaaa", repeat[char_])); // kleene synonym + BOOST_TEST(test("aaaaaaaa", repeat(8)[char_])); + BOOST_TEST(!test("aa", repeat(3)[char_])); + BOOST_TEST(test("aaa", repeat(3, 5)[char_])); + BOOST_TEST(test("aaaaa", repeat(3, 5)[char_])); + BOOST_TEST(!test("aaaaaa", repeat(3, 5)[char_])); + BOOST_TEST(!test("aa", repeat(3, 5)[char_])); + + BOOST_TEST(test("aaa", repeat(3, inf)[char_])); + BOOST_TEST(test("aaaaa", repeat(3, inf)[char_])); + BOOST_TEST(test("aaaaaa", repeat(3, inf)[char_])); + BOOST_TEST(!test("aa", repeat(3, inf)[char_])); + } + { + std::string s; + BOOST_TEST(test_attr("aaaaaaaa", repeat[char_ >> char_], s)); // kleene synonym + BOOST_TEST(s == "aaaaaaaa"); + + s.clear(); + BOOST_TEST(test_attr("aaaaaaaa", repeat(4)[char_ >> char_], s)); + BOOST_TEST(s == "aaaaaaaa"); + + BOOST_TEST(!test("aa", repeat(3)[char_ >> char_])); + BOOST_TEST(!test("a", repeat(1)[char_ >> char_])); + + s.clear(); + BOOST_TEST(test_attr("aa", repeat(1, 3)[char_ >> char_], s)); + BOOST_TEST(s == "aa"); + + s.clear(); + BOOST_TEST(test_attr("aaaaaa", repeat(1, 3)[char_ >> char_], s)); + BOOST_TEST(s == "aaaaaa"); + + BOOST_TEST(!test("aaaaaaa", repeat(1, 3)[char_ >> char_])); + BOOST_TEST(!test("a", repeat(1, 3)[char_ >> char_])); + + s.clear(); + BOOST_TEST(test_attr("aaaa", repeat(2, inf)[char_ >> char_], s)); + BOOST_TEST(s == "aaaa"); + + s.clear(); + BOOST_TEST(test_attr("aaaaaa", repeat(2, inf)[char_ >> char_], s)); + BOOST_TEST(s == "aaaaaa"); + + BOOST_TEST(!test("aa", repeat(2, inf)[char_ >> char_])); + } + + { // from classic spirit tests + BOOST_TEST(test("", repeat(0, inf)['x'])); + + // repeat exact 8 + #define rep8 repeat(8)[alpha] >> 'X' + BOOST_TEST(!test("abcdefgX", rep8, false)); + BOOST_TEST(test("abcdefghX", rep8)); + BOOST_TEST(!test("abcdefghiX", rep8, false)); + BOOST_TEST(!test("abcdefgX", rep8, false)); + BOOST_TEST(!test("aX", rep8, false)); + + // repeat 2 to 8 + #define rep28 repeat(2, 8)[alpha] >> '*' + BOOST_TEST(test("abcdefg*", rep28)); + BOOST_TEST(test("abcdefgh*", rep28)); + BOOST_TEST(!test("abcdefghi*", rep28, false)); + BOOST_TEST(!test("a*", rep28, false)); + + // repeat 2 or more + #define rep2_ repeat(2, inf)[alpha] >> '+' + BOOST_TEST(test("abcdefg+", rep2_)); + BOOST_TEST(test("abcdefgh+", rep2_)); + BOOST_TEST(test("abcdefghi+", rep2_)); + BOOST_TEST(test("abcdefg+", rep2_)); + BOOST_TEST(!test("a+", rep2_, false)); + + // repeat 0 + #define rep0 repeat(0)[alpha] >> '/' + BOOST_TEST(test("/", rep0)); + BOOST_TEST(!test("a/", rep0, false)); + + // repeat 0 or 1 + #define rep01 repeat(0, 1)[alpha >> digit] >> '?' + BOOST_TEST(!test("abcdefg?", rep01, false)); + BOOST_TEST(!test("a?", rep01, false)); + BOOST_TEST(!test("1?", rep01, false)); + BOOST_TEST(!test("11?", rep01, false)); + BOOST_TEST(!test("aa?", rep01, false)); + BOOST_TEST(test("?", rep01)); + BOOST_TEST(test("a1?", rep01)); + } + + { + BOOST_TEST(test(" a a aaa aa", repeat(7)[char_], space)); + BOOST_TEST(test("12345 678 9", repeat(9)[digit], space)); + } + + { + std::vector<std::string> v; + BOOST_TEST(test_attr("a b c d", repeat(4)[lexeme[+alpha]], v, space) && 4 == v.size() && + v[0] == "a" && v[1] == "b" && v[2] == "c" && v[3] == "d"); + } + { + BOOST_TEST(test("1 2 3", int_ >> repeat(2)[int_], space)); + BOOST_TEST(!test("1 2", int_ >> repeat(2)[int_], space)); + } + + { + std::vector<char> v; + BOOST_TEST(test_attr("1 2 3", int_ >> repeat(2)[int_], v, space)); + BOOST_TEST(v.size() == 3 && v[0] == 1 && v[1] == 2 && v[2] == 3); + + BOOST_TEST(!test("1 2", int_ >> repeat(2)[int_], space)); + } + + { // test move only types + std::vector<move_only> v; + BOOST_TEST(test_attr("sss", repeat(3)[synth_move_only], v)); + BOOST_TEST_EQ(v.size(), 3); + } + + return boost::report_errors(); +} diff --git a/src/boost/libs/spirit/test/x3/rule1.cpp b/src/boost/libs/spirit/test/x3/rule1.cpp new file mode 100644 index 00000000..09941dec --- /dev/null +++ b/src/boost/libs/spirit/test/x3/rule1.cpp @@ -0,0 +1,129 @@ +/*============================================================================= + Copyright (c) 2001-2015 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +=============================================================================*/ + +#include <boost/detail/lightweight_test.hpp> +#include <boost/spirit/home/x3.hpp> + +#include <string> +#include <cstring> +#include <iostream> +#include "test.hpp" + +int +main() +{ + using spirit_test::test_attr; + using spirit_test::test; + + using namespace boost::spirit::x3::ascii; + using boost::spirit::x3::rule; + using boost::spirit::x3::lit; + using boost::spirit::x3::int_; + using boost::spirit::x3::unused_type; + using boost::spirit::x3::phrase_parse; + using boost::spirit::x3::skip_flag; + using boost::spirit::x3::traits::has_attribute; + + // check attribute advertising + static_assert( has_attribute<rule<class r, int>, /*Context=*/unused_type>::value, ""); + static_assert(!has_attribute<rule<class r >, /*Context=*/unused_type>::value, ""); + static_assert( has_attribute<decltype(rule<class r, int>{} = int_), /*Context=*/unused_type>::value, ""); + static_assert(!has_attribute<decltype(rule<class r >{} = int_), /*Context=*/unused_type>::value, ""); + + + { // basic tests + + auto a = lit('a'); + auto b = lit('b'); + auto c = lit('c'); + rule<class r> r; + + { + auto start = + r = *(a | b | c); + + BOOST_TEST(test("abcabcacb", start)); + } + + { + auto start = + r = (a | b) >> (r | b); + + BOOST_TEST(test("aaaabababaaabbb", start)); + BOOST_TEST(test("aaaabababaaabba", start, false)); + + // ignore the skipper! + BOOST_TEST(test("aaaabababaaabba", start, space, false)); + } + } + + { // basic tests w/ skipper + + auto a = lit('a'); + auto b = lit('b'); + auto c = lit('c'); + rule<class r> r; + + { + auto start = + r = *(a | b | c); + + BOOST_TEST(test(" a b c a b c a c b ", start, space)); + } + + { + auto start = + r = (a | b) >> (r | b); + + BOOST_TEST(test(" a a a a b a b a b a a a b b b ", start, space)); + BOOST_TEST(test(" a a a a b a b a b a a a b b a ", start, space, false)); + } + } + + { // basic tests w/ skipper but no final post-skip + + auto a = rule<class a>() + = lit('a'); + + auto b = rule<class b>() + = lit('b'); + + auto c = rule<class c>() + = lit('c'); + + { + auto start = rule<class start>() = *(a | b) >> c; + + char const *s1 = " a b a a b b a c ... " + , *const e1 = s1 + std::strlen(s1); + BOOST_TEST(phrase_parse(s1, e1, start, space, skip_flag::dont_post_skip) + && s1 == e1 - 5); + + } + + { + rule<class start> start; + + auto p = + start = (a | b) >> (start | c); + { + char const *s1 = " a a a a b a b a b a a a b b b c " + , *const e1 = s1 + std::strlen(s1); + BOOST_TEST(phrase_parse(s1, e1, p, space, skip_flag::post_skip) + && s1 == e1); + } + { + char const *s1 = " a a a a b a b a b a a a b b b c " + , *const e1 = s1 + std::strlen(s1); + BOOST_TEST(phrase_parse(s1, e1, p, space, skip_flag::dont_post_skip) + && s1 == e1 - 1); + } + } + } + + return boost::report_errors(); +} diff --git a/src/boost/libs/spirit/test/x3/rule2.cpp b/src/boost/libs/spirit/test/x3/rule2.cpp new file mode 100644 index 00000000..fd6c07fa --- /dev/null +++ b/src/boost/libs/spirit/test/x3/rule2.cpp @@ -0,0 +1,108 @@ +/*============================================================================= + Copyright (c) 2001-2015 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +=============================================================================*/ + +#include <boost/detail/lightweight_test.hpp> +#include <boost/spirit/home/x3.hpp> + +#include <string> +#include <cstring> +#include <iostream> +#include "test.hpp" + +int +main() +{ + using spirit_test::test_attr; + using spirit_test::test; + + using namespace boost::spirit::x3::ascii; + using boost::spirit::x3::rule; + using boost::spirit::x3::lit; + using boost::spirit::x3::unused_type; + using boost::spirit::x3::_attr; + + { // context tests + + char ch; + auto a = rule<class a, char>() = alpha; + + // this semantic action requires the context + auto f = [&](auto& ctx){ ch = _attr(ctx); }; + BOOST_TEST(test("x", a[f])); + BOOST_TEST(ch == 'x'); + + // this semantic action requires the (unused) context + auto f2 = [&](auto&){ ch = 'y'; }; + BOOST_TEST(test("x", a[f2])); + BOOST_TEST(ch == 'y'); + + // the semantic action may optionally not have any arguments at all + auto f3 = [&]{ ch = 'z'; }; + BOOST_TEST(test("x", a[f3])); + BOOST_TEST(ch == 'z'); + + BOOST_TEST(test_attr("z", a, ch)); // attribute is given. + BOOST_TEST(ch == 'z'); + } + + { // auto rules tests + + char ch = '\0'; + auto a = rule<class a, char>() = alpha; + auto f = [&](auto& ctx){ ch = _attr(ctx); }; + + BOOST_TEST(test("x", a[f])); + BOOST_TEST(ch == 'x'); + ch = '\0'; + BOOST_TEST(test_attr("z", a, ch)); // attribute is given. + BOOST_TEST(ch == 'z'); + + ch = '\0'; + BOOST_TEST(test("x", a[f])); + BOOST_TEST(ch == 'x'); + ch = '\0'; + BOOST_TEST(test_attr("z", a, ch)); // attribute is given. + BOOST_TEST(ch == 'z'); + } + + { // auto rules tests: allow stl containers as attributes to + // sequences (in cases where attributes of the elements + // are convertible to the value_type of the container or if + // the element itself is an stl container with value_type + // that is convertible to the value_type of the attribute). + + std::string s; + auto f = [&](auto& ctx){ s = _attr(ctx); }; + + { + auto r = rule<class r, std::string>() + = char_ >> *(',' >> char_) + ; + + BOOST_TEST(test("a,b,c,d,e,f", r[f])); + BOOST_TEST(s == "abcdef"); + } + + { + auto r = rule<class r, std::string>() + = char_ >> *(',' >> char_); + s.clear(); + BOOST_TEST(test("a,b,c,d,e,f", r[f])); + BOOST_TEST(s == "abcdef"); + } + + { + auto r = rule<class r, std::string>() + = char_ >> char_ >> char_ >> char_ >> char_ >> char_; + s.clear(); + BOOST_TEST(test("abcdef", r[f])); + BOOST_TEST(s == "abcdef"); + } + } + + return boost::report_errors(); +} diff --git a/src/boost/libs/spirit/test/x3/rule3.cpp b/src/boost/libs/spirit/test/x3/rule3.cpp new file mode 100644 index 00000000..420146c0 --- /dev/null +++ b/src/boost/libs/spirit/test/x3/rule3.cpp @@ -0,0 +1,109 @@ +/*============================================================================= + Copyright (c) 2001-2012 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +=============================================================================*/ + +#include <boost/detail/lightweight_test.hpp> +#include <boost/spirit/home/x3.hpp> +#include <boost/fusion/include/std_pair.hpp> + +#include <string> +#include <cstring> +#include <iostream> +#include "test.hpp" + +using boost::spirit::x3::_val; + +struct f +{ + template <typename Context> + void operator()(Context const& ctx) const + { + _val(ctx) += _attr(ctx); + } +}; + + +struct stationary : boost::noncopyable +{ + explicit stationary(int i) : val{i} {} + stationary& operator=(int i) { val = i; return *this; } + + int val; +}; + + +namespace check_stationary { + +boost::spirit::x3::rule<class a_r, stationary> const a; +boost::spirit::x3::rule<class b_r, stationary> const b; + +auto const a_def = '{' >> boost::spirit::x3::int_ >> '}'; +auto const b_def = a; + +BOOST_SPIRIT_DEFINE(a, b) + +} + + +int main() +{ + using spirit_test::test_attr; + using spirit_test::test; + + using namespace boost::spirit::x3::ascii; + using boost::spirit::x3::rule; + using boost::spirit::x3::lit; + using boost::spirit::x3::eps; + using boost::spirit::x3::unused_type; + + + { // synth attribute value-init + + std::string s; + typedef rule<class r, std::string> rule_type; + + auto rdef = rule_type() + = alpha [f()] + ; + + BOOST_TEST(test_attr("abcdef", +rdef, s)); + BOOST_TEST(s == "abcdef"); + } + + { // synth attribute value-init + + std::string s; + typedef rule<class r, std::string> rule_type; + + auto rdef = rule_type() = + alpha / + [](auto& ctx) + { + _val(ctx) += _attr(ctx); + } + ; + + BOOST_TEST(test_attr("abcdef", +rdef, s)); + BOOST_TEST(s == "abcdef"); + } + + { + auto r = rule<class r, int>{} = eps[([] (auto& ctx) { + using boost::spirit::x3::_val; + static_assert(std::is_same<std::decay_t<decltype(_val(ctx))>, unused_type>::value, + "Attribute must not be synthesized"); + })]; + BOOST_TEST(test("", r)); + } + + { // ensure no unneded synthesization, copying and moving occured + stationary st { 0 }; + BOOST_TEST(test_attr("{42}", check_stationary::b, st)); + BOOST_TEST_EQ(st.val, 42); + } + + return boost::report_errors(); +} diff --git a/src/boost/libs/spirit/test/x3/rule4.cpp b/src/boost/libs/spirit/test/x3/rule4.cpp new file mode 100644 index 00000000..3e3a647d --- /dev/null +++ b/src/boost/libs/spirit/test/x3/rule4.cpp @@ -0,0 +1,164 @@ +/*============================================================================= + Copyright (c) 2001-2015 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +=============================================================================*/ + +#include <boost/detail/lightweight_test.hpp> +#include <boost/spirit/home/x3.hpp> +#include <boost/fusion/include/vector.hpp> +#include <boost/fusion/include/at.hpp> + +#include <string> +#include <cstring> +#include <iostream> +#include "test.hpp" + +namespace x3 = boost::spirit::x3; + +int got_it = 0; + +struct my_rule_class +{ + template <typename Iterator, typename Exception, typename Context> + x3::error_handler_result + on_error(Iterator&, Iterator const& last, Exception const& x, Context const&) + { + std::cout + << "Error! Expecting: " + << x.which() + << ", got: \"" + << std::string(x.where(), last) + << "\"" + << std::endl + ; + return x3::error_handler_result::fail; + } + + template <typename Iterator, typename Attribute, typename Context> + inline void + on_success(Iterator const&, Iterator const&, Attribute&, Context const&) + { + ++got_it; + } +}; + +int +main() +{ + using spirit_test::test_attr; + using spirit_test::test; + + using namespace boost::spirit::x3::ascii; + using boost::spirit::x3::rule; + using boost::spirit::x3::int_; + using boost::spirit::x3::lit; + + { // show that ra = rb and ra %= rb works as expected + rule<class a, int> ra; + rule<class b, int> rb; + int attr; + + auto ra_def = (ra %= int_); + BOOST_TEST(test_attr("123", ra_def, attr)); + BOOST_TEST(attr == 123); + + auto rb_def = (rb %= ra_def); + BOOST_TEST(test_attr("123", rb_def, attr)); + BOOST_TEST(attr == 123); + + auto rb_def2 = (rb = ra_def); + BOOST_TEST(test_attr("123", rb_def2, attr)); + BOOST_TEST(attr == 123); + } + + { // show that ra %= rb works as expected with semantic actions + rule<class a, int> ra; + rule<class b, int> rb; + int attr; + + auto f = [](auto&){}; + auto ra_def = (ra %= int_[f]); + BOOST_TEST(test_attr("123", ra_def, attr)); + BOOST_TEST(attr == 123); + + auto ra_def2 = (rb = (ra %= int_[f])); + BOOST_TEST(test_attr("123", ra_def2, attr)); + BOOST_TEST(attr == 123); + } + + + { // std::string as container attribute with auto rules + + std::string attr; + + // test deduced auto rule behavior + + auto text = rule<class text, std::string>() + = +(!char_(')') >> !char_('>') >> char_); + + attr.clear(); + BOOST_TEST(test_attr("x", text, attr)); + BOOST_TEST(attr == "x"); + } + + { // error handling + + auto r = rule<my_rule_class, char const*>() + = '(' > int_ > ',' > int_ > ')'; + + BOOST_TEST(test("(123,456)", r)); + BOOST_TEST(!test("(abc,def)", r)); + BOOST_TEST(!test("(123,456]", r)); + BOOST_TEST(!test("(123;456)", r)); + BOOST_TEST(!test("[123,456]", r)); + + BOOST_TEST(got_it == 1); + } + + { + typedef boost::variant<double, int> v_type; + auto r1 = rule<class r1, v_type>() + = int_; + v_type v; + BOOST_TEST(test_attr("1", r1, v) && v.which() == 1 && + boost::get<int>(v) == 1); + + typedef boost::optional<int> ov_type; + auto r2 = rule<class r2, ov_type>() + = int_; + ov_type ov; + BOOST_TEST(test_attr("1", r2, ov) && ov && boost::get<int>(ov) == 1); + } + + // test handling of single element fusion sequences + { + using boost::fusion::vector; + using boost::fusion::at_c; + auto r = rule<class r, vector<int>>() + = int_; + + vector<int> v(0); + BOOST_TEST(test_attr("1", r, v) && at_c<0>(v) == 1); + } + + { // attribute compatibility test + using boost::spirit::x3::rule; + using boost::spirit::x3::int_; + + auto const expr = int_; + + short i; + BOOST_TEST(test_attr("1", expr, i) && i == 1); // ok + + const rule< class int_rule, int > int_rule( "int_rule" ); + auto const int_rule_def = int_; + auto const start = int_rule = int_rule_def; + + short j; + BOOST_TEST(test_attr("1", start, j) && j == 1); // error + } + + return boost::report_errors(); +} diff --git a/src/boost/libs/spirit/test/x3/rule_separate_tu.cpp b/src/boost/libs/spirit/test/x3/rule_separate_tu.cpp new file mode 100644 index 00000000..c3fcb29e --- /dev/null +++ b/src/boost/libs/spirit/test/x3/rule_separate_tu.cpp @@ -0,0 +1,71 @@ +/*============================================================================= + Copyright (c) 2019 Nikita Kniazev + + Use, modification and distribution is subject to the Boost Software + License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at + http://www.boost.org/LICENSE_1_0.txt) +=============================================================================*/ + +#include "rule_separate_tu_grammar.hpp" + +#include <boost/core/lightweight_test.hpp> + +#include "test.hpp" + +namespace sem_act { + +namespace x3 = boost::spirit::x3; + +auto nop = [](auto const&){}; + +x3::rule<class used_attr1_r, int> used_attr1; +auto const used_attr1_def = used_attr::grammar[nop]; +BOOST_SPIRIT_DEFINE(used_attr1); + +x3::rule<class used_attr2_r, int> used_attr2; +auto const used_attr2_def = unused_attr::grammar[nop]; +BOOST_SPIRIT_DEFINE(used_attr2); + +x3::rule<class unused_attr1_r> unused_attr1; +auto const unused_attr1_def = used_attr::grammar[nop]; +BOOST_SPIRIT_DEFINE(unused_attr1); + +x3::rule<class unused_attr2_r> unused_attr2; +auto const unused_attr2_def = unused_attr::grammar[nop]; +BOOST_SPIRIT_DEFINE(unused_attr2); + +} + +int main() +{ + using spirit_test::test; + using spirit_test::test_attr; + + { + BOOST_TEST(test("*", unused_attr::skipper)); + BOOST_TEST(test("#", unused_attr::skipper2)); + BOOST_TEST(test("==", unused_attr::grammar)); + BOOST_TEST(test("*=*=", unused_attr::grammar, unused_attr::skipper)); + BOOST_TEST(test("#=#=", unused_attr::grammar, unused_attr::skipper2)); + } + + { + long i; + static_assert(!std::is_same<decltype(i), used_attr::grammar_type::attribute_type>::value, + "ensure we have instantiated the rule with a different attribute type"); + BOOST_TEST(test_attr("123", used_attr::grammar, i)); + BOOST_TEST_EQ(i, 123); + BOOST_TEST(test_attr(" 42", used_attr::grammar, i, used_attr::skipper)); + BOOST_TEST_EQ(i, 42); + } + + { + long i; + BOOST_TEST(test_attr("123", sem_act::used_attr1, i)); + BOOST_TEST(test_attr("===", sem_act::used_attr2, i)); + BOOST_TEST(test("123", sem_act::unused_attr1)); + BOOST_TEST(test("===", sem_act::unused_attr2)); + } + + return boost::report_errors(); +} diff --git a/src/boost/libs/spirit/test/x3/rule_separate_tu_grammar.cpp b/src/boost/libs/spirit/test/x3/rule_separate_tu_grammar.cpp new file mode 100644 index 00000000..cf29fd75 --- /dev/null +++ b/src/boost/libs/spirit/test/x3/rule_separate_tu_grammar.cpp @@ -0,0 +1,42 @@ +/*============================================================================= + Copyright (c) 2019 Nikita Kniazev + + Use, modification and distribution is subject to the Boost Software + License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at + http://www.boost.org/LICENSE_1_0.txt) +=============================================================================*/ + +#include "rule_separate_tu_grammar.hpp" + +#include <boost/spirit/home/x3.hpp> + +namespace unused_attr { + +const auto skipper_def = x3::lit('*'); +BOOST_SPIRIT_DEFINE(skipper) +BOOST_SPIRIT_INSTANTIATE(skipper_type, char const*, x3::unused_type) + +const auto skipper2_def = x3::lit('#'); +BOOST_SPIRIT_DEFINE(skipper2) +BOOST_SPIRIT_INSTANTIATE(skipper2_type, char const*, x3::unused_type) + +const auto grammar_def = *x3::lit('='); +BOOST_SPIRIT_DEFINE(grammar) +BOOST_SPIRIT_INSTANTIATE(grammar_type, char const*, x3::unused_type) +BOOST_SPIRIT_INSTANTIATE(grammar_type, char const*, x3::phrase_parse_context<skipper_type>::type) +BOOST_SPIRIT_INSTANTIATE(grammar_type, char const*, x3::phrase_parse_context<skipper2_type>::type) + +} + +namespace used_attr { + +const auto skipper_def = x3::space; +BOOST_SPIRIT_DEFINE(skipper) +BOOST_SPIRIT_INSTANTIATE(skipper_type, char const*, x3::unused_type) + +const auto grammar_def = x3::int_; +BOOST_SPIRIT_DEFINE(grammar) +BOOST_SPIRIT_INSTANTIATE(grammar_type, char const*, x3::unused_type) +BOOST_SPIRIT_INSTANTIATE(grammar_type, char const*, x3::phrase_parse_context<skipper_type>::type) + +} diff --git a/src/boost/libs/spirit/test/x3/rule_separate_tu_grammar.hpp b/src/boost/libs/spirit/test/x3/rule_separate_tu_grammar.hpp new file mode 100644 index 00000000..7187a36a --- /dev/null +++ b/src/boost/libs/spirit/test/x3/rule_separate_tu_grammar.hpp @@ -0,0 +1,49 @@ +/*============================================================================= + Copyright (c) 2019 Nikita Kniazev + + Use, modification and distribution is subject to the Boost Software + License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at + http://www.boost.org/LICENSE_1_0.txt) +=============================================================================*/ + +#include <boost/spirit/home/x3.hpp> + +// Check that `BOOST_SPIRIT_INSTANTIATE` instantiates `parse_rule` with proper +// types when a rule has no attribute. + +namespace unused_attr { + +namespace x3 = boost::spirit::x3; + +// skipper must has no attribute, checks `parse` and `skip_over` +using skipper_type = x3::rule<class skipper_r>; +const skipper_type skipper; +BOOST_SPIRIT_DECLARE(skipper_type) + +// the `unused_type const` must have the same effect as no attribute +using skipper2_type = x3::rule<class skipper2_r, x3::unused_type const>; +const skipper2_type skipper2; +BOOST_SPIRIT_DECLARE(skipper2_type) + +// grammar must has no attribute, checks `parse` and `phrase_parse` +using grammar_type = x3::rule<class grammar_r>; +const grammar_type grammar; +BOOST_SPIRIT_DECLARE(grammar_type) + +} + +// Check instantiation when rule has an attribute. + +namespace used_attr { + +namespace x3 = boost::spirit::x3; + +using skipper_type = x3::rule<class skipper_r>; +const skipper_type skipper; +BOOST_SPIRIT_DECLARE(skipper_type) + +using grammar_type = x3::rule<class grammar_r, int>; +const grammar_type grammar; +BOOST_SPIRIT_DECLARE(grammar_type) + +} diff --git a/src/boost/libs/spirit/test/x3/seek.cpp b/src/boost/libs/spirit/test/x3/seek.cpp new file mode 100644 index 00000000..2986a55e --- /dev/null +++ b/src/boost/libs/spirit/test/x3/seek.cpp @@ -0,0 +1,95 @@ +/*////////////////////////////////////////////////////////////////////////////// + Copyright (c) 2011 Jamboree + Copyright (c) 2014 Lee Clagett + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +//////////////////////////////////////////////////////////////////////////////*/ +#include <vector> + +#include <boost/detail/lightweight_test.hpp> +#include <boost/spirit/home/x3/auxiliary/eoi.hpp> +#include <boost/spirit/home/x3/core.hpp> +#include <boost/spirit/home/x3/char.hpp> +#include <boost/spirit/home/x3/string.hpp> +#include <boost/spirit/home/x3/numeric.hpp> +#include <boost/spirit/home/x3/operator/plus.hpp> +#include <boost/spirit/home/x3/operator/sequence.hpp> + +#include <boost/spirit/home/x3/directive/seek.hpp> + +#include "test.hpp" + + +/////////////////////////////////////////////////////////////////////////////// +int main() +{ + using namespace spirit_test; + namespace x3 = boost::spirit::x3; + + // test eoi + { + BOOST_TEST(test("", x3::seek[x3::eoi])); + BOOST_TEST(test(" ", x3::seek[x3::eoi], x3::space)); + BOOST_TEST(test("a", x3::seek[x3::eoi])); + BOOST_TEST(test(" a", x3::seek[x3::eoi], x3::space)); + } + + // test literal finding + { + int i = 0; + + BOOST_TEST( + test_attr("!@#$%^&*KEY:123", x3::seek["KEY:"] >> x3::int_, i) + && i == 123 + ); + } + // test sequence finding + { + int i = 0; + + BOOST_TEST( + test_attr("!@#$%^&* KEY : 123", x3::seek[x3::lit("KEY") >> ':'] >> x3::int_, i, x3::space) + && i == 123 + ); + } + + // test attr finding + { + std::vector<int> v; + + BOOST_TEST( // expect partial match + test_attr("a06b78c3d", +x3::seek[x3::int_], v, false) + && v.size() == 3 && v[0] == 6 && v[1] == 78 && v[2] == 3 + ); + } + + // test action + { + + bool b = false; + auto const action = [&b]() { b = true; }; + + BOOST_TEST( // expect partial match + test("abcdefg", x3::seek["def"][action], false) + && b + ); + } + + // test container + { + std::vector<int> v; + + BOOST_TEST( + test_attr("abcInt:100Int:95Int:44", x3::seek[+("Int:" >> x3::int_)], v) + && v.size() == 3 && v[0] == 100 && v[1] == 95 && v[2] == 44 + ); + } + + // test failure rollback + { + BOOST_TEST(test_failure("abcdefg", x3::seek[x3::int_])); + } + + return boost::report_errors(); +} diff --git a/src/boost/libs/spirit/test/x3/sequence.cpp b/src/boost/libs/spirit/test/x3/sequence.cpp new file mode 100644 index 00000000..f6559078 --- /dev/null +++ b/src/boost/libs/spirit/test/x3/sequence.cpp @@ -0,0 +1,503 @@ +/*============================================================================= + Copyright (c) 2001-2015 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +=============================================================================*/ +#include <boost/detail/lightweight_test.hpp> +#include <boost/spirit/home/x3.hpp> +#include <boost/fusion/include/vector.hpp> +#include <boost/fusion/include/deque.hpp> +#include <boost/fusion/include/at.hpp> +#include <boost/fusion/include/comparison.hpp> + +#include <string> +#include <iostream> +#include "test.hpp" +#include "utils.hpp" + +int +main() +{ + using boost::spirit::x3::unused_type; + + using boost::spirit::x3::char_; + using boost::spirit::x3::space; + using boost::spirit::x3::string; + using boost::spirit::x3::attr; + using boost::spirit::x3::omit; + using boost::spirit::x3::lit; + using boost::spirit::x3::unused; + using boost::spirit::x3::int_; + using boost::spirit::x3::float_; + using boost::spirit::x3::no_case; + using boost::spirit::x3::rule; + using boost::spirit::x3::alnum; + + using boost::spirit::x3::traits::attribute_of; + + using boost::fusion::vector; + using boost::fusion::deque; + using boost::fusion::at_c; + + using spirit_test::test; + using spirit_test::test_attr; + + { + BOOST_TEST((test("aa", char_ >> char_))); + BOOST_TEST((test("aa", char_ >> 'a'))); + BOOST_TEST((test("aaa", char_ >> char_ >> char_('a')))); + BOOST_TEST((test("xi", char_('x') >> char_('i')))); + BOOST_TEST((!test("xi", char_('x') >> char_('o')))); + BOOST_TEST((test("xin", char_('x') >> char_('i') >> char_('n')))); + } + +#ifdef BOOST_SPIRIT_COMPILE_ERROR_CHECK + { + // Compile check only + struct x {}; + char_ >> x(); // this should give a reasonable error message + } +#endif + + { + BOOST_TEST((test(" a a", char_ >> char_, space))); + BOOST_TEST((test(" x i", char_('x') >> char_('i'), space))); + BOOST_TEST((!test(" x i", char_('x') >> char_('o'), space))); + } + + + { + BOOST_TEST((test(" Hello, World", lit("Hello") >> ',' >> "World", space))); + } + + + { + vector<char, char> attr; + BOOST_TEST((test_attr("ab", char_ >> char_, attr))); + BOOST_TEST((at_c<0>(attr) == 'a')); + BOOST_TEST((at_c<1>(attr) == 'b')); + } + +#ifdef BOOST_SPIRIT_COMPILE_ERROR_CHECK + { + // Compile check only + vector<char, char> attr; + + // error: attr does not have enough elements + test_attr("abc", char_ >> char_ >> char_, attr); + } +#endif + + { + vector<char, char, char> attr; + BOOST_TEST((test_attr(" a\n b\n c", char_ >> char_ >> char_, attr, space))); + BOOST_TEST((at_c<0>(attr) == 'a')); + BOOST_TEST((at_c<1>(attr) == 'b')); + BOOST_TEST((at_c<2>(attr) == 'c')); + } + + { + // 'b' has an unused_type. unused attributes are not part of the sequence + vector<char, char> attr; + BOOST_TEST((test_attr("abc", char_ >> 'b' >> char_, attr))); + BOOST_TEST((at_c<0>(attr) == 'a')); + BOOST_TEST((at_c<1>(attr) == 'c')); + } + + { + // 'b' has an unused_type. unused attributes are not part of the sequence + vector<char, char> attr; + BOOST_TEST((test_attr("acb", char_ >> char_ >> 'b', attr))); + BOOST_TEST((at_c<0>(attr) == 'a')); + BOOST_TEST((at_c<1>(attr) == 'c')); + } + + { + // "hello" has an unused_type. unused attributes are not part of the sequence + vector<char, char> attr; + BOOST_TEST((test_attr("a hello c", char_ >> "hello" >> char_, attr, space))); + BOOST_TEST((at_c<0>(attr) == 'a')); + BOOST_TEST((at_c<1>(attr) == 'c')); + } + + { + // a single element + char attr; + BOOST_TEST((test_attr("ab", char_ >> 'b', attr))); + BOOST_TEST((attr == 'a')); + } + + { + // a single element fusion sequence + vector<char> attr; + BOOST_TEST((test_attr("ab", char_ >> 'b', attr))); + BOOST_TEST((at_c<0>(attr) == 'a')); + } + + { + // make sure single element tuples get passed through if the rhs + // has a single element tuple as its attribute. Edit JDG 2014: + // actually he issue here is that if the rhs in this case a rule + // (r), it should get it (i.e. the sequence parser should not + // unwrap it). It's odd that the RHS (r) does not really have a + // single element tuple (it's a deque<char, int>), so the original + // comment is not accurate. + + typedef deque<char, int> attr_type; + attr_type fv; + + auto r = rule<class r, attr_type>() + = char_ >> ',' >> int_; + + BOOST_TEST((test_attr("test:x,1", "test:" >> r, fv) && + fv == attr_type('x', 1))); + } + + { + // make sure single element tuples get passed through if the rhs + // has a single element tuple as its attribute. This is a correction + // of the test above. + + typedef deque<int> attr_type; + attr_type fv; + + auto r = rule<class r, attr_type>() + = int_; + + BOOST_TEST((test_attr("test:1", "test:" >> r, fv) && + fv == attr_type(1))); + } + + { + // unused means we don't care about the attribute + BOOST_TEST((test_attr("abc", char_ >> 'b' >> char_, unused))); + } + + { + BOOST_TEST((test("aA", no_case[char_('a') >> 'a']))); + BOOST_TEST((test("BEGIN END", no_case[lit("begin") >> "end"], space))); + BOOST_TEST((!test("BEGIN END", no_case[lit("begin") >> "nend"], space))); + } + + { // check attribute is passed through unary to another sequence + using boost::spirit::x3::eps; + std::string s; + BOOST_TEST(test_attr("ab", eps >> no_case[char_ >> char_], s)); + BOOST_TEST("ab" == s); + s.clear(); + BOOST_TEST(test_attr("ab", no_case[char_ >> char_] >> eps, s)); + BOOST_TEST("ab" == s); + s.clear(); + BOOST_TEST(test_attr("abc", char_ >> no_case[char_ >> char_], s)); + BOOST_TEST("abc" == s); + s.clear(); + BOOST_TEST(test_attr("abc", no_case[char_ >> char_] >> char_, s)); + BOOST_TEST("abc" == s); + } + + { +#ifdef SPIRIT_NO_COMPILE_CHECK + char_ >> char_ = char_ >> char_; // disallow this! +#endif + } + + { // alternative forms of attributes. Allow sequences to take in + // stl containers. + + std::vector<char> v; + BOOST_TEST(test_attr("abc", char_ >> char_ >> char_, v)); + BOOST_TEST(v.size() == 3); + BOOST_TEST(v[0] == 'a'); + BOOST_TEST(v[1] == 'b'); + BOOST_TEST(v[2] == 'c'); + } + + { // alternative forms of attributes. Allow sequences to take in + // stl containers. + + std::vector<char> v; + BOOST_TEST(test_attr("a,b,c", char_ >> *(',' >> char_), v)); + BOOST_TEST(v.size() == 3); + BOOST_TEST(v[0] == 'a'); + BOOST_TEST(v[1] == 'b'); + BOOST_TEST(v[2] == 'c'); + } + + { // alternative forms of attributes. Allow sequences to take in + // stl containers. + + std::vector<char> v; + BOOST_TEST(test_attr("abc", char_ >> *char_, v)); + BOOST_TEST(v.size() == 3); + BOOST_TEST(v[0] == 'a'); + BOOST_TEST(v[1] == 'b'); + BOOST_TEST(v[2] == 'c'); + } + + { // alternative forms of attributes. Allow sequences to take in + // stl containers. + //~ using boost::spirit::x3::hold; + + std::vector<char> v; + BOOST_TEST(test_attr("abc", char_ >> *(char_ >> char_), v)); + BOOST_TEST(v.size() == 3); + BOOST_TEST(v[0] == 'a'); + BOOST_TEST(v[1] == 'b'); + BOOST_TEST(v[2] == 'c'); + + v.clear(); + BOOST_TEST(!test_attr("abcd", char_ >> *(char_ >> char_), v)); + + // $$$ hold not yet implementd $$$ + //~ v.clear(); + //~ BOOST_TEST(test_attr("abcdef", char_ >> *hold[char_ >> char_] >> char_, v)); + //~ BOOST_TEST(v.size() == 6); + //~ BOOST_TEST(v[0] == 'a'); + //~ BOOST_TEST(v[1] == 'b'); + //~ BOOST_TEST(v[2] == 'c'); + //~ BOOST_TEST(v[3] == 'd'); + //~ BOOST_TEST(v[4] == 'e'); + //~ BOOST_TEST(v[5] == 'f'); + + v.clear(); + BOOST_TEST(test_attr("abc", char_ >> +(char_ >> char_), v)); + BOOST_TEST(v.size() == 3); + BOOST_TEST(v[0] == 'a'); + BOOST_TEST(v[1] == 'b'); + BOOST_TEST(v[2] == 'c'); + } + + { // alternative forms of attributes. Allow sequences to take in + // stl containers. + + std::vector<char> v; + BOOST_TEST(test_attr("abc", char_ >> -(+char_), v)); + BOOST_TEST(v.size() == 3); + BOOST_TEST(v[0] == 'a'); + BOOST_TEST(v[1] == 'b'); + BOOST_TEST(v[2] == 'c'); + } + + { // alternative forms of attributes. Allow sequences to take in + // stl containers. + + std::string s; + BOOST_TEST(test_attr("foobar", string("foo") >> string("bar"), s)); + BOOST_TEST(s == "foobar"); + + s.clear(); + + // $$$ hold not yet implemented $$$ + //~ using boost::spirit::x3::hold; + + //~ rule<char const*, std::string()> word = +char_("abc"); + //~ BOOST_TEST(test_attr("ab.bc.ca", *hold[word >> string(".")] >> word, s)); + //~ BOOST_TEST(s == "ab.bc.ca"); + } + + // Make sure get_sequence_types works for sequences of sequences. + { + std::vector<char> v; + BOOST_TEST(test_attr(" a b", (' ' >> char_) >> (' ' >> char_), v)); + BOOST_TEST(v.size() == 2); + BOOST_TEST(v[0] == 'a'); + BOOST_TEST(v[1] == 'b'); + } + + // alternative forms of attributes. Allow sequences to take in + // stl containers of stl containers. + { + std::vector<std::string> v; + BOOST_TEST(test_attr("abc1,abc2", + *~char_(',') >> *(',' >> *~char_(',')), v)); + BOOST_TEST(v.size() == 2 && v[0] == "abc1" && v[1] == "abc2"); + } + + { + std::vector<std::string> v; + + auto e = rule<class e, std::string>() + = *~char_(','); + + auto l = rule<class l, std::vector<std::string>>() + = e >> *(',' >> e); + + BOOST_TEST(test_attr("abc1,abc2,abc3", l, v)); + BOOST_TEST(v.size() == 3); + BOOST_TEST(v[0] == "abc1"); + BOOST_TEST(v[1] == "abc2"); + BOOST_TEST(v[2] == "abc3"); + } + + // do the same with a plain string object + { + std::string s; + BOOST_TEST(test_attr("abc1,abc2", + *~char_(',') >> *(',' >> *~char_(',')), s)); + BOOST_TEST(s == "abc1abc2"); + } + + { + std::string s; + auto e = rule<class e, std::string>() + = *~char_(','); + + auto l = rule<class l, std::string>() + = e >> *(',' >> e); + + BOOST_TEST(test_attr("abc1,abc2,abc3", l, s)); + BOOST_TEST(s == "abc1abc2abc3"); + } + + { + std::vector<char> v; + BOOST_TEST(test_attr("ab", char_ >> -char_, v)); + BOOST_TEST(v.size() == 2 && v[0] == 'a' && v[1] == 'b'); + + v.clear(); + BOOST_TEST(test_attr("a", char_ >> -char_, v)); + BOOST_TEST(v.size() == 1 && v[0] == 'a'); + + // $$$ should this be allowed? I don't think so... $$$ + //~ v.clear(); + //~ BOOST_TEST(test_attr("a", char_, v)); + //~ BOOST_TEST(v.size() == 1 && v[0] == 'a'); + } + + { + std::vector<boost::optional<char>> v; + BOOST_TEST(test_attr("ab", char_ >> -char_, v)); + BOOST_TEST(v.size() == 2 && v[0] == 'a' && v[1] == 'b'); + + v.clear(); + BOOST_TEST(test_attr("a", char_ >> -char_, v)); + BOOST_TEST(v.size() == 2 && v[0] == 'a' && !v[1]); + + // $$$ should this be allowed? I don't think so... $$$ + //~ v.clear(); + //~ BOOST_TEST(test_attr("a", char_, v)); + //~ BOOST_TEST(v.size() == 1 && v[0] == 'a'); + } + + // test from spirit mailing list + // "Optional operator causes string attribute concatenation" + { + typedef vector<char, char, int> attr_type; + attr_type attr; + + auto node = alnum >> -('[' >> alnum >> '=' >> int_ >> ']'); + + BOOST_TEST(test_attr("x[y=123]", node, attr)); + BOOST_TEST(attr == attr_type('x', 'y', 123)); + } + + // test from spirit mailing list (variation of above) + // "Optional operator causes string attribute concatenation" + { + typedef vector<std::string, std::string, int> attr_type; + attr_type attr; + + auto node = +alnum >> -('[' >> +alnum >> '=' >> int_ >> ']'); + + BOOST_TEST(test_attr("xxx[yyy=123]", node, attr)); + BOOST_TEST(attr == attr_type("xxx", "yyy", 123)); + } + + // test from spirit mailing list + // "Error with container within sequence" + { + typedef vector<std::string> attr_type; + attr_type attr; + + auto r = *alnum; + + BOOST_TEST(test_attr("abcdef", r, attr)); + BOOST_TEST(at_c<0>(attr) == "abcdef"); + } + + // test from spirit mailing list (variation of above) + // "Error with container within sequence" + { + typedef vector<std::vector<int>> attr_type; + attr_type attr; + + auto r = *int_; + + BOOST_TEST(test_attr("123 456", r, attr, space)); + BOOST_TEST(at_c<0>(attr).size() == 2); + BOOST_TEST(at_c<0>(attr)[0] == 123); + BOOST_TEST(at_c<0>(attr)[1] == 456); + } + + { + using Attr = boost::variant<int, float>; + Attr attr; + auto const term = rule<class term, Attr>("term") = int_ | float_; + auto const expr = rule<class expr, Attr>("expr") = term | ('(' > term > ')'); + BOOST_TEST((test_attr("(1)", expr, attr, space))); + } + + // test that failing sequence leaves attribute consistent + { + std::string attr; + //no need to use omit[], but lit() is buggy ATM + BOOST_TEST(test_attr("A\nB\nC", *(char_ >> omit[lit("\n")]), attr, false)); + BOOST_TEST(attr == "AB"); + } + + // test that sequence with only one parser producing attribute + // makes it unwrapped + { + BOOST_TEST((boost::is_same< + typename attribute_of<decltype(lit("abc") >> attr(long())), unused_type>::type, + long>() )); + } + + { // test action + using boost::fusion::at_c; + + char c = 0; + int n = 0; + auto f = [&](auto& ctx) + { + c = at_c<0>(_attr(ctx)); + n = at_c<1>(_attr(ctx)); + }; + + BOOST_TEST(test("x123\"a string\"", (char_ >> int_ >> "\"a string\"")[f])); + BOOST_TEST(c == 'x'); + BOOST_TEST(n == 123); + } + + { // test action + char c = 0; + int n = 0; + auto f = [&](auto& ctx) + { + c = at_c<0>(_attr(ctx)); + n = at_c<1>(_attr(ctx)); + }; + + BOOST_TEST(test("x 123 \"a string\"", (char_ >> int_ >> "\"a string\"")[f], space)); + BOOST_TEST(c == 'x'); + BOOST_TEST(n == 123); + } + + { +#ifdef SPIRIT_NO_COMPILE_CHECK + char const* const s = ""; + int i; + parse(s, s, int_ >> int_, i); +#endif + } + + { // test move only types + using boost::spirit::x3::eps; + std::vector<move_only> v; + BOOST_TEST(test_attr("ssszs", *synth_move_only >> 'z' >> synth_move_only, v)); + BOOST_TEST_EQ(v.size(), 4); + } + + return boost::report_errors(); +} diff --git a/src/boost/libs/spirit/test/x3/skip.cpp b/src/boost/libs/spirit/test/x3/skip.cpp new file mode 100644 index 00000000..3a201408 --- /dev/null +++ b/src/boost/libs/spirit/test/x3/skip.cpp @@ -0,0 +1,48 @@ +/*============================================================================= + Copyright (c) 2001-2015 Joel de Guzman + Copyright (c) 2013 Agustin Berge + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +=============================================================================*/ +#include <boost/detail/lightweight_test.hpp> +#include <boost/spirit/home/x3.hpp> + +#include <iostream> +#include "test.hpp" + +int +main() +{ + using spirit_test::test; + using spirit_test::test_attr; + using boost::spirit::x3::ascii::space; + using boost::spirit::x3::ascii::space_type; + using boost::spirit::x3::ascii::char_; + using boost::spirit::x3::ascii::alpha; + using boost::spirit::x3::lexeme; + using boost::spirit::x3::skip; + using boost::spirit::x3::lit; + + { + BOOST_TEST((test("a b c d", skip(space)[*char_]))); + } + + { // test attribute + std::string s; + BOOST_TEST((test_attr("a b c d", skip(space)[*char_], s))); + BOOST_TEST(s == "abcd"); + } + + { // reskip + BOOST_TEST((test("ab c d", lexeme[lit('a') >> 'b' >> skip[lit('c') >> 'd']], space))); + BOOST_TEST((test("abcd", lexeme[lit('a') >> 'b' >> skip[lit('c') >> 'd']], space))); + BOOST_TEST(!(test("a bcd", lexeme[lit('a') >> 'b' >> skip[lit('c') >> 'd']], space))); + + BOOST_TEST((test("ab c d", lexeme[lexeme[lit('a') >> 'b' >> skip[lit('c') >> 'd']]], space))); + BOOST_TEST((test("abcd", lexeme[lexeme[lit('a') >> 'b' >> skip[lit('c') >> 'd']]], space))); + BOOST_TEST(!(test("a bcd", lexeme[lexeme[lit('a') >> 'b' >> skip[lit('c') >> 'd']]], space))); + } + + return boost::report_errors(); +} diff --git a/src/boost/libs/spirit/test/x3/symbols1.cpp b/src/boost/libs/spirit/test/x3/symbols1.cpp new file mode 100644 index 00000000..38771e45 --- /dev/null +++ b/src/boost/libs/spirit/test/x3/symbols1.cpp @@ -0,0 +1,187 @@ +/*============================================================================= + Copyright (c) 2001-2015 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +=============================================================================*/ +#include <boost/detail/lightweight_test.hpp> +#include <boost/spirit/home/x3.hpp> + +#include <iostream> +#include "test.hpp" + +// Custom string type with a C-style string conversion. +struct custom_string_c +{ + custom_string_c(char c) { str[0] = c; str[1] = '\0'; } + + operator char*() { return str; } + operator char const*() const { return str; } + +private: + char str[2]; +}; + +int +main() +{ + using spirit_test::test; + using spirit_test::test_attr; + using boost::spirit::x3::symbols; + using boost::spirit::x3::no_case; + + { // basics + symbols<int> sym; + + sym.add + ("Joel") + ("Ruby") + ("Tenji") + ("Tutit") + ("Kim") + ("Joey") + ("Joeyboy") + ; + + BOOST_TEST((test("Joel", sym))); + BOOST_TEST((test("Ruby", sym))); + BOOST_TEST((test("Tenji", sym))); + BOOST_TEST((test("Tutit", sym))); + BOOST_TEST((test("Kim", sym))); + BOOST_TEST((test("Joey", sym))); + BOOST_TEST((test("Joeyboy", sym))); + BOOST_TEST((!test("XXX", sym))); + + // test copy + symbols<int> sym2; + sym2 = sym; + BOOST_TEST((test("Joel", sym2))); + BOOST_TEST((test("Ruby", sym2))); + BOOST_TEST((test("Tenji", sym2))); + BOOST_TEST((test("Tutit", sym2))); + BOOST_TEST((test("Kim", sym2))); + BOOST_TEST((test("Joey", sym2))); + BOOST_TEST((!test("XXX", sym2))); + + // make sure it plays well with other parsers + BOOST_TEST((test("Joelyo", sym >> "yo"))); + + sym.remove + ("Joel") + ("Ruby") + ; + + BOOST_TEST((!test("Joel", sym))); + BOOST_TEST((!test("Ruby", sym))); + } + + { // comma syntax + symbols<int> sym; + sym += "Joel", "Ruby", "Tenji", "Tutit", "Kim", "Joey"; + + BOOST_TEST((test("Joel", sym))); + BOOST_TEST((test("Ruby", sym))); + BOOST_TEST((test("Tenji", sym))); + BOOST_TEST((test("Tutit", sym))); + BOOST_TEST((test("Kim", sym))); + BOOST_TEST((test("Joey", sym))); + BOOST_TEST((!test("XXX", sym))); + + sym -= "Joel", "Ruby"; + + BOOST_TEST((!test("Joel", sym))); + BOOST_TEST((!test("Ruby", sym))); + } + + { // no-case handling + using namespace boost::spirit::x3::ascii; + + symbols<int> sym; + // NOTE: make sure all entries are in lower-case!!! + sym = "joel", "ruby", "tenji", "tutit", "kim", "joey"; + + BOOST_TEST((test("joel", no_case[sym]))); + BOOST_TEST((test("ruby", no_case[sym]))); + BOOST_TEST((test("tenji", no_case[sym]))); + BOOST_TEST((test("tutit", no_case[sym]))); + BOOST_TEST((test("kim", no_case[sym]))); + BOOST_TEST((test("joey", no_case[sym]))); + + BOOST_TEST((test("JOEL", no_case[sym]))); + BOOST_TEST((test("RUBY", no_case[sym]))); + BOOST_TEST((test("TENJI", no_case[sym]))); + BOOST_TEST((test("TUTIT", no_case[sym]))); + BOOST_TEST((test("KIM", no_case[sym]))); + BOOST_TEST((test("JOEY", no_case[sym]))); + + // make sure it plays well with other parsers + BOOST_TEST((test("Joelyo", no_case[sym] >> "yo"))); + } + + { // attributes + symbols<int> sym; + + sym.add + ("Joel", 1) + ("Ruby", 2) + ("Tenji", 3) + ("Tutit", 4) + ("Kim", 5) + ("Joey", 6) + ; + + int i; + BOOST_TEST((test_attr("Joel", sym, i))); + BOOST_TEST(i == 1); + BOOST_TEST((test_attr("Ruby", sym, i))); + BOOST_TEST(i == 2); + BOOST_TEST((test_attr("Tenji", sym, i))); + BOOST_TEST(i == 3); + BOOST_TEST((test_attr("Tutit", sym, i))); + BOOST_TEST(i == 4); + BOOST_TEST((test_attr("Kim", sym, i))); + BOOST_TEST(i == 5); + BOOST_TEST((test_attr("Joey", sym, i))); + BOOST_TEST(i == 6); + BOOST_TEST((!test_attr("XXX", sym, i))); + + // double add: + + sym.add("Joel", 265); + BOOST_TEST((test_attr("Joel", sym, i))); + BOOST_TEST(i == 1); + } + + { // actions + using boost::spirit::x3::_attr; + + symbols<int> sym; + sym.add + ("Joel", 1) + ("Ruby", 2) + ("Tenji", 3) + ("Tutit", 4) + ("Kim", 5) + ("Joey", 6) + ; + + int i; + auto f = [&](auto& ctx){ i = _attr(ctx); }; + + BOOST_TEST((test("Joel", sym[f]))); + BOOST_TEST(i == 1); + BOOST_TEST((test("Ruby", sym[f]))); + BOOST_TEST(i == 2); + BOOST_TEST((test("Tenji", sym[f]))); + BOOST_TEST(i == 3); + BOOST_TEST((test("Tutit", sym[f]))); + BOOST_TEST(i == 4); + BOOST_TEST((test("Kim", sym[f]))); + BOOST_TEST(i == 5); + BOOST_TEST((test("Joey", sym[f]))); + BOOST_TEST(i == 6); + BOOST_TEST((!test("XXX", sym[f]))); + } + + return boost::report_errors(); +} diff --git a/src/boost/libs/spirit/test/x3/symbols2.cpp b/src/boost/libs/spirit/test/x3/symbols2.cpp new file mode 100644 index 00000000..f401dc14 --- /dev/null +++ b/src/boost/libs/spirit/test/x3/symbols2.cpp @@ -0,0 +1,202 @@ +/*============================================================================= + Copyright (c) 2001-2015 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +=============================================================================*/ +#include <boost/detail/lightweight_test.hpp> +#include <boost/spirit/home/x3.hpp> + +#include <iostream> +#include "test.hpp" + +// Custom string type with a C-style string conversion. +struct custom_string_c +{ + custom_string_c(char c) { str[0] = c; str[1] = '\0'; } + + operator char*() { return str; } + operator char const*() const { return str; } + +private: + char str[2]; +}; + +std::string get_str(char const* str) +{ + return std::string(str); +} + +int +main() +{ + using spirit_test::test; + using spirit_test::test_attr; + using boost::spirit::x3::symbols; + using boost::spirit::x3::rule; + + { // construction from symbol array + char const* syms[] = {"Joel","Ruby","Tenji","Tutit","Kim","Joey"}; + symbols<int> sym(syms); + + BOOST_TEST((test("Joel", sym))); + BOOST_TEST((test("Ruby", sym))); + BOOST_TEST((test("Tenji", sym))); + BOOST_TEST((test("Tutit", sym))); + BOOST_TEST((test("Kim", sym))); + BOOST_TEST((test("Joey", sym))); + BOOST_TEST((!test("XXX", sym))); + } + + { // construction from 2 arrays + + char const* syms[] = {"Joel","Ruby","Tenji","Tutit","Kim","Joey"}; + int data[] = {1,2,3,4,5,6}; + symbols<int> sym(syms, data); + + int i; + BOOST_TEST((test_attr("Joel", sym, i))); + BOOST_TEST(i == 1); + BOOST_TEST((test_attr("Ruby", sym, i))); + BOOST_TEST(i == 2); + BOOST_TEST((test_attr("Tenji", sym, i))); + BOOST_TEST(i == 3); + BOOST_TEST((test_attr("Tutit", sym, i))); + BOOST_TEST(i == 4); + BOOST_TEST((test_attr("Kim", sym, i))); + BOOST_TEST(i == 5); + BOOST_TEST((test_attr("Joey", sym, i))); + BOOST_TEST(i == 6); + BOOST_TEST((!test_attr("XXX", sym, i))); + } + + { // allow std::string and other string types + symbols<> sym; + + // const and non-const std::string + std::string a("abc"); + std::string const b("def"); + sym += a; + sym += b; + BOOST_TEST((test("abc", sym))); + BOOST_TEST((test("def", sym))); + sym = a; + BOOST_TEST((test("abc", sym))); + BOOST_TEST((!test("def", sym))); + + // non-const C-style string + char arr[2]; arr[0] = 'a'; arr[1] = '\0'; + sym = arr; + BOOST_TEST((test("a", sym))); + BOOST_TEST((!test("b", sym))); + + // const and non-const custom string type + custom_string_c c('x'); + custom_string_c const cc('y'); + sym = c, cc; + BOOST_TEST((test("x", sym))); + BOOST_TEST((test("y", sym))); + BOOST_TEST((!test("z", sym))); + } + + { // find + + symbols<int> sym; + sym.add("a", 1)("b", 2); + + BOOST_TEST(!sym.find("c")); + + BOOST_TEST(sym.find("a") && *sym.find("a") == 1); + BOOST_TEST(sym.find("b") && *sym.find("b") == 2); + + BOOST_TEST(sym.at("a") == 1); + BOOST_TEST(sym.at("b") == 2); + BOOST_TEST(sym.at("c") == 0); + + BOOST_TEST(sym.find("a") && *sym.find("a") == 1); + BOOST_TEST(sym.find("b") && *sym.find("b") == 2); + BOOST_TEST(sym.find("c") && *sym.find("c") == 0); + + symbols<int> const_sym(sym); + + BOOST_TEST(const_sym.find("a") && *const_sym.find("a") == 1); + BOOST_TEST(const_sym.find("b") && *const_sym.find("b") == 2); + BOOST_TEST(const_sym.find("c") && *const_sym.find("c") == 0); + BOOST_TEST(!const_sym.find("d")); + + char const *str1 = "all"; + char const *first = str1, *last = str1 + 3; + BOOST_TEST(*sym.prefix_find(first, last) == 1 && first == str1 + 1); + + char const *str2 = "dart"; + first = str2; last = str2 + 4; + BOOST_TEST(!sym.prefix_find(first, last) && first == str2); + } + + { // name + symbols <int> sym,sym2; + sym.name("test"); + BOOST_TEST(sym.name()=="test"); + sym2 = sym; + BOOST_TEST(sym2.name()=="test"); + + symbols <int> sym3(sym); + BOOST_TEST(sym3.name()=="test"); + } + + { // Substrings + + symbols<int> sym; + BOOST_TEST(sym.at("foo") == 0); + sym.at("foo") = 1; + BOOST_TEST(sym.at("foo") == 1); + BOOST_TEST(sym.at("fool") == 0); + sym.at("fool") = 2; + BOOST_TEST(sym.find("foo") && *sym.find("foo") == 1); + BOOST_TEST(sym.find("fool") && *sym.find("fool") == 2); + BOOST_TEST(!sym.find("foolish")); + BOOST_TEST(!sym.find("foot")); + BOOST_TEST(!sym.find("afoot")); + + char const *str, *first, *last; + str = "foolish"; first = str; last = str + 7; + BOOST_TEST(*sym.prefix_find(first, last) == 2 && first == str + 4); + + first = str; last = str + 4; + BOOST_TEST(*sym.prefix_find(first, last) == 2 && first == str + 4); + + str = "food"; first = str; last = str + 4; + BOOST_TEST(*sym.prefix_find(first, last) == 1 && first == str + 3); + + first = str; last = str + 3; + BOOST_TEST(*sym.prefix_find(first, last) == 1 && first == str + 3); + + first = str; last = str + 2; + BOOST_TEST(!sym.prefix_find(first, last) && first == str); + } + + { + // remove bug + + std::string s; + symbols<double> vars; + + vars.add("l1", 12.0); + vars.add("l2", 0.0); + vars.remove("l2"); + vars.find("l1"); + double* d = vars.find("l1"); + BOOST_TEST(d != 0); + } + + { // test for proto problem with rvalue references (10-11-2011) + symbols<int> sym; + sym += get_str("Joel"); + sym += get_str("Ruby"); + + BOOST_TEST((test("Joel", sym))); + BOOST_TEST((test("Ruby", sym))); + } + + return boost::report_errors(); +} diff --git a/src/boost/libs/spirit/test/x3/symbols3.cpp b/src/boost/libs/spirit/test/x3/symbols3.cpp new file mode 100644 index 00000000..d732ca3d --- /dev/null +++ b/src/boost/libs/spirit/test/x3/symbols3.cpp @@ -0,0 +1,86 @@ +/*============================================================================= + Copyright (c) 2013 Carl Barron + Copyright (c) 2015 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +=============================================================================*/ + +#include <boost/detail/lightweight_test.hpp> +#include <boost/spirit/home/x3.hpp> +#include <boost/fusion/include/at.hpp> +#include <boost/fusion/include/vector.hpp> +#include <boost/fusion/include/adapt_struct.hpp> +#include <boost/mpl/int.hpp> +#include <boost/optional.hpp> + +#include <iostream> +#include <numeric> +#include <vector> +#include "test.hpp" + +struct roman +{ + boost::optional<int> a; + boost::optional<int> b; + boost::optional<int> c; +}; + +BOOST_FUSION_ADAPT_STRUCT(roman, + a, b, c +) + +int eval(roman const & c) +{ + return c.a.get_value_or(0) + c.b.get_value_or(0) + c.c.get_value_or(0); +} + +int +main() +{ + using spirit_test::test; + using spirit_test::test_attr; + using boost::spirit::x3::symbols; + + { // construction from initializer-list + symbols<int> const ones = + { + {"I", 1}, {"II", 2}, {"III", 3}, {"IV", 4}, + {"V", 5}, {"VI", 6}, {"VII", 7}, {"VIII", 8}, + {"IX", 9} + }; + symbols<int> const tens = + { + {"X", 10}, {"XX", 20}, {"XXX", 30}, {"XL", 40}, + {"L", 50}, {"LX", 60}, {"LXX", 70}, {"LXXX", 80}, + {"XC", 90} + }; + symbols<int> const hundreds + { + {"C", 100}, {"CC", 200}, {"CCC", 300}, {"CD", 400}, + {"D", 500}, {"DC", 600}, {"DCC", 700}, {"DCCC", 800}, + {"CM", 900} + }; + + auto number = -hundreds >> -tens >> -ones; + + roman r; + BOOST_TEST((test_attr("CDXLII", number, r))); + BOOST_TEST(eval(r) == 442); + } + + { // construction from initializer-list without attribute + symbols<> foo = {"a1", "a2", "a3"}; + + BOOST_TEST((test("a3", foo))); + } + + { // assignment from initializer-list + symbols<> foo; + foo = {"a1", "a2", "a3"}; + + BOOST_TEST((test("a3", foo))); + } + + return boost::report_errors(); +} diff --git a/src/boost/libs/spirit/test/x3/test.hpp b/src/boost/libs/spirit/test/x3/test.hpp new file mode 100644 index 00000000..af1c22ee --- /dev/null +++ b/src/boost/libs/spirit/test/x3/test.hpp @@ -0,0 +1,125 @@ +/*============================================================================= + Copyright (c) 2001-2013 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +=============================================================================*/ +#if !defined(BOOST_SPIRIT_TEST_FEBRUARY_01_2007_0605PM) +#define BOOST_SPIRIT_TEST_FEBRUARY_01_2007_0605PM + +#include <boost/spirit/home/x3/core/parse.hpp> +#include <boost/utility/string_view.hpp> +#include <iostream> + +namespace spirit_test +{ + template <typename Char, typename Parser> + bool test(Char const* in, Parser const& p, bool full_match = true) + { + Char const* last = in; + while (*last) + last++; + return boost::spirit::x3::parse(in, last, p) + && (!full_match || (in == last)); + } + + template <typename Char, typename Parser> + bool test(boost::basic_string_view<Char, std::char_traits<Char>> in, + Parser const& p, bool full_match = true) + { + auto const last = in.end(); + auto pos = in.begin(); + + return boost::spirit::x3::parse(pos, last, p) && (!full_match || (pos == last)); + } + + template <typename Char, typename Parser, typename Skipper> + bool test(Char const* in, Parser const& p + , Skipper const& s, bool full_match = true) + { + Char const* last = in; + while (*last) + last++; + return boost::spirit::x3::phrase_parse(in, last, p, s) + && (!full_match || (in == last)); + } + + template <typename Char, typename Parser> + bool test_failure(Char const* in, Parser const& p) + { + Char const * const start = in; + Char const* last = in; + while (*last) + last++; + + return !boost::spirit::x3::parse(in, last, p) && (in == start); + } + + template <typename Char, typename Parser> + bool test_failure(boost::basic_string_view<Char, std::char_traits<Char>> const in, + Parser const& p) + { + auto pos = in.begin(); + return !boost::spirit::x3::parse(pos, in.end(), p) && (pos == in.begin()); + } + + template <typename Char, typename Parser, typename Attr> + bool test_attr(Char const* in, Parser const& p + , Attr& attr, bool full_match = true) + { + Char const* last = in; + while (*last) + last++; + return boost::spirit::x3::parse(in, last, p, attr) + && (!full_match || (in == last)); + } + + template <typename Char, typename Parser, typename Attr, typename Skipper> + bool test_attr(Char const* in, Parser const& p + , Attr& attr, Skipper const& s, bool full_match = true) + { + Char const* last = in; + while (*last) + last++; + return boost::spirit::x3::phrase_parse(in, last, p, s, attr) + && (!full_match || (in == last)); + } + + template <typename Char, typename Parser> + bool binary_test(Char const* in, std::size_t size, Parser const& p, + bool full_match = true) + { + Char const* last = in + size; + return boost::spirit::x3::parse(in, last, p) + && (!full_match || (in == last)); + } + + template <typename Char, typename Parser, typename Skipper> + bool binary_test(Char const* in, std::size_t size, Parser const& p, + Skipper const& s, bool full_match = true) + { + Char const* last = in + size; + return boost::spirit::x3::phrase_parse(in, last, p, s) + && (!full_match || (in == last)); + } + + template <typename Char, typename Parser, typename Attr> + bool binary_test_attr(Char const* in, std::size_t size, Parser const& p, + Attr& attr, bool full_match = true) + { + Char const* last = in + size; + return boost::spirit::x3::parse(in, last, p, attr) + && (!full_match || (in == last)); + } + + template <typename Char, typename Parser, typename Attr, typename Skipper> + bool binary_test_attr(Char const* in, std::size_t size, Parser const& p, + Attr& attr, Skipper const& s, bool full_match = true) + { + Char const* last = in + size; + return boost::spirit::x3::phrase_parse(in, last, p, s, attr) + && (!full_match || (in == last)); + } +} + +#endif diff --git a/src/boost/libs/spirit/test/x3/to_utf8.cpp b/src/boost/libs/spirit/test/x3/to_utf8.cpp new file mode 100644 index 00000000..9974e8b2 --- /dev/null +++ b/src/boost/libs/spirit/test/x3/to_utf8.cpp @@ -0,0 +1,28 @@ +/*============================================================================= + Copyright (c) 2018 Nikita Kniazev + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +=============================================================================*/ +#include <boost/core/lightweight_test.hpp> +#include <boost/spirit/home/x3/support/utility/utf8.hpp> + +int main() +{ + using boost::spirit::x3::to_utf8; + + // Assume wchar_t is 16-bit on Windows and 32-bit on Unix +#if defined(_WIN32) || defined(__CYGWIN__) + BOOST_TEST_CSTR_EQ("\xEF\xBF\xA1", to_utf8(L'\uFFE1').c_str()); +#else + BOOST_TEST_CSTR_EQ("\xF0\x9F\xA7\x90", to_utf8(L'\U0001F9D0').c_str()); +#endif + + BOOST_TEST_CSTR_EQ("\xF0\x9F\xA7\x90\xF0\x9F\xA7\xA0", + to_utf8(L"\U0001F9D0\U0001F9E0").c_str()); + + BOOST_TEST_CSTR_EQ("\xF0\x9F\xA7\x90\xF0\x9F\xA7\xA0", + to_utf8(std::wstring(L"\U0001F9D0\U0001F9E0")).c_str()); + + return boost::report_errors(); +} diff --git a/src/boost/libs/spirit/test/x3/tst.cpp b/src/boost/libs/spirit/test/x3/tst.cpp new file mode 100644 index 00000000..abe19a59 --- /dev/null +++ b/src/boost/libs/spirit/test/x3/tst.cpp @@ -0,0 +1,337 @@ +/*============================================================================= + Copyright (c) 2001-2015 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +=============================================================================*/ +#include <boost/detail/lightweight_test.hpp> +#include <boost/spirit/home/x3/string/tst.hpp> +#include <boost/spirit/home/x3/string/tst_map.hpp> +#include <boost/spirit/home/x3/support/no_case.hpp> +#include <boost/spirit/home/support/char_encoding/standard.hpp> +#include <boost/spirit/home/support/char_encoding/standard_wide.hpp> +#include <string> +#include <cctype> +#include <iostream> + +namespace +{ + template <typename TST, typename Char> + void add(TST& tst, Char const* s, int data) + { + Char const* last = s; + while (*last) + last++; + tst.add(s, last, data); + } + + template <typename TST, typename Char> + void remove(TST& tst, Char const* s) + { + Char const* last = s; + while (*last) + last++; + tst.remove(s, last); + } + + template <typename TST, typename Char, typename CaseCompare> + void docheck(TST const& tst, CaseCompare const& comp, Char const* s, bool expected, int N = 0, int val = -1) + { + Char const* first = s; + Char const* last = s; + while (*last) + last++; + int* r = tst.find(s, last,comp); + BOOST_TEST((r != 0) == expected); + if (r != 0) + BOOST_TEST((s-first) == N); + if (r) + BOOST_TEST(*r == val); + } + + struct printer + { + template <typename String, typename Data> + void operator()(String const& s, Data const& data) + { + std::cout << " " << s << ": " << data << std::endl; + } + }; + + template <typename TST> + void print(TST const& tst) + { + std::cout << '[' << std::endl; + tst.for_each(printer()); + std::cout << ']' << std::endl; + } + +} + +boost::spirit::x3::case_compare<boost::spirit::char_encoding::standard> ncomp; +boost::spirit::x3::case_compare<boost::spirit::char_encoding::standard_wide> wcomp; +boost::spirit::x3::no_case_compare<boost::spirit::char_encoding::standard> nc_ncomp; +boost::spirit::x3::no_case_compare<boost::spirit::char_encoding::standard_wide> nc_wcomp; + +template <typename Lookup, typename WideLookup> +void tests() +{ + { // basic tests + Lookup lookup; + + docheck(lookup, ncomp, "not-yet-there", false); + docheck(lookup, ncomp, "", false); + + add(lookup, "apple", 123); + docheck(lookup, ncomp, "apple", true, 5, 123); // full match + docheck(lookup, ncomp, "banana", false); // no-match + docheck(lookup, ncomp, "applexxx", true, 5, 123); // partial match + + add(lookup, "applepie", 456); + docheck(lookup, ncomp, "applepie", true, 8, 456); // full match + docheck(lookup, ncomp, "banana", false); // no-match + docheck(lookup, ncomp, "applepiexxx", true, 8, 456); // partial match + docheck(lookup, ncomp, "apple", true, 5, 123); // full match + docheck(lookup, ncomp, "applexxx", true, 5, 123); // partial match + } + + { // variation of above + Lookup lookup; + + add(lookup, "applepie", 456); + add(lookup, "apple", 123); + + docheck(lookup, ncomp, "applepie", true, 8, 456); // full match + docheck(lookup, ncomp, "banana", false); // no-match + docheck(lookup, ncomp, "applepiexxx", true, 8, 456); // partial match + docheck(lookup, ncomp, "apple", true, 5, 123); // full match + docheck(lookup, ncomp, "applexxx", true, 5, 123); // partial match + } + { // variation of above + Lookup lookup; + + add(lookup, "applepie", 456); + add(lookup, "apple", 123); + + docheck(lookup, ncomp, "applepie", true, 8, 456); // full match + docheck(lookup, ncomp, "banana", false); // no-match + docheck(lookup, ncomp, "applepiexxx", true, 8, 456); // partial match + docheck(lookup, ncomp, "apple", true, 5, 123); // full match + docheck(lookup, ncomp, "applexxx", true, 5, 123); // partial match + } + + { // narrow char tests + Lookup lookup; + add(lookup, "pineapple", 1); + add(lookup, "orange", 2); + add(lookup, "banana", 3); + add(lookup, "applepie", 4); + add(lookup, "apple", 5); + + docheck(lookup, ncomp, "pineapple", true, 9, 1); + docheck(lookup, ncomp, "orange", true, 6, 2); + docheck(lookup, ncomp, "banana", true, 6, 3); + docheck(lookup, ncomp, "apple", true, 5, 5); + docheck(lookup, ncomp, "pizza", false); + docheck(lookup, ncomp, "steak", false); + docheck(lookup, ncomp, "applepie", true, 8, 4); + docheck(lookup, ncomp, "bananarama", true, 6, 3); + docheck(lookup, ncomp, "applet", true, 5, 5); + docheck(lookup, ncomp, "applepi", true, 5, 5); + docheck(lookup, ncomp, "appl", false); + + docheck(lookup, ncomp, "pineapplez", true, 9, 1); + docheck(lookup, ncomp, "orangez", true, 6, 2); + docheck(lookup, ncomp, "bananaz", true, 6, 3); + docheck(lookup, ncomp, "applez", true, 5, 5); + docheck(lookup, ncomp, "pizzaz", false); + docheck(lookup, ncomp, "steakz", false); + docheck(lookup, ncomp, "applepiez", true, 8, 4); + docheck(lookup, ncomp, "bananaramaz", true, 6, 3); + docheck(lookup, ncomp, "appletz", true, 5, 5); + docheck(lookup, ncomp, "applepix", true, 5, 5); + } + + { // wide char tests + WideLookup lookup; + add(lookup, L"pineapple", 1); + add(lookup, L"orange", 2); + add(lookup, L"banana", 3); + add(lookup, L"applepie", 4); + add(lookup, L"apple", 5); + + docheck(lookup, wcomp, L"pineapple", true, 9, 1); + docheck(lookup, wcomp, L"orange", true, 6, 2); + docheck(lookup, wcomp, L"banana", true, 6, 3); + docheck(lookup, wcomp, L"apple", true, 5, 5); + docheck(lookup, wcomp, L"pizza", false); + docheck(lookup, wcomp, L"steak", false); + docheck(lookup, wcomp, L"applepie", true, 8, 4); + docheck(lookup, wcomp, L"bananarama", true, 6, 3); + docheck(lookup, wcomp, L"applet", true, 5, 5); + docheck(lookup, wcomp, L"applepi", true, 5, 5); + docheck(lookup, wcomp, L"appl", false); + + docheck(lookup, wcomp, L"pineapplez", true, 9, 1); + docheck(lookup, wcomp, L"orangez", true, 6, 2); + docheck(lookup, wcomp, L"bananaz", true, 6, 3); + docheck(lookup, wcomp, L"applez", true, 5, 5); + docheck(lookup, wcomp, L"pizzaz", false); + docheck(lookup, wcomp, L"steakz", false); + docheck(lookup, wcomp, L"applepiez", true, 8, 4); + docheck(lookup, wcomp, L"bananaramaz", true, 6, 3); + docheck(lookup, wcomp, L"appletz", true, 5, 5); + docheck(lookup, wcomp, L"applepix", true, 5, 5); + } + + { // test remove + Lookup lookup; + add(lookup, "pineapple", 1); + add(lookup, "orange", 2); + add(lookup, "banana", 3); + add(lookup, "applepie", 4); + add(lookup, "apple", 5); + + docheck(lookup, ncomp, "pineapple", true, 9, 1); + docheck(lookup, ncomp, "orange", true, 6, 2); + docheck(lookup, ncomp, "banana", true, 6, 3); + docheck(lookup, ncomp, "apple", true, 5, 5); + docheck(lookup, ncomp, "applepie", true, 8, 4); + docheck(lookup, ncomp, "bananarama", true, 6, 3); + docheck(lookup, ncomp, "applet", true, 5, 5); + docheck(lookup, ncomp, "applepi", true, 5, 5); + docheck(lookup, ncomp, "appl", false); + + remove(lookup, "banana"); + docheck(lookup, ncomp, "pineapple", true, 9, 1); + docheck(lookup, ncomp, "orange", true, 6, 2); + docheck(lookup, ncomp, "banana", false); + docheck(lookup, ncomp, "apple", true, 5, 5); + docheck(lookup, ncomp, "applepie", true, 8, 4); + docheck(lookup, ncomp, "bananarama", false); + docheck(lookup, ncomp, "applet", true, 5, 5); + docheck(lookup, ncomp, "applepi", true, 5, 5); + docheck(lookup, ncomp, "appl", false); + + remove(lookup, "apple"); + docheck(lookup, ncomp, "pineapple", true, 9, 1); + docheck(lookup, ncomp, "orange", true, 6, 2); + docheck(lookup, ncomp, "apple", false); + docheck(lookup, ncomp, "applepie", true, 8, 4); + docheck(lookup, ncomp, "applet", false); + docheck(lookup, ncomp, "applepi", false); + docheck(lookup, ncomp, "appl", false); + + remove(lookup, "orange"); + docheck(lookup, ncomp, "pineapple", true, 9, 1); + docheck(lookup, ncomp, "orange", false); + docheck(lookup, ncomp, "applepie", true, 8, 4); + + remove(lookup, "pineapple"); + docheck(lookup, ncomp, "pineapple", false); + docheck(lookup, ncomp, "orange", false); + docheck(lookup, ncomp, "applepie", true, 8, 4); + + remove(lookup, "applepie"); + docheck(lookup, ncomp, "applepie", false); + } + + { // copy/assign/clear test + Lookup lookupa; + add(lookupa, "pineapple", 1); + add(lookupa, "orange", 2); + add(lookupa, "banana", 3); + add(lookupa, "applepie", 4); + add(lookupa, "apple", 5); + + Lookup lookupb(lookupa); // copy ctor + docheck(lookupb, ncomp, "pineapple", true, 9, 1); + docheck(lookupb, ncomp, "orange", true, 6, 2); + docheck(lookupb, ncomp, "banana", true, 6, 3); + docheck(lookupb, ncomp, "apple", true, 5, 5); + docheck(lookupb, ncomp, "pizza", false); + docheck(lookupb, ncomp, "steak", false); + docheck(lookupb, ncomp, "applepie", true, 8, 4); + docheck(lookupb, ncomp, "bananarama", true, 6, 3); + docheck(lookupb, ncomp, "applet", true, 5, 5); + docheck(lookupb, ncomp, "applepi", true, 5, 5); + docheck(lookupb, ncomp, "appl", false); + + lookupb.clear(); // clear + docheck(lookupb, ncomp, "pineapple", false); + docheck(lookupb, ncomp, "orange", false); + docheck(lookupb, ncomp, "banana", false); + docheck(lookupb, ncomp, "apple", false); + docheck(lookupb, ncomp, "applepie", false); + docheck(lookupb, ncomp, "bananarama", false); + docheck(lookupb, ncomp, "applet", false); + docheck(lookupb, ncomp, "applepi", false); + docheck(lookupb, ncomp, "appl", false); + + lookupb = lookupa; // assign + docheck(lookupb, ncomp, "pineapple", true, 9, 1); + docheck(lookupb, ncomp, "orange", true, 6, 2); + docheck(lookupb, ncomp, "banana", true, 6, 3); + docheck(lookupb, ncomp, "apple", true, 5, 5); + docheck(lookupb, ncomp, "pizza", false); + docheck(lookupb, ncomp, "steak", false); + docheck(lookupb, ncomp, "applepie", true, 8, 4); + docheck(lookupb, ncomp, "bananarama", true, 6, 3); + docheck(lookupb, ncomp, "applet", true, 5, 5); + docheck(lookupb, ncomp, "applepi", true, 5, 5); + docheck(lookupb, ncomp, "appl", false); + } + + { // test for_each + Lookup lookup; + add(lookup, "pineapple", 1); + add(lookup, "orange", 2); + add(lookup, "banana", 3); + add(lookup, "applepie", 4); + add(lookup, "apple", 5); + + print(lookup); + } + + { // case insensitive tests + Lookup lookup; + + // NOTE: make sure all entries are in lower-case!!! + add(lookup, "pineapple", 1); + add(lookup, "orange", 2); + add(lookup, "banana", 3); + add(lookup, "applepie", 4); + add(lookup, "apple", 5); + + docheck(lookup, nc_ncomp, "pineapple", true, 9, 1); + docheck(lookup, nc_ncomp, "orange", true, 6, 2); + docheck(lookup, nc_ncomp, "banana", true, 6, 3); + docheck(lookup, nc_ncomp, "apple", true, 5, 5); + docheck(lookup, nc_ncomp, "applepie", true, 8, 4); + + docheck(lookup, nc_ncomp, "PINEAPPLE", true, 9, 1); + docheck(lookup, nc_ncomp, "ORANGE", true, 6, 2); + docheck(lookup, nc_ncomp, "BANANA", true, 6, 3); + docheck(lookup, nc_ncomp, "APPLE", true, 5, 5); + docheck(lookup, nc_ncomp, "APPLEPIE", true, 8, 4); + + docheck(lookup, nc_ncomp, "pineApple", true, 9, 1); + docheck(lookup, nc_ncomp, "orangE", true, 6, 2); + docheck(lookup, nc_ncomp, "Banana", true, 6, 3); + docheck(lookup, nc_ncomp, "aPPLe", true, 5, 5); + docheck(lookup, nc_ncomp, "ApplePie", true, 8, 4); + + print(lookup); + } +} + +int main() +{ + using boost::spirit::x3::tst; + using boost::spirit::x3::tst_map; + + tests<tst<char, int>, tst<wchar_t, int> >(); +//~ tests<tst_map<char, int>, tst_map<wchar_t, int> >(); + + return boost::report_errors(); +} diff --git a/src/boost/libs/spirit/test/x3/uint.hpp b/src/boost/libs/spirit/test/x3/uint.hpp new file mode 100644 index 00000000..b7d4fb7d --- /dev/null +++ b/src/boost/libs/spirit/test/x3/uint.hpp @@ -0,0 +1,59 @@ +/*============================================================================= + Copyright (c) 2001-2012 Joel de Guzman + Copyright (c) 2001-2011 Hartmut Kaiser + Copyright (c) 2011 Bryce Lelbach + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +=============================================================================*/ +#if !defined(BOOST_SPIRIT_TEST_QI_UINT_HPP) +#define BOOST_SPIRIT_TEST_QI_UINT_HPP + +#include <climits> +#include <boost/detail/lightweight_test.hpp> +#include <boost/spirit/home/x3.hpp> + +#include "test.hpp" +#include <cstring> + +/////////////////////////////////////////////////////////////////////////////// +// +// *** BEWARE PLATFORM DEPENDENT!!! *** +// *** The following assumes 32 bit integers and 64 bit long longs. +// *** Modify these constant strings when appropriate. +// +/////////////////////////////////////////////////////////////////////////////// + + char const* max_unsigned = "4294967295"; + char const* unsigned_overflow = "4294967296"; + char const* max_int = "2147483647"; + char const* int_overflow = "2147483648"; + char const* min_int = "-2147483648"; + char const* int_underflow = "-2147483649"; + char const* max_binary = "11111111111111111111111111111111"; + char const* binary_overflow = "100000000000000000000000000000000"; + char const* max_octal = "37777777777"; + char const* octal_overflow = "100000000000"; + char const* max_hex = "FFFFFFFF"; + char const* hex_overflow = "100000000"; + +/////////////////////////////////////////////////////////////////////////////// +// A custom int type +struct custom_uint +{ + unsigned n; + custom_uint() : n(0) {} + explicit custom_uint(unsigned n_) : n(n_) {} + custom_uint& operator=(unsigned n_) { n = n_; return *this; } + friend bool operator==(custom_uint a, custom_uint b) + { return a.n == b.n; } + friend bool operator==(custom_uint a, unsigned b) + { return a.n == b; } + friend custom_uint operator*(custom_uint a, custom_uint b) + { return custom_uint(a.n * b.n); } + friend custom_uint operator+(custom_uint a, custom_uint b) + { return custom_uint(a.n + b.n); } +}; + +#endif + diff --git a/src/boost/libs/spirit/test/x3/uint1.cpp b/src/boost/libs/spirit/test/x3/uint1.cpp new file mode 100644 index 00000000..7778ef0b --- /dev/null +++ b/src/boost/libs/spirit/test/x3/uint1.cpp @@ -0,0 +1,211 @@ +/*============================================================================= + Copyright (c) 2001-2015 Joel de Guzman + Copyright (c) 2001-2011 Hartmut Kaiser + Copyright (c) 2011 Bryce Lelbach + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +=============================================================================*/ +#include "uint.hpp" +#include <boost/spirit/home/x3.hpp> + +int +main() +{ + using spirit_test::test; + using spirit_test::test_attr; + /////////////////////////////////////////////////////////////////////////// + // unsigned tests + /////////////////////////////////////////////////////////////////////////// + { + using boost::spirit::x3::uint_; + unsigned u; + + BOOST_TEST(test("123456", uint_)); + BOOST_TEST(test_attr("123456", uint_, u)); + BOOST_TEST(u == 123456); + + BOOST_TEST(test(max_unsigned, uint_)); + BOOST_TEST(test_attr(max_unsigned, uint_, u)); + BOOST_TEST(u == UINT_MAX); + + BOOST_TEST(!test(unsigned_overflow, uint_)); + BOOST_TEST(!test_attr(unsigned_overflow, uint_, u)); + } + + /////////////////////////////////////////////////////////////////////////// + // binary tests + /////////////////////////////////////////////////////////////////////////// + { + using boost::spirit::x3::bin; + unsigned u; + + BOOST_TEST(test("11111110", bin)); + BOOST_TEST(test_attr("11111110", bin, u)); + BOOST_TEST(u == 0xFE); + + BOOST_TEST(test(max_binary, bin)); + BOOST_TEST(test_attr(max_binary, bin, u)); + BOOST_TEST(u == UINT_MAX); + + BOOST_TEST(!test(binary_overflow, bin)); + BOOST_TEST(!test_attr(binary_overflow, bin, u)); + } + + /////////////////////////////////////////////////////////////////////////// + // octal tests + /////////////////////////////////////////////////////////////////////////// + { + using boost::spirit::x3::oct; + unsigned u; + + BOOST_TEST(test("12545674515", oct)); + BOOST_TEST(test_attr("12545674515", oct, u)); + BOOST_TEST(u == 012545674515); + + BOOST_TEST(test(max_octal, oct)); + BOOST_TEST(test_attr(max_octal, oct, u)); + BOOST_TEST(u == UINT_MAX); + + BOOST_TEST(!test(octal_overflow, oct)); + BOOST_TEST(!test_attr(octal_overflow, oct, u)); + } + + /////////////////////////////////////////////////////////////////////////// + // hex tests + /////////////////////////////////////////////////////////////////////////// + { + using boost::spirit::x3::hex; + unsigned u; + + BOOST_TEST(test("95BC8DF", hex)); + BOOST_TEST(test_attr("95BC8DF", hex, u)); + BOOST_TEST(u == 0x95BC8DF); + + BOOST_TEST(test("abcdef12", hex)); + BOOST_TEST(test_attr("abcdef12", hex, u)); + BOOST_TEST(u == 0xabcdef12); + + BOOST_TEST(test(max_hex, hex)); + BOOST_TEST(test_attr(max_hex, hex, u)); + BOOST_TEST(u == UINT_MAX); + + BOOST_TEST(!test(hex_overflow, hex)); + BOOST_TEST(!test_attr(hex_overflow, hex, u)); + } + + /////////////////////////////////////////////////////////////////////////// + // limited fieldwidth + /////////////////////////////////////////////////////////////////////////// + { + unsigned u; + using boost::spirit::x3::uint_parser; + + uint_parser<unsigned, 10, 1, 3> uint3; + BOOST_TEST(test("123456", uint3, false)); + BOOST_TEST(test_attr("123456", uint3, u, false)); + BOOST_TEST(u == 123); + + uint_parser<unsigned, 10, 2, 4> uint4; + BOOST_TEST(test("123456", uint4, false)); + BOOST_TEST(test_attr("123456", uint4, u, false)); + BOOST_TEST(u == 1234); + + char const * first = "0000000"; + char const * last = first + std::strlen(first); + uint_parser<unsigned, 10, 4, 4> uint_exact4; + BOOST_TEST(boost::spirit::x3::parse(first, last, uint_exact4, u) + && first != last && (last-first == 3) && u == 0); + + first = "0001400"; + last = first + std::strlen(first); + BOOST_TEST(boost::spirit::x3::parse(first, last, uint_exact4, u) + && first != last && (last-first == 3) && u == 1); + + BOOST_TEST(!test("1", uint4)); + BOOST_TEST(!test_attr("1", uint4, u)); + BOOST_TEST(test_attr("014567", uint4, u, false) && u == 145); + } + + /////////////////////////////////////////////////////////////////////////// + // action tests + /////////////////////////////////////////////////////////////////////////// + { + using boost::spirit::x3::_attr; + using boost::spirit::x3::uint_; + using boost::spirit::x3::ascii::space; + int n; + + auto f = [&](auto& ctx){ n = _attr(ctx); }; + + BOOST_TEST(test("123", uint_[f])); + BOOST_TEST(n == 123); + BOOST_TEST(test(" 456", uint_[f], space)); + BOOST_TEST(n == 456); + } + + /////////////////////////////////////////////////////////////////////////// + // Check overflow is parse error + /////////////////////////////////////////////////////////////////////////// + { + boost::spirit::x3::uint_parser<boost::uint8_t> uint8_; + boost::uint8_t u8; + + BOOST_TEST(!test_attr("999", uint8_, u8)); + BOOST_TEST(!test_attr("256", uint8_, u8)); + BOOST_TEST(test_attr("255", uint8_, u8)); + + boost::spirit::x3::uint_parser<boost::uint16_t> uint16_; + boost::uint16_t u16; + + BOOST_TEST(!test_attr("99999", uint16_, u16)); + BOOST_TEST(!test_attr("65536", uint16_, u16)); + BOOST_TEST(test_attr("65535", uint16_, u16)); + + boost::spirit::x3::uint_parser<boost::uint32_t> uint32_; + boost::uint32_t u32; + + BOOST_TEST(!test_attr("9999999999", uint32_, u32)); + BOOST_TEST(!test_attr("4294967296", uint32_, u32)); + BOOST_TEST(test_attr("4294967295", uint32_, u32)); + + boost::spirit::x3::uint_parser<boost::int8_t> u_int8_; + + BOOST_TEST(!test_attr("999", u_int8_, u8)); + BOOST_TEST(!test_attr("-1", u_int8_, u8)); + BOOST_TEST(!test_attr("128", u_int8_, u8)); + BOOST_TEST(test_attr("127", u_int8_, u8)); + BOOST_TEST(test_attr("0", u_int8_, u8)); + + boost::spirit::x3::uint_parser<boost::int16_t> u_int16_; + + BOOST_TEST(!test_attr("99999", u_int16_, u16)); + BOOST_TEST(!test_attr("-1", u_int16_, u16)); + BOOST_TEST(!test_attr("32768", u_int16_, u16)); + BOOST_TEST(test_attr("32767", u_int16_, u16)); + BOOST_TEST(test_attr("0", u_int16_, u16)); + + boost::spirit::x3::uint_parser<boost::int32_t> u_int32_; + + BOOST_TEST(!test_attr("9999999999", u_int32_, u32)); + BOOST_TEST(!test_attr("-1", u_int32_, u32)); + BOOST_TEST(!test_attr("2147483648", u_int32_, u32)); + BOOST_TEST(test_attr("2147483647", u_int32_, u32)); + BOOST_TEST(test_attr("0", u_int32_, u32)); + } + + /////////////////////////////////////////////////////////////////////////// + // custom uint tests + /////////////////////////////////////////////////////////////////////////// + { + using boost::spirit::x3::uint_; + using boost::spirit::x3::uint_parser; + custom_uint u; + + BOOST_TEST(test_attr("123456", uint_, u)); + uint_parser<custom_uint, 10, 1, 2> uint2; + BOOST_TEST(test_attr("12", uint2, u)); + } + + return boost::report_errors(); +} diff --git a/src/boost/libs/spirit/test/x3/uint_radix.cpp b/src/boost/libs/spirit/test/x3/uint_radix.cpp new file mode 100644 index 00000000..4ae4fb0f --- /dev/null +++ b/src/boost/libs/spirit/test/x3/uint_radix.cpp @@ -0,0 +1,740 @@ +/*============================================================================= + Copyright (c) 2011 Jan Frederick Eick + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +=============================================================================*/ + +#include <boost/config/warning_disable.hpp> +#include <boost/detail/lightweight_test.hpp> +#include <boost/spirit/home/x3.hpp> + +#include <climits> +#include <cstring> +#include "test.hpp" + +#include "uint_radix.hpp" + +int +main() +{ + using spirit_test::test; + using spirit_test::test_attr; + + using boost::spirit::x3::uint_parser; + + /////////////////////////////////////////////////////////////////////////// + // arbitrary radix test (base 3) + /////////////////////////////////////////////////////////////////////////// + { + unsigned int u; + uint_parser<unsigned int, 3, 1, -1> base3_parser; + + BOOST_TEST(test("210112221200", base3_parser)); + BOOST_TEST(test_attr("210112221200", base3_parser, u)); + BOOST_TEST(424242 == u); + + BOOST_TEST(!test("1231", base3_parser)); + BOOST_TEST(!test_attr("1231", base3_parser, u)); + + BOOST_TEST(test(max_unsigned_base3, base3_parser)); + BOOST_TEST(test_attr(max_unsigned_base3, base3_parser, u)); + + BOOST_TEST(!test(unsigned_overflow_base3, base3_parser)); + BOOST_TEST(!test_attr(unsigned_overflow_base3, base3_parser, u)); + BOOST_TEST(!test(digit_overflow_base3, base3_parser)); + BOOST_TEST(!test_attr(digit_overflow_base3, base3_parser, u)); + } + + /////////////////////////////////////////////////////////////////////////// + // arbitrary radix test (base 4) + /////////////////////////////////////////////////////////////////////////// + { + unsigned int u; + + uint_parser<unsigned int, 4, 1, -1> base4_parser; + + BOOST_TEST(test("1213210302", base4_parser)); + BOOST_TEST(test_attr("1213210302", base4_parser, u)); + BOOST_TEST(424242 == u); + + BOOST_TEST(!test("1234", base4_parser)); + BOOST_TEST(!test_attr("1234", base4_parser, u)); + + BOOST_TEST(test(max_unsigned_base4, base4_parser)); + BOOST_TEST(test_attr(max_unsigned_base4, base4_parser, u)); + BOOST_TEST(!test(digit_overflow_base4, base4_parser)); + BOOST_TEST(!test_attr(digit_overflow_base4, base4_parser, u)); + } + + /////////////////////////////////////////////////////////////////////////// + // arbitrary radix test (base 5) + /////////////////////////////////////////////////////////////////////////// + { + unsigned int u; + + uint_parser<unsigned int, 5, 1, -1> base5_parser; + + BOOST_TEST(test("102033432", base5_parser)); + BOOST_TEST(test_attr("102033432", base5_parser, u)); + BOOST_TEST(424242 == u); + + BOOST_TEST(!test("2345", base5_parser)); + BOOST_TEST(!test_attr("2345", base5_parser, u)); + + BOOST_TEST(test(max_unsigned_base5, base5_parser)); + BOOST_TEST(test_attr(max_unsigned_base5, base5_parser, u)); + + BOOST_TEST(!test(unsigned_overflow_base5, base5_parser)); + BOOST_TEST(!test_attr(unsigned_overflow_base5, base5_parser, u)); + BOOST_TEST(!test(digit_overflow_base5, base5_parser)); + BOOST_TEST(!test_attr(digit_overflow_base5, base5_parser, u)); + } + + /////////////////////////////////////////////////////////////////////////// + // arbitrary radix test (base 6) + /////////////////////////////////////////////////////////////////////////// + { + unsigned int u; + + uint_parser<unsigned int, 6, 1, -1> base6_parser; + + BOOST_TEST(test("13032030", base6_parser)); + BOOST_TEST(test_attr("13032030", base6_parser, u)); + BOOST_TEST(424242 == u); + + BOOST_TEST(!test("3456", base6_parser)); + BOOST_TEST(!test_attr("3456", base6_parser, u)); + + BOOST_TEST(test(max_unsigned_base6, base6_parser)); + BOOST_TEST(test_attr(max_unsigned_base6, base6_parser, u)); + + BOOST_TEST(!test(unsigned_overflow_base6, base6_parser)); + BOOST_TEST(!test_attr(unsigned_overflow_base6, base6_parser, u)); + BOOST_TEST(!test(digit_overflow_base6, base6_parser)); + BOOST_TEST(!test_attr(digit_overflow_base6, base6_parser, u)); + } + + /////////////////////////////////////////////////////////////////////////// + // arbitrary radix test (base 7) + /////////////////////////////////////////////////////////////////////////// + { + unsigned int u; + + uint_parser<unsigned int, 7, 1, -1> base7_parser; + + BOOST_TEST(test("3414600", base7_parser)); + BOOST_TEST(test_attr("3414600", base7_parser, u)); + BOOST_TEST(424242 == u); + + BOOST_TEST(!test("4567", base7_parser)); + BOOST_TEST(!test_attr("4567", base7_parser, u)); + + BOOST_TEST(test(max_unsigned_base7, base7_parser)); + BOOST_TEST(test_attr(max_unsigned_base7, base7_parser, u)); + + BOOST_TEST(!test(unsigned_overflow_base7, base7_parser)); + BOOST_TEST(!test_attr(unsigned_overflow_base7, base7_parser, u)); + BOOST_TEST(!test(digit_overflow_base7, base7_parser)); + BOOST_TEST(!test_attr(digit_overflow_base7, base7_parser, u)); + } + + /////////////////////////////////////////////////////////////////////////// + // arbitrary radix test (base 9) + /////////////////////////////////////////////////////////////////////////// + { + unsigned int u; + + uint_parser<unsigned int, 9, 1, -1> base9_parser; + + BOOST_TEST(test("715850", base9_parser)); + BOOST_TEST(test_attr("715850", base9_parser, u)); + BOOST_TEST(424242 == u); + + BOOST_TEST(!test("6789", base9_parser)); + BOOST_TEST(!test_attr("6789", base9_parser, u)); + + BOOST_TEST(test(max_unsigned_base9, base9_parser)); + BOOST_TEST(test_attr(max_unsigned_base9, base9_parser, u)); + + BOOST_TEST(!test(unsigned_overflow_base9, base9_parser)); + BOOST_TEST(!test_attr(unsigned_overflow_base9, base9_parser, u)); + BOOST_TEST(!test(digit_overflow_base9, base9_parser)); + BOOST_TEST(!test_attr(digit_overflow_base9, base9_parser, u)); + } + + /////////////////////////////////////////////////////////////////////////// + // arbitrary radix test (base 11) + /////////////////////////////////////////////////////////////////////////// + { + unsigned int u; + + uint_parser<unsigned int, 11, 1, -1> base11_parser; + + BOOST_TEST(test("26a815", base11_parser)); + BOOST_TEST(test_attr("26a815", base11_parser, u)); + BOOST_TEST(424242 == u); + + BOOST_TEST(!test("90ab", base11_parser)); + BOOST_TEST(!test_attr("90AB", base11_parser, u)); + + BOOST_TEST(test(max_unsigned_base11, base11_parser)); + BOOST_TEST(test_attr(max_unsigned_base11, base11_parser, u)); + + BOOST_TEST(!test(unsigned_overflow_base11, base11_parser)); + BOOST_TEST(!test_attr(unsigned_overflow_base11, base11_parser, u)); + BOOST_TEST(!test(digit_overflow_base11, base11_parser)); + BOOST_TEST(!test_attr(digit_overflow_base11, base11_parser, u)); + } + + /////////////////////////////////////////////////////////////////////////// + // arbitrary radix test (base 12) + /////////////////////////////////////////////////////////////////////////// + { + unsigned int u; + uint_parser<unsigned int, 12, 1, -1> base12_parser; + + BOOST_TEST(test("185616", base12_parser)); + BOOST_TEST(test_attr("185616", base12_parser, u)); + BOOST_TEST(424242 == u); + + BOOST_TEST(!test("9abc", base12_parser)); + BOOST_TEST(!test_attr("9ABC", base12_parser, u)); + + BOOST_TEST(test(max_unsigned_base12, base12_parser)); + BOOST_TEST(test_attr(max_unsigned_base12, base12_parser, u)); + + BOOST_TEST(!test(unsigned_overflow_base12, base12_parser)); + BOOST_TEST(!test_attr(unsigned_overflow_base12, base12_parser, u)); + BOOST_TEST(!test(digit_overflow_base12, base12_parser)); + BOOST_TEST(!test_attr(digit_overflow_base12, base12_parser, u)); + } + + /////////////////////////////////////////////////////////////////////////// + // arbitrary radix test (base 13) + /////////////////////////////////////////////////////////////////////////// + { + unsigned int u; + uint_parser<unsigned int, 13, 1, -1> base13_parser; + + BOOST_TEST(test("11b140", base13_parser)); + BOOST_TEST(test_attr("11b140", base13_parser, u)); + BOOST_TEST(424242 == u); + + BOOST_TEST(!test("abcd", base13_parser)); + BOOST_TEST(!test_attr("ABCD", base13_parser, u)); + + BOOST_TEST(test(max_unsigned_base13, base13_parser)); + BOOST_TEST(test_attr(max_unsigned_base13, base13_parser, u)); + + BOOST_TEST(!test(unsigned_overflow_base13, base13_parser)); + BOOST_TEST(!test_attr(unsigned_overflow_base13, base13_parser, u)); + BOOST_TEST(!test(digit_overflow_base13, base13_parser)); + BOOST_TEST(!test_attr(digit_overflow_base13, base13_parser, u)); + } + + /////////////////////////////////////////////////////////////////////////// + // arbitrary radix test (base 14) + /////////////////////////////////////////////////////////////////////////// + { + unsigned int u; + uint_parser<unsigned int, 14, 1, -1> base14_parser; + + BOOST_TEST(test("b0870", base14_parser)); + BOOST_TEST(test_attr("b0870", base14_parser, u)); + BOOST_TEST(424242 == u); + + BOOST_TEST(!test("bcde", base14_parser)); + BOOST_TEST(!test_attr("BCDE", base14_parser, u)); + + BOOST_TEST(test(max_unsigned_base14, base14_parser)); + BOOST_TEST(test_attr(max_unsigned_base14, base14_parser, u)); + + BOOST_TEST(!test(unsigned_overflow_base14, base14_parser)); + BOOST_TEST(!test_attr(unsigned_overflow_base14, base14_parser, u)); + BOOST_TEST(!test(digit_overflow_base14, base14_parser)); + BOOST_TEST(!test_attr(digit_overflow_base14, base14_parser, u)); + } + + /////////////////////////////////////////////////////////////////////////// + // arbitrary radix test (base 15) + /////////////////////////////////////////////////////////////////////////// + { + unsigned int u; + uint_parser<unsigned int, 15, 1, -1> base15_parser; + + BOOST_TEST(test("85a7c", base15_parser)); + BOOST_TEST(test_attr("85a7c", base15_parser, u)); + BOOST_TEST(424242 == u); + + BOOST_TEST(!test("cdef", base15_parser)); + BOOST_TEST(!test_attr("CDEF", base15_parser, u)); + + BOOST_TEST(test(max_unsigned_base15, base15_parser)); + BOOST_TEST(test_attr(max_unsigned_base15, base15_parser, u)); + + BOOST_TEST(!test(unsigned_overflow_base15, base15_parser)); + BOOST_TEST(!test_attr(unsigned_overflow_base15, base15_parser, u)); + BOOST_TEST(!test(digit_overflow_base15, base15_parser)); + BOOST_TEST(!test_attr(digit_overflow_base15, base15_parser, u)); + } + + /////////////////////////////////////////////////////////////////////////// + // arbitrary radix test (base 17) + /////////////////////////////////////////////////////////////////////////// + { + unsigned int u; + uint_parser<unsigned int, 17, 1, -1> base17_parser; + + BOOST_TEST(test("515g7", base17_parser)); + BOOST_TEST(test_attr("515g7", base17_parser, u)); + BOOST_TEST(424242 == u); + + BOOST_TEST(!test("efgh", base17_parser)); + BOOST_TEST(!test_attr("EFGH", base17_parser, u)); + + BOOST_TEST(test(max_unsigned_base17, base17_parser)); + BOOST_TEST(test_attr(max_unsigned_base17, base17_parser, u)); + + BOOST_TEST(!test(unsigned_overflow_base17, base17_parser)); + BOOST_TEST(!test_attr(unsigned_overflow_base17, base17_parser, u)); + BOOST_TEST(!test(digit_overflow_base17, base17_parser)); + BOOST_TEST(!test_attr(digit_overflow_base17, base17_parser, u)); + } + + /////////////////////////////////////////////////////////////////////////// + // arbitrary radix test (base 18) + /////////////////////////////////////////////////////////////////////////// + { + unsigned int u; + uint_parser<unsigned int, 18, 1, -1> base18_parser; + + BOOST_TEST(test("40d70", base18_parser)); + BOOST_TEST(test_attr("40d70", base18_parser, u)); + BOOST_TEST(424242 == u); + + BOOST_TEST(!test("fghi", base18_parser)); + BOOST_TEST(!test_attr("FGHI", base18_parser, u)); + + BOOST_TEST(test(max_unsigned_base18, base18_parser)); + BOOST_TEST(test_attr(max_unsigned_base18, base18_parser, u)); + + BOOST_TEST(!test(unsigned_overflow_base18, base18_parser)); + BOOST_TEST(!test_attr(unsigned_overflow_base18, base18_parser, u)); + BOOST_TEST(!test(digit_overflow_base18, base18_parser)); + BOOST_TEST(!test_attr(digit_overflow_base18, base18_parser, u)); + } + + /////////////////////////////////////////////////////////////////////////// + // arbitrary radix test (base 19) + /////////////////////////////////////////////////////////////////////////// + { + unsigned int u; + uint_parser<unsigned int, 19, 1, -1> base19_parser; + + BOOST_TEST(test("34g3a", base19_parser)); + BOOST_TEST(test_attr("34g3a", base19_parser, u)); + BOOST_TEST(424242 == u); + + BOOST_TEST(!test("ghij", base19_parser)); + BOOST_TEST(!test_attr("GHIJ", base19_parser, u)); + + BOOST_TEST(test(max_unsigned_base19, base19_parser)); + BOOST_TEST(test_attr(max_unsigned_base19, base19_parser, u)); + + BOOST_TEST(!test(unsigned_overflow_base19, base19_parser)); + BOOST_TEST(!test_attr(unsigned_overflow_base19, base19_parser, u)); + BOOST_TEST(!test(digit_overflow_base19, base19_parser)); + BOOST_TEST(!test_attr(digit_overflow_base19, base19_parser, u)); + } + + /////////////////////////////////////////////////////////////////////////// + // arbitrary radix test (base 20) + /////////////////////////////////////////////////////////////////////////// + { + unsigned int u; + uint_parser<unsigned int, 20, 1, -1> base20_parser; + + BOOST_TEST(test("2d0c2", base20_parser)); + BOOST_TEST(test_attr("2d0c2", base20_parser, u)); + BOOST_TEST(424242 == u); + + BOOST_TEST(!test("hijk", base20_parser)); + BOOST_TEST(!test_attr("HIJK", base20_parser, u)); + + BOOST_TEST(test(max_unsigned_base20, base20_parser)); + BOOST_TEST(test_attr(max_unsigned_base20, base20_parser, u)); + + BOOST_TEST(!test(unsigned_overflow_base20, base20_parser)); + BOOST_TEST(!test_attr(unsigned_overflow_base20, base20_parser, u)); + BOOST_TEST(!test(digit_overflow_base20, base20_parser)); + BOOST_TEST(!test_attr(digit_overflow_base20, base20_parser, u)); + } + + /////////////////////////////////////////////////////////////////////////// + // arbitrary radix test (base 21) + /////////////////////////////////////////////////////////////////////////// + { + unsigned int u; + uint_parser<unsigned int, 21, 1, -1> base21_parser; + + BOOST_TEST(test("23h00", base21_parser)); + BOOST_TEST(test_attr("23h00", base21_parser, u)); + BOOST_TEST(424242 == u); + + BOOST_TEST(!test("ijkl", base21_parser)); + BOOST_TEST(!test_attr("IJKL", base21_parser, u)); + + BOOST_TEST(test(max_unsigned_base21, base21_parser)); + BOOST_TEST(test_attr(max_unsigned_base21, base21_parser, u)); + + BOOST_TEST(!test(unsigned_overflow_base21, base21_parser)); + BOOST_TEST(!test_attr(unsigned_overflow_base21, base21_parser, u)); + BOOST_TEST(!test(digit_overflow_base21, base21_parser)); + BOOST_TEST(!test_attr(digit_overflow_base21, base21_parser, u)); + } + + /////////////////////////////////////////////////////////////////////////// + // arbitrary radix test (base 22) + /////////////////////////////////////////////////////////////////////////// + { + unsigned int u; + uint_parser<unsigned int, 22, 1, -1> base22_parser; + + BOOST_TEST(test("1hibg", base22_parser)); + BOOST_TEST(test_attr("1hibg", base22_parser, u)); + BOOST_TEST(424242 == u); + + BOOST_TEST(!test("jklm", base22_parser)); + BOOST_TEST(!test_attr("JKLM", base22_parser, u)); + + BOOST_TEST(test(max_unsigned_base22, base22_parser)); + BOOST_TEST(test_attr(max_unsigned_base22, base22_parser, u)); + + BOOST_TEST(!test(unsigned_overflow_base22, base22_parser)); + BOOST_TEST(!test_attr(unsigned_overflow_base22, base22_parser, u)); + BOOST_TEST(!test(digit_overflow_base22, base22_parser)); + BOOST_TEST(!test_attr(digit_overflow_base22, base22_parser, u)); + } + + /////////////////////////////////////////////////////////////////////////// + // arbitrary radix test (base 23) + /////////////////////////////////////////////////////////////////////////// + { + unsigned int u; + uint_parser<unsigned int, 23, 1, -1> base23_parser; + + BOOST_TEST(test("1bjm7", base23_parser)); + BOOST_TEST(test_attr("1bjm7", base23_parser, u)); + BOOST_TEST(424242 == u); + + BOOST_TEST(!test("klmn", base23_parser)); + BOOST_TEST(!test_attr("KLMN", base23_parser, u)); + + BOOST_TEST(test(max_unsigned_base23, base23_parser)); + BOOST_TEST(test_attr(max_unsigned_base23, base23_parser, u)); + + BOOST_TEST(!test(unsigned_overflow_base23, base23_parser)); + BOOST_TEST(!test_attr(unsigned_overflow_base23, base23_parser, u)); + BOOST_TEST(!test(digit_overflow_base23, base23_parser)); + BOOST_TEST(!test_attr(digit_overflow_base23, base23_parser, u)); + } + + /////////////////////////////////////////////////////////////////////////// + // arbitrary radix test (base 24) + /////////////////////////////////////////////////////////////////////////// + { + unsigned int u; + uint_parser<unsigned int, 24, 1, -1> base24_parser; + + BOOST_TEST(test("16gci", base24_parser)); + BOOST_TEST(test_attr("16gci", base24_parser, u)); + BOOST_TEST(424242 == u); + + BOOST_TEST(!test("lmno", base24_parser)); + BOOST_TEST(!test_attr("LMNO", base24_parser, u)); + + BOOST_TEST(test(max_unsigned_base24, base24_parser)); + BOOST_TEST(test_attr(max_unsigned_base24, base24_parser, u)); + + BOOST_TEST(!test(unsigned_overflow_base24, base24_parser)); + BOOST_TEST(!test_attr(unsigned_overflow_base24, base24_parser, u)); + BOOST_TEST(!test(digit_overflow_base24, base24_parser)); + BOOST_TEST(!test_attr(digit_overflow_base24, base24_parser, u)); + } + + /////////////////////////////////////////////////////////////////////////// + // arbitrary radix test (base 25) + /////////////////////////////////////////////////////////////////////////// + { + unsigned int u; + uint_parser<unsigned int, 25, 1, -1> base25_parser; + + BOOST_TEST(test("123jh", base25_parser)); + BOOST_TEST(test_attr("123jh", base25_parser, u)); + BOOST_TEST(424242 == u); + + BOOST_TEST(!test("mnop", base25_parser)); + BOOST_TEST(!test_attr("MNOP", base25_parser, u)); + + BOOST_TEST(test(max_unsigned_base25, base25_parser)); + BOOST_TEST(test_attr(max_unsigned_base25, base25_parser, u)); + + BOOST_TEST(!test(unsigned_overflow_base25, base25_parser)); + BOOST_TEST(!test_attr(unsigned_overflow_base25, base25_parser, u)); + BOOST_TEST(!test(digit_overflow_base25, base25_parser)); + BOOST_TEST(!test_attr(digit_overflow_base25, base25_parser, u)); + } + + /////////////////////////////////////////////////////////////////////////// + // arbitrary radix test (base 26) + /////////////////////////////////////////////////////////////////////////// + { + unsigned int u; + uint_parser<unsigned int, 26, 1, -1> base26_parser; + + BOOST_TEST(test("o3f0", base26_parser)); + BOOST_TEST(test_attr("o3f0", base26_parser, u)); + BOOST_TEST(424242 == u); + + BOOST_TEST(!test("nopq", base26_parser)); + BOOST_TEST(!test_attr("NOPQ", base26_parser, u)); + + BOOST_TEST(test(max_unsigned_base26, base26_parser)); + BOOST_TEST(test_attr(max_unsigned_base26, base26_parser, u)); + + BOOST_TEST(!test(unsigned_overflow_base26, base26_parser)); + BOOST_TEST(!test_attr(unsigned_overflow_base26, base26_parser, u)); + BOOST_TEST(!test(digit_overflow_base26, base26_parser)); + BOOST_TEST(!test_attr(digit_overflow_base26, base26_parser, u)); + } + + /////////////////////////////////////////////////////////////////////////// + // arbitrary radix test (base 27) + /////////////////////////////////////////////////////////////////////////// + { + unsigned int u; + uint_parser<unsigned int, 27, 1, -1> base27_parser; + + BOOST_TEST(test("lepi", base27_parser)); + BOOST_TEST(test_attr("lepi", base27_parser, u)); + BOOST_TEST(424242 == u); + + BOOST_TEST(!test("opqr", base27_parser)); + BOOST_TEST(!test_attr("OPQR", base27_parser, u)); + + BOOST_TEST(test(max_unsigned_base27, base27_parser)); + BOOST_TEST(test_attr(max_unsigned_base27, base27_parser, u)); + + BOOST_TEST(!test(unsigned_overflow_base27, base27_parser)); + BOOST_TEST(!test_attr(unsigned_overflow_base27, base27_parser, u)); + BOOST_TEST(!test(digit_overflow_base27, base27_parser)); + BOOST_TEST(!test_attr(digit_overflow_base27, base27_parser, u)); + } + + /////////////////////////////////////////////////////////////////////////// + // arbitrary radix test (base 28) + /////////////////////////////////////////////////////////////////////////// + { + unsigned int u; + uint_parser<unsigned int, 28, 1, -1> base28_parser; + + BOOST_TEST(test("j93e", base28_parser)); + BOOST_TEST(test_attr("j93e", base28_parser, u)); + BOOST_TEST(424242 == u); + + BOOST_TEST(!test("pqrs", base28_parser)); + BOOST_TEST(!test_attr("PQRS", base28_parser, u)); + + BOOST_TEST(test(max_unsigned_base28, base28_parser)); + BOOST_TEST(test_attr(max_unsigned_base28, base28_parser, u)); + + BOOST_TEST(!test(unsigned_overflow_base28, base28_parser)); + BOOST_TEST(!test_attr(unsigned_overflow_base28, base28_parser, u)); + BOOST_TEST(!test(digit_overflow_base28, base28_parser)); + BOOST_TEST(!test_attr(digit_overflow_base28, base28_parser, u)); + } + + /////////////////////////////////////////////////////////////////////////// + // arbitrary radix test (base 29) + /////////////////////////////////////////////////////////////////////////// + { + unsigned int u; + uint_parser<unsigned int, 29, 1, -1> base29_parser; + + BOOST_TEST(test("hbd1", base29_parser)); + BOOST_TEST(test_attr("hbd1", base29_parser, u)); + BOOST_TEST(424242 == u); + + BOOST_TEST(!test("qrst", base29_parser)); + BOOST_TEST(!test_attr("QRST", base29_parser, u)); + + BOOST_TEST(test(max_unsigned_base29, base29_parser)); + BOOST_TEST(test_attr(max_unsigned_base29, base29_parser, u)); + + BOOST_TEST(!test(unsigned_overflow_base29, base29_parser)); + BOOST_TEST(!test_attr(unsigned_overflow_base29, base29_parser, u)); + BOOST_TEST(!test(digit_overflow_base29, base29_parser)); + BOOST_TEST(!test_attr(digit_overflow_base29, base29_parser, u)); + } + + /////////////////////////////////////////////////////////////////////////// + // arbitrary radix test (base 30) + /////////////////////////////////////////////////////////////////////////// + { + unsigned int u; + uint_parser<unsigned int, 30, 1, -1> base30_parser; + + BOOST_TEST(test("flbc", base30_parser)); + BOOST_TEST(test_attr("flbc", base30_parser, u)); + BOOST_TEST(424242 == u); + + BOOST_TEST(!test("rstu", base30_parser)); + BOOST_TEST(!test_attr("RSTU", base30_parser, u)); + + BOOST_TEST(test(max_unsigned_base30, base30_parser)); + BOOST_TEST(test_attr(max_unsigned_base30, base30_parser, u)); + + BOOST_TEST(!test(unsigned_overflow_base30, base30_parser)); + BOOST_TEST(!test_attr(unsigned_overflow_base30, base30_parser, u)); + BOOST_TEST(!test(digit_overflow_base30, base30_parser)); + BOOST_TEST(!test_attr(digit_overflow_base30, base30_parser, u)); + } + + /////////////////////////////////////////////////////////////////////////// + // arbitrary radix test (base 31) + /////////////////////////////////////////////////////////////////////////// + { + unsigned int u; + uint_parser<unsigned int, 31, 1, -1> base31_parser; + + BOOST_TEST(test("e7e7", base31_parser)); + BOOST_TEST(test_attr("e7e7", base31_parser, u)); + BOOST_TEST(424242 == u); + + BOOST_TEST(!test("stuv", base31_parser)); + BOOST_TEST(!test_attr("STUV", base31_parser, u)); + + BOOST_TEST(test(max_unsigned_base31, base31_parser)); + BOOST_TEST(test_attr(max_unsigned_base31, base31_parser, u)); + + BOOST_TEST(!test(unsigned_overflow_base31, base31_parser)); + BOOST_TEST(!test_attr(unsigned_overflow_base31, base31_parser, u)); + BOOST_TEST(!test(digit_overflow_base31, base31_parser)); + BOOST_TEST(!test_attr(digit_overflow_base31, base31_parser, u)); + } + + /////////////////////////////////////////////////////////////////////////// + // arbitrary radix test (base 32) + /////////////////////////////////////////////////////////////////////////// + { + unsigned int u; + uint_parser<unsigned int, 32, 1, -1> base32_parser; + + BOOST_TEST(test("cu9i", base32_parser)); + BOOST_TEST(test_attr("cu9i", base32_parser, u)); + BOOST_TEST(424242 == u); + + BOOST_TEST(!test("tuvw", base32_parser)); + BOOST_TEST(!test_attr("TUVW", base32_parser, u)); + + BOOST_TEST(test(max_unsigned_base32, base32_parser)); + BOOST_TEST(test_attr(max_unsigned_base32, base32_parser, u)); + + BOOST_TEST(!test(unsigned_overflow_base32, base32_parser)); + BOOST_TEST(!test_attr(unsigned_overflow_base32, base32_parser, u)); + BOOST_TEST(!test(digit_overflow_base32, base32_parser)); + BOOST_TEST(!test_attr(digit_overflow_base32, base32_parser, u)); + } + + /////////////////////////////////////////////////////////////////////////// + // arbitrary radix test (base 33) + /////////////////////////////////////////////////////////////////////////// + { + unsigned int u; + uint_parser<unsigned int, 33, 1, -1> base33_parser; + + BOOST_TEST(test("bqir", base33_parser)); + BOOST_TEST(test_attr("bqir", base33_parser, u)); + BOOST_TEST(424242 == u); + + BOOST_TEST(!test("uvwx", base33_parser)); + BOOST_TEST(!test_attr("UVWX", base33_parser, u)); + + BOOST_TEST(test(max_unsigned_base33, base33_parser)); + BOOST_TEST(test_attr(max_unsigned_base33, base33_parser, u)); + + BOOST_TEST(!test(unsigned_overflow_base33, base33_parser)); + BOOST_TEST(!test_attr(unsigned_overflow_base33, base33_parser, u)); + BOOST_TEST(!test(digit_overflow_base33, base33_parser)); + BOOST_TEST(!test_attr(digit_overflow_base33, base33_parser, u)); + } + + /////////////////////////////////////////////////////////////////////////// + // arbitrary radix test (base 34) + /////////////////////////////////////////////////////////////////////////// + { + unsigned int u; + uint_parser<unsigned int, 34, 1, -1> base34_parser; + + BOOST_TEST(test("aqxo", base34_parser)); + BOOST_TEST(test_attr("aqxo", base34_parser, u)); + BOOST_TEST(424242 == u); + + BOOST_TEST(!test("vwxy", base34_parser)); + BOOST_TEST(!test_attr("VWXY", base34_parser, u)); + + BOOST_TEST(test(max_unsigned_base34, base34_parser)); + BOOST_TEST(test_attr(max_unsigned_base34, base34_parser, u)); + + BOOST_TEST(!test(unsigned_overflow_base34, base34_parser)); + BOOST_TEST(!test_attr(unsigned_overflow_base34, base34_parser, u)); + BOOST_TEST(!test(digit_overflow_base34, base34_parser)); + BOOST_TEST(!test_attr(digit_overflow_base34, base34_parser, u)); + } + + /////////////////////////////////////////////////////////////////////////// + // arbitrary radix test (base 35) + /////////////////////////////////////////////////////////////////////////// + { + unsigned int u; + uint_parser<unsigned int, 35, 1, -1> base35_parser; + + BOOST_TEST(test("9vb7", base35_parser)); + BOOST_TEST(test_attr("9vb7", base35_parser, u)); + BOOST_TEST(424242 == u); + + BOOST_TEST(!test("wxyz", base35_parser)); + BOOST_TEST(!test_attr("WXYZ", base35_parser, u)); + + BOOST_TEST(test(max_unsigned_base35, base35_parser)); + BOOST_TEST(test_attr(max_unsigned_base35, base35_parser, u)); + + BOOST_TEST(!test(unsigned_overflow_base35, base35_parser)); + BOOST_TEST(!test_attr(unsigned_overflow_base35, base35_parser, u)); + BOOST_TEST(!test(digit_overflow_base35, base35_parser)); + BOOST_TEST(!test_attr(digit_overflow_base35, base35_parser, u)); + } + + /////////////////////////////////////////////////////////////////////////// + // arbitrary radix test (base 36) + /////////////////////////////////////////////////////////////////////////// + { + unsigned int u; + uint_parser<unsigned int, 36, 1, -1> base36_parser; + + BOOST_TEST(test("93ci", base36_parser)); + BOOST_TEST(test_attr("93ci", base36_parser, u)); + BOOST_TEST(424242 == u); + + BOOST_TEST(test(max_unsigned_base36, base36_parser)); + BOOST_TEST(test_attr(max_unsigned_base36, base36_parser, u)); + + BOOST_TEST(!test(unsigned_overflow_base36, base36_parser)); + BOOST_TEST(!test_attr(unsigned_overflow_base36, base36_parser, u)); + BOOST_TEST(!test(digit_overflow_base36, base36_parser)); + BOOST_TEST(!test_attr(digit_overflow_base36, base36_parser, u)); + } + + return boost::report_errors(); +} diff --git a/src/boost/libs/spirit/test/x3/uint_radix.hpp b/src/boost/libs/spirit/test/x3/uint_radix.hpp new file mode 100644 index 00000000..07b5638f --- /dev/null +++ b/src/boost/libs/spirit/test/x3/uint_radix.hpp @@ -0,0 +1,142 @@ +/*============================================================================= + Copyright (c) 2011 Jan Frederick Eick + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +=============================================================================*/ + +#if !defined(BOOST_SPIRIT_TEST_X3_UINT4_HPP) +#define BOOST_SPIRIT_TEST_X3_UINT4_HPP + +/////////////////////////////////////////////////////////////////////////////// +// +// *** BEWARE PLATFORM DEPENDENT!!! *** +// *** The following assumes 32 bit integers and 64 bit long longs. +// *** Modify these constant strings when appropriate. +// +/////////////////////////////////////////////////////////////////////////////// + +char const* max_unsigned_base3 = "102002022201221111210"; +char const* unsigned_overflow_base3 = "102002022201221111211"; +char const* digit_overflow_base3 = "1020020222012211112100"; + +char const* max_unsigned_base4 = "3333333333333333"; +char const* digit_overflow_base4 = "33333333333333330"; + +char const* max_unsigned_base5 = "32244002423140"; +char const* unsigned_overflow_base5 = "32244002423141"; +char const* digit_overflow_base5 = "322440024231400"; + +char const* max_unsigned_base6 = "1550104015503"; +char const* unsigned_overflow_base6 = "1550104015504"; +char const* digit_overflow_base6 = "15501040155030"; + +char const* max_unsigned_base7 = "211301422353"; +char const* unsigned_overflow_base7 = "211301422354"; +char const* digit_overflow_base7 = "2113014223530"; + +char const* max_unsigned_base9 = "12068657453"; +char const* unsigned_overflow_base9 = "12068657454"; +char const* digit_overflow_base9 = "120686574530"; + +char const* max_unsigned_base11 = "1904440553"; +char const* unsigned_overflow_base11 = "1904440554"; +char const* digit_overflow_base11 = "19044405530"; + +char const* max_unsigned_base12 = "9BA461593"; +char const* unsigned_overflow_base12 = "9BA461594"; +char const* digit_overflow_base12 = "9BA4615930"; + +char const* max_unsigned_base13 = "535A79888"; +char const* unsigned_overflow_base13 = "535A79889"; +char const* digit_overflow_base13 = "535A798880"; + +char const* max_unsigned_base14 = "2CA5B7463"; +char const* unsigned_overflow_base14 = "2CA5B7464"; +char const* digit_overflow_base14 = "2CA5B74630"; + +char const* max_unsigned_base15 = "1A20DCD80"; +char const* unsigned_overflow_base15 = "1A20DCD81"; +char const* digit_overflow_base15 = "1A20DCD800"; + +char const* max_unsigned_base17 = "A7FFDA90"; +char const* unsigned_overflow_base17 = "A7FFDA91"; +char const* digit_overflow_base17 = "A7FFDA900"; + +char const* max_unsigned_base18 = "704HE7G3"; +char const* unsigned_overflow_base18 = "704HE7G4"; +char const* digit_overflow_base18 = "704HE7G30"; + +char const* max_unsigned_base19 = "4F5AFF65"; +char const* unsigned_overflow_base19 = "4F5AFF66"; +char const* digit_overflow_base19 = "4F5AFF650"; + +char const* max_unsigned_base20 = "3723AI4F"; +char const* unsigned_overflow_base20 = "3723AI4G"; +char const* digit_overflow_base20 = "3723AI4G0"; + +char const* max_unsigned_base21 = "281D55I3"; +char const* unsigned_overflow_base21 = "281D55I4"; +char const* digit_overflow_base21 = "281D55I30"; + +char const* max_unsigned_base22 = "1FJ8B183"; +char const* unsigned_overflow_base22 = "1FJ8B184"; +char const* digit_overflow_base22 = "1FJ8B1830"; + +char const* max_unsigned_base23 = "1606K7IB"; +char const* unsigned_overflow_base23 = "1606K7IC"; +char const* digit_overflow_base23 = "1606K7IB0"; + +char const* max_unsigned_base24 = "MB994AF"; +char const* unsigned_overflow_base24 = "MB994AG"; +char const* digit_overflow_base24 = "MB994AF0"; + +char const* max_unsigned_base25 = "HEK2MGK"; +char const* unsigned_overflow_base25 = "HEK2MGL"; +char const* digit_overflow_base25 = "HEK2MGK0"; + +char const* max_unsigned_base26 = "DNCHBNL"; +char const* unsigned_overflow_base26 = "DNCHBNM"; +char const* digit_overflow_base26 = "DNCHBNL0"; + +char const* max_unsigned_base27 = "B28JPDL"; +char const* unsigned_overflow_base27 = "B28JPDM"; +char const* digit_overflow_base27 = "B28JPDL0"; + +char const* max_unsigned_base28 = "8PFGIH3"; +char const* unsigned_overflow_base28 = "8PFGIH4"; +char const* digit_overflow_base28 = "8PFGIH30"; + +char const* max_unsigned_base29 = "76BEIGF"; +char const* unsigned_overflow_base29 = "76BEIGH"; +char const* digit_overflow_base29 = "76BEIGF0"; + +char const* max_unsigned_base30 = "5QMCPQF"; +char const* unsigned_overflow_base30 = "5QMCPQG"; +char const* digit_overflow_base30 = "5QMCPQF0"; + +char const* max_unsigned_base31 = "4Q0JTO3"; +char const* unsigned_overflow_base31 = "4Q0JTO4"; +char const* digit_overflow_base31 = "4Q0JTO30"; + +char const* max_unsigned_base32 = "3VVVVVV"; +char const* unsigned_overflow_base32 = "3VVVVVW"; +char const* digit_overflow_base32 = "3VVVVVV0"; + +char const* max_unsigned_base33 = "3AOKQ93"; +char const* unsigned_overflow_base33 = "3AOKQ94"; +char const* digit_overflow_base33 = "3AOKQ930"; + +char const* max_unsigned_base34 = "2QHXJLH"; +char const* unsigned_overflow_base34 = "2QHXJLI"; +char const* digit_overflow_base34 = "2QHXJLH0"; + +char const* max_unsigned_base35 = "2BR45QA"; +char const* unsigned_overflow_base35 = "2BR45QB"; +char const* digit_overflow_base35 = "2BR45QA0"; + +char const* max_unsigned_base36 = "1Z141Z3"; +char const* unsigned_overflow_base36 = "1Z141Z4"; +char const* digit_overflow_base36 = "1Z141Z30"; + +#endif
\ No newline at end of file diff --git a/src/boost/libs/spirit/test/x3/unused_type.cpp b/src/boost/libs/spirit/test/x3/unused_type.cpp new file mode 100644 index 00000000..6a660590 --- /dev/null +++ b/src/boost/libs/spirit/test/x3/unused_type.cpp @@ -0,0 +1,34 @@ +/*============================================================================= + Copyright (c) 2019 Nikita Kniazev + + Use, modification and distribution is subject to the Boost Software + License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at + http://www.boost.org/LICENSE_1_0.txt) +=============================================================================*/ + +#include <boost/spirit/home/x3/support/unused.hpp> +#include <type_traits> + +void test_use(boost::spirit::x3::unused_type) {} + +int main() +{ + using boost::spirit::x3::unused; + using boost::spirit::x3::unused_type; + + static_assert(std::is_trivial<unused_type>::value, ""); + + unused_type unused_mut; + static_assert(std::is_same<decltype((unused)), unused_type const&>::value, ""); + static_assert(std::is_same<decltype((unused_mut)), unused_type&>::value, ""); + static_assert(std::is_same<decltype(unused = 123), unused_type const&>::value, ""); + static_assert(std::is_same<decltype(unused = unused), unused_type const&>::value, ""); + static_assert(std::is_same<decltype(unused = unused_mut), unused_type const&>::value, ""); + static_assert(std::is_same<decltype(unused_mut = 123), unused_type&>::value, ""); + static_assert(std::is_same<decltype(unused_mut = unused), unused_type&>::value, ""); + static_assert(std::is_same<decltype(unused_mut = unused_mut), unused_type&>::value, ""); + + test_use(0); + test_use(unused); + test_use(unused_mut); +} diff --git a/src/boost/libs/spirit/test/x3/utils.hpp b/src/boost/libs/spirit/test/x3/utils.hpp new file mode 100644 index 00000000..588f60de --- /dev/null +++ b/src/boost/libs/spirit/test/x3/utils.hpp @@ -0,0 +1,48 @@ +/*============================================================================= + Copyright (c) 2019 Nikita Kniazev + + Use, modification and distribution is subject to the Boost Software + License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at + http://www.boost.org/LICENSE_1_0.txt) +=============================================================================*/ +#if !defined(BOOST_SPIRIT_TEST_X3_UTILS_HPP) +#define BOOST_SPIRIT_TEST_X3_UTILS_HPP + +#include <boost/spirit/home/x3/core/parser.hpp> + +struct move_only +{ + move_only() = default; + move_only(move_only&&) = default; + move_only& operator=(move_only&&) = default; +}; + + +template <typename T> +struct synth_parser : boost::spirit::x3::parser<synth_parser<T>> +{ + typedef T attribute_type; + + static bool const has_attribute = true; + static bool const handles_container = false; + + template <typename Iterator, typename Context, + typename RuleContext, typename Attribute> + bool parse(Iterator& iter, Iterator const& last, Context const&, + RuleContext&, Attribute& attr) const + { + if (iter != last && *iter == 's') { + ++iter; + boost::spirit::x3::traits::move_to(attribute_type{}, attr); + return true; + } + return false; + } +}; + +template <typename T> +synth_parser<T> synth{}; + +synth_parser<move_only> const synth_move_only{}; + +#endif diff --git a/src/boost/libs/spirit/test/x3/with.cpp b/src/boost/libs/spirit/test/x3/with.cpp new file mode 100644 index 00000000..8160b80e --- /dev/null +++ b/src/boost/libs/spirit/test/x3/with.cpp @@ -0,0 +1,114 @@ +/*============================================================================= + Copyright (c) 2015 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +=============================================================================*/ +#include <boost/detail/lightweight_test.hpp> +#include <boost/spirit/home/x3.hpp> +#include "test.hpp" + +namespace x3 = boost::spirit::x3; + +struct my_tag; + +struct my_rule_class +{ + template <typename Iterator, typename Exception, typename Context> + x3::error_handler_result + on_error(Iterator&, Iterator const&, Exception const&, Context const& context) + { + x3::get<my_tag>(context)++; + return x3::error_handler_result::fail; + } + + template <typename Iterator, typename Attribute, typename Context> + inline void + on_success(Iterator const&, Iterator const&, Attribute&, Context const& context) + { + x3::get<my_tag>(context)++; + } +}; + +int +main() +{ + using spirit_test::test_attr; + using spirit_test::test; + + using boost::spirit::x3::rule; + using boost::spirit::x3::int_; + using boost::spirit::x3::with; + + { // injecting data into the context in the grammar + + int val = 0; + auto r = rule<my_rule_class, char const*>() = + '(' > int_ > ',' > int_ > ')' + ; + + auto start = + with<my_tag>(std::ref(val)) [ r ] + ; + + BOOST_TEST(test("(123,456)", start)); + BOOST_TEST(!test("(abc,def)", start)); + BOOST_TEST(val == 2); + } + + { // injecting non-const lvalue into the context + int val = 0; + auto const r = int_[([](auto& ctx){ + x3::get<my_tag>(ctx) += x3::_attr(ctx); + })]; + BOOST_TEST(test("123,456", with<my_tag>(val)[r % ','])); + BOOST_TEST(579 == val); + } + + { // injecting rvalue into the context + auto const r1 = int_[([](auto& ctx){ + x3::get<my_tag>(ctx) += x3::_attr(ctx); + })]; + auto const r2 = rule<struct my_rvalue_rule_class, int>() = + x3::lit('(') >> (r1 % ',') >> x3::lit(')')[([](auto& ctx){ + x3::_val(ctx) = x3::get<my_tag>(ctx); + })]; + int attr = 0; + BOOST_TEST(test_attr("(1,2,3)", with<my_tag>(100)[r2], attr)); + BOOST_TEST(106 == attr); + } + + { // injecting const/non-const lvalue and rvalue into the context + struct functor { + int operator()(int& val) { + return val * 10; // non-const ref returns 10 * injected val + } + int operator()(int const& val) { + return val; // const ref returns injected val + } + }; + + auto f = [](auto& ctx){ + x3::_val(ctx) = x3::_attr(ctx) + functor()(x3::get<my_tag>(ctx)); + }; + auto const r = rule<struct my_rule_class2, int>() = int_[f]; + + int attr = 0; + int const cval = 10; + BOOST_TEST(test_attr("5", with<my_tag>(cval)[r], attr)); + BOOST_TEST(15 == attr); // x3::get returns const ref to cval + + attr = 0; + int val = 10; + BOOST_TEST(test_attr("5", with<my_tag>(val)[r], attr)); + BOOST_TEST(105 == attr); // x3::get returns ref to val + + attr = 0; + + BOOST_TEST(test_attr("5", with<my_tag>(10)[r], attr)); + // x3::get returns ref to member variable of with_directive + BOOST_TEST(105 == attr); + } + + return boost::report_errors(); +} diff --git a/src/boost/libs/spirit/test/x3/x3_variant.cpp b/src/boost/libs/spirit/test/x3/x3_variant.cpp new file mode 100644 index 00000000..5a3f510c --- /dev/null +++ b/src/boost/libs/spirit/test/x3/x3_variant.cpp @@ -0,0 +1,57 @@ +/*============================================================================= + Copyright (c) 2001-2016 Joel de Guzman + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +=============================================================================*/ +#include <boost/detail/lightweight_test.hpp> +#include <boost/spirit/home/x3.hpp> +#include <boost/spirit/home/x3/support/ast/variant.hpp> + +#include <string> +#include <iostream> +#include "test.hpp" + +namespace x3 = boost::spirit::x3; + +struct none {}; + +using variant = x3::variant< + none + , bool + , std::string + , int + , double + >; + +struct ast : variant +{ + using variant::variant; + using variant::operator=; + + ast(char const* s) + : variant(std::string{s}) + {} + + ast& operator=(char const* s) + { + variant::operator=(std::string{s}); + return *this; + } +}; + +int +main() +{ + { + ast v{123}; + BOOST_TEST(boost::get<int>(v) == 123); + + v = "test"; + BOOST_TEST(boost::get<std::string>(v) == "test"); + + v = true; + BOOST_TEST(boost::get<bool>(v) == true); + } + return boost::report_errors(); +} |