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