1 ///////////////////////////////////////////////////////////////////////////////
2 // regex_impl.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_CORE_REGEX_IMPL_HPP_EAN_10_04_2005
9 #define BOOST_XPRESSIVE_DETAIL_CORE_REGEX_IMPL_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 <vector>
17 #include <boost/intrusive_ptr.hpp>
18 #include <boost/xpressive/regex_traits.hpp>
19 #include <boost/xpressive/detail/detail_fwd.hpp>
20 #include <boost/xpressive/detail/dynamic/matchable.hpp>
21 #include <boost/xpressive/detail/utility/tracking_ptr.hpp>
22 #include <boost/xpressive/detail/utility/counted_base.hpp>
23 
24 namespace boost { namespace xpressive { namespace detail
25 {
26 
27 ///////////////////////////////////////////////////////////////////////////////
28 // finder
29 template<typename BidiIter>
30 struct finder
31   : counted_base<finder<BidiIter> >
32 {
~finderboost::xpressive::detail::finder33     virtual ~finder() {}
ok_for_partial_matchesboost::xpressive::detail::finder34     virtual bool ok_for_partial_matches() const { return true; }
35     virtual bool operator ()(match_state<BidiIter> &state) const = 0;
36 };
37 
38 ///////////////////////////////////////////////////////////////////////////////
39 // traits
40 template<typename Char>
41 struct traits
42   : counted_base<traits<Char> >
43 {
~traitsboost::xpressive::detail::traits44     virtual ~traits() {}
45     virtual Char tolower(Char ch) const = 0;
46     virtual Char toupper(Char ch) const = 0;
47     virtual bool in_range(Char from, Char to, Char ch) const = 0;
48     virtual int value(Char ch, int radix) const = 0;
49 };
50 
51 ///////////////////////////////////////////////////////////////////////////////
52 // named_mark
53 template<typename Char>
54 struct named_mark
55 {
56     typedef typename detail::string_type<Char>::type string_type;
57 
named_markboost::xpressive::detail::named_mark58     named_mark(string_type name, std::size_t mark_nbr)
59       : name_(name)
60       , mark_nbr_(mark_nbr)
61     {}
62 
63     string_type name_;
64     std::size_t mark_nbr_;
65 };
66 
67 ///////////////////////////////////////////////////////////////////////////////
68 // traits_holder
69 template<typename Traits>
70 struct traits_holder
71   : traits<typename Traits::char_type>
72 {
73     typedef typename Traits::char_type char_type;
74 
traits_holderboost::xpressive::detail::traits_holder75     explicit traits_holder(Traits const &tr)
76       : traits_(tr)
77     {
78     }
79 
traitsboost::xpressive::detail::traits_holder80     Traits const &traits() const
81     {
82         return this->traits_;
83     }
84 
tolowerboost::xpressive::detail::traits_holder85     char_type tolower(char_type ch) const
86     {
87         return this->tolower_(ch, typename Traits::version_tag());
88     }
89 
toupperboost::xpressive::detail::traits_holder90     char_type toupper(char_type ch) const
91     {
92         return this->toupper_(ch, typename Traits::version_tag());
93     }
94 
valueboost::xpressive::detail::traits_holder95     int value(char_type ch, int radix) const
96     {
97         return this->traits_.value(ch, radix);
98     }
99 
in_rangeboost::xpressive::detail::traits_holder100     bool in_range(char_type from, char_type to, char_type ch) const
101     {
102         return this->traits_.in_range(from, to, ch);
103     }
104 
105 private:
tolower_boost::xpressive::detail::traits_holder106     char_type tolower_(char_type ch, regex_traits_version_1_tag) const
107     {
108         return ch;
109     }
110 
toupper_boost::xpressive::detail::traits_holder111     char_type toupper_(char_type ch, regex_traits_version_1_tag) const
112     {
113         return ch;
114     }
115 
tolower_boost::xpressive::detail::traits_holder116     char_type tolower_(char_type ch, regex_traits_version_2_tag) const
117     {
118         return this->traits_.tolower(ch);
119     }
120 
toupper_boost::xpressive::detail::traits_holder121     char_type toupper_(char_type ch, regex_traits_version_2_tag) const
122     {
123         return this->traits_.toupper(ch);
124     }
125 
126     Traits traits_;
127 };
128 
129 ///////////////////////////////////////////////////////////////////////////////
130 // regex_impl
131 //
132 template<typename BidiIter>
133 struct regex_impl
134   : enable_reference_tracking<regex_impl<BidiIter> >
135 {
136     typedef typename iterator_value<BidiIter>::type char_type;
137 
regex_implboost::xpressive::detail::regex_impl138     regex_impl()
139       : enable_reference_tracking<regex_impl<BidiIter> >()
140       , xpr_()
141       , traits_()
142       , finder_()
143       , named_marks_()
144       , mark_count_(0)
145       , hidden_mark_count_(0)
146     {
147         #ifdef BOOST_XPRESSIVE_DEBUG_CYCLE_TEST
148         ++instances;
149         #endif
150     }
151 
regex_implboost::xpressive::detail::regex_impl152     regex_impl(regex_impl<BidiIter> const &that)
153       : enable_reference_tracking<regex_impl<BidiIter> >(that)
154       , xpr_(that.xpr_)
155       , traits_(that.traits_)
156       , finder_(that.finder_)
157       , named_marks_(that.named_marks_)
158       , mark_count_(that.mark_count_)
159       , hidden_mark_count_(that.hidden_mark_count_)
160     {
161         #ifdef BOOST_XPRESSIVE_DEBUG_CYCLE_TEST
162         ++instances;
163         #endif
164     }
165 
~regex_implboost::xpressive::detail::regex_impl166     ~regex_impl()
167     {
168         #ifdef BOOST_XPRESSIVE_DEBUG_CYCLE_TEST
169         --instances;
170         #endif
171     }
172 
swapboost::xpressive::detail::regex_impl173     void swap(regex_impl<BidiIter> &that)
174     {
175         enable_reference_tracking<regex_impl<BidiIter> >::swap(that);
176         this->xpr_.swap(that.xpr_);
177         this->traits_.swap(that.traits_);
178         this->finder_.swap(that.finder_);
179         this->named_marks_.swap(that.named_marks_);
180         std::swap(this->mark_count_, that.mark_count_);
181         std::swap(this->hidden_mark_count_, that.hidden_mark_count_);
182     }
183 
184     intrusive_ptr<matchable_ex<BidiIter> const> xpr_;
185     intrusive_ptr<traits<char_type> const> traits_;
186     intrusive_ptr<finder<BidiIter> > finder_;
187     std::vector<named_mark<char_type> > named_marks_;
188     std::size_t mark_count_;
189     std::size_t hidden_mark_count_;
190 
191     #ifdef BOOST_XPRESSIVE_DEBUG_CYCLE_TEST
192     static int instances;
193     #endif
194 
195 private:
196     regex_impl &operator =(regex_impl const &);
197 };
198 
199 template<typename BidiIter>
swap(regex_impl<BidiIter> & left,regex_impl<BidiIter> & right)200 void swap(regex_impl<BidiIter> &left, regex_impl<BidiIter> &right)
201 {
202     left.swap(right);
203 }
204 
205 #ifdef BOOST_XPRESSIVE_DEBUG_CYCLE_TEST
206 template<typename BidiIter>
207 int regex_impl<BidiIter>::instances = 0;
208 #endif
209 
210 }}} // namespace boost::xpressive::detail
211 
212 #endif
213