/*============================================================================= Copyright (c) 2001-2011 Joel de Guzman Copyright (c) 2001-2011 Hartmut Kaiser Copyright (c) 2010 Bryce Lelbach Distributed under the Boost Software License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) ================================================_==============================*/ #if !defined(BOOST_SPIRIT_STRING_TRAITS_OCTOBER_2008_1252PM) #define BOOST_SPIRIT_STRING_TRAITS_OCTOBER_2008_1252PM #if defined(_MSC_VER) #pragma once #endif #include #include #include #include #include #include #include #if defined(__GNUC__) && (__GNUC__ < 4) #include #endif namespace boost { namespace spirit { namespace traits { /////////////////////////////////////////////////////////////////////////// // Determine if T is a character type /////////////////////////////////////////////////////////////////////////// template struct is_char : mpl::false_ {}; template struct is_char : is_char {}; template <> struct is_char : mpl::true_ {}; template <> struct is_char : mpl::true_ {}; /////////////////////////////////////////////////////////////////////////// // Determine if T is a string /////////////////////////////////////////////////////////////////////////// template struct is_string : mpl::false_ {}; template struct is_string : is_string {}; template <> struct is_string : mpl::true_ {}; template <> struct is_string : mpl::true_ {}; template <> struct is_string : mpl::true_ {}; template <> struct is_string : mpl::true_ {}; template struct is_string : mpl::true_ {}; template struct is_string : mpl::true_ {}; template struct is_string : mpl::true_ {}; template struct is_string : mpl::true_ {}; template struct is_string : mpl::true_ {}; template struct is_string : mpl::true_ {}; template struct is_string : mpl::true_ {}; template struct is_string : mpl::true_ {}; template struct is_string > : mpl::true_ {}; /////////////////////////////////////////////////////////////////////////// // Get the underlying char type of a string /////////////////////////////////////////////////////////////////////////// template struct char_type_of; template struct char_type_of : char_type_of {}; template <> struct char_type_of : mpl::identity {}; template <> struct char_type_of : mpl::identity {}; template <> struct char_type_of : mpl::identity {}; template <> struct char_type_of : mpl::identity {}; template <> struct char_type_of : mpl::identity {}; template <> struct char_type_of : mpl::identity {}; template struct char_type_of : mpl::identity {}; template struct char_type_of : mpl::identity {}; template struct char_type_of : mpl::identity {}; template struct char_type_of : mpl::identity {}; template struct char_type_of : mpl::identity {}; template struct char_type_of : mpl::identity {}; template struct char_type_of : mpl::identity {}; template struct char_type_of : mpl::identity {}; template struct char_type_of > : mpl::identity {}; /////////////////////////////////////////////////////////////////////////// // Get the C string from a string /////////////////////////////////////////////////////////////////////////// template struct extract_c_string; template struct extract_c_string { typedef typename char_type_of::type char_type; template static T const* call (T* str) { return (T const*)str; } template static T const* call (T const* str) { return str; } }; // Forwarder that strips const template struct extract_c_string { typedef typename extract_c_string::char_type char_type; static typename extract_c_string::char_type const* call (T const str) { return extract_c_string::call(str); } }; // Forwarder that strips references template struct extract_c_string { typedef typename extract_c_string::char_type char_type; static typename extract_c_string::char_type const* call (T& str) { return extract_c_string::call(str); } }; // Forwarder that strips const references template struct extract_c_string { typedef typename extract_c_string::char_type char_type; static typename extract_c_string::char_type const* call (T const& str) { return extract_c_string::call(str); } }; template struct extract_c_string > { typedef T char_type; typedef std::basic_string string; static T const* call (string const& str) { return str.c_str(); } }; template typename extract_c_string::char_type const* get_c_string (T* str) { return extract_c_string::call(str); } template typename extract_c_string::char_type const* get_c_string (T const* str) { return extract_c_string::call(str); } template typename extract_c_string::char_type const* get_c_string (String& str) { return extract_c_string::call(str); } template typename extract_c_string::char_type const* get_c_string (String const& str) { return extract_c_string::call(str); } /////////////////////////////////////////////////////////////////////////// // Get the begin/end iterators from a string /////////////////////////////////////////////////////////////////////////// // Implementation for C-style strings. // gcc 3.x.x has problems resolving ambiguities here #if defined(__GNUC__) && (__GNUC__ < 4) template inline typename add_const::type * get_begin(T* str) { return str; } template inline typename add_const::type* get_end(T* str) { T* last = str; while (*last) last++; return last; } #else template inline T const* get_begin(T const* str) { return str; } template inline T* get_begin(T* str) { return str; } template inline T const* get_end(T const* str) { T const* last = str; while (*last) last++; return last; } template inline T* get_end(T* str) { T* last = str; while (*last) last++; return last; } #endif // Implementation for containers (includes basic_string). template inline typename Str::const_iterator get_begin(Str const& str) { return str.begin(); } template inline typename Str::iterator get_begin(Str& str BOOST_PROTO_DISABLE_IF_IS_CONST(Str)) { return str.begin(); } template inline typename Str::const_iterator get_end(Str const& str) { return str.end(); } template inline typename Str::iterator get_end(Str& str BOOST_PROTO_DISABLE_IF_IS_CONST(Str)) { return str.end(); } // Default implementation for other types: try a C-style string // conversion. // These overloads are explicitly disabled for containers, // as they would be ambiguous with the previous ones. template inline typename disable_if , T const*>::type get_begin(Str const& str) { return str; } template inline typename disable_if , T const*>::type get_end(Str const& str) { return get_end(get_begin(str)); } } namespace result_of { template struct get_begin { typedef typename traits::char_type_of::type char_type; typedef typename mpl::if_< is_const , char_type const , char_type >::type* type; }; template struct get_begin >::type> { typedef typename mpl::if_< is_const , typename Str::const_iterator , typename Str::iterator >::type type; }; template struct get_end : get_begin {}; } }} #endif