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