optimize.hpp 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. ///////////////////////////////////////////////////////////////////////////////
  2. // optimize.hpp
  3. //
  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)
  7. #ifndef BOOST_XPRESSIVE_DETAIL_CORE_OPTIMIZE_HPP_EAN_10_04_2005
  8. #define BOOST_XPRESSIVE_DETAIL_CORE_OPTIMIZE_HPP_EAN_10_04_2005
  9. #include <string>
  10. #include <utility>
  11. #include <boost/mpl/bool.hpp>
  12. #include <boost/intrusive_ptr.hpp>
  13. #include <boost/iterator/iterator_traits.hpp>
  14. #include <boost/xpressive/detail/core/finder.hpp>
  15. #include <boost/xpressive/detail/core/linker.hpp>
  16. #include <boost/xpressive/detail/core/peeker.hpp>
  17. #include <boost/xpressive/detail/core/regex_impl.hpp>
  18. namespace boost { namespace xpressive { namespace detail
  19. {
  20. ///////////////////////////////////////////////////////////////////////////////
  21. // optimize_regex
  22. //
  23. template<typename BidiIter, typename Traits>
  24. intrusive_ptr<finder<BidiIter> > optimize_regex
  25. (
  26. xpression_peeker<typename iterator_value<BidiIter>::type> const &peeker
  27. , Traits const &tr
  28. , mpl::false_
  29. )
  30. {
  31. if(peeker.line_start())
  32. {
  33. return intrusive_ptr<finder<BidiIter> >
  34. (
  35. new line_start_finder<BidiIter, Traits>(tr)
  36. );
  37. }
  38. else if(peeker.leading_simple_repeat())
  39. {
  40. return intrusive_ptr<finder<BidiIter> >
  41. (
  42. new leading_simple_repeat_finder<BidiIter>()
  43. );
  44. }
  45. else if(256 != peeker.bitset().count())
  46. {
  47. return intrusive_ptr<finder<BidiIter> >
  48. (
  49. new hash_peek_finder<BidiIter, Traits>(peeker.bitset())
  50. );
  51. }
  52. return intrusive_ptr<finder<BidiIter> >();
  53. }
  54. ///////////////////////////////////////////////////////////////////////////////
  55. // optimize_regex
  56. //
  57. template<typename BidiIter, typename Traits>
  58. intrusive_ptr<finder<BidiIter> > optimize_regex
  59. (
  60. xpression_peeker<typename iterator_value<BidiIter>::type> const &peeker
  61. , Traits const &tr
  62. , mpl::true_
  63. )
  64. {
  65. typedef typename iterator_value<BidiIter>::type char_type;
  66. // if we have a leading string literal, initialize a boyer-moore struct with it
  67. peeker_string<char_type> const &str = peeker.get_string();
  68. if(str.begin_ != str.end_)
  69. {
  70. BOOST_ASSERT(1 == peeker.bitset().count());
  71. return intrusive_ptr<finder<BidiIter> >
  72. (
  73. new boyer_moore_finder<BidiIter, Traits>(str.begin_, str.end_, tr, str.icase_)
  74. );
  75. }
  76. return optimize_regex<BidiIter>(peeker, tr, mpl::false_());
  77. }
  78. ///////////////////////////////////////////////////////////////////////////////
  79. // common_compile
  80. //
  81. template<typename BidiIter, typename Traits>
  82. void common_compile
  83. (
  84. intrusive_ptr<matchable_ex<BidiIter> const> const &regex
  85. , regex_impl<BidiIter> &impl
  86. , Traits const &tr
  87. )
  88. {
  89. typedef typename iterator_value<BidiIter>::type char_type;
  90. // "link" the regex
  91. xpression_linker<char_type> linker(tr);
  92. regex->link(linker);
  93. // "peek" into the compiled regex to see if there are optimization opportunities
  94. hash_peek_bitset<char_type> bset;
  95. xpression_peeker<char_type> peeker(bset, tr, linker.has_backrefs());
  96. regex->peek(peeker);
  97. // optimization: get the peek chars OR the boyer-moore search string
  98. impl.finder_ = optimize_regex<BidiIter>(peeker, tr, is_random<BidiIter>());
  99. impl.xpr_ = regex;
  100. }
  101. }}} // namespace boost::xpressive
  102. #endif