summaryrefslogtreecommitdiffstats
path: root/src/boost/libs/spirit/test/support
diff options
context:
space:
mode:
Diffstat (limited to 'src/boost/libs/spirit/test/support')
-rw-r--r--src/boost/libs/spirit/test/support/Jamfile58
-rw-r--r--src/boost/libs/spirit/test/support/istream_iterator_basic.cpp60
-rw-r--r--src/boost/libs/spirit/test/support/regression_line_pos_iterator.cpp149
-rw-r--r--src/boost/libs/spirit/test/support/regression_multi_pass_error_handler.cpp65
-rw-r--r--src/boost/libs/spirit/test/support/regression_multi_pass_functor.cpp107
-rw-r--r--src/boost/libs/spirit/test/support/regression_multi_pass_parse.cpp61
-rw-r--r--src/boost/libs/spirit/test/support/regression_multi_pass_position_iterator.cpp31
-rw-r--r--src/boost/libs/spirit/test/support/unused_type.cpp45
-rw-r--r--src/boost/libs/spirit/test/support/utree.cpp501
-rw-r--r--src/boost/libs/spirit/test/support/utree_debug.cpp29
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();
+}