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