boost/xpressive/detail/dynamic/matchable.hpp
/////////////////////////////////////////////////////////////////////////////// // matchable.hpp // // Copyright 2004 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) #ifndef BOOST_XPRESSIVE_DETAIL_DYNAMIC_MATCHABLE_HPP_EAN_10_04_2005 #define BOOST_XPRESSIVE_DETAIL_DYNAMIC_MATCHABLE_HPP_EAN_10_04_2005 // MS compatible compilers support #pragma once #if defined(_MSC_VER) && (_MSC_VER >= 1020) # pragma once #endif #include <utility> #include <boost/assert.hpp> #include <boost/shared_ptr.hpp> #include <boost/mpl/assert.hpp> #include <boost/type_traits/is_same.hpp> #include <boost/xpressive/detail/core/state.hpp> #include <boost/xpressive/detail/core/quant_style.hpp> #include <boost/xpressive/regex_error.hpp> namespace boost { namespace xpressive { namespace detail { template<typename BidiIter> struct matchable; /////////////////////////////////////////////////////////////////////////////// // sequence // template<typename BidiIter> struct sequence : std::pair < shared_ptr<matchable<BidiIter> const> , shared_ptr<matchable<BidiIter> const> * > { typedef shared_ptr<matchable<BidiIter> const> matchable_ptr_t; typedef std::pair<matchable_ptr_t, matchable_ptr_t *> base_t; explicit sequence(matchable_ptr_t head = matchable_ptr_t(), matchable_ptr_t *tail_ptr = 0) : base_t(head, tail_ptr) { } bool is_empty() const { return !this->first; } sequence &operator +=(sequence that) { if(is_empty()) { *this = that; } else if(!that.is_empty()) { *this->second = that.first; this->second = that.second; } return *this; } }; ////////////////////////////////////////////////////////////////////////// // quant_spec // struct quant_spec { unsigned int min_; unsigned int max_; bool greedy_; }; /////////////////////////////////////////////////////////////////////////////// // matchable // template<typename BidiIter> struct matchable : xpression_base { typedef typename iterator_value<BidiIter>::type char_type; virtual ~matchable() {} virtual bool match(state_type<BidiIter> &state) const = 0; virtual std::size_t get_width(state_type<BidiIter> *state) const = 0; virtual void link(xpression_linker<char_type> &) const {} virtual void peek(xpression_peeker<char_type> &peeker) const { peeker.fail(); } virtual sequence<BidiIter> quantify ( quant_spec const & //spec , std::size_t & //hidden_mark_count , sequence<BidiIter> //seq , alternates_factory<BidiIter> const &//factory ) const { throw regex_error(regex_constants::error_badrepeat, "expression cannot be quantified"); } virtual bool is_quantifiable() const { BOOST_ASSERT(false); throw regex_error(regex_constants::error_internal, "internal error, sorry!"); } /////////////////////////////////////////////////////////////////////////////////////////////// // The following 4 functions (push_match, top_match, pop_match and skip_match) are // used to implement looping and branching across the matchers. Call push_match to record // a position. Then, another matcher further down the xpression chain has the // option to call either top_match, pop_match or skip_match. top_match and pop_match will // jump back to the place recorded by push_match, whereas skip_match will skip the jump and // pass execution down the xpression chain. top_match will leave the xpression on top of the // stack, whereas pop_match will remove it. Each function comes in 2 flavors: one for // statically bound xpressions and one for dynamically bound xpressions. // template<typename Top> bool push_match(state_type<BidiIter> &state) const { BOOST_MPL_ASSERT((is_same<Top, matchable<BidiIter> >)); return this->match(state); } static bool top_match(state_type<BidiIter> &state, xpression_base const *top) { return static_cast<matchable<BidiIter> const *>(top)->match(state); } static bool pop_match(state_type<BidiIter> &state, xpression_base const *top) { return static_cast<matchable<BidiIter> const *>(top)->match(state); } bool skip_match(state_type<BidiIter> &state) const { return this->match(state); } }; }}} // namespace boost::xpressive::detail #endif