1 | /*============================================================================= |
2 | Copyright (c) 2001-2011 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 <boost/spirit/include/qi_symbols.hpp> |
8 | |
9 | #include <boost/spirit/include/qi_string.hpp> |
10 | #include <boost/spirit/include/qi_char.hpp> |
11 | #include <boost/spirit/include/qi_action.hpp> |
12 | #include <boost/spirit/include/qi_auxiliary.hpp> |
13 | #include <boost/spirit/include/qi_directive.hpp> |
14 | #include <boost/spirit/include/qi_operator.hpp> |
15 | #include <boost/spirit/include/qi_nonterminal.hpp> |
16 | #include <boost/spirit/include/support_argument.hpp> |
17 | #include <boost/phoenix/core.hpp> |
18 | #include <boost/phoenix/operator.hpp> |
19 | |
20 | #include <iostream> |
21 | #include "test.hpp" |
22 | |
23 | // Custom string type with a C-style string conversion. |
24 | struct custom_string_c |
25 | { |
26 | custom_string_c(char c) { str[0] = c; str[1] = '\0'; } |
27 | |
28 | operator char*() { return str; } |
29 | operator char const*() const { return str; } |
30 | |
31 | private: |
32 | char str[2]; |
33 | }; |
34 | |
35 | std::string get_str(char const* str) |
36 | { |
37 | return std::string(str); |
38 | } |
39 | |
40 | int |
41 | main() |
42 | { |
43 | using spirit_test::test; |
44 | using spirit_test::test_attr; |
45 | using boost::spirit::qi::symbols; |
46 | using boost::spirit::qi::rule; |
47 | using boost::spirit::qi::lazy; |
48 | using boost::spirit::qi::_r1; |
49 | |
50 | { // construction from symbol array |
51 | char const* syms[] = {"Joel" ,"Ruby" ,"Tenji" ,"Tutit" ,"Kim" ,"Joey" }; |
52 | symbols<char, int> sym(syms); |
53 | |
54 | BOOST_TEST((test("Joel" , sym))); |
55 | BOOST_TEST((test("Ruby" , sym))); |
56 | BOOST_TEST((test("Tenji" , sym))); |
57 | BOOST_TEST((test("Tutit" , sym))); |
58 | BOOST_TEST((test("Kim" , sym))); |
59 | BOOST_TEST((test("Joey" , sym))); |
60 | BOOST_TEST((!test("XXX" , sym))); |
61 | } |
62 | |
63 | { // construction from 2 arrays |
64 | |
65 | char const* syms[] = {"Joel" ,"Ruby" ,"Tenji" ,"Tutit" ,"Kim" ,"Joey" }; |
66 | int data[] = {1,2,3,4,5,6}; |
67 | symbols<char, int> sym(syms, data); |
68 | |
69 | int i; |
70 | BOOST_TEST((test_attr("Joel" , sym, i))); |
71 | BOOST_TEST(i == 1); |
72 | BOOST_TEST((test_attr("Ruby" , sym, i))); |
73 | BOOST_TEST(i == 2); |
74 | BOOST_TEST((test_attr("Tenji" , sym, i))); |
75 | BOOST_TEST(i == 3); |
76 | BOOST_TEST((test_attr("Tutit" , sym, i))); |
77 | BOOST_TEST(i == 4); |
78 | BOOST_TEST((test_attr("Kim" , sym, i))); |
79 | BOOST_TEST(i == 5); |
80 | BOOST_TEST((test_attr("Joey" , sym, i))); |
81 | BOOST_TEST(i == 6); |
82 | BOOST_TEST((!test_attr("XXX" , sym, i))); |
83 | } |
84 | |
85 | { // allow std::string and other string types |
86 | symbols<> sym; |
87 | |
88 | // const and non-const std::string |
89 | std::string a("abc" ); |
90 | std::string const b("def" ); |
91 | sym += a; |
92 | sym += b; |
93 | BOOST_TEST((test("abc" , sym))); |
94 | BOOST_TEST((test("def" , sym))); |
95 | sym = a; |
96 | BOOST_TEST((test("abc" , sym))); |
97 | BOOST_TEST((!test("def" , sym))); |
98 | |
99 | // non-const C-style string |
100 | char arr[2]; arr[0] = 'a'; arr[1] = '\0'; |
101 | sym = arr; |
102 | BOOST_TEST((test("a" , sym))); |
103 | BOOST_TEST((!test("b" , sym))); |
104 | |
105 | // const and non-const custom string type |
106 | custom_string_c c('x'); |
107 | custom_string_c const cc('y'); |
108 | sym = c, cc; |
109 | BOOST_TEST((test("x" , sym))); |
110 | BOOST_TEST((test("y" , sym))); |
111 | BOOST_TEST((!test("z" , sym))); |
112 | } |
113 | |
114 | { |
115 | namespace phx = boost::phoenix; |
116 | |
117 | symbols<char, int> sym; |
118 | sym.add |
119 | ("a" , 1) |
120 | ("b" , 2) |
121 | ; |
122 | |
123 | rule<char const*, int(symbols<char, int>&)> r; |
124 | r %= lazy(f: _r1); |
125 | |
126 | int i = 0; |
127 | BOOST_TEST(test_attr("a" , r(phx::ref(sym)), i)); |
128 | BOOST_TEST(i == 1); |
129 | BOOST_TEST(test_attr("b" , r(phx::ref(sym)), i)); |
130 | BOOST_TEST(i == 2); |
131 | BOOST_TEST(!test("c" , r(phx::ref(sym)))); |
132 | } |
133 | |
134 | { // find |
135 | |
136 | symbols<char, int> sym; |
137 | sym.add("a" , 1)("b" , 2); |
138 | |
139 | BOOST_TEST(!sym.find("c" )); |
140 | |
141 | BOOST_TEST(sym.find("a" ) && *sym.find("a" ) == 1); |
142 | BOOST_TEST(sym.find("b" ) && *sym.find("b" ) == 2); |
143 | |
144 | BOOST_TEST(sym.at("a" ) == 1); |
145 | BOOST_TEST(sym.at("b" ) == 2); |
146 | BOOST_TEST(sym.at("c" ) == 0); |
147 | |
148 | BOOST_TEST(sym.find("a" ) && *sym.find("a" ) == 1); |
149 | BOOST_TEST(sym.find("b" ) && *sym.find("b" ) == 2); |
150 | BOOST_TEST(sym.find("c" ) && *sym.find("c" ) == 0); |
151 | |
152 | symbols<char, int> const_sym(sym); |
153 | |
154 | BOOST_TEST(const_sym.find("a" ) && *const_sym.find("a" ) == 1); |
155 | BOOST_TEST(const_sym.find("b" ) && *const_sym.find("b" ) == 2); |
156 | BOOST_TEST(const_sym.find("c" ) && *const_sym.find("c" ) == 0); |
157 | BOOST_TEST(!const_sym.find("d" )); |
158 | |
159 | char const *str1 = "all" ; |
160 | char const *first = str1, *last = str1 + 3; |
161 | BOOST_TEST(*sym.prefix_find(first, last) == 1 && first == str1 + 1); |
162 | |
163 | char const *str2 = "dart" ; |
164 | first = str2; last = str2 + 4; |
165 | BOOST_TEST(!sym.prefix_find(first, last) && first == str2); |
166 | } |
167 | |
168 | { // name |
169 | symbols <char, int> sym,sym2; |
170 | sym.name(str: "test" ); |
171 | BOOST_TEST(sym.name()=="test" ); |
172 | sym2 = sym; |
173 | BOOST_TEST(sym2.name()=="test" ); |
174 | |
175 | symbols <char,int> sym3(sym); |
176 | BOOST_TEST(sym3.name()=="test" ); |
177 | } |
178 | |
179 | { // Substrings |
180 | |
181 | symbols<char, int> sym; |
182 | BOOST_TEST(sym.at("foo" ) == 0); |
183 | sym.at(str: "foo" ) = 1; |
184 | BOOST_TEST(sym.at("foo" ) == 1); |
185 | BOOST_TEST(sym.at("fool" ) == 0); |
186 | sym.at(str: "fool" ) = 2; |
187 | BOOST_TEST(sym.find("foo" ) && *sym.find("foo" ) == 1); |
188 | BOOST_TEST(sym.find("fool" ) && *sym.find("fool" ) == 2); |
189 | BOOST_TEST(!sym.find("foolish" )); |
190 | BOOST_TEST(!sym.find("foot" )); |
191 | BOOST_TEST(!sym.find("afoot" )); |
192 | |
193 | char const *str, *first, *last; |
194 | str = "foolish" ; first = str; last = str + 7; |
195 | BOOST_TEST(*sym.prefix_find(first, last) == 2 && first == str + 4); |
196 | |
197 | first = str; last = str + 4; |
198 | BOOST_TEST(*sym.prefix_find(first, last) == 2 && first == str + 4); |
199 | |
200 | str = "food" ; first = str; last = str + 4; |
201 | BOOST_TEST(*sym.prefix_find(first, last) == 1 && first == str + 3); |
202 | |
203 | first = str; last = str + 3; |
204 | BOOST_TEST(*sym.prefix_find(first, last) == 1 && first == str + 3); |
205 | |
206 | first = str; last = str + 2; |
207 | BOOST_TEST(!sym.prefix_find(first, last) && first == str); |
208 | } |
209 | |
210 | { |
211 | // remove bug |
212 | |
213 | std::string s; |
214 | symbols<char, double> vars; |
215 | |
216 | vars.add("l1" , 12.0); |
217 | vars.add("l2" , 0.0); |
218 | vars.remove("l2" ); |
219 | vars.find(str: "l1" ); |
220 | double* d = vars.find(str: "l1" ); |
221 | BOOST_TEST(d != 0); |
222 | } |
223 | |
224 | { // test for proto problem with rvalue references (10-11-2011) |
225 | symbols<char, int> sym; |
226 | sym += get_str(str: "Joel" ); |
227 | sym += get_str(str: "Ruby" ); |
228 | |
229 | BOOST_TEST((test("Joel" , sym))); |
230 | BOOST_TEST((test("Ruby" , sym))); |
231 | } |
232 | |
233 | return boost::report_errors(); |
234 | } |
235 | |