Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:53:50

0001 ///////////////////////////////////////////////////////////////////////////////
0002 // matchable.hpp
0003 //
0004 //  Copyright 2008 Eric Niebler. Distributed under the Boost
0005 //  Software License, Version 1.0. (See accompanying file
0006 //  LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
0007 
0008 #ifndef BOOST_XPRESSIVE_DETAIL_DYNAMIC_MATCHABLE_HPP_EAN_10_04_2005
0009 #define BOOST_XPRESSIVE_DETAIL_DYNAMIC_MATCHABLE_HPP_EAN_10_04_2005
0010 
0011 // MS compatible compilers support #pragma once
0012 #if defined(_MSC_VER)
0013 # pragma once
0014 #endif
0015 
0016 #include <boost/assert.hpp>
0017 #include <boost/mpl/assert.hpp>
0018 #include <boost/intrusive_ptr.hpp>
0019 #include <boost/throw_exception.hpp>
0020 #include <boost/type_traits/is_same.hpp>
0021 #include <boost/xpressive/detail/core/quant_style.hpp>
0022 #include <boost/xpressive/detail/utility/counted_base.hpp>
0023 #include <boost/xpressive/detail/detail_fwd.hpp>
0024 #include <boost/xpressive/detail/dynamic/sequence.hpp>
0025 #include <boost/xpressive/regex_error.hpp>
0026 
0027 namespace boost { namespace xpressive { namespace detail
0028 {
0029 
0030 //////////////////////////////////////////////////////////////////////////
0031 // quant_spec
0032 struct quant_spec
0033 {
0034     unsigned int min_;
0035     unsigned int max_;
0036     bool greedy_;
0037     std::size_t *hidden_mark_count_;
0038 };
0039 
0040 ///////////////////////////////////////////////////////////////////////////////
0041 // matchable
0042 template<typename BidiIter>
0043 struct matchable
0044 {
0045     typedef BidiIter iterator_type;
0046     typedef typename iterator_value<iterator_type>::type char_type;
0047     virtual ~matchable() {}
0048     virtual bool match(match_state<BidiIter> &state) const = 0;
0049 };
0050 
0051 ///////////////////////////////////////////////////////////////////////////////
0052 // matchable_ex
0053 template<typename BidiIter>
0054 struct matchable_ex
0055   : matchable<BidiIter>
0056   , counted_base<matchable_ex<BidiIter> >
0057 {
0058     typedef BidiIter iterator_type;
0059     typedef typename iterator_value<iterator_type>::type char_type;
0060 
0061     virtual void link(xpression_linker<char_type> &) const
0062     {
0063     }
0064 
0065     virtual void peek(xpression_peeker<char_type> &peeker) const
0066     {
0067         peeker.fail();
0068     }
0069 
0070     virtual void repeat(quant_spec const &, sequence<BidiIter> &) const
0071     {
0072         BOOST_THROW_EXCEPTION(
0073             regex_error(regex_constants::error_badrepeat, "expression cannot be quantified")
0074         );
0075     }
0076 
0077     ///////////////////////////////////////////////////////////////////////////////////////////////
0078     // The following 4 functions (push_match, top_match, pop_match and skip_match) are
0079     // used to implement looping and branching across the matchers. Call push_match to record
0080     // a position. Then, another matcher further down the xpression chain has the
0081     // option to call either top_match, pop_match or skip_match. top_match and pop_match will
0082     // jump back to the place recorded by push_match, whereas skip_match will skip the jump and
0083     // pass execution down the xpression chain. top_match will leave the xpression on top of the
0084     // stack, whereas pop_match will remove it. Each function comes in 2 flavors: one for
0085     // statically bound xpressions and one for dynamically bound xpressions.
0086     //
0087 
0088     template<typename Top>
0089     bool push_match(match_state<BidiIter> &state) const
0090     {
0091         BOOST_MPL_ASSERT((is_same<Top, matchable_ex<BidiIter> >));
0092         return this->match(state);
0093     }
0094 
0095     static bool top_match(match_state<BidiIter> &state, void const *top)
0096     {
0097         return static_cast<matchable_ex<BidiIter> const *>(top)->match(state);
0098     }
0099 
0100     static bool pop_match(match_state<BidiIter> &state, void const *top)
0101     {
0102         return static_cast<matchable_ex<BidiIter> const *>(top)->match(state);
0103     }
0104 
0105     bool skip_match(match_state<BidiIter> &state) const
0106     {
0107         return this->match(state);
0108     }
0109 };
0110 
0111 ///////////////////////////////////////////////////////////////////////////////
0112 // shared_matchable
0113 template<typename BidiIter>
0114 struct shared_matchable
0115 {
0116     typedef BidiIter iterator_type;
0117     typedef typename iterator_value<BidiIter>::type char_type;
0118     typedef intrusive_ptr<matchable_ex<BidiIter> const> matchable_ptr;
0119 
0120     BOOST_STATIC_CONSTANT(std::size_t, width = unknown_width::value);
0121     BOOST_STATIC_CONSTANT(bool, pure = false);
0122 
0123     shared_matchable(matchable_ptr const &xpr = matchable_ptr())
0124       : xpr_(xpr)
0125     {
0126     }
0127 
0128     bool operator !() const
0129     {
0130         return !this->xpr_;
0131     }
0132 
0133     friend bool operator ==(shared_matchable<BidiIter> const &left, shared_matchable<BidiIter> const &right)
0134     {
0135         return left.xpr_ == right.xpr_;
0136     }
0137 
0138     friend bool operator !=(shared_matchable<BidiIter> const &left, shared_matchable<BidiIter> const &right)
0139     {
0140         return left.xpr_ != right.xpr_;
0141     }
0142 
0143     matchable_ptr const &matchable() const
0144     {
0145         return this->xpr_;
0146     }
0147 
0148     bool match(match_state<BidiIter> &state) const
0149     {
0150         return this->xpr_->match(state);
0151     }
0152 
0153     void link(xpression_linker<char_type> &linker) const
0154     {
0155         this->xpr_->link(linker);
0156     }
0157 
0158     void peek(xpression_peeker<char_type> &peeker) const
0159     {
0160         this->xpr_->peek(peeker);
0161     }
0162 
0163     // BUGBUG yuk!
0164     template<typename Top>
0165     bool push_match(match_state<BidiIter> &state) const
0166     {
0167         BOOST_MPL_ASSERT((is_same<Top, matchable_ex<BidiIter> >));
0168         return this->match(state);
0169     }
0170 
0171 private:
0172     matchable_ptr xpr_;
0173 };
0174 
0175 }}} // namespace boost::xpressive::detail
0176 
0177 #endif