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