]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/boost/spirit/home/classic/tree/common.hpp
import quincy beta 17.1.0
[ceph.git] / ceph / src / boost / boost / spirit / home / classic / tree / common.hpp
1 /*=============================================================================
2 Copyright (c) 2001-2003 Daniel Nuffer
3 Copyright (c) 2001-2007 Hartmut Kaiser
4 Revised 2007, Copyright (c) Tobias Schwinger
5 http://spirit.sourceforge.net/
6
7 Distributed under the Boost Software License, Version 1.0. (See accompanying
8 file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
9 =============================================================================*/
10 #ifndef BOOST_SPIRIT_TREE_COMMON_HPP
11 #define BOOST_SPIRIT_TREE_COMMON_HPP
12
13 #if !defined(BOOST_SPIRIT_USE_LIST_FOR_TREES)
14 #include <vector>
15 #else
16 #include <list>
17 #endif
18
19 #if defined(BOOST_SPIRIT_USE_BOOST_ALLOCATOR_FOR_TREES)
20 #include <boost/pool/pool_alloc.hpp>
21 #endif
22
23 #include <algorithm>
24
25 #include <boost/ref.hpp>
26 #include <boost/call_traits.hpp>
27 #include <boost/spirit/home/classic/namespace.hpp>
28 #include <boost/spirit/home/classic/core.hpp>
29 #include <boost/assert.hpp>
30
31 #if defined(BOOST_SPIRIT_DEBUG) && \
32 (BOOST_SPIRIT_DEBUG_FLAGS & BOOST_SPIRIT_DEBUG_FLAGS_NODES)
33 #include <iostream>
34 #include <boost/spirit/home/classic/debug/debug_node.hpp>
35 #endif
36
37 #include <boost/spirit/home/classic/tree/common_fwd.hpp>
38
39 #include <iterator> // for std::iterator_traits, std::distance
40
41 namespace boost { namespace spirit {
42
43 BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
44
45 template <typename T>
46 void swap(tree_node<T>& a, tree_node<T>& b);
47
48 template <typename T, typename V>
49 void swap(node_iter_data<T, V>& a, node_iter_data<T, V>& b);
50
51 namespace impl {
52 template <typename T>
53 inline void cp_swap(T& t1, T& t2);
54 }
55
56 template <typename T>
57 struct tree_node
58 {
59 typedef T parse_node_t;
60
61 #if !defined(BOOST_SPIRIT_USE_BOOST_ALLOCATOR_FOR_TREES)
62 typedef std::allocator<tree_node<T> > allocator_type;
63 #elif !defined(BOOST_SPIRIT_USE_LIST_FOR_TREES)
64 typedef boost::pool_allocator<tree_node<T> > allocator_type;
65 #else
66 typedef boost::fast_pool_allocator<tree_node<T> > allocator_type;
67 #endif
68
69 #if !defined(BOOST_SPIRIT_USE_LIST_FOR_TREES)
70 typedef std::vector<tree_node<T>, allocator_type> children_t;
71 #else
72 typedef std::list<tree_node<T>, allocator_type> children_t;
73 #endif // BOOST_SPIRIT_USE_LIST_FOR_TREES
74
75 typedef typename children_t::iterator tree_iterator;
76 typedef typename children_t::const_iterator const_tree_iterator;
77
78 T value;
79 children_t children;
80
81 tree_node()
82 : value()
83 , children()
84 {}
85
86 explicit tree_node(T const& v)
87 : value(v)
88 , children()
89 {}
90
91 tree_node(T const& v, children_t const& c)
92 : value(v)
93 , children(c)
94 {}
95
96 void swap(tree_node<T>& x)
97 {
98 impl::cp_swap(value, x.value);
99 impl::cp_swap(children, x.children);
100 }
101 };
102
103 #if defined(BOOST_SPIRIT_DEBUG) && \
104 (BOOST_SPIRIT_DEBUG_FLAGS & BOOST_SPIRIT_DEBUG_FLAGS_NODES)
105 template <typename T>
106 inline std::ostream&
107 operator<<(std::ostream& o, tree_node<T> const& n)
108 {
109 static int depth = 0;
110 o << "\n";
111 for (int i = 0; i <= depth; ++i)
112 {
113 o << "\t";
114 }
115 o << "(depth = " << depth++ << " value = " << n.value;
116 int c = 0;
117 for (typename tree_node<T>::children_t::const_iterator it = n.children.begin();
118 it != n.children.end(); ++it)
119 {
120 o << " children[" << c++ << "] = " << *it;
121 }
122 o << ")";
123 --depth;
124 return o;
125 }
126 #endif
127
128 //////////////////////////////////
129 template <typename IteratorT, typename ValueT>
130 struct node_iter_data
131 {
132 typedef IteratorT iterator_t;
133 typedef IteratorT /*const*/ const_iterator_t;
134
135 node_iter_data()
136 : first(), last(), is_root_(false), parser_id_(), value_()
137 {}
138
139 node_iter_data(IteratorT const& _first, IteratorT const& _last)
140 : first(_first), last(_last), is_root_(false), parser_id_(), value_()
141 {}
142
143 void swap(node_iter_data& x)
144 {
145 impl::cp_swap(first, x.first);
146 impl::cp_swap(last, x.last);
147 impl::cp_swap(parser_id_, x.parser_id_);
148 impl::cp_swap(is_root_, x.is_root_);
149 impl::cp_swap(value_, x.value_);
150 }
151
152 IteratorT begin()
153 {
154 return first;
155 }
156
157 IteratorT const& begin() const
158 {
159 return first;
160 }
161
162 IteratorT end()
163 {
164 return last;
165 }
166
167 IteratorT const& end() const
168 {
169 return last;
170 }
171
172 bool is_root() const
173 {
174 return is_root_;
175 }
176
177 void is_root(bool b)
178 {
179 is_root_ = b;
180 }
181
182 parser_id id() const
183 {
184 return parser_id_;
185 }
186
187 void id(parser_id r)
188 {
189 parser_id_ = r;
190 }
191
192 ValueT const& value() const
193 {
194 return value_;
195 }
196
197 void value(ValueT const& v)
198 {
199 value_ = v;
200 }
201 private:
202 IteratorT first, last;
203 bool is_root_;
204 parser_id parser_id_;
205 ValueT value_;
206
207 public:
208 };
209
210 #if defined(BOOST_SPIRIT_DEBUG) && \
211 (BOOST_SPIRIT_DEBUG_FLAGS & BOOST_SPIRIT_DEBUG_FLAGS_NODES)
212 // value is default nil_t, so provide an operator<< for nil_t
213 inline std::ostream&
214 operator<<(std::ostream& o, nil_t const&)
215 {
216 return o;
217 }
218
219 template <typename IteratorT, typename ValueT>
220 inline std::ostream&
221 operator<<(std::ostream& o, node_iter_data<IteratorT, ValueT> const& n)
222 {
223 o << "(id = " << n.id() << " text = \"";
224 typedef typename node_iter_data<IteratorT, ValueT>::const_iterator_t
225 iterator_t;
226 for (iterator_t it = n.begin(); it != n.end(); ++it)
227 impl::token_printer(o, *it);
228 o << "\" is_root = " << n.is_root()
229 << /*" value = " << n.value() << */")";
230 return o;
231 }
232 #endif
233
234 //////////////////////////////////
235 template <typename IteratorT = char const*, typename ValueT = nil_t>
236 struct node_val_data
237 {
238 typedef
239 typename std::iterator_traits<IteratorT>::value_type
240 value_type;
241
242 #if !defined(BOOST_SPIRIT_USE_BOOST_ALLOCATOR_FOR_TREES)
243 typedef std::allocator<value_type> allocator_type;
244 #elif !defined(BOOST_SPIRIT_USE_LIST_FOR_TREES)
245 typedef boost::pool_allocator<value_type> allocator_type;
246 #else
247 typedef boost::fast_pool_allocator<value_type> allocator_type;
248 #endif
249
250 #if !defined(BOOST_SPIRIT_USE_LIST_FOR_TREES)
251 typedef std::vector<value_type, allocator_type> container_t;
252 #else
253 typedef std::list<value_type, allocator_type> container_t;
254 #endif
255
256 typedef typename container_t::iterator iterator_t;
257 typedef typename container_t::const_iterator const_iterator_t;
258
259 node_val_data()
260 : text(), is_root_(false), parser_id_(), value_()
261 {}
262
263 #if defined(BOOST_NO_TEMPLATED_ITERATOR_CONSTRUCTORS)
264 node_val_data(IteratorT const& _first, IteratorT const& _last)
265 : text(), is_root_(false), parser_id_(), value_()
266 {
267 std::copy(_first, _last, std::inserter(text, text.end()));
268 }
269
270 // This constructor is for building text out of iterators
271 template <typename IteratorT2>
272 node_val_data(IteratorT2 const& _first, IteratorT2 const& _last)
273 : text(), is_root_(false), parser_id_(), value_()
274 {
275 std::copy(_first, _last, std::inserter(text, text.end()));
276 }
277 #else
278 node_val_data(IteratorT const& _first, IteratorT const& _last)
279 : text(_first, _last), is_root_(false), parser_id_(), value_()
280 {}
281
282 // This constructor is for building text out of iterators
283 template <typename IteratorT2>
284 node_val_data(IteratorT2 const& _first, IteratorT2 const& _last)
285 : text(_first, _last), is_root_(false), parser_id_(), value_()
286 {}
287 #endif
288
289 void swap(node_val_data& x)
290 {
291 impl::cp_swap(text, x.text);
292 impl::cp_swap(is_root_, x.is_root_);
293 impl::cp_swap(parser_id_, x.parser_id_);
294 impl::cp_swap(value_, x.value_);
295 }
296
297 typename container_t::iterator begin()
298 {
299 return text.begin();
300 }
301
302 typename container_t::const_iterator begin() const
303 {
304 return text.begin();
305 }
306
307 typename container_t::iterator end()
308 {
309 return text.end();
310 }
311
312 typename container_t::const_iterator end() const
313 {
314 return text.end();
315 }
316
317 bool is_root() const
318 {
319 return is_root_;
320 }
321
322 void is_root(bool b)
323 {
324 is_root_ = b;
325 }
326
327 parser_id id() const
328 {
329 return parser_id_;
330 }
331
332 void id(parser_id r)
333 {
334 parser_id_ = r;
335 }
336
337 ValueT const& value() const
338 {
339 return value_;
340 }
341
342 void value(ValueT const& v)
343 {
344 value_ = v;
345 }
346
347 private:
348 container_t text;
349 bool is_root_;
350 parser_id parser_id_;
351 ValueT value_;
352 };
353
354 #if defined(BOOST_SPIRIT_DEBUG) && \
355 (BOOST_SPIRIT_DEBUG_FLAGS & BOOST_SPIRIT_DEBUG_FLAGS_NODES)
356 template <typename IteratorT, typename ValueT>
357 inline std::ostream&
358 operator<<(std::ostream& o, node_val_data<IteratorT, ValueT> const& n)
359 {
360 o << "(id = " << n.id() << " text = \"";
361 typedef typename node_val_data<IteratorT, ValueT>::const_iterator_t
362 iterator_t;
363 for (iterator_t it = n.begin(); it != n.end(); ++it)
364 impl::token_printer(o, *it);
365 o << "\" is_root = " << n.is_root()
366 << " value = " << n.value() << ")";
367 return o;
368 }
369 #endif
370
371 template <typename T>
372 inline void
373 swap(tree_node<T>& a, tree_node<T>& b)
374 {
375 a.swap(b);
376 }
377
378 template <typename T, typename V>
379 inline void
380 swap(node_iter_data<T, V>& a, node_iter_data<T, V>& b)
381 {
382 a.swap(b);
383 }
384
385 //////////////////////////////////
386 template <typename ValueT>
387 class node_iter_data_factory
388 {
389 public:
390 // This inner class is so that node_iter_data_factory can simulate
391 // a template template parameter
392 template <typename IteratorT>
393 class factory
394 {
395 public:
396 typedef IteratorT iterator_t;
397 typedef node_iter_data<iterator_t, ValueT> node_t;
398
399 static node_t create_node(iterator_t const& first, iterator_t const& last,
400 bool /*is_leaf_node*/)
401 {
402 return node_t(first, last);
403 }
404
405 static node_t empty_node()
406 {
407 return node_t();
408 }
409
410 // precondition: ContainerT contains a tree_node<node_t>. And all
411 // iterators in the container point to the same sequence.
412 template <typename ContainerT>
413 static node_t group_nodes(ContainerT const& nodes)
414 {
415 return node_t(nodes.begin()->value.begin(),
416 nodes.back().value.end());
417 }
418 };
419 };
420
421 //////////////////////////////////
422 template <typename ValueT>
423 class node_val_data_factory
424 {
425 public:
426 // This inner class is so that node_val_data_factory can simulate
427 // a template template parameter
428 template <typename IteratorT>
429 class factory
430 {
431 public:
432 typedef IteratorT iterator_t;
433 typedef node_val_data<iterator_t, ValueT> node_t;
434
435 static node_t create_node(iterator_t const& first, iterator_t const& last,
436 bool is_leaf_node)
437 {
438 if (is_leaf_node)
439 return node_t(first, last);
440 else
441 return node_t();
442 }
443
444 static node_t empty_node()
445 {
446 return node_t();
447 }
448
449 template <typename ContainerT>
450 static node_t group_nodes(ContainerT const& nodes)
451 {
452 typename node_t::container_t c;
453 typename ContainerT::const_iterator i_end = nodes.end();
454 // copy all the nodes text into a new one
455 for (typename ContainerT::const_iterator i = nodes.begin();
456 i != i_end; ++i)
457 {
458 // See docs: reduced_node_d cannot be used with a
459 // rule inside the [].
460 BOOST_ASSERT(i->children.size() == 0);
461 c.insert(c.end(), i->value.begin(), i->value.end());
462 }
463 return node_t(c.begin(), c.end());
464 }
465 };
466 };
467
468 //////////////////////////////////
469 template <typename ValueT>
470 class node_all_val_data_factory
471 {
472 public:
473 // This inner class is so that node_all_val_data_factory can simulate
474 // a template template parameter
475 template <typename IteratorT>
476 class factory
477 {
478 public:
479 typedef IteratorT iterator_t;
480 typedef node_val_data<iterator_t, ValueT> node_t;
481
482 static node_t create_node(iterator_t const& first, iterator_t const& last,
483 bool /*is_leaf_node*/)
484 {
485 return node_t(first, last);
486 }
487
488 static node_t empty_node()
489 {
490 return node_t();
491 }
492
493 template <typename ContainerT>
494 static node_t group_nodes(ContainerT const& nodes)
495 {
496 typename node_t::container_t c;
497 typename ContainerT::const_iterator i_end = nodes.end();
498 // copy all the nodes text into a new one
499 for (typename ContainerT::const_iterator i = nodes.begin();
500 i != i_end; ++i)
501 {
502 BOOST_ASSERT(i->children.size() == 0);
503 c.insert(c.end(), i->value.begin(), i->value.end());
504 }
505 return node_t(c.begin(), c.end());
506 }
507 };
508 };
509
510 namespace impl {
511
512 ///////////////////////////////////////////////////////////////////////////
513 // can't call unqualified swap from within classname::swap
514 // as Koenig lookup rules will find only the classname::swap
515 // member function not the global declaration, so use cp_swap
516 // as a forwarding function (JM):
517 template <typename T>
518 inline void cp_swap(T& t1, T& t2)
519 {
520 using std::swap;
521 using BOOST_SPIRIT_CLASSIC_NS::swap;
522 using boost::swap;
523 swap(t1, t2);
524 }
525 }
526
527 //////////////////////////////////
528 template <typename IteratorT, typename NodeFactoryT, typename T>
529 class tree_match : public match<T>
530 {
531 public:
532
533 typedef typename NodeFactoryT::template factory<IteratorT> node_factory_t;
534 typedef typename node_factory_t::node_t parse_node_t;
535 typedef tree_node<parse_node_t> node_t;
536 typedef typename node_t::children_t container_t;
537 typedef typename container_t::iterator tree_iterator;
538 typedef typename container_t::const_iterator const_tree_iterator;
539
540 typedef T attr_t;
541 typedef typename boost::call_traits<T>::param_type param_type;
542 typedef typename boost::call_traits<T>::reference reference;
543 typedef typename boost::call_traits<T>::const_reference const_reference;
544
545 tree_match()
546 : match<T>(), trees()
547 {}
548
549 explicit
550 tree_match(std::size_t length_)
551 : match<T>(length_), trees()
552 {}
553
554 tree_match(std::size_t length_, parse_node_t const& n)
555 : match<T>(length_), trees()
556 {
557 trees.push_back(node_t(n));
558 }
559
560 tree_match(std::size_t length_, param_type val, parse_node_t const& n)
561 : match<T>(length_, val), trees()
562 {
563 #if !defined(BOOST_SPIRIT_USE_LIST_FOR_TREES)
564 trees.reserve(10); // this is more or less an arbitrary number...
565 #endif
566 trees.push_back(node_t(n));
567 }
568
569 // attention, these constructors will change the second parameter!
570 tree_match(std::size_t length_, container_t& c)
571 : match<T>(length_), trees()
572 {
573 impl::cp_swap(trees, c);
574 }
575
576 tree_match(std::size_t length_, param_type val, container_t& c)
577 : match<T>(length_, val), trees()
578 {
579 impl::cp_swap(trees, c);
580 }
581
582 template <typename T2>
583 tree_match(match<T2> const& other)
584 : match<T>(other), trees()
585 {}
586
587 template <typename T2, typename T3, typename T4>
588 tree_match(tree_match<T2, T3, T4> const& other)
589 : match<T>(other), trees()
590 { impl::cp_swap(trees, other.trees); }
591
592 template <typename T2>
593 tree_match&
594 operator=(match<T2> const& other)
595 {
596 match<T>::operator=(other);
597 return *this;
598 }
599
600 template <typename T2, typename T3, typename T4>
601 tree_match&
602 operator=(tree_match<T2, T3, T4> const& other)
603 {
604 match<T>::operator=(other);
605 impl::cp_swap(trees, other.trees);
606 return *this;
607 }
608
609 tree_match(tree_match const& x)
610 : match<T>(x), trees()
611 {
612 // use auto_ptr like ownership for the trees data member
613 impl::cp_swap(trees, x.trees);
614 }
615
616 tree_match& operator=(tree_match const& x)
617 {
618 tree_match tmp(x);
619 this->swap(tmp);
620 return *this;
621 }
622
623 void swap(tree_match& x)
624 {
625 match<T>::swap(x);
626 impl::cp_swap(trees, x.trees);
627 }
628
629 mutable container_t trees;
630 };
631
632 #if defined(BOOST_SPIRIT_DEBUG) && \
633 (BOOST_SPIRIT_DEBUG_FLAGS & BOOST_SPIRIT_DEBUG_FLAGS_NODES)
634 template <typename IteratorT, typename NodeFactoryT, typename T>
635 inline std::ostream&
636 operator<<(std::ostream& o, tree_match<IteratorT, NodeFactoryT, T> const& m)
637 {
638 typedef
639 typename tree_match<IteratorT, NodeFactoryT, T>::container_t::iterator
640 iterator;
641
642 o << "(length = " << (int)m.length();
643 int c = 0;
644 for (iterator i = m.trees.begin(); i != m.trees.end(); ++i)
645 {
646 o << " trees[" << c++ << "] = " << *i;
647 }
648 o << "\n)";
649 return o;
650 }
651 #endif
652
653 //////////////////////////////////
654 struct tree_policy
655 {
656 template <typename FunctorT, typename MatchT>
657 static void apply_op_to_match(FunctorT const& /*op*/, MatchT& /*m*/)
658 {}
659
660 template <typename MatchT, typename Iterator1T, typename Iterator2T>
661 static void group_match(MatchT& /*m*/, parser_id const& /*id*/,
662 Iterator1T const& /*first*/, Iterator2T const& /*last*/)
663 {}
664
665 template <typename MatchT>
666 static void concat(MatchT& /*a*/, MatchT const& /*b*/)
667 {}
668 };
669
670 //////////////////////////////////
671 template <
672 typename MatchPolicyT,
673 typename IteratorT,
674 typename NodeFactoryT,
675 typename TreePolicyT,
676 typename T
677 >
678 struct common_tree_match_policy : public match_policy
679 {
680 common_tree_match_policy()
681 {
682 }
683
684 template <typename PolicyT>
685 common_tree_match_policy(PolicyT const & policies)
686 : match_policy((match_policy const &)policies)
687 {
688 }
689
690 template <typename U>
691 struct result { typedef tree_match<IteratorT, NodeFactoryT, U> type; };
692
693 typedef tree_match<IteratorT, NodeFactoryT, T> match_t;
694 typedef IteratorT iterator_t;
695 typedef TreePolicyT tree_policy_t;
696 typedef NodeFactoryT factory_t;
697
698 static const match_t no_match() { return match_t(); }
699 static const match_t empty_match()
700 { return match_t(0, tree_policy_t::empty_node()); }
701
702 template <typename AttrT, typename Iterator1T, typename Iterator2T>
703 static tree_match<IteratorT, NodeFactoryT, AttrT> create_match(
704 std::size_t length,
705 AttrT const& val,
706 Iterator1T const& first,
707 Iterator2T const& last)
708 {
709 #if defined(BOOST_SPIRIT_DEBUG) && \
710 (BOOST_SPIRIT_DEBUG_FLAGS & BOOST_SPIRIT_DEBUG_FLAGS_NODES)
711
712 BOOST_SPIRIT_DEBUG_OUT << "\n>>> create_node(begin) <<<\n"
713 "creating node text: \"";
714 for (Iterator1T it = first; it != last; ++it)
715 impl::token_printer(BOOST_SPIRIT_DEBUG_OUT, *it);
716 BOOST_SPIRIT_DEBUG_OUT << "\"\n";
717 BOOST_SPIRIT_DEBUG_OUT << ">>> create_node(end) <<<\n\n";
718 #endif
719 return tree_match<IteratorT, NodeFactoryT, AttrT>(length, val,
720 tree_policy_t::create_node(length, first, last, true));
721 }
722
723 template <typename Match1T, typename Match2T>
724 static void concat_match(Match1T& a, Match2T const& b)
725 {
726 #if defined(BOOST_SPIRIT_DEBUG) && \
727 (BOOST_SPIRIT_DEBUG_FLAGS & BOOST_SPIRIT_DEBUG_FLAGS_NODES)
728
729 BOOST_SPIRIT_DEBUG_OUT << "\n>>> concat_match(begin) <<<\n";
730 BOOST_SPIRIT_DEBUG_OUT << "tree a:\n" << a << "\n";
731 BOOST_SPIRIT_DEBUG_OUT << "tree b:\n" << b << "\n";
732 BOOST_SPIRIT_DEBUG_OUT << ">>> concat_match(end) <<<\n\n";
733 #endif
734 BOOST_SPIRIT_ASSERT(a && b);
735 if (a.length() == 0)
736 {
737 a = b;
738 return;
739 }
740 else if (b.length() == 0
741 #ifdef BOOST_SPIRIT_NO_TREE_NODE_COLLAPSING
742 && !b.trees.begin()->value.id().to_long()
743 #endif
744 )
745 {
746 return;
747 }
748 a.concat(b);
749 tree_policy_t::concat(a, b);
750 }
751
752 template <typename MatchT, typename IteratorT2>
753 void
754 group_match(
755 MatchT& m,
756 parser_id const& id,
757 IteratorT2 const& first,
758 IteratorT2 const& last) const
759 {
760 if (!m) return;
761
762 #if defined(BOOST_SPIRIT_DEBUG) && \
763 (BOOST_SPIRIT_DEBUG_FLAGS & BOOST_SPIRIT_DEBUG_FLAGS_TREES)
764
765 BOOST_SPIRIT_DEBUG_OUT << "\n>>> group_match(begin) <<<\n"
766 "new node(" << id << ") \"";
767 for (IteratorT2 it = first; it != last; ++it)
768 impl::token_printer(BOOST_SPIRIT_DEBUG_OUT, *it);
769 BOOST_SPIRIT_DEBUG_OUT << "\"\n";
770 BOOST_SPIRIT_DEBUG_OUT << "new child tree (before grouping):\n" << m << "\n";
771
772 tree_policy_t::group_match(m, id, first, last);
773
774 BOOST_SPIRIT_DEBUG_OUT << "new child tree (after grouping):\n" << m << "\n";
775 BOOST_SPIRIT_DEBUG_OUT << ">>> group_match(end) <<<\n\n";
776 #else
777 tree_policy_t::group_match(m, id, first, last);
778 #endif
779 }
780 };
781
782 //////////////////////////////////
783 template <typename MatchPolicyT, typename NodeFactoryT>
784 struct common_tree_tree_policy
785 {
786 typedef typename MatchPolicyT::iterator_t iterator_t;
787 typedef typename MatchPolicyT::match_t match_t;
788 typedef typename NodeFactoryT::template factory<iterator_t> factory_t;
789 typedef typename factory_t::node_t node_t;
790
791 template <typename Iterator1T, typename Iterator2T>
792 static node_t
793 create_node(std::size_t /*length*/, Iterator1T const& first,
794 Iterator2T const& last, bool leaf_node)
795 {
796 return factory_t::create_node(first, last, leaf_node);
797 }
798
799 static node_t
800 empty_node()
801 {
802 return factory_t::empty_node();
803 }
804
805 template <typename FunctorT>
806 static void apply_op_to_match(FunctorT const& op, match_t& m)
807 {
808 op(m);
809 }
810 };
811
812 //////////////////////////////////
813 // directives to modify how the parse tree is generated
814
815 struct no_tree_gen_node_parser_gen;
816
817 template <typename T>
818 struct no_tree_gen_node_parser
819 : public unary<T, parser<no_tree_gen_node_parser<T> > >
820 {
821 typedef no_tree_gen_node_parser<T> self_t;
822 typedef no_tree_gen_node_parser_gen parser_generator_t;
823 typedef unary_parser_category parser_category_t;
824
825 no_tree_gen_node_parser(T const& a)
826 : unary<T, parser<no_tree_gen_node_parser<T> > >(a) {}
827
828 template <typename ScannerT>
829 typename parser_result<self_t, ScannerT>::type
830 parse(ScannerT const& scanner) const
831 {
832 typedef typename ScannerT::iteration_policy_t iteration_policy_t;
833 typedef match_policy match_policy_t;
834 typedef typename ScannerT::action_policy_t action_policy_t;
835 typedef scanner_policies<
836 iteration_policy_t,
837 match_policy_t,
838 action_policy_t
839 > policies_t;
840
841 return this->subject().parse(scanner.change_policies(policies_t(scanner)));
842 }
843 };
844
845 struct no_tree_gen_node_parser_gen
846 {
847 template <typename T>
848 struct result {
849
850 typedef no_tree_gen_node_parser<T> type;
851 };
852
853 template <typename T>
854 static no_tree_gen_node_parser<T>
855 generate(parser<T> const& s)
856 {
857 return no_tree_gen_node_parser<T>(s.derived());
858 }
859
860 template <typename T>
861 no_tree_gen_node_parser<T>
862 operator[](parser<T> const& s) const
863 {
864 return no_tree_gen_node_parser<T>(s.derived());
865 }
866 };
867
868 const no_tree_gen_node_parser_gen no_node_d = no_tree_gen_node_parser_gen();
869
870 //////////////////////////////////
871
872 struct leaf_node_parser_gen;
873
874 template<typename T>
875 struct leaf_node_parser
876 : public unary<T, parser<leaf_node_parser<T> > >
877 {
878 typedef leaf_node_parser<T> self_t;
879 typedef leaf_node_parser_gen parser_generator_t;
880 typedef unary_parser_category parser_category_t;
881
882 leaf_node_parser(T const& a)
883 : unary<T, parser<leaf_node_parser<T> > >(a) {}
884
885 template <typename ScannerT>
886 typename parser_result<self_t, ScannerT>::type
887 parse(ScannerT const& scanner) const
888 {
889 typedef scanner_policies< typename ScannerT::iteration_policy_t,
890 match_policy, typename ScannerT::action_policy_t > policies_t;
891
892 typedef typename ScannerT::iterator_t iterator_t;
893 typedef typename parser_result<self_t, ScannerT>::type result_t;
894 typedef typename result_t::node_factory_t factory_t;
895
896 iterator_t from = scanner.first;
897 result_t hit = impl::contiguous_parser_parse<result_t>(this->subject(),
898 scanner.change_policies(policies_t(scanner,match_policy(),scanner)),
899 scanner);
900
901 if (hit)
902 return result_t(hit.length(),
903 factory_t::create_node(from, scanner.first, true));
904 else
905 return result_t(hit.length());
906 }
907 };
908
909 struct leaf_node_parser_gen
910 {
911 template <typename T>
912 struct result {
913
914 typedef leaf_node_parser<T> type;
915 };
916
917 template <typename T>
918 static leaf_node_parser<T>
919 generate(parser<T> const& s)
920 {
921 return leaf_node_parser<T>(s.derived());
922 }
923
924 template <typename T>
925 leaf_node_parser<T>
926 operator[](parser<T> const& s) const
927 {
928 return leaf_node_parser<T>(s.derived());
929 }
930 };
931
932 const leaf_node_parser_gen leaf_node_d = leaf_node_parser_gen();
933 const leaf_node_parser_gen token_node_d = leaf_node_parser_gen();
934
935 //////////////////////////////////
936 namespace impl {
937
938 template <typename MatchPolicyT>
939 struct tree_policy_selector
940 {
941 typedef tree_policy type;
942 };
943
944 } // namespace impl
945
946 //////////////////////////////////
947 template <typename NodeParserT>
948 struct node_parser_gen;
949
950 template <typename T, typename NodeParserT>
951 struct node_parser
952 : public unary<T, parser<node_parser<T, NodeParserT> > >
953 {
954 typedef node_parser<T, NodeParserT> self_t;
955 typedef node_parser_gen<NodeParserT> parser_generator_t;
956 typedef unary_parser_category parser_category_t;
957
958 node_parser(T const& a)
959 : unary<T, parser<node_parser<T, NodeParserT> > >(a) {}
960
961 template <typename ScannerT>
962 struct result
963 {
964 typedef typename parser_result<T, ScannerT>::type type;
965 };
966
967 template <typename ScannerT>
968 typename parser_result<self_t, ScannerT>::type
969 parse(ScannerT const& scanner) const
970 {
971 typename parser_result<self_t, ScannerT>::type hit = this->subject().parse(scanner);
972 if (hit)
973 {
974 impl::tree_policy_selector<typename ScannerT::match_policy_t>::type::apply_op_to_match(NodeParserT(), hit);
975 }
976 return hit;
977 }
978 };
979
980 template <typename NodeParserT>
981 struct node_parser_gen
982 {
983 template <typename T>
984 struct result {
985
986 typedef node_parser<T, NodeParserT> type;
987 };
988
989 template <typename T>
990 static node_parser<T, NodeParserT>
991 generate(parser<T> const& s)
992 {
993 return node_parser<T, NodeParserT>(s.derived());
994 }
995
996 template <typename T>
997 node_parser<T, NodeParserT>
998 operator[](parser<T> const& s) const
999 {
1000 return node_parser<T, NodeParserT>(s.derived());
1001 }
1002 };
1003 //////////////////////////////////
1004 struct reduced_node_op
1005 {
1006 template <typename MatchT>
1007 void operator()(MatchT& m) const
1008 {
1009 if (m.trees.size() == 1)
1010 {
1011 m.trees.begin()->children.clear();
1012 }
1013 else if (m.trees.size() > 1)
1014 {
1015 typedef typename MatchT::node_factory_t node_factory_t;
1016 m = MatchT(m.length(), node_factory_t::group_nodes(m.trees));
1017 }
1018 }
1019 };
1020
1021 const node_parser_gen<reduced_node_op> reduced_node_d =
1022 node_parser_gen<reduced_node_op>();
1023
1024
1025 struct discard_node_op
1026 {
1027 template <typename MatchT>
1028 void operator()(MatchT& m) const
1029 {
1030 m.trees.clear();
1031 }
1032 };
1033
1034 const node_parser_gen<discard_node_op> discard_node_d =
1035 node_parser_gen<discard_node_op>();
1036
1037 struct infix_node_op
1038 {
1039 template <typename MatchT>
1040 void operator()(MatchT& m) const
1041 {
1042 typedef typename MatchT::container_t container_t;
1043 typedef typename MatchT::container_t::iterator iter_t;
1044 typedef typename MatchT::container_t::value_type value_t;
1045
1046 using std::swap;
1047 using boost::swap;
1048 using BOOST_SPIRIT_CLASSIC_NS::swap;
1049
1050 // copying the tree nodes is expensive, since it may copy a whole
1051 // tree. swapping them is cheap, so swap the nodes we want into
1052 // a new container of children.
1053 container_t new_children;
1054 std::size_t length = 0;
1055 std::size_t tree_size = m.trees.size();
1056
1057 // the infix_node_d[] make no sense for nodes with no subnodes
1058 BOOST_SPIRIT_ASSERT(tree_size >= 1);
1059
1060 bool keep = true;
1061 #if !defined(BOOST_SPIRIT_USE_LIST_FOR_TREES)
1062 new_children.reserve((tree_size+1)/2);
1063 #endif
1064 iter_t i_end = m.trees.end();
1065 for (iter_t i = m.trees.begin(); i != i_end; ++i)
1066 {
1067 if (keep) {
1068 // adjust the length
1069 length += std::distance((*i).value.begin(), (*i).value.end());
1070
1071 // move the child node
1072 new_children.push_back(value_t());
1073 swap(new_children.back(), *i);
1074 keep = false;
1075 }
1076 else {
1077 // ignore this child node
1078 keep = true;
1079 }
1080 }
1081
1082 m = MatchT(length, new_children);
1083 }
1084 };
1085
1086 const node_parser_gen<infix_node_op> infix_node_d =
1087 node_parser_gen<infix_node_op>();
1088
1089 struct discard_first_node_op
1090 {
1091 template <typename MatchT>
1092 void operator()(MatchT& m) const
1093 {
1094 typedef typename MatchT::container_t container_t;
1095 typedef typename MatchT::container_t::iterator iter_t;
1096 typedef typename MatchT::container_t::value_type value_t;
1097
1098 using std::swap;
1099 using boost::swap;
1100 using BOOST_SPIRIT_CLASSIC_NS::swap;
1101
1102 // copying the tree nodes is expensive, since it may copy a whole
1103 // tree. swapping them is cheap, so swap the nodes we want into
1104 // a new container of children, instead of saying
1105 // m.trees.erase(m.trees.begin()) because, on a container_t that will
1106 // cause all the nodes afterwards to be copied into the previous
1107 // position.
1108 container_t new_children;
1109 std::size_t length = 0;
1110 std::size_t tree_size = m.trees.size();
1111
1112 // the discard_first_node_d[] make no sense for nodes with no subnodes
1113 BOOST_SPIRIT_ASSERT(tree_size >= 1);
1114
1115 if (tree_size > 1) {
1116 #if !defined(BOOST_SPIRIT_USE_LIST_FOR_TREES)
1117 new_children.reserve(tree_size - 1);
1118 #endif
1119 iter_t i = m.trees.begin(), i_end = m.trees.end();
1120 for (++i; i != i_end; ++i)
1121 {
1122 // adjust the length
1123 length += std::distance((*i).value.begin(), (*i).value.end());
1124
1125 // move the child node
1126 new_children.push_back(value_t());
1127 swap(new_children.back(), *i);
1128 }
1129 }
1130 else {
1131 // if there was a tree and now there isn't any, insert an empty node
1132 iter_t i = m.trees.begin();
1133
1134 // This isn't entirely correct, since the empty node will reference
1135 // the end of the discarded node, but I currently don't see any way to
1136 // get at the begin of the node following this subnode.
1137 // This should be safe anyway because the it shouldn't get dereferenced
1138 // under any circumstances.
1139 typedef typename value_t::parse_node_t::iterator_t iterator_type;
1140 iterator_type it = (*i).value.end();
1141
1142 new_children.push_back(
1143 value_t(typename value_t::parse_node_t(it, it)));
1144 }
1145
1146 m = MatchT(length, new_children);
1147 }
1148 };
1149
1150 const node_parser_gen<discard_first_node_op> discard_first_node_d =
1151 node_parser_gen<discard_first_node_op>();
1152
1153 struct discard_last_node_op
1154 {
1155 template <typename MatchT>
1156 void operator()(MatchT& m) const
1157 {
1158 typedef typename MatchT::container_t container_t;
1159 typedef typename MatchT::container_t::iterator iter_t;
1160 typedef typename MatchT::container_t::value_type value_t;
1161
1162 using std::swap;
1163 using boost::swap;
1164 using BOOST_SPIRIT_CLASSIC_NS::swap;
1165
1166 // copying the tree nodes is expensive, since it may copy a whole
1167 // tree. swapping them is cheap, so swap the nodes we want into
1168 // a new container of children, instead of saying
1169 // m.trees.erase(m.trees.begin()) because, on a container_t that will
1170 // cause all the nodes afterwards to be copied into the previous
1171 // position.
1172 container_t new_children;
1173 std::size_t length = 0;
1174 std::size_t tree_size = m.trees.size();
1175
1176 // the discard_last_node_d[] make no sense for nodes with no subnodes
1177 BOOST_SPIRIT_ASSERT(tree_size >= 1);
1178
1179 if (tree_size > 1) {
1180 m.trees.pop_back();
1181 #if !defined(BOOST_SPIRIT_USE_LIST_FOR_TREES)
1182 new_children.reserve(tree_size - 1);
1183 #endif
1184 iter_t i_end = m.trees.end();
1185 for (iter_t i = m.trees.begin(); i != i_end; ++i)
1186 {
1187 // adjust the length
1188 length += std::distance((*i).value.begin(), (*i).value.end());
1189
1190 // move the child node
1191 new_children.push_back(value_t());
1192 swap(new_children.back(), *i);
1193 }
1194 }
1195 else {
1196 // if there was a tree and now there isn't any, insert an empty node
1197 iter_t i = m.trees.begin();
1198
1199 typedef typename value_t::parse_node_t::iterator_t iterator_type;
1200 iterator_type it = (*i).value.begin();
1201
1202 new_children.push_back(
1203 value_t(typename value_t::parse_node_t(it, it)));
1204 }
1205
1206 m = MatchT(length, new_children);
1207 }
1208 };
1209
1210 const node_parser_gen<discard_last_node_op> discard_last_node_d =
1211 node_parser_gen<discard_last_node_op>();
1212
1213 struct inner_node_op
1214 {
1215 template <typename MatchT>
1216 void operator()(MatchT& m) const
1217 {
1218 typedef typename MatchT::container_t container_t;
1219 typedef typename MatchT::container_t::iterator iter_t;
1220 typedef typename MatchT::container_t::value_type value_t;
1221
1222 using std::swap;
1223 using boost::swap;
1224 using BOOST_SPIRIT_CLASSIC_NS::swap;
1225
1226 // copying the tree nodes is expensive, since it may copy a whole
1227 // tree. swapping them is cheap, so swap the nodes we want into
1228 // a new container of children, instead of saying
1229 // m.trees.erase(m.trees.begin()) because, on a container_t that will
1230 // cause all the nodes afterwards to be copied into the previous
1231 // position.
1232 container_t new_children;
1233 std::size_t length = 0;
1234 std::size_t tree_size = m.trees.size();
1235
1236 // the inner_node_d[] make no sense for nodes with less then 2 subnodes
1237 BOOST_SPIRIT_ASSERT(tree_size >= 2);
1238
1239 if (tree_size > 2) {
1240 m.trees.pop_back(); // erase the last element
1241 #if !defined(BOOST_SPIRIT_USE_LIST_FOR_TREES)
1242 new_children.reserve(tree_size - 1);
1243 #endif
1244 iter_t i = m.trees.begin(); // skip over the first element
1245 iter_t i_end = m.trees.end();
1246 for (++i; i != i_end; ++i)
1247 {
1248 // adjust the length
1249 length += std::distance((*i).value.begin(), (*i).value.end());
1250
1251 // move the child node
1252 new_children.push_back(value_t());
1253 swap(new_children.back(), *i);
1254 }
1255 }
1256 else {
1257 // if there was a tree and now there isn't any, insert an empty node
1258 iter_t i = m.trees.begin(); // skip over the first element
1259
1260 typedef typename value_t::parse_node_t::iterator_t iterator_type;
1261 iterator_type it = (*++i).value.begin();
1262
1263 new_children.push_back(
1264 value_t(typename value_t::parse_node_t(it, it)));
1265 }
1266
1267 m = MatchT(length, new_children);
1268 }
1269 };
1270
1271 const node_parser_gen<inner_node_op> inner_node_d =
1272 node_parser_gen<inner_node_op>();
1273
1274
1275 //////////////////////////////////
1276 // action_directive_parser and action_directive_parser_gen
1277 // are meant to be used as a template to create directives that
1278 // generate action classes. For example access_match and
1279 // access_node. The ActionParserT template parameter must be
1280 // a class that has an innter class called action that is templated
1281 // on the parser type and the action type.
1282 template <typename ActionParserT>
1283 struct action_directive_parser_gen;
1284
1285 template <typename T, typename ActionParserT>
1286 struct action_directive_parser
1287 : public unary<T, parser<action_directive_parser<T, ActionParserT> > >
1288 {
1289 typedef action_directive_parser<T, ActionParserT> self_t;
1290 typedef action_directive_parser_gen<ActionParserT> parser_generator_t;
1291 typedef unary_parser_category parser_category_t;
1292
1293 action_directive_parser(T const& a)
1294 : unary<T, parser<action_directive_parser<T, ActionParserT> > >(a) {}
1295
1296 template <typename ScannerT>
1297 struct result
1298 {
1299 typedef typename parser_result<T, ScannerT>::type type;
1300 };
1301
1302 template <typename ScannerT>
1303 typename parser_result<self_t, ScannerT>::type
1304 parse(ScannerT const& scanner) const
1305 {
1306 return this->subject().parse(scanner);
1307 }
1308
1309 template <typename ActionT>
1310 typename ActionParserT::template action<action_directive_parser<T, ActionParserT>, ActionT>
1311 operator[](ActionT const& actor) const
1312 {
1313 typedef typename
1314 ActionParserT::template action<action_directive_parser, ActionT>
1315 action_t;
1316 return action_t(*this, actor);
1317 }
1318 };
1319
1320 //////////////////////////////////
1321 template <typename ActionParserT>
1322 struct action_directive_parser_gen
1323 {
1324 template <typename T>
1325 struct result {
1326
1327 typedef action_directive_parser<T, ActionParserT> type;
1328 };
1329
1330 template <typename T>
1331 static action_directive_parser<T, ActionParserT>
1332 generate(parser<T> const& s)
1333 {
1334 return action_directive_parser<T, ActionParserT>(s.derived());
1335 }
1336
1337 template <typename T>
1338 action_directive_parser<T, ActionParserT>
1339 operator[](parser<T> const& s) const
1340 {
1341 return action_directive_parser<T, ActionParserT>(s.derived());
1342 }
1343 };
1344
1345 //////////////////////////////////
1346 // Calls the attached action passing it the match from the parser
1347 // and the first and last iterators.
1348 // The inner template class is used to simulate template-template parameters
1349 // (declared in common_fwd.hpp).
1350 template <typename ParserT, typename ActionT>
1351 struct access_match_action::action
1352 : public unary<ParserT, parser<access_match_action::action<ParserT, ActionT> > >
1353 {
1354 typedef action_parser_category parser_category;
1355 typedef action<ParserT, ActionT> self_t;
1356
1357 template <typename ScannerT>
1358 struct result
1359 {
1360 typedef typename parser_result<ParserT, ScannerT>::type type;
1361 };
1362
1363 action( ParserT const& subject,
1364 ActionT const& actor_);
1365
1366 template <typename ScannerT>
1367 typename parser_result<self_t, ScannerT>::type
1368 parse(ScannerT const& scanner) const;
1369
1370 ActionT const &predicate() const;
1371
1372 private:
1373 ActionT actor;
1374 };
1375
1376 //////////////////////////////////
1377 template <typename ParserT, typename ActionT>
1378 access_match_action::action<ParserT, ActionT>::action(
1379 ParserT const& subject,
1380 ActionT const& actor_)
1381 : unary<ParserT, parser<access_match_action::action<ParserT, ActionT> > >(subject)
1382 , actor(actor_)
1383 {}
1384
1385 //////////////////////////////////
1386 template <typename ParserT, typename ActionT>
1387 template <typename ScannerT>
1388 typename parser_result<access_match_action::action<ParserT, ActionT>, ScannerT>::type
1389 access_match_action::action<ParserT, ActionT>::
1390 parse(ScannerT const& scan) const
1391 {
1392 typedef typename ScannerT::iterator_t iterator_t;
1393 typedef typename parser_result<self_t, ScannerT>::type result_t;
1394 if (!scan.at_end())
1395 {
1396 iterator_t save = scan.first;
1397 result_t hit = this->subject().parse(scan);
1398 actor(hit, save, scan.first);
1399 return hit;
1400 }
1401 return scan.no_match();
1402 }
1403
1404 //////////////////////////////////
1405 template <typename ParserT, typename ActionT>
1406 ActionT const &access_match_action::action<ParserT, ActionT>::predicate() const
1407 {
1408 return actor;
1409 }
1410
1411 //////////////////////////////////
1412 const action_directive_parser_gen<access_match_action> access_match_d
1413 = action_directive_parser_gen<access_match_action>();
1414
1415
1416
1417 //////////////////////////////////
1418 // Calls the attached action passing it the node from the parser
1419 // and the first and last iterators
1420 // The inner template class is used to simulate template-template parameters
1421 // (declared in common_fwd.hpp).
1422 template <typename ParserT, typename ActionT>
1423 struct access_node_action::action
1424 : public unary<ParserT, parser<access_node_action::action<ParserT, ActionT> > >
1425 {
1426 typedef action_parser_category parser_category;
1427 typedef action<ParserT, ActionT> self_t;
1428
1429 template <typename ScannerT>
1430 struct result
1431 {
1432 typedef typename parser_result<ParserT, ScannerT>::type type;
1433 };
1434
1435 action( ParserT const& subject,
1436 ActionT const& actor_);
1437
1438 template <typename ScannerT>
1439 typename parser_result<self_t, ScannerT>::type
1440 parse(ScannerT const& scanner) const;
1441
1442 ActionT const &predicate() const;
1443
1444 private:
1445 ActionT actor;
1446 };
1447
1448 //////////////////////////////////
1449 template <typename ParserT, typename ActionT>
1450 access_node_action::action<ParserT, ActionT>::action(
1451 ParserT const& subject,
1452 ActionT const& actor_)
1453 : unary<ParserT, parser<access_node_action::action<ParserT, ActionT> > >(subject)
1454 , actor(actor_)
1455 {}
1456
1457 //////////////////////////////////
1458 template <typename ParserT, typename ActionT>
1459 template <typename ScannerT>
1460 typename parser_result<access_node_action::action<ParserT, ActionT>, ScannerT>::type
1461 access_node_action::action<ParserT, ActionT>::
1462 parse(ScannerT const& scan) const
1463 {
1464 typedef typename ScannerT::iterator_t iterator_t;
1465 typedef typename parser_result<self_t, ScannerT>::type result_t;
1466 if (!scan.at_end())
1467 {
1468 iterator_t save = scan.first;
1469 result_t hit = this->subject().parse(scan);
1470 if (hit && hit.trees.size() > 0)
1471 actor(*hit.trees.begin(), save, scan.first);
1472 return hit;
1473 }
1474 return scan.no_match();
1475 }
1476
1477 //////////////////////////////////
1478 template <typename ParserT, typename ActionT>
1479 ActionT const &access_node_action::action<ParserT, ActionT>::predicate() const
1480 {
1481 return actor;
1482 }
1483
1484 //////////////////////////////////
1485 const action_directive_parser_gen<access_node_action> access_node_d
1486 = action_directive_parser_gen<access_node_action>();
1487
1488
1489
1490 //////////////////////////////////
1491
1492 ///////////////////////////////////////////////////////////////////////////////
1493 //
1494 // tree_parse_info
1495 //
1496 // Results returned by the tree parse functions:
1497 //
1498 // stop: points to the final parse position (i.e parsing
1499 // processed the input up to this point).
1500 //
1501 // match: true if parsing is successful. This may be full:
1502 // the parser consumed all the input, or partial:
1503 // the parser consumed only a portion of the input.
1504 //
1505 // full: true when we have a full match (i.e the parser
1506 // consumed all the input.
1507 //
1508 // length: The number of characters consumed by the parser.
1509 // This is valid only if we have a successful match
1510 // (either partial or full). A negative value means
1511 // that the match is unsuccessful.
1512 //
1513 // trees: Contains the root node(s) of the tree.
1514 //
1515 ///////////////////////////////////////////////////////////////////////////////
1516 template <
1517 typename IteratorT,
1518 typename NodeFactoryT,
1519 typename T
1520 >
1521 struct tree_parse_info
1522 {
1523 IteratorT stop;
1524 bool match;
1525 bool full;
1526 std::size_t length;
1527 typename tree_match<IteratorT, NodeFactoryT, T>::container_t trees;
1528
1529 tree_parse_info()
1530 : stop()
1531 , match(false)
1532 , full(false)
1533 , length(0)
1534 , trees()
1535 {}
1536
1537 template <typename IteratorT2>
1538 tree_parse_info(tree_parse_info<IteratorT2> const& pi)
1539 : stop(pi.stop)
1540 , match(pi.match)
1541 , full(pi.full)
1542 , length(pi.length)
1543 , trees()
1544 {
1545 using std::swap;
1546 using boost::swap;
1547 using BOOST_SPIRIT_CLASSIC_NS::swap;
1548
1549 // use auto_ptr like ownership for the trees data member
1550 swap(trees, pi.trees);
1551 }
1552
1553 tree_parse_info(
1554 IteratorT stop_,
1555 bool match_,
1556 bool full_,
1557 std::size_t length_,
1558 typename tree_match<IteratorT, NodeFactoryT, T>::container_t trees_)
1559 : stop(stop_)
1560 , match(match_)
1561 , full(full_)
1562 , length(length_)
1563 , trees()
1564 {
1565 using std::swap;
1566 using boost::swap;
1567 using BOOST_SPIRIT_CLASSIC_NS::swap;
1568
1569 // use auto_ptr like ownership for the trees data member
1570 swap(trees, trees_);
1571 }
1572 };
1573
1574 BOOST_SPIRIT_CLASSIC_NAMESPACE_END
1575
1576 }} // namespace BOOST_SPIRIT_CLASSIC_NS
1577
1578 #endif
1579