1 /*=============================================================================
2     Copyright (c) 2001-2014 Joel de Guzman
3     Copyright (c) 2001-2011 Hartmut Kaiser
4     Copyright (c)      2010 Bryce Lelbach
5 
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
11 
12 #include <string>
13 #include <boost/mpl/bool.hpp>
14 #include <boost/mpl/identity.hpp>
15 
16 namespace boost { namespace spirit { namespace x3 { namespace traits
17 {
18     ///////////////////////////////////////////////////////////////////////////
19     // Determine if T is a character type
20     ///////////////////////////////////////////////////////////////////////////
21     template <typename T>
22     struct is_char : mpl::false_ {};
23 
24     template <typename T>
25     struct is_char<T const> : is_char<T> {};
26 
27     template <>
28     struct is_char<char> : mpl::true_ {};
29 
30     template <>
31     struct is_char<wchar_t> : mpl::true_ {};
32 
33     ///////////////////////////////////////////////////////////////////////////
34     // Determine if T is a string
35     ///////////////////////////////////////////////////////////////////////////
36     template <typename T>
37     struct is_string : mpl::false_ {};
38 
39     template <typename T>
40     struct is_string<T const> : is_string<T> {};
41 
42     template <>
43     struct is_string<char const*> : mpl::true_ {};
44 
45     template <>
46     struct is_string<wchar_t const*> : mpl::true_ {};
47 
48     template <>
49     struct is_string<char*> : mpl::true_ {};
50 
51     template <>
52     struct is_string<wchar_t*> : mpl::true_ {};
53 
54     template <std::size_t N>
55     struct is_string<char[N]> : mpl::true_ {};
56 
57     template <std::size_t N>
58     struct is_string<wchar_t[N]> : mpl::true_ {};
59 
60     template <std::size_t N>
61     struct is_string<char const[N]> : mpl::true_ {};
62 
63     template <std::size_t N>
64     struct is_string<wchar_t const[N]> : mpl::true_ {};
65 
66     template <std::size_t N>
67     struct is_string<char(&)[N]> : mpl::true_ {};
68 
69     template <std::size_t N>
70     struct is_string<wchar_t(&)[N]> : mpl::true_ {};
71 
72     template <std::size_t N>
73     struct is_string<char const(&)[N]> : mpl::true_ {};
74 
75     template <std::size_t N>
76     struct is_string<wchar_t const(&)[N]> : mpl::true_ {};
77 
78     template <typename T, typename Traits, typename Allocator>
79     struct is_string<std::basic_string<T, Traits, Allocator> > : mpl::true_ {};
80 
81     ///////////////////////////////////////////////////////////////////////////
82     // Get the underlying char type of a string
83     ///////////////////////////////////////////////////////////////////////////
84     template <typename T>
85     struct char_type_of;
86 
87     template <typename T>
88     struct char_type_of<T const> : char_type_of<T> {};
89 
90     template <>
91     struct char_type_of<char> : mpl::identity<char> {};
92 
93     template <>
94     struct char_type_of<wchar_t> : mpl::identity<wchar_t> {};
95 
96     template <>
97     struct char_type_of<char const*> : mpl::identity<char const> {};
98 
99     template <>
100     struct char_type_of<wchar_t const*> : mpl::identity<wchar_t const> {};
101 
102     template <>
103     struct char_type_of<char*> : mpl::identity<char> {};
104 
105     template <>
106     struct char_type_of<wchar_t*> : mpl::identity<wchar_t> {};
107 
108     template <std::size_t N>
109     struct char_type_of<char[N]> : mpl::identity<char> {};
110 
111     template <std::size_t N>
112     struct char_type_of<wchar_t[N]> : mpl::identity<wchar_t> {};
113 
114     template <std::size_t N>
115     struct char_type_of<char const[N]> : mpl::identity<char const> {};
116 
117     template <std::size_t N>
118     struct char_type_of<wchar_t const[N]> : mpl::identity<wchar_t const> {};
119 
120     template <std::size_t N>
121     struct char_type_of<char(&)[N]> : mpl::identity<char> {};
122 
123     template <std::size_t N>
124     struct char_type_of<wchar_t(&)[N]> : mpl::identity<wchar_t> {};
125 
126     template <std::size_t N>
127     struct char_type_of<char const(&)[N]> : mpl::identity<char const> {};
128 
129     template <std::size_t N>
130     struct char_type_of<wchar_t const(&)[N]> : mpl::identity<wchar_t const> {};
131 
132     template <typename T, typename Traits, typename Allocator>
133     struct char_type_of<std::basic_string<T, Traits, Allocator> >
134       : mpl::identity<T> {};
135 
136     ///////////////////////////////////////////////////////////////////////////
137     // Get the C string from a string
138     ///////////////////////////////////////////////////////////////////////////
139     template <typename String>
140     struct extract_c_string;
141 
142     template <typename String>
143     struct extract_c_string
144     {
145         typedef typename char_type_of<String>::type char_type;
146 
147         template <typename T>
callboost::spirit::x3::traits::extract_c_string148         static T const* call (T* str)
149         {
150             return (T const*)str;
151         }
152 
153         template <typename T>
callboost::spirit::x3::traits::extract_c_string154         static T const* call (T const* str)
155         {
156             return str;
157         }
158     };
159 
160     // Forwarder that strips const
161     template <typename T>
162     struct extract_c_string<T const>
163     {
164         typedef typename extract_c_string<T>::char_type char_type;
165 
callboost::spirit::x3::traits::extract_c_string166         static typename extract_c_string<T>::char_type const* call (T const str)
167         {
168             return extract_c_string<T>::call(str);
169         }
170     };
171 
172     // Forwarder that strips references
173     template <typename T>
174     struct extract_c_string<T&>
175     {
176         typedef typename extract_c_string<T>::char_type char_type;
177 
callboost::spirit::x3::traits::extract_c_string178         static typename extract_c_string<T>::char_type const* call (T& str)
179         {
180             return extract_c_string<T>::call(str);
181         }
182     };
183 
184     // Forwarder that strips const references
185     template <typename T>
186     struct extract_c_string<T const&>
187     {
188         typedef typename extract_c_string<T>::char_type char_type;
189 
callboost::spirit::x3::traits::extract_c_string190         static typename extract_c_string<T>::char_type const* call (T const& str)
191         {
192             return extract_c_string<T>::call(str);
193         }
194     };
195 
196     template <typename T, typename Traits, typename Allocator>
197     struct extract_c_string<std::basic_string<T, Traits, Allocator> >
198     {
199         typedef T char_type;
200 
201         typedef std::basic_string<T, Traits, Allocator> string;
202 
callboost::spirit::x3::traits::extract_c_string203         static T const* call (string const& str)
204         {
205             return str.c_str();
206         }
207     };
208 
209     template <typename T>
210     typename extract_c_string<T*>::char_type const*
get_c_string(T * str)211     get_c_string(T* str)
212     {
213         return extract_c_string<T*>::call(str);
214     }
215 
216     template <typename T>
217     typename extract_c_string<T const*>::char_type const*
get_c_string(T const * str)218     get_c_string(T const* str)
219     {
220         return extract_c_string<T const*>::call(str);
221     }
222 
223     template <typename String>
224     typename extract_c_string<String>::char_type const*
get_c_string(String & str)225     get_c_string(String& str)
226     {
227         return extract_c_string<String>::call(str);
228     }
229 
230     template <typename String>
231     typename extract_c_string<String>::char_type const*
get_c_string(String const & str)232     get_c_string(String const& str)
233     {
234         return extract_c_string<String>::call(str);
235     }
236 
237     ///////////////////////////////////////////////////////////////////////////
238     // Get the begin/end iterators from a string
239     ///////////////////////////////////////////////////////////////////////////
240 
241     // Implementation for C-style strings.
242 
243     template <typename T>
get_string_begin(T const * str)244     inline T const* get_string_begin(T const* str) { return str; }
245 
246     template <typename T>
get_string_begin(T * str)247     inline T* get_string_begin(T* str) { return str; }
248 
249     template <typename T>
get_string_end(T const * str)250     inline T const* get_string_end(T const* str)
251     {
252         T const* last = str;
253         while (*last)
254             last++;
255         return last;
256     }
257 
258     template <typename T>
get_string_end(T * str)259     inline T* get_string_end(T* str)
260     {
261         T* last = str;
262         while (*last)
263             last++;
264         return last;
265     }
266 
267     // Implementation for containers (includes basic_string).
268     template <typename T, typename Str>
get_string_begin(Str const & str)269     inline typename Str::const_iterator get_string_begin(Str const& str)
270     { return str.begin(); }
271 
272     template <typename T, typename Str>
273     inline typename Str::iterator
get_string_begin(Str & str)274     get_string_begin(Str& str)
275     { return str.begin(); }
276 
277     template <typename T, typename Str>
get_string_end(Str const & str)278     inline typename Str::const_iterator get_string_end(Str const& str)
279     { return str.end(); }
280 
281     template <typename T, typename Str>
282     inline typename Str::iterator
get_string_end(Str & str)283     get_string_end(Str& str)
284     { return str.end(); }
285 }}}}
286 
287 #endif
288