visitor.hpp 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  1. ///////////////////////////////////////////////////////////////////////////////
  2. // visitor.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_STATIC_VISITOR_HPP_EAN_10_04_2005
  8. #define BOOST_XPRESSIVE_DETAIL_STATIC_VISITOR_HPP_EAN_10_04_2005
  9. // MS compatible compilers support #pragma once
  10. #if defined(_MSC_VER)
  11. # pragma once
  12. #endif
  13. #include <boost/ref.hpp>
  14. #include <boost/shared_ptr.hpp>
  15. #include <boost/xpressive/detail/detail_fwd.hpp>
  16. #include <boost/xpressive/detail/core/regex_impl.hpp>
  17. #include <boost/xpressive/detail/static/transmogrify.hpp>
  18. #include <boost/xpressive/detail/core/matcher/mark_begin_matcher.hpp>
  19. namespace boost { namespace xpressive { namespace detail
  20. {
  21. ///////////////////////////////////////////////////////////////////////////////
  22. //
  23. template<typename BidiIter>
  24. struct xpression_visitor_base
  25. {
  26. explicit xpression_visitor_base(shared_ptr<regex_impl<BidiIter> > const &self)
  27. : self_(self)
  28. {
  29. }
  30. void swap(xpression_visitor_base<BidiIter> &that)
  31. {
  32. this->self_.swap(that.self_);
  33. }
  34. int get_hidden_mark()
  35. {
  36. return -(int)(++this->self_->hidden_mark_count_);
  37. }
  38. void mark_number(int mark_nbr)
  39. {
  40. if(0 < mark_nbr)
  41. {
  42. this->self_->mark_count_ =
  43. (std::max)(this->self_->mark_count_, (std::size_t)mark_nbr);
  44. }
  45. }
  46. shared_ptr<regex_impl<BidiIter> > &self()
  47. {
  48. return this->self_;
  49. }
  50. protected:
  51. template<typename Matcher>
  52. void visit_(Matcher const &)
  53. {
  54. }
  55. void visit_(reference_wrapper<basic_regex<BidiIter> > const &rex)
  56. {
  57. // when visiting an embedded regex, track the references
  58. this->self_->track_reference(*detail::core_access<BidiIter>::get_regex_impl(rex.get()));
  59. }
  60. void visit_(reference_wrapper<basic_regex<BidiIter> const> const &rex)
  61. {
  62. // when visiting an embedded regex, track the references
  63. this->self_->track_reference(*detail::core_access<BidiIter>::get_regex_impl(rex.get()));
  64. }
  65. void visit_(tracking_ptr<regex_impl<BidiIter> > const &rex)
  66. {
  67. // when visiting an embedded regex, track the references
  68. this->self_->track_reference(*rex.get());
  69. }
  70. void visit_(mark_placeholder const &backref)
  71. {
  72. // keep track of the largest mark number found
  73. this->mark_number(backref.mark_number_);
  74. }
  75. void visit_(mark_begin_matcher const &mark_begin)
  76. {
  77. // keep track of the largest mark number found
  78. this->mark_number(mark_begin.mark_number_);
  79. }
  80. private:
  81. shared_ptr<regex_impl<BidiIter> > self_;
  82. };
  83. ///////////////////////////////////////////////////////////////////////////////
  84. //
  85. template<typename BidiIter, typename ICase, typename Traits>
  86. struct xpression_visitor
  87. : xpression_visitor_base<BidiIter>
  88. {
  89. typedef BidiIter iterator_type;
  90. typedef ICase icase_type;
  91. typedef Traits traits_type;
  92. typedef typename boost::iterator_value<BidiIter>::type char_type;
  93. explicit xpression_visitor(Traits const &tr, shared_ptr<regex_impl<BidiIter> > const &self)
  94. : xpression_visitor_base<BidiIter>(self)
  95. , traits_(tr)
  96. {
  97. }
  98. template<typename Matcher>
  99. struct apply
  100. {
  101. typedef typename transmogrify<BidiIter, ICase, Traits, Matcher>::type type;
  102. };
  103. template<typename Matcher>
  104. typename apply<Matcher>::type
  105. call(Matcher const &matcher)
  106. {
  107. this->visit_(matcher);
  108. return transmogrify<BidiIter, ICase, Traits, Matcher>::call(matcher, *this);
  109. }
  110. Traits const &traits() const
  111. {
  112. return this->traits_;
  113. }
  114. private:
  115. Traits traits_;
  116. };
  117. }}}
  118. #endif