Chris@16
|
1 // Copyright (c) 2001-2011 Hartmut Kaiser
|
Chris@16
|
2 //
|
Chris@16
|
3 // Distributed under the Boost Software License, Version 1.0. (See accompanying
|
Chris@16
|
4 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
Chris@16
|
5
|
Chris@16
|
6 #if !defined(BOOST_PP_IS_ITERATING)
|
Chris@16
|
7
|
Chris@16
|
8 #if !defined(BOOST_SPIRIT_KARMA_GENERATE_ATTR_APR_23_2009_0541PM)
|
Chris@16
|
9 #define BOOST_SPIRIT_KARMA_GENERATE_ATTR_APR_23_2009_0541PM
|
Chris@16
|
10
|
Chris@16
|
11 #include <boost/spirit/home/karma/generate.hpp>
|
Chris@16
|
12
|
Chris@16
|
13 #include <boost/fusion/include/vector.hpp>
|
Chris@16
|
14 #include <boost/preprocessor/cat.hpp>
|
Chris@16
|
15 #include <boost/preprocessor/iterate.hpp>
|
Chris@16
|
16 #include <boost/preprocessor/repetition/enum.hpp>
|
Chris@16
|
17 #include <boost/preprocessor/repetition/enum_params.hpp>
|
Chris@16
|
18 #include <boost/preprocessor/repetition/enum_binary_params.hpp>
|
Chris@16
|
19
|
Chris@16
|
20 #define BOOST_PP_FILENAME_1 <boost/spirit/home/karma/generate_attr.hpp>
|
Chris@16
|
21 #define BOOST_PP_ITERATION_LIMITS (2, SPIRIT_ARGUMENTS_LIMIT)
|
Chris@16
|
22 #include BOOST_PP_ITERATE()
|
Chris@16
|
23
|
Chris@16
|
24 #endif
|
Chris@16
|
25
|
Chris@16
|
26 ///////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
27 //
|
Chris@16
|
28 // Preprocessor vertical repetition code
|
Chris@16
|
29 //
|
Chris@16
|
30 ///////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
31 #else // defined(BOOST_PP_IS_ITERATING)
|
Chris@16
|
32
|
Chris@16
|
33 #define N BOOST_PP_ITERATION()
|
Chris@16
|
34 #define BOOST_SPIRIT_KARMA_ATTRIBUTE_REFERENCE(z, n, A) \
|
Chris@16
|
35 BOOST_PP_CAT(A, n) const&
|
Chris@16
|
36
|
Chris@16
|
37 namespace boost { namespace spirit { namespace karma
|
Chris@16
|
38 {
|
Chris@16
|
39 ///////////////////////////////////////////////////////////////////////////
|
Chris@16
|
40 template <typename OutputIterator, typename Properties, typename Expr
|
Chris@16
|
41 , BOOST_PP_ENUM_PARAMS(N, typename A)>
|
Chris@16
|
42 inline bool
|
Chris@16
|
43 generate(
|
Chris@16
|
44 detail::output_iterator<OutputIterator, Properties>& sink
|
Chris@16
|
45 , Expr const& expr
|
Chris@16
|
46 , BOOST_PP_ENUM_BINARY_PARAMS(N, A, const& attr))
|
Chris@16
|
47 {
|
Chris@16
|
48 // Report invalid expression error as early as possible.
|
Chris@16
|
49 // If you got an error_invalid_expression error message here,
|
Chris@16
|
50 // then the expression (expr) is not a valid spirit karma expression.
|
Chris@16
|
51 BOOST_SPIRIT_ASSERT_MATCH(karma::domain, Expr);
|
Chris@16
|
52
|
Chris@16
|
53 typedef fusion::vector<
|
Chris@16
|
54 BOOST_PP_ENUM(N, BOOST_SPIRIT_KARMA_ATTRIBUTE_REFERENCE, A)
|
Chris@16
|
55 > vector_type;
|
Chris@16
|
56
|
Chris@16
|
57 vector_type attr (BOOST_PP_ENUM_PARAMS(N, attr));
|
Chris@16
|
58 return compile<karma::domain>(expr).generate(sink, unused, unused, attr);
|
Chris@16
|
59 }
|
Chris@16
|
60
|
Chris@16
|
61 template <typename OutputIterator, typename Expr
|
Chris@16
|
62 , BOOST_PP_ENUM_PARAMS(N, typename A)>
|
Chris@16
|
63 inline bool
|
Chris@16
|
64 generate(
|
Chris@16
|
65 OutputIterator& sink_
|
Chris@16
|
66 , Expr const& expr
|
Chris@16
|
67 , BOOST_PP_ENUM_BINARY_PARAMS(N, A, const& attr))
|
Chris@16
|
68 {
|
Chris@16
|
69 typedef traits::properties_of<
|
Chris@16
|
70 typename result_of::compile<karma::domain, Expr>::type
|
Chris@16
|
71 > properties;
|
Chris@16
|
72
|
Chris@16
|
73 // wrap user supplied iterator into our own output iterator
|
Chris@16
|
74 detail::output_iterator<OutputIterator
|
Chris@16
|
75 , mpl::int_<properties::value> > sink(sink_);
|
Chris@16
|
76 return karma::generate(sink, expr, BOOST_PP_ENUM_PARAMS(N, attr));
|
Chris@16
|
77 }
|
Chris@16
|
78
|
Chris@16
|
79 template <typename OutputIterator, typename Expr
|
Chris@16
|
80 , BOOST_PP_ENUM_PARAMS(N, typename A)>
|
Chris@16
|
81 inline bool
|
Chris@16
|
82 generate(
|
Chris@16
|
83 OutputIterator const& sink_
|
Chris@16
|
84 , Expr const& expr
|
Chris@16
|
85 , BOOST_PP_ENUM_BINARY_PARAMS(N, A, const& attr))
|
Chris@16
|
86 {
|
Chris@16
|
87 OutputIterator sink = sink_;
|
Chris@16
|
88 return karma::generate(sink, expr, BOOST_PP_ENUM_PARAMS(N, attr));
|
Chris@16
|
89 }
|
Chris@16
|
90
|
Chris@16
|
91 ///////////////////////////////////////////////////////////////////////////
|
Chris@16
|
92 template <typename OutputIterator, typename Properties, typename Expr
|
Chris@16
|
93 , typename Delimiter, BOOST_PP_ENUM_PARAMS(N, typename A)>
|
Chris@16
|
94 inline bool
|
Chris@16
|
95 generate_delimited(
|
Chris@16
|
96 detail::output_iterator<OutputIterator, Properties>& sink
|
Chris@16
|
97 , Expr const& expr
|
Chris@16
|
98 , Delimiter const& delimiter
|
Chris@16
|
99 , BOOST_SCOPED_ENUM(delimit_flag) pre_delimit
|
Chris@16
|
100 , BOOST_PP_ENUM_BINARY_PARAMS(N, A, const& attr))
|
Chris@16
|
101 {
|
Chris@16
|
102 // Report invalid expression error as early as possible.
|
Chris@16
|
103 // If you got an error_invalid_expression error message here,
|
Chris@16
|
104 // then either the expression (expr) or skipper is not a valid
|
Chris@16
|
105 // spirit karma expression.
|
Chris@16
|
106 BOOST_SPIRIT_ASSERT_MATCH(karma::domain, Expr);
|
Chris@16
|
107 BOOST_SPIRIT_ASSERT_MATCH(karma::domain, Delimiter);
|
Chris@16
|
108
|
Chris@16
|
109 typename result_of::compile<karma::domain, Delimiter>::type const
|
Chris@16
|
110 delimiter_ = compile<karma::domain>(delimiter);
|
Chris@16
|
111
|
Chris@16
|
112 if (pre_delimit == delimit_flag::predelimit &&
|
Chris@16
|
113 !karma::delimit_out(sink, delimiter_))
|
Chris@16
|
114 {
|
Chris@16
|
115 return false;
|
Chris@16
|
116 }
|
Chris@16
|
117
|
Chris@16
|
118 typedef fusion::vector<
|
Chris@16
|
119 BOOST_PP_ENUM(N, BOOST_SPIRIT_KARMA_ATTRIBUTE_REFERENCE, A)
|
Chris@16
|
120 > vector_type;
|
Chris@16
|
121
|
Chris@16
|
122 vector_type attr (BOOST_PP_ENUM_PARAMS(N, attr));
|
Chris@16
|
123 return compile<karma::domain>(expr).
|
Chris@16
|
124 generate(sink, unused, delimiter_, attr);
|
Chris@16
|
125 }
|
Chris@16
|
126
|
Chris@16
|
127 template <typename OutputIterator, typename Expr, typename Delimiter
|
Chris@16
|
128 , BOOST_PP_ENUM_PARAMS(N, typename A)>
|
Chris@16
|
129 inline bool
|
Chris@16
|
130 generate_delimited(
|
Chris@16
|
131 OutputIterator& sink_
|
Chris@16
|
132 , Expr const& expr
|
Chris@16
|
133 , Delimiter const& delimiter
|
Chris@16
|
134 , BOOST_SCOPED_ENUM(delimit_flag) pre_delimit
|
Chris@16
|
135 , BOOST_PP_ENUM_BINARY_PARAMS(N, A, const& attr))
|
Chris@16
|
136 {
|
Chris@16
|
137 typedef traits::properties_of<
|
Chris@16
|
138 typename result_of::compile<karma::domain, Expr>::type
|
Chris@16
|
139 > properties;
|
Chris@16
|
140 typedef traits::properties_of<
|
Chris@16
|
141 typename result_of::compile<karma::domain, Delimiter>::type
|
Chris@16
|
142 > delimiter_properties;
|
Chris@16
|
143
|
Chris@16
|
144 // wrap user supplied iterator into our own output iterator
|
Chris@16
|
145 detail::output_iterator<OutputIterator
|
Chris@16
|
146 , mpl::int_<properties::value | delimiter_properties::value>
|
Chris@16
|
147 > sink(sink_);
|
Chris@16
|
148 return karma::generate_delimited(sink, expr, delimiter, pre_delimit
|
Chris@16
|
149 , BOOST_PP_ENUM_PARAMS(N, attr));
|
Chris@16
|
150 }
|
Chris@16
|
151
|
Chris@16
|
152 template <typename OutputIterator, typename Expr, typename Delimiter
|
Chris@16
|
153 , BOOST_PP_ENUM_PARAMS(N, typename A)>
|
Chris@16
|
154 inline bool
|
Chris@16
|
155 generate_delimited(
|
Chris@16
|
156 OutputIterator const& sink_
|
Chris@16
|
157 , Expr const& expr
|
Chris@16
|
158 , Delimiter const& delimiter
|
Chris@16
|
159 , BOOST_SCOPED_ENUM(delimit_flag) pre_delimit
|
Chris@16
|
160 , BOOST_PP_ENUM_BINARY_PARAMS(N, A, const& attr))
|
Chris@16
|
161 {
|
Chris@16
|
162 OutputIterator sink = sink_;
|
Chris@16
|
163 return karma::generate_delimited(sink, expr, delimiter, pre_delimit
|
Chris@16
|
164 , BOOST_PP_ENUM_PARAMS(N, attr));
|
Chris@16
|
165 }
|
Chris@16
|
166
|
Chris@16
|
167 ///////////////////////////////////////////////////////////////////////////
|
Chris@16
|
168 template <typename OutputIterator, typename Expr, typename Delimiter
|
Chris@16
|
169 , BOOST_PP_ENUM_PARAMS(N, typename A)>
|
Chris@16
|
170 inline bool
|
Chris@16
|
171 generate_delimited(
|
Chris@16
|
172 OutputIterator& sink_
|
Chris@16
|
173 , Expr const& expr
|
Chris@16
|
174 , Delimiter const& delimiter
|
Chris@16
|
175 , BOOST_PP_ENUM_BINARY_PARAMS(N, A, const& attr))
|
Chris@16
|
176 {
|
Chris@16
|
177 typedef traits::properties_of<
|
Chris@16
|
178 typename result_of::compile<karma::domain, Expr>::type
|
Chris@16
|
179 > properties;
|
Chris@16
|
180 typedef traits::properties_of<
|
Chris@16
|
181 typename result_of::compile<karma::domain, Delimiter>::type
|
Chris@16
|
182 > delimiter_properties;
|
Chris@16
|
183
|
Chris@16
|
184 // wrap user supplied iterator into our own output iterator
|
Chris@16
|
185 detail::output_iterator<OutputIterator
|
Chris@16
|
186 , mpl::int_<properties::value | delimiter_properties::value>
|
Chris@16
|
187 > sink(sink_);
|
Chris@16
|
188 return karma::generate_delimited(sink, expr, delimiter
|
Chris@16
|
189 , delimit_flag::dont_predelimit, BOOST_PP_ENUM_PARAMS(N, attr));
|
Chris@16
|
190 }
|
Chris@16
|
191
|
Chris@16
|
192 template <typename OutputIterator, typename Expr, typename Delimiter
|
Chris@16
|
193 , BOOST_PP_ENUM_PARAMS(N, typename A)>
|
Chris@16
|
194 inline bool
|
Chris@16
|
195 generate_delimited(
|
Chris@16
|
196 OutputIterator const& sink_
|
Chris@16
|
197 , Expr const& expr
|
Chris@16
|
198 , Delimiter const& delimiter
|
Chris@16
|
199 , BOOST_PP_ENUM_BINARY_PARAMS(N, A, const& attr))
|
Chris@16
|
200 {
|
Chris@16
|
201 OutputIterator sink = sink_;
|
Chris@16
|
202 return karma::generate_delimited(sink, expr, delimiter
|
Chris@16
|
203 , delimit_flag::dont_predelimit, BOOST_PP_ENUM_PARAMS(N, attr));
|
Chris@16
|
204 }
|
Chris@16
|
205
|
Chris@16
|
206 }}}
|
Chris@16
|
207
|
Chris@16
|
208 #undef BOOST_SPIRIT_KARMA_ATTRIBUTE_REFERENCE
|
Chris@16
|
209 #undef N
|
Chris@16
|
210
|
Chris@16
|
211 #endif // defined(BOOST_PP_IS_ITERATING)
|
Chris@16
|
212
|