Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: // matchable.hpp Chris@16: // Chris@16: // Copyright 2008 Eric Niebler. Distributed under the Boost Chris@16: // Software License, Version 1.0. (See accompanying file Chris@16: // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) Chris@16: Chris@16: #ifndef BOOST_XPRESSIVE_DETAIL_DYNAMIC_MATCHABLE_HPP_EAN_10_04_2005 Chris@16: #define BOOST_XPRESSIVE_DETAIL_DYNAMIC_MATCHABLE_HPP_EAN_10_04_2005 Chris@16: Chris@16: // MS compatible compilers support #pragma once Chris@101: #if defined(_MSC_VER) Chris@16: # pragma once Chris@16: #endif Chris@16: Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: Chris@16: namespace boost { namespace xpressive { namespace detail Chris@16: { Chris@16: Chris@16: ////////////////////////////////////////////////////////////////////////// Chris@16: // quant_spec Chris@16: struct quant_spec Chris@16: { Chris@16: unsigned int min_; Chris@16: unsigned int max_; Chris@16: bool greedy_; Chris@16: std::size_t *hidden_mark_count_; Chris@16: }; Chris@16: Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: // matchable Chris@16: template Chris@16: struct matchable Chris@16: { Chris@16: typedef BidiIter iterator_type; Chris@16: typedef typename iterator_value::type char_type; Chris@16: virtual ~matchable() {} Chris@16: virtual bool match(match_state &state) const = 0; Chris@16: }; Chris@16: Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: // matchable_ex Chris@16: template Chris@16: struct matchable_ex Chris@16: : matchable Chris@16: , counted_base > Chris@16: { Chris@16: typedef BidiIter iterator_type; Chris@16: typedef typename iterator_value::type char_type; Chris@16: Chris@16: virtual void link(xpression_linker &) const Chris@16: { Chris@16: } Chris@16: Chris@16: virtual void peek(xpression_peeker &peeker) const Chris@16: { Chris@16: peeker.fail(); Chris@16: } Chris@16: Chris@16: virtual void repeat(quant_spec const &, sequence &) const Chris@16: { Chris@16: BOOST_THROW_EXCEPTION( Chris@16: regex_error(regex_constants::error_badrepeat, "expression cannot be quantified") Chris@16: ); Chris@16: } Chris@16: Chris@16: /////////////////////////////////////////////////////////////////////////////////////////////// Chris@16: // The following 4 functions (push_match, top_match, pop_match and skip_match) are Chris@16: // used to implement looping and branching across the matchers. Call push_match to record Chris@16: // a position. Then, another matcher further down the xpression chain has the Chris@16: // option to call either top_match, pop_match or skip_match. top_match and pop_match will Chris@16: // jump back to the place recorded by push_match, whereas skip_match will skip the jump and Chris@16: // pass execution down the xpression chain. top_match will leave the xpression on top of the Chris@16: // stack, whereas pop_match will remove it. Each function comes in 2 flavors: one for Chris@16: // statically bound xpressions and one for dynamically bound xpressions. Chris@16: // Chris@16: Chris@16: template Chris@16: bool push_match(match_state &state) const Chris@16: { Chris@16: BOOST_MPL_ASSERT((is_same >)); Chris@16: return this->match(state); Chris@16: } Chris@16: Chris@16: static bool top_match(match_state &state, void const *top) Chris@16: { Chris@16: return static_cast const *>(top)->match(state); Chris@16: } Chris@16: Chris@16: static bool pop_match(match_state &state, void const *top) Chris@16: { Chris@16: return static_cast const *>(top)->match(state); Chris@16: } Chris@16: Chris@16: bool skip_match(match_state &state) const Chris@16: { Chris@16: return this->match(state); Chris@16: } Chris@16: }; Chris@16: Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: // shared_matchable Chris@16: template Chris@16: struct shared_matchable Chris@16: { Chris@16: typedef BidiIter iterator_type; Chris@16: typedef typename iterator_value::type char_type; Chris@16: typedef intrusive_ptr const> matchable_ptr; Chris@16: Chris@16: BOOST_STATIC_CONSTANT(std::size_t, width = unknown_width::value); Chris@16: BOOST_STATIC_CONSTANT(bool, pure = false); Chris@16: Chris@16: shared_matchable(matchable_ptr const &xpr = matchable_ptr()) Chris@16: : xpr_(xpr) Chris@16: { Chris@16: } Chris@16: Chris@16: bool operator !() const Chris@16: { Chris@16: return !this->xpr_; Chris@16: } Chris@16: Chris@16: friend bool operator ==(shared_matchable const &left, shared_matchable const &right) Chris@16: { Chris@16: return left.xpr_ == right.xpr_; Chris@16: } Chris@16: Chris@16: friend bool operator !=(shared_matchable const &left, shared_matchable const &right) Chris@16: { Chris@16: return left.xpr_ != right.xpr_; Chris@16: } Chris@16: Chris@16: matchable_ptr const &matchable() const Chris@16: { Chris@16: return this->xpr_; Chris@16: } Chris@16: Chris@16: bool match(match_state &state) const Chris@16: { Chris@16: return this->xpr_->match(state); Chris@16: } Chris@16: Chris@16: void link(xpression_linker &linker) const Chris@16: { Chris@16: this->xpr_->link(linker); Chris@16: } Chris@16: Chris@16: void peek(xpression_peeker &peeker) const Chris@16: { Chris@16: this->xpr_->peek(peeker); Chris@16: } Chris@16: Chris@16: // BUGBUG yuk! Chris@16: template Chris@16: bool push_match(match_state &state) const Chris@16: { Chris@16: BOOST_MPL_ASSERT((is_same >)); Chris@16: return this->match(state); Chris@16: } Chris@16: Chris@16: private: Chris@16: matchable_ptr xpr_; Chris@16: }; Chris@16: Chris@16: }}} // namespace boost::xpressive::detail Chris@16: Chris@16: #endif