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/mpl/print.hpp>
10
11 #include <boost/spirit/include/karma_operator.hpp>
12 #include <boost/spirit/include/karma_char.hpp>
13 #include <boost/spirit/include/karma_string.hpp>
14 #include <boost/spirit/include/karma_numeric.hpp>
15 #include <boost/spirit/include/karma_directive.hpp>
16 #include <boost/spirit/include/karma_action.hpp>
17 #include <boost/spirit/include/karma_nonterminal.hpp>
18 #include <boost/spirit/include/karma_auxiliary.hpp>
19 #include <boost/spirit/include/phoenix_core.hpp>
20 #include <boost/spirit/include/phoenix_operator.hpp>
21 #include <boost/fusion/include/std_pair.hpp>
22
23 #include <boost/assign/std/vector.hpp>
24
25 #include <string>
26 #include <vector>
27 #include <iostream>
28
29 #include "test.hpp"
30
31 using namespace spirit_test;
32 using boost::spirit::unused_type;
33
34 ///////////////////////////////////////////////////////////////////////////////
35 struct action
36 {
actionaction37 action (std::vector<char>& vec)
38 : vec(vec), it(vec.begin())
39 {}
40
operator ()action41 void operator()(unsigned& value, unused_type const&, bool& pass) const
42 {
43 pass = (it != vec.end());
44 if (pass)
45 value = *it++;
46 }
47
48 std::vector<char>& vec;
49 mutable std::vector<char>::iterator it;
50 };
51
52 ///////////////////////////////////////////////////////////////////////////////
main()53 int main()
54 {
55 using namespace boost::spirit;
56 using namespace boost::spirit::ascii;
57
58 using namespace boost::assign;
59
60 std::vector<char> v;
61 v += 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h';
62
63 {
64 BOOST_TEST(test("a,b,c,d,e,f,g,h", char_ % ',', v));
65 BOOST_TEST(test_delimited("a , b , c , d , e , f , g , h ",
66 char_ % ',', v, space));
67 }
68
69 {
70 std::string s ("abcdefgh");
71 BOOST_TEST(test("a,b,c,d,e,f,g,h", char_ % ',', s));
72 BOOST_TEST(test_delimited("a , b , c , d , e , f , g , h ",
73 char_ % ',', s, space));
74 }
75
76 {
77 std::string s ("abcdefg");
78 BOOST_TEST(test("abc,de,fg", char_ << ((char_ << char_) % ','), s));
79 BOOST_TEST(test_delimited("a b c , d e , f g ",
80 char_ << ((char_ << char_) % ','), s, space));
81 }
82
83 { // actions
84 namespace phx = boost::phoenix;
85
86 BOOST_TEST(test("a,b,c,d,e,f,g,h", (char_ % ',')[_1 = phx::ref(v)]));
87 BOOST_TEST(test_delimited("a , b , c , d , e , f , g , h ",
88 (char_ % ',')[_1 = phx::ref(v)], space));
89 }
90
91 // failing sub-generators
92 {
93 using boost::spirit::karma::strict;
94 using boost::spirit::karma::relaxed;
95
96 typedef std::pair<char, char> data;
97 std::vector<data> v2;
98 v2 += std::make_pair('a', 'a'),
99 std::make_pair('b', 'b'),
100 std::make_pair('c', 'c'),
101 std::make_pair('d', 'd'),
102 std::make_pair('e', 'e'),
103 std::make_pair('f', 'f'),
104 std::make_pair('g', 'g');
105
106 karma::rule<spirit_test::output_iterator<char>::type, data()> r;
107
108 r = &char_('d') << char_;
109 BOOST_TEST(test("d", r % ',', v2));
110 BOOST_TEST(test("d", relaxed[r % ','], v2));
111 BOOST_TEST(!test("", strict[r % ','], v2));
112
113 r = &char_('a') << char_;
114 BOOST_TEST(test("a", r % ',', v2));
115 BOOST_TEST(test("a", relaxed[r % ','], v2));
116 BOOST_TEST(test("a", strict[r % ','], v2));
117
118 r = &char_('g') << char_;
119 BOOST_TEST(test("g", r % ',', v2));
120 BOOST_TEST(test("g", relaxed[r % ','], v2));
121 BOOST_TEST(!test("", strict[r % ','], v2));
122
123 r = !char_('d') << char_;
124 BOOST_TEST(test("a,b,c,e,f,g", r % ',', v2));
125 BOOST_TEST(test("a,b,c,e,f,g", relaxed[r % ','], v2));
126 BOOST_TEST(test("a,b,c", strict[r % ','], v2));
127
128 r = !char_('a') << char_;
129 BOOST_TEST(test("b,c,d,e,f,g", r % ',', v2));
130 BOOST_TEST(test("b,c,d,e,f,g", relaxed[r % ','], v2));
131 BOOST_TEST(!test("", strict[r % ','], v2));
132
133 r = !char_('g') << char_;
134 BOOST_TEST(test("a,b,c,d,e,f", r % ',', v2));
135 BOOST_TEST(test("a,b,c,d,e,f", relaxed[r % ','], v2));
136 BOOST_TEST(test("a,b,c,d,e,f", strict[r % ','], v2));
137
138 r = &char_('A') << char_;
139 BOOST_TEST(!test("", r % ',', v2));
140 }
141
142 {
143 // make sure user defined end condition is applied if no attribute
144 // is passed in
145 BOOST_TEST(test("[61,62,63,64,65,66,67,68]",
146 '[' << hex[action(v)] % ',' << ']'));
147 }
148
149 return boost::report_errors();
150 }
151
152