]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/libs/spirit/include/boost/spirit/home/classic/tree/common.hpp
bump version to 12.2.2-pve1
[ceph.git] / ceph / src / boost / libs / spirit / include / boost / spirit / home / classic / tree / common.hpp
CommitLineData
7c673cae
FG
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
40namespace boost { namespace spirit {
41
42BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
43
44template <typename T>
45void swap(tree_node<T>& a, tree_node<T>& b);
46
47template <typename T, typename V>
48void swap(node_iter_data<T, V>& a, node_iter_data<T, V>& b);
49
50namespace impl {
51 template <typename T>
52 inline void cp_swap(T& t1, T& t2);
53}
54
55template <typename T>
56struct 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)
111template <typename T>
112inline std::ostream&
113operator<<(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//////////////////////////////////
135template <typename IteratorT, typename ValueT>
136struct 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 }
207private:
208 IteratorT first, last;
209 bool is_root_;
210 parser_id parser_id_;
211 ValueT value_;
212
213public:
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
219inline std::ostream&
220operator<<(std::ostream& o, nil_t const&)
221{
222 return o;
223}
224
225template <typename IteratorT, typename ValueT>
226inline std::ostream&
227operator<<(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//////////////////////////////////
241template <typename IteratorT = char const*, typename ValueT = nil_t>
242struct 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
353private:
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)
362template <typename IteratorT, typename ValueT>
363inline std::ostream&
364operator<<(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
377template <typename T>
378inline void
379swap(tree_node<T>& a, tree_node<T>& b)
380{
381 a.swap(b);
382}
383
384template <typename T, typename V>
385inline void
386swap(node_iter_data<T, V>& a, node_iter_data<T, V>& b)
387{
388 a.swap(b);
389}
390
391//////////////////////////////////
392template <typename ValueT>
393class node_iter_data_factory
394{
395public:
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//////////////////////////////////
428template <typename ValueT>
429class node_val_data_factory
430{
431public:
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//////////////////////////////////
475template <typename ValueT>
476class node_all_val_data_factory
477{
478public:
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
516namespace 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 template <typename T>
524 inline void cp_swap(T& t1, T& t2)
525 {
526 using std::swap;
527 using BOOST_SPIRIT_CLASSIC_NS::swap;
528 using boost::swap;
529 swap(t1, t2);
530 }
531}
532
533//////////////////////////////////
534template <typename IteratorT, typename NodeFactoryT, typename T>
535class tree_match : public match<T>
536{
537public:
538
539 typedef typename NodeFactoryT::template factory<IteratorT> node_factory_t;
540 typedef typename node_factory_t::node_t parse_node_t;
541 typedef tree_node<parse_node_t> node_t;
542 typedef typename node_t::children_t container_t;
543 typedef typename container_t::iterator tree_iterator;
544 typedef typename container_t::const_iterator const_tree_iterator;
545
546 typedef T attr_t;
547 typedef typename boost::call_traits<T>::param_type param_type;
548 typedef typename boost::call_traits<T>::reference reference;
549 typedef typename boost::call_traits<T>::const_reference const_reference;
550
551 tree_match()
552 : match<T>(), trees()
553 {}
554
555 explicit
556 tree_match(std::size_t length_)
557 : match<T>(length_), trees()
558 {}
559
560 tree_match(std::size_t length_, parse_node_t const& n)
561 : match<T>(length_), trees()
562 {
563 trees.push_back(node_t(n));
564 }
565
566 tree_match(std::size_t length_, param_type val, parse_node_t const& n)
567 : match<T>(length_, val), trees()
568 {
569#if !defined(BOOST_SPIRIT_USE_LIST_FOR_TREES)
570 trees.reserve(10); // this is more or less an arbitrary number...
571#endif
572 trees.push_back(node_t(n));
573 }
574
575 // attention, these constructors will change the second parameter!
576 tree_match(std::size_t length_, container_t& c)
577 : match<T>(length_), trees()
578 {
579 impl::cp_swap(trees, c);
580 }
581
582 tree_match(std::size_t length_, param_type val, container_t& c)
583 : match<T>(length_, val), trees()
584 {
585 impl::cp_swap(trees, c);
586 }
587
588 template <typename T2>
589 tree_match(match<T2> const& other)
590 : match<T>(other), trees()
591 {}
592
593 template <typename T2, typename T3, typename T4>
594 tree_match(tree_match<T2, T3, T4> const& other)
595 : match<T>(other), trees()
596 { impl::cp_swap(trees, other.trees); }
597
598 template <typename T2>
599 tree_match&
600 operator=(match<T2> const& other)
601 {
602 match<T>::operator=(other);
603 return *this;
604 }
605
606 template <typename T2, typename T3, typename T4>
607 tree_match&
608 operator=(tree_match<T2, T3, T4> const& other)
609 {
610 match<T>::operator=(other);
611 impl::cp_swap(trees, other.trees);
612 return *this;
613 }
614
615 tree_match(tree_match const& x)
616 : match<T>(x), trees()
617 {
618 // use auto_ptr like ownership for the trees data member
619 impl::cp_swap(trees, x.trees);
620 }
621
622 tree_match& operator=(tree_match const& x)
623 {
624 tree_match tmp(x);
625 this->swap(tmp);
626 return *this;
627 }
628
629 void swap(tree_match& x)
630 {
631 match<T>::swap(x);
632 impl::cp_swap(trees, x.trees);
633 }
634
635 mutable container_t trees;
636};
637
638#if defined(BOOST_SPIRIT_DEBUG) && \
639 (BOOST_SPIRIT_DEBUG_FLAGS & BOOST_SPIRIT_DEBUG_FLAGS_NODES)
640template <typename IteratorT, typename NodeFactoryT, typename T>
641inline std::ostream&
642operator<<(std::ostream& o, tree_match<IteratorT, NodeFactoryT, T> const& m)
643{
644 typedef
645 typename tree_match<IteratorT, NodeFactoryT, T>::container_t::iterator
646 iterator;
647
648 o << "(length = " << (int)m.length();
649 int c = 0;
650 for (iterator i = m.trees.begin(); i != m.trees.end(); ++i)
651 {
652 o << " trees[" << c++ << "] = " << *i;
653 }
654 o << "\n)";
655 return o;
656}
657#endif
658
659//////////////////////////////////
660struct tree_policy
661{
662 template <typename FunctorT, typename MatchT>
663 static void apply_op_to_match(FunctorT const& /*op*/, MatchT& /*m*/)
664 {}
665
666 template <typename MatchT, typename Iterator1T, typename Iterator2T>
667 static void group_match(MatchT& /*m*/, parser_id const& /*id*/,
668 Iterator1T const& /*first*/, Iterator2T const& /*last*/)
669 {}
670
671 template <typename MatchT>
672 static void concat(MatchT& /*a*/, MatchT const& /*b*/)
673 {}
674};
675
676//////////////////////////////////
677template <
678 typename MatchPolicyT,
679 typename IteratorT,
680 typename NodeFactoryT,
681 typename TreePolicyT,
682 typename T
683>
684struct common_tree_match_policy : public match_policy
685{
686 common_tree_match_policy()
687 {
688 }
689
690 template <typename PolicyT>
691 common_tree_match_policy(PolicyT const & policies)
692 : match_policy((match_policy const &)policies)
693 {
694 }
695
696 template <typename U>
697 struct result { typedef tree_match<IteratorT, NodeFactoryT, U> type; };
698
699 typedef tree_match<IteratorT, NodeFactoryT, T> match_t;
700 typedef IteratorT iterator_t;
701 typedef TreePolicyT tree_policy_t;
702 typedef NodeFactoryT factory_t;
703
704 static const match_t no_match() { return match_t(); }
705 static const match_t empty_match()
706 { return match_t(0, tree_policy_t::empty_node()); }
707
708 template <typename AttrT, typename Iterator1T, typename Iterator2T>
709 static tree_match<IteratorT, NodeFactoryT, AttrT> create_match(
710 std::size_t length,
711 AttrT const& val,
712 Iterator1T const& first,
713 Iterator2T const& last)
714 {
715#if defined(BOOST_SPIRIT_DEBUG) && \
716 (BOOST_SPIRIT_DEBUG_FLAGS & BOOST_SPIRIT_DEBUG_FLAGS_NODES)
717
718 BOOST_SPIRIT_DEBUG_OUT << "\n>>> create_node(begin) <<<\n"
719 "creating node text: \"";
720 for (Iterator1T it = first; it != last; ++it)
721 impl::token_printer(BOOST_SPIRIT_DEBUG_OUT, *it);
722 BOOST_SPIRIT_DEBUG_OUT << "\"\n";
723 BOOST_SPIRIT_DEBUG_OUT << ">>> create_node(end) <<<\n\n";
724#endif
725 return tree_match<IteratorT, NodeFactoryT, AttrT>(length, val,
726 tree_policy_t::create_node(length, first, last, true));
727 }
728
729 template <typename Match1T, typename Match2T>
730 static void concat_match(Match1T& a, Match2T const& b)
731 {
732#if defined(BOOST_SPIRIT_DEBUG) && \
733 (BOOST_SPIRIT_DEBUG_FLAGS & BOOST_SPIRIT_DEBUG_FLAGS_NODES)
734
735 BOOST_SPIRIT_DEBUG_OUT << "\n>>> concat_match(begin) <<<\n";
736 BOOST_SPIRIT_DEBUG_OUT << "tree a:\n" << a << "\n";
737 BOOST_SPIRIT_DEBUG_OUT << "tree b:\n" << b << "\n";
738 BOOST_SPIRIT_DEBUG_OUT << ">>> concat_match(end) <<<\n\n";
739#endif
740 BOOST_SPIRIT_ASSERT(a && b);
741 if (a.length() == 0)
742 {
743 a = b;
744 return;
745 }
746 else if (b.length() == 0
747#ifdef BOOST_SPIRIT_NO_TREE_NODE_COLLAPSING
748 && !b.trees.begin()->value.id().to_long()
749#endif
750 )
751 {
752 return;
753 }
754 a.concat(b);
755 tree_policy_t::concat(a, b);
756 }
757
758 template <typename MatchT, typename IteratorT2>
759 void
760 group_match(
761 MatchT& m,
762 parser_id const& id,
763 IteratorT2 const& first,
764 IteratorT2 const& last) const
765 {
766 if (!m) return;
767
768#if defined(BOOST_SPIRIT_DEBUG) && \
769 (BOOST_SPIRIT_DEBUG_FLAGS & BOOST_SPIRIT_DEBUG_FLAGS_TREES)
770
771 BOOST_SPIRIT_DEBUG_OUT << "\n>>> group_match(begin) <<<\n"
772 "new node(" << id << ") \"";
773 for (IteratorT2 it = first; it != last; ++it)
774 impl::token_printer(BOOST_SPIRIT_DEBUG_OUT, *it);
775 BOOST_SPIRIT_DEBUG_OUT << "\"\n";
776 BOOST_SPIRIT_DEBUG_OUT << "new child tree (before grouping):\n" << m << "\n";
777
778 tree_policy_t::group_match(m, id, first, last);
779
780 BOOST_SPIRIT_DEBUG_OUT << "new child tree (after grouping):\n" << m << "\n";
781 BOOST_SPIRIT_DEBUG_OUT << ">>> group_match(end) <<<\n\n";
782#else
783 tree_policy_t::group_match(m, id, first, last);
784#endif
785 }
786};
787
788//////////////////////////////////
789template <typename MatchPolicyT, typename NodeFactoryT>
790struct common_tree_tree_policy
791{
792 typedef typename MatchPolicyT::iterator_t iterator_t;
793 typedef typename MatchPolicyT::match_t match_t;
794 typedef typename NodeFactoryT::template factory<iterator_t> factory_t;
795 typedef typename factory_t::node_t node_t;
796
797 template <typename Iterator1T, typename Iterator2T>
798 static node_t
799 create_node(std::size_t /*length*/, Iterator1T const& first,
800 Iterator2T const& last, bool leaf_node)
801 {
802 return factory_t::create_node(first, last, leaf_node);
803 }
804
805 static node_t
806 empty_node()
807 {
808 return factory_t::empty_node();
809 }
810
811 template <typename FunctorT>
812 static void apply_op_to_match(FunctorT const& op, match_t& m)
813 {
814 op(m);
815 }
816};
817
818//////////////////////////////////
819// directives to modify how the parse tree is generated
820
821struct no_tree_gen_node_parser_gen;
822
823template <typename T>
824struct no_tree_gen_node_parser
825: public unary<T, parser<no_tree_gen_node_parser<T> > >
826{
827 typedef no_tree_gen_node_parser<T> self_t;
828 typedef no_tree_gen_node_parser_gen parser_generator_t;
829 typedef unary_parser_category parser_category_t;
830
831 no_tree_gen_node_parser(T const& a)
832 : unary<T, parser<no_tree_gen_node_parser<T> > >(a) {}
833
834 template <typename ScannerT>
835 typename parser_result<self_t, ScannerT>::type
836 parse(ScannerT const& scanner) const
837 {
838 typedef typename ScannerT::iteration_policy_t iteration_policy_t;
839 typedef match_policy match_policy_t;
840 typedef typename ScannerT::action_policy_t action_policy_t;
841 typedef scanner_policies<
842 iteration_policy_t,
843 match_policy_t,
844 action_policy_t
845 > policies_t;
846
847 return this->subject().parse(scanner.change_policies(policies_t(scanner)));
848 }
849};
850
851struct no_tree_gen_node_parser_gen
852{
853 template <typename T>
854 struct result {
855
856 typedef no_tree_gen_node_parser<T> type;
857 };
858
859 template <typename T>
860 static no_tree_gen_node_parser<T>
861 generate(parser<T> const& s)
862 {
863 return no_tree_gen_node_parser<T>(s.derived());
864 }
865
866 template <typename T>
867 no_tree_gen_node_parser<T>
868 operator[](parser<T> const& s) const
869 {
870 return no_tree_gen_node_parser<T>(s.derived());
871 }
872};
873
874const no_tree_gen_node_parser_gen no_node_d = no_tree_gen_node_parser_gen();
875
876//////////////////////////////////
877
878struct leaf_node_parser_gen;
879
880template<typename T>
881struct leaf_node_parser
882: public unary<T, parser<leaf_node_parser<T> > >
883{
884 typedef leaf_node_parser<T> self_t;
885 typedef leaf_node_parser_gen parser_generator_t;
886 typedef unary_parser_category parser_category_t;
887
888 leaf_node_parser(T const& a)
889 : unary<T, parser<leaf_node_parser<T> > >(a) {}
890
891 template <typename ScannerT>
892 typename parser_result<self_t, ScannerT>::type
893 parse(ScannerT const& scanner) const
894 {
895 typedef scanner_policies< typename ScannerT::iteration_policy_t,
896 match_policy, typename ScannerT::action_policy_t > policies_t;
897
898 typedef typename ScannerT::iterator_t iterator_t;
899 typedef typename parser_result<self_t, ScannerT>::type result_t;
900 typedef typename result_t::node_factory_t factory_t;
901
902 iterator_t from = scanner.first;
903 result_t hit = impl::contiguous_parser_parse<result_t>(this->subject(),
904 scanner.change_policies(policies_t(scanner,match_policy(),scanner)),
905 scanner);
906
907 if (hit)
908 return result_t(hit.length(),
909 factory_t::create_node(from, scanner.first, true));
910 else
911 return result_t(hit.length());
912 }
913};
914
915struct leaf_node_parser_gen
916{
917 template <typename T>
918 struct result {
919
920 typedef leaf_node_parser<T> type;
921 };
922
923 template <typename T>
924 static leaf_node_parser<T>
925 generate(parser<T> const& s)
926 {
927 return leaf_node_parser<T>(s.derived());
928 }
929
930 template <typename T>
931 leaf_node_parser<T>
932 operator[](parser<T> const& s) const
933 {
934 return leaf_node_parser<T>(s.derived());
935 }
936};
937
938const leaf_node_parser_gen leaf_node_d = leaf_node_parser_gen();
939const leaf_node_parser_gen token_node_d = leaf_node_parser_gen();
940
941//////////////////////////////////
942namespace impl {
943
944 template <typename MatchPolicyT>
945 struct tree_policy_selector
946 {
947 typedef tree_policy type;
948 };
949
950} // namespace impl
951
952//////////////////////////////////
953template <typename NodeParserT>
954struct node_parser_gen;
955
956template <typename T, typename NodeParserT>
957struct node_parser
958: public unary<T, parser<node_parser<T, NodeParserT> > >
959{
960 typedef node_parser<T, NodeParserT> self_t;
961 typedef node_parser_gen<NodeParserT> parser_generator_t;
962 typedef unary_parser_category parser_category_t;
963
964 node_parser(T const& a)
965 : unary<T, parser<node_parser<T, NodeParserT> > >(a) {}
966
967 template <typename ScannerT>
968 struct result
969 {
970 typedef typename parser_result<T, ScannerT>::type type;
971 };
972
973 template <typename ScannerT>
974 typename parser_result<self_t, ScannerT>::type
975 parse(ScannerT const& scanner) const
976 {
977 typename parser_result<self_t, ScannerT>::type hit = this->subject().parse(scanner);
978 if (hit)
979 {
980 impl::tree_policy_selector<typename ScannerT::match_policy_t>::type::apply_op_to_match(NodeParserT(), hit);
981 }
982 return hit;
983 }
984};
985
986template <typename NodeParserT>
987struct node_parser_gen
988{
989 template <typename T>
990 struct result {
991
992 typedef node_parser<T, NodeParserT> type;
993 };
994
995 template <typename T>
996 static node_parser<T, NodeParserT>
997 generate(parser<T> const& s)
998 {
999 return node_parser<T, NodeParserT>(s.derived());
1000 }
1001
1002 template <typename T>
1003 node_parser<T, NodeParserT>
1004 operator[](parser<T> const& s) const
1005 {
1006 return node_parser<T, NodeParserT>(s.derived());
1007 }
1008};
1009//////////////////////////////////
1010struct reduced_node_op
1011{
1012 template <typename MatchT>
1013 void operator()(MatchT& m) const
1014 {
1015 if (m.trees.size() == 1)
1016 {
1017 m.trees.begin()->children.clear();
1018 }
1019 else if (m.trees.size() > 1)
1020 {
1021 typedef typename MatchT::node_factory_t node_factory_t;
1022 m = MatchT(m.length(), node_factory_t::group_nodes(m.trees));
1023 }
1024 }
1025};
1026
1027const node_parser_gen<reduced_node_op> reduced_node_d =
1028 node_parser_gen<reduced_node_op>();
1029
1030
1031struct discard_node_op
1032{
1033 template <typename MatchT>
1034 void operator()(MatchT& m) const
1035 {
1036 m.trees.clear();
1037 }
1038};
1039
1040const node_parser_gen<discard_node_op> discard_node_d =
1041 node_parser_gen<discard_node_op>();
1042
1043struct infix_node_op
1044{
1045 template <typename MatchT>
1046 void operator()(MatchT& m) const
1047 {
1048 typedef typename MatchT::container_t container_t;
1049 typedef typename MatchT::container_t::iterator iter_t;
1050 typedef typename MatchT::container_t::value_type value_t;
1051
1052 using std::swap;
1053 using boost::swap;
1054 using BOOST_SPIRIT_CLASSIC_NS::swap;
1055
1056 // copying the tree nodes is expensive, since it may copy a whole
1057 // tree. swapping them is cheap, so swap the nodes we want into
1058 // a new container of children.
1059 container_t new_children;
1060 std::size_t length = 0;
1061 std::size_t tree_size = m.trees.size();
1062
1063 // the infix_node_d[] make no sense for nodes with no subnodes
1064 BOOST_SPIRIT_ASSERT(tree_size >= 1);
1065
1066 bool keep = true;
1067#if !defined(BOOST_SPIRIT_USE_LIST_FOR_TREES)
1068 new_children.reserve((tree_size+1)/2);
1069#endif
1070 iter_t i_end = m.trees.end();
1071 for (iter_t i = m.trees.begin(); i != i_end; ++i)
1072 {
1073 if (keep) {
1074 // adjust the length
1075 length += std::distance((*i).value.begin(), (*i).value.end());
1076
1077 // move the child node
1078 new_children.push_back(value_t());
1079 swap(new_children.back(), *i);
1080 keep = false;
1081 }
1082 else {
1083 // ignore this child node
1084 keep = true;
1085 }
1086 }
1087
1088 m = MatchT(length, new_children);
1089 }
1090};
1091
1092const node_parser_gen<infix_node_op> infix_node_d =
1093 node_parser_gen<infix_node_op>();
1094
1095struct discard_first_node_op
1096{
1097 template <typename MatchT>
1098 void operator()(MatchT& m) const
1099 {
1100 typedef typename MatchT::container_t container_t;
1101 typedef typename MatchT::container_t::iterator iter_t;
1102 typedef typename MatchT::container_t::value_type value_t;
1103
1104 using std::swap;
1105 using boost::swap;
1106 using BOOST_SPIRIT_CLASSIC_NS::swap;
1107
1108 // copying the tree nodes is expensive, since it may copy a whole
1109 // tree. swapping them is cheap, so swap the nodes we want into
1110 // a new container of children, instead of saying
1111 // m.trees.erase(m.trees.begin()) because, on a container_t that will
1112 // cause all the nodes afterwards to be copied into the previous
1113 // position.
1114 container_t new_children;
1115 std::size_t length = 0;
1116 std::size_t tree_size = m.trees.size();
1117
1118 // the discard_first_node_d[] make no sense for nodes with no subnodes
1119 BOOST_SPIRIT_ASSERT(tree_size >= 1);
1120
1121 if (tree_size > 1) {
1122#if !defined(BOOST_SPIRIT_USE_LIST_FOR_TREES)
1123 new_children.reserve(tree_size - 1);
1124#endif
1125 iter_t i = m.trees.begin(), i_end = m.trees.end();
1126 for (++i; i != i_end; ++i)
1127 {
1128 // adjust the length
1129 length += std::distance((*i).value.begin(), (*i).value.end());
1130
1131 // move the child node
1132 new_children.push_back(value_t());
1133 swap(new_children.back(), *i);
1134 }
1135 }
1136 else {
1137 // if there was a tree and now there isn't any, insert an empty node
1138 iter_t i = m.trees.begin();
1139
1140 // This isn't entirely correct, since the empty node will reference
1141 // the end of the discarded node, but I currently don't see any way to
1142 // get at the begin of the node following this subnode.
1143 // This should be safe anyway because the it shouldn't get dereferenced
1144 // under any circumstances.
1145 typedef typename value_t::parse_node_t::iterator_t iterator_type;
1146 iterator_type it = (*i).value.end();
1147
1148 new_children.push_back(
1149 value_t(typename value_t::parse_node_t(it, it)));
1150 }
1151
1152 m = MatchT(length, new_children);
1153 }
1154};
1155
1156const node_parser_gen<discard_first_node_op> discard_first_node_d =
1157 node_parser_gen<discard_first_node_op>();
1158
1159struct discard_last_node_op
1160{
1161 template <typename MatchT>
1162 void operator()(MatchT& m) const
1163 {
1164 typedef typename MatchT::container_t container_t;
1165 typedef typename MatchT::container_t::iterator iter_t;
1166 typedef typename MatchT::container_t::value_type value_t;
1167
1168 using std::swap;
1169 using boost::swap;
1170 using BOOST_SPIRIT_CLASSIC_NS::swap;
1171
1172 // copying the tree nodes is expensive, since it may copy a whole
1173 // tree. swapping them is cheap, so swap the nodes we want into
1174 // a new container of children, instead of saying
1175 // m.trees.erase(m.trees.begin()) because, on a container_t that will
1176 // cause all the nodes afterwards to be copied into the previous
1177 // position.
1178 container_t new_children;
1179 std::size_t length = 0;
1180 std::size_t tree_size = m.trees.size();
1181
1182 // the discard_last_node_d[] make no sense for nodes with no subnodes
1183 BOOST_SPIRIT_ASSERT(tree_size >= 1);
1184
1185 if (tree_size > 1) {
1186 m.trees.pop_back();
1187#if !defined(BOOST_SPIRIT_USE_LIST_FOR_TREES)
1188 new_children.reserve(tree_size - 1);
1189#endif
1190 iter_t i_end = m.trees.end();
1191 for (iter_t i = m.trees.begin(); i != i_end; ++i)
1192 {
1193 // adjust the length
1194 length += std::distance((*i).value.begin(), (*i).value.end());
1195
1196 // move the child node
1197 new_children.push_back(value_t());
1198 swap(new_children.back(), *i);
1199 }
1200 }
1201 else {
1202 // if there was a tree and now there isn't any, insert an empty node
1203 iter_t i = m.trees.begin();
1204
1205 typedef typename value_t::parse_node_t::iterator_t iterator_type;
1206 iterator_type it = (*i).value.begin();
1207
1208 new_children.push_back(
1209 value_t(typename value_t::parse_node_t(it, it)));
1210 }
1211
1212 m = MatchT(length, new_children);
1213 }
1214};
1215
1216const node_parser_gen<discard_last_node_op> discard_last_node_d =
1217 node_parser_gen<discard_last_node_op>();
1218
1219struct inner_node_op
1220{
1221 template <typename MatchT>
1222 void operator()(MatchT& m) const
1223 {
1224 typedef typename MatchT::container_t container_t;
1225 typedef typename MatchT::container_t::iterator iter_t;
1226 typedef typename MatchT::container_t::value_type value_t;
1227
1228 using std::swap;
1229 using boost::swap;
1230 using BOOST_SPIRIT_CLASSIC_NS::swap;
1231
1232 // copying the tree nodes is expensive, since it may copy a whole
1233 // tree. swapping them is cheap, so swap the nodes we want into
1234 // a new container of children, instead of saying
1235 // m.trees.erase(m.trees.begin()) because, on a container_t that will
1236 // cause all the nodes afterwards to be copied into the previous
1237 // position.
1238 container_t new_children;
1239 std::size_t length = 0;
1240 std::size_t tree_size = m.trees.size();
1241
1242 // the inner_node_d[] make no sense for nodes with less then 2 subnodes
1243 BOOST_SPIRIT_ASSERT(tree_size >= 2);
1244
1245 if (tree_size > 2) {
1246 m.trees.pop_back(); // erase the last element
1247#if !defined(BOOST_SPIRIT_USE_LIST_FOR_TREES)
1248 new_children.reserve(tree_size - 1);
1249#endif
1250 iter_t i = m.trees.begin(); // skip over the first element
1251 iter_t i_end = m.trees.end();
1252 for (++i; i != i_end; ++i)
1253 {
1254 // adjust the length
1255 length += std::distance((*i).value.begin(), (*i).value.end());
1256
1257 // move the child node
1258 new_children.push_back(value_t());
1259 swap(new_children.back(), *i);
1260 }
1261 }
1262 else {
1263 // if there was a tree and now there isn't any, insert an empty node
1264 iter_t i = m.trees.begin(); // skip over the first element
1265
1266 typedef typename value_t::parse_node_t::iterator_t iterator_type;
1267 iterator_type it = (*++i).value.begin();
1268
1269 new_children.push_back(
1270 value_t(typename value_t::parse_node_t(it, it)));
1271 }
1272
1273 m = MatchT(length, new_children);
1274 }
1275};
1276
1277const node_parser_gen<inner_node_op> inner_node_d =
1278 node_parser_gen<inner_node_op>();
1279
1280
1281//////////////////////////////////
1282// action_directive_parser and action_directive_parser_gen
1283// are meant to be used as a template to create directives that
1284// generate action classes. For example access_match and
1285// access_node. The ActionParserT template parameter must be
1286// a class that has an innter class called action that is templated
1287// on the parser type and the action type.
1288template <typename ActionParserT>
1289struct action_directive_parser_gen;
1290
1291template <typename T, typename ActionParserT>
1292struct action_directive_parser
1293: public unary<T, parser<action_directive_parser<T, ActionParserT> > >
1294{
1295 typedef action_directive_parser<T, ActionParserT> self_t;
1296 typedef action_directive_parser_gen<ActionParserT> parser_generator_t;
1297 typedef unary_parser_category parser_category_t;
1298
1299 action_directive_parser(T const& a)
1300 : unary<T, parser<action_directive_parser<T, ActionParserT> > >(a) {}
1301
1302 template <typename ScannerT>
1303 struct result
1304 {
1305 typedef typename parser_result<T, ScannerT>::type type;
1306 };
1307
1308 template <typename ScannerT>
1309 typename parser_result<self_t, ScannerT>::type
1310 parse(ScannerT const& scanner) const
1311 {
1312 return this->subject().parse(scanner);
1313 }
1314
1315 template <typename ActionT>
1316 typename ActionParserT::template action<action_directive_parser<T, ActionParserT>, ActionT>
1317 operator[](ActionT const& actor) const
1318 {
1319 typedef typename
1320 ActionParserT::template action<action_directive_parser, ActionT>
1321 action_t;
1322 return action_t(*this, actor);
1323 }
1324};
1325
1326//////////////////////////////////
1327template <typename ActionParserT>
1328struct action_directive_parser_gen
1329{
1330 template <typename T>
1331 struct result {
1332
1333 typedef action_directive_parser<T, ActionParserT> type;
1334 };
1335
1336 template <typename T>
1337 static action_directive_parser<T, ActionParserT>
1338 generate(parser<T> const& s)
1339 {
1340 return action_directive_parser<T, ActionParserT>(s.derived());
1341 }
1342
1343 template <typename T>
1344 action_directive_parser<T, ActionParserT>
1345 operator[](parser<T> const& s) const
1346 {
1347 return action_directive_parser<T, ActionParserT>(s.derived());
1348 }
1349};
1350
1351//////////////////////////////////
1352// Calls the attached action passing it the match from the parser
1353// and the first and last iterators.
1354// The inner template class is used to simulate template-template parameters
1355// (declared in common_fwd.hpp).
1356template <typename ParserT, typename ActionT>
1357struct access_match_action::action
1358: public unary<ParserT, parser<access_match_action::action<ParserT, ActionT> > >
1359{
1360 typedef action_parser_category parser_category;
1361 typedef action<ParserT, ActionT> self_t;
1362
1363 template <typename ScannerT>
1364 struct result
1365 {
1366 typedef typename parser_result<ParserT, ScannerT>::type type;
1367 };
1368
1369 action( ParserT const& subject,
1370 ActionT const& actor_);
1371
1372 template <typename ScannerT>
1373 typename parser_result<self_t, ScannerT>::type
1374 parse(ScannerT const& scanner) const;
1375
1376 ActionT const &predicate() const;
1377
1378 private:
1379 ActionT actor;
1380};
1381
1382//////////////////////////////////
1383template <typename ParserT, typename ActionT>
1384access_match_action::action<ParserT, ActionT>::action(
1385 ParserT const& subject,
1386 ActionT const& actor_)
1387: unary<ParserT, parser<access_match_action::action<ParserT, ActionT> > >(subject)
1388, actor(actor_)
1389{}
1390
1391//////////////////////////////////
1392template <typename ParserT, typename ActionT>
1393template <typename ScannerT>
1394typename parser_result<access_match_action::action<ParserT, ActionT>, ScannerT>::type
1395access_match_action::action<ParserT, ActionT>::
1396parse(ScannerT const& scan) const
1397{
1398 typedef typename ScannerT::iterator_t iterator_t;
1399 typedef typename parser_result<self_t, ScannerT>::type result_t;
1400 if (!scan.at_end())
1401 {
1402 iterator_t save = scan.first;
1403 result_t hit = this->subject().parse(scan);
1404 actor(hit, save, scan.first);
1405 return hit;
1406 }
1407 return scan.no_match();
1408}
1409
1410//////////////////////////////////
1411template <typename ParserT, typename ActionT>
1412ActionT const &access_match_action::action<ParserT, ActionT>::predicate() const
1413{
1414 return actor;
1415}
1416
1417//////////////////////////////////
1418const action_directive_parser_gen<access_match_action> access_match_d
1419 = action_directive_parser_gen<access_match_action>();
1420
1421
1422
1423//////////////////////////////////
1424// Calls the attached action passing it the node from the parser
1425// and the first and last iterators
1426// The inner template class is used to simulate template-template parameters
1427// (declared in common_fwd.hpp).
1428template <typename ParserT, typename ActionT>
1429struct access_node_action::action
1430: public unary<ParserT, parser<access_node_action::action<ParserT, ActionT> > >
1431{
1432 typedef action_parser_category parser_category;
1433 typedef action<ParserT, ActionT> self_t;
1434
1435 template <typename ScannerT>
1436 struct result
1437 {
1438 typedef typename parser_result<ParserT, ScannerT>::type type;
1439 };
1440
1441 action( ParserT const& subject,
1442 ActionT const& actor_);
1443
1444 template <typename ScannerT>
1445 typename parser_result<self_t, ScannerT>::type
1446 parse(ScannerT const& scanner) const;
1447
1448 ActionT const &predicate() const;
1449
1450 private:
1451 ActionT actor;
1452};
1453
1454//////////////////////////////////
1455template <typename ParserT, typename ActionT>
1456access_node_action::action<ParserT, ActionT>::action(
1457 ParserT const& subject,
1458 ActionT const& actor_)
1459: unary<ParserT, parser<access_node_action::action<ParserT, ActionT> > >(subject)
1460, actor(actor_)
1461{}
1462
1463//////////////////////////////////
1464template <typename ParserT, typename ActionT>
1465template <typename ScannerT>
1466typename parser_result<access_node_action::action<ParserT, ActionT>, ScannerT>::type
1467access_node_action::action<ParserT, ActionT>::
1468parse(ScannerT const& scan) const
1469{
1470 typedef typename ScannerT::iterator_t iterator_t;
1471 typedef typename parser_result<self_t, ScannerT>::type result_t;
1472 if (!scan.at_end())
1473 {
1474 iterator_t save = scan.first;
1475 result_t hit = this->subject().parse(scan);
1476 if (hit && hit.trees.size() > 0)
1477 actor(*hit.trees.begin(), save, scan.first);
1478 return hit;
1479 }
1480 return scan.no_match();
1481}
1482
1483//////////////////////////////////
1484template <typename ParserT, typename ActionT>
1485ActionT const &access_node_action::action<ParserT, ActionT>::predicate() const
1486{
1487 return actor;
1488}
1489
1490//////////////////////////////////
1491const action_directive_parser_gen<access_node_action> access_node_d
1492 = action_directive_parser_gen<access_node_action>();
1493
1494
1495
1496//////////////////////////////////
1497
1498///////////////////////////////////////////////////////////////////////////////
1499//
1500// tree_parse_info
1501//
1502// Results returned by the tree parse functions:
1503//
1504// stop: points to the final parse position (i.e parsing
1505// processed the input up to this point).
1506//
1507// match: true if parsing is successful. This may be full:
1508// the parser consumed all the input, or partial:
1509// the parser consumed only a portion of the input.
1510//
1511// full: true when we have a full match (i.e the parser
1512// consumed all the input.
1513//
1514// length: The number of characters consumed by the parser.
1515// This is valid only if we have a successful match
1516// (either partial or full). A negative value means
1517// that the match is unsucessful.
1518//
1519// trees: Contains the root node(s) of the tree.
1520//
1521///////////////////////////////////////////////////////////////////////////////
1522template <
1523 typename IteratorT,
1524 typename NodeFactoryT,
1525 typename T
1526>
1527struct tree_parse_info
1528{
1529 IteratorT stop;
1530 bool match;
1531 bool full;
1532 std::size_t length;
1533 typename tree_match<IteratorT, NodeFactoryT, T>::container_t trees;
1534
1535 tree_parse_info()
1536 : stop()
1537 , match(false)
1538 , full(false)
1539 , length(0)
1540 , trees()
1541 {}
1542
1543 template <typename IteratorT2>
1544 tree_parse_info(tree_parse_info<IteratorT2> const& pi)
1545 : stop(pi.stop)
1546 , match(pi.match)
1547 , full(pi.full)
1548 , length(pi.length)
1549 , trees()
1550 {
1551 using std::swap;
1552 using boost::swap;
1553 using BOOST_SPIRIT_CLASSIC_NS::swap;
1554
1555 // use auto_ptr like ownership for the trees data member
1556 swap(trees, pi.trees);
1557 }
1558
1559 tree_parse_info(
1560 IteratorT stop_,
1561 bool match_,
1562 bool full_,
1563 std::size_t length_,
1564 typename tree_match<IteratorT, NodeFactoryT, T>::container_t trees_)
1565 : stop(stop_)
1566 , match(match_)
1567 , full(full_)
1568 , length(length_)
1569 , trees()
1570 {
1571 using std::swap;
1572 using boost::swap;
1573 using BOOST_SPIRIT_CLASSIC_NS::swap;
1574
1575 // use auto_ptr like ownership for the trees data member
1576 swap(trees, trees_);
1577 }
1578};
1579
1580BOOST_SPIRIT_CLASSIC_NAMESPACE_END
1581
1582}} // namespace BOOST_SPIRIT_CLASSIC_NS
1583
1584#endif
1585