|
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