Chris@16
|
1 ///////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
2 // transmogrify.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_TRANSMOGRIFY_HPP_EAN_10_04_2005
|
Chris@16
|
9 #define BOOST_XPRESSIVE_DETAIL_STATIC_TRANSMOGRIFY_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 <cstring> // for std::strlen
|
Chris@16
|
17 #include <boost/mpl/if.hpp>
|
Chris@16
|
18 #include <boost/mpl/or.hpp>
|
Chris@16
|
19 #include <boost/mpl/bool.hpp>
|
Chris@16
|
20 #include <boost/mpl/assert.hpp>
|
Chris@16
|
21 #include <boost/type_traits/is_same.hpp>
|
Chris@16
|
22 #include <boost/xpressive/detail/detail_fwd.hpp>
|
Chris@16
|
23 #include <boost/xpressive/detail/core/matchers.hpp>
|
Chris@16
|
24 #include <boost/xpressive/detail/static/placeholders.hpp>
|
Chris@16
|
25 #include <boost/xpressive/detail/utility/dont_care.hpp>
|
Chris@16
|
26 #include <boost/xpressive/detail/utility/traits_utils.hpp>
|
Chris@16
|
27
|
Chris@16
|
28 namespace boost { namespace xpressive { namespace detail
|
Chris@16
|
29 {
|
Chris@16
|
30 template<typename T, typename Char>
|
Chris@16
|
31 struct is_char_literal
|
Chris@16
|
32 : mpl::or_<is_same<T, Char>, is_same<T, char> >
|
Chris@16
|
33 {};
|
Chris@16
|
34
|
Chris@16
|
35 ///////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
36 // transmogrify
|
Chris@16
|
37 //
|
Chris@16
|
38 template<typename BidiIter, typename ICase, typename Traits, typename Matcher, typename EnableIf = void>
|
Chris@16
|
39 struct default_transmogrify
|
Chris@16
|
40 {
|
Chris@16
|
41 typedef typename Traits::char_type char_type;
|
Chris@16
|
42 typedef typename Traits::string_type string_type;
|
Chris@16
|
43
|
Chris@16
|
44 typedef typename mpl::if_c
|
Chris@16
|
45 <
|
Chris@16
|
46 is_char_literal<Matcher, char_type>::value
|
Chris@16
|
47 , literal_matcher<Traits, ICase, mpl::false_>
|
Chris@16
|
48 , string_matcher<Traits, ICase>
|
Chris@16
|
49 >::type type;
|
Chris@16
|
50
|
Chris@16
|
51 template<typename Matcher2, typename Visitor>
|
Chris@16
|
52 static type call(Matcher2 const &m, Visitor &visitor)
|
Chris@16
|
53 {
|
Chris@16
|
54 return default_transmogrify::call_(m, visitor, is_char_literal<Matcher2, char_type>());
|
Chris@16
|
55 }
|
Chris@16
|
56
|
Chris@16
|
57 template<typename Matcher2, typename Visitor>
|
Chris@16
|
58 static type call_(Matcher2 const &m, Visitor &visitor, mpl::true_)
|
Chris@16
|
59 {
|
Chris@16
|
60 char_type ch = char_cast<char_type>(m, visitor.traits());
|
Chris@16
|
61 return type(ch, visitor.traits());
|
Chris@16
|
62 }
|
Chris@16
|
63
|
Chris@16
|
64 template<typename Matcher2, typename Visitor>
|
Chris@16
|
65 static type call_(Matcher2 const &m, Visitor &visitor, mpl::false_)
|
Chris@16
|
66 {
|
Chris@16
|
67 string_type str = string_cast<string_type>(m, visitor.traits());
|
Chris@16
|
68 return type(str, visitor.traits());
|
Chris@16
|
69 }
|
Chris@16
|
70 };
|
Chris@16
|
71
|
Chris@16
|
72 template<typename BidiIter, typename ICase, typename Traits, typename Matcher>
|
Chris@16
|
73 struct default_transmogrify<BidiIter, ICase, Traits, Matcher, typename Matcher::is_boost_xpressive_xpression_>
|
Chris@16
|
74 {
|
Chris@16
|
75 typedef Matcher type;
|
Chris@16
|
76
|
Chris@16
|
77 template<typename Matcher2>
|
Chris@16
|
78 static Matcher2 const &call(Matcher2 const &m, dont_care)
|
Chris@16
|
79 {
|
Chris@16
|
80 return m;
|
Chris@16
|
81 }
|
Chris@16
|
82 };
|
Chris@16
|
83
|
Chris@16
|
84 template<typename BidiIter, typename ICase, typename Traits, typename Matcher>
|
Chris@16
|
85 struct transmogrify
|
Chris@16
|
86 : default_transmogrify<BidiIter, ICase, Traits, Matcher>
|
Chris@16
|
87 {};
|
Chris@16
|
88
|
Chris@16
|
89 template<typename BidiIter, typename ICase, typename Traits>
|
Chris@16
|
90 struct transmogrify<BidiIter, ICase, Traits, assert_bol_placeholder >
|
Chris@16
|
91 {
|
Chris@16
|
92 typedef assert_bol_matcher<Traits> type;
|
Chris@16
|
93
|
Chris@16
|
94 template<typename Matcher2, typename Visitor>
|
Chris@16
|
95 static type call(Matcher2, Visitor &visitor)
|
Chris@16
|
96 {
|
Chris@16
|
97 return type(visitor.traits());
|
Chris@16
|
98 }
|
Chris@16
|
99 };
|
Chris@16
|
100
|
Chris@16
|
101 template<typename BidiIter, typename ICase, typename Traits>
|
Chris@16
|
102 struct transmogrify<BidiIter, ICase, Traits, assert_eol_placeholder >
|
Chris@16
|
103 {
|
Chris@16
|
104 typedef assert_eol_matcher<Traits> type;
|
Chris@16
|
105
|
Chris@16
|
106 template<typename Matcher2, typename Visitor>
|
Chris@16
|
107 static type call(Matcher2, Visitor &visitor)
|
Chris@16
|
108 {
|
Chris@16
|
109 return type(visitor.traits());
|
Chris@16
|
110 }
|
Chris@16
|
111 };
|
Chris@16
|
112
|
Chris@16
|
113 template<typename BidiIter, typename ICase, typename Traits>
|
Chris@16
|
114 struct transmogrify<BidiIter, ICase, Traits, logical_newline_placeholder >
|
Chris@16
|
115 {
|
Chris@16
|
116 typedef logical_newline_matcher<Traits> type;
|
Chris@16
|
117
|
Chris@16
|
118 template<typename Matcher2, typename Visitor>
|
Chris@16
|
119 static type call(Matcher2, Visitor &visitor)
|
Chris@16
|
120 {
|
Chris@16
|
121 return type(visitor.traits());
|
Chris@16
|
122 }
|
Chris@16
|
123 };
|
Chris@16
|
124
|
Chris@16
|
125 template<typename BidiIter, typename ICase, typename Traits, typename Char>
|
Chris@16
|
126 struct transmogrify<BidiIter, ICase, Traits, range_placeholder<Char> >
|
Chris@16
|
127 {
|
Chris@16
|
128 // By design, we don't widen character ranges.
|
Chris@16
|
129 typedef typename iterator_value<BidiIter>::type char_type;
|
Chris@16
|
130 BOOST_MPL_ASSERT((is_same<Char, char_type>));
|
Chris@16
|
131 typedef range_matcher<Traits, ICase> type;
|
Chris@16
|
132
|
Chris@16
|
133 template<typename Matcher2, typename Visitor>
|
Chris@16
|
134 static type call(Matcher2 const &m, Visitor &visitor)
|
Chris@16
|
135 {
|
Chris@16
|
136 return type(m.ch_min_, m.ch_max_, m.not_, visitor.traits());
|
Chris@16
|
137 }
|
Chris@16
|
138 };
|
Chris@16
|
139
|
Chris@16
|
140 template<typename BidiIter, typename ICase, typename Traits>
|
Chris@16
|
141 struct transmogrify<BidiIter, ICase, Traits, mark_placeholder >
|
Chris@16
|
142 {
|
Chris@16
|
143 typedef mark_matcher<Traits, ICase> type;
|
Chris@16
|
144
|
Chris@16
|
145 template<typename Matcher2, typename Visitor>
|
Chris@16
|
146 static type call(Matcher2 const &m, Visitor &visitor)
|
Chris@16
|
147 {
|
Chris@16
|
148 return type(m.mark_number_, visitor.traits());
|
Chris@16
|
149 }
|
Chris@16
|
150 };
|
Chris@16
|
151
|
Chris@16
|
152 template<typename BidiIter, typename ICase, typename Traits>
|
Chris@16
|
153 struct transmogrify<BidiIter, ICase, Traits, posix_charset_placeholder >
|
Chris@16
|
154 {
|
Chris@16
|
155 typedef posix_charset_matcher<Traits> type;
|
Chris@16
|
156
|
Chris@16
|
157 template<typename Matcher2, typename Visitor>
|
Chris@16
|
158 static type call(Matcher2 const &m, Visitor &visitor)
|
Chris@16
|
159 {
|
Chris@16
|
160 char const *name_end = m.name_ + std::strlen(m.name_);
|
Chris@16
|
161 return type(visitor.traits().lookup_classname(m.name_, name_end, ICase::value), m.not_);
|
Chris@16
|
162 }
|
Chris@16
|
163 };
|
Chris@16
|
164
|
Chris@16
|
165 template<typename BidiIter, typename Traits, typename Size>
|
Chris@16
|
166 struct transmogrify<BidiIter, mpl::true_, Traits, set_matcher<Traits, Size> >
|
Chris@16
|
167 {
|
Chris@16
|
168 typedef set_matcher<Traits, Size> type;
|
Chris@16
|
169
|
Chris@16
|
170 template<typename Matcher2, typename Visitor>
|
Chris@16
|
171 static type call(Matcher2 m, Visitor &visitor)
|
Chris@16
|
172 {
|
Chris@16
|
173 m.nocase(visitor.traits());
|
Chris@16
|
174 return m;
|
Chris@16
|
175 }
|
Chris@16
|
176 };
|
Chris@16
|
177
|
Chris@16
|
178 template<typename BidiIter, typename ICase, typename Traits, typename Cond>
|
Chris@16
|
179 struct transmogrify<BidiIter, ICase, Traits, assert_word_placeholder<Cond> >
|
Chris@16
|
180 {
|
Chris@16
|
181 typedef assert_word_matcher<Cond, Traits> type;
|
Chris@16
|
182
|
Chris@16
|
183 template<typename Visitor>
|
Chris@16
|
184 static type call(dont_care, Visitor &visitor)
|
Chris@16
|
185 {
|
Chris@16
|
186 return type(visitor.traits());
|
Chris@16
|
187 }
|
Chris@16
|
188 };
|
Chris@16
|
189
|
Chris@16
|
190 template<typename BidiIter, typename ICase, typename Traits>
|
Chris@16
|
191 struct transmogrify<BidiIter, ICase, Traits, reference_wrapper<basic_regex<BidiIter> > >
|
Chris@16
|
192 {
|
Chris@16
|
193 typedef regex_byref_matcher<BidiIter> type;
|
Chris@16
|
194
|
Chris@16
|
195 template<typename Matcher2>
|
Chris@16
|
196 static type call(Matcher2 const &m, dont_care)
|
Chris@16
|
197 {
|
Chris@16
|
198 return type(detail::core_access<BidiIter>::get_regex_impl(m.get()));
|
Chris@16
|
199 }
|
Chris@16
|
200 };
|
Chris@16
|
201
|
Chris@16
|
202 template<typename BidiIter, typename ICase, typename Traits>
|
Chris@16
|
203 struct transmogrify<BidiIter, ICase, Traits, reference_wrapper<basic_regex<BidiIter> const> >
|
Chris@16
|
204 {
|
Chris@16
|
205 typedef regex_byref_matcher<BidiIter> type;
|
Chris@16
|
206
|
Chris@16
|
207 template<typename Matcher2>
|
Chris@16
|
208 static type call(Matcher2 const &m, dont_care)
|
Chris@16
|
209 {
|
Chris@16
|
210 return type(detail::core_access<BidiIter>::get_regex_impl(m.get()));
|
Chris@16
|
211 }
|
Chris@16
|
212 };
|
Chris@16
|
213
|
Chris@16
|
214 template<typename BidiIter, typename ICase, typename Traits>
|
Chris@16
|
215 struct transmogrify<BidiIter, ICase, Traits, tracking_ptr<regex_impl<BidiIter> > >
|
Chris@16
|
216 {
|
Chris@16
|
217 typedef regex_matcher<BidiIter> type;
|
Chris@16
|
218
|
Chris@16
|
219 template<typename Matcher2>
|
Chris@16
|
220 static type call(Matcher2 const &m, dont_care)
|
Chris@16
|
221 {
|
Chris@16
|
222 return type(m.get());
|
Chris@16
|
223 }
|
Chris@16
|
224 };
|
Chris@16
|
225
|
Chris@16
|
226 template<typename BidiIter, typename ICase, typename Traits>
|
Chris@16
|
227 struct transmogrify<BidiIter, ICase, Traits, self_placeholder >
|
Chris@16
|
228 {
|
Chris@16
|
229 typedef regex_byref_matcher<BidiIter> type;
|
Chris@16
|
230
|
Chris@16
|
231 template<typename Matcher2, typename Visitor>
|
Chris@16
|
232 static type call(Matcher2, Visitor &visitor)
|
Chris@16
|
233 {
|
Chris@16
|
234 return type(visitor.self());
|
Chris@16
|
235 }
|
Chris@16
|
236 };
|
Chris@16
|
237
|
Chris@16
|
238 }}}
|
Chris@16
|
239
|
Chris@16
|
240 #endif
|