Chris@16
|
1 /*=============================================================================
|
Chris@16
|
2 Copyright (c) 2001-2011 Joel de Guzman
|
Chris@16
|
3 Copyright (c) 2001-2011 Hartmut Kaiser
|
Chris@16
|
4 Copyright (c) 2010 Bryce Lelbach
|
Chris@16
|
5
|
Chris@16
|
6 Distributed under the Boost Software License, Version 1.0. (See accompanying
|
Chris@16
|
7 file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
Chris@16
|
8 ================================================_==============================*/
|
Chris@16
|
9 #if !defined(BOOST_SPIRIT_STRING_TRAITS_OCTOBER_2008_1252PM)
|
Chris@16
|
10 #define BOOST_SPIRIT_STRING_TRAITS_OCTOBER_2008_1252PM
|
Chris@16
|
11
|
Chris@16
|
12 #if defined(_MSC_VER)
|
Chris@16
|
13 #pragma once
|
Chris@16
|
14 #endif
|
Chris@16
|
15
|
Chris@16
|
16 #include <boost/spirit/home/support/container.hpp>
|
Chris@16
|
17 #include <string>
|
Chris@16
|
18 #include <boost/mpl/bool.hpp>
|
Chris@16
|
19 #include <boost/mpl/identity.hpp>
|
Chris@16
|
20 #include <boost/mpl/if.hpp>
|
Chris@16
|
21 #include <boost/proto/proto_fwd.hpp>
|
Chris@16
|
22 #include <boost/type_traits/is_const.hpp>
|
Chris@16
|
23 #if defined(__GNUC__) && (__GNUC__ < 4)
|
Chris@16
|
24 #include <boost/type_traits/add_const.hpp>
|
Chris@16
|
25 #endif
|
Chris@16
|
26
|
Chris@16
|
27 namespace boost { namespace spirit { namespace traits
|
Chris@16
|
28 {
|
Chris@16
|
29 ///////////////////////////////////////////////////////////////////////////
|
Chris@16
|
30 // Determine if T is a character type
|
Chris@16
|
31 ///////////////////////////////////////////////////////////////////////////
|
Chris@16
|
32 template <typename T>
|
Chris@16
|
33 struct is_char : mpl::false_ {};
|
Chris@16
|
34
|
Chris@16
|
35 template <typename T>
|
Chris@16
|
36 struct is_char<T const> : is_char<T> {};
|
Chris@16
|
37
|
Chris@16
|
38 template <>
|
Chris@16
|
39 struct is_char<char> : mpl::true_ {};
|
Chris@16
|
40
|
Chris@16
|
41 template <>
|
Chris@16
|
42 struct is_char<wchar_t> : mpl::true_ {};
|
Chris@16
|
43
|
Chris@16
|
44 ///////////////////////////////////////////////////////////////////////////
|
Chris@16
|
45 // Determine if T is a string
|
Chris@16
|
46 ///////////////////////////////////////////////////////////////////////////
|
Chris@16
|
47 template <typename T>
|
Chris@16
|
48 struct is_string : mpl::false_ {};
|
Chris@16
|
49
|
Chris@16
|
50 template <typename T>
|
Chris@16
|
51 struct is_string<T const> : is_string<T> {};
|
Chris@16
|
52
|
Chris@16
|
53 template <>
|
Chris@16
|
54 struct is_string<char const*> : mpl::true_ {};
|
Chris@16
|
55
|
Chris@16
|
56 template <>
|
Chris@16
|
57 struct is_string<wchar_t const*> : mpl::true_ {};
|
Chris@16
|
58
|
Chris@16
|
59 template <>
|
Chris@16
|
60 struct is_string<char*> : mpl::true_ {};
|
Chris@16
|
61
|
Chris@16
|
62 template <>
|
Chris@16
|
63 struct is_string<wchar_t*> : mpl::true_ {};
|
Chris@16
|
64
|
Chris@16
|
65 template <std::size_t N>
|
Chris@16
|
66 struct is_string<char[N]> : mpl::true_ {};
|
Chris@16
|
67
|
Chris@16
|
68 template <std::size_t N>
|
Chris@16
|
69 struct is_string<wchar_t[N]> : mpl::true_ {};
|
Chris@16
|
70
|
Chris@16
|
71 template <std::size_t N>
|
Chris@16
|
72 struct is_string<char const[N]> : mpl::true_ {};
|
Chris@16
|
73
|
Chris@16
|
74 template <std::size_t N>
|
Chris@16
|
75 struct is_string<wchar_t const[N]> : mpl::true_ {};
|
Chris@16
|
76
|
Chris@16
|
77 template <std::size_t N>
|
Chris@16
|
78 struct is_string<char(&)[N]> : mpl::true_ {};
|
Chris@16
|
79
|
Chris@16
|
80 template <std::size_t N>
|
Chris@16
|
81 struct is_string<wchar_t(&)[N]> : mpl::true_ {};
|
Chris@16
|
82
|
Chris@16
|
83 template <std::size_t N>
|
Chris@16
|
84 struct is_string<char const(&)[N]> : mpl::true_ {};
|
Chris@16
|
85
|
Chris@16
|
86 template <std::size_t N>
|
Chris@16
|
87 struct is_string<wchar_t const(&)[N]> : mpl::true_ {};
|
Chris@16
|
88
|
Chris@16
|
89 template <typename T, typename Traits, typename Allocator>
|
Chris@16
|
90 struct is_string<std::basic_string<T, Traits, Allocator> > : mpl::true_ {};
|
Chris@16
|
91
|
Chris@16
|
92 ///////////////////////////////////////////////////////////////////////////
|
Chris@16
|
93 // Get the underlying char type of a string
|
Chris@16
|
94 ///////////////////////////////////////////////////////////////////////////
|
Chris@16
|
95 template <typename T>
|
Chris@16
|
96 struct char_type_of;
|
Chris@16
|
97
|
Chris@16
|
98 template <typename T>
|
Chris@16
|
99 struct char_type_of<T const> : char_type_of<T> {};
|
Chris@16
|
100
|
Chris@16
|
101 template <>
|
Chris@16
|
102 struct char_type_of<char> : mpl::identity<char> {};
|
Chris@16
|
103
|
Chris@16
|
104 template <>
|
Chris@16
|
105 struct char_type_of<wchar_t> : mpl::identity<wchar_t> {};
|
Chris@16
|
106
|
Chris@16
|
107 template <>
|
Chris@16
|
108 struct char_type_of<char const*> : mpl::identity<char const> {};
|
Chris@16
|
109
|
Chris@16
|
110 template <>
|
Chris@16
|
111 struct char_type_of<wchar_t const*> : mpl::identity<wchar_t const> {};
|
Chris@16
|
112
|
Chris@16
|
113 template <>
|
Chris@16
|
114 struct char_type_of<char*> : mpl::identity<char> {};
|
Chris@16
|
115
|
Chris@16
|
116 template <>
|
Chris@16
|
117 struct char_type_of<wchar_t*> : mpl::identity<wchar_t> {};
|
Chris@16
|
118
|
Chris@16
|
119 template <std::size_t N>
|
Chris@16
|
120 struct char_type_of<char[N]> : mpl::identity<char> {};
|
Chris@16
|
121
|
Chris@16
|
122 template <std::size_t N>
|
Chris@16
|
123 struct char_type_of<wchar_t[N]> : mpl::identity<wchar_t> {};
|
Chris@16
|
124
|
Chris@16
|
125 template <std::size_t N>
|
Chris@16
|
126 struct char_type_of<char const[N]> : mpl::identity<char const> {};
|
Chris@16
|
127
|
Chris@16
|
128 template <std::size_t N>
|
Chris@16
|
129 struct char_type_of<wchar_t const[N]> : mpl::identity<wchar_t const> {};
|
Chris@16
|
130
|
Chris@16
|
131 template <std::size_t N>
|
Chris@16
|
132 struct char_type_of<char(&)[N]> : mpl::identity<char> {};
|
Chris@16
|
133
|
Chris@16
|
134 template <std::size_t N>
|
Chris@16
|
135 struct char_type_of<wchar_t(&)[N]> : mpl::identity<wchar_t> {};
|
Chris@16
|
136
|
Chris@16
|
137 template <std::size_t N>
|
Chris@16
|
138 struct char_type_of<char const(&)[N]> : mpl::identity<char const> {};
|
Chris@16
|
139
|
Chris@16
|
140 template <std::size_t N>
|
Chris@16
|
141 struct char_type_of<wchar_t const(&)[N]> : mpl::identity<wchar_t const> {};
|
Chris@16
|
142
|
Chris@16
|
143 template <typename T, typename Traits, typename Allocator>
|
Chris@16
|
144 struct char_type_of<std::basic_string<T, Traits, Allocator> >
|
Chris@16
|
145 : mpl::identity<T> {};
|
Chris@16
|
146
|
Chris@16
|
147 ///////////////////////////////////////////////////////////////////////////
|
Chris@16
|
148 // Get the C string from a string
|
Chris@16
|
149 ///////////////////////////////////////////////////////////////////////////
|
Chris@16
|
150 template <typename String>
|
Chris@16
|
151 struct extract_c_string;
|
Chris@16
|
152
|
Chris@16
|
153 template <typename String>
|
Chris@16
|
154 struct extract_c_string
|
Chris@16
|
155 {
|
Chris@16
|
156 typedef typename char_type_of<String>::type char_type;
|
Chris@16
|
157
|
Chris@16
|
158 template <typename T>
|
Chris@16
|
159 static T const* call (T* str)
|
Chris@16
|
160 {
|
Chris@16
|
161 return (T const*)str;
|
Chris@16
|
162 }
|
Chris@16
|
163
|
Chris@16
|
164 template <typename T>
|
Chris@16
|
165 static T const* call (T const* str)
|
Chris@16
|
166 {
|
Chris@16
|
167 return str;
|
Chris@16
|
168 }
|
Chris@16
|
169 };
|
Chris@16
|
170
|
Chris@16
|
171 // Forwarder that strips const
|
Chris@16
|
172 template <typename T>
|
Chris@16
|
173 struct extract_c_string<T const>
|
Chris@16
|
174 {
|
Chris@16
|
175 typedef typename extract_c_string<T>::char_type char_type;
|
Chris@16
|
176
|
Chris@16
|
177 static typename extract_c_string<T>::char_type const* call (T const str)
|
Chris@16
|
178 {
|
Chris@16
|
179 return extract_c_string<T>::call(str);
|
Chris@16
|
180 }
|
Chris@16
|
181 };
|
Chris@16
|
182
|
Chris@16
|
183 // Forwarder that strips references
|
Chris@16
|
184 template <typename T>
|
Chris@16
|
185 struct extract_c_string<T&>
|
Chris@16
|
186 {
|
Chris@16
|
187 typedef typename extract_c_string<T>::char_type char_type;
|
Chris@16
|
188
|
Chris@16
|
189 static typename extract_c_string<T>::char_type const* call (T& str)
|
Chris@16
|
190 {
|
Chris@16
|
191 return extract_c_string<T>::call(str);
|
Chris@16
|
192 }
|
Chris@16
|
193 };
|
Chris@16
|
194
|
Chris@16
|
195 // Forwarder that strips const references
|
Chris@16
|
196 template <typename T>
|
Chris@16
|
197 struct extract_c_string<T const&>
|
Chris@16
|
198 {
|
Chris@16
|
199 typedef typename extract_c_string<T>::char_type char_type;
|
Chris@16
|
200
|
Chris@16
|
201 static typename extract_c_string<T>::char_type const* call (T const& str)
|
Chris@16
|
202 {
|
Chris@16
|
203 return extract_c_string<T>::call(str);
|
Chris@16
|
204 }
|
Chris@16
|
205 };
|
Chris@16
|
206
|
Chris@16
|
207 template <typename T, typename Traits, typename Allocator>
|
Chris@16
|
208 struct extract_c_string<std::basic_string<T, Traits, Allocator> >
|
Chris@16
|
209 {
|
Chris@16
|
210 typedef T char_type;
|
Chris@16
|
211
|
Chris@16
|
212 typedef std::basic_string<T, Traits, Allocator> string;
|
Chris@16
|
213
|
Chris@16
|
214 static T const* call (string const& str)
|
Chris@16
|
215 {
|
Chris@16
|
216 return str.c_str();
|
Chris@16
|
217 }
|
Chris@16
|
218 };
|
Chris@16
|
219
|
Chris@16
|
220 template <typename T>
|
Chris@16
|
221 typename extract_c_string<T*>::char_type const*
|
Chris@16
|
222 get_c_string (T* str)
|
Chris@16
|
223 {
|
Chris@16
|
224 return extract_c_string<T*>::call(str);
|
Chris@16
|
225 }
|
Chris@16
|
226
|
Chris@16
|
227 template <typename T>
|
Chris@16
|
228 typename extract_c_string<T const*>::char_type const*
|
Chris@16
|
229 get_c_string (T const* str)
|
Chris@16
|
230 {
|
Chris@16
|
231 return extract_c_string<T const*>::call(str);
|
Chris@16
|
232 }
|
Chris@16
|
233
|
Chris@16
|
234 template <typename String>
|
Chris@16
|
235 typename extract_c_string<String>::char_type const*
|
Chris@16
|
236 get_c_string (String& str)
|
Chris@16
|
237 {
|
Chris@16
|
238 return extract_c_string<String>::call(str);
|
Chris@16
|
239 }
|
Chris@16
|
240
|
Chris@16
|
241 template <typename String>
|
Chris@16
|
242 typename extract_c_string<String>::char_type const*
|
Chris@16
|
243 get_c_string (String const& str)
|
Chris@16
|
244 {
|
Chris@16
|
245 return extract_c_string<String>::call(str);
|
Chris@16
|
246 }
|
Chris@16
|
247
|
Chris@16
|
248 ///////////////////////////////////////////////////////////////////////////
|
Chris@16
|
249 // Get the begin/end iterators from a string
|
Chris@16
|
250 ///////////////////////////////////////////////////////////////////////////
|
Chris@16
|
251
|
Chris@16
|
252 // Implementation for C-style strings.
|
Chris@16
|
253
|
Chris@16
|
254 // gcc 3.x.x has problems resolving ambiguities here
|
Chris@16
|
255 #if defined(__GNUC__) && (__GNUC__ < 4)
|
Chris@16
|
256 template <typename T>
|
Chris@16
|
257 inline typename add_const<T>::type * get_begin(T* str) { return str; }
|
Chris@16
|
258
|
Chris@16
|
259 template <typename T>
|
Chris@16
|
260 inline typename add_const<T>::type* get_end(T* str)
|
Chris@16
|
261 {
|
Chris@16
|
262 T* last = str;
|
Chris@16
|
263 while (*last)
|
Chris@16
|
264 last++;
|
Chris@16
|
265 return last;
|
Chris@16
|
266 }
|
Chris@16
|
267 #else
|
Chris@16
|
268 template <typename T>
|
Chris@16
|
269 inline T const* get_begin(T const* str) { return str; }
|
Chris@16
|
270
|
Chris@16
|
271 template <typename T>
|
Chris@16
|
272 inline T* get_begin(T* str) { return str; }
|
Chris@16
|
273
|
Chris@16
|
274 template <typename T>
|
Chris@16
|
275 inline T const* get_end(T const* str)
|
Chris@16
|
276 {
|
Chris@16
|
277 T const* last = str;
|
Chris@16
|
278 while (*last)
|
Chris@16
|
279 last++;
|
Chris@16
|
280 return last;
|
Chris@16
|
281 }
|
Chris@16
|
282
|
Chris@16
|
283 template <typename T>
|
Chris@16
|
284 inline T* get_end(T* str)
|
Chris@16
|
285 {
|
Chris@16
|
286 T* last = str;
|
Chris@16
|
287 while (*last)
|
Chris@16
|
288 last++;
|
Chris@16
|
289 return last;
|
Chris@16
|
290 }
|
Chris@16
|
291 #endif
|
Chris@16
|
292
|
Chris@16
|
293 // Implementation for containers (includes basic_string).
|
Chris@16
|
294 template <typename T, typename Str>
|
Chris@16
|
295 inline typename Str::const_iterator get_begin(Str const& str)
|
Chris@16
|
296 { return str.begin(); }
|
Chris@16
|
297
|
Chris@16
|
298 template <typename T, typename Str>
|
Chris@16
|
299 inline typename Str::iterator
|
Chris@16
|
300 get_begin(Str& str BOOST_PROTO_DISABLE_IF_IS_CONST(Str))
|
Chris@16
|
301 { return str.begin(); }
|
Chris@16
|
302
|
Chris@16
|
303 template <typename T, typename Str>
|
Chris@16
|
304 inline typename Str::const_iterator get_end(Str const& str)
|
Chris@16
|
305 { return str.end(); }
|
Chris@16
|
306
|
Chris@16
|
307 template <typename T, typename Str>
|
Chris@16
|
308 inline typename Str::iterator
|
Chris@16
|
309 get_end(Str& str BOOST_PROTO_DISABLE_IF_IS_CONST(Str))
|
Chris@16
|
310 { return str.end(); }
|
Chris@16
|
311
|
Chris@16
|
312 // Default implementation for other types: try a C-style string
|
Chris@16
|
313 // conversion.
|
Chris@16
|
314 // These overloads are explicitly disabled for containers,
|
Chris@16
|
315 // as they would be ambiguous with the previous ones.
|
Chris@16
|
316 template <typename T, typename Str>
|
Chris@16
|
317 inline typename disable_if<is_container<Str>
|
Chris@16
|
318 , T const*>::type get_begin(Str const& str)
|
Chris@16
|
319 { return str; }
|
Chris@16
|
320
|
Chris@16
|
321 template <typename T, typename Str>
|
Chris@16
|
322 inline typename disable_if<is_container<Str>
|
Chris@16
|
323 , T const*>::type get_end(Str const& str)
|
Chris@16
|
324 { return get_end(get_begin<T>(str)); }
|
Chris@16
|
325 }
|
Chris@16
|
326
|
Chris@16
|
327 namespace result_of
|
Chris@16
|
328 {
|
Chris@16
|
329 template <typename Char, typename T, typename Enable = void>
|
Chris@16
|
330 struct get_begin
|
Chris@16
|
331 {
|
Chris@16
|
332 typedef typename traits::char_type_of<T>::type char_type;
|
Chris@16
|
333
|
Chris@16
|
334 typedef typename mpl::if_<
|
Chris@16
|
335 is_const<char_type>
|
Chris@16
|
336 , char_type const
|
Chris@16
|
337 , char_type
|
Chris@16
|
338 >::type* type;
|
Chris@16
|
339 };
|
Chris@16
|
340
|
Chris@16
|
341 template <typename Char, typename Str>
|
Chris@16
|
342 struct get_begin<Char, Str
|
Chris@16
|
343 , typename enable_if<traits::is_container<Str> >::type>
|
Chris@16
|
344 {
|
Chris@16
|
345 typedef typename mpl::if_<
|
Chris@16
|
346 is_const<Str>
|
Chris@16
|
347 , typename Str::const_iterator
|
Chris@16
|
348 , typename Str::iterator
|
Chris@16
|
349 >::type type;
|
Chris@16
|
350 };
|
Chris@16
|
351
|
Chris@16
|
352 template <typename Char, typename T>
|
Chris@16
|
353 struct get_end : get_begin<Char, T> {};
|
Chris@16
|
354 }
|
Chris@16
|
355
|
Chris@16
|
356 }}
|
Chris@16
|
357
|
Chris@16
|
358 #endif
|