]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | // Copyright (c) 2001-2011 Hartmut Kaiser |
2 | // | |
3 | // Distributed under the Boost Software License, Version 1.0. (See accompanying | |
4 | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) | |
5 | ||
6 | #if !defined(BOOST_SPIRIT_KARMA_SYMBOLS_NOV_23_2009_1251PM) | |
7 | #define BOOST_SPIRIT_KARMA_SYMBOLS_NOV_23_2009_1251PM | |
8 | ||
9 | #include <boost/spirit/home/support/common_terminals.hpp> | |
10 | #include <boost/spirit/home/support/info.hpp> | |
11 | #include <boost/spirit/home/support/unused.hpp> | |
12 | #include <boost/spirit/home/support/attributes_fwd.hpp> | |
13 | #include <boost/spirit/home/support/detail/get_encoding.hpp> | |
14 | #include <boost/spirit/home/karma/detail/attributes.hpp> | |
15 | #include <boost/spirit/home/karma/detail/extract_from.hpp> | |
16 | #include <boost/spirit/home/karma/domain.hpp> | |
17 | #include <boost/spirit/home/karma/meta_compiler.hpp> | |
18 | #include <boost/spirit/home/karma/reference.hpp> | |
19 | #include <boost/spirit/home/karma/generate.hpp> | |
20 | #include <boost/spirit/home/karma/delimit_out.hpp> | |
21 | #include <boost/spirit/home/karma/detail/get_casetag.hpp> | |
22 | #include <boost/spirit/home/karma/detail/string_generate.hpp> | |
23 | #include <boost/config.hpp> | |
24 | #include <boost/shared_ptr.hpp> | |
25 | #include <boost/mpl/if.hpp> | |
26 | #include <map> | |
27 | #include <set> | |
28 | ||
29 | #if defined(BOOST_MSVC) | |
30 | # pragma warning(push) | |
31 | # pragma warning(disable: 4355) // 'this' : used in base member initializer list warning | |
32 | #endif | |
33 | ||
34 | /////////////////////////////////////////////////////////////////////////////// | |
35 | namespace boost { namespace spirit { namespace traits | |
36 | { | |
37 | template <typename T, typename Attribute, typename Enable> | |
38 | struct symbols_lookup | |
39 | { | |
40 | typedef | |
41 | mpl::eval_if<fusion::traits::is_sequence<T> | |
42 | , traits::detail::value_at_c<T, 0> | |
43 | , detail::add_const_ref<T> > sequence_type; | |
44 | typedef typename | |
45 | mpl::eval_if<traits::is_container<T> | |
46 | , traits::container_value<T> | |
47 | , sequence_type>::type type; | |
48 | ||
49 | // fusion sequence | |
50 | template <typename T_> | |
51 | static type call(T_ const& t, mpl::false_, mpl::true_) | |
52 | { | |
53 | return fusion::at_c<0>(t); | |
54 | } | |
55 | ||
56 | // container | |
57 | template <typename T_, typename IsSequence> | |
58 | static type call(T_ const& t, mpl::true_, IsSequence) | |
59 | { | |
60 | return t[0]; | |
61 | } | |
62 | ||
63 | // not a container and not a fusion sequence | |
64 | template <typename T_> | |
65 | static type call(T_ const& t, mpl::false_, mpl::false_) | |
66 | { | |
67 | return t; | |
68 | } | |
69 | ||
70 | static type call(T const& t) | |
71 | { | |
72 | typedef typename traits::is_container<T>::type is_container; | |
73 | typedef typename fusion::traits::is_sequence<T>::type is_sequence; | |
74 | ||
75 | return call(t, is_container(), is_sequence()); | |
76 | } | |
77 | }; | |
78 | ||
79 | template <typename Attribute> | |
80 | struct symbols_lookup<Attribute, Attribute> | |
81 | { | |
82 | typedef Attribute const& type; | |
83 | ||
84 | static type call(Attribute const& t) | |
85 | { | |
86 | return t; | |
87 | } | |
88 | }; | |
89 | ||
90 | template <typename Attribute, typename T, typename Enable> | |
91 | struct symbols_value | |
92 | { | |
93 | typedef | |
94 | mpl::eval_if<fusion::traits::is_sequence<T> | |
95 | , traits::detail::value_at_c<T, 1> | |
96 | , mpl::identity<unused_type> > sequence_type; | |
97 | typedef typename | |
98 | mpl::eval_if<traits::is_container<T> | |
99 | , traits::container_value<T> | |
100 | , sequence_type>::type type; | |
101 | ||
102 | // fusion sequence | |
103 | template <typename T_> | |
104 | static type call(T_ const& t, mpl::false_, mpl::true_) | |
105 | { | |
106 | return fusion::at_c<1>(t); | |
107 | } | |
108 | ||
109 | // container | |
110 | template <typename T_, typename IsSequence> | |
111 | static type call(T_ const& t, mpl::true_, IsSequence) | |
112 | { | |
113 | return t[1]; | |
114 | } | |
115 | ||
116 | // not a container nor a fusion sequence | |
117 | template <typename T_> | |
118 | static type call(T_ const&, mpl::false_, mpl::false_) | |
119 | { | |
120 | return unused; | |
121 | } | |
122 | ||
123 | static type call(T const& t) | |
124 | { | |
125 | typedef typename traits::is_container<T>::type is_container; | |
126 | typedef typename fusion::traits::is_sequence<T>::type is_sequence; | |
127 | ||
128 | return call(t, is_container(), is_sequence()); | |
129 | } | |
130 | }; | |
131 | ||
132 | template <typename Attribute> | |
133 | struct symbols_value<Attribute, Attribute> | |
134 | { | |
135 | typedef unused_type type; | |
136 | ||
137 | static type call(Attribute const&) | |
138 | { | |
139 | return unused; | |
140 | } | |
141 | }; | |
142 | }}} | |
143 | ||
144 | /////////////////////////////////////////////////////////////////////////////// | |
145 | namespace boost { namespace spirit { namespace karma | |
146 | { | |
147 | /////////////////////////////////////////////////////////////////////////// | |
148 | template <typename T, typename Attribute> | |
149 | struct symbols_lookup | |
150 | : mpl::if_< | |
151 | traits::not_is_unused<T> | |
152 | , std::map<Attribute, T> | |
153 | , std::set<Attribute> | |
154 | > | |
155 | {}; | |
156 | ||
157 | /////////////////////////////////////////////////////////////////////////// | |
158 | namespace detail | |
159 | { | |
160 | /////////////////////////////////////////////////////////////////////// | |
161 | template <typename CharEncoding, typename Tag> | |
162 | struct generate_encoded | |
163 | { | |
164 | typedef typename | |
165 | proto::terminal<tag::char_code<Tag, CharEncoding> >::type | |
166 | encoding_type; | |
167 | ||
168 | template <typename OutputIterator, typename Expr, typename Attribute> | |
169 | static bool call(OutputIterator& sink, Expr const& expr | |
170 | , Attribute const& attr) | |
171 | { | |
172 | encoding_type const encoding = encoding_type(); | |
173 | return karma::generate(sink, encoding[expr], attr); | |
174 | } | |
175 | }; | |
176 | ||
177 | template <> | |
178 | struct generate_encoded<unused_type, unused_type> | |
179 | { | |
180 | template <typename OutputIterator, typename Expr, typename Attribute> | |
181 | static bool call(OutputIterator& sink, Expr const& expr | |
182 | , Attribute const& attr) | |
183 | { | |
184 | return karma::generate(sink, expr, attr); | |
185 | } | |
186 | }; | |
187 | } | |
188 | ||
189 | template < | |
190 | typename Attribute = char, typename T = unused_type | |
191 | , typename Lookup = typename symbols_lookup<T, Attribute>::type | |
192 | , typename CharEncoding = unused_type, typename Tag = unused_type> | |
193 | struct symbols | |
194 | : proto::extends< | |
195 | typename proto::terminal< | |
196 | reference<symbols<Attribute, T, Lookup, CharEncoding, Tag> > | |
197 | >::type | |
198 | , symbols<Attribute, T, Lookup, CharEncoding, Tag> > | |
199 | , primitive_generator< | |
200 | symbols<Attribute, T, Lookup, CharEncoding, Tag> > | |
201 | { | |
202 | typedef T value_type; // the value associated with each entry | |
203 | ||
204 | typedef reference<symbols> reference_; | |
205 | typedef typename proto::terminal<reference_>::type terminal; | |
206 | typedef proto::extends<terminal, symbols> base_type; | |
207 | ||
208 | template <typename Context, typename Unused> | |
209 | struct attribute | |
210 | { | |
211 | typedef Attribute type; | |
212 | }; | |
213 | ||
214 | symbols(std::string const& name = "symbols") | |
215 | : base_type(terminal::make(reference_(*this))) | |
216 | , add(*this) | |
217 | , remove(*this) | |
218 | , lookup(new Lookup()) | |
219 | , name_(name) | |
220 | {} | |
221 | ||
222 | symbols(symbols const& syms) | |
223 | : base_type(terminal::make(reference_(*this))) | |
224 | , add(*this) | |
225 | , remove(*this) | |
226 | , lookup(syms.lookup) | |
227 | , name_(syms.name_) | |
228 | {} | |
229 | ||
230 | template <typename CharEncoding_, typename Tag_> | |
231 | symbols(symbols<Attribute, T, Lookup, CharEncoding_, Tag_> const& syms) | |
232 | : base_type(terminal::make(reference_(*this))) | |
233 | , add(*this) | |
234 | , remove(*this) | |
235 | , lookup(syms.lookup) | |
236 | , name_(syms.name_) | |
237 | {} | |
238 | ||
239 | template <typename Symbols, typename Data> | |
240 | symbols(Symbols const& syms, Data const& data | |
241 | , std::string const& name = "symbols") | |
242 | : base_type(terminal::make(reference_(*this))) | |
243 | , add(*this) | |
244 | , remove(*this) | |
245 | , lookup(new Lookup()) | |
246 | , name_(name) | |
247 | { | |
248 | typename range_const_iterator<Symbols>::type si = boost::begin(syms); | |
249 | typename range_const_iterator<Data>::type di = boost::begin(data); | |
250 | while (si != boost::end(syms)) | |
251 | add(*si++, *di++); | |
252 | } | |
253 | ||
254 | symbols& | |
255 | operator=(symbols const& rhs) | |
256 | { | |
257 | *lookup = *rhs.lookup; | |
258 | name_ = rhs.name_; | |
259 | return *this; | |
260 | } | |
261 | ||
262 | template <typename CharEncoding_, typename Tag_> | |
263 | symbols& | |
264 | operator=(symbols<Attribute, T, Lookup, CharEncoding_, Tag_> const& rhs) | |
265 | { | |
266 | *lookup = *rhs.lookup; | |
267 | name_ = rhs.name_; | |
268 | return *this; | |
269 | } | |
270 | ||
271 | void clear() | |
272 | { | |
273 | lookup->clear(); | |
274 | } | |
275 | ||
276 | struct adder; | |
277 | struct remover; | |
278 | ||
279 | template <typename Attr, typename T_> | |
280 | adder const& | |
281 | operator=(std::pair<Attr, T_> const& p) | |
282 | { | |
283 | lookup->clear(); | |
284 | return add(p.first, p.second); | |
285 | } | |
286 | ||
287 | template <typename Attr, typename T_> | |
288 | friend adder const& | |
289 | operator+= (symbols& sym, std::pair<Attr, T_> const& p) | |
290 | { | |
291 | return sym.add(p.first, p.second); | |
292 | } | |
293 | ||
294 | template <typename Attr> | |
295 | friend remover const& | |
296 | operator-= (symbols& sym, Attr const& attr) | |
297 | { | |
298 | return sym.remove(attr); | |
299 | } | |
300 | ||
301 | #if defined(BOOST_NO_CXX11_RVALUE_REFERENCES) | |
302 | // non-const version needed to suppress proto's += kicking in | |
303 | template <typename Attr, typename T_> | |
304 | friend adder const& | |
305 | operator+= (symbols& sym, std::pair<Attr, T_>& p) | |
306 | { | |
307 | return sym.add(p.first, p.second); | |
308 | } | |
309 | ||
310 | // non-const version needed to suppress proto's -= kicking in | |
311 | template <typename Attr> | |
312 | friend remover const& | |
313 | operator-= (symbols& sym, Attr& attr) | |
314 | { | |
315 | return sym.remove(attr); | |
316 | } | |
317 | #else | |
318 | // for rvalue references | |
319 | template <typename Attr, typename T_> | |
320 | friend adder const& | |
321 | operator+= (symbols& sym, std::pair<Attr, T_>&& p) | |
322 | { | |
323 | return sym.add(p.first, p.second); | |
324 | } | |
325 | ||
326 | // for rvalue references | |
327 | template <typename Attr> | |
328 | friend remover const& | |
329 | operator-= (symbols& sym, Attr&& attr) | |
330 | { | |
331 | return sym.remove(attr); | |
332 | } | |
333 | #endif | |
334 | template <typename F> | |
335 | void for_each(F f) const | |
336 | { | |
337 | std::for_each(lookup->begin(), lookup->end(), f); | |
338 | } | |
339 | ||
340 | template <typename Attr> | |
341 | value_type* find(Attr const& attr) | |
342 | { | |
343 | typename Lookup::iterator it = lookup->find(attr); | |
344 | return (it != lookup->end()) ? &(*it).second : 0; | |
345 | } | |
346 | ||
347 | template <typename Attr> | |
348 | value_type& at(Attr const& attr) | |
349 | { | |
350 | return (*lookup)[attr]; | |
351 | } | |
352 | ||
353 | /////////////////////////////////////////////////////////////////////// | |
354 | template <typename OutputIterator, typename Context, typename Delimiter | |
355 | , typename Attr> | |
356 | bool generate(OutputIterator& sink, Context&, Delimiter const& d | |
357 | , Attr const& attr) const | |
358 | { | |
359 | typename Lookup::iterator it = lookup->find( | |
360 | traits::symbols_lookup<Attr, Attribute>::call(attr)); | |
361 | if (it == lookup->end()) | |
362 | return false; | |
363 | ||
364 | return karma::detail::generate_encoded<CharEncoding, Tag>::call( | |
365 | sink, (*it).second | |
366 | , traits::symbols_value<Attribute, Attr>::call(attr)) && | |
367 | karma::delimit_out(sink, d); | |
368 | } | |
369 | ||
370 | template <typename Context> | |
371 | info what(Context&) const | |
372 | { | |
373 | return info(name_); | |
374 | } | |
375 | ||
376 | void name(std::string const &str) | |
377 | { | |
378 | name_ = str; | |
379 | } | |
380 | std::string const &name() const | |
381 | { | |
382 | return name_; | |
383 | } | |
384 | ||
385 | /////////////////////////////////////////////////////////////////////// | |
386 | struct adder | |
387 | { | |
388 | template <typename, typename = unused_type> | |
389 | struct result { typedef adder const& type; }; | |
390 | ||
391 | adder(symbols& sym) | |
392 | : sym(sym) | |
393 | { | |
394 | } | |
395 | ||
396 | template <typename Attr> | |
397 | adder const& | |
398 | operator()(Attr const& attr, T const& val = T()) const | |
399 | { | |
400 | sym.lookup->insert(typename Lookup::value_type(attr, val)); | |
401 | return *this; | |
402 | } | |
403 | ||
404 | template <typename Attr> | |
405 | adder const& | |
406 | operator, (Attr const& attr) const | |
407 | { | |
408 | sym.lookup->insert(typename Lookup::value_type(attr, T())); | |
409 | return *this; | |
410 | } | |
411 | ||
412 | symbols& sym; | |
413 | ||
414 | private: | |
415 | // silence MSVC warning C4512: assignment operator could not be generated | |
416 | adder& operator= (adder const&); | |
417 | }; | |
418 | ||
419 | struct remover | |
420 | { | |
421 | template <typename> | |
422 | struct result { typedef remover const& type; }; | |
423 | ||
424 | remover(symbols& sym) | |
425 | : sym(sym) | |
426 | { | |
427 | } | |
428 | ||
429 | template <typename Attr> | |
430 | remover const& | |
431 | operator()(Attr const& attr) const | |
432 | { | |
433 | sym.lookup->erase(attr); | |
434 | return *this; | |
435 | } | |
436 | ||
437 | template <typename Attr> | |
438 | remover const& | |
439 | operator, (Attr const& attr) const | |
440 | { | |
441 | sym.lookup->erase(attr); | |
442 | return *this; | |
443 | } | |
444 | ||
445 | symbols& sym; | |
446 | ||
447 | private: | |
448 | // silence MSVC warning C4512: assignment operator could not be generated | |
449 | remover& operator= (remover const&); | |
450 | }; | |
451 | ||
452 | adder add; | |
453 | remover remove; | |
454 | shared_ptr<Lookup> lookup; | |
455 | std::string name_; | |
456 | }; | |
457 | ||
458 | /////////////////////////////////////////////////////////////////////////// | |
459 | // specialization for unused stored type | |
460 | template < | |
461 | typename Attribute, typename Lookup | |
462 | , typename CharEncoding, typename Tag> | |
463 | struct symbols<Attribute, unused_type, Lookup, CharEncoding, Tag> | |
464 | : proto::extends< | |
465 | typename proto::terminal< | |
466 | spirit::karma::reference< | |
467 | symbols<Attribute, unused_type, Lookup, CharEncoding, Tag> > | |
468 | >::type | |
469 | , symbols<Attribute, unused_type, Lookup, CharEncoding, Tag> | |
470 | > | |
471 | , spirit::karma::generator< | |
472 | symbols<Attribute, unused_type, Lookup, CharEncoding, Tag> > | |
473 | { | |
474 | typedef unused_type value_type; // the value associated with each entry | |
475 | ||
476 | typedef spirit::karma::reference<symbols> reference_; | |
477 | typedef typename proto::terminal<reference_>::type terminal; | |
478 | typedef proto::extends<terminal, symbols> base_type; | |
479 | ||
480 | template <typename Context, typename Unused> | |
481 | struct attribute | |
482 | { | |
483 | typedef Attribute type; | |
484 | }; | |
485 | ||
486 | symbols(std::string const& name = "symbols") | |
487 | : base_type(terminal::make(reference_(*this))) | |
488 | , add(*this) | |
489 | , remove(*this) | |
490 | , lookup(new Lookup()) | |
491 | , name_(name) | |
492 | {} | |
493 | ||
494 | symbols(symbols const& syms) | |
495 | : base_type(terminal::make(reference_(*this))) | |
496 | , add(*this) | |
497 | , remove(*this) | |
498 | , lookup(syms.lookup) | |
499 | , name_(syms.name_) | |
500 | {} | |
501 | ||
502 | template <typename CharEncoding_, typename Tag_> | |
503 | symbols(symbols<Attribute, unused_type, Lookup, CharEncoding_, Tag_> const& syms) | |
504 | : base_type(terminal::make(reference_(*this))) | |
505 | , add(*this) | |
506 | , remove(*this) | |
507 | , lookup(syms.lookup) | |
508 | , name_(syms.name_) | |
509 | {} | |
510 | ||
511 | template <typename Symbols, typename Data> | |
512 | symbols(Symbols const& syms, Data const& data | |
513 | , std::string const& name = "symbols") | |
514 | : base_type(terminal::make(reference_(*this))) | |
515 | , add(*this) | |
516 | , remove(*this) | |
517 | , lookup(new Lookup()) | |
518 | , name_(name) | |
519 | { | |
520 | typename range_const_iterator<Symbols>::type si = boost::begin(syms); | |
521 | typename range_const_iterator<Data>::type di = boost::begin(data); | |
522 | while (si != boost::end(syms)) | |
523 | add(*si++, *di++); | |
524 | } | |
525 | ||
526 | symbols& | |
527 | operator=(symbols const& rhs) | |
528 | { | |
529 | *lookup = *rhs.lookup; | |
530 | name_ = rhs.name_; | |
531 | return *this; | |
532 | } | |
533 | ||
534 | template <typename CharEncoding_, typename Tag_> | |
535 | symbols& | |
536 | operator=(symbols<Attribute, unused_type, Lookup, CharEncoding_, Tag_> const& rhs) | |
537 | { | |
538 | *lookup = *rhs.lookup; | |
539 | name_ = rhs.name_; | |
540 | return *this; | |
541 | } | |
542 | ||
543 | void clear() | |
544 | { | |
545 | lookup->clear(); | |
546 | } | |
547 | ||
548 | struct adder; | |
549 | struct remover; | |
550 | ||
551 | template <typename Attr> | |
552 | adder const& | |
553 | operator=(Attr const& attr) | |
554 | { | |
555 | lookup->clear(); | |
556 | return add(attr); | |
557 | } | |
558 | ||
559 | template <typename Attr> | |
560 | friend adder const& | |
561 | operator+= (symbols& sym, Attr const& attr) | |
562 | { | |
563 | return sym.add(attr); | |
564 | } | |
565 | ||
566 | template <typename Attr> | |
567 | friend remover const& | |
568 | operator-= (symbols& sym, Attr const& attr) | |
569 | { | |
570 | return sym.remove(attr); | |
571 | } | |
572 | ||
573 | // non-const version needed to suppress proto's += kicking in | |
574 | template <typename Attr> | |
575 | friend adder const& | |
576 | operator+= (symbols& sym, Attr& attr) | |
577 | { | |
578 | return sym.add(attr); | |
579 | } | |
580 | ||
581 | // non-const version needed to suppress proto's -= kicking in | |
582 | template <typename Attr> | |
583 | friend remover const& | |
584 | operator-= (symbols& sym, Attr& attr) | |
585 | { | |
586 | return sym.remove(attr); | |
587 | } | |
588 | ||
589 | template <typename F> | |
590 | void for_each(F f) const | |
591 | { | |
592 | std::for_each(lookup->begin(), lookup->end(), f); | |
593 | } | |
594 | ||
595 | template <typename Attr> | |
596 | value_type const* find(Attr const& attr) | |
597 | { | |
598 | typename Lookup::iterator it = lookup->find(attr); | |
599 | return (it != lookup->end()) ? &unused : 0; | |
600 | } | |
601 | ||
602 | template <typename Attr> | |
603 | value_type at(Attr const& attr) | |
604 | { | |
605 | typename Lookup::iterator it = lookup->find(attr); | |
606 | if (it == lookup->end()) | |
607 | add(attr); | |
608 | return unused; | |
609 | } | |
610 | ||
611 | /////////////////////////////////////////////////////////////////////// | |
612 | template <typename OutputIterator, typename Context, typename Delimiter | |
613 | , typename Attr> | |
614 | bool generate(OutputIterator& sink, Context&, Delimiter const& d | |
615 | , Attr const& attr) const | |
616 | { | |
617 | typename Lookup::iterator it = lookup->find( | |
618 | traits::symbols_lookup<Attr, Attribute>::call(attr)); | |
619 | if (it == lookup->end()) | |
620 | return false; | |
621 | ||
622 | return karma::detail::generate_encoded<CharEncoding, Tag>:: | |
623 | call(sink | |
624 | , traits::symbols_lookup<Attr, Attribute>::call(attr) | |
625 | , unused) && | |
626 | karma::delimit_out(sink, d); | |
627 | } | |
628 | ||
629 | template <typename Context> | |
630 | info what(Context&) const | |
631 | { | |
632 | return info(name_); | |
633 | } | |
634 | ||
635 | void name(std::string const &str) | |
636 | { | |
637 | name_ = str; | |
638 | } | |
639 | std::string const &name() const | |
640 | { | |
641 | return name_; | |
642 | } | |
643 | ||
644 | /////////////////////////////////////////////////////////////////////// | |
645 | struct adder | |
646 | { | |
647 | template <typename, typename = unused_type> | |
648 | struct result { typedef adder const& type; }; | |
649 | ||
650 | adder(symbols& sym) | |
651 | : sym(sym) | |
652 | { | |
653 | } | |
654 | ||
655 | template <typename Attr> | |
656 | adder const& | |
657 | operator()(Attr const& attr) const | |
658 | { | |
659 | sym.lookup->insert(attr); | |
660 | return *this; | |
661 | } | |
662 | ||
663 | template <typename Attr> | |
664 | adder const& | |
665 | operator, (Attr const& attr) const | |
666 | { | |
667 | sym.lookup->insert(attr); | |
668 | return *this; | |
669 | } | |
670 | ||
671 | symbols& sym; | |
672 | ||
673 | private: | |
674 | // silence MSVC warning C4512: assignment operator could not be generated | |
675 | adder& operator= (adder const&); | |
676 | }; | |
677 | ||
678 | struct remover | |
679 | { | |
680 | template <typename> | |
681 | struct result { typedef remover const& type; }; | |
682 | ||
683 | remover(symbols& sym) | |
684 | : sym(sym) | |
685 | { | |
686 | } | |
687 | ||
688 | template <typename Attr> | |
689 | remover const& | |
690 | operator()(Attr const& attr) const | |
691 | { | |
692 | sym.lookup->erase(attr); | |
693 | return *this; | |
694 | } | |
695 | ||
696 | template <typename Attr> | |
697 | remover const& | |
698 | operator, (Attr const& attr) const | |
699 | { | |
700 | sym.lookup->erase(attr); | |
701 | return *this; | |
702 | } | |
703 | ||
704 | symbols& sym; | |
705 | ||
706 | private: | |
707 | // silence MSVC warning C4512: assignment operator could not be generated | |
708 | remover& operator= (remover const&); | |
709 | }; | |
710 | ||
711 | adder add; | |
712 | remover remove; | |
713 | shared_ptr<Lookup> lookup; | |
714 | std::string name_; | |
715 | }; | |
716 | ||
717 | /////////////////////////////////////////////////////////////////////////// | |
718 | // Generator generators: make_xxx function (objects) | |
719 | /////////////////////////////////////////////////////////////////////////// | |
720 | template <typename Attribute, typename T, typename Lookup | |
721 | , typename CharEnconding, typename Tag, typename Modifiers> | |
722 | struct make_primitive< | |
723 | reference<symbols<Attribute, T, Lookup, CharEnconding, Tag> > | |
724 | , Modifiers> | |
725 | { | |
726 | static bool const lower = | |
727 | has_modifier<Modifiers, tag::char_code_base<tag::lower> >::value; | |
728 | static bool const upper = | |
729 | has_modifier<Modifiers, tag::char_code_base<tag::upper> >::value; | |
730 | ||
731 | typedef reference< | |
732 | symbols<Attribute, T, Lookup, CharEnconding, Tag> | |
733 | > reference_; | |
734 | ||
735 | typedef typename mpl::if_c< | |
736 | lower || upper | |
737 | , symbols< | |
738 | Attribute, T, Lookup | |
739 | , typename spirit::detail::get_encoding_with_case< | |
740 | Modifiers, unused_type, lower || upper>::type | |
741 | , typename detail::get_casetag<Modifiers, lower || upper>::type> | |
742 | , reference_>::type | |
743 | result_type; | |
744 | ||
745 | result_type operator()(reference_ ref, unused_type) const | |
746 | { | |
747 | return result_type(ref.ref.get()); | |
748 | } | |
749 | }; | |
750 | }}} | |
751 | ||
752 | namespace boost { namespace spirit { namespace traits | |
753 | { | |
754 | /////////////////////////////////////////////////////////////////////////// | |
755 | template <typename Attribute, typename T, typename Lookup | |
756 | , typename CharEncoding, typename Tag | |
757 | , typename Attr, typename Context, typename Iterator> | |
758 | struct handles_container<karma::symbols<Attribute, T, Lookup, CharEncoding, Tag> | |
759 | , Attr, Context, Iterator> | |
760 | : traits::is_container<Attr> {}; | |
761 | }}} | |
762 | ||
763 | #if defined(BOOST_MSVC) | |
764 | # pragma warning(pop) | |
765 | #endif | |
766 | ||
767 | #endif | |
768 |