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