comparison DEPENDENCIES/generic/include/boost/spirit/home/classic/tree/common.hpp @ 16:2665513ce2d3

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