1 // Character Traits for use by standard string and iostream -*- C++ -*- 2 3 // Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 4 // 2006, 2007, 2008, 2009, 2010 5 // Free Software Foundation, Inc. 6 // 7 // This file is part of the GNU ISO C++ Library. This library is free 8 // software; you can redistribute it and/or modify it under the 9 // terms of the GNU General Public License as published by the 10 // Free Software Foundation; either version 3, or (at your option) 11 // any later version. 12 13 // This library is distributed in the hope that it will be useful, 14 // but WITHOUT ANY WARRANTY; without even the implied warranty of 15 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 // GNU General Public License for more details. 17 18 // Under Section 7 of GPL version 3, you are granted additional 19 // permissions described in the GCC Runtime Library Exception, version 20 // 3.1, as published by the Free Software Foundation. 21 22 // You should have received a copy of the GNU General Public License and 23 // a copy of the GCC Runtime Library Exception along with this program; 24 // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 25 // <http://www.gnu.org/licenses/>. 26 27 /** @file bits/char_traits.h 28 * This is an internal header file, included by other library headers. 29 * Do not attempt to use it directly. @headername{string} 30 */ 31 32 // 33 // ISO C++ 14882: 21 Strings library 34 // 35 36 #ifndef _CHAR_TRAITS_H 37 #define _CHAR_TRAITS_H 1 38 39 #pragma GCC system_header 40 41 #include <bits/stl_algobase.h> // std::copy, std::fill_n 42 #include <bits/postypes.h> // For streampos 43 #include <cwchar> // For WEOF, wmemmove, wmemset, etc. 44 45 namespace __gnu_cxx _GLIBCXX_VISIBILITY(default) 46 { 47 _GLIBCXX_BEGIN_NAMESPACE_VERSION 48 49 /** 50 * @brief Mapping from character type to associated types. 51 * 52 * @note This is an implementation class for the generic version 53 * of char_traits. It defines int_type, off_type, pos_type, and 54 * state_type. By default these are unsigned long, streamoff, 55 * streampos, and mbstate_t. Users who need a different set of 56 * types, but who don't need to change the definitions of any function 57 * defined in char_traits, can specialize __gnu_cxx::_Char_types 58 * while leaving __gnu_cxx::char_traits alone. */ 59 template<typename _CharT> 60 struct _Char_types 61 { 62 typedef unsigned long int_type; 63 typedef std::streampos pos_type; 64 typedef std::streamoff off_type; 65 typedef std::mbstate_t state_type; 66 }; 67 68 69 /** 70 * @brief Base class used to implement std::char_traits. 71 * 72 * @note For any given actual character type, this definition is 73 * probably wrong. (Most of the member functions are likely to be 74 * right, but the int_type and state_type typedefs, and the eof() 75 * member function, are likely to be wrong.) The reason this class 76 * exists is so users can specialize it. Classes in namespace std 77 * may not be specialized for fundamental types, but classes in 78 * namespace __gnu_cxx may be. 79 * 80 * See http://gcc.gnu.org/onlinedocs/libstdc++/manual/bk01pt05ch13s03.html 81 * for advice on how to make use of this class for @a unusual character 82 * types. Also, check out include/ext/pod_char_traits.h. 83 */ 84 template<typename _CharT> 85 struct char_traits 86 { 87 typedef _CharT char_type; 88 typedef typename _Char_types<_CharT>::int_type int_type; 89 typedef typename _Char_types<_CharT>::pos_type pos_type; 90 typedef typename _Char_types<_CharT>::off_type off_type; 91 typedef typename _Char_types<_CharT>::state_type state_type; 92 93 static void 94 assign(char_type& __c1, const char_type& __c2) 95 { __c1 = __c2; } 96 97 static _GLIBCXX_CONSTEXPR bool 98 eq(const char_type& __c1, const char_type& __c2) 99 { return __c1 == __c2; } 100 101 static _GLIBCXX_CONSTEXPR bool 102 lt(const char_type& __c1, const char_type& __c2) 103 { return __c1 < __c2; } 104 105 static int 106 compare(const char_type* __s1, const char_type* __s2, std::size_t __n); 107 108 static std::size_t 109 length(const char_type* __s); 110 111 static const char_type* 112 find(const char_type* __s, std::size_t __n, const char_type& __a); 113 114 static char_type* 115 move(char_type* __s1, const char_type* __s2, std::size_t __n); 116 117 static char_type* 118 copy(char_type* __s1, const char_type* __s2, std::size_t __n); 119 120 static char_type* 121 assign(char_type* __s, std::size_t __n, char_type __a); 122 123 static _GLIBCXX_CONSTEXPR char_type 124 to_char_type(const int_type& __c) 125 { return static_cast<char_type>(__c); } 126 127 static _GLIBCXX_CONSTEXPR int_type 128 to_int_type(const char_type& __c) 129 { return static_cast<int_type>(__c); } 130 131 static _GLIBCXX_CONSTEXPR bool 132 eq_int_type(const int_type& __c1, const int_type& __c2) 133 { return __c1 == __c2; } 134 135 static _GLIBCXX_CONSTEXPR int_type 136 eof() 137 { return static_cast<int_type>(_GLIBCXX_STDIO_EOF); } 138 139 static _GLIBCXX_CONSTEXPR int_type 140 not_eof(const int_type& __c) 141 { return !eq_int_type(__c, eof()) ? __c : to_int_type(char_type()); } 142 }; 143 144 template<typename _CharT> 145 int 146 char_traits<_CharT>:: 147 compare(const char_type* __s1, const char_type* __s2, std::size_t __n) 148 { 149 for (std::size_t __i = 0; __i < __n; ++__i) 150 if (lt(__s1[__i], __s2[__i])) 151 return -1; 152 else if (lt(__s2[__i], __s1[__i])) 153 return 1; 154 return 0; 155 } 156 157 template<typename _CharT> 158 std::size_t 159 char_traits<_CharT>:: 160 length(const char_type* __p) 161 { 162 std::size_t __i = 0; 163 while (!eq(__p[__i], char_type())) 164 ++__i; 165 return __i; 166 } 167 168 template<typename _CharT> 169 const typename char_traits<_CharT>::char_type* 170 char_traits<_CharT>:: 171 find(const char_type* __s, std::size_t __n, const char_type& __a) 172 { 173 for (std::size_t __i = 0; __i < __n; ++__i) 174 if (eq(__s[__i], __a)) 175 return __s + __i; 176 return 0; 177 } 178 179 template<typename _CharT> 180 typename char_traits<_CharT>::char_type* 181 char_traits<_CharT>:: 182 move(char_type* __s1, const char_type* __s2, std::size_t __n) 183 { 184 return static_cast<_CharT*>(__builtin_memmove(__s1, __s2, 185 __n * sizeof(char_type))); 186 } 187 188 template<typename _CharT> 189 typename char_traits<_CharT>::char_type* 190 char_traits<_CharT>:: 191 copy(char_type* __s1, const char_type* __s2, std::size_t __n) 192 { 193 // NB: Inline std::copy so no recursive dependencies. 194 std::copy(__s2, __s2 + __n, __s1); 195 return __s1; 196 } 197 198 template<typename _CharT> 199 typename char_traits<_CharT>::char_type* 200 char_traits<_CharT>:: 201 assign(char_type* __s, std::size_t __n, char_type __a) 202 { 203 // NB: Inline std::fill_n so no recursive dependencies. 204 std::fill_n(__s, __n, __a); 205 return __s; 206 } 207 208 _GLIBCXX_END_NAMESPACE_VERSION 209 } // namespace 210 211 namespace std _GLIBCXX_VISIBILITY(default) 212 { 213 _GLIBCXX_BEGIN_NAMESPACE_VERSION 214 215 // 21.1 216 /** 217 * @brief Basis for explicit traits specializations. 218 * 219 * @note For any given actual character type, this definition is 220 * probably wrong. Since this is just a thin wrapper around 221 * __gnu_cxx::char_traits, it is possible to achieve a more 222 * appropriate definition by specializing __gnu_cxx::char_traits. 223 * 224 * See http://gcc.gnu.org/onlinedocs/libstdc++/manual/bk01pt05ch13s03.html 225 * for advice on how to make use of this class for @a unusual character 226 * types. Also, check out include/ext/pod_char_traits.h. 227 */ 228 template<class _CharT> 229 struct char_traits : public __gnu_cxx::char_traits<_CharT> 230 { }; 231 232 233 /// 21.1.3.1 char_traits specializations 234 template<> 235 struct char_traits<char> 236 { 237 typedef char char_type; 238 typedef int int_type; 239 typedef streampos pos_type; 240 typedef streamoff off_type; 241 typedef mbstate_t state_type; 242 243 static void 244 assign(char_type& __c1, const char_type& __c2) 245 { __c1 = __c2; } 246 247 static _GLIBCXX_CONSTEXPR bool 248 eq(const char_type& __c1, const char_type& __c2) 249 { return __c1 == __c2; } 250 251 static _GLIBCXX_CONSTEXPR bool 252 lt(const char_type& __c1, const char_type& __c2) 253 { return __c1 < __c2; } 254 255 static int 256 compare(const char_type* __s1, const char_type* __s2, size_t __n) 257 { return __builtin_memcmp(__s1, __s2, __n); } 258 259 static size_t 260 length(const char_type* __s) 261 { return __builtin_strlen(__s); } 262 263 static const char_type* 264 find(const char_type* __s, size_t __n, const char_type& __a) 265 { return static_cast<const char_type*>(__builtin_memchr(__s, __a, __n)); } 266 267 static char_type* 268 move(char_type* __s1, const char_type* __s2, size_t __n) 269 { return static_cast<char_type*>(__builtin_memmove(__s1, __s2, __n)); } 270 271 static char_type* 272 copy(char_type* __s1, const char_type* __s2, size_t __n) 273 { return static_cast<char_type*>(__builtin_memcpy(__s1, __s2, __n)); } 274 275 static char_type* 276 assign(char_type* __s, size_t __n, char_type __a) 277 { return static_cast<char_type*>(__builtin_memset(__s, __a, __n)); } 278 279 static _GLIBCXX_CONSTEXPR char_type 280 to_char_type(const int_type& __c) 281 { return static_cast<char_type>(__c); } 282 283 // To keep both the byte 0xff and the eof symbol 0xffffffff 284 // from ending up as 0xffffffff. 285 static _GLIBCXX_CONSTEXPR int_type 286 to_int_type(const char_type& __c) 287 { return static_cast<int_type>(static_cast<unsigned char>(__c)); } 288 289 static _GLIBCXX_CONSTEXPR bool 290 eq_int_type(const int_type& __c1, const int_type& __c2) 291 { return __c1 == __c2; } 292 293 static _GLIBCXX_CONSTEXPR int_type 294 eof() 295 { return static_cast<int_type>(_GLIBCXX_STDIO_EOF); } 296 297 static _GLIBCXX_CONSTEXPR int_type 298 not_eof(const int_type& __c) 299 { return (__c == eof()) ? 0 : __c; } 300 }; 301 302 303 #ifdef _GLIBCXX_USE_WCHAR_T 304 /// 21.1.3.2 char_traits specializations 305 template<> 306 struct char_traits<wchar_t> 307 { 308 typedef wchar_t char_type; 309 typedef wint_t int_type; 310 typedef streamoff off_type; 311 typedef wstreampos pos_type; 312 typedef mbstate_t state_type; 313 314 static void 315 assign(char_type& __c1, const char_type& __c2) 316 { __c1 = __c2; } 317 318 static _GLIBCXX_CONSTEXPR bool 319 eq(const char_type& __c1, const char_type& __c2) 320 { return __c1 == __c2; } 321 322 static _GLIBCXX_CONSTEXPR bool 323 lt(const char_type& __c1, const char_type& __c2) 324 { return __c1 < __c2; } 325 326 static int 327 compare(const char_type* __s1, const char_type* __s2, size_t __n) 328 { return wmemcmp(__s1, __s2, __n); } 329 330 static size_t 331 length(const char_type* __s) 332 { return wcslen(__s); } 333 334 static const char_type* 335 find(const char_type* __s, size_t __n, const char_type& __a) 336 { return wmemchr(__s, __a, __n); } 337 338 static char_type* 339 move(char_type* __s1, const char_type* __s2, size_t __n) 340 { return wmemmove(__s1, __s2, __n); } 341 342 static char_type* 343 copy(char_type* __s1, const char_type* __s2, size_t __n) 344 { return wmemcpy(__s1, __s2, __n); } 345 346 static char_type* 347 assign(char_type* __s, size_t __n, char_type __a) 348 { return wmemset(__s, __a, __n); } 349 350 static _GLIBCXX_CONSTEXPR char_type 351 to_char_type(const int_type& __c) 352 { return char_type(__c); } 353 354 static _GLIBCXX_CONSTEXPR int_type 355 to_int_type(const char_type& __c) 356 { return int_type(__c); } 357 358 static _GLIBCXX_CONSTEXPR bool 359 eq_int_type(const int_type& __c1, const int_type& __c2) 360 { return __c1 == __c2; } 361 362 static _GLIBCXX_CONSTEXPR int_type 363 eof() 364 { return static_cast<int_type>(WEOF); } 365 366 static _GLIBCXX_CONSTEXPR int_type 367 not_eof(const int_type& __c) 368 { return eq_int_type(__c, eof()) ? 0 : __c; } 369 }; 370 #endif //_GLIBCXX_USE_WCHAR_T 371 372 _GLIBCXX_END_NAMESPACE_VERSION 373 } // namespace 374 375 #if (defined(__GXX_EXPERIMENTAL_CXX0X__) \ 376 && defined(_GLIBCXX_USE_C99_STDINT_TR1)) 377 378 #include <cstdint> 379 380 namespace std _GLIBCXX_VISIBILITY(default) 381 { 382 _GLIBCXX_BEGIN_NAMESPACE_VERSION 383 384 template<> 385 struct char_traits<char16_t> 386 { 387 typedef char16_t char_type; 388 typedef uint_least16_t int_type; 389 typedef streamoff off_type; 390 typedef u16streampos pos_type; 391 typedef mbstate_t state_type; 392 393 static void 394 assign(char_type& __c1, const char_type& __c2) 395 { __c1 = __c2; } 396 397 static _GLIBCXX_CONSTEXPR bool 398 eq(const char_type& __c1, const char_type& __c2) 399 { return __c1 == __c2; } 400 401 static _GLIBCXX_CONSTEXPR bool 402 lt(const char_type& __c1, const char_type& __c2) 403 { return __c1 < __c2; } 404 405 static int 406 compare(const char_type* __s1, const char_type* __s2, size_t __n) 407 { 408 for (size_t __i = 0; __i < __n; ++__i) 409 if (lt(__s1[__i], __s2[__i])) 410 return -1; 411 else if (lt(__s2[__i], __s1[__i])) 412 return 1; 413 return 0; 414 } 415 416 static size_t 417 length(const char_type* __s) 418 { 419 size_t __i = 0; 420 while (!eq(__s[__i], char_type())) 421 ++__i; 422 return __i; 423 } 424 425 static const char_type* 426 find(const char_type* __s, size_t __n, const char_type& __a) 427 { 428 for (size_t __i = 0; __i < __n; ++__i) 429 if (eq(__s[__i], __a)) 430 return __s + __i; 431 return 0; 432 } 433 434 static char_type* 435 move(char_type* __s1, const char_type* __s2, size_t __n) 436 { 437 return (static_cast<char_type*> 438 (__builtin_memmove(__s1, __s2, __n * sizeof(char_type)))); 439 } 440 441 static char_type* 442 copy(char_type* __s1, const char_type* __s2, size_t __n) 443 { 444 return (static_cast<char_type*> 445 (__builtin_memcpy(__s1, __s2, __n * sizeof(char_type)))); 446 } 447 448 static char_type* 449 assign(char_type* __s, size_t __n, char_type __a) 450 { 451 for (size_t __i = 0; __i < __n; ++__i) 452 assign(__s[__i], __a); 453 return __s; 454 } 455 456 static _GLIBCXX_CONSTEXPR char_type 457 to_char_type(const int_type& __c) 458 { return char_type(__c); } 459 460 static _GLIBCXX_CONSTEXPR int_type 461 to_int_type(const char_type& __c) 462 { return int_type(__c); } 463 464 static _GLIBCXX_CONSTEXPR bool 465 eq_int_type(const int_type& __c1, const int_type& __c2) 466 { return __c1 == __c2; } 467 468 static _GLIBCXX_CONSTEXPR int_type 469 eof() 470 { return static_cast<int_type>(-1); } 471 472 static _GLIBCXX_CONSTEXPR int_type 473 not_eof(const int_type& __c) 474 { return eq_int_type(__c, eof()) ? 0 : __c; } 475 }; 476 477 template<> 478 struct char_traits<char32_t> 479 { 480 typedef char32_t char_type; 481 typedef uint_least32_t int_type; 482 typedef streamoff off_type; 483 typedef u32streampos pos_type; 484 typedef mbstate_t state_type; 485 486 static void 487 assign(char_type& __c1, const char_type& __c2) 488 { __c1 = __c2; } 489 490 static _GLIBCXX_CONSTEXPR bool 491 eq(const char_type& __c1, const char_type& __c2) 492 { return __c1 == __c2; } 493 494 static _GLIBCXX_CONSTEXPR bool 495 lt(const char_type& __c1, const char_type& __c2) 496 { return __c1 < __c2; } 497 498 static int 499 compare(const char_type* __s1, const char_type* __s2, size_t __n) 500 { 501 for (size_t __i = 0; __i < __n; ++__i) 502 if (lt(__s1[__i], __s2[__i])) 503 return -1; 504 else if (lt(__s2[__i], __s1[__i])) 505 return 1; 506 return 0; 507 } 508 509 static size_t 510 length(const char_type* __s) 511 { 512 size_t __i = 0; 513 while (!eq(__s[__i], char_type())) 514 ++__i; 515 return __i; 516 } 517 518 static const char_type* 519 find(const char_type* __s, size_t __n, const char_type& __a) 520 { 521 for (size_t __i = 0; __i < __n; ++__i) 522 if (eq(__s[__i], __a)) 523 return __s + __i; 524 return 0; 525 } 526 527 static char_type* 528 move(char_type* __s1, const char_type* __s2, size_t __n) 529 { 530 return (static_cast<char_type*> 531 (__builtin_memmove(__s1, __s2, __n * sizeof(char_type)))); 532 } 533 534 static char_type* 535 copy(char_type* __s1, const char_type* __s2, size_t __n) 536 { 537 return (static_cast<char_type*> 538 (__builtin_memcpy(__s1, __s2, __n * sizeof(char_type)))); 539 } 540 541 static char_type* 542 assign(char_type* __s, size_t __n, char_type __a) 543 { 544 for (size_t __i = 0; __i < __n; ++__i) 545 assign(__s[__i], __a); 546 return __s; 547 } 548 549 static _GLIBCXX_CONSTEXPR char_type 550 to_char_type(const int_type& __c) 551 { return char_type(__c); } 552 553 static _GLIBCXX_CONSTEXPR int_type 554 to_int_type(const char_type& __c) 555 { return int_type(__c); } 556 557 static _GLIBCXX_CONSTEXPR bool 558 eq_int_type(const int_type& __c1, const int_type& __c2) 559 { return __c1 == __c2; } 560 561 static _GLIBCXX_CONSTEXPR int_type 562 eof() 563 { return static_cast<int_type>(-1); } 564 565 static _GLIBCXX_CONSTEXPR int_type 566 not_eof(const int_type& __c) 567 { return eq_int_type(__c, eof()) ? 0 : __c; } 568 }; 569 570 _GLIBCXX_END_NAMESPACE_VERSION 571 } // namespace 572 573 #endif 574 575 #endif // _CHAR_TRAITS_H 576