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 8 #ifndef BOOST_XPRESSIVE_DETAIL_STATIC_VISITOR_HPP_EAN_10_04_2005 9 #define BOOST_XPRESSIVE_DETAIL_STATIC_VISITOR_HPP_EAN_10_04_2005 10 11 // MS compatible compilers support #pragma once 12 #if defined(_MSC_VER) 13 # pragma once 14 #endif 15 16 #include <boost/ref.hpp> 17 #include <boost/shared_ptr.hpp> 18 #include <boost/xpressive/detail/detail_fwd.hpp> 19 #include <boost/xpressive/detail/core/regex_impl.hpp> 20 #include <boost/xpressive/detail/static/transmogrify.hpp> 21 #include <boost/xpressive/detail/core/matcher/mark_begin_matcher.hpp> 22 23 namespace boost { namespace xpressive { namespace detail 24 { 25 /////////////////////////////////////////////////////////////////////////////// 26 // 27 template<typename BidiIter> 28 struct xpression_visitor_base 29 { xpression_visitor_baseboost::xpressive::detail::xpression_visitor_base30 explicit xpression_visitor_base(shared_ptr<regex_impl<BidiIter> > const &self) 31 : self_(self) 32 { 33 } 34 swapboost::xpressive::detail::xpression_visitor_base35 void swap(xpression_visitor_base<BidiIter> &that) 36 { 37 this->self_.swap(that.self_); 38 } 39 get_hidden_markboost::xpressive::detail::xpression_visitor_base40 int get_hidden_mark() 41 { 42 return -(int)(++this->self_->hidden_mark_count_); 43 } 44 mark_numberboost::xpressive::detail::xpression_visitor_base45 void mark_number(int mark_nbr) 46 { 47 if(0 < mark_nbr) 48 { 49 this->self_->mark_count_ = 50 (std::max)(this->self_->mark_count_, (std::size_t)mark_nbr); 51 } 52 } 53 selfboost::xpressive::detail::xpression_visitor_base54 shared_ptr<regex_impl<BidiIter> > &self() 55 { 56 return this->self_; 57 } 58 59 protected: 60 61 template<typename Matcher> visit_boost::xpressive::detail::xpression_visitor_base62 void visit_(Matcher const &) 63 { 64 } 65 visit_boost::xpressive::detail::xpression_visitor_base66 void visit_(reference_wrapper<basic_regex<BidiIter> > const &rex) 67 { 68 // when visiting an embedded regex, track the references 69 this->self_->track_reference(*detail::core_access<BidiIter>::get_regex_impl(rex.get())); 70 } 71 visit_boost::xpressive::detail::xpression_visitor_base72 void visit_(reference_wrapper<basic_regex<BidiIter> const> const &rex) 73 { 74 // when visiting an embedded regex, track the references 75 this->self_->track_reference(*detail::core_access<BidiIter>::get_regex_impl(rex.get())); 76 } 77 visit_boost::xpressive::detail::xpression_visitor_base78 void visit_(tracking_ptr<regex_impl<BidiIter> > const &rex) 79 { 80 // when visiting an embedded regex, track the references 81 this->self_->track_reference(*rex.get()); 82 } 83 visit_boost::xpressive::detail::xpression_visitor_base84 void visit_(mark_placeholder const &backref) 85 { 86 // keep track of the largest mark number found 87 this->mark_number(backref.mark_number_); 88 } 89 visit_boost::xpressive::detail::xpression_visitor_base90 void visit_(mark_begin_matcher const &mark_begin) 91 { 92 // keep track of the largest mark number found 93 this->mark_number(mark_begin.mark_number_); 94 } 95 96 private: 97 shared_ptr<regex_impl<BidiIter> > self_; 98 }; 99 100 /////////////////////////////////////////////////////////////////////////////// 101 // 102 template<typename BidiIter, typename ICase, typename Traits> 103 struct xpression_visitor 104 : xpression_visitor_base<BidiIter> 105 { 106 typedef BidiIter iterator_type; 107 typedef ICase icase_type; 108 typedef Traits traits_type; 109 typedef typename boost::iterator_value<BidiIter>::type char_type; 110 xpression_visitorboost::xpressive::detail::xpression_visitor111 explicit xpression_visitor(Traits const &tr, shared_ptr<regex_impl<BidiIter> > const &self) 112 : xpression_visitor_base<BidiIter>(self) 113 , traits_(tr) 114 { 115 } 116 117 template<typename Matcher> 118 struct apply 119 { 120 typedef typename transmogrify<BidiIter, ICase, Traits, Matcher>::type type; 121 }; 122 123 template<typename Matcher> 124 typename apply<Matcher>::type callboost::xpressive::detail::xpression_visitor125 call(Matcher const &matcher) 126 { 127 this->visit_(matcher); 128 return transmogrify<BidiIter, ICase, Traits, Matcher>::call(matcher, *this); 129 } 130 traitsboost::xpressive::detail::xpression_visitor131 Traits const &traits() const 132 { 133 return this->traits_; 134 } 135 136 private: 137 138 Traits traits_; 139 }; 140 141 }}} 142 143 #endif 144