You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
117 lines
3.4 KiB
117 lines
3.4 KiB
3 years ago
|
///////////////////////////////////////////////////////////////////////////////
|
||
|
// 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
|