1 /*=============================================================================
2 Copyright (c) 2001-2014 Joel de Guzman
3 Copyright (c) 2001-2011 Hartmut Kaiser
4 Copyright (c) 2010 Bryce Lelbach
6 Distributed under the Boost Software License, Version 1.0. (See accompanying
7 file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
8 ================================================_==============================*/
9 #if !defined(BOOST_SPIRIT_X3_STRING_TRAITS_OCTOBER_2008_1252PM)
10 #define BOOST_SPIRIT_X3_STRING_TRAITS_OCTOBER_2008_1252PM
13 #include <boost/mpl/bool.hpp>
14 #include <boost/mpl/identity.hpp>
16 namespace boost { namespace spirit { namespace x3 { namespace traits
18 ///////////////////////////////////////////////////////////////////////////
19 // Determine if T is a character type
20 ///////////////////////////////////////////////////////////////////////////
22 struct is_char : mpl::false_ {};
25 struct is_char<T const> : is_char<T> {};
28 struct is_char<char> : mpl::true_ {};
31 struct is_char<wchar_t> : mpl::true_ {};
33 ///////////////////////////////////////////////////////////////////////////
34 // Determine if T is a string
35 ///////////////////////////////////////////////////////////////////////////
37 struct is_string : mpl::false_ {};
40 struct is_string<T const> : is_string<T> {};
43 struct is_string<char const*> : mpl::true_ {};
46 struct is_string<wchar_t const*> : mpl::true_ {};
49 struct is_string<char*> : mpl::true_ {};
52 struct is_string<wchar_t*> : mpl::true_ {};
54 template <std::size_t N>
55 struct is_string<char[N]> : mpl::true_ {};
57 template <std::size_t N>
58 struct is_string<wchar_t[N]> : mpl::true_ {};
60 template <std::size_t N>
61 struct is_string<char const[N]> : mpl::true_ {};
63 template <std::size_t N>
64 struct is_string<wchar_t const[N]> : mpl::true_ {};
66 template <std::size_t N>
67 struct is_string<char(&)[N]> : mpl::true_ {};
69 template <std::size_t N>
70 struct is_string<wchar_t(&)[N]> : mpl::true_ {};
72 template <std::size_t N>
73 struct is_string<char const(&)[N]> : mpl::true_ {};
75 template <std::size_t N>
76 struct is_string<wchar_t const(&)[N]> : mpl::true_ {};
78 template <typename T, typename Traits, typename Allocator>
79 struct is_string<std::basic_string<T, Traits, Allocator> > : mpl::true_ {};
81 ///////////////////////////////////////////////////////////////////////////
82 // Get the underlying char type of a string
83 ///////////////////////////////////////////////////////////////////////////
88 struct char_type_of<T const> : char_type_of<T> {};
91 struct char_type_of<char> : mpl::identity<char> {};
94 struct char_type_of<wchar_t> : mpl::identity<wchar_t> {};
97 struct char_type_of<char const*> : mpl::identity<char const> {};
100 struct char_type_of<wchar_t const*> : mpl::identity<wchar_t const> {};
103 struct char_type_of<char*> : mpl::identity<char> {};
106 struct char_type_of<wchar_t*> : mpl::identity<wchar_t> {};
108 template <std::size_t N>
109 struct char_type_of<char[N]> : mpl::identity<char> {};
111 template <std::size_t N>
112 struct char_type_of<wchar_t[N]> : mpl::identity<wchar_t> {};
114 template <std::size_t N>
115 struct char_type_of<char const[N]> : mpl::identity<char const> {};
117 template <std::size_t N>
118 struct char_type_of<wchar_t const[N]> : mpl::identity<wchar_t const> {};
120 template <std::size_t N>
121 struct char_type_of<char(&)[N]> : mpl::identity<char> {};
123 template <std::size_t N>
124 struct char_type_of<wchar_t(&)[N]> : mpl::identity<wchar_t> {};
126 template <std::size_t N>
127 struct char_type_of<char const(&)[N]> : mpl::identity<char const> {};
129 template <std::size_t N>
130 struct char_type_of<wchar_t const(&)[N]> : mpl::identity<wchar_t const> {};
132 template <typename T, typename Traits, typename Allocator>
133 struct char_type_of<std::basic_string<T, Traits, Allocator> >
134 : mpl::identity<T> {};
136 ///////////////////////////////////////////////////////////////////////////
137 // Get the C string from a string
138 ///////////////////////////////////////////////////////////////////////////
139 template <typename String>
140 struct extract_c_string;
142 template <typename String>
143 struct extract_c_string
145 typedef typename char_type_of<String>::type char_type;
147 template <typename T>
148 static T const* call (T* str)
150 return (T const*)str;
153 template <typename T>
154 static T const* call (T const* str)
160 // Forwarder that strips const
161 template <typename T>
162 struct extract_c_string<T const>
164 typedef typename extract_c_string<T>::char_type char_type;
166 static typename extract_c_string<T>::char_type const* call (T const str)
168 return extract_c_string<T>::call(str);
172 // Forwarder that strips references
173 template <typename T>
174 struct extract_c_string<T&>
176 typedef typename extract_c_string<T>::char_type char_type;
178 static typename extract_c_string<T>::char_type const* call (T& str)
180 return extract_c_string<T>::call(str);
184 // Forwarder that strips const references
185 template <typename T>
186 struct extract_c_string<T const&>
188 typedef typename extract_c_string<T>::char_type char_type;
190 static typename extract_c_string<T>::char_type const* call (T const& str)
192 return extract_c_string<T>::call(str);
196 template <typename T, typename Traits, typename Allocator>
197 struct extract_c_string<std::basic_string<T, Traits, Allocator> >
201 typedef std::basic_string<T, Traits, Allocator> string;
203 static T const* call (string const& str)
209 template <typename T>
210 typename extract_c_string<T*>::char_type const*
213 return extract_c_string<T*>::call(str);
216 template <typename T>
217 typename extract_c_string<T const*>::char_type const*
218 get_c_string(T const* str)
220 return extract_c_string<T const*>::call(str);
223 template <typename String>
224 typename extract_c_string<String>::char_type const*
225 get_c_string(String& str)
227 return extract_c_string<String>::call(str);
230 template <typename String>
231 typename extract_c_string<String>::char_type const*
232 get_c_string(String const& str)
234 return extract_c_string<String>::call(str);
237 ///////////////////////////////////////////////////////////////////////////
238 // Get the begin/end iterators from a string
239 ///////////////////////////////////////////////////////////////////////////
241 // Implementation for C-style strings.
243 template <typename T>
244 inline T const* get_string_begin(T const* str) { return str; }
246 template <typename T>
247 inline T* get_string_begin(T* str) { return str; }
249 template <typename T>
250 inline T const* get_string_end(T const* str)
258 template <typename T>
259 inline T* get_string_end(T* str)
267 // Implementation for containers (includes basic_string).
268 template <typename T, typename Str>
269 inline typename Str::const_iterator get_string_begin(Str const& str)
270 { return str.begin(); }
272 template <typename T, typename Str>
273 inline typename Str::iterator
274 get_string_begin(Str& str)
275 { return str.begin(); }
277 template <typename T, typename Str>
278 inline typename Str::const_iterator get_string_end(Str const& str)
279 { return str.end(); }
281 template <typename T, typename Str>
282 inline typename Str::iterator
283 get_string_end(Str& str)
284 { return str.end(); }