PageRenderTime 29ms CodeModel.GetById 14ms app.highlight 12ms RepoModel.GetById 1ms app.codeStats 0ms

/Src/Dependencies/Boost/boost/spirit/home/karma/operator/plus.hpp

http://hadesmem.googlecode.com/
C++ Header | 226 lines | 159 code | 33 blank | 34 comment | 9 complexity | 7dca8fe54e9619fb90c1395209e166de MD5 | raw file
  1//  Copyright (c) 2001-2011 Joel de Guzman
  2//  Copyright (c) 2001-2011 Hartmut Kaiser
  3//
  4//  Distributed under the Boost Software License, Version 1.0. (See accompanying
  5//  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  6
  7#if !defined(BOOST_SPIRIT_KARMA_POSITIVE_MAR_03_2007_0945PM)
  8#define BOOST_SPIRIT_KARMA_POSITIVE_MAR_03_2007_0945PM
  9
 10#if defined(_MSC_VER)
 11#pragma once
 12#endif
 13
 14#include <boost/spirit/home/karma/domain.hpp>
 15#include <boost/spirit/home/karma/generator.hpp>
 16#include <boost/spirit/home/karma/meta_compiler.hpp>
 17#include <boost/spirit/home/karma/detail/indirect_iterator.hpp>
 18#include <boost/spirit/home/karma/detail/output_iterator.hpp>
 19#include <boost/spirit/home/karma/detail/get_stricttag.hpp>
 20#include <boost/spirit/home/karma/detail/pass_container.hpp>
 21#include <boost/spirit/home/karma/detail/fail_function.hpp>
 22#include <boost/spirit/home/support/info.hpp>
 23#include <boost/spirit/home/support/unused.hpp>
 24#include <boost/spirit/home/support/container.hpp>
 25#include <boost/spirit/home/support/has_semantic_action.hpp>
 26#include <boost/spirit/home/support/handles_container.hpp>
 27#include <boost/spirit/home/karma/detail/attributes.hpp>
 28
 29#include <boost/type_traits/add_const.hpp>
 30
 31namespace boost { namespace spirit
 32{
 33    ///////////////////////////////////////////////////////////////////////////
 34    // Enablers
 35    ///////////////////////////////////////////////////////////////////////////
 36    template <>
 37    struct use_operator<karma::domain, proto::tag::unary_plus> // enables +g
 38      : mpl::true_ {};
 39}}
 40
 41///////////////////////////////////////////////////////////////////////////////
 42namespace boost { namespace spirit { namespace karma
 43{
 44    template <typename Subject, typename Strict, typename Derived>
 45    struct base_plus : unary_generator<Derived>
 46    {
 47    private:
 48        // Ignore return value in relaxed mode (failing subject generators 
 49        // are just skipped). This allows to selectively generate items in 
 50        // the provided attribute.
 51        template <typename F, typename Attribute>
 52        bool generate_subject(F f, Attribute const&, bool& result, mpl::false_) const
 53        {
 54            bool r = !f(subject);
 55            if (r) 
 56                result = true;
 57            else if (!f.is_at_end())
 58                f.next();
 59            return true;
 60        }
 61
 62        template <typename F, typename Attribute>
 63        bool generate_subject(F f, Attribute const&, bool& result, mpl::true_) const
 64        {
 65            bool r = !f(subject);
 66            if (r)
 67                result = true;
 68            return r;
 69        }
 70
 71        // There is no way to distinguish a failed generator from a 
 72        // generator to be skipped. We assume the user takes responsibility
 73        // for ending the loop if no attribute is specified.
 74        template <typename F>
 75        bool generate_subject(F f, unused_type, bool& result, mpl::false_) const
 76        {
 77            bool r = f(subject);
 78            if (!r)
 79                result = true;
 80            return !r;
 81        }
 82
 83//         template <typename F>
 84//         bool generate_subject(F f, unused_type, bool& result, mpl::true_) const
 85//         {
 86//             bool r = f(subject);
 87//             if (!r)
 88//                 result = true;
 89//             return !r;
 90//         }
 91
 92    public:
 93        typedef Subject subject_type;
 94        typedef typename subject_type::properties properties;
 95
 96        // Build a std::vector from the subjects attribute. Note
 97        // that build_std_vector may return unused_type if the
 98        // subject's attribute is an unused_type.
 99        template <typename Context, typename Iterator>
100        struct attribute
101          : traits::build_std_vector<
102                typename traits::attribute_of<subject_type, Context, Iterator>::type
103            >
104        {};
105
106        base_plus(Subject const& subject)
107          : subject(subject) {}
108
109        template <
110            typename OutputIterator, typename Context, typename Delimiter
111          , typename Attribute>
112        bool generate(OutputIterator& sink, Context& ctx
113          , Delimiter const& d, Attribute const& attr) const
114        {
115            typedef detail::fail_function<
116                OutputIterator, Context, Delimiter> fail_function;
117
118            typedef typename traits::container_iterator<
119                typename add_const<Attribute>::type
120            >::type iterator_type;
121
122            typedef 
123                typename traits::make_indirect_iterator<iterator_type>::type 
124            indirect_iterator_type;
125            typedef detail::pass_container<
126                fail_function, Attribute, indirect_iterator_type, mpl::false_>
127            pass_container;
128
129            iterator_type it = traits::begin(attr);
130            iterator_type end = traits::end(attr);
131
132            // plus fails if the parameter is empty
133            if (traits::compare(it, end))
134                return false;
135
136            pass_container pass(fail_function(sink, ctx, d), 
137                indirect_iterator_type(it), indirect_iterator_type(end));
138
139            // from now on plus fails if the underlying output fails or overall
140            // no subject generators succeeded
141            bool result = false;
142            while (!pass.is_at_end())
143            {
144                if (!generate_subject(pass, attr, result, Strict()))
145                    break;
146            }
147            return result && detail::sink_is_good(sink);
148        }
149
150        template <typename Context>
151        info what(Context& context) const
152        {
153            return info("plus", subject.what(context));
154        }
155
156        Subject subject;
157    };
158
159    template <typename Subject>
160    struct plus 
161      : base_plus<Subject, mpl::false_, plus<Subject> >
162    {
163        typedef base_plus<Subject, mpl::false_, plus> base_plus_;
164
165        plus(Subject const& subject)
166          : base_plus_(subject) {}
167    };
168
169    template <typename Subject>
170    struct strict_plus 
171      : base_plus<Subject, mpl::true_, strict_plus<Subject> >
172    {
173        typedef base_plus<Subject, mpl::true_, strict_plus> base_plus_;
174
175        strict_plus(Subject const& subject)
176          : base_plus_(subject) {}
177    };
178
179    ///////////////////////////////////////////////////////////////////////////
180    // Generator generators: make_xxx function (objects)
181    ///////////////////////////////////////////////////////////////////////////
182    namespace detail
183    {
184        template <typename Elements, bool strict_mode = false>
185        struct make_plus 
186          : make_unary_composite<Elements, plus>
187        {};
188
189        template <typename Elements>
190        struct make_plus<Elements, true> 
191          : make_unary_composite<Elements, strict_plus>
192        {};
193    }
194
195    template <typename Elements, typename Modifiers>
196    struct make_composite<proto::tag::unary_plus, Elements, Modifiers>
197      : detail::make_plus<Elements, detail::get_stricttag<Modifiers>::value>
198    {};
199}}}
200
201namespace boost { namespace spirit { namespace traits
202{
203    ///////////////////////////////////////////////////////////////////////////
204    template <typename Subject>
205    struct has_semantic_action<karma::plus<Subject> >
206      : unary_has_semantic_action<Subject> {};
207
208    template <typename Subject>
209    struct has_semantic_action<karma::strict_plus<Subject> >
210      : unary_has_semantic_action<Subject> {};
211
212    ///////////////////////////////////////////////////////////////////////////
213    template <typename Subject, typename Attribute, typename Context
214      , typename Iterator>
215    struct handles_container<karma::plus<Subject>, Attribute
216          , Context, Iterator>
217      : mpl::true_ {};
218
219    template <typename Subject, typename Attribute, typename Context
220      , typename Iterator>
221    struct handles_container<karma::strict_plus<Subject>, Attribute
222          , Context, Iterator>
223      : mpl::true_ {};
224}}}
225
226#endif