1 //  Copyright (c) 2001-2011 Hartmut Kaiser
2 //  Copyright (c) 2001-2011 Joel de Guzman
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 #ifndef BOOST_SPIRIT_KARMA_OPERATOR_NOT_PREDICATE_HPP
8 #define BOOST_SPIRIT_KARMA_OPERATOR_NOT_PREDICATE_HPP
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/meta_compiler.hpp>
16 #include <boost/spirit/home/karma/generator.hpp>
17 #include <boost/spirit/home/karma/detail/output_iterator.hpp>
18 #include <boost/spirit/home/karma/detail/attributes.hpp>
19 #include <boost/spirit/home/support/info.hpp>
20 #include <boost/spirit/home/support/has_semantic_action.hpp>
21 #include <boost/spirit/home/support/handles_container.hpp>
22 #include <boost/proto/operators.hpp>
23 #include <boost/proto/tags.hpp>
24 
25 namespace boost { namespace spirit
26 {
27     ///////////////////////////////////////////////////////////////////////////
28     // Enablers
29     ///////////////////////////////////////////////////////////////////////////
30     template <>
31     struct use_operator<karma::domain, proto::tag::logical_not> // enables !g
32       : mpl::true_ {};
33 }}
34 
35 namespace boost { namespace spirit { namespace karma
36 {
37     template <typename Subject>
38     struct not_predicate : unary_generator<not_predicate<Subject> >
39     {
40         typedef Subject subject_type;
41 
42         typedef mpl::int_<
43             generator_properties::disabling | subject_type::properties::value
44         > properties;
45 
46         template <typename Context, typename Iterator>
47         struct attribute
48           : traits::attribute_of<subject_type, Context, Iterator>
49         {};
50 
not_predicateboost::spirit::karma::not_predicate51         not_predicate(Subject const& subject)
52           : subject(subject) {}
53 
54         template <
55             typename OutputIterator, typename Context, typename Delimiter
56           , typename Attribute>
generateboost::spirit::karma::not_predicate57         bool generate(OutputIterator& sink, Context& ctx, Delimiter const& d
58           , Attribute const& attr) const
59         {
60             // inhibits output
61             detail::disable_output<OutputIterator> disable(sink);
62             return !subject.generate(sink, ctx, d, attr);
63         }
64 
65         template <typename Context>
whatboost::spirit::karma::not_predicate66         info what(Context& context) const
67         {
68             return info("not-predicate", subject.what(context));
69         }
70 
71         Subject subject;
72     };
73 
74     ///////////////////////////////////////////////////////////////////////////
75     // Generator generators: make_xxx function (objects)
76     ///////////////////////////////////////////////////////////////////////////
77     template <typename Elements, typename Modifiers>
78     struct make_composite<proto::tag::logical_not, Elements, Modifiers>
79       : make_unary_composite<Elements, not_predicate> {};
80 
81 }}}
82 
83 namespace boost { namespace spirit { namespace traits
84 {
85     ///////////////////////////////////////////////////////////////////////////
86     template <typename Subject>
87     struct has_semantic_action<karma::not_predicate<Subject> >
88       : unary_has_semantic_action<Subject> {};
89 
90     ///////////////////////////////////////////////////////////////////////////
91     template <typename Subject, typename Attribute, typename Context
92         , typename Iterator>
93     struct handles_container<karma::not_predicate<Subject>, Attribute
94         , Context, Iterator>
95       : unary_handles_container<Subject, Attribute, Context, Iterator> {};
96 }}}
97 
98 #endif
99