1 // Copyright (c) 2001-2011 Hartmut Kaiser
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)
6 #if !defined(BOOST_PP_IS_ITERATING)
8 #if !defined(BOOST_SPIRIT_KARMA_GENERATE_ATTR_APR_23_2009_0541PM)
9 #define BOOST_SPIRIT_KARMA_GENERATE_ATTR_APR_23_2009_0541PM
11 #include <boost/spirit/home/karma/generate.hpp>
13 #include <boost/fusion/include/vector.hpp>
14 #include <boost/preprocessor/cat.hpp>
15 #include <boost/preprocessor/iterate.hpp>
16 #include <boost/preprocessor/repetition/enum.hpp>
17 #include <boost/preprocessor/repetition/enum_params.hpp>
18 #include <boost/preprocessor/repetition/enum_binary_params.hpp>
20 #define BOOST_PP_FILENAME_1 <boost/spirit/home/karma/generate_attr.hpp>
21 #define BOOST_PP_ITERATION_LIMITS (2, SPIRIT_ARGUMENTS_LIMIT)
22 #include BOOST_PP_ITERATE()
26 ///////////////////////////////////////////////////////////////////////////////
28 // Preprocessor vertical repetition code
30 ///////////////////////////////////////////////////////////////////////////////
31 #else // defined(BOOST_PP_IS_ITERATING)
33 #define N BOOST_PP_ITERATION()
34 #define BOOST_SPIRIT_KARMA_ATTRIBUTE_REFERENCE(z, n, A) \
35 BOOST_PP_CAT(A, n) const&
37 namespace boost { namespace spirit { namespace karma
39 ///////////////////////////////////////////////////////////////////////////
40 template <typename OutputIterator, typename Properties, typename Expr
41 , BOOST_PP_ENUM_PARAMS(N, typename A)>
44 detail::output_iterator<OutputIterator, Properties>& sink
46 , BOOST_PP_ENUM_BINARY_PARAMS(N, A, const& attr))
48 // Report invalid expression error as early as possible.
49 // If you got an error_invalid_expression error message here,
50 // then the expression (expr) is not a valid spirit karma expression.
51 BOOST_SPIRIT_ASSERT_MATCH(karma::domain, Expr);
53 typedef fusion::vector<
54 BOOST_PP_ENUM(N, BOOST_SPIRIT_KARMA_ATTRIBUTE_REFERENCE, A)
57 vector_type attr (BOOST_PP_ENUM_PARAMS(N, attr));
58 return compile<karma::domain>(expr).generate(sink, unused, unused, attr);
61 template <typename OutputIterator, typename Expr
62 , BOOST_PP_ENUM_PARAMS(N, typename A)>
67 , BOOST_PP_ENUM_BINARY_PARAMS(N, A, const& attr))
69 typedef traits::properties_of<
70 typename result_of::compile<karma::domain, Expr>::type
73 // wrap user supplied iterator into our own output iterator
74 detail::output_iterator<OutputIterator
75 , mpl::int_<properties::value> > sink(sink_);
76 return karma::generate(sink, expr, BOOST_PP_ENUM_PARAMS(N, attr));
79 template <typename OutputIterator, typename Expr
80 , BOOST_PP_ENUM_PARAMS(N, typename A)>
83 OutputIterator const& sink_
85 , BOOST_PP_ENUM_BINARY_PARAMS(N, A, const& attr))
87 OutputIterator sink = sink_;
88 return karma::generate(sink, expr, BOOST_PP_ENUM_PARAMS(N, attr));
91 ///////////////////////////////////////////////////////////////////////////
92 template <typename OutputIterator, typename Properties, typename Expr
93 , typename Delimiter, BOOST_PP_ENUM_PARAMS(N, typename A)>
96 detail::output_iterator<OutputIterator, Properties>& sink
98 , Delimiter const& delimiter
99 , BOOST_SCOPED_ENUM(delimit_flag) pre_delimit
100 , BOOST_PP_ENUM_BINARY_PARAMS(N, A, const& attr))
102 // Report invalid expression error as early as possible.
103 // If you got an error_invalid_expression error message here,
104 // then either the expression (expr) or skipper is not a valid
105 // spirit karma expression.
106 BOOST_SPIRIT_ASSERT_MATCH(karma::domain, Expr);
107 BOOST_SPIRIT_ASSERT_MATCH(karma::domain, Delimiter);
109 typename result_of::compile<karma::domain, Delimiter>::type const
110 delimiter_ = compile<karma::domain>(delimiter);
112 if (pre_delimit == delimit_flag::predelimit &&
113 !karma::delimit_out(sink, delimiter_))
118 typedef fusion::vector<
119 BOOST_PP_ENUM(N, BOOST_SPIRIT_KARMA_ATTRIBUTE_REFERENCE, A)
122 vector_type attr (BOOST_PP_ENUM_PARAMS(N, attr));
123 return compile<karma::domain>(expr).
124 generate(sink, unused, delimiter_, attr);
127 template <typename OutputIterator, typename Expr, typename Delimiter
128 , BOOST_PP_ENUM_PARAMS(N, typename A)>
131 OutputIterator& sink_
133 , Delimiter const& delimiter
134 , BOOST_SCOPED_ENUM(delimit_flag) pre_delimit
135 , BOOST_PP_ENUM_BINARY_PARAMS(N, A, const& attr))
137 typedef traits::properties_of<
138 typename result_of::compile<karma::domain, Expr>::type
140 typedef traits::properties_of<
141 typename result_of::compile<karma::domain, Delimiter>::type
142 > delimiter_properties;
144 // wrap user supplied iterator into our own output iterator
145 detail::output_iterator<OutputIterator
146 , mpl::int_<properties::value | delimiter_properties::value>
148 return karma::generate_delimited(sink, expr, delimiter, pre_delimit
149 , BOOST_PP_ENUM_PARAMS(N, attr));
152 template <typename OutputIterator, typename Expr, typename Delimiter
153 , BOOST_PP_ENUM_PARAMS(N, typename A)>
156 OutputIterator const& sink_
158 , Delimiter const& delimiter
159 , BOOST_SCOPED_ENUM(delimit_flag) pre_delimit
160 , BOOST_PP_ENUM_BINARY_PARAMS(N, A, const& attr))
162 OutputIterator sink = sink_;
163 return karma::generate_delimited(sink, expr, delimiter, pre_delimit
164 , BOOST_PP_ENUM_PARAMS(N, attr));
167 ///////////////////////////////////////////////////////////////////////////
168 template <typename OutputIterator, typename Expr, typename Delimiter
169 , BOOST_PP_ENUM_PARAMS(N, typename A)>
172 OutputIterator& sink_
174 , Delimiter const& delimiter
175 , BOOST_PP_ENUM_BINARY_PARAMS(N, A, const& attr))
177 typedef traits::properties_of<
178 typename result_of::compile<karma::domain, Expr>::type
180 typedef traits::properties_of<
181 typename result_of::compile<karma::domain, Delimiter>::type
182 > delimiter_properties;
184 // wrap user supplied iterator into our own output iterator
185 detail::output_iterator<OutputIterator
186 , mpl::int_<properties::value | delimiter_properties::value>
188 return karma::generate_delimited(sink, expr, delimiter
189 , delimit_flag::dont_predelimit, BOOST_PP_ENUM_PARAMS(N, attr));
192 template <typename OutputIterator, typename Expr, typename Delimiter
193 , BOOST_PP_ENUM_PARAMS(N, typename A)>
196 OutputIterator const& sink_
198 , Delimiter const& delimiter
199 , BOOST_PP_ENUM_BINARY_PARAMS(N, A, const& attr))
201 OutputIterator sink = sink_;
202 return karma::generate_delimited(sink, expr, delimiter
203 , delimit_flag::dont_predelimit, BOOST_PP_ENUM_PARAMS(N, attr));
208 #undef BOOST_SPIRIT_KARMA_ATTRIBUTE_REFERENCE
211 #endif // defined(BOOST_PP_IS_ITERATING)