]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/libs/spirit/include/boost/spirit/home/karma/directive/left_alignment.hpp
bump version to 12.2.2-pve1
[ceph.git] / ceph / src / boost / libs / spirit / include / boost / spirit / home / karma / directive / left_alignment.hpp
CommitLineData
7c673cae
FG
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_LEFT_ALIGNMENT_FEB_27_2007_1216PM)
7#define BOOST_SPIRIT_KARMA_LEFT_ALIGNMENT_FEB_27_2007_1216PM
8
9#if defined(_MSC_VER)
10#pragma once
11#endif
12
13#include <boost/spirit/home/karma/meta_compiler.hpp>
14#include <boost/spirit/home/karma/generator.hpp>
15#include <boost/spirit/home/karma/domain.hpp>
16#include <boost/spirit/home/karma/detail/output_iterator.hpp>
17#include <boost/spirit/home/karma/detail/default_width.hpp>
18#include <boost/spirit/home/karma/delimit_out.hpp>
19#include <boost/spirit/home/karma/auxiliary/lazy.hpp>
20#include <boost/spirit/home/support/unused.hpp>
21#include <boost/spirit/home/support/common_terminals.hpp>
22#include <boost/spirit/home/karma/detail/attributes.hpp>
23#include <boost/spirit/home/support/info.hpp>
24#include <boost/spirit/home/support/unused.hpp>
25#include <boost/spirit/home/support/has_semantic_action.hpp>
26#include <boost/spirit/home/support/handles_container.hpp>
27#include <boost/fusion/include/at.hpp>
28#include <boost/fusion/include/vector.hpp>
29#include <boost/lexical_cast.hpp>
30#include <boost/integer_traits.hpp>
31#include <boost/mpl/bool.hpp>
32#include <boost/utility/enable_if.hpp>
33#include <boost/detail/workaround.hpp>
34
35///////////////////////////////////////////////////////////////////////////////
36namespace boost { namespace spirit
37{
38 ///////////////////////////////////////////////////////////////////////////
39 // Enablers
40 ///////////////////////////////////////////////////////////////////////////
41
42 // enables left_align[]
43 template <>
44 struct use_directive<karma::domain, tag::left_align>
45 : mpl::true_ {};
46
47 // enables left_align(d)[g] and left_align(w)[g], where d is a generator
48 // and w is a maximum width
49 template <typename T>
50 struct use_directive<karma::domain
51 , terminal_ex<tag::left_align, fusion::vector1<T> > >
52 : mpl::true_ {};
53
54 // enables *lazy* left_align(d)[g], where d provides a generator
55 template <>
56 struct use_lazy_directive<karma::domain, tag::left_align, 1>
57 : mpl::true_ {};
58
59 // enables left_align(w, d)[g], where d is a generator and w is a maximum
60 // width
61 template <typename Width, typename Padding>
62 struct use_directive<karma::domain
63 , terminal_ex<tag::left_align, fusion::vector2<Width, Padding> > >
64 : spirit::traits::matches<karma::domain, Padding> {};
65
66 // enables *lazy* left_align(w, d)[g], where d provides a generator and w
67 // is a maximum width
68 template <>
69 struct use_lazy_directive<karma::domain, tag::left_align, 2>
70 : mpl::true_ {};
71
72}}
73
74///////////////////////////////////////////////////////////////////////////////
75namespace boost { namespace spirit { namespace karma
76{
77#ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS
78 using spirit::left_align;
79#endif
80 using spirit::left_align_type;
81
82 namespace detail
83 {
84 ///////////////////////////////////////////////////////////////////////
85 // The left_align_generate template function is used for all the
86 // different flavors of the left_align[] directive.
87 ///////////////////////////////////////////////////////////////////////
88 template <typename OutputIterator, typename Context, typename Delimiter,
89 typename Attribute, typename Embedded, typename Padding>
90 inline static bool
91 left_align_generate(OutputIterator& sink, Context& ctx,
92 Delimiter const& d, Attribute const& attr, Embedded const& e,
93 unsigned int const width, Padding const& p)
94 {
95#if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1600))
96 e; // suppresses warning: C4100: 'e' : unreferenced formal parameter
97#endif
98 // wrap the given output iterator to allow counting
99 detail::enable_counting<OutputIterator> counting(sink);
100
101 // first generate the underlying output
102 bool r = e.generate(sink, ctx, d, attr);
103
104 // pad the output until the max width is reached
105 while(r && counting.count() < width)
106 r = p.generate(sink, ctx, unused, unused);
107
108 return r;
109 }
110 }
111
112 ///////////////////////////////////////////////////////////////////////////
113 // The simple left alignment directive is used for left_align[...]
114 // generators. It uses default values for the generated width (defined via
115 // the BOOST_KARMA_DEFAULT_FIELD_LENGTH constant) and for the padding
116 // generator (always spaces).
117 ///////////////////////////////////////////////////////////////////////////
118 template <typename Subject, typename Width = detail::default_width>
119 struct simple_left_alignment
120 : unary_generator<simple_left_alignment<Subject, Width> >
121 {
122 typedef Subject subject_type;
123
124 typedef mpl::int_<
125 generator_properties::counting | subject_type::properties::value
126 > properties;
127
128 template <typename Context, typename Iterator>
129 struct attribute
130 : traits::attribute_of<subject_type, Context, Iterator>
131 {};
132
133 simple_left_alignment(Subject const& subject, Width width = Width())
134 : subject(subject), width(width) {}
135
136 template <typename OutputIterator, typename Context, typename Delimiter
137 , typename Attribute>
138 bool generate(OutputIterator& sink, Context& ctx, Delimiter const& d
139 , Attribute const& attr) const
140 {
141 return detail::left_align_generate(sink, ctx, d, attr,
142 subject, width, compile<karma::domain>(' '));
143 }
144
145 template <typename Context>
146 info what(Context& context) const
147 {
148 return info("left_align", subject.what(context));
149 }
150
151 Subject subject;
152 Width width;
153 };
154
155 ///////////////////////////////////////////////////////////////////////////
156 // The left alignment directive with padding, is used for generators like
157 // left_align(padding)[...], where padding is a arbitrary generator
158 // expression. It uses a default value for the generated width (defined
159 // via the BOOST_KARMA_DEFAULT_FIELD_LENGTH constant).
160 ///////////////////////////////////////////////////////////////////////////
161 template <typename Subject, typename Padding
162 , typename Width = detail::default_width>
163 struct padding_left_alignment
164 : unary_generator<padding_left_alignment<Subject, Padding, Width> >
165 {
166 typedef Subject subject_type;
167 typedef Padding padding_type;
168
169 typedef mpl::int_<
170 generator_properties::counting |
171 subject_type::properties::value | padding_type::properties::value
172 > properties;
173
174 template <typename Context, typename Iterator>
175 struct attribute
176 : traits::attribute_of<subject_type, Context, Iterator>
177 {};
178
179 padding_left_alignment(Subject const& subject, Padding const& padding
180 , Width width = Width())
181 : subject(subject), padding(padding), width(width) {}
182
183 template <typename OutputIterator, typename Context, typename Delimiter
184 , typename Attribute>
185 bool generate(OutputIterator& sink, Context& ctx, Delimiter const& d
186 , Attribute const& attr) const
187 {
188 return detail::left_align_generate(sink, ctx, d, attr,
189 subject, width, padding);
190 }
191
192 template <typename Context>
193 info what(Context& context) const
194 {
195 return info("left_align", subject.what(context));
196 }
197
198 Subject subject;
199 Padding padding;
200 Width width;
201 };
202
203 ///////////////////////////////////////////////////////////////////////////
204 // Generator generators: make_xxx function (objects)
205 ///////////////////////////////////////////////////////////////////////////
206
207 // creates left_align[] directive generator
208 template <typename Subject, typename Modifiers>
209 struct make_directive<tag::left_align, Subject, Modifiers>
210 {
211 typedef simple_left_alignment<Subject> result_type;
212 result_type operator()(unused_type, Subject const& subject
213 , unused_type) const
214 {
215 return result_type(subject);
216 }
217 };
218
219 // creates left_align(width)[] directive generator
220 template <typename Width, typename Subject, typename Modifiers>
221 struct make_directive<
222 terminal_ex<tag::left_align, fusion::vector1<Width> >
223 , Subject, Modifiers
224 , typename enable_if_c< integer_traits<Width>::is_integral >::type>
225 {
226 typedef simple_left_alignment<Subject, Width> result_type;
227
228 template <typename Terminal>
229 result_type operator()(Terminal const& term, Subject const& subject
230 , unused_type) const
231 {
232 return result_type(subject, fusion::at_c<0>(term.args));
233 }
234 };
235
236 // creates left_align(pad)[] directive generator
237 template <typename Padding, typename Subject, typename Modifiers>
238 struct make_directive<
239 terminal_ex<tag::left_align, fusion::vector1<Padding> >
240 , Subject, Modifiers
241 , typename enable_if<
242 mpl::and_<
243 spirit::traits::matches<karma::domain, Padding>,
244 mpl::not_<mpl::bool_<integer_traits<Padding>::is_integral> >
245 >
246 >::type>
247 {
248 typedef typename
249 result_of::compile<karma::domain, Padding, Modifiers>::type
250 padding_type;
251
252 typedef padding_left_alignment<Subject, padding_type> result_type;
253
254 template <typename Terminal>
255 result_type operator()(Terminal const& term, Subject const& subject
256 , Modifiers const& modifiers) const
257 {
258 return result_type(subject
259 , compile<karma::domain>(fusion::at_c<0>(term.args), modifiers));
260 }
261 };
262
263 // creates left_align(width, pad)[] directive generator
264 template <typename Width, typename Padding, typename Subject
265 , typename Modifiers>
266 struct make_directive<
267 terminal_ex<tag::left_align, fusion::vector2<Width, Padding> >
268 , Subject, Modifiers>
269 {
270 typedef typename
271 result_of::compile<karma::domain, Padding, Modifiers>::type
272 padding_type;
273
274 typedef padding_left_alignment<Subject, padding_type, Width> result_type;
275
276 template <typename Terminal>
277 result_type operator()(Terminal const& term, Subject const& subject
278 , Modifiers const& modifiers) const
279 {
280 return result_type(subject
281 , compile<karma::domain>(fusion::at_c<1>(term.args), modifiers)
282 , fusion::at_c<0>(term.args));
283 }
284 };
285
286}}} // namespace boost::spirit::karma
287
288namespace boost { namespace spirit { namespace traits
289{
290 ///////////////////////////////////////////////////////////////////////////
291 template <typename Subject, typename Width>
292 struct has_semantic_action<karma::simple_left_alignment<Subject, Width> >
293 : unary_has_semantic_action<Subject> {};
294
295 template <typename Subject, typename Padding, typename Width>
296 struct has_semantic_action<
297 karma::padding_left_alignment<Subject, Padding, Width> >
298 : unary_has_semantic_action<Subject> {};
299
300 ///////////////////////////////////////////////////////////////////////////
301 template <typename Subject, typename Width, typename Attribute
302 , typename Context, typename Iterator>
303 struct handles_container<
304 karma::simple_left_alignment<Subject, Width>, Attribute
305 , Context, Iterator>
306 : unary_handles_container<Subject, Attribute, Context, Iterator> {};
307
308 template <typename Subject, typename Padding, typename Width
309 , typename Attribute, typename Context, typename Iterator>
310 struct handles_container<
311 karma::padding_left_alignment<Subject, Padding, Width>
312 , Attribute, Context, Iterator>
313 : unary_handles_container<Subject, Attribute, Context, Iterator> {};
314}}}
315
316#endif
317
318