Mercurial > hg > vamp-build-and-test
comparison DEPENDENCIES/generic/include/boost/spirit/home/karma/operator/kleene.hpp @ 16:2665513ce2d3
Add boost headers
author | Chris Cannam |
---|---|
date | Tue, 05 Aug 2014 11:11:38 +0100 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
15:663ca0da4350 | 16:2665513ce2d3 |
---|---|
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_KLEENE_MAR_03_2007_0337AM) | |
8 #define BOOST_SPIRIT_KARMA_KLEENE_MAR_03_2007_0337AM | |
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/output_iterator.hpp> | |
18 #include <boost/spirit/home/karma/detail/indirect_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/handles_container.hpp> | |
26 #include <boost/spirit/home/karma/detail/attributes.hpp> | |
27 | |
28 #include <boost/type_traits/add_const.hpp> | |
29 | |
30 namespace boost { namespace spirit | |
31 { | |
32 /////////////////////////////////////////////////////////////////////////// | |
33 // Enablers | |
34 /////////////////////////////////////////////////////////////////////////// | |
35 template <> | |
36 struct use_operator<karma::domain, proto::tag::dereference> // enables *g | |
37 : mpl::true_ {}; | |
38 }} | |
39 | |
40 /////////////////////////////////////////////////////////////////////////////// | |
41 namespace boost { namespace spirit { namespace karma | |
42 { | |
43 template <typename Subject, typename Strict, typename Derived> | |
44 struct base_kleene : unary_generator<Derived> | |
45 { | |
46 private: | |
47 // Ignore return value in relaxed mode (failing subject generators | |
48 // are just skipped). This allows to selectively generate items in | |
49 // the provided attribute. | |
50 template <typename F, typename Attribute> | |
51 bool generate_subject(F f, Attribute const&, mpl::false_) const | |
52 { | |
53 bool r = !f(subject); | |
54 if (!r && !f.is_at_end()) | |
55 f.next(); | |
56 return true; | |
57 } | |
58 | |
59 template <typename F, typename Attribute> | |
60 bool generate_subject(F f, Attribute const&, mpl::true_) const | |
61 { | |
62 return !f(subject); | |
63 } | |
64 | |
65 // There is no way to distinguish a failed generator from a | |
66 // generator to be skipped. We assume the user takes responsibility | |
67 // for ending the loop if no attribute is specified. | |
68 template <typename F> | |
69 bool generate_subject(F f, unused_type, mpl::false_) const | |
70 { | |
71 return !f(subject); | |
72 } | |
73 | |
74 // template <typename F> | |
75 // bool generate_subject(F f, unused_type, mpl::true_) const | |
76 // { | |
77 // return !f(subject); | |
78 // } | |
79 | |
80 public: | |
81 typedef Subject subject_type; | |
82 typedef typename subject_type::properties properties; | |
83 | |
84 // Build a std::vector from the subject's attribute. Note | |
85 // that build_std_vector may return unused_type if the | |
86 // subject's attribute is an unused_type. | |
87 template <typename Context, typename Iterator> | |
88 struct attribute | |
89 : traits::build_std_vector< | |
90 typename traits::attribute_of<Subject, Context, Iterator>::type | |
91 > | |
92 {}; | |
93 | |
94 base_kleene(Subject const& subject) | |
95 : subject(subject) {} | |
96 | |
97 template < | |
98 typename OutputIterator, typename Context, typename Delimiter | |
99 , typename Attribute> | |
100 bool generate(OutputIterator& sink, Context& ctx | |
101 , Delimiter const& d, Attribute const& attr) const | |
102 { | |
103 typedef detail::fail_function< | |
104 OutputIterator, Context, Delimiter> fail_function; | |
105 | |
106 typedef typename traits::container_iterator< | |
107 typename add_const<Attribute>::type | |
108 >::type iterator_type; | |
109 | |
110 typedef | |
111 typename traits::make_indirect_iterator<iterator_type>::type | |
112 indirect_iterator_type; | |
113 typedef detail::pass_container< | |
114 fail_function, Attribute, indirect_iterator_type, mpl::false_> | |
115 pass_container; | |
116 | |
117 iterator_type it = traits::begin(attr); | |
118 iterator_type end = traits::end(attr); | |
119 | |
120 pass_container pass(fail_function(sink, ctx, d), | |
121 indirect_iterator_type(it), indirect_iterator_type(end)); | |
122 | |
123 // kleene fails only if the underlying output fails | |
124 while (!pass.is_at_end()) | |
125 { | |
126 if (!generate_subject(pass, attr, Strict())) | |
127 break; | |
128 } | |
129 return detail::sink_is_good(sink); | |
130 } | |
131 | |
132 template <typename Context> | |
133 info what(Context& context) const | |
134 { | |
135 return info("kleene", subject.what(context)); | |
136 } | |
137 | |
138 Subject subject; | |
139 }; | |
140 | |
141 template <typename Subject> | |
142 struct kleene | |
143 : base_kleene<Subject, mpl::false_, kleene<Subject> > | |
144 { | |
145 typedef base_kleene<Subject, mpl::false_, kleene> base_kleene_; | |
146 | |
147 kleene(Subject const& subject) | |
148 : base_kleene_(subject) {} | |
149 }; | |
150 | |
151 template <typename Subject> | |
152 struct strict_kleene | |
153 : base_kleene<Subject, mpl::true_, strict_kleene<Subject> > | |
154 { | |
155 typedef base_kleene<Subject, mpl::true_, strict_kleene> base_kleene_; | |
156 | |
157 strict_kleene(Subject const& subject) | |
158 : base_kleene_(subject) {} | |
159 }; | |
160 | |
161 /////////////////////////////////////////////////////////////////////////// | |
162 // Generator generators: make_xxx function (objects) | |
163 /////////////////////////////////////////////////////////////////////////// | |
164 namespace detail | |
165 { | |
166 template <typename Subject, bool strict_mode = false> | |
167 struct make_kleene | |
168 : make_unary_composite<Subject, kleene> | |
169 {}; | |
170 | |
171 template <typename Subject> | |
172 struct make_kleene<Subject, true> | |
173 : make_unary_composite<Subject, strict_kleene> | |
174 {}; | |
175 } | |
176 | |
177 template <typename Subject, typename Modifiers> | |
178 struct make_composite<proto::tag::dereference, Subject, Modifiers> | |
179 : detail::make_kleene<Subject, detail::get_stricttag<Modifiers>::value> | |
180 {}; | |
181 }}} | |
182 | |
183 namespace boost { namespace spirit { namespace traits | |
184 { | |
185 /////////////////////////////////////////////////////////////////////////// | |
186 template <typename Subject> | |
187 struct has_semantic_action<karma::kleene<Subject> > | |
188 : unary_has_semantic_action<Subject> {}; | |
189 | |
190 template <typename Subject> | |
191 struct has_semantic_action<karma::strict_kleene<Subject> > | |
192 : unary_has_semantic_action<Subject> {}; | |
193 | |
194 /////////////////////////////////////////////////////////////////////////// | |
195 template <typename Subject, typename Attribute, typename Context | |
196 , typename Iterator> | |
197 struct handles_container<karma::kleene<Subject>, Attribute | |
198 , Context, Iterator> | |
199 : mpl::true_ {}; | |
200 | |
201 template <typename Subject, typename Attribute, typename Context | |
202 , typename Iterator> | |
203 struct handles_container<karma::strict_kleene<Subject>, Attribute | |
204 , Context, Iterator> | |
205 : mpl::true_ {}; | |
206 }}} | |
207 | |
208 #endif |