]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/spirit/include/boost/spirit/home/qi/string/symbols.hpp
add subtree-ish sources for 12.0.3
[ceph.git] / ceph / src / boost / libs / spirit / include / boost / spirit / home / qi / string / symbols.hpp
1 /*=============================================================================
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_SYMBOLS_MARCH_11_2007_1055AM)
8 #define BOOST_SPIRIT_SYMBOLS_MARCH_11_2007_1055AM
9
10 #if defined(_MSC_VER)
11 #pragma once
12 #endif
13
14 #include <boost/spirit/home/qi/domain.hpp>
15 #include <boost/spirit/home/qi/skip_over.hpp>
16 #include <boost/spirit/home/qi/string/tst.hpp>
17 #include <boost/spirit/home/qi/reference.hpp>
18 #include <boost/spirit/home/qi/meta_compiler.hpp>
19 #include <boost/spirit/home/qi/detail/assign_to.hpp>
20 #include <boost/spirit/home/qi/parser.hpp>
21 #include <boost/spirit/home/support/detail/get_encoding.hpp>
22 #include <boost/spirit/home/support/modify.hpp>
23 #include <boost/spirit/home/support/info.hpp>
24 #include <boost/spirit/home/support/unused.hpp>
25 #include <boost/spirit/home/support/string_traits.hpp>
26
27 #include <boost/fusion/include/at.hpp>
28 #include <boost/range.hpp>
29 #include <boost/type_traits/add_reference.hpp>
30 #include <boost/shared_ptr.hpp>
31
32 #if defined(BOOST_MSVC)
33 # pragma warning(push)
34 # pragma warning(disable: 4355) // 'this' : used in base member initializer list warning
35 #endif
36
37 namespace boost { namespace spirit { namespace qi
38 {
39 template <
40 typename Char = char
41 , typename T = unused_type
42 , typename Lookup = tst<Char, T>
43 , typename Filter = tst_pass_through>
44 struct symbols
45 : proto::extends<
46 typename proto::terminal<
47 reference<symbols<Char, T, Lookup, Filter> >
48 >::type
49 , symbols<Char, T, Lookup, Filter>
50 >
51 , primitive_parser<symbols<Char, T, Lookup, Filter> >
52 {
53 typedef Char char_type; // the character type
54 typedef T value_type; // the value associated with each entry
55 typedef symbols<Char, T, Lookup, Filter> this_type;
56 typedef reference<this_type> reference_;
57 typedef typename proto::terminal<reference_>::type terminal;
58 typedef proto::extends<terminal, this_type> base_type;
59
60 template <typename Context, typename Iterator>
61 struct attribute
62 {
63 typedef value_type type;
64 };
65
66 symbols(std::string const& name = "symbols")
67 : base_type(terminal::make(reference_(*this)))
68 , add(*this)
69 , remove(*this)
70 , lookup(new Lookup())
71 , name_(name)
72 {
73 }
74
75 symbols(symbols const& syms)
76 : base_type(terminal::make(reference_(*this)))
77 , add(*this)
78 , remove(*this)
79 , lookup(syms.lookup)
80 , name_(syms.name_)
81 {
82 }
83
84 template <typename Filter_>
85 symbols(symbols<Char, T, Lookup, Filter_> const& syms)
86 : base_type(terminal::make(reference_(*this)))
87 , add(*this)
88 , remove(*this)
89 , lookup(syms.lookup)
90 , name_(syms.name_)
91 {
92 }
93
94 template <typename Symbols>
95 symbols(Symbols const& syms, std::string const& name = "symbols")
96 : base_type(terminal::make(reference_(*this)))
97 , add(*this)
98 , remove(*this)
99 , lookup(new Lookup())
100 , name_(name)
101 {
102 typename range_const_iterator<Symbols>::type si = boost::begin(syms);
103 while (si != boost::end(syms))
104 add(*si++);
105 }
106
107 template <typename Symbols, typename Data>
108 symbols(Symbols const& syms, Data const& data
109 , std::string const& name = "symbols")
110 : base_type(terminal::make(reference_(*this)))
111 , add(*this)
112 , remove(*this)
113 , lookup(new Lookup())
114 , name_(name)
115 {
116 typename range_const_iterator<Symbols>::type si = boost::begin(syms);
117 typename range_const_iterator<Data>::type di = boost::begin(data);
118 while (si != boost::end(syms))
119 add(*si++, *di++);
120 }
121
122 symbols&
123 operator=(symbols const& rhs)
124 {
125 name_ = rhs.name_;
126 *lookup = *rhs.lookup;
127 return *this;
128 }
129
130 template <typename Filter_>
131 symbols&
132 operator=(symbols<Char, T, Lookup, Filter_> const& rhs)
133 {
134 name_ = rhs.name_;
135 *lookup = *rhs.lookup;
136 return *this;
137 }
138
139 void clear()
140 {
141 lookup->clear();
142 }
143
144 struct adder;
145 struct remover;
146
147 template <typename Str>
148 adder const&
149 operator=(Str const& str)
150 {
151 lookup->clear();
152 return add(str);
153 }
154
155 template <typename Str>
156 friend adder const&
157 operator+=(symbols& sym, Str const& str)
158 {
159 return sym.add(str);
160 }
161
162 template <typename Str>
163 friend remover const&
164 operator-=(symbols& sym, Str const& str)
165 {
166 return sym.remove(str);
167 }
168
169 #if defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
170 // non-const version needed to suppress proto's += kicking in
171 template <typename Str>
172 friend adder const&
173 operator+=(symbols& sym, Str& str)
174 {
175 return sym.add(str);
176 }
177
178 // non-const version needed to suppress proto's -= kicking in
179 template <typename Str>
180 friend remover const&
181 operator-=(symbols& sym, Str& str)
182 {
183 return sym.remove(str);
184 }
185 #else
186 // for rvalue references
187 template <typename Str>
188 friend adder const&
189 operator+=(symbols& sym, Str&& str)
190 {
191 return sym.add(str);
192 }
193
194 // for rvalue references
195 template <typename Str>
196 friend remover const&
197 operator-=(symbols& sym, Str&& str)
198 {
199 return sym.remove(str);
200 }
201 #endif
202 template <typename F>
203 void for_each(F f) const
204 {
205 lookup->for_each(f);
206 }
207
208 template <typename Str>
209 value_type& at(Str const& str)
210 {
211 return *lookup->add(traits::get_begin<Char>(str)
212 , traits::get_end<Char>(str), T());
213 }
214
215 template <typename Iterator>
216 value_type* prefix_find(Iterator& first, Iterator const& last)
217 {
218 return lookup->find(first, last, Filter());
219 }
220
221 template <typename Iterator>
222 value_type const* prefix_find(Iterator& first, Iterator const& last) const
223 {
224 return lookup->find(first, last, Filter());
225 }
226
227 template <typename Str>
228 value_type* find(Str const& str)
229 {
230 return find_impl(traits::get_begin<Char>(str)
231 , traits::get_end<Char>(str));
232 }
233
234 template <typename Str>
235 value_type const* find(Str const& str) const
236 {
237 return find_impl(traits::get_begin<Char>(str)
238 , traits::get_end<Char>(str));
239 }
240
241 private:
242 template <typename Iterator>
243 value_type* find_impl(Iterator begin, Iterator end)
244 {
245 value_type* r = lookup->find(begin, end, Filter());
246 return begin == end ? r : 0;
247 }
248
249 template <typename Iterator>
250 value_type const* find_impl(Iterator begin, Iterator end) const
251 {
252 value_type const* r = lookup->find(begin, end, Filter());
253 return begin == end ? r : 0;
254 }
255
256 public:
257 template <typename Iterator, typename Context
258 , typename Skipper, typename Attribute>
259 bool parse(Iterator& first, Iterator const& last
260 , Context& /*context*/, Skipper const& skipper, Attribute& attr_) const
261 {
262 qi::skip_over(first, last, skipper);
263
264 if (value_type* val_ptr
265 = lookup->find(first, last, Filter()))
266 {
267 spirit::traits::assign_to(*val_ptr, attr_);
268 return true;
269 }
270 return false;
271 }
272
273 template <typename Context>
274 info what(Context& /*context*/) const
275 {
276 return info(name_);
277 }
278
279 void name(std::string const &str)
280 {
281 name_ = str;
282 }
283 std::string const &name() const
284 {
285 return name_;
286 }
287
288 struct adder
289 {
290 template <typename, typename = unused_type, typename = unused_type>
291 struct result { typedef adder const& type; };
292
293 adder(symbols& sym_)
294 : sym(sym_)
295 {
296 }
297
298 template <typename Iterator>
299 adder const&
300 operator()(Iterator const& first, Iterator const& last, T const& val) const
301 {
302 sym.lookup->add(first, last, val);
303 return *this;
304 }
305
306 template <typename Str>
307 adder const&
308 operator()(Str const& s, T const& val = T()) const
309 {
310 sym.lookup->add(traits::get_begin<Char>(s)
311 , traits::get_end<Char>(s), val);
312 return *this;
313 }
314
315 template <typename Str>
316 adder const&
317 operator,(Str const& s) const
318 {
319 sym.lookup->add(traits::get_begin<Char>(s)
320 , traits::get_end<Char>(s), T());
321 return *this;
322 }
323
324 symbols& sym;
325
326 private:
327 // silence MSVC warning C4512: assignment operator could not be generated
328 adder& operator= (adder const&);
329 };
330
331 struct remover
332 {
333 template <typename, typename = unused_type, typename = unused_type>
334 struct result { typedef remover const& type; };
335
336 remover(symbols& sym_)
337 : sym(sym_)
338 {
339 }
340
341 template <typename Iterator>
342 remover const&
343 operator()(Iterator const& first, Iterator const& last) const
344 {
345 sym.lookup->remove(first, last);
346 return *this;
347 }
348
349 template <typename Str>
350 remover const&
351 operator()(Str const& s) const
352 {
353 sym.lookup->remove(traits::get_begin<Char>(s)
354 , traits::get_end<Char>(s));
355 return *this;
356 }
357
358 template <typename Str>
359 remover const&
360 operator,(Str const& s) const
361 {
362 sym.lookup->remove(traits::get_begin<Char>(s)
363 , traits::get_end<Char>(s));
364 return *this;
365 }
366
367 symbols& sym;
368
369 private:
370 // silence MSVC warning C4512: assignment operator could not be generated
371 remover& operator= (remover const&);
372 };
373
374 adder add;
375 remover remove;
376 shared_ptr<Lookup> lookup;
377 std::string name_;
378 };
379
380 ///////////////////////////////////////////////////////////////////////////
381 // Parser generators: make_xxx function (objects)
382 ///////////////////////////////////////////////////////////////////////////
383 template <typename Char, typename T, typename Lookup
384 , typename Filter, typename Modifiers>
385 struct make_primitive<reference<symbols<Char, T, Lookup, Filter> >, Modifiers>
386 {
387 template <typename CharEncoding>
388 struct no_case_filter
389 {
390 Char operator()(Char ch) const
391 {
392 return static_cast<Char>(CharEncoding::tolower(ch));
393 }
394 };
395
396 typedef has_modifier<Modifiers, tag::char_code_base<tag::no_case> > no_case;
397 typedef reference<symbols<Char, T, Lookup, Filter> > reference_;
398 typedef no_case_filter<
399 typename spirit::detail::get_encoding_with_case<
400 Modifiers
401 , char_encoding::standard
402 , no_case::value>::type>
403 nc_filter;
404
405 typedef typename mpl::if_<
406 no_case
407 , symbols<Char, T, Lookup, nc_filter>
408 , reference_>::type
409 result_type;
410
411 result_type operator()(reference_ ref, unused_type) const
412 {
413 return result_type(ref.ref.get());
414 }
415 };
416 }}}
417
418 namespace boost { namespace spirit { namespace traits
419 {
420 ///////////////////////////////////////////////////////////////////////////
421 template <typename Char, typename T, typename Lookup, typename Filter
422 , typename Attr, typename Context, typename Iterator>
423 struct handles_container<qi::symbols<Char, T, Lookup, Filter>, Attr, Context, Iterator>
424 : traits::is_container<Attr> {};
425 }}}
426
427 #if defined(BOOST_MSVC)
428 # pragma warning(pop)
429 #endif
430
431 #endif