| /////////////////////////////////////////////////////////////////////////////// |
| // optimize.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_OPTIMIZE_HPP_EAN_10_04_2005 |
| #define BOOST_XPRESSIVE_DETAIL_CORE_OPTIMIZE_HPP_EAN_10_04_2005 |
| |
| #include <string> |
| #include <utility> |
| #include <boost/mpl/bool.hpp> |
| #include <boost/intrusive_ptr.hpp> |
| #include <boost/iterator/iterator_traits.hpp> |
| #include <boost/xpressive/detail/core/finder.hpp> |
| #include <boost/xpressive/detail/core/linker.hpp> |
| #include <boost/xpressive/detail/core/peeker.hpp> |
| #include <boost/xpressive/detail/core/regex_impl.hpp> |
| |
| namespace boost { namespace xpressive { namespace detail |
| { |
| |
| /////////////////////////////////////////////////////////////////////////////// |
| // optimize_regex |
| // |
| template<typename BidiIter, typename Traits> |
| intrusive_ptr<finder<BidiIter> > optimize_regex |
| ( |
| xpression_peeker<typename iterator_value<BidiIter>::type> const &peeker |
| , Traits const &tr |
| , mpl::false_ |
| ) |
| { |
| if(peeker.line_start()) |
| { |
| return intrusive_ptr<finder<BidiIter> > |
| ( |
| new line_start_finder<BidiIter, Traits>(tr) |
| ); |
| } |
| else if(peeker.leading_simple_repeat()) |
| { |
| return intrusive_ptr<finder<BidiIter> > |
| ( |
| new leading_simple_repeat_finder<BidiIter>() |
| ); |
| } |
| else if(256 != peeker.bitset().count()) |
| { |
| return intrusive_ptr<finder<BidiIter> > |
| ( |
| new hash_peek_finder<BidiIter, Traits>(peeker.bitset()) |
| ); |
| } |
| |
| return intrusive_ptr<finder<BidiIter> >(); |
| } |
| |
| /////////////////////////////////////////////////////////////////////////////// |
| // optimize_regex |
| // |
| template<typename BidiIter, typename Traits> |
| intrusive_ptr<finder<BidiIter> > optimize_regex |
| ( |
| xpression_peeker<typename iterator_value<BidiIter>::type> const &peeker |
| , Traits const &tr |
| , mpl::true_ |
| ) |
| { |
| typedef typename iterator_value<BidiIter>::type char_type; |
| |
| // if we have a leading string literal, initialize a boyer-moore struct with it |
| peeker_string<char_type> const &str = peeker.get_string(); |
| if(str.begin_ != str.end_) |
| { |
| BOOST_ASSERT(1 == peeker.bitset().count()); |
| return intrusive_ptr<finder<BidiIter> > |
| ( |
| new boyer_moore_finder<BidiIter, Traits>(str.begin_, str.end_, tr, str.icase_) |
| ); |
| } |
| |
| return optimize_regex<BidiIter>(peeker, tr, mpl::false_()); |
| } |
| |
| /////////////////////////////////////////////////////////////////////////////// |
| // common_compile |
| // |
| template<typename BidiIter, typename Traits> |
| void common_compile |
| ( |
| intrusive_ptr<matchable_ex<BidiIter> const> const ®ex |
| , regex_impl<BidiIter> &impl |
| , Traits const &tr |
| ) |
| { |
| typedef typename iterator_value<BidiIter>::type char_type; |
| |
| // "link" the regex |
| xpression_linker<char_type> linker(tr); |
| regex->link(linker); |
| |
| // "peek" into the compiled regex to see if there are optimization opportunities |
| hash_peek_bitset<char_type> bset; |
| xpression_peeker<char_type> peeker(bset, tr, linker.has_backrefs()); |
| regex->peek(peeker); |
| |
| // optimization: get the peek chars OR the boyer-moore search string |
| impl.finder_ = optimize_regex<BidiIter>(peeker, tr, is_random<BidiIter>()); |
| impl.xpr_ = regex; |
| } |
| |
| }}} // namespace boost::xpressive |
| |
| #endif |