Chris@16: // Copyright (c) 2001-2011 Hartmut Kaiser Chris@16: // Chris@16: // Distributed under the Boost Software License, Version 1.0. (See accompanying Chris@16: // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) Chris@16: Chris@16: #if !defined(BOOST_SPIRIT_KARMA_MAXWIDTH_MAR_18_2009_0827AM) Chris@16: #define BOOST_SPIRIT_KARMA_MAXWIDTH_MAR_18_2009_0827AM Chris@16: Chris@16: #if defined(_MSC_VER) Chris@16: #pragma once Chris@16: #endif Chris@16: Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: namespace boost { namespace spirit Chris@16: { Chris@16: /////////////////////////////////////////////////////////////////////////// Chris@16: // Enablers Chris@16: /////////////////////////////////////////////////////////////////////////// Chris@16: Chris@16: // enables maxwidth[] Chris@16: template <> Chris@16: struct use_directive Chris@16: : mpl::true_ {}; Chris@16: Chris@16: // enables maxwidth(w)[g], where w provides a maxwidth Chris@16: template Chris@16: struct use_directive > > Chris@16: : mpl::true_ {}; Chris@16: Chris@16: // enables *lazy* maxwidth(w)[g], where w provides a maxwidth Chris@16: template <> Chris@16: struct use_lazy_directive Chris@16: : mpl::true_ {}; Chris@16: Chris@16: // enables maxwidth(w, r)[g], where w provides a maxwidth and r is an output Chris@16: // iterator used to receive the rest of the output not fitting into the Chris@16: // maxwidth limit Chris@16: template Chris@16: struct use_directive > > Chris@16: : mpl::true_ {}; Chris@16: Chris@16: // enables *lazy* maxwidth(w, r)[g], where w provides a maxwidth and r is Chris@16: // an output iterator used to receive the rest of the output not fitting Chris@16: // into the maxwidth limit Chris@16: template <> Chris@16: struct use_lazy_directive Chris@16: : mpl::true_ {}; Chris@16: Chris@16: }} Chris@16: Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: namespace boost { namespace spirit { namespace karma Chris@16: { Chris@16: #ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS Chris@16: using spirit::maxwidth; Chris@16: #endif Chris@16: using spirit::maxwidth_type; Chris@16: Chris@16: namespace detail Chris@16: { Chris@16: /////////////////////////////////////////////////////////////////////// Chris@16: template Chris@16: bool buffer_copy_rest(detail::enable_buffering& buff Chris@16: , std::size_t start_at, RestIterator& dest) Chris@16: { Chris@16: return buff.buffer_copy_rest(dest, start_at); Chris@16: } Chris@16: Chris@16: template Chris@16: bool buffer_copy_rest(detail::enable_buffering& Chris@16: , std::size_t, unused_type) Chris@16: { Chris@16: return true; Chris@16: } Chris@16: Chris@16: /////////////////////////////////////////////////////////////////////// Chris@16: // The maxwidth_generate template function is used for all the Chris@16: // different flavors of the maxwidth[] directive. Chris@16: /////////////////////////////////////////////////////////////////////// Chris@16: template Chris@16: inline static bool Chris@16: maxwidth_generate(OutputIterator& sink, Context& ctx, Chris@16: Delimiter const& d, Attribute const& attr, Embedded const& e, Chris@16: unsigned int const maxwidth, Rest& restdest) Chris@16: { Chris@16: #if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1600)) Chris@16: e; // suppresses warning: C4100: 'e' : unreferenced formal parameter Chris@16: #endif Chris@16: // wrap the given output iterator to allow buffering, but disable Chris@16: // counting Chris@16: detail::enable_buffering buffering(sink); Chris@16: Chris@16: // generate the underlying output and copy the embedded Chris@16: // output to the target output iterator applying the given Chris@16: // maxwidth Chris@16: bool r = false; Chris@16: { Chris@16: detail::disable_counting nocounting(sink); Chris@16: r = e.generate(sink, ctx, d, attr); Chris@16: } // re-enable counting Chris@16: Chris@16: return r && buffering.buffer_copy(maxwidth) && Chris@16: buffer_copy_rest(buffering, maxwidth, restdest); Chris@16: } Chris@16: } Chris@16: Chris@16: /////////////////////////////////////////////////////////////////////////// Chris@16: // The maxwidth directive is used for maxwidth[...] Chris@16: // generators. It uses default values for the generated width (defined via Chris@16: // the BOOST_KARMA_DEFAULT_FIELD_MAXWIDTH constant). Chris@16: // Chris@16: // The maxwidth with width directive, is used for generators Chris@16: // like maxwidth(width)[...]. Chris@16: /////////////////////////////////////////////////////////////////////////// Chris@16: template Chris@16: struct maxwidth_width Chris@16: : unary_generator > Chris@16: { Chris@16: typedef Subject subject_type; Chris@16: Chris@16: typedef mpl::int_< Chris@16: generator_properties::countingbuffer | subject_type::properties::value Chris@16: > properties; Chris@16: Chris@16: template Chris@16: struct attribute Chris@16: : traits::attribute_of Chris@16: {}; Chris@16: Chris@16: maxwidth_width(Subject const& subject, Width const& w = Width() Chris@16: , Rest const& r = Rest()) Chris@16: : subject(subject), width(w), rest(r) {} Chris@16: Chris@16: template Chris@16: bool generate(OutputIterator& sink, Context& ctx, Delimiter const& d Chris@16: , Attribute const& attr) const Chris@16: { Chris@16: return detail::maxwidth_generate(sink, ctx, d, attr, subject Chris@16: , width, rest); Chris@16: } Chris@16: Chris@16: template Chris@16: info what(Context& context) const Chris@16: { Chris@16: return info("maxwidth", subject.what(context)); Chris@16: } Chris@16: Chris@16: Subject subject; Chris@16: Width width; Chris@16: Rest rest; Chris@16: }; Chris@16: Chris@16: /////////////////////////////////////////////////////////////////////////// Chris@16: // Generator generators: make_xxx function (objects) Chris@16: /////////////////////////////////////////////////////////////////////////// Chris@16: Chris@16: // creates maxwidth[] directive generator Chris@16: template Chris@16: struct make_directive Chris@16: { Chris@16: typedef maxwidth_width result_type; Chris@16: result_type operator()(unused_type, Subject const& subject Chris@16: , unused_type) const Chris@16: { Chris@16: return result_type(subject); Chris@16: } Chris@16: }; Chris@16: Chris@16: // creates maxwidth(width)[] directive generator Chris@16: template Chris@16: struct make_directive< Chris@16: terminal_ex > Chris@16: , Subject, Modifiers> Chris@16: { Chris@16: typedef maxwidth_width result_type; Chris@16: Chris@16: template Chris@16: result_type operator()(Terminal const& term, Subject const& subject Chris@16: , unused_type) const Chris@16: { Chris@16: return result_type(subject, fusion::at_c<0>(term.args), unused); Chris@16: } Chris@16: }; Chris@16: Chris@16: // creates maxwidth(width, restiter)[] directive generator Chris@16: template < Chris@16: typename T, typename RestIter, typename Subject, typename Modifiers> Chris@16: struct make_directive< Chris@16: terminal_ex > Chris@16: , Subject, Modifiers> Chris@16: { Chris@16: typedef maxwidth_width result_type; Chris@16: Chris@16: template Chris@16: result_type operator()(Terminal const& term, Subject const& subject Chris@16: , unused_type) const Chris@16: { Chris@16: return result_type(subject, fusion::at_c<0>(term.args) Chris@16: , fusion::at_c<1>(term.args)); Chris@16: } Chris@16: }; Chris@16: Chris@16: }}} // namespace boost::spirit::karma Chris@16: Chris@16: namespace boost { namespace spirit { namespace traits Chris@16: { Chris@16: /////////////////////////////////////////////////////////////////////////// Chris@16: template Chris@16: struct has_semantic_action > Chris@16: : unary_has_semantic_action {}; Chris@16: Chris@16: /////////////////////////////////////////////////////////////////////////// Chris@16: template Chris@16: struct handles_container, Attribute Chris@16: , Context, Iterator> Chris@16: : unary_handles_container {}; Chris@16: }}} Chris@16: Chris@16: #endif Chris@16: Chris@16: