Chris@16
|
1 ///////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
2 // visitor.hpp
|
Chris@16
|
3 //
|
Chris@16
|
4 // Copyright 2008 Eric Niebler. Distributed under the Boost
|
Chris@16
|
5 // Software License, Version 1.0. (See accompanying file
|
Chris@16
|
6 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
Chris@16
|
7
|
Chris@16
|
8 #ifndef BOOST_XPRESSIVE_DETAIL_STATIC_VISITOR_HPP_EAN_10_04_2005
|
Chris@16
|
9 #define BOOST_XPRESSIVE_DETAIL_STATIC_VISITOR_HPP_EAN_10_04_2005
|
Chris@16
|
10
|
Chris@16
|
11 // MS compatible compilers support #pragma once
|
Chris@101
|
12 #if defined(_MSC_VER)
|
Chris@16
|
13 # pragma once
|
Chris@16
|
14 #endif
|
Chris@16
|
15
|
Chris@16
|
16 #include <boost/ref.hpp>
|
Chris@16
|
17 #include <boost/shared_ptr.hpp>
|
Chris@16
|
18 #include <boost/xpressive/detail/detail_fwd.hpp>
|
Chris@16
|
19 #include <boost/xpressive/detail/core/regex_impl.hpp>
|
Chris@16
|
20 #include <boost/xpressive/detail/static/transmogrify.hpp>
|
Chris@16
|
21 #include <boost/xpressive/detail/core/matcher/mark_begin_matcher.hpp>
|
Chris@16
|
22
|
Chris@16
|
23 namespace boost { namespace xpressive { namespace detail
|
Chris@16
|
24 {
|
Chris@16
|
25 ///////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
26 //
|
Chris@16
|
27 template<typename BidiIter>
|
Chris@16
|
28 struct xpression_visitor_base
|
Chris@16
|
29 {
|
Chris@16
|
30 explicit xpression_visitor_base(shared_ptr<regex_impl<BidiIter> > const &self)
|
Chris@16
|
31 : self_(self)
|
Chris@16
|
32 {
|
Chris@16
|
33 }
|
Chris@16
|
34
|
Chris@16
|
35 void swap(xpression_visitor_base<BidiIter> &that)
|
Chris@16
|
36 {
|
Chris@16
|
37 this->self_.swap(that.self_);
|
Chris@16
|
38 }
|
Chris@16
|
39
|
Chris@16
|
40 int get_hidden_mark()
|
Chris@16
|
41 {
|
Chris@16
|
42 return -(int)(++this->self_->hidden_mark_count_);
|
Chris@16
|
43 }
|
Chris@16
|
44
|
Chris@16
|
45 void mark_number(int mark_nbr)
|
Chris@16
|
46 {
|
Chris@16
|
47 if(0 < mark_nbr)
|
Chris@16
|
48 {
|
Chris@16
|
49 this->self_->mark_count_ =
|
Chris@16
|
50 (std::max)(this->self_->mark_count_, (std::size_t)mark_nbr);
|
Chris@16
|
51 }
|
Chris@16
|
52 }
|
Chris@16
|
53
|
Chris@16
|
54 shared_ptr<regex_impl<BidiIter> > &self()
|
Chris@16
|
55 {
|
Chris@16
|
56 return this->self_;
|
Chris@16
|
57 }
|
Chris@16
|
58
|
Chris@16
|
59 protected:
|
Chris@16
|
60
|
Chris@16
|
61 template<typename Matcher>
|
Chris@16
|
62 void visit_(Matcher const &)
|
Chris@16
|
63 {
|
Chris@16
|
64 }
|
Chris@16
|
65
|
Chris@16
|
66 void visit_(reference_wrapper<basic_regex<BidiIter> > const &rex)
|
Chris@16
|
67 {
|
Chris@16
|
68 // when visiting an embedded regex, track the references
|
Chris@16
|
69 this->self_->track_reference(*detail::core_access<BidiIter>::get_regex_impl(rex.get()));
|
Chris@16
|
70 }
|
Chris@16
|
71
|
Chris@16
|
72 void visit_(reference_wrapper<basic_regex<BidiIter> const> const &rex)
|
Chris@16
|
73 {
|
Chris@16
|
74 // when visiting an embedded regex, track the references
|
Chris@16
|
75 this->self_->track_reference(*detail::core_access<BidiIter>::get_regex_impl(rex.get()));
|
Chris@16
|
76 }
|
Chris@16
|
77
|
Chris@16
|
78 void visit_(tracking_ptr<regex_impl<BidiIter> > const &rex)
|
Chris@16
|
79 {
|
Chris@16
|
80 // when visiting an embedded regex, track the references
|
Chris@16
|
81 this->self_->track_reference(*rex.get());
|
Chris@16
|
82 }
|
Chris@16
|
83
|
Chris@16
|
84 void visit_(mark_placeholder const &backref)
|
Chris@16
|
85 {
|
Chris@16
|
86 // keep track of the largest mark number found
|
Chris@16
|
87 this->mark_number(backref.mark_number_);
|
Chris@16
|
88 }
|
Chris@16
|
89
|
Chris@16
|
90 void visit_(mark_begin_matcher const &mark_begin)
|
Chris@16
|
91 {
|
Chris@16
|
92 // keep track of the largest mark number found
|
Chris@16
|
93 this->mark_number(mark_begin.mark_number_);
|
Chris@16
|
94 }
|
Chris@16
|
95
|
Chris@16
|
96 private:
|
Chris@16
|
97 shared_ptr<regex_impl<BidiIter> > self_;
|
Chris@16
|
98 };
|
Chris@16
|
99
|
Chris@16
|
100 ///////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
101 //
|
Chris@16
|
102 template<typename BidiIter, typename ICase, typename Traits>
|
Chris@16
|
103 struct xpression_visitor
|
Chris@16
|
104 : xpression_visitor_base<BidiIter>
|
Chris@16
|
105 {
|
Chris@16
|
106 typedef BidiIter iterator_type;
|
Chris@16
|
107 typedef ICase icase_type;
|
Chris@16
|
108 typedef Traits traits_type;
|
Chris@16
|
109 typedef typename boost::iterator_value<BidiIter>::type char_type;
|
Chris@16
|
110
|
Chris@16
|
111 explicit xpression_visitor(Traits const &tr, shared_ptr<regex_impl<BidiIter> > const &self)
|
Chris@16
|
112 : xpression_visitor_base<BidiIter>(self)
|
Chris@16
|
113 , traits_(tr)
|
Chris@16
|
114 {
|
Chris@16
|
115 }
|
Chris@16
|
116
|
Chris@16
|
117 template<typename Matcher>
|
Chris@16
|
118 struct apply
|
Chris@16
|
119 {
|
Chris@16
|
120 typedef typename transmogrify<BidiIter, ICase, Traits, Matcher>::type type;
|
Chris@16
|
121 };
|
Chris@16
|
122
|
Chris@16
|
123 template<typename Matcher>
|
Chris@16
|
124 typename apply<Matcher>::type
|
Chris@16
|
125 call(Matcher const &matcher)
|
Chris@16
|
126 {
|
Chris@16
|
127 this->visit_(matcher);
|
Chris@16
|
128 return transmogrify<BidiIter, ICase, Traits, Matcher>::call(matcher, *this);
|
Chris@16
|
129 }
|
Chris@16
|
130
|
Chris@16
|
131 Traits const &traits() const
|
Chris@16
|
132 {
|
Chris@16
|
133 return this->traits_;
|
Chris@16
|
134 }
|
Chris@16
|
135
|
Chris@16
|
136 private:
|
Chris@16
|
137
|
Chris@16
|
138 Traits traits_;
|
Chris@16
|
139 };
|
Chris@16
|
140
|
Chris@16
|
141 }}}
|
Chris@16
|
142
|
Chris@16
|
143 #endif
|