]>
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 | ||
7c673cae FG |
6 | #include <boost/config/warning_disable.hpp> |
7 | #include <boost/detail/lightweight_test.hpp> | |
8 | ||
9 | #include <boost/spirit/include/karma_char.hpp> | |
10 | #include <boost/spirit/include/karma_string.hpp> | |
11 | #include <boost/spirit/include/karma_numeric.hpp> | |
12 | #include <boost/spirit/include/karma_generate.hpp> | |
13 | #include <boost/spirit/include/karma_operator.hpp> | |
14 | #include <boost/spirit/include/karma_directive.hpp> | |
15 | #include <boost/spirit/include/karma_action.hpp> | |
16 | #include <boost/spirit/include/karma_nonterminal.hpp> | |
17 | #include <boost/spirit/include/karma_auxiliary.hpp> | |
18 | #include <boost/spirit/include/karma_directive.hpp> | |
19 | #include <boost/spirit/include/support_unused.hpp> | |
20 | #include <boost/spirit/include/phoenix_core.hpp> | |
21 | #include <boost/spirit/include/phoenix_operator.hpp> | |
92f5a8d4 | 22 | #include <boost/spirit/include/phoenix_function.hpp> |
7c673cae FG |
23 | #include <boost/fusion/include/vector.hpp> |
24 | ||
25 | #include "test.hpp" | |
26 | ||
27 | using namespace spirit_test; | |
28 | ||
29 | /////////////////////////////////////////////////////////////////////////////// | |
30 | // lazy version of fusion::size | |
31 | struct seqsize_impl | |
32 | { | |
33 | template <typename Sequence> | |
34 | struct result | |
35 | : boost::fusion::result_of::size<Sequence> | |
36 | {}; | |
37 | ||
38 | template <typename This, typename Sequence> | |
39 | struct result<This(Sequence)> | |
40 | : result<typename boost::proto::detail::uncvref<Sequence>::type> | |
41 | {}; | |
42 | ||
43 | template <typename Sequence> | |
44 | typename result<Sequence>::type | |
45 | operator()(Sequence const& seq) const | |
46 | { | |
47 | return boost::fusion::size(seq); | |
48 | } | |
49 | }; | |
50 | ||
51 | boost::phoenix::function<seqsize_impl> const seqsize = seqsize_impl(); | |
52 | ||
53 | /////////////////////////////////////////////////////////////////////////////// | |
54 | int main() | |
55 | { | |
56 | using namespace boost::spirit; | |
57 | using namespace boost::spirit::ascii; | |
58 | namespace fusion = boost::fusion; | |
59 | ||
60 | { | |
61 | std::list<int> v; | |
62 | v.push_back(1); | |
63 | v.push_back(2); | |
64 | v.push_back(3); | |
65 | BOOST_TEST(test("123", int_ << int_ << int_, v)); | |
66 | BOOST_TEST(test_delimited("1 2 3 ", int_ << int_ << int_, v, ' ')); | |
67 | BOOST_TEST(test("1,2,3", int_ << ',' << int_ << ',' << int_, v)); | |
68 | BOOST_TEST(test_delimited("1 , 2 , 3 ", int_ << ',' << int_ << ',' << int_, v, ' ')); | |
69 | } | |
70 | ||
71 | { | |
72 | BOOST_TEST(test("aa", lower[char_('A') << 'a'])); | |
73 | BOOST_TEST(test_delimited("BEGIN END ", | |
74 | upper[lit("begin") << "end"], char(' '))); | |
75 | BOOST_TEST(!test_delimited("BEGIN END ", | |
76 | upper[lit("begin") << "nend"], char(' '))); | |
77 | ||
78 | BOOST_TEST(test("Aa ", left_align[char_('A') << 'a'])); | |
79 | BOOST_TEST(test(" Aa ", center[char_('A') << 'a'])); | |
80 | BOOST_TEST(test(" Aa", right_align[char_('A') << 'a'])); | |
81 | } | |
82 | ||
83 | { | |
84 | // make sure single element tuples get passed through if the rhs | |
85 | // has a single element tuple as its attribute | |
86 | typedef spirit_test::output_iterator<char>::type iterator_type; | |
87 | fusion::vector<double, int> fv(2.0, 1); | |
88 | karma::rule<iterator_type, fusion::vector<double, int>()> r; | |
89 | r %= double_ << ',' << int_; | |
90 | BOOST_TEST(test("test:2.0,1", "test:" << r, fv)); | |
91 | } | |
92 | ||
93 | // action tests | |
94 | { | |
95 | using namespace boost::phoenix; | |
96 | ||
97 | BOOST_TEST(test("abcdefg", | |
98 | (char_ << char_ << string)[_1 = 'a', _2 = 'b', _3 = "cdefg"])); | |
99 | BOOST_TEST(test_delimited("a b cdefg ", | |
100 | (char_ << char_ << string)[_1 = 'a', _2 = 'b', _3 = "cdefg"], | |
101 | char(' '))); | |
102 | ||
103 | BOOST_TEST(test_delimited("a 12 c ", | |
104 | (char_ << lit(12) << char_)[_1 = 'a', _2 = 'c'], char(' '))); | |
105 | ||
106 | char c = 'c'; | |
107 | BOOST_TEST(test("abc", | |
108 | (char_[_1 = 'a'] << 'b' << char_)[_1 = 'x', _2 = ref(c)])); | |
109 | BOOST_TEST(test_delimited("a b c ", | |
110 | (char_[_1 = 'a'] << 'b' << char_)[_2 = ref(c)], char(' '))); | |
111 | ||
112 | BOOST_TEST(test("aa", lower[char_ << 'A'][_1 = 'A'])); | |
113 | BOOST_TEST(test("AA", upper[char_ << 'a'][_1 = 'a'])); | |
114 | ||
115 | BOOST_TEST(test("Aa ", left_align[char_ << 'a'][_1 = 'A'])); | |
116 | BOOST_TEST(test(" Aa ", center[char_ << 'a'][_1 = 'A'])); | |
117 | BOOST_TEST(test(" Aa", right_align[char_ << 'a'][_1 = 'A'])); | |
118 | } | |
119 | ||
120 | // test special case where sequence has a one element vector attribute | |
121 | // sequence and this element is a rule (attribute has to be passed through | |
122 | // without change) | |
123 | { | |
124 | typedef spirit_test::output_iterator<char>::type outiter_type; | |
125 | namespace karma = boost::spirit::karma; | |
126 | ||
127 | karma::rule<outiter_type, std::vector<int>()> r = -(int_ % ','); | |
128 | std::vector<int> v; | |
129 | BOOST_TEST(test(">", '>' << r, v)); | |
130 | ||
131 | v.push_back(1); | |
132 | v.push_back(2); | |
133 | v.push_back(3); | |
134 | v.push_back(4); | |
135 | BOOST_TEST(test(">1,2,3,4", '>' << r, v)); | |
136 | } | |
137 | ||
138 | { | |
139 | namespace karma = boost::spirit::karma; | |
140 | typedef spirit_test::output_iterator<char>::type outiter_type; | |
141 | ||
142 | karma::rule<outiter_type, std::string()> e = karma::string; | |
143 | karma::rule<outiter_type, std::vector<std::string>()> l = e << *(',' << e); | |
144 | ||
145 | std::vector<std::string> v; | |
146 | v.push_back("abc1"); | |
147 | v.push_back("abc2"); | |
148 | v.push_back("abc3"); | |
149 | BOOST_TEST(test("abc1,abc2,abc3", l, v)); | |
150 | } | |
151 | ||
152 | { | |
153 | namespace karma = boost::spirit::karma; | |
154 | namespace phoenix = boost::phoenix; | |
155 | ||
156 | typedef spirit_test::output_iterator<char>::type outiter_type; | |
157 | typedef fusion::vector<char, char, char> vector_type; | |
158 | ||
159 | vector_type p ('a', 'b', 'c'); | |
160 | BOOST_TEST(test("ab", char_ << char_, p)); | |
161 | ||
162 | karma::rule<outiter_type, vector_type()> r; | |
163 | r %= char_ << char_ << &karma::eps[seqsize(_val) == 3]; | |
164 | BOOST_TEST(!test("", r, p)); | |
165 | ||
166 | r %= char_ << char_ << char_ << &karma::eps[seqsize(_val) == 3]; | |
167 | BOOST_TEST(test("abc", r, p)); | |
168 | } | |
169 | ||
170 | { | |
171 | std::list<int> v; | |
172 | v.push_back(1); | |
173 | v.push_back(2); | |
174 | v.push_back(3); | |
175 | v.push_back(4); | |
176 | ||
177 | BOOST_TEST(test("1234", repeat(2)[int_] << *int_, v)); | |
178 | BOOST_TEST(test_delimited("1 2 3 4 ", repeat(2)[int_] << *int_, v, char(' '))); | |
179 | } | |
180 | ||
181 | return boost::report_errors(); | |
182 | } | |
183 |