1// Copyright (c) 2001-2011 Hartmut Kaiser
2//
3// Distributed under the Boost Software License, Version 1.0. (See accompanying
4// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
5
6#include <boost/spirit/include/qi_auto.hpp>
7
8#include <boost/fusion/include/std_pair.hpp>
9#include <boost/algorithm/string/predicate.hpp>
10
11#include <boost/spirit/include/qi_bool.hpp>
12#include <boost/spirit/include/qi_char.hpp>
13#include <boost/spirit/include/qi_numeric.hpp>
14#include <boost/spirit/include/qi_string.hpp>
15#include <boost/spirit/include/qi_nonterminal.hpp>
16#include <boost/spirit/include/qi_operator.hpp>
17#include <boost/spirit/include/qi_directive.hpp>
18
19#include "test.hpp"
20
21namespace qi = boost::spirit::qi;
22namespace traits = boost::spirit::traits;
23
24///////////////////////////////////////////////////////////////////////////////
25template <typename Char, typename T>
26bool test_create_parser(Char const *in, T& t)
27{
28 Char const* last = in;
29 while (*last)
30 last++;
31
32 BOOST_TEST((traits::meta_create_exists<qi::domain, T>::value));
33 return qi::phrase_parse(in, last, qi::create_parser<T>(), qi::space, t);
34}
35
36template <typename Char, typename T>
37bool test_create_parser_auto(Char const *in, T& t)
38{
39 Char const* last = in;
40 while (*last)
41 last++;
42
43 BOOST_TEST((traits::meta_create_exists<qi::domain, T>::value));
44 return qi::phrase_parse(in, last, t, qi::space);
45}
46
47template <typename Char, typename Attribute>
48bool test_rule(Char const* in, Attribute const& expected)
49{
50 BOOST_TEST((traits::meta_create_exists<qi::domain, Attribute>::value));
51
52 Attribute attr = Attribute();
53 qi::rule<Char const*, Attribute()> r = qi::create_parser<Attribute>();
54 return spirit_test::test_attr(in, r, attr) && attr == expected;
55}
56
57template <typename Char, typename Attribute, typename Skipper>
58bool test_rule(Char const* in, Attribute const& expected, Skipper const& skipper)
59{
60 BOOST_TEST((traits::meta_create_exists<qi::domain, Attribute>::value));
61
62 Attribute attr = Attribute();
63 qi::rule<Char const*, Attribute(), Skipper> r = qi::create_parser<Attribute>();
64 return spirit_test::test_attr(in, r, attr, skipper) && attr == expected;
65}
66
67struct my_type {};
68
69///////////////////////////////////////////////////////////////////////////////
70int main()
71{
72 {
73 BOOST_TEST((!traits::meta_create_exists<qi::domain, my_type>::value));
74 }
75
76 {
77 // test primitive types
78 bool b = false;
79 BOOST_TEST(test_create_parser("true", b) && b == true);
80 int i = 0;
81 BOOST_TEST(test_create_parser("1", i) && i == 1);
82 double d = 0;
83 BOOST_TEST(test_create_parser("1.1", d) && d == 1.1);
84 char c = '\0';
85 BOOST_TEST(test_create_parser("a", c) && c == 'a');
86 wchar_t wc = L'\0';
87 BOOST_TEST(test_create_parser(L"a", wc) && wc == L'a');
88
89 // test containers
90 std::vector<int> v;
91 BOOST_TEST(test_create_parser("0 1 2", v) && v.size() == 3 &&
92 v[0] == 0 && v[1] == 1 && v[2] == 2);
93
94 std::list<int> l;
95 BOOST_TEST(test_create_parser("0 1 2", l) && l.size() == 3 &&
96 *l.begin() == 0 && *(++l.begin()) == 1 && *(++ ++l.begin()) == 2);
97
98 // test optional
99 boost::optional<int> o;
100 BOOST_TEST(test_create_parser("", o) && !o);
101 BOOST_TEST(test_create_parser("1", o) && !!o && boost::get<int>(o) == 1);
102
103 // test alternative
104 boost::variant<double, bool, std::vector<char> > vv;
105 BOOST_TEST(test_create_parser("true", vv) && vv.which() == 1 &&
106 boost::get<bool>(vv) == true);
107 BOOST_TEST(test_create_parser("1.0", vv) && vv.which() == 0 &&
108 boost::get<double>(vv) == 1.0);
109 BOOST_TEST(test_create_parser("some_string", vv) && vv.which() == 2 &&
110 boost::equals(boost::get<std::vector<char> >(vv), "some_string"));
111
112 // test fusion sequence
113 std::pair<int, double> p;
114 BOOST_TEST(test_create_parser("1 2.0", p) &&
115 p.first == 1 && p.second == 2.0);
116 }
117
118 {
119 // test containers
120 std::vector<int> v;
121 BOOST_TEST(test_create_parser_auto("0 1 2", v) && v.size() == 3 &&
122 v[0] == 0 && v[1] == 1 && v[2] == 2);
123
124 std::list<int> l;
125 BOOST_TEST(test_create_parser_auto("0 1 2", l) && l.size() == 3 &&
126 *l.begin() == 0 && *(++l.begin()) == 1 && *(++ ++l.begin()) == 2);
127
128 // test optional
129 boost::optional<int> o;
130 BOOST_TEST(test_create_parser_auto("", o) && !o);
131 BOOST_TEST(test_create_parser_auto("1", o) && !!o && boost::get<int>(o) == 1);
132
133 // test alternative
134 boost::variant<double, bool, std::vector<char> > vv;
135 BOOST_TEST(test_create_parser_auto("true", vv) && vv.which() == 1 &&
136 boost::get<bool>(vv) == true);
137 BOOST_TEST(test_create_parser_auto("1.0", vv) && vv.which() == 0 &&
138 boost::get<double>(vv) == 1.0);
139 BOOST_TEST(test_create_parser_auto("some_string", vv) && vv.which() == 2 &&
140 boost::equals(boost::get<std::vector<char> >(vv), "some_string"));
141
142 // test fusion sequence
143 std::pair<int, double> p;
144 BOOST_TEST(test_create_parser_auto("1 2.0", p) &&
145 p.first == 1 && p.second == 2.0);
146 }
147
148 {
149 using qi::auto_;
150 using qi::no_case;
151 using spirit_test::test_attr;
152
153 // test primitive types
154 bool b = false;
155 BOOST_TEST(test_attr("true", auto_, b) && b == true);
156 int i = 0;
157 BOOST_TEST(test_attr("1", auto_, i) && i == 1);
158 double d = 0;
159 BOOST_TEST(test_attr("1.1", auto_, d) && d == 1.1);
160 char c = '\0';
161 BOOST_TEST(test_attr("a", auto_, c) && c == 'a');
162 wchar_t wc = L'\0';
163 BOOST_TEST(test_attr(L"a", auto_, wc) && wc == L'a');
164
165 b = false;
166 BOOST_TEST(test_attr("TRUE", no_case[auto_], b) && b == true);
167
168 // test containers
169 std::vector<int> v;
170 BOOST_TEST(test_attr("0 1 2", auto_, v, qi::space) && v.size() == 3 &&
171 v[0] == 0 && v[1] == 1 && v[2] == 2);
172 v.clear();
173 BOOST_TEST(test_attr("0,1,2", auto_ % ',', v) && v.size() == 3 &&
174 v[0] == 0 && v[1] == 1 && v[2] == 2);
175
176 std::list<int> l;
177 BOOST_TEST(test_attr("0 1 2", auto_, l, qi::space) && l.size() == 3 &&
178 *l.begin() == 0 && *(++l.begin()) == 1 && *(++ ++l.begin()) == 2);
179 l.clear();
180 BOOST_TEST(test_attr("0,1,2", auto_ % ',', l) && l.size() == 3 &&
181 *l.begin() == 0 && *(++l.begin()) == 1 && *(++ ++l.begin()) == 2);
182
183 // test optional
184 boost::optional<int> o;
185 BOOST_TEST(test_attr("", auto_, o) && !o);
186 BOOST_TEST(test_attr("1", auto_, o) && !!o && boost::get<int>(o) == 1);
187
188 // test alternative
189 boost::variant<double, bool, std::vector<char> > vv;
190 BOOST_TEST(test_attr("true", auto_, vv) && vv.which() == 1 &&
191 boost::get<bool>(vv) == true);
192 BOOST_TEST(test_attr("1.0", auto_, vv) && vv.which() == 0 &&
193 boost::get<double>(vv) == 1.0);
194 BOOST_TEST(test_create_parser("some_string", vv) && vv.which() == 2 &&
195 boost::equals(boost::get<std::vector<char> >(vv), "some_string"));
196
197 // test fusion sequence
198 std::pair<int, double> p;
199 BOOST_TEST(test_attr("1 2.0", auto_, p, qi::space) &&
200 p.first == 1 && p.second == 2.0);
201 }
202
203 {
204 // test primitive types
205 BOOST_TEST(test_rule("true", true));
206 BOOST_TEST(test_rule("1", 1));
207 BOOST_TEST(test_rule("1.1", 1.1));
208
209 // test containers
210 std::vector<int> v;
211 v.push_back(x: 0);
212 v.push_back(x: 1);
213 v.push_back(x: 2);
214 BOOST_TEST(test_rule("0 1 2", v, qi::space));
215
216 std::list<int> l;
217 l.push_back(x: 0);
218 l.push_back(x: 1);
219 l.push_back(x: 2);
220 BOOST_TEST(test_rule("0 1 2", l, qi::space));
221
222 // test optional
223 boost::optional<int> o;
224 BOOST_TEST(test_rule("", o));
225 o = 1;
226 BOOST_TEST(test_rule("1", o));
227
228 // test alternative
229// boost::variant<int, double, float, std::string> vv;
230// vv = 1;
231// BOOST_TEST(test_rule("1", vv));
232// vv = 1.0;
233// BOOST_TEST(test_rule("1.0", vv));
234// vv = 1.0f;
235// BOOST_TEST(test_rule("1.0", vv));
236// vv = "some string";
237// BOOST_TEST(test_rule("some string", vv));
238
239 // test fusion sequence
240 std::pair<int, double> p (1, 2.0);
241 BOOST_TEST(test_rule("1 2.0", p, qi::space));
242 }
243
244 {
245 // test literal char interference
246 using spirit_test::test;
247 BOOST_TEST(test("x", 'x'));
248 BOOST_TEST(test("x", 'x', qi::space));
249 BOOST_TEST(!test("y", 'x'));
250 BOOST_TEST(!test("y", 'x', qi::space));
251 BOOST_TEST(test(L"x", L'x'));
252 BOOST_TEST(test(L"x", L'x', qi::space));
253 BOOST_TEST(!test(L"y", L'x'));
254 BOOST_TEST(!test(L"y", L'x', qi::space));
255 }
256
257 return boost::report_errors();
258}
259

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