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.
24struct 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
31private:
32 char str[2];
33};
34
35std::string get_str(char const* str)
36{
37 return std::string(str);
38}
39
40int
41main()
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

source code of boost/libs/spirit/test/qi/symbols2.cpp