1 ///////////////////////////////////////////////////////////////////////////////
4 // Copyright 2008 Eric Niebler. Distributed under the Boost
5 // Software License, Version 1.0. (See accompanying file
6 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
8 #ifndef BOOST_XPRESSIVE_DETAIL_CORE_OPTIMIZE_HPP_EAN_10_04_2005
9 #define BOOST_XPRESSIVE_DETAIL_CORE_OPTIMIZE_HPP_EAN_10_04_2005
13 #include <boost/mpl/bool.hpp>
14 #include <boost/intrusive_ptr.hpp>
15 #include <boost/iterator/iterator_traits.hpp>
16 #include <boost/xpressive/detail/core/finder.hpp>
17 #include <boost/xpressive/detail/core/linker.hpp>
18 #include <boost/xpressive/detail/core/peeker.hpp>
19 #include <boost/xpressive/detail/core/regex_impl.hpp>
21 namespace boost { namespace xpressive { namespace detail
24 ///////////////////////////////////////////////////////////////////////////////
27 template<typename BidiIter, typename Traits>
28 intrusive_ptr<finder<BidiIter> > optimize_regex
30 xpression_peeker<typename iterator_value<BidiIter>::type> const &peeker
35 if(peeker.line_start())
37 return intrusive_ptr<finder<BidiIter> >
39 new line_start_finder<BidiIter, Traits>(tr)
42 else if(peeker.leading_simple_repeat())
44 return intrusive_ptr<finder<BidiIter> >
46 new leading_simple_repeat_finder<BidiIter>()
49 else if(256 != peeker.bitset().count())
51 return intrusive_ptr<finder<BidiIter> >
53 new hash_peek_finder<BidiIter, Traits>(peeker.bitset())
57 return intrusive_ptr<finder<BidiIter> >();
60 ///////////////////////////////////////////////////////////////////////////////
63 template<typename BidiIter, typename Traits>
64 intrusive_ptr<finder<BidiIter> > optimize_regex
66 xpression_peeker<typename iterator_value<BidiIter>::type> const &peeker
71 typedef typename iterator_value<BidiIter>::type char_type;
73 // if we have a leading string literal, initialize a boyer-moore struct with it
74 peeker_string<char_type> const &str = peeker.get_string();
75 if(str.begin_ != str.end_)
77 BOOST_ASSERT(1 == peeker.bitset().count());
78 return intrusive_ptr<finder<BidiIter> >
80 new boyer_moore_finder<BidiIter, Traits>(str.begin_, str.end_, tr, str.icase_)
84 return optimize_regex<BidiIter>(peeker, tr, mpl::false_());
87 ///////////////////////////////////////////////////////////////////////////////
90 template<typename BidiIter, typename Traits>
93 intrusive_ptr<matchable_ex<BidiIter> const> const ®ex
94 , regex_impl<BidiIter> &impl
98 typedef typename iterator_value<BidiIter>::type char_type;
101 xpression_linker<char_type> linker(tr);
104 // "peek" into the compiled regex to see if there are optimization opportunities
105 hash_peek_bitset<char_type> bset;
106 xpression_peeker<char_type> peeker(bset, tr, linker.has_backrefs());
109 // optimization: get the peek chars OR the boyer-moore search string
110 impl.finder_ = optimize_regex<BidiIter>(peeker, tr, is_random<BidiIter>());
114 }}} // namespace boost::xpressive