1 /*=============================================================================
2     Copyright (c) 2001-2010 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/include/qi_operator.hpp>
9 #include <boost/spirit/include/qi_char.hpp>
10 #include <boost/spirit/include/qi_string.hpp>
11 #include <boost/spirit/include/qi_numeric.hpp>
12 #include <boost/spirit/include/qi_action.hpp>
13 #include <boost/spirit/include/qi_nonterminal.hpp>
14 #include <boost/spirit/include/support_argument.hpp>
15 #include <boost/fusion/include/vector.hpp>
16 #include <boost/fusion/include/at.hpp>
17 #include <boost/spirit/include/phoenix_core.hpp>
18 #include <boost/spirit/include/phoenix_operator.hpp>
19 #include <boost/optional.hpp>
20 
21 #include <string>
22 #include <iostream>
23 #include "test.hpp"
24 
25 using namespace spirit_test;
26 
27 int
main()28 main()
29 {
30     using boost::spirit::qi::int_;
31     using boost::spirit::qi::_1;
32     using boost::spirit::qi::_2;
33     using boost::spirit::qi::rule;
34     using boost::spirit::ascii::alpha;
35     using boost::spirit::ascii::char_;
36 
37     using boost::fusion::vector;
38     using boost::fusion::at_c;
39     using boost::optional;
40 
41     {
42         BOOST_TEST((test("a", char_('a') ^ char_('b') ^ char_('c'))));
43         BOOST_TEST((test("b", char_('a') ^ char_('b') ^ char_('c'))));
44         BOOST_TEST((test("ab", char_('a') ^ char_('b') ^ char_('c'))));
45         BOOST_TEST((test("ba", char_('a') ^ char_('b') ^ char_('c'))));
46         BOOST_TEST((test("abc", char_('a') ^ char_('b') ^ char_('c'))));
47         BOOST_TEST((test("acb", char_('a') ^ char_('b') ^ char_('c'))));
48         BOOST_TEST((test("bca", char_('a') ^ char_('b') ^ char_('c'))));
49         BOOST_TEST((test("bac", char_('a') ^ char_('b') ^ char_('c'))));
50         BOOST_TEST((test("cab", char_('a') ^ char_('b') ^ char_('c'))));
51         BOOST_TEST((test("cba", char_('a') ^ char_('b') ^ char_('c'))));
52 
53         BOOST_TEST((!test("cca", char_('a') ^ char_('b') ^ char_('c'))));
54     }
55 
56     {   // test optional must stay uninitialized
57         optional<int> i;
58         BOOST_TEST((test_attr("", -int_ ^ int_, i)));
59         BOOST_TEST(!i);
60     }
61 
62     {
63         vector<optional<int>, optional<char> > attr;
64 
65         BOOST_TEST((test_attr("a", int_ ^ alpha, attr)));
66         BOOST_TEST((!at_c<0>(attr)));
67         BOOST_TEST((at_c<1>(attr).get() == 'a'));
68 
69         at_c<1>(attr) = optional<char>(); // clear the optional
70         BOOST_TEST((test_attr("123", int_ ^ alpha, attr)));
71         BOOST_TEST((at_c<0>(attr).get() == 123));
72         BOOST_TEST((!at_c<1>(attr)));
73 
74         at_c<0>(attr) = optional<int>(); // clear the optional
75         BOOST_TEST((test_attr("123a", int_ ^ alpha, attr)));
76         BOOST_TEST((at_c<0>(attr).get() == 123));
77         BOOST_TEST((at_c<1>(attr).get() == 'a'));
78 
79         at_c<0>(attr) = optional<int>(); // clear the optional
80         at_c<1>(attr) = optional<char>(); // clear the optional
81         BOOST_TEST((test_attr("a123", int_ ^ alpha, attr)));
82         BOOST_TEST((at_c<0>(attr).get() == 123));
83         BOOST_TEST((at_c<1>(attr).get() == 'a'));
84     }
85 
86     {   // test action
87         using namespace boost::phoenix;
88         namespace phx = boost::phoenix;
89 
90         optional<int> i;
91         optional<char> c;
92 
93         BOOST_TEST((test("123a", (int_ ^ alpha)[(phx::ref(i) = _1, phx::ref(c) = _2)])));
94         BOOST_TEST((i.get() == 123));
95         BOOST_TEST((c.get() == 'a'));
96     }
97 
98     {   // test rule %=
99 
100         typedef vector<optional<int>, optional<char> > attr_type;
101         attr_type attr;
102 
103         rule<char const*, attr_type()> r;
104         r %= int_ ^ alpha;
105 
106         BOOST_TEST((test_attr("a", r, attr)));
107         BOOST_TEST((!at_c<0>(attr)));
108         BOOST_TEST((at_c<1>(attr).get() == 'a'));
109 
110         at_c<1>(attr) = optional<char>(); // clear the optional
111         BOOST_TEST((test_attr("123", r, attr)));
112         BOOST_TEST((at_c<0>(attr).get() == 123));
113         BOOST_TEST((!at_c<1>(attr)));
114 
115         at_c<0>(attr) = optional<int>(); // clear the optional
116         BOOST_TEST((test_attr("123a", r, attr)));
117         BOOST_TEST((at_c<0>(attr).get() == 123));
118         BOOST_TEST((at_c<1>(attr).get() == 'a'));
119 
120         at_c<0>(attr) = optional<int>(); // clear the optional
121         at_c<1>(attr) = optional<char>(); // clear the optional
122         BOOST_TEST((test_attr("a123", r, attr)));
123         BOOST_TEST((at_c<0>(attr).get() == 123));
124         BOOST_TEST((at_c<1>(attr).get() == 'a'));
125     }
126 
127     return boost::report_errors();
128 }
129 
130