46fd6c164156280668515661f8655f7ba3d568d6
[platform/upstream/boost.git] / boost / xpressive / detail / static / visitor.hpp
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     {
30         explicit xpression_visitor_base(shared_ptr<regex_impl<BidiIter> > const &self)
31           : self_(self)
32         {
33         }
34
35         void swap(xpression_visitor_base<BidiIter> &that)
36         {
37             this->self_.swap(that.self_);
38         }
39
40         int get_hidden_mark()
41         {
42             return -(int)(++this->self_->hidden_mark_count_);
43         }
44
45         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
54         shared_ptr<regex_impl<BidiIter> > &self()
55         {
56             return this->self_;
57         }
58
59     protected:
60
61         template<typename Matcher>
62         void visit_(Matcher const &)
63         {
64         }
65
66         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
72         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
78         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
84         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
90         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
111         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
125         call(Matcher const &matcher)
126         {
127             this->visit_(matcher);
128             return transmogrify<BidiIter, ICase, Traits, Matcher>::call(matcher, *this);
129         }
130
131         Traits const &traits() const
132         {
133             return this->traits_;
134         }
135
136     private:
137
138         Traits traits_;
139     };
140
141 }}}
142
143 #endif