| /////////////////////////////////////////////////////////////////////////////// |
| // alternate_matcher.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) |
| |
| #ifndef BOOST_XPRESSIVE_DETAIL_CORE_MATCHER_ALTERNATE_MATCHER_HPP_EAN_10_04_2005 |
| #define BOOST_XPRESSIVE_DETAIL_CORE_MATCHER_ALTERNATE_MATCHER_HPP_EAN_10_04_2005 |
| |
| // MS compatible compilers support #pragma once |
| #if defined(_MSC_VER) && (_MSC_VER >= 1020) |
| # pragma once |
| #endif |
| |
| #include <boost/version.hpp> |
| #if BOOST_VERSION <= 103200 |
| // WORKAROUND for Fusion bug in Boost 1.32 |
| namespace boost { namespace fusion |
| { |
| namespace detail { struct iterator_root; } |
| using detail::iterator_root; |
| }} |
| #endif |
| |
| #include <boost/xpressive/detail/detail_fwd.hpp> |
| #include <boost/xpressive/detail/core/quant_style.hpp> |
| #include <boost/xpressive/detail/core/state.hpp> |
| #include <boost/xpressive/detail/dynamic/matchable.hpp> |
| #include <boost/xpressive/detail/utility/hash_peek_bitset.hpp> |
| #include <boost/xpressive/detail/utility/algorithm.hpp> |
| #include <boost/xpressive/detail/utility/any.hpp> |
| |
| namespace boost { namespace xpressive { namespace detail |
| { |
| |
| /////////////////////////////////////////////////////////////////////////////// |
| // alt_match_pred |
| // |
| template<typename BidiIter, typename Next> |
| struct alt_match_pred |
| { |
| alt_match_pred(match_state<BidiIter> &state) |
| : state_(&state) |
| { |
| } |
| |
| template<typename Xpr> |
| bool operator ()(Xpr const &xpr) const |
| { |
| return xpr.BOOST_NESTED_TEMPLATE push_match<Next>(*this->state_); |
| } |
| |
| private: |
| match_state<BidiIter> *state_; |
| }; |
| |
| /////////////////////////////////////////////////////////////////////////////// |
| // alt_match |
| // |
| template<typename BidiIter, typename Next> |
| inline bool alt_match |
| ( |
| alternates_vector<BidiIter> const &alts, match_state<BidiIter> &state, Next const & |
| ) |
| { |
| return detail::any(alts.begin(), alts.end(), alt_match_pred<BidiIter, Next>(state)); |
| } |
| |
| template<typename Head, typename Tail, typename BidiIter, typename Next> |
| inline bool alt_match |
| ( |
| alternates_list<Head, Tail> const &alts, match_state<BidiIter> &state, Next const & |
| ) |
| { |
| return fusion::any(alts, alt_match_pred<BidiIter, Next>(state)); |
| } |
| |
| /////////////////////////////////////////////////////////////////////////////// |
| // alternate_matcher |
| template<typename Alternates, typename Traits> |
| struct alternate_matcher |
| : quant_style< |
| Alternates::width != unknown_width::value && Alternates::pure ? quant_fixed_width : quant_variable_width |
| , Alternates::width |
| , Alternates::pure |
| > |
| { |
| typedef Alternates alternates_type; |
| typedef typename Traits::char_type char_type; |
| |
| Alternates alternates_; |
| mutable hash_peek_bitset<char_type> bset_; |
| |
| explicit alternate_matcher(Alternates const &alternates = Alternates()) |
| : alternates_(alternates) |
| , bset_() |
| { |
| } |
| |
| template<typename BidiIter, typename Next> |
| bool match(match_state<BidiIter> &state, Next const &next) const |
| { |
| if(!state.eos() && !this->can_match_(*state.cur_, traits_cast<Traits>(state))) |
| { |
| return false; |
| } |
| |
| return detail::alt_match(this->alternates_, state, next); |
| } |
| |
| detail::width get_width() const |
| { |
| // Only called when constructing static regexes, and this is a |
| // set of same-width alternates where the widths are known at compile |
| // time, as in: sregex rx = +(_ | 'a' | _n); |
| BOOST_MPL_ASSERT_RELATION(unknown_width::value, !=, Alternates::width); |
| return Alternates::width; |
| } |
| |
| private: |
| alternate_matcher &operator =(alternate_matcher const &); |
| |
| bool can_match_(char_type ch, Traits const &tr) const |
| { |
| return this->bset_.test(ch, tr); |
| } |
| }; |
| |
| }}} |
| |
| #endif |