PageRenderTime 39ms CodeModel.GetById 21ms app.highlight 13ms RepoModel.GetById 1ms app.codeStats 0ms

/Src/Dependencies/Boost/boost/spirit/home/karma/directive/buffer.hpp

http://hadesmem.googlecode.com/
C++ Header | 132 lines | 96 code | 17 blank | 19 comment | 1 complexity | 737c32b2c71c947b1c8f929bc3b9d0e6 MD5 | raw file
  1//  Copyright (c) 2001-2011 Hartmut Kaiser
  2//
  3//  Distributed under the Boost Software License, Version 1.0. (See accompanying
  4//  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  5
  6#if !defined(SPIRIT_KARMA_BUFFER_AUG_03_2009_0949AM)
  7#define SPIRIT_KARMA_BUFFER_AUG_03_2009_0949AM
  8
  9#if defined(_MSC_VER)
 10#pragma once
 11#endif
 12
 13#include <boost/spirit/home/karma/meta_compiler.hpp>
 14#include <boost/spirit/home/karma/generator.hpp>
 15#include <boost/spirit/home/karma/domain.hpp>
 16#include <boost/spirit/home/karma/detail/output_iterator.hpp>
 17#include <boost/spirit/home/support/unused.hpp>
 18#include <boost/spirit/home/support/info.hpp>
 19#include <boost/spirit/home/support/common_terminals.hpp>
 20#include <boost/spirit/home/support/has_semantic_action.hpp>
 21#include <boost/spirit/home/support/handles_container.hpp>
 22#include <boost/spirit/home/karma/detail/attributes.hpp>
 23
 24namespace boost { namespace spirit
 25{
 26    ///////////////////////////////////////////////////////////////////////////
 27    // Enablers
 28    ///////////////////////////////////////////////////////////////////////////
 29    template <>
 30    struct use_directive<karma::domain, tag::buffer> // enables buffer
 31      : mpl::true_ {};
 32
 33}}
 34
 35namespace boost { namespace spirit { namespace karma
 36{
 37#ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS
 38    using spirit::buffer;
 39#endif
 40    using spirit::buffer_type;
 41
 42    ///////////////////////////////////////////////////////////////////////////
 43    // buffer_directive buffers all generated output of the embedded generator
 44    // and flushes it only if the whole embedded generator succeeds
 45    ///////////////////////////////////////////////////////////////////////////
 46    template <typename Subject>
 47    struct buffer_directive : unary_generator<buffer_directive<Subject> >
 48    {
 49        typedef Subject subject_type;
 50        typedef mpl::int_<
 51            subject_type::properties::value | 
 52            generator_properties::countingbuffer
 53        > properties;
 54
 55        buffer_directive(Subject const& subject)
 56          : subject(subject) {}
 57
 58        template <typename Context, typename Iterator>
 59        struct attribute
 60          : traits::attribute_of<subject_type, Context, Iterator>
 61        {};
 62
 63        template <typename OutputIterator, typename Context, typename Delimiter
 64          , typename Attribute>
 65        bool generate(OutputIterator& sink, Context& ctx, Delimiter const& d
 66          , Attribute const& attr) const
 67        {
 68            // wrap the given output iterator to avoid output as long as the
 69            // embedded generator (subject) fails
 70            detail::enable_buffering<OutputIterator> buffering(sink);
 71            bool r = false;
 72            {
 73                detail::disable_counting<OutputIterator> nocounting(sink);
 74                r = subject.generate(sink, ctx, d, attr);
 75            }
 76            if (r) 
 77                buffering.buffer_copy();
 78            return r;
 79        }
 80
 81        template <typename Context>
 82        info what(Context& context) const
 83        {
 84            return info("buffer", subject.what(context));
 85        }
 86
 87        Subject subject;
 88    };
 89
 90    ///////////////////////////////////////////////////////////////////////////
 91    // Generator generators: make_xxx function (objects)
 92    ///////////////////////////////////////////////////////////////////////////
 93    template <typename Subject, typename Modifiers>
 94    struct make_directive<tag::buffer, Subject, Modifiers>
 95    {
 96        typedef buffer_directive<Subject> result_type;
 97        result_type operator()(unused_type, Subject const& subject
 98          , unused_type) const
 99        {
100            return result_type(subject);
101        }
102    };
103
104    // make sure buffer[buffer[...]] does not result in double buffering
105    template <typename Subject, typename Modifiers>
106    struct make_directive<tag::buffer, buffer_directive<Subject>, Modifiers>
107    {
108        typedef buffer_directive<Subject> result_type;
109        result_type operator()(unused_type
110          , buffer_directive<Subject> const& subject, unused_type) const
111        {
112            return subject;
113        }
114    };
115}}}
116
117namespace boost { namespace spirit { namespace traits
118{
119    ///////////////////////////////////////////////////////////////////////////
120    template <typename Subject>
121    struct has_semantic_action<karma::buffer_directive<Subject> >
122      : unary_has_semantic_action<Subject> {};
123
124    ///////////////////////////////////////////////////////////////////////////
125    template <typename Subject, typename Attribute, typename Context
126        , typename Iterator>
127    struct handles_container<karma::buffer_directive<Subject>, Attribute
128        , Context, Iterator>
129      : unary_handles_container<Subject, Attribute, Context, Iterator> {};
130}}}
131
132#endif