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 #ifndef BOOST_SPIRIT_KARMA_DIRECTIVE_BUFFER_HPP
0007 #define BOOST_SPIRIT_KARMA_DIRECTIVE_BUFFER_HPP
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/support/unused.hpp>
0018 #include <boost/spirit/home/support/info.hpp>
0019 #include <boost/spirit/home/support/common_terminals.hpp>
0020 #include <boost/spirit/home/support/has_semantic_action.hpp>
0021 #include <boost/spirit/home/support/handles_container.hpp>
0022 #include <boost/spirit/home/karma/detail/attributes.hpp>
0023 
0024 namespace boost { namespace spirit
0025 {
0026     ///////////////////////////////////////////////////////////////////////////
0027     // Enablers
0028     ///////////////////////////////////////////////////////////////////////////
0029     template <>
0030     struct use_directive<karma::domain, tag::buffer> // enables buffer
0031       : mpl::true_ {};
0032 
0033 }}
0034 
0035 namespace boost { namespace spirit { namespace karma
0036 {
0037 #ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS
0038     using spirit::buffer;
0039 #endif
0040     using spirit::buffer_type;
0041 
0042     ///////////////////////////////////////////////////////////////////////////
0043     // buffer_directive buffers all generated output of the embedded generator
0044     // and flushes it only if the whole embedded generator succeeds
0045     ///////////////////////////////////////////////////////////////////////////
0046     template <typename Subject>
0047     struct buffer_directive : unary_generator<buffer_directive<Subject> >
0048     {
0049         typedef Subject subject_type;
0050         typedef mpl::int_<
0051             subject_type::properties::value | 
0052             generator_properties::countingbuffer
0053         > properties;
0054 
0055         buffer_directive(Subject const& subject)
0056           : subject(subject) {}
0057 
0058         template <typename Context, typename Iterator>
0059         struct attribute
0060           : traits::attribute_of<subject_type, Context, Iterator>
0061         {};
0062 
0063         template <typename OutputIterator, typename Context, typename Delimiter
0064           , typename Attribute>
0065         bool generate(OutputIterator& sink, Context& ctx, Delimiter const& d
0066           , Attribute const& attr) const
0067         {
0068             // wrap the given output iterator to avoid output as long as the
0069             // embedded generator (subject) fails
0070             detail::enable_buffering<OutputIterator> buffering(sink);
0071             bool r = false;
0072             {
0073                 detail::disable_counting<OutputIterator> nocounting(sink);
0074                 r = subject.generate(sink, ctx, d, attr);
0075             }
0076             if (r) 
0077                 buffering.buffer_copy();
0078             return r;
0079         }
0080 
0081         template <typename Context>
0082         info what(Context& context) const
0083         {
0084             return info("buffer", subject.what(context));
0085         }
0086 
0087         Subject subject;
0088     };
0089 
0090     ///////////////////////////////////////////////////////////////////////////
0091     // Generator generators: make_xxx function (objects)
0092     ///////////////////////////////////////////////////////////////////////////
0093     template <typename Subject, typename Modifiers>
0094     struct make_directive<tag::buffer, Subject, Modifiers>
0095     {
0096         typedef buffer_directive<Subject> result_type;
0097         result_type operator()(unused_type, Subject const& subject
0098           , unused_type) const
0099         {
0100             return result_type(subject);
0101         }
0102     };
0103 
0104     // make sure buffer[buffer[...]] does not result in double buffering
0105     template <typename Subject, typename Modifiers>
0106     struct make_directive<tag::buffer, buffer_directive<Subject>, Modifiers>
0107     {
0108         typedef buffer_directive<Subject> result_type;
0109         result_type operator()(unused_type
0110           , buffer_directive<Subject> const& subject, unused_type) const
0111         {
0112             return subject;
0113         }
0114     };
0115 }}}
0116 
0117 namespace boost { namespace spirit { namespace traits
0118 {
0119     ///////////////////////////////////////////////////////////////////////////
0120     template <typename Subject>
0121     struct has_semantic_action<karma::buffer_directive<Subject> >
0122       : unary_has_semantic_action<Subject> {};
0123 
0124     ///////////////////////////////////////////////////////////////////////////
0125     template <typename Subject, typename Attribute, typename Context
0126         , typename Iterator>
0127     struct handles_container<karma::buffer_directive<Subject>, Attribute
0128         , Context, Iterator>
0129       : unary_handles_container<Subject, Attribute, Context, Iterator> {};
0130 }}}
0131 
0132 #endif