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