Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-19 09:47:36

0001 //  Copyright (c) 2001-2011 Hartmut Kaiser
0002 //
0003 //  Distributed under the Boost Software License, Version 1.0. (See accompanying
0004 //  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
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     // Enablers
0036     ///////////////////////////////////////////////////////////////////////////
0037 
0038     // enables maxwidth[]
0039     template <>
0040     struct use_directive<karma::domain, tag::maxwidth>
0041       : mpl::true_ {};
0042 
0043     // enables maxwidth(w)[g], where w provides a maxwidth
0044     template <typename T>
0045     struct use_directive<karma::domain
0046           , terminal_ex<tag::maxwidth, fusion::vector1<T> > > 
0047       : mpl::true_ {};
0048 
0049     // enables *lazy* maxwidth(w)[g], where w provides a maxwidth
0050     template <>
0051     struct use_lazy_directive<karma::domain, tag::maxwidth, 1> 
0052       : mpl::true_ {};
0053 
0054     // enables maxwidth(w, r)[g], where w provides a maxwidth and r is an output
0055     // iterator used to receive the rest of the output not fitting into the 
0056     // maxwidth limit
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     // enables *lazy* maxwidth(w, r)[g], where w provides a maxwidth and r is 
0063     // an output iterator used to receive the rest of the output not fitting 
0064     // into the maxwidth limit
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         //  The maxwidth_generate template function is used for all the 
0098         //  different flavors of the maxwidth[] directive. 
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; // suppresses warning: C4100: 'e' : unreferenced formal parameter
0109 #endif
0110             // wrap the given output iterator to allow buffering, but disable 
0111             // counting
0112             detail::enable_buffering<OutputIterator> buffering(sink);
0113 
0114             // generate the underlying output and copy the embedded 
0115             // output to the target output iterator applying the given 
0116             // maxwidth
0117             bool r = false;
0118             {
0119                 detail::disable_counting<OutputIterator> nocounting(sink);
0120                 r = e.generate(sink, ctx, d, attr);
0121             }   // re-enable counting
0122 
0123             return r && buffering.buffer_copy(maxwidth) &&
0124                    buffer_copy_rest(buffering, maxwidth, restdest);
0125         }
0126     }
0127 
0128     ///////////////////////////////////////////////////////////////////////////
0129     //  The maxwidth directive is used for maxwidth[...]
0130     //  generators. It uses default values for the generated width (defined via
0131     //  the BOOST_KARMA_DEFAULT_FIELD_MAXWIDTH constant).
0132     // 
0133     //  The maxwidth with width directive, is used for generators
0134     //  like maxwidth(width)[...]. 
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     // Generator generators: make_xxx function (objects)
0178     ///////////////////////////////////////////////////////////////////////////
0179 
0180     // creates maxwidth[] directive generator
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     // creates maxwidth(width)[] directive generator
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     // creates maxwidth(width, restiter)[] directive generator
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 }}} // namespace boost::spirit::karma
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