1 /*=============================================================================
2     Copyright (c) 2001-2010 Joel de Guzman
3 
4     Distributed under the Boost Software License, Version 1.0. (See accompanying
5     file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6 =============================================================================*/
7 #include <string>
8 #include <vector>
9 
10 #include <boost/detail/lightweight_test.hpp>
11 #include <boost/utility/enable_if.hpp>
12 
13 #include <boost/spirit/include/qi_operator.hpp>
14 #include <boost/spirit/include/qi_char.hpp>
15 #include <boost/spirit/include/qi_string.hpp>
16 #include <boost/spirit/include/qi_numeric.hpp>
17 #include <boost/spirit/include/qi_directive.hpp>
18 #include <boost/spirit/include/qi_action.hpp>
19 #include <boost/spirit/include/support_argument.hpp>
20 #include <boost/spirit/include/phoenix_core.hpp>
21 #include <boost/spirit/include/phoenix_operator.hpp>
22 
23 #include <string>
24 #include <iostream>
25 #include "test.hpp"
26 
27 struct x_attr
28 {
29 };
30 
31 namespace boost { namespace spirit { namespace traits
32 {
33     template <>
34     struct container_value<x_attr>
35     {
36         typedef char type; // value type of container
37     };
38 
39     template <>
40     struct push_back_container<x_attr, char>
41     {
callboost::spirit::traits::push_back_container42         static bool call(x_attr& /*c*/, char /*val*/)
43         {
44             // push back value type into container
45             return true;
46         }
47     };
48 }}}
49 
50 int
main()51 main()
52 {
53     using spirit_test::test;
54     using spirit_test::test_attr;
55     using namespace boost::spirit::ascii;
56     using boost::spirit::qi::int_;
57     using boost::spirit::qi::omit;
58     using boost::spirit::qi::lit;
59     using boost::spirit::qi::_1;
60     using boost::spirit::qi::lexeme;
61 
62     {
63         BOOST_TEST(test("aaaaaaaa", +char_));
64         BOOST_TEST(test("a", +char_));
65         BOOST_TEST(!test("", +char_));
66         BOOST_TEST(test("aaaaaaaa", +alpha));
67         BOOST_TEST(!test("aaaaaaaa", +upper));
68     }
69 
70     {
71         BOOST_TEST(test(" a a aaa aa", +char_, space));
72         BOOST_TEST(test("12345 678 9 ", +digit, space));
73     }
74 
75     {
76         BOOST_TEST(test("aBcdeFGH", no_case[+char_]));
77         BOOST_TEST(test("a B cde FGH  ", no_case[+char_], space));
78     }
79 
80     {
81         std::vector<int> v;
82         BOOST_TEST(test_attr("123 456 789 10", +int_, v, space) && 4 == v.size() &&
83             v[0] == 123 && v[1] == 456 && v[2] == 789 &&  v[3] == 10);
84     }
85 
86     {
87         std::vector<std::string> v;
88         BOOST_TEST(test_attr("a b c d", +lexeme[+alpha], v, space) && 4 == v.size() &&
89             v[0] == "a" && v[1] == "b" && v[2] == "c" &&  v[3] == "d");
90     }
91 
92     {
93         BOOST_TEST(test("Kim Kim Kim", +lit("Kim"), space));
94     }
95 
96     {
97         // The following 2 tests show that omit does not inhibit explicit attributes
98 
99         std::string s;
100         BOOST_TEST(test_attr("bbbb", omit[+char_('b')], s) && s == "bbbb");
101 
102         s.clear();
103         BOOST_TEST(test_attr("b b b b ", omit[+char_('b')], s, space) && s == "bbbb");
104     }
105 
106     { // actions
107         namespace phx = boost::phoenix;
108 
109         std::vector<char> v;
110         BOOST_TEST(test("bbbb", (+char_)[phx::ref(v) = _1]) && 4 == v.size() &&
111             v[0] == 'b' && v[1] == 'b' && v[2] == 'b' &&  v[3] == 'b');
112     }
113 
114     { // more actions
115         namespace phx = boost::phoenix;
116 
117         std::vector<int> v;
118         BOOST_TEST(test("1 2 3", (+int_)[phx::ref(v) = _1], space) && 3 == v.size() &&
119             v[0] == 1 && v[1] == 2 && v[2] == 3);
120     }
121 
122     { // attribute customization
123 
124         x_attr x;
125         test_attr("abcde", +char_, x);
126     }
127 
128     return boost::report_errors();
129 }
130 
131