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