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

source code of boost/libs/spirit/test/karma/attribute.cpp