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