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/spirit/include/phoenix_limits.hpp>
10
11 #include <boost/fusion/include/struct.hpp>
12 #include <boost/fusion/include/nview.hpp>
13
14 #include <boost/spirit/include/karma_char.hpp>
15 #include <boost/spirit/include/karma_string.hpp>
16 #include <boost/spirit/include/karma_numeric.hpp>
17 #include <boost/spirit/include/karma_operator.hpp>
18 #include <boost/spirit/include/karma_nonterminal.hpp>
19 #include <boost/spirit/include/karma_auxiliary.hpp>
20
21 #include "test.hpp"
22
23 using namespace spirit_test;
24
25 ///////////////////////////////////////////////////////////////////////////////
26 struct test_data
27 {
28 std::string s1;
29 std::string s2;
30 int i1;
31 double d1;
32 std::string s3;
33 };
34
35 BOOST_FUSION_ADAPT_STRUCT(
36 test_data,
37 (int, i1)
38 (std::string, s1)
39 (std::string, s2)
40 (std::string, s3)
41 (double, d1)
42 )
43
44 ///////////////////////////////////////////////////////////////////////////////
45 // this is just a test structure we need to use in place of an int
46 struct test_int_data1
47 {
48 int i;
49 };
50
51 // so we provide a custom attribute transformation
52 namespace boost { namespace spirit { namespace traits
53 {
54 template <>
55 struct transform_attribute<test_int_data1 const, int, karma::domain>
56 {
57 typedef int type;
preboost::spirit::traits::transform_attribute58 static int pre(test_int_data1 const& d) { return d.i; }
59 };
60 }}}
61
62 ///////////////////////////////////////////////////////////////////////////////
63 // this is another test structure we need to use in place of an int, but this
64 // time we use a reference to the embedded element
65 struct test_int_data2
66 {
67 int i;
68 };
69
70 // so we provide a custom attribute transformation
71 namespace boost { namespace spirit { namespace traits
72 {
73 template <>
74 struct transform_attribute<test_int_data2 const, int, karma::domain>
75 {
76 typedef int const& type;
preboost::spirit::traits::transform_attribute77 static int const& pre(test_int_data2 const& d) { return d.i; }
78 };
79 }}}
80
81 ///////////////////////////////////////////////////////////////////////////////
main()82 int main()
83 {
84 namespace fusion = boost::fusion;
85 namespace karma = boost::spirit::karma;
86
87 test_data d1 = { "s11", "s12", 1, 2.5, "s13" };
88 {
89
90 BOOST_TEST(test("s121",
91 karma::string << karma::int_,
92 fusion::as_nview<2, 0>(d1)));
93
94 BOOST_TEST(test_delimited("s12 1 ",
95 karma::string << karma::int_,
96 fusion::as_nview<2, 0>(d1), ' '));
97 }
98
99 {
100 test_data d2 = { "s21", "s22", 2, 3.4, "s23" };
101 typedef fusion::result_of::as_nview<test_data const, 1, 2, 4>::type
102 test_view;
103 std::vector<test_data> v;
104 v.push_back(d1);
105 v.push_back(d2);
106
107 karma::rule<output_iterator<char>::type, test_view()> r =
108 karma::string << karma::string << karma::double_;
109
110 BOOST_TEST(test("s11s122.5\ns21s223.4", r % karma::eol, v));
111 BOOST_TEST(test_delimited("s11s122.5 \n s21s223.4 ",
112 r % karma::eol, v, ' '));
113 }
114
115 {
116 test_int_data1 d = { 1 };
117 BOOST_TEST(test("1", karma::attr_cast(karma::int_), d));
118 BOOST_TEST(test("1", karma::attr_cast<test_int_data1>(karma::int_), d));
119 BOOST_TEST(test("1", karma::attr_cast<test_int_data1, int>(karma::int_), d));
120 }
121
122 {
123 test_int_data1 d[] = {{ 1 }, { 2 }};
124 std::vector<test_int_data1> v;
125 v.push_back(d[0]);
126 v.push_back(d[1]);
127
128 BOOST_TEST(test("1,2", karma::attr_cast(karma::int_) % ',', v));
129 BOOST_TEST(test("1,2"
130 , karma::attr_cast<test_int_data1>(karma::int_) % ',', v));
131 BOOST_TEST(test("1,2"
132 , karma::attr_cast<test_int_data1, int>(karma::int_) % ',', v));
133 }
134
135 {
136 test_int_data1 d[] = {{ 1 }, { 2 }};
137 std::vector<test_int_data1> v;
138 v.push_back(d[0]);
139 v.push_back(d[1]);
140
141 karma::rule<output_iterator<char>::type, int()> r = karma::int_;
142 BOOST_TEST(test("1,2", r % ',', v));
143 }
144
145 {
146 test_int_data1 d[] = {{ 1 }, { 2 }};
147 std::vector<test_int_data1> v;
148 v.push_back(d[0]);
149 v.push_back(d[1] );
150
151 // this won't compile as there is no defined transformation for
152 // test_int_data1 and double
153 // BOOST_TEST(test("1.0,2.0", karma::attr_cast(karma::double_) % ',', v));
154 // BOOST_TEST(test("1.0,2.0"
155 // , karma::attr_cast<test_int_data1>(karma::double_) % ',', v));
156
157 BOOST_TEST(test("1.0,2.0"
158 , karma::attr_cast<test_int_data1, int>(karma::double_) % ',', v));
159
160 karma::rule<output_iterator<char>::type, int()> r = karma::double_;
161 BOOST_TEST(test("1.0,2.0", r % ',', v));
162 }
163
164 {
165 test_int_data2 d = { 1 };
166 BOOST_TEST(test("1", karma::attr_cast(karma::int_), d));
167 BOOST_TEST(test("1", karma::attr_cast<test_int_data2>(karma::int_), d));
168 BOOST_TEST(test("1", karma::attr_cast<test_int_data2, int>(karma::int_), d));
169 }
170
171 {
172 test_int_data2 d[] = {{ 1 }, { 2 }};
173 std::vector<test_int_data2> v;
174 v.push_back(d[0]);
175 v.push_back(d[1]);
176
177 BOOST_TEST(test("1,2", karma::attr_cast(karma::int_) % ',', v));
178 BOOST_TEST(test("1,2"
179 , karma::attr_cast<test_int_data2>(karma::int_) % ',', v));
180 BOOST_TEST(test("1,2"
181 , karma::attr_cast<test_int_data2, int>(karma::int_) % ',', v));
182 }
183
184 {
185 test_int_data2 d[] = {{ 1 }, { 2 }};
186 std::vector<test_int_data2> v;
187 v.push_back(d[0]);
188 v.push_back(d[1]);
189
190 karma::rule<output_iterator<char>::type, int()> r = karma::int_;
191 BOOST_TEST(test("1,2", r % ',', v));
192 }
193
194 {
195 test_int_data2 d[] = {{ 1 }, { 2 }};
196 std::vector<test_int_data2> v;
197 v.push_back(d[0]);
198 v.push_back(d[1] );
199
200 // this won't compile as there is no defined transformation for
201 // test_int_data2 and double
202 // BOOST_TEST(test("1.0,2.0", karma::attr_cast(karma::double_) % ',', v));
203 // BOOST_TEST(test("1.0,2.0"
204 // , karma::attr_cast<test_int_data2>(karma::double_) % ',', v));
205
206 BOOST_TEST(test("1.0,2.0"
207 , karma::attr_cast<test_int_data2, int>(karma::double_) % ',', v));
208
209 karma::rule<output_iterator<char>::type, int()> r = karma::double_;
210 BOOST_TEST(test("1.0,2.0", r % ',', v));
211 }
212
213 return boost::report_errors();
214 }
215