File indexing completed on 2025-01-19 09:47:37
0001
0002
0003
0004
0005
0006 #if !defined(BOOST_SPIRIT_KARMA_RIGHT_ALIGNMENT_FEB_27_2007_1216PM)
0007 #define BOOST_SPIRIT_KARMA_RIGHT_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/support/has_semantic_action.hpp>
0024 #include <boost/spirit/home/support/handles_container.hpp>
0025 #include <boost/spirit/home/karma/detail/attributes.hpp>
0026 #include <boost/spirit/home/support/info.hpp>
0027 #include <boost/spirit/home/support/unused.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::right_align>
0045 : mpl::true_ {};
0046
0047
0048
0049 template <typename T>
0050 struct use_directive<karma::domain
0051 , terminal_ex<tag::right_align, fusion::vector1<T> > >
0052 : mpl::true_ {};
0053
0054
0055 template <>
0056 struct use_lazy_directive<karma::domain, tag::right_align, 1>
0057 : mpl::true_ {};
0058
0059
0060
0061 template <typename Width, typename Padding>
0062 struct use_directive<karma::domain
0063 , terminal_ex<tag::right_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::right_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::right_align;
0079 #endif
0080 using spirit::right_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 right_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_buffering<OutputIterator> buffering(sink, width);
0100 bool r = false;
0101
0102
0103 {
0104 detail::disable_counting<OutputIterator> nocounting(sink);
0105 r = e.generate(sink, ctx, d, attr);
0106 }
0107
0108 buffering.disable();
0109
0110
0111 detail::enable_counting<OutputIterator> counting(sink, buffering.buffer_size());
0112 while(r && counting.count() < width)
0113 r = p.generate(sink, ctx, unused, unused);
0114
0115
0116 if (r)
0117 buffering.buffer_copy();
0118 return r;
0119 }
0120 }
0121
0122
0123
0124
0125
0126
0127
0128 template <typename Subject, typename Width = detail::default_width>
0129 struct simple_right_alignment
0130 : unary_generator<simple_right_alignment<Subject, Width> >
0131 {
0132 typedef Subject subject_type;
0133
0134 typedef mpl::int_<
0135 generator_properties::countingbuffer | subject_type::properties::value
0136 > properties;
0137
0138 template <typename Context, typename Iterator>
0139 struct attribute
0140 : traits::attribute_of<subject_type, Context, Iterator>
0141 {};
0142
0143 simple_right_alignment(Subject const& subject, Width width = Width())
0144 : subject(subject), width(width) {}
0145
0146 template <typename OutputIterator, typename Context, typename Delimiter
0147 , typename Attribute>
0148 bool generate(OutputIterator& sink, Context& ctx, Delimiter const& d
0149 , Attribute const& attr) const
0150 {
0151 return detail::right_align_generate(sink, ctx, d, attr,
0152 subject, width, compile<karma::domain>(' '));
0153 }
0154
0155 template <typename Context>
0156 info what(Context& context) const
0157 {
0158 return info("right_align", subject.what(context));
0159 }
0160
0161 Subject subject;
0162 Width width;
0163 };
0164
0165
0166
0167
0168
0169
0170
0171 template <typename Subject, typename Padding
0172 , typename Width = detail::default_width>
0173 struct padding_right_alignment
0174 : unary_generator<padding_right_alignment<Subject, Padding, Width> >
0175 {
0176 typedef Subject subject_type;
0177 typedef Padding padding_type;
0178
0179 typedef mpl::int_<
0180 generator_properties::countingbuffer |
0181 subject_type::properties::value | padding_type::properties::value
0182 > properties;
0183
0184 template <typename Context, typename Iterator>
0185 struct attribute
0186 : traits::attribute_of<subject_type, Context, Iterator>
0187 {};
0188
0189 padding_right_alignment(Subject const& subject, Padding const& padding
0190 , Width width = Width())
0191 : subject(subject), padding(padding), width(width) {}
0192
0193 template <typename OutputIterator, typename Context, typename Delimiter
0194 , typename Attribute>
0195 bool generate(OutputIterator& sink, Context& ctx, Delimiter const& d
0196 , Attribute const& attr) const
0197 {
0198 return detail::right_align_generate(sink, ctx, d, attr,
0199 subject, width, padding);
0200 }
0201
0202 template <typename Context>
0203 info what(Context& context) const
0204 {
0205 return info("right_align", subject.what(context));
0206 }
0207
0208 Subject subject;
0209 Padding padding;
0210 Width width;
0211 };
0212
0213
0214
0215
0216
0217
0218 template <typename Subject, typename Modifiers>
0219 struct make_directive<tag::right_align, Subject, Modifiers>
0220 {
0221 typedef simple_right_alignment<Subject> result_type;
0222 result_type operator()(unused_type, Subject const& subject
0223 , unused_type) const
0224 {
0225 return result_type(subject);
0226 }
0227 };
0228
0229
0230 template <typename Width, typename Subject, typename Modifiers>
0231 struct make_directive<
0232 terminal_ex<tag::right_align, fusion::vector1<Width> >
0233 , Subject, Modifiers
0234 , typename enable_if_c< integer_traits<Width>::is_integral >::type>
0235 {
0236 typedef simple_right_alignment<Subject, Width> result_type;
0237
0238 template <typename Terminal>
0239 result_type operator()(Terminal const& term, Subject const& subject
0240 , unused_type) const
0241 {
0242 return result_type(subject, fusion::at_c<0>(term.args));
0243 }
0244 };
0245
0246
0247 template <typename Padding, typename Subject, typename Modifiers>
0248 struct make_directive<
0249 terminal_ex<tag::right_align, fusion::vector1<Padding> >
0250 , Subject, Modifiers
0251 , typename enable_if<
0252 mpl::and_<
0253 spirit::traits::matches<karma::domain, Padding>,
0254 mpl::not_<mpl::bool_<integer_traits<Padding>::is_integral> >
0255 >
0256 >::type>
0257 {
0258 typedef typename
0259 result_of::compile<karma::domain, Padding, Modifiers>::type
0260 padding_type;
0261
0262 typedef padding_right_alignment<Subject, padding_type> result_type;
0263
0264 template <typename Terminal>
0265 result_type operator()(Terminal const& term, Subject const& subject
0266 , Modifiers const& modifiers) const
0267 {
0268 return result_type(subject
0269 , compile<karma::domain>(fusion::at_c<0>(term.args), modifiers));
0270 }
0271 };
0272
0273
0274 template <typename Width, typename Padding, typename Subject
0275 , typename Modifiers>
0276 struct make_directive<
0277 terminal_ex<tag::right_align, fusion::vector2<Width, Padding> >
0278 , Subject, Modifiers>
0279 {
0280 typedef typename
0281 result_of::compile<karma::domain, Padding, Modifiers>::type
0282 padding_type;
0283
0284 typedef padding_right_alignment<Subject, padding_type, Width> result_type;
0285
0286 template <typename Terminal>
0287 result_type operator()(Terminal const& term, Subject const& subject
0288 , Modifiers const& modifiers) const
0289 {
0290 return result_type(subject
0291 , compile<karma::domain>(fusion::at_c<1>(term.args), modifiers)
0292 , fusion::at_c<0>(term.args));
0293 }
0294 };
0295
0296 }}}
0297
0298 namespace boost { namespace spirit { namespace traits
0299 {
0300
0301 template <typename Subject, typename Width>
0302 struct has_semantic_action<karma::simple_right_alignment<Subject, Width> >
0303 : unary_has_semantic_action<Subject> {};
0304
0305 template <typename Subject, typename Padding, typename Width>
0306 struct has_semantic_action<
0307 karma::padding_right_alignment<Subject, Padding, Width> >
0308 : unary_has_semantic_action<Subject> {};
0309
0310
0311 template <typename Subject, typename Width, typename Attribute
0312 , typename Context, typename Iterator>
0313 struct handles_container<
0314 karma::simple_right_alignment<Subject, Width>
0315 , Attribute, Context, Iterator>
0316 : unary_handles_container<Subject, Attribute, Context, Iterator> {};
0317
0318 template <typename Subject, typename Padding, typename Width
0319 , typename Attribute, typename Context, typename Iterator>
0320 struct handles_container<
0321 karma::padding_right_alignment<Subject, Padding, Width>
0322 , Attribute, Context, Iterator>
0323 : unary_handles_container<Subject, Attribute, Context, Iterator> {};
0324 }}}
0325
0326 #endif
0327