123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501 |
- /*=============================================================================
- 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();
- }
|