]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
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 | ||
1e59de90 | 6 | #include <boost/spirit/include/karma_plus.hpp> |
7c673cae FG |
7 | |
8 | #include <boost/spirit/include/karma_char.hpp> | |
9 | #include <boost/spirit/include/karma_string.hpp> | |
10 | #include <boost/spirit/include/karma_numeric.hpp> | |
11 | #include <boost/spirit/include/karma_generate.hpp> | |
12 | #include <boost/spirit/include/karma_operator.hpp> | |
13 | #include <boost/spirit/include/karma_action.hpp> | |
14 | #include <boost/spirit/include/karma_nonterminal.hpp> | |
15 | #include <boost/spirit/include/karma_auxiliary.hpp> | |
16 | #include <boost/spirit/include/karma_directive.hpp> | |
1e59de90 TL |
17 | |
18 | #include <boost/assign/std/vector.hpp> | |
7c673cae | 19 | #include <boost/fusion/include/vector.hpp> |
1e59de90 TL |
20 | #include <boost/phoenix/core.hpp> |
21 | #include <boost/phoenix/operator.hpp> | |
7c673cae FG |
22 | #include <boost/fusion/include/std_pair.hpp> |
23 | ||
24 | #include "test.hpp" | |
25 | ||
26 | using namespace spirit_test; | |
27 | ||
28 | /////////////////////////////////////////////////////////////////////////////// | |
29 | struct action | |
30 | { | |
31 | action (std::vector<char>& vec) | |
32 | : vec(vec), it(vec.begin()) | |
33 | {} | |
34 | ||
35 | void operator()(unsigned& value, boost::spirit::unused_type, bool& pass) const | |
36 | { | |
37 | pass = (it != vec.end()); | |
38 | if (pass) | |
39 | value = *it++; | |
40 | } | |
41 | ||
42 | std::vector<char>& vec; | |
43 | mutable std::vector<char>::iterator it; | |
44 | }; | |
45 | ||
46 | /////////////////////////////////////////////////////////////////////////////// | |
47 | int main() | |
48 | { | |
49 | using namespace boost::spirit; | |
50 | using namespace boost::spirit::ascii; | |
51 | namespace fusion = boost::fusion; | |
52 | ||
53 | { | |
54 | std::string s1("aaaa"); | |
55 | BOOST_TEST(test("aaaa", +char_, s1)); | |
56 | BOOST_TEST(test_delimited("a a a a ", +char_, s1, ' ')); | |
57 | ||
58 | std::string s2("a"); | |
59 | BOOST_TEST(test("a", +char_, s2)); | |
60 | BOOST_TEST(test_delimited("a ", +char_, s2, ' ')); | |
61 | ||
62 | std::string s3(""); | |
63 | BOOST_TEST(!test("", +char_, s2)); | |
64 | BOOST_TEST(!test_delimited("", +char_, s3, ' ')); | |
65 | } | |
66 | ||
67 | { | |
68 | std::string s1("aaaaa"); | |
69 | BOOST_TEST(test("aaaaa", char_ << +(char_ << char_), s1)); | |
70 | BOOST_TEST(test_delimited("a a a a a ", | |
71 | char_ << +(char_ << char_), s1, ' ')); | |
72 | ||
73 | s1 = "a"; | |
74 | BOOST_TEST(!test("", char_ << +(char_ << char_), s1)); | |
75 | s1 = "aa"; | |
76 | BOOST_TEST(!test("", char_ << +(char_ << char_), s1)); | |
77 | s1 = "aaaa"; | |
78 | BOOST_TEST(!test("", char_ << +(char_ << char_), s1)); | |
79 | } | |
80 | ||
81 | { | |
82 | using boost::spirit::karma::strict; | |
83 | using boost::spirit::karma::relaxed; | |
84 | using namespace boost::assign; | |
85 | ||
86 | typedef std::pair<char, char> data; | |
87 | std::vector<data> v1; | |
88 | v1 += std::make_pair('a', 'a'), | |
89 | std::make_pair('b', 'b'), | |
90 | std::make_pair('c', 'c'), | |
91 | std::make_pair('d', 'd'), | |
92 | std::make_pair('e', 'e'), | |
93 | std::make_pair('f', 'f'), | |
94 | std::make_pair('g', 'g'); | |
95 | ||
96 | karma::rule<spirit_test::output_iterator<char>::type, data()> r; | |
97 | r = &char_('a') << char_; | |
98 | ||
99 | BOOST_TEST(!test("", r << +(r << r), v1)); | |
100 | BOOST_TEST(!test("", relaxed[r << +(r << r)], v1)); | |
101 | BOOST_TEST(!test("", strict[r << +(r << r)], v1)); | |
102 | ||
103 | v1 += std::make_pair('a', 'a'); | |
104 | ||
105 | BOOST_TEST(!test("", r << *(r << r), v1)); | |
106 | BOOST_TEST(!test("", relaxed[r << +(r << r)], v1)); | |
107 | BOOST_TEST(!test("", strict[r << +(r << r)], v1)); | |
108 | ||
109 | v1 += std::make_pair('a', 'a'); | |
110 | ||
111 | BOOST_TEST(test("aaa", r << +(r << r), v1)); | |
112 | BOOST_TEST(test("aaa", relaxed[r << +(r << r)], v1)); | |
113 | BOOST_TEST(!test("", strict[r << +(r << r)], v1)); | |
114 | } | |
115 | ||
116 | { | |
117 | using namespace boost::assign; | |
118 | ||
119 | std::vector<char> v; | |
120 | v += 'a', 'b', 'c'; | |
121 | ||
122 | BOOST_TEST(test("abc", +char_, v)); | |
123 | BOOST_TEST(test_delimited("a b c ", +char_, v, ' ')); | |
124 | } | |
125 | ||
126 | { | |
127 | using namespace boost::assign; | |
128 | ||
129 | std::vector<int> v; | |
130 | v += 10, 20, 30; | |
131 | ||
132 | BOOST_TEST(test("102030", +int_, v)); | |
133 | BOOST_TEST(test_delimited("10, 20, 30, ", +int_, v, lit(", "))); | |
134 | ||
135 | BOOST_TEST(test("10,20,30,", +(int_ << ','), v)); | |
136 | BOOST_TEST(test_delimited("10 , 20 , 30 , ", +(int_ << ','), v, lit(' '))); | |
137 | ||
138 | // leads to infinite loops | |
139 | // fusion::vector<char, char> cc ('a', 'c'); | |
140 | // BOOST_TEST(test("ac", char_ << !+(lit(' ') << ',') << char_, cc)); | |
141 | // BOOST_TEST(test_delimited("a c ", | |
142 | // char_ << !+(lit(' ') << ',') << char_, cc, " ")); | |
143 | } | |
144 | ||
145 | { // actions | |
146 | using namespace boost::assign; | |
147 | namespace phx = boost::phoenix; | |
148 | ||
149 | std::vector<char> v; | |
150 | v += 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'; | |
151 | ||
152 | BOOST_TEST(test("abcdefgh", (+char_)[_1 = phx::ref(v)])); | |
153 | BOOST_TEST(test_delimited("a b c d e f g h ", | |
154 | (+char_ )[_1 = phx::ref(v)], space)); | |
155 | } | |
156 | ||
157 | // failing sub-generators | |
158 | { | |
159 | using boost::spirit::karma::strict; | |
160 | using boost::spirit::karma::relaxed; | |
161 | ||
162 | using namespace boost::assign; | |
163 | ||
164 | typedef std::pair<char, char> data; | |
165 | std::vector<data> v2; | |
166 | v2 += std::make_pair('a', 'a'), | |
167 | std::make_pair('b', 'b'), | |
168 | std::make_pair('c', 'c'), | |
169 | std::make_pair('d', 'd'), | |
170 | std::make_pair('e', 'e'), | |
171 | std::make_pair('f', 'f'), | |
172 | std::make_pair('g', 'g'); | |
173 | ||
174 | karma::rule<spirit_test::output_iterator<char>::type, data()> r; | |
175 | ||
176 | r = &char_('d') << char_; | |
177 | BOOST_TEST(test("d", +r, v2)); | |
178 | BOOST_TEST(test("d", relaxed[+r], v2)); | |
179 | BOOST_TEST(!test("", strict[+r], v2)); | |
180 | ||
181 | r = &char_('a') << char_; | |
182 | BOOST_TEST(test("a", +r, v2)); | |
183 | BOOST_TEST(test("a", relaxed[+r], v2)); | |
184 | BOOST_TEST(test("a", strict[+r], v2)); | |
185 | ||
186 | r = &char_('g') << char_; | |
187 | BOOST_TEST(test("g", +r, v2)); | |
188 | BOOST_TEST(test("g", relaxed[+r], v2)); | |
189 | BOOST_TEST(!test("", strict[+r], v2)); | |
190 | ||
191 | r = !char_('d') << char_; | |
192 | BOOST_TEST(test("abcefg", +r, v2)); | |
193 | BOOST_TEST(test("abcefg", relaxed[+r], v2)); | |
194 | BOOST_TEST(test("abc", strict[+r], v2)); | |
195 | ||
196 | r = !char_('a') << char_; | |
197 | BOOST_TEST(test("bcdefg", +r, v2)); | |
198 | BOOST_TEST(test("bcdefg", relaxed[+r], v2)); | |
199 | BOOST_TEST(!test("", strict[+r], v2)); | |
200 | ||
201 | r = !char_('g') << char_; | |
202 | BOOST_TEST(test("abcdef", +r, v2)); | |
203 | BOOST_TEST(test("abcdef", +r, v2)); | |
204 | BOOST_TEST(test("abcdef", +r, v2)); | |
205 | ||
206 | r = &char_('A') << char_; | |
207 | BOOST_TEST(!test("", +r, v2)); | |
208 | } | |
209 | ||
210 | { | |
211 | // make sure user defined end condition is applied if no attribute | |
212 | // is passed in | |
213 | using namespace boost::assign; | |
214 | ||
215 | std::vector<char> v; | |
216 | v += 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'; | |
217 | BOOST_TEST(test("[6162636465666768]", '[' << +hex[action(v)] << ']')); | |
218 | } | |
219 | ||
220 | return boost::report_errors(); | |
221 | } | |
222 |