File indexing completed on 2025-01-19 09:47:36
0001
0002
0003
0004
0005
0006 #if !defined(BOOST_SPIRIT_KARMA_MAXWIDTH_MAR_18_2009_0827AM)
0007 #define BOOST_SPIRIT_KARMA_MAXWIDTH_MAR_18_2009_0827AM
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/support/unused.hpp>
0021 #include <boost/spirit/home/support/common_terminals.hpp>
0022 #include <boost/spirit/home/support/has_semantic_action.hpp>
0023 #include <boost/spirit/home/support/handles_container.hpp>
0024 #include <boost/spirit/home/karma/detail/attributes.hpp>
0025 #include <boost/spirit/home/support/info.hpp>
0026 #include <boost/spirit/home/support/unused.hpp>
0027 #include <boost/fusion/include/at.hpp>
0028 #include <boost/fusion/include/vector.hpp>
0029 #include <boost/detail/workaround.hpp>
0030
0031
0032 namespace boost { namespace spirit
0033 {
0034
0035
0036
0037
0038
0039 template <>
0040 struct use_directive<karma::domain, tag::maxwidth>
0041 : mpl::true_ {};
0042
0043
0044 template <typename T>
0045 struct use_directive<karma::domain
0046 , terminal_ex<tag::maxwidth, fusion::vector1<T> > >
0047 : mpl::true_ {};
0048
0049
0050 template <>
0051 struct use_lazy_directive<karma::domain, tag::maxwidth, 1>
0052 : mpl::true_ {};
0053
0054
0055
0056
0057 template <typename T, typename RestIter>
0058 struct use_directive<karma::domain
0059 , terminal_ex<tag::maxwidth, fusion::vector2<T, RestIter> > >
0060 : mpl::true_ {};
0061
0062
0063
0064
0065 template <>
0066 struct use_lazy_directive<karma::domain, tag::maxwidth, 2>
0067 : mpl::true_ {};
0068
0069 }}
0070
0071
0072 namespace boost { namespace spirit { namespace karma
0073 {
0074 #ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS
0075 using spirit::maxwidth;
0076 #endif
0077 using spirit::maxwidth_type;
0078
0079 namespace detail
0080 {
0081
0082 template <typename OutputIterator, typename RestIterator>
0083 bool buffer_copy_rest(detail::enable_buffering<OutputIterator>& buff
0084 , std::size_t start_at, RestIterator& dest)
0085 {
0086 return buff.buffer_copy_rest(dest, start_at);
0087 }
0088
0089 template <typename OutputIterator>
0090 bool buffer_copy_rest(detail::enable_buffering<OutputIterator>&
0091 , std::size_t, unused_type)
0092 {
0093 return true;
0094 }
0095
0096
0097
0098
0099
0100 template <typename OutputIterator, typename Context, typename Delimiter,
0101 typename Attribute, typename Embedded, typename Rest>
0102 inline static bool
0103 maxwidth_generate(OutputIterator& sink, Context& ctx,
0104 Delimiter const& d, Attribute const& attr, Embedded const& e,
0105 unsigned int const maxwidth, Rest& restdest)
0106 {
0107 #if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1600))
0108 (void)e;
0109 #endif
0110
0111
0112 detail::enable_buffering<OutputIterator> buffering(sink);
0113
0114
0115
0116
0117 bool r = false;
0118 {
0119 detail::disable_counting<OutputIterator> nocounting(sink);
0120 r = e.generate(sink, ctx, d, attr);
0121 }
0122
0123 return r && buffering.buffer_copy(maxwidth) &&
0124 buffer_copy_rest(buffering, maxwidth, restdest);
0125 }
0126 }
0127
0128
0129
0130
0131
0132
0133
0134
0135
0136 template <typename Subject, typename Width = detail::default_max_width
0137 , typename Rest = unused_type>
0138 struct maxwidth_width
0139 : unary_generator<maxwidth_width<Subject, Width, Rest> >
0140 {
0141 typedef Subject subject_type;
0142
0143 typedef mpl::int_<
0144 generator_properties::countingbuffer | subject_type::properties::value
0145 > properties;
0146
0147 template <typename Context, typename Iterator>
0148 struct attribute
0149 : traits::attribute_of<subject_type, Context, Iterator>
0150 {};
0151
0152 maxwidth_width(Subject const& subject, Width const& w = Width()
0153 , Rest const& r = Rest())
0154 : subject(subject), width(w), rest(r) {}
0155
0156 template <typename OutputIterator, typename Context, typename Delimiter
0157 , typename Attribute>
0158 bool generate(OutputIterator& sink, Context& ctx, Delimiter const& d
0159 , Attribute const& attr) const
0160 {
0161 return detail::maxwidth_generate(sink, ctx, d, attr, subject
0162 , width, rest);
0163 }
0164
0165 template <typename Context>
0166 info what(Context& context) const
0167 {
0168 return info("maxwidth", subject.what(context));
0169 }
0170
0171 Subject subject;
0172 Width width;
0173 Rest rest;
0174 };
0175
0176
0177
0178
0179
0180
0181 template <typename Subject, typename Modifiers>
0182 struct make_directive<tag::maxwidth, Subject, Modifiers>
0183 {
0184 typedef maxwidth_width<Subject> result_type;
0185 result_type operator()(unused_type, Subject const& subject
0186 , unused_type) const
0187 {
0188 return result_type(subject);
0189 }
0190 };
0191
0192
0193 template <typename T, typename Subject, typename Modifiers>
0194 struct make_directive<
0195 terminal_ex<tag::maxwidth, fusion::vector1<T> >
0196 , Subject, Modifiers>
0197 {
0198 typedef maxwidth_width<Subject, T> result_type;
0199
0200 template <typename Terminal>
0201 result_type operator()(Terminal const& term, Subject const& subject
0202 , unused_type) const
0203 {
0204 return result_type(subject, fusion::at_c<0>(term.args), unused);
0205 }
0206 };
0207
0208
0209 template <
0210 typename T, typename RestIter, typename Subject, typename Modifiers>
0211 struct make_directive<
0212 terminal_ex<tag::maxwidth, fusion::vector2<T, RestIter> >
0213 , Subject, Modifiers>
0214 {
0215 typedef maxwidth_width<Subject, T, RestIter> result_type;
0216
0217 template <typename Terminal>
0218 result_type operator()(Terminal const& term, Subject const& subject
0219 , unused_type) const
0220 {
0221 return result_type(subject, fusion::at_c<0>(term.args)
0222 , fusion::at_c<1>(term.args));
0223 }
0224 };
0225
0226 }}}
0227
0228 namespace boost { namespace spirit { namespace traits
0229 {
0230
0231 template <typename Subject, typename Width, typename Rest>
0232 struct has_semantic_action<karma::maxwidth_width<Subject, Width, Rest> >
0233 : unary_has_semantic_action<Subject> {};
0234
0235
0236 template <typename Subject, typename Attribute, typename Context
0237 , typename Iterator>
0238 struct handles_container<karma::maxwidth_width<Subject>, Attribute
0239 , Context, Iterator>
0240 : unary_handles_container<Subject, Attribute, Context, Iterator> {};
0241 }}}
0242
0243 #endif
0244
0245