PageRenderTime 62ms CodeModel.GetById 36ms app.highlight 21ms RepoModel.GetById 1ms app.codeStats 1ms

/Src/Dependencies/Boost/boost/spirit/home/support/string_traits.hpp

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