Boost logo

Boost-Commit :

From: eric_at_[hidden]
Date: 2007-10-11 16:51:00


Author: eric_niebler
Date: 2007-10-11 16:50:59 EDT (Thu, 11 Oct 2007)
New Revision: 39941
URL: http://svn.boost.org/trac/boost/changeset/39941

Log:
add let() so regexes with late-bound action args can be used with regex_(token_)iterator
Text files modified:
   trunk/boost/xpressive/detail/detail_fwd.hpp | 6 ++++
   trunk/boost/xpressive/proto/matches.hpp | 7 -----
   trunk/boost/xpressive/proto/transform/fold.hpp | 8 +++---
   trunk/boost/xpressive/regex_actions.hpp | 52 ++++++++++++++++++++++++++++++++++++++++
   trunk/boost/xpressive/regex_iterator.hpp | 31 +++++++++++++++++++----
   trunk/boost/xpressive/regex_token_iterator.hpp | 50 ++++++++++++++++++++++++++++++++++++++
   6 files changed, 137 insertions(+), 17 deletions(-)

Modified: trunk/boost/xpressive/detail/detail_fwd.hpp
==============================================================================
--- trunk/boost/xpressive/detail/detail_fwd.hpp (original)
+++ trunk/boost/xpressive/detail/detail_fwd.hpp 2007-10-11 16:50:59 EDT (Thu, 11 Oct 2007)
@@ -235,6 +235,12 @@
     template<typename Locale, typename BidiIter>
     struct regex_traits_type;
 
+ template<typename Expr>
+ struct let_;
+
+ template<typename Args, typename BidiIter>
+ void bind_args(let_<Args> const &, match_results<BidiIter> &);
+
     ///////////////////////////////////////////////////////////////////////////////
     // Misc.
     struct no_next;

Modified: trunk/boost/xpressive/proto/matches.hpp
==============================================================================
--- trunk/boost/xpressive/proto/matches.hpp (original)
+++ trunk/boost/xpressive/proto/matches.hpp 2007-10-11 16:50:59 EDT (Thu, 11 Oct 2007)
@@ -100,13 +100,6 @@
               : lambda_matches<Expr0, Grammar0>
             {};
 
- #if BOOST_WORKAROUND(__GNUC__, BOOST_TESTED_AT(4))
- template<template<typename> class T, typename Expr0>
- struct lambda_matches<T<Expr0>, T<proto::_> BOOST_MPL_AUX_LAMBDA_ARITY_PARAM(1) >
- : mpl::true_
- {};
- #endif
-
             // vararg_matches_impl
             template<typename Args1, typename Back, long From, long To>
             struct vararg_matches_impl;

Modified: trunk/boost/xpressive/proto/transform/fold.hpp
==============================================================================
--- trunk/boost/xpressive/proto/transform/fold.hpp (original)
+++ trunk/boost/xpressive/proto/transform/fold.hpp 2007-10-11 16:50:59 EDT (Thu, 11 Oct 2007)
@@ -82,14 +82,14 @@
 
             template<typename Expr, typename State, typename Visitor>
             struct apply
- : detail::fold_impl<Grammar, Expr, State, Visitor>
+ : detail::fold_impl<Grammar, typename Expr::proto_base_expr, State, Visitor>
             {};
 
             template<typename Expr, typename State, typename Visitor>
             static typename apply<Expr, State, Visitor>::type
             call(Expr const &expr, State const &state, Visitor &visitor)
             {
- return apply<Expr, State, Visitor>::call(expr, state, visitor);
+ return apply<Expr, State, Visitor>::call(expr.proto_base(), state, visitor);
             }
         };
 
@@ -103,14 +103,14 @@
 
             template<typename Expr, typename State, typename Visitor>
             struct apply
- : detail::reverse_fold_impl<Grammar, Expr, State, Visitor>
+ : detail::reverse_fold_impl<Grammar, typename Expr::proto_base_expr, State, Visitor>
             {};
 
             template<typename Expr, typename State, typename Visitor>
             static typename apply<Expr, State, Visitor>::type
             call(Expr const &expr, State const &state, Visitor &visitor)
             {
- return apply<Expr, State, Visitor>::call(expr, state, visitor);
+ return apply<Expr, State, Visitor>::call(expr.proto_base(), state, visitor);
             }
         };
 

Modified: trunk/boost/xpressive/regex_actions.hpp
==============================================================================
--- trunk/boost/xpressive/regex_actions.hpp (original)
+++ trunk/boost/xpressive/regex_actions.hpp 2007-10-11 16:50:59 EDT (Thu, 11 Oct 2007)
@@ -36,6 +36,7 @@
 
 // Doxygen can't handle proto :-(
 #ifndef BOOST_XPRESSIVE_DOXYGEN_INVOKED
+# include <boost/xpressive/proto/transform/fold.hpp>
 # include <boost/xpressive/detail/core/matcher/action_matcher.hpp>
 #endif
 
@@ -80,6 +81,53 @@
 
         struct check_tag
         {};
+
+ template<typename Grammar>
+ struct BindArg
+ : Grammar
+ {
+ template<typename Expr, typename State, typename Visitor>
+ struct apply
+ {
+ typedef State type;
+ };
+
+ template<typename Expr, typename State, typename Visitor>
+ static State call(Expr const &expr, State const &state, Visitor &visitor)
+ {
+ visitor.let(expr);
+ return state;
+ }
+ };
+
+ struct let_tag
+ {};
+
+ struct BindArgs
+ : boost::proto::transform::fold<
+ boost::proto::function<
+ boost::proto::transform::state<boost::proto::terminal<let_tag> >
+ , boost::proto::vararg< BindArg< boost::proto::assign<boost::proto::_, boost::proto::_> > >
+ >
+ >
+ {};
+
+ struct let_domain
+ : boost::proto::domain<boost::proto::pod_generator<let_> >
+ {};
+
+ template<typename Expr>
+ struct let_
+ {
+ BOOST_PROTO_EXTENDS(Expr, let_<Expr>, let_domain)
+ BOOST_PROTO_EXTENDS_FUNCTION(Expr, let_<Expr>, let_domain)
+ };
+
+ template<typename Args, typename BidiIter>
+ void bind_args(let_<Args> const &args, match_results<BidiIter> &what)
+ {
+ BindArgs::call(args, 0, what);
+ }
     }
 
     namespace op
@@ -694,6 +742,10 @@
     ///
     proto::terminal<detail::check_tag>::type const check = {{}};
 
+ /// let(), for binding references to non-local variables
+ ///
+ detail::let_<proto::terminal<detail::let_tag>::type> const let = {{{}}};
+
     template<typename T, int I = 0, typename Dummy = proto::is_proto_expr>
     struct placeholder
     {

Modified: trunk/boost/xpressive/regex_iterator.hpp
==============================================================================
--- trunk/boost/xpressive/regex_iterator.hpp (original)
+++ trunk/boost/xpressive/regex_iterator.hpp 2007-10-11 16:50:59 EDT (Thu, 11 Oct 2007)
@@ -121,6 +121,21 @@
         this->next_();
     }
 
+ template<typename LetExpr>
+ regex_iterator
+ (
+ BidiIter begin
+ , BidiIter end
+ , basic_regex<BidiIter> const &rex
+ , detail::let_<LetExpr> const &args
+ , regex_constants::match_flag_type flags = regex_constants::match_default
+ )
+ : impl_(new impl_type_(begin, begin, end, &rex, flags))
+ {
+ detail::bind_args(args, this->impl_->what_);
+ this->next_();
+ }
+
     regex_iterator(regex_iterator<BidiIter> const &that)
       : impl_(that.impl_) // COW
     {
@@ -200,15 +215,19 @@
     {
         if(1 != this->impl_->use_count())
         {
+ // This is OK, the use_count is > 1
+ impl_type_ *that = this->impl_.get();
             this->impl_ = new impl_type_
             (
- this->impl_->state_.begin_
- , this->impl_->state_.cur_
- , this->impl_->state_.end_
- , this->impl_->rex_
- , this->impl_->flags_
- , this->impl_->not_null_
+ that->state_.begin_
+ , that->state_.cur_
+ , that->state_.end_
+ , that->rex_
+ , that->flags_
+ , that->not_null_
             );
+ detail::core_access<BidiIter>::get_action_args(this->impl_->what_)
+ = detail::core_access<BidiIter>::get_action_args(that->what_);
         }
     }
 

Modified: trunk/boost/xpressive/regex_token_iterator.hpp
==============================================================================
--- trunk/boost/xpressive/regex_token_iterator.hpp (original)
+++ trunk/boost/xpressive/regex_token_iterator.hpp 2007-10-11 16:50:59 EDT (Thu, 11 Oct 2007)
@@ -166,6 +166,26 @@
     /// \param begin The beginning of the character range to search.
     /// \param end The end of the character range to search.
     /// \param rex The regex pattern to search for.
+ /// \param args A let() expression with argument bindings for semantic actions.
+ /// \pre \c [begin,end) is a valid range.
+ template<typename LetExpr>
+ regex_token_iterator
+ (
+ BidiIter begin
+ , BidiIter end
+ , basic_regex<BidiIter> const &rex
+ , detail::let_<LetExpr> const &args
+ )
+ : impl_(new impl_type_(begin, begin, end, &rex))
+ {
+ detail::bind_args(args, this->impl_->iter_.what_);
+ this->next_();
+ }
+
+ /// \param begin The beginning of the character range to search.
+ /// \param end The end of the character range to search.
+ /// \param rex The regex pattern to search for.
+ /// \param flags Optional match flags, used to control how the expression is matched against the sequence. (See match_flag_type.)
     /// \pre \c [begin,end) is a valid range.
     /// \pre \c subs is either an integer greater or equal to -1,
     /// or else an array or non-empty \c std::vector\<\> of such integers.
@@ -183,6 +203,30 @@
         this->next_();
     }
 
+ /// \param begin The beginning of the character range to search.
+ /// \param end The end of the character range to search.
+ /// \param rex The regex pattern to search for.
+ /// \param args A let() expression with argument bindings for semantic actions.
+ /// \param flags Optional match flags, used to control how the expression is matched against the sequence. (See match_flag_type.)
+ /// \pre \c [begin,end) is a valid range.
+ /// \pre \c subs is either an integer greater or equal to -1,
+ /// or else an array or non-empty \c std::vector\<\> of such integers.
+ template<typename Subs, typename LetExpr>
+ regex_token_iterator
+ (
+ BidiIter begin
+ , BidiIter end
+ , basic_regex<BidiIter> const &rex
+ , Subs const &subs
+ , detail::let_<LetExpr> const &args
+ , regex_constants::match_flag_type flags = regex_constants::match_default
+ )
+ : impl_(new impl_type_(begin, begin, end, &rex, flags, detail::to_vector(subs)))
+ {
+ detail::bind_args(args, this->impl_->iter_.what_);
+ this->next_();
+ }
+
     /// \post <tt>*this == that</tt>
     regex_token_iterator(regex_token_iterator<BidiIter> const &that)
       : impl_(that.impl_) // COW
@@ -279,6 +323,12 @@
                 // Find a better way
                 clone->iter_.what_ = this->impl_->iter_.what_;
             }
+ else
+ {
+ // At the very least, copy the action args
+ detail::core_access<BidiIter>::get_action_args(clone->iter_.what_)
+ = detail::core_access<BidiIter>::get_action_args(this->impl_->iter_.what_);
+ }
 
             this->impl_.swap(clone);
         }


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk