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