|
Boost-Commit : |
Subject: [Boost-commit] svn:boost r63305 - in trunk: boost/xpressive/detail/core/matcher libs/xpressive/test
From: eric_at_[hidden]
Date: 2010-06-25 09:49:05
Author: eric_niebler
Date: 2010-06-25 09:49:03 EDT (Fri, 25 Jun 2010)
New Revision: 63305
URL: http://svn.boost.org/trac/boost/changeset/63305
Log:
support user-defined assertions with placeholders for non-local variables
Added:
trunk/libs/xpressive/test/test_assert_with_placeholder.cpp (contents, props changed)
Text files modified:
trunk/boost/xpressive/detail/core/matcher/predicate_matcher.hpp | 32 ++++++++++++++++++++++++++++++--
trunk/libs/xpressive/test/Jamfile.v2 | 1 +
2 files changed, 31 insertions(+), 2 deletions(-)
Modified: trunk/boost/xpressive/detail/core/matcher/predicate_matcher.hpp
==============================================================================
--- trunk/boost/xpressive/detail/core/matcher/predicate_matcher.hpp (original)
+++ trunk/boost/xpressive/detail/core/matcher/predicate_matcher.hpp 2010-06-25 09:49:03 EDT (Fri, 25 Jun 2010)
@@ -29,11 +29,17 @@
template<typename BidiIter>
struct predicate_context
{
- explicit predicate_context(int sub, sub_match_impl<BidiIter> const *sub_matches)
+ explicit predicate_context(int sub, sub_match_impl<BidiIter> const *sub_matches, action_args_type *action_args)
: sub_(sub)
, sub_matches_(sub_matches)
+ , action_args_(action_args)
{}
+ action_args_type const &args() const
+ {
+ return *this->action_args_;
+ }
+
// eval_terminal
template<typename Expr, typename Arg>
struct eval_terminal
@@ -70,6 +76,26 @@
}
};
+ template<typename Expr, typename Type, typename Int>
+ struct eval_terminal<Expr, action_arg<Type, Int> >
+ {
+ typedef typename action_arg<Type, Int>::reference result_type;
+ result_type operator()(Expr &expr, predicate_context const &ctx) const
+ {
+ action_args_type::const_iterator where_ = ctx.args().find(&typeid(proto::value(expr)));
+ if(where_ == ctx.args().end())
+ {
+ BOOST_THROW_EXCEPTION(
+ regex_error(
+ regex_constants::error_badarg
+ , "An argument to an action was unspecified"
+ )
+ );
+ }
+ return proto::value(expr).cast(where_->second);
+ }
+ };
+
// eval
template<typename Expr, typename Tag = typename Expr::proto_tag>
struct eval
@@ -88,8 +114,10 @@
{};
#endif
+ private:
int sub_;
sub_match_impl<BidiIter> const *sub_matches_;
+ action_args_type *action_args_;
};
///////////////////////////////////////////////////////////////////////////////
@@ -137,7 +165,7 @@
template<typename BidiIter, typename Next>
bool match_(match_state<BidiIter> &state, Next const &next, mpl::false_) const
{
- predicate_context<BidiIter> ctx(this->sub_, state.sub_matches_);
+ predicate_context<BidiIter> ctx(this->sub_, state.sub_matches_, state.action_args_);
return proto::eval(proto::child_c<1>(this->predicate_), ctx) && next.match(state);
}
};
Modified: trunk/libs/xpressive/test/Jamfile.v2
==============================================================================
--- trunk/libs/xpressive/test/Jamfile.v2 (original)
+++ trunk/libs/xpressive/test/Jamfile.v2 2010-06-25 09:49:03 EDT (Fri, 25 Jun 2010)
@@ -56,6 +56,7 @@
[ run test_static.cpp ]
[ run test_actions.cpp ]
[ run test_assert.cpp ]
+ [ run test_assert_with_placeholder.cpp ]
[ run test_symbols.cpp ]
[ run test_dynamic.cpp ]
[ run test_dynamic_grammar.cpp ]
Added: trunk/libs/xpressive/test/test_assert_with_placeholder.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/xpressive/test/test_assert_with_placeholder.cpp 2010-06-25 09:49:03 EDT (Fri, 25 Jun 2010)
@@ -0,0 +1,76 @@
+///////////////////////////////////////////////////////////////////////////////
+// test_assert_with_placeholder.hpp
+//
+// Copyright 2008 Eric Niebler. Distributed under the Boost
+// Software License, Version 1.0. (See accompanying file
+// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/xpressive/xpressive.hpp>
+#include <boost/xpressive/regex_actions.hpp>
+#include <boost/test/unit_test.hpp>
+
+using namespace boost::xpressive;
+
+placeholder<int> const _cnt = {{}};
+
+struct count_a_impl
+{
+ typedef void result_type;
+
+ void operator()(int &cnt) const
+ {
+ ++cnt;
+ }
+};
+
+boost::xpressive::function<count_a_impl>::type const count_a = {{}};
+
+struct check_a_impl
+{
+ typedef bool result_type;
+
+ bool operator()(int &cnt, int val) const
+ {
+ if(cnt < val)
+ {
+ ++cnt;
+ return true;
+ }
+ return false;
+ }
+};
+
+boost::xpressive::function<check_a_impl>::type const check_a = {{}};
+
+void test_assert_with_placeholder()
+{
+ int cnt = 0;
+ std::string a_str("a_aaaaa___a_aa_aaa_");
+ const sregex expr1(*(as_xpr('a')[count_a(_cnt)] | '_'));
+ const sregex expr2(*(as_xpr('a')[check(check_a(_cnt, 5))] | '_'));
+
+ sregex_iterator iter1(a_str.begin(), a_str.end(), expr1,
+ let(_cnt = cnt));
+ BOOST_CHECK_EQUAL(iter1->str(0), a_str);
+ BOOST_CHECK_EQUAL(cnt, 12);
+
+ cnt = 0;
+ sregex_iterator iter2(a_str.begin(), a_str.end(), expr2,
+ let(_cnt = cnt));
+
+ BOOST_CHECK_EQUAL(iter2->str(0), std::string("a_aaaa"));
+ BOOST_CHECK_EQUAL(cnt, 5);
+}
+
+using namespace boost::unit_test;
+///////////////////////////////////////////////////////////////////////////////
+// init_unit_test_suite
+//
+test_suite* init_unit_test_suite( int argc, char* argv[] )
+{
+ test_suite *test = BOOST_TEST_SUITE("test that custom assertions can use argument placeholders");
+
+ test->add(BOOST_TEST_CASE(&test_assert_with_placeholder));
+
+ return test;
+}
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