diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 18:45:59 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 18:45:59 +0000 |
commit | 19fcec84d8d7d21e796c7624e521b60d28ee21ed (patch) | |
tree | 42d26aa27d1e3f7c0b8bd3fd14e7d7082f5008dc /src/boost/libs/spirit/test/support | |
parent | Initial commit. (diff) | |
download | ceph-upstream.tar.xz ceph-upstream.zip |
Adding upstream version 16.2.11+ds.upstream/16.2.11+dsupstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/boost/libs/spirit/test/support')
10 files changed, 1106 insertions, 0 deletions
diff --git a/src/boost/libs/spirit/test/support/Jamfile b/src/boost/libs/spirit/test/support/Jamfile new file mode 100644 index 000000000..cd928e949 --- /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 000000000..136a38f15 --- /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 000000000..4c6ca79f0 --- /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 000000000..dd2eb9c6a --- /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 000000000..d95ac2582 --- /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 000000000..1ccbf1d65 --- /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 000000000..6df9d2f47 --- /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 000000000..845205328 --- /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 000000000..2b9b038ca --- /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 000000000..ebf44c4aa --- /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(); +} |