]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/boost/spirit/home/karma/char/char_generator.hpp
update source to Ceph Pacific 16.2.2
[ceph.git] / ceph / src / boost / boost / spirit / home / karma / char / char_generator.hpp
CommitLineData
7c673cae
FG
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#if !defined(BOOST_SPIRIT_CHAR_GENERATOR_SEP_07_2009_0417PM)
8#define BOOST_SPIRIT_CHAR_GENERATOR_SEP_07_2009_0417PM
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/detail/generate_to.hpp>
17#include <boost/spirit/home/karma/detail/extract_from.hpp>
18#include <boost/spirit/home/karma/meta_compiler.hpp>
19#include <boost/spirit/home/karma/delimit_out.hpp>
20#include <boost/spirit/home/support/unused.hpp>
21#include <boost/spirit/home/support/info.hpp>
22#include <boost/spirit/home/support/container.hpp>
f67539c2
TL
23#include <boost/proto/operators.hpp>
24#include <boost/proto/tags.hpp>
7c673cae
FG
25
26namespace boost { namespace spirit
27{
28 ///////////////////////////////////////////////////////////////////////////
29 // Enablers
30 ///////////////////////////////////////////////////////////////////////////
31 template <>
32 struct use_operator<karma::domain, proto::tag::complement> // enables ~
33 : mpl::true_ {};
34
35}}
36
37namespace boost { namespace spirit { namespace traits // classification
38{
39 namespace detail
40 {
41 BOOST_MPL_HAS_XXX_TRAIT_DEF(char_generator_id)
42 }
43
44 template <typename T>
45 struct is_char_generator : detail::has_char_generator_id<T> {};
46}}}
47
48namespace boost { namespace spirit { namespace karma
49{
50 ///////////////////////////////////////////////////////////////////////////
51 // The base char_parser
52 ///////////////////////////////////////////////////////////////////////////
53 template <typename Derived, typename CharEncoding, typename Tag
54 , typename Char = typename CharEncoding::char_type, typename Attr = Char>
55 struct char_generator : primitive_generator<Derived>
56 {
57 typedef CharEncoding char_encoding;
58 typedef Tag tag;
59 typedef Char char_type;
60 struct char_generator_id;
61
62 // if Attr is unused_type, Derived must supply its own attribute
63 // metafunction
64 template <typename Context, typename Unused>
65 struct attribute
66 {
67 typedef Attr type;
68 };
69
70 template <
71 typename OutputIterator, typename Context, typename Delimiter
72 , typename Attribute>
73 bool generate(OutputIterator& sink, Context& context, Delimiter const& d
74 , Attribute const& attr) const
75 {
76 if (!traits::has_optional_value(attr))
77 return false;
78
79 Attr ch = Attr();
80 if (!this->derived().test(traits::extract_from<Attr>(attr, context), ch, context))
81 return false;
82
83 return karma::detail::generate_to(sink, ch, char_encoding(), tag()) &&
84 karma::delimit_out(sink, d); // always do post-delimiting
85 }
86
87 // Requirement: g.test(attr, ch, context) -> bool
88 //
89 // attr: associated attribute
90 // ch: character to be generated (set by test())
91 // context: enclosing rule context
92 };
93
94 ///////////////////////////////////////////////////////////////////////////
95 // negated_char_generator handles ~cg expressions (cg is a char_generator)
96 ///////////////////////////////////////////////////////////////////////////
97 template <typename Positive>
98 struct negated_char_generator
99 : char_generator<negated_char_generator<Positive>
100 , typename Positive::char_encoding, typename Positive::tag>
101 {
102 negated_char_generator(Positive const& positive)
103 : positive(positive) {}
104
105 template <typename Attribute, typename CharParam, typename Context>
106 bool test(Attribute const& attr, CharParam& ch, Context& context) const
107 {
108 return !positive.test(attr, ch, context);
109 }
110
111 template <typename Context>
112 info what(Context& context) const
113 {
114 return info("not", positive.what(context));
115 }
116
117 Positive positive;
118 };
119
120 ///////////////////////////////////////////////////////////////////////////
121 // Generator generators: make_xxx function (objects)
122 ///////////////////////////////////////////////////////////////////////////
123 namespace detail
124 {
125 template <typename Positive>
126 struct make_negated_char_generator
127 {
128 typedef negated_char_generator<Positive> result_type;
129 result_type operator()(Positive const& positive) const
130 {
131 return result_type(positive);
132 }
133 };
134
135 template <typename Positive>
136 struct make_negated_char_generator<negated_char_generator<Positive> >
137 {
138 typedef Positive result_type;
139 result_type operator()(negated_char_generator<Positive> const& ncg) const
140 {
141 return ncg.positive;
142 }
143 };
144 }
145
146 template <typename Elements, typename Modifiers>
147 struct make_composite<proto::tag::complement, Elements, Modifiers>
148 {
149 typedef typename
150 fusion::result_of::value_at_c<Elements, 0>::type
151 subject;
152
153 BOOST_SPIRIT_ASSERT_MSG((
154 traits::is_char_generator<subject>::value
155 ), subject_is_not_negatable, (subject));
156
157 typedef typename
158 detail::make_negated_char_generator<subject>::result_type
159 result_type;
160
161 result_type operator()(Elements const& elements, unused_type) const
162 {
163 return detail::make_negated_char_generator<subject>()(
164 fusion::at_c<0>(elements));
165 }
166 };
167
168}}}
169
170#endif