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 | #if !defined(BOOST_SPIRIT_KARMA_GENERATE_DEC_01_2009_0734PM) |
7 | #define BOOST_SPIRIT_KARMA_GENERATE_DEC_01_2009_0734PM |
8 | |
9 | #if defined(_MSC_VER) |
10 | #pragma once |
11 | #endif |
12 | |
13 | #include <boost/spirit/home/support/context.hpp> |
14 | #include <boost/spirit/home/support/nonterminal/locals.hpp> |
15 | #include <boost/spirit/home/karma/detail/generate.hpp> |
16 | |
17 | namespace boost { namespace spirit { namespace karma |
18 | { |
19 | /////////////////////////////////////////////////////////////////////////// |
20 | template <typename OutputIterator, typename Expr> |
21 | inline bool |
22 | generate( |
23 | OutputIterator& sink |
24 | , Expr const& expr) |
25 | { |
26 | return detail::generate_impl<Expr>::call(sink, expr); |
27 | } |
28 | |
29 | template <typename OutputIterator, typename Expr> |
30 | inline bool |
31 | generate( |
32 | OutputIterator const& sink_ |
33 | , Expr const& expr) |
34 | { |
35 | OutputIterator sink = sink_; |
36 | return karma::generate(sink, expr); |
37 | } |
38 | |
39 | /////////////////////////////////////////////////////////////////////////// |
40 | namespace detail |
41 | { |
42 | template <typename T> |
43 | struct make_context |
44 | { |
45 | typedef context<fusion::cons<T const&>, locals<> > type; |
46 | }; |
47 | |
48 | template <> |
49 | struct make_context<unused_type> |
50 | { |
51 | typedef unused_type type; |
52 | }; |
53 | } |
54 | |
55 | template <typename OutputIterator, typename Properties, typename Expr |
56 | , typename Attr> |
57 | inline bool |
58 | generate( |
59 | detail::output_iterator<OutputIterator, Properties>& sink |
60 | , Expr const& expr |
61 | , Attr const& attr) |
62 | { |
63 | // Report invalid expression error as early as possible. |
64 | // If you got an error_invalid_expression error message here, |
65 | // then the expression (expr) is not a valid spirit karma expression. |
66 | BOOST_SPIRIT_ASSERT_MATCH(karma::domain, Expr); |
67 | |
68 | typename detail::make_context<Attr>::type context(attr); |
69 | return compile<karma::domain>(expr).generate(sink, context, unused, attr); |
70 | } |
71 | |
72 | template <typename OutputIterator, typename Expr, typename Attr> |
73 | inline bool |
74 | generate( |
75 | OutputIterator& sink_ |
76 | , Expr const& expr |
77 | , Attr const& attr) |
78 | { |
79 | // Report invalid expression error as early as possible. |
80 | // If you got an error_invalid_expression error message here, |
81 | // then the expression (expr) is not a valid spirit karma expression. |
82 | BOOST_SPIRIT_ASSERT_MATCH(karma::domain, Expr); |
83 | |
84 | typedef traits::properties_of< |
85 | typename result_of::compile<karma::domain, Expr>::type |
86 | > properties; |
87 | |
88 | // wrap user supplied iterator into our own output iterator |
89 | detail::output_iterator<OutputIterator |
90 | , mpl::int_<properties::value> > sink(sink_); |
91 | return karma::generate(sink, expr, attr); |
92 | } |
93 | |
94 | template <typename OutputIterator, typename Expr, typename Attr> |
95 | inline bool |
96 | generate( |
97 | OutputIterator const& sink_ |
98 | , Expr const& expr |
99 | , Attr const& attr) |
100 | { |
101 | OutputIterator sink = sink_; |
102 | return karma::generate(sink, expr, attr); |
103 | } |
104 | |
105 | /////////////////////////////////////////////////////////////////////////// |
106 | template <typename OutputIterator, typename Expr, typename Delimiter> |
107 | inline bool |
108 | generate_delimited( |
109 | OutputIterator& sink |
110 | , Expr const& expr |
111 | , Delimiter const& delimiter |
112 | , BOOST_SCOPED_ENUM(delimit_flag) pre_delimit = |
113 | delimit_flag::dont_predelimit) |
114 | { |
115 | return detail::generate_delimited_impl<Expr>::call( |
116 | sink, expr, delimiter, pre_delimit); |
117 | } |
118 | |
119 | template <typename OutputIterator, typename Expr, typename Delimiter> |
120 | inline bool |
121 | generate_delimited( |
122 | OutputIterator const& sink_ |
123 | , Expr const& expr |
124 | , Delimiter const& delimiter |
125 | , BOOST_SCOPED_ENUM(delimit_flag) pre_delimit = |
126 | delimit_flag::dont_predelimit) |
127 | { |
128 | OutputIterator sink = sink_; |
129 | return karma::generate_delimited(sink, expr, delimiter, pre_delimit); |
130 | } |
131 | |
132 | /////////////////////////////////////////////////////////////////////////// |
133 | template <typename OutputIterator, typename Properties, typename Expr |
134 | , typename Delimiter, typename Attribute> |
135 | inline bool |
136 | generate_delimited( |
137 | detail::output_iterator<OutputIterator, Properties>& sink |
138 | , Expr const& expr |
139 | , Delimiter const& delimiter |
140 | , BOOST_SCOPED_ENUM(delimit_flag) pre_delimit |
141 | , Attribute const& attr) |
142 | { |
143 | // Report invalid expression error as early as possible. |
144 | // If you got an error_invalid_expression error message here, |
145 | // then either the expression (expr) or skipper is not a valid |
146 | // spirit karma expression. |
147 | BOOST_SPIRIT_ASSERT_MATCH(karma::domain, Expr); |
148 | BOOST_SPIRIT_ASSERT_MATCH(karma::domain, Delimiter); |
149 | |
150 | typename result_of::compile<karma::domain, Delimiter>::type const |
151 | delimiter_ = compile<karma::domain>(delimiter); |
152 | |
153 | if (pre_delimit == delimit_flag::predelimit && |
154 | !karma::delimit_out(sink, delimiter_)) |
155 | { |
156 | return false; |
157 | } |
158 | |
159 | typename detail::make_context<Attribute>::type context(attr); |
160 | return compile<karma::domain>(expr). |
161 | generate(sink, context, delimiter_, attr); |
162 | } |
163 | |
164 | template <typename OutputIterator, typename Expr, typename Delimiter |
165 | , typename Attribute> |
166 | inline bool |
167 | generate_delimited( |
168 | OutputIterator& sink_ |
169 | , Expr const& expr |
170 | , Delimiter const& delimiter |
171 | , BOOST_SCOPED_ENUM(delimit_flag) pre_delimit |
172 | , Attribute const& attr) |
173 | { |
174 | typedef traits::properties_of< |
175 | typename result_of::compile<karma::domain, Expr>::type |
176 | > properties; |
177 | typedef traits::properties_of< |
178 | typename result_of::compile<karma::domain, Delimiter>::type |
179 | > delimiter_properties; |
180 | |
181 | // wrap user supplied iterator into our own output iterator |
182 | detail::output_iterator<OutputIterator |
183 | , mpl::int_<properties::value | delimiter_properties::value> |
184 | > sink(sink_); |
185 | return karma::generate_delimited(sink, expr, delimiter, pre_delimit, attr); |
186 | } |
187 | |
188 | template <typename OutputIterator, typename Expr, typename Delimiter |
189 | , typename Attribute> |
190 | inline bool |
191 | generate_delimited( |
192 | OutputIterator const& sink_ |
193 | , Expr const& expr |
194 | , Delimiter const& delimiter |
195 | , BOOST_SCOPED_ENUM(delimit_flag) pre_delimit |
196 | , Attribute const& attr) |
197 | { |
198 | OutputIterator sink = sink_; |
199 | return karma::generate_delimited(sink, expr, delimiter, pre_delimit, attr); |
200 | } |
201 | |
202 | /////////////////////////////////////////////////////////////////////////// |
203 | template <typename OutputIterator, typename Expr, typename Delimiter |
204 | , typename Attribute> |
205 | inline bool |
206 | generate_delimited( |
207 | OutputIterator& sink |
208 | , Expr const& expr |
209 | , Delimiter const& delimiter |
210 | , Attribute const& attr) |
211 | { |
212 | return karma::generate_delimited(sink, expr, delimiter |
213 | , delimit_flag::dont_predelimit, attr); |
214 | } |
215 | |
216 | template <typename OutputIterator, typename Expr, typename Delimiter |
217 | , typename Attribute> |
218 | inline bool |
219 | generate_delimited( |
220 | OutputIterator const& sink_ |
221 | , Expr const& expr |
222 | , Delimiter const& delimiter |
223 | , Attribute const& attr) |
224 | { |
225 | OutputIterator sink = sink_; |
226 | return karma::generate_delimited(sink, expr, delimiter |
227 | , delimit_flag::dont_predelimit, attr); |
228 | } |
229 | }}} |
230 | |
231 | #endif |
232 | |
233 | |