Back to home page

EIC code displayed by LXR

 
 

    


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

0001 ///////////////////////////////////////////////////////////////////////////////
0002 // peeker.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_CORE_PEEKER_HPP_EAN_10_04_2005
0009 #define BOOST_XPRESSIVE_DETAIL_CORE_PEEKER_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 <string>
0017 #include <typeinfo>
0018 #include <boost/assert.hpp>
0019 #include <boost/mpl/bool.hpp>
0020 #include <boost/mpl/assert.hpp>
0021 #include <boost/mpl/size_t.hpp>
0022 #include <boost/mpl/equal_to.hpp>
0023 #include <boost/utility/enable_if.hpp>
0024 #include <boost/xpressive/detail/detail_fwd.hpp>
0025 #include <boost/xpressive/detail/core/matchers.hpp>
0026 #include <boost/xpressive/detail/utility/hash_peek_bitset.hpp>
0027 #include <boost/xpressive/detail/utility/never_true.hpp>
0028 #include <boost/xpressive/detail/utility/algorithm.hpp>
0029 
0030 namespace boost { namespace xpressive { namespace detail
0031 {
0032 
0033 ///////////////////////////////////////////////////////////////////////////////
0034 // peeker_string
0035 //
0036 template<typename Char>
0037 struct peeker_string
0038 {
0039     Char const *begin_;
0040     Char const *end_;
0041     bool icase_;
0042 };
0043 
0044 ///////////////////////////////////////////////////////////////////////////////
0045 // char_sink
0046 //
0047 template<typename Traits, bool ICase>
0048 struct char_sink
0049 {
0050     typedef typename Traits::char_type char_type;
0051 
0052     char_sink(hash_peek_bitset<char_type> &bset, Traits const &tr)
0053       : bset_(bset)
0054       , traits_(tr)
0055     {}
0056 
0057     void operator()(char_type ch) const
0058     {
0059         this->bset_.set_char(ch, ICase, this->traits_);
0060     }
0061 
0062     hash_peek_bitset<char_type> &bset_;
0063     Traits const &traits_;
0064 private:
0065     char_sink &operator =(char_sink const &);
0066 };
0067 
0068 ///////////////////////////////////////////////////////////////////////////////
0069 // xpression_peeker
0070 //
0071 template<typename Char>
0072 struct xpression_peeker
0073 {
0074     template<typename Traits>
0075     xpression_peeker(hash_peek_bitset<Char> &bset, Traits const &tr, bool has_backrefs = false)
0076       : bset_(bset)
0077       , str_()
0078       , line_start_(false)
0079       , traits_(0)
0080       , traits_type_(0)
0081       , leading_simple_repeat_(0)
0082       , has_backrefs_(has_backrefs)
0083     {
0084         this->set_traits(tr);
0085     }
0086 
0087     ///////////////////////////////////////////////////////////////////////////////
0088     // accessors
0089     peeker_string<Char> const &get_string() const
0090     {
0091         return this->str_;
0092     }
0093 
0094     bool line_start() const
0095     {
0096         return this->line_start_;
0097     }
0098 
0099     bool leading_simple_repeat() const
0100     {
0101         return 0 < this->leading_simple_repeat_;
0102     }
0103 
0104     hash_peek_bitset<Char> const &bitset() const
0105     {
0106         return this->bset_;
0107     }
0108 
0109     ///////////////////////////////////////////////////////////////////////////////
0110     // modifiers
0111     void fail()
0112     {
0113         this->bset_.set_all();
0114     }
0115 
0116     template<typename Matcher>
0117     mpl::false_ accept(Matcher const &)
0118     {
0119         this->fail();
0120         return mpl::false_();
0121     }
0122 
0123     mpl::true_ accept(mark_begin_matcher const &)
0124     {
0125         if(this->has_backrefs_)
0126         {
0127             --this->leading_simple_repeat_;
0128         }
0129         return mpl::true_();
0130     }
0131 
0132     mpl::true_ accept(repeat_begin_matcher const &)
0133     {
0134         --this->leading_simple_repeat_;
0135         return mpl::true_();
0136     }
0137 
0138     template<typename Traits>
0139     mpl::true_ accept(assert_bol_matcher<Traits> const &)
0140     {
0141         this->line_start_ = true;
0142         return mpl::true_();
0143     }
0144 
0145     template<typename Traits, typename ICase>
0146     mpl::false_ accept(literal_matcher<Traits, ICase, mpl::false_> const &xpr)
0147     {
0148         this->bset_.set_char(xpr.ch_, ICase(), this->get_traits_<Traits>());
0149         return mpl::false_();
0150     }
0151 
0152     template<typename Traits, typename ICase>
0153     mpl::false_ accept(string_matcher<Traits, ICase> const &xpr)
0154     {
0155         this->bset_.set_char(xpr.str_[0], ICase(), this->get_traits_<Traits>());
0156         this->str_.begin_ = detail::data_begin(xpr.str_);
0157         this->str_.end_ = detail::data_end(xpr.str_);
0158         this->str_.icase_ = ICase::value;
0159         return mpl::false_();
0160     }
0161 
0162     template<typename Alternates, typename Traits>
0163     mpl::false_ accept(alternate_matcher<Alternates, Traits> const &xpr)
0164     {
0165         BOOST_ASSERT(0 != xpr.bset_.count());
0166         this->bset_.set_bitset(xpr.bset_);
0167         return mpl::false_();
0168     }
0169 
0170     template<typename Matcher, typename Traits, typename ICase>
0171     mpl::false_ accept(attr_matcher<Matcher, Traits, ICase> const &xpr)
0172     {
0173         xpr.sym_.peek(char_sink<Traits, ICase::value>(this->bset_, this->get_traits_<Traits>()));
0174         return mpl::false_();
0175     }
0176 
0177     template<typename Xpr, typename Greedy>
0178     mpl::false_ accept(optional_matcher<Xpr, Greedy> const &)
0179     {
0180         this->fail();  // a union of xpr and next
0181         return mpl::false_();
0182     }
0183 
0184     template<typename Xpr, typename Greedy>
0185     mpl::false_ accept(optional_mark_matcher<Xpr, Greedy> const &)
0186     {
0187         this->fail();  // a union of xpr and next
0188         return mpl::false_();
0189     }
0190 
0191     //template<typename Xpr, typename Greedy>
0192     //mpl::true_ accept(optional_matcher<Xpr, Greedy> const &xpr)
0193     //{
0194     //    xpr.xpr_.peek(*this);  // a union of xpr and next
0195     //    return mpl::true_();
0196     //}
0197 
0198     //template<typename Xpr, typename Greedy>
0199     //mpl::true_ accept(optional_mark_matcher<Xpr, Greedy> const &xpr)
0200     //{
0201     //    xpr.xpr_.peek(*this);  // a union of xpr and next
0202     //    return mpl::true_();
0203     //}
0204 
0205     template<typename Traits>
0206     mpl::false_ accept(posix_charset_matcher<Traits> const &xpr)
0207     {
0208         this->bset_.set_class(xpr.mask_, xpr.not_, this->get_traits_<Traits>());
0209         return mpl::false_();
0210     }
0211 
0212     template<typename ICase, typename Traits>
0213     typename enable_if<is_narrow_char<typename Traits::char_type>, mpl::false_>::type
0214     accept(charset_matcher<Traits, ICase, basic_chset<Char> > const &xpr)
0215     {
0216         BOOST_ASSERT(0 != xpr.charset_.base().count());
0217         this->bset_.set_charset(xpr.charset_, ICase());
0218         return mpl::false_();
0219     }
0220 
0221     template<typename Traits, typename ICase>
0222     mpl::false_ accept(range_matcher<Traits, ICase> const &xpr)
0223     {
0224         this->bset_.set_range(xpr.ch_min_, xpr.ch_max_, xpr.not_, ICase(), this->get_traits_<Traits>());
0225         return mpl::false_();
0226     }
0227 
0228     template<typename Xpr, typename Greedy>
0229     mpl::false_ accept(simple_repeat_matcher<Xpr, Greedy> const &xpr)
0230     {
0231         if(Greedy() && 1U == xpr.width_)
0232         {
0233             ++this->leading_simple_repeat_;
0234             xpr.leading_ = this->leading_simple_repeat();
0235         }
0236         0 != xpr.min_ ? xpr.xpr_.peek(*this) : this->fail(); // could be a union of xpr and next
0237         return mpl::false_();
0238     }
0239 
0240     template<typename Xpr>
0241     mpl::false_ accept(keeper_matcher<Xpr> const &xpr)
0242     {
0243         xpr.xpr_.peek(*this);
0244         return mpl::false_();
0245     }
0246 
0247     template<typename Traits>
0248     void set_traits(Traits const &tr)
0249     {
0250         if(0 == this->traits_)
0251         {
0252             this->traits_ = &tr;
0253             this->traits_type_ = &typeid(Traits);
0254         }
0255         else if(*this->traits_type_ != typeid(Traits) || this->get_traits_<Traits>() != tr)
0256         {
0257             this->fail(); // traits mis-match! set all and bail
0258         }
0259     }
0260 
0261 private:
0262     xpression_peeker(xpression_peeker const &);
0263     xpression_peeker &operator =(xpression_peeker const &);
0264 
0265     template<typename Traits>
0266     Traits const &get_traits_() const
0267     {
0268         BOOST_ASSERT(!!(*this->traits_type_ == typeid(Traits)));
0269         return *static_cast<Traits const *>(this->traits_);
0270     }
0271 
0272     hash_peek_bitset<Char> &bset_;
0273     peeker_string<Char> str_;
0274     bool str_icase_;
0275     bool line_start_;
0276     void const *traits_;
0277     std::type_info const *traits_type_;
0278     int leading_simple_repeat_;
0279     bool has_backrefs_;
0280 };
0281 
0282 }}} // namespace boost::xpressive::detail
0283 
0284 #endif