Back to home page

EIC code displayed by LXR

 
 

    


Warning, file /include/boost/spirit/home/support/string_traits.hpp was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).

0001 /*=============================================================================
0002     Copyright (c) 2001-2011 Joel de Guzman
0003     Copyright (c) 2001-2011 Hartmut Kaiser
0004     Copyright (c)      2010 Bryce Lelbach
0005 
0006     Distributed under the Boost Software License, Version 1.0. (See accompanying
0007     file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
0008 ================================================_==============================*/
0009 #if !defined(BOOST_SPIRIT_STRING_TRAITS_OCTOBER_2008_1252PM)
0010 #define BOOST_SPIRIT_STRING_TRAITS_OCTOBER_2008_1252PM
0011 
0012 #if defined(_MSC_VER)
0013 #pragma once
0014 #endif
0015 
0016 #include <boost/spirit/home/support/container.hpp>
0017 #include <string>
0018 #include <boost/mpl/bool.hpp>
0019 #include <boost/mpl/identity.hpp>
0020 #include <boost/mpl/if.hpp>
0021 #include <boost/proto/proto_fwd.hpp> // for BOOST_PROTO_DISABLE_IF_IS_CONST
0022 #include <boost/type_traits/is_const.hpp>
0023 #if defined(__GNUC__) && (__GNUC__ < 4)
0024 #include <boost/type_traits/add_const.hpp>
0025 #endif
0026 
0027 namespace boost { namespace spirit { namespace traits
0028 {
0029     ///////////////////////////////////////////////////////////////////////////
0030     // Determine if T is a character type
0031     ///////////////////////////////////////////////////////////////////////////
0032     template <typename T>
0033     struct is_char : mpl::false_ {};
0034 
0035     template <typename T>
0036     struct is_char<T const> : is_char<T> {};
0037 
0038     template <>
0039     struct is_char<char> : mpl::true_ {};
0040 
0041     template <>
0042     struct is_char<wchar_t> : mpl::true_ {};
0043 
0044     ///////////////////////////////////////////////////////////////////////////
0045     // Determine if T is a string
0046     ///////////////////////////////////////////////////////////////////////////
0047     template <typename T>
0048     struct is_string : mpl::false_ {};
0049 
0050     template <typename T>
0051     struct is_string<T const> : is_string<T> {};
0052 
0053     template <>
0054     struct is_string<char const*> : mpl::true_ {};
0055 
0056     template <>
0057     struct is_string<wchar_t const*> : mpl::true_ {};
0058 
0059     template <>
0060     struct is_string<char*> : mpl::true_ {};
0061 
0062     template <>
0063     struct is_string<wchar_t*> : mpl::true_ {};
0064 
0065     template <std::size_t N>
0066     struct is_string<char[N]> : mpl::true_ {};
0067 
0068     template <std::size_t N>
0069     struct is_string<wchar_t[N]> : mpl::true_ {};
0070 
0071     template <std::size_t N>
0072     struct is_string<char const[N]> : mpl::true_ {};
0073 
0074     template <std::size_t N>
0075     struct is_string<wchar_t const[N]> : mpl::true_ {};
0076 
0077     template <std::size_t N>
0078     struct is_string<char(&)[N]> : mpl::true_ {};
0079 
0080     template <std::size_t N>
0081     struct is_string<wchar_t(&)[N]> : mpl::true_ {};
0082 
0083     template <std::size_t N>
0084     struct is_string<char const(&)[N]> : mpl::true_ {};
0085 
0086     template <std::size_t N>
0087     struct is_string<wchar_t const(&)[N]> : mpl::true_ {};
0088 
0089     template <typename T, typename Traits, typename Allocator>
0090     struct is_string<std::basic_string<T, Traits, Allocator> > : mpl::true_ {};
0091 
0092     ///////////////////////////////////////////////////////////////////////////
0093     // Get the underlying char type of a string
0094     ///////////////////////////////////////////////////////////////////////////
0095     template <typename T>
0096     struct char_type_of;
0097 
0098     template <typename T>
0099     struct char_type_of<T const> : char_type_of<T> {};
0100 
0101     template <>
0102     struct char_type_of<char> : mpl::identity<char> {};
0103 
0104     template <>
0105     struct char_type_of<wchar_t> : mpl::identity<wchar_t> {};
0106 
0107     template <>
0108     struct char_type_of<char const*> : mpl::identity<char const> {};
0109 
0110     template <>
0111     struct char_type_of<wchar_t const*> : mpl::identity<wchar_t const> {};
0112 
0113     template <>
0114     struct char_type_of<char*> : mpl::identity<char> {};
0115 
0116     template <>
0117     struct char_type_of<wchar_t*> : mpl::identity<wchar_t> {};
0118 
0119     template <std::size_t N>
0120     struct char_type_of<char[N]> : mpl::identity<char> {};
0121 
0122     template <std::size_t N>
0123     struct char_type_of<wchar_t[N]> : mpl::identity<wchar_t> {};
0124 
0125     template <std::size_t N>
0126     struct char_type_of<char const[N]> : mpl::identity<char const> {};
0127 
0128     template <std::size_t N>
0129     struct char_type_of<wchar_t const[N]> : mpl::identity<wchar_t const> {};
0130 
0131     template <std::size_t N>
0132     struct char_type_of<char(&)[N]> : mpl::identity<char> {};
0133 
0134     template <std::size_t N>
0135     struct char_type_of<wchar_t(&)[N]> : mpl::identity<wchar_t> {};
0136 
0137     template <std::size_t N>
0138     struct char_type_of<char const(&)[N]> : mpl::identity<char const> {};
0139 
0140     template <std::size_t N>
0141     struct char_type_of<wchar_t const(&)[N]> : mpl::identity<wchar_t const> {};
0142 
0143     template <typename T, typename Traits, typename Allocator>
0144     struct char_type_of<std::basic_string<T, Traits, Allocator> >
0145       : mpl::identity<T> {};
0146 
0147     ///////////////////////////////////////////////////////////////////////////
0148     // Get the C string from a string
0149     ///////////////////////////////////////////////////////////////////////////
0150     template <typename String>
0151     struct extract_c_string;
0152 
0153     template <typename String>
0154     struct extract_c_string
0155     {
0156         typedef typename char_type_of<String>::type char_type;
0157 
0158         template <typename T>
0159         static T const* call (T* str)
0160         {
0161             return (T const*)str; 
0162         }
0163 
0164         template <typename T>
0165         static T const* call (T const* str)
0166         {
0167             return str; 
0168         }
0169     }; 
0170     
0171     // Forwarder that strips const
0172     template <typename T>
0173     struct extract_c_string<T const>
0174     {
0175         typedef typename extract_c_string<T>::char_type char_type;
0176 
0177         static typename extract_c_string<T>::char_type const* call (T const str)
0178         {
0179             return extract_c_string<T>::call(str);
0180         }
0181     };
0182 
0183     // Forwarder that strips references
0184     template <typename T>
0185     struct extract_c_string<T&>
0186     {
0187         typedef typename extract_c_string<T>::char_type char_type;
0188 
0189         static typename extract_c_string<T>::char_type const* call (T& str)
0190         {
0191             return extract_c_string<T>::call(str);
0192         }
0193     };
0194 
0195     // Forwarder that strips const references
0196     template <typename T>
0197     struct extract_c_string<T const&>
0198     {
0199         typedef typename extract_c_string<T>::char_type char_type;
0200 
0201         static typename extract_c_string<T>::char_type const* call (T const& str)
0202         {
0203             return extract_c_string<T>::call(str);
0204         }
0205     };
0206 
0207     template <typename T, typename Traits, typename Allocator>
0208     struct extract_c_string<std::basic_string<T, Traits, Allocator> >
0209     {
0210         typedef T char_type;
0211 
0212         typedef std::basic_string<T, Traits, Allocator> string;
0213 
0214         static T const* call (string const& str)
0215         {
0216             return str.c_str();
0217         }
0218     };
0219     
0220     template <typename T>
0221     typename extract_c_string<T*>::char_type const*
0222     get_c_string (T* str)
0223     {
0224         return extract_c_string<T*>::call(str);
0225     }
0226 
0227     template <typename T>
0228     typename extract_c_string<T const*>::char_type const*
0229     get_c_string (T const* str)
0230     {
0231         return extract_c_string<T const*>::call(str);
0232     }
0233     
0234     template <typename String>
0235     typename extract_c_string<String>::char_type const*
0236     get_c_string (String& str)
0237     {
0238         return extract_c_string<String>::call(str);
0239     }
0240 
0241     template <typename String>
0242     typename extract_c_string<String>::char_type const*
0243     get_c_string (String const& str)
0244     {
0245         return extract_c_string<String>::call(str);
0246     }
0247 
0248     ///////////////////////////////////////////////////////////////////////////
0249     // Get the begin/end iterators from a string
0250     ///////////////////////////////////////////////////////////////////////////
0251 
0252     // Implementation for C-style strings.
0253 
0254 // gcc 3.x.x has problems resolving ambiguities here
0255 #if defined(__GNUC__) && (__GNUC__ < 4)
0256     template <typename T>
0257     inline typename add_const<T>::type * get_begin(T* str) { return str; }
0258 
0259     template <typename T>
0260     inline typename add_const<T>::type* get_end(T* str)
0261     {
0262         T* last = str;
0263         while (*last)
0264             last++;
0265         return last;
0266     }
0267 #else
0268     template <typename T>
0269     inline T const* get_begin(T const* str) { return str; }
0270 
0271     template <typename T>
0272     inline T* get_begin(T* str) { return str; }
0273 
0274     template <typename T>
0275     inline T const* get_end(T const* str)
0276     {
0277         T const* last = str;
0278         while (*last)
0279             last++;
0280         return last;
0281     }
0282 
0283     template <typename T>
0284     inline T* get_end(T* str)
0285     {
0286         T* last = str;
0287         while (*last)
0288             last++;
0289         return last;
0290     }
0291 #endif
0292 
0293     // Implementation for containers (includes basic_string).
0294     template <typename T, typename Str>
0295     inline typename Str::const_iterator get_begin(Str const& str)
0296     { return str.begin(); }
0297 
0298     template <typename T, typename Str>
0299     inline typename Str::iterator
0300     get_begin(Str& str BOOST_PROTO_DISABLE_IF_IS_CONST(Str))
0301     { return str.begin(); }
0302 
0303     template <typename T, typename Str>
0304     inline typename Str::const_iterator get_end(Str const& str)
0305     { return str.end(); }
0306 
0307     template <typename T, typename Str>
0308     inline typename Str::iterator
0309     get_end(Str& str BOOST_PROTO_DISABLE_IF_IS_CONST(Str))
0310     { return str.end(); }
0311 
0312     // Default implementation for other types: try a C-style string
0313     // conversion.
0314     // These overloads are explicitly disabled for containers,
0315     // as they would be ambiguous with the previous ones.
0316     template <typename T, typename Str>
0317     inline typename disable_if<is_container<Str>
0318       , T const*>::type get_begin(Str const& str)
0319     { return str; }
0320 
0321     template <typename T, typename Str>
0322     inline typename disable_if<is_container<Str>
0323       , T const*>::type get_end(Str const& str)
0324     { return get_end(get_begin<T>(str)); }
0325 }
0326 
0327 namespace result_of
0328 {
0329     template <typename Char, typename T, typename Enable = void>
0330     struct get_begin
0331     {
0332         typedef typename traits::char_type_of<T>::type char_type;
0333 
0334         typedef typename mpl::if_<
0335             is_const<char_type>
0336           , char_type const 
0337           , char_type
0338         >::type* type;
0339     };
0340 
0341     template <typename Char, typename Str>
0342     struct get_begin<Char, Str
0343       , typename enable_if<traits::is_container<Str> >::type>
0344     {
0345         typedef typename mpl::if_<
0346             is_const<Str>
0347           , typename Str::const_iterator
0348           , typename Str::iterator
0349         >::type type;
0350     };
0351 
0352     template <typename Char, typename T>
0353     struct get_end : get_begin<Char, T> {};
0354 }
0355 
0356 }}
0357 
0358 #endif