File indexing completed on 2025-01-19 09:47:36
0001
0002
0003
0004
0005
0006 #if !defined(BOOST_SPIRIT_KARMA_LEFT_ALIGNMENT_FEB_27_2007_1216PM)
0007 #define BOOST_SPIRIT_KARMA_LEFT_ALIGNMENT_FEB_27_2007_1216PM
0008
0009 #if defined(_MSC_VER)
0010 #pragma once
0011 #endif
0012
0013 #include <boost/spirit/home/karma/meta_compiler.hpp>
0014 #include <boost/spirit/home/karma/generator.hpp>
0015 #include <boost/spirit/home/karma/domain.hpp>
0016 #include <boost/spirit/home/karma/detail/output_iterator.hpp>
0017 #include <boost/spirit/home/karma/detail/default_width.hpp>
0018 #include <boost/spirit/home/karma/delimit_out.hpp>
0019 #include <boost/spirit/home/karma/auxiliary/lazy.hpp>
0020 #include <boost/spirit/home/karma/char/char.hpp>
0021 #include <boost/spirit/home/support/unused.hpp>
0022 #include <boost/spirit/home/support/common_terminals.hpp>
0023 #include <boost/spirit/home/karma/detail/attributes.hpp>
0024 #include <boost/spirit/home/support/info.hpp>
0025 #include <boost/spirit/home/support/unused.hpp>
0026 #include <boost/spirit/home/support/has_semantic_action.hpp>
0027 #include <boost/spirit/home/support/handles_container.hpp>
0028 #include <boost/fusion/include/at.hpp>
0029 #include <boost/fusion/include/vector.hpp>
0030 #include <boost/integer_traits.hpp>
0031 #include <boost/mpl/bool.hpp>
0032 #include <boost/utility/enable_if.hpp>
0033 #include <boost/detail/workaround.hpp>
0034
0035
0036 namespace boost { namespace spirit
0037 {
0038
0039
0040
0041
0042
0043 template <>
0044 struct use_directive<karma::domain, tag::left_align>
0045 : mpl::true_ {};
0046
0047
0048
0049 template <typename T>
0050 struct use_directive<karma::domain
0051 , terminal_ex<tag::left_align, fusion::vector1<T> > >
0052 : mpl::true_ {};
0053
0054
0055 template <>
0056 struct use_lazy_directive<karma::domain, tag::left_align, 1>
0057 : mpl::true_ {};
0058
0059
0060
0061 template <typename Width, typename Padding>
0062 struct use_directive<karma::domain
0063 , terminal_ex<tag::left_align, fusion::vector2<Width, Padding> > >
0064 : spirit::traits::matches<karma::domain, Padding> {};
0065
0066
0067
0068 template <>
0069 struct use_lazy_directive<karma::domain, tag::left_align, 2>
0070 : mpl::true_ {};
0071
0072 }}
0073
0074
0075 namespace boost { namespace spirit { namespace karma
0076 {
0077 #ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS
0078 using spirit::left_align;
0079 #endif
0080 using spirit::left_align_type;
0081
0082 namespace detail
0083 {
0084
0085
0086
0087
0088 template <typename OutputIterator, typename Context, typename Delimiter,
0089 typename Attribute, typename Embedded, typename Padding>
0090 inline static bool
0091 left_align_generate(OutputIterator& sink, Context& ctx,
0092 Delimiter const& d, Attribute const& attr, Embedded const& e,
0093 unsigned int const width, Padding const& p)
0094 {
0095 #if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1600))
0096 (void)e;
0097 #endif
0098
0099 detail::enable_counting<OutputIterator> counting(sink);
0100
0101
0102 bool r = e.generate(sink, ctx, d, attr);
0103
0104
0105 while(r && counting.count() < width)
0106 r = p.generate(sink, ctx, unused, unused);
0107
0108 return r;
0109 }
0110 }
0111
0112
0113
0114
0115
0116
0117
0118 template <typename Subject, typename Width = detail::default_width>
0119 struct simple_left_alignment
0120 : unary_generator<simple_left_alignment<Subject, Width> >
0121 {
0122 typedef Subject subject_type;
0123
0124 typedef mpl::int_<
0125 generator_properties::counting | subject_type::properties::value
0126 > properties;
0127
0128 template <typename Context, typename Iterator>
0129 struct attribute
0130 : traits::attribute_of<subject_type, Context, Iterator>
0131 {};
0132
0133 simple_left_alignment(Subject const& subject, Width width = Width())
0134 : subject(subject), width(width) {}
0135
0136 template <typename OutputIterator, typename Context, typename Delimiter
0137 , typename Attribute>
0138 bool generate(OutputIterator& sink, Context& ctx, Delimiter const& d
0139 , Attribute const& attr) const
0140 {
0141 return detail::left_align_generate(sink, ctx, d, attr,
0142 subject, width, compile<karma::domain>(' '));
0143 }
0144
0145 template <typename Context>
0146 info what(Context& context) const
0147 {
0148 return info("left_align", subject.what(context));
0149 }
0150
0151 Subject subject;
0152 Width width;
0153 };
0154
0155
0156
0157
0158
0159
0160
0161 template <typename Subject, typename Padding
0162 , typename Width = detail::default_width>
0163 struct padding_left_alignment
0164 : unary_generator<padding_left_alignment<Subject, Padding, Width> >
0165 {
0166 typedef Subject subject_type;
0167 typedef Padding padding_type;
0168
0169 typedef mpl::int_<
0170 generator_properties::counting |
0171 subject_type::properties::value | padding_type::properties::value
0172 > properties;
0173
0174 template <typename Context, typename Iterator>
0175 struct attribute
0176 : traits::attribute_of<subject_type, Context, Iterator>
0177 {};
0178
0179 padding_left_alignment(Subject const& subject, Padding const& padding
0180 , Width width = Width())
0181 : subject(subject), padding(padding), width(width) {}
0182
0183 template <typename OutputIterator, typename Context, typename Delimiter
0184 , typename Attribute>
0185 bool generate(OutputIterator& sink, Context& ctx, Delimiter const& d
0186 , Attribute const& attr) const
0187 {
0188 return detail::left_align_generate(sink, ctx, d, attr,
0189 subject, width, padding);
0190 }
0191
0192 template <typename Context>
0193 info what(Context& context) const
0194 {
0195 return info("left_align", subject.what(context));
0196 }
0197
0198 Subject subject;
0199 Padding padding;
0200 Width width;
0201 };
0202
0203
0204
0205
0206
0207
0208 template <typename Subject, typename Modifiers>
0209 struct make_directive<tag::left_align, Subject, Modifiers>
0210 {
0211 typedef simple_left_alignment<Subject> result_type;
0212 result_type operator()(unused_type, Subject const& subject
0213 , unused_type) const
0214 {
0215 return result_type(subject);
0216 }
0217 };
0218
0219
0220 template <typename Width, typename Subject, typename Modifiers>
0221 struct make_directive<
0222 terminal_ex<tag::left_align, fusion::vector1<Width> >
0223 , Subject, Modifiers
0224 , typename enable_if_c< integer_traits<Width>::is_integral >::type>
0225 {
0226 typedef simple_left_alignment<Subject, Width> result_type;
0227
0228 template <typename Terminal>
0229 result_type operator()(Terminal const& term, Subject const& subject
0230 , unused_type) const
0231 {
0232 return result_type(subject, fusion::at_c<0>(term.args));
0233 }
0234 };
0235
0236
0237 template <typename Padding, typename Subject, typename Modifiers>
0238 struct make_directive<
0239 terminal_ex<tag::left_align, fusion::vector1<Padding> >
0240 , Subject, Modifiers
0241 , typename enable_if<
0242 mpl::and_<
0243 spirit::traits::matches<karma::domain, Padding>,
0244 mpl::not_<mpl::bool_<integer_traits<Padding>::is_integral> >
0245 >
0246 >::type>
0247 {
0248 typedef typename
0249 result_of::compile<karma::domain, Padding, Modifiers>::type
0250 padding_type;
0251
0252 typedef padding_left_alignment<Subject, padding_type> result_type;
0253
0254 template <typename Terminal>
0255 result_type operator()(Terminal const& term, Subject const& subject
0256 , Modifiers const& modifiers) const
0257 {
0258 return result_type(subject
0259 , compile<karma::domain>(fusion::at_c<0>(term.args), modifiers));
0260 }
0261 };
0262
0263
0264 template <typename Width, typename Padding, typename Subject
0265 , typename Modifiers>
0266 struct make_directive<
0267 terminal_ex<tag::left_align, fusion::vector2<Width, Padding> >
0268 , Subject, Modifiers>
0269 {
0270 typedef typename
0271 result_of::compile<karma::domain, Padding, Modifiers>::type
0272 padding_type;
0273
0274 typedef padding_left_alignment<Subject, padding_type, Width> result_type;
0275
0276 template <typename Terminal>
0277 result_type operator()(Terminal const& term, Subject const& subject
0278 , Modifiers const& modifiers) const
0279 {
0280 return result_type(subject
0281 , compile<karma::domain>(fusion::at_c<1>(term.args), modifiers)
0282 , fusion::at_c<0>(term.args));
0283 }
0284 };
0285
0286 }}}
0287
0288 namespace boost { namespace spirit { namespace traits
0289 {
0290
0291 template <typename Subject, typename Width>
0292 struct has_semantic_action<karma::simple_left_alignment<Subject, Width> >
0293 : unary_has_semantic_action<Subject> {};
0294
0295 template <typename Subject, typename Padding, typename Width>
0296 struct has_semantic_action<
0297 karma::padding_left_alignment<Subject, Padding, Width> >
0298 : unary_has_semantic_action<Subject> {};
0299
0300
0301 template <typename Subject, typename Width, typename Attribute
0302 , typename Context, typename Iterator>
0303 struct handles_container<
0304 karma::simple_left_alignment<Subject, Width>, Attribute
0305 , Context, Iterator>
0306 : unary_handles_container<Subject, Attribute, Context, Iterator> {};
0307
0308 template <typename Subject, typename Padding, typename Width
0309 , typename Attribute, typename Context, typename Iterator>
0310 struct handles_container<
0311 karma::padding_left_alignment<Subject, Padding, Width>
0312 , Attribute, Context, Iterator>
0313 : unary_handles_container<Subject, Attribute, Context, Iterator> {};
0314 }}}
0315
0316 #endif
0317
0318