libstdc++
|
00001 // Character Traits for use by standard string and iostream -*- C++ -*- 00002 00003 // Copyright (C) 1997-2017 Free Software Foundation, Inc. 00004 // 00005 // This file is part of the GNU ISO C++ Library. This library is free 00006 // software; you can redistribute it and/or modify it under the 00007 // terms of the GNU General Public License as published by the 00008 // Free Software Foundation; either version 3, or (at your option) 00009 // any later version. 00010 00011 // This library is distributed in the hope that it will be useful, 00012 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 // GNU General Public License for more details. 00015 00016 // Under Section 7 of GPL version 3, you are granted additional 00017 // permissions described in the GCC Runtime Library Exception, version 00018 // 3.1, as published by the Free Software Foundation. 00019 00020 // You should have received a copy of the GNU General Public License and 00021 // a copy of the GCC Runtime Library Exception along with this program; 00022 // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 00023 // <http://www.gnu.org/licenses/>. 00024 00025 /** @file bits/char_traits.h 00026 * This is an internal header file, included by other library headers. 00027 * Do not attempt to use it directly. @headername{string} 00028 */ 00029 00030 // 00031 // ISO C++ 14882: 21 Strings library 00032 // 00033 00034 #ifndef _CHAR_TRAITS_H 00035 #define _CHAR_TRAITS_H 1 00036 00037 #pragma GCC system_header 00038 00039 #include <bits/stl_algobase.h> // std::copy, std::fill_n 00040 #include <bits/postypes.h> // For streampos 00041 #include <cwchar> // For WEOF, wmemmove, wmemset, etc. 00042 00043 namespace __gnu_cxx _GLIBCXX_VISIBILITY(default) 00044 { 00045 _GLIBCXX_BEGIN_NAMESPACE_VERSION 00046 00047 /** 00048 * @brief Mapping from character type to associated types. 00049 * 00050 * @note This is an implementation class for the generic version 00051 * of char_traits. It defines int_type, off_type, pos_type, and 00052 * state_type. By default these are unsigned long, streamoff, 00053 * streampos, and mbstate_t. Users who need a different set of 00054 * types, but who don't need to change the definitions of any function 00055 * defined in char_traits, can specialize __gnu_cxx::_Char_types 00056 * while leaving __gnu_cxx::char_traits alone. */ 00057 template<typename _CharT> 00058 struct _Char_types 00059 { 00060 typedef unsigned long int_type; 00061 typedef std::streampos pos_type; 00062 typedef std::streamoff off_type; 00063 typedef std::mbstate_t state_type; 00064 }; 00065 00066 00067 /** 00068 * @brief Base class used to implement std::char_traits. 00069 * 00070 * @note For any given actual character type, this definition is 00071 * probably wrong. (Most of the member functions are likely to be 00072 * right, but the int_type and state_type typedefs, and the eof() 00073 * member function, are likely to be wrong.) The reason this class 00074 * exists is so users can specialize it. Classes in namespace std 00075 * may not be specialized for fundamental types, but classes in 00076 * namespace __gnu_cxx may be. 00077 * 00078 * See https://gcc.gnu.org/onlinedocs/libstdc++/manual/strings.html#strings.string.character_types 00079 * for advice on how to make use of this class for @a unusual character 00080 * types. Also, check out include/ext/pod_char_traits.h. 00081 */ 00082 template<typename _CharT> 00083 struct char_traits 00084 { 00085 typedef _CharT char_type; 00086 typedef typename _Char_types<_CharT>::int_type int_type; 00087 typedef typename _Char_types<_CharT>::pos_type pos_type; 00088 typedef typename _Char_types<_CharT>::off_type off_type; 00089 typedef typename _Char_types<_CharT>::state_type state_type; 00090 00091 static _GLIBCXX14_CONSTEXPR void 00092 assign(char_type& __c1, const char_type& __c2) 00093 { __c1 = __c2; } 00094 00095 static _GLIBCXX_CONSTEXPR bool 00096 eq(const char_type& __c1, const char_type& __c2) 00097 { return __c1 == __c2; } 00098 00099 static _GLIBCXX_CONSTEXPR bool 00100 lt(const char_type& __c1, const char_type& __c2) 00101 { return __c1 < __c2; } 00102 00103 static _GLIBCXX14_CONSTEXPR int 00104 compare(const char_type* __s1, const char_type* __s2, std::size_t __n); 00105 00106 static _GLIBCXX14_CONSTEXPR std::size_t 00107 length(const char_type* __s); 00108 00109 static _GLIBCXX14_CONSTEXPR const char_type* 00110 find(const char_type* __s, std::size_t __n, const char_type& __a); 00111 00112 static char_type* 00113 move(char_type* __s1, const char_type* __s2, std::size_t __n); 00114 00115 static char_type* 00116 copy(char_type* __s1, const char_type* __s2, std::size_t __n); 00117 00118 static char_type* 00119 assign(char_type* __s, std::size_t __n, char_type __a); 00120 00121 static _GLIBCXX_CONSTEXPR char_type 00122 to_char_type(const int_type& __c) 00123 { return static_cast<char_type>(__c); } 00124 00125 static _GLIBCXX_CONSTEXPR int_type 00126 to_int_type(const char_type& __c) 00127 { return static_cast<int_type>(__c); } 00128 00129 static _GLIBCXX_CONSTEXPR bool 00130 eq_int_type(const int_type& __c1, const int_type& __c2) 00131 { return __c1 == __c2; } 00132 00133 static _GLIBCXX_CONSTEXPR int_type 00134 eof() 00135 { return static_cast<int_type>(_GLIBCXX_STDIO_EOF); } 00136 00137 static _GLIBCXX_CONSTEXPR int_type 00138 not_eof(const int_type& __c) 00139 { return !eq_int_type(__c, eof()) ? __c : to_int_type(char_type()); } 00140 }; 00141 00142 // #define __cpp_lib_constexpr_char_traits 201611 00143 00144 template<typename _CharT> 00145 _GLIBCXX14_CONSTEXPR int 00146 char_traits<_CharT>:: 00147 compare(const char_type* __s1, const char_type* __s2, std::size_t __n) 00148 { 00149 for (std::size_t __i = 0; __i < __n; ++__i) 00150 if (lt(__s1[__i], __s2[__i])) 00151 return -1; 00152 else if (lt(__s2[__i], __s1[__i])) 00153 return 1; 00154 return 0; 00155 } 00156 00157 template<typename _CharT> 00158 _GLIBCXX14_CONSTEXPR std::size_t 00159 char_traits<_CharT>:: 00160 length(const char_type* __p) 00161 { 00162 std::size_t __i = 0; 00163 while (!eq(__p[__i], char_type())) 00164 ++__i; 00165 return __i; 00166 } 00167 00168 template<typename _CharT> 00169 _GLIBCXX14_CONSTEXPR const typename char_traits<_CharT>::char_type* 00170 char_traits<_CharT>:: 00171 find(const char_type* __s, std::size_t __n, const char_type& __a) 00172 { 00173 for (std::size_t __i = 0; __i < __n; ++__i) 00174 if (eq(__s[__i], __a)) 00175 return __s + __i; 00176 return 0; 00177 } 00178 00179 template<typename _CharT> 00180 typename char_traits<_CharT>::char_type* 00181 char_traits<_CharT>:: 00182 move(char_type* __s1, const char_type* __s2, std::size_t __n) 00183 { 00184 return static_cast<_CharT*>(__builtin_memmove(__s1, __s2, 00185 __n * sizeof(char_type))); 00186 } 00187 00188 template<typename _CharT> 00189 typename char_traits<_CharT>::char_type* 00190 char_traits<_CharT>:: 00191 copy(char_type* __s1, const char_type* __s2, std::size_t __n) 00192 { 00193 // NB: Inline std::copy so no recursive dependencies. 00194 std::copy(__s2, __s2 + __n, __s1); 00195 return __s1; 00196 } 00197 00198 template<typename _CharT> 00199 typename char_traits<_CharT>::char_type* 00200 char_traits<_CharT>:: 00201 assign(char_type* __s, std::size_t __n, char_type __a) 00202 { 00203 // NB: Inline std::fill_n so no recursive dependencies. 00204 std::fill_n(__s, __n, __a); 00205 return __s; 00206 } 00207 00208 _GLIBCXX_END_NAMESPACE_VERSION 00209 } // namespace 00210 00211 namespace std _GLIBCXX_VISIBILITY(default) 00212 { 00213 _GLIBCXX_BEGIN_NAMESPACE_VERSION 00214 00215 // 21.1 00216 /** 00217 * @brief Basis for explicit traits specializations. 00218 * 00219 * @note For any given actual character type, this definition is 00220 * probably wrong. Since this is just a thin wrapper around 00221 * __gnu_cxx::char_traits, it is possible to achieve a more 00222 * appropriate definition by specializing __gnu_cxx::char_traits. 00223 * 00224 * See https://gcc.gnu.org/onlinedocs/libstdc++/manual/strings.html#strings.string.character_types 00225 * for advice on how to make use of this class for @a unusual character 00226 * types. Also, check out include/ext/pod_char_traits.h. 00227 */ 00228 template<class _CharT> 00229 struct char_traits : public __gnu_cxx::char_traits<_CharT> 00230 { }; 00231 00232 00233 /// 21.1.3.1 char_traits specializations 00234 template<> 00235 struct char_traits<char> 00236 { 00237 typedef char char_type; 00238 typedef int int_type; 00239 typedef streampos pos_type; 00240 typedef streamoff off_type; 00241 typedef mbstate_t state_type; 00242 00243 static _GLIBCXX17_CONSTEXPR void 00244 assign(char_type& __c1, const char_type& __c2) _GLIBCXX_NOEXCEPT 00245 { __c1 = __c2; } 00246 00247 static _GLIBCXX_CONSTEXPR bool 00248 eq(const char_type& __c1, const char_type& __c2) _GLIBCXX_NOEXCEPT 00249 { return __c1 == __c2; } 00250 00251 static _GLIBCXX_CONSTEXPR bool 00252 lt(const char_type& __c1, const char_type& __c2) _GLIBCXX_NOEXCEPT 00253 { 00254 // LWG 467. 00255 return (static_cast<unsigned char>(__c1) 00256 < static_cast<unsigned char>(__c2)); 00257 } 00258 00259 static /* _GLIBCXX17_CONSTEXPR */ int 00260 compare(const char_type* __s1, const char_type* __s2, size_t __n) 00261 { 00262 if (__n == 0) 00263 return 0; 00264 return __builtin_memcmp(__s1, __s2, __n); 00265 } 00266 00267 static /* _GLIBCXX17_CONSTEXPR */ size_t 00268 length(const char_type* __s) 00269 { return __builtin_strlen(__s); } 00270 00271 static /* _GLIBCXX17_CONSTEXPR */ const char_type* 00272 find(const char_type* __s, size_t __n, const char_type& __a) 00273 { 00274 if (__n == 0) 00275 return 0; 00276 return static_cast<const char_type*>(__builtin_memchr(__s, __a, __n)); 00277 } 00278 00279 static char_type* 00280 move(char_type* __s1, const char_type* __s2, size_t __n) 00281 { 00282 if (__n == 0) 00283 return __s1; 00284 return static_cast<char_type*>(__builtin_memmove(__s1, __s2, __n)); 00285 } 00286 00287 static char_type* 00288 copy(char_type* __s1, const char_type* __s2, size_t __n) 00289 { 00290 if (__n == 0) 00291 return __s1; 00292 return static_cast<char_type*>(__builtin_memcpy(__s1, __s2, __n)); 00293 } 00294 00295 static char_type* 00296 assign(char_type* __s, size_t __n, char_type __a) 00297 { 00298 if (__n == 0) 00299 return __s; 00300 return static_cast<char_type*>(__builtin_memset(__s, __a, __n)); 00301 } 00302 00303 static _GLIBCXX_CONSTEXPR char_type 00304 to_char_type(const int_type& __c) _GLIBCXX_NOEXCEPT 00305 { return static_cast<char_type>(__c); } 00306 00307 // To keep both the byte 0xff and the eof symbol 0xffffffff 00308 // from ending up as 0xffffffff. 00309 static _GLIBCXX_CONSTEXPR int_type 00310 to_int_type(const char_type& __c) _GLIBCXX_NOEXCEPT 00311 { return static_cast<int_type>(static_cast<unsigned char>(__c)); } 00312 00313 static _GLIBCXX_CONSTEXPR bool 00314 eq_int_type(const int_type& __c1, const int_type& __c2) _GLIBCXX_NOEXCEPT 00315 { return __c1 == __c2; } 00316 00317 static _GLIBCXX_CONSTEXPR int_type 00318 eof() _GLIBCXX_NOEXCEPT 00319 { return static_cast<int_type>(_GLIBCXX_STDIO_EOF); } 00320 00321 static _GLIBCXX_CONSTEXPR int_type 00322 not_eof(const int_type& __c) _GLIBCXX_NOEXCEPT 00323 { return (__c == eof()) ? 0 : __c; } 00324 }; 00325 00326 00327 #ifdef _GLIBCXX_USE_WCHAR_T 00328 /// 21.1.3.2 char_traits specializations 00329 template<> 00330 struct char_traits<wchar_t> 00331 { 00332 typedef wchar_t char_type; 00333 typedef wint_t int_type; 00334 typedef streamoff off_type; 00335 typedef wstreampos pos_type; 00336 typedef mbstate_t state_type; 00337 00338 static _GLIBCXX17_CONSTEXPR void 00339 assign(char_type& __c1, const char_type& __c2) _GLIBCXX_NOEXCEPT 00340 { __c1 = __c2; } 00341 00342 static _GLIBCXX_CONSTEXPR bool 00343 eq(const char_type& __c1, const char_type& __c2) _GLIBCXX_NOEXCEPT 00344 { return __c1 == __c2; } 00345 00346 static _GLIBCXX_CONSTEXPR bool 00347 lt(const char_type& __c1, const char_type& __c2) _GLIBCXX_NOEXCEPT 00348 { return __c1 < __c2; } 00349 00350 static /* _GLIBCXX17_CONSTEXPR */ int 00351 compare(const char_type* __s1, const char_type* __s2, size_t __n) 00352 { 00353 if (__n == 0) 00354 return 0; 00355 return wmemcmp(__s1, __s2, __n); 00356 } 00357 00358 static /* _GLIBCXX17_CONSTEXPR */ size_t 00359 length(const char_type* __s) 00360 { return wcslen(__s); } 00361 00362 static /* _GLIBCXX17_CONSTEXPR */ const char_type* 00363 find(const char_type* __s, size_t __n, const char_type& __a) 00364 { 00365 if (__n == 0) 00366 return 0; 00367 return wmemchr(__s, __a, __n); 00368 } 00369 00370 static char_type* 00371 move(char_type* __s1, const char_type* __s2, size_t __n) 00372 { 00373 if (__n == 0) 00374 return __s1; 00375 return wmemmove(__s1, __s2, __n); 00376 } 00377 00378 static char_type* 00379 copy(char_type* __s1, const char_type* __s2, size_t __n) 00380 { 00381 if (__n == 0) 00382 return __s1; 00383 return wmemcpy(__s1, __s2, __n); 00384 } 00385 00386 static char_type* 00387 assign(char_type* __s, size_t __n, char_type __a) 00388 { 00389 if (__n == 0) 00390 return __s; 00391 return wmemset(__s, __a, __n); 00392 } 00393 00394 static _GLIBCXX_CONSTEXPR char_type 00395 to_char_type(const int_type& __c) _GLIBCXX_NOEXCEPT 00396 { return char_type(__c); } 00397 00398 static _GLIBCXX_CONSTEXPR int_type 00399 to_int_type(const char_type& __c) _GLIBCXX_NOEXCEPT 00400 { return int_type(__c); } 00401 00402 static _GLIBCXX_CONSTEXPR bool 00403 eq_int_type(const int_type& __c1, const int_type& __c2) _GLIBCXX_NOEXCEPT 00404 { return __c1 == __c2; } 00405 00406 static _GLIBCXX_CONSTEXPR int_type 00407 eof() _GLIBCXX_NOEXCEPT 00408 { return static_cast<int_type>(WEOF); } 00409 00410 static _GLIBCXX_CONSTEXPR int_type 00411 not_eof(const int_type& __c) _GLIBCXX_NOEXCEPT 00412 { return eq_int_type(__c, eof()) ? 0 : __c; } 00413 }; 00414 #endif //_GLIBCXX_USE_WCHAR_T 00415 00416 _GLIBCXX_END_NAMESPACE_VERSION 00417 } // namespace 00418 00419 #if ((__cplusplus >= 201103L) \ 00420 && defined(_GLIBCXX_USE_C99_STDINT_TR1)) 00421 00422 #include <cstdint> 00423 00424 namespace std _GLIBCXX_VISIBILITY(default) 00425 { 00426 _GLIBCXX_BEGIN_NAMESPACE_VERSION 00427 00428 template<> 00429 struct char_traits<char16_t> 00430 { 00431 typedef char16_t char_type; 00432 typedef uint_least16_t int_type; 00433 typedef streamoff off_type; 00434 typedef u16streampos pos_type; 00435 typedef mbstate_t state_type; 00436 00437 static _GLIBCXX17_CONSTEXPR void 00438 assign(char_type& __c1, const char_type& __c2) noexcept 00439 { __c1 = __c2; } 00440 00441 static constexpr bool 00442 eq(const char_type& __c1, const char_type& __c2) noexcept 00443 { return __c1 == __c2; } 00444 00445 static constexpr bool 00446 lt(const char_type& __c1, const char_type& __c2) noexcept 00447 { return __c1 < __c2; } 00448 00449 static _GLIBCXX17_CONSTEXPR int 00450 compare(const char_type* __s1, const char_type* __s2, size_t __n) 00451 { 00452 for (size_t __i = 0; __i < __n; ++__i) 00453 if (lt(__s1[__i], __s2[__i])) 00454 return -1; 00455 else if (lt(__s2[__i], __s1[__i])) 00456 return 1; 00457 return 0; 00458 } 00459 00460 static _GLIBCXX17_CONSTEXPR size_t 00461 length(const char_type* __s) 00462 { 00463 size_t __i = 0; 00464 while (!eq(__s[__i], char_type())) 00465 ++__i; 00466 return __i; 00467 } 00468 00469 static _GLIBCXX17_CONSTEXPR const char_type* 00470 find(const char_type* __s, size_t __n, const char_type& __a) 00471 { 00472 for (size_t __i = 0; __i < __n; ++__i) 00473 if (eq(__s[__i], __a)) 00474 return __s + __i; 00475 return 0; 00476 } 00477 00478 static char_type* 00479 move(char_type* __s1, const char_type* __s2, size_t __n) 00480 { 00481 if (__n == 0) 00482 return __s1; 00483 return (static_cast<char_type*> 00484 (__builtin_memmove(__s1, __s2, __n * sizeof(char_type)))); 00485 } 00486 00487 static char_type* 00488 copy(char_type* __s1, const char_type* __s2, size_t __n) 00489 { 00490 if (__n == 0) 00491 return __s1; 00492 return (static_cast<char_type*> 00493 (__builtin_memcpy(__s1, __s2, __n * sizeof(char_type)))); 00494 } 00495 00496 static char_type* 00497 assign(char_type* __s, size_t __n, char_type __a) 00498 { 00499 for (size_t __i = 0; __i < __n; ++__i) 00500 assign(__s[__i], __a); 00501 return __s; 00502 } 00503 00504 static constexpr char_type 00505 to_char_type(const int_type& __c) noexcept 00506 { return char_type(__c); } 00507 00508 static constexpr int_type 00509 to_int_type(const char_type& __c) noexcept 00510 { return int_type(__c); } 00511 00512 static constexpr bool 00513 eq_int_type(const int_type& __c1, const int_type& __c2) noexcept 00514 { return __c1 == __c2; } 00515 00516 static constexpr int_type 00517 eof() noexcept 00518 { return static_cast<int_type>(-1); } 00519 00520 static constexpr int_type 00521 not_eof(const int_type& __c) noexcept 00522 { return eq_int_type(__c, eof()) ? 0 : __c; } 00523 }; 00524 00525 template<> 00526 struct char_traits<char32_t> 00527 { 00528 typedef char32_t char_type; 00529 typedef uint_least32_t int_type; 00530 typedef streamoff off_type; 00531 typedef u32streampos pos_type; 00532 typedef mbstate_t state_type; 00533 00534 static _GLIBCXX17_CONSTEXPR void 00535 assign(char_type& __c1, const char_type& __c2) noexcept 00536 { __c1 = __c2; } 00537 00538 static constexpr bool 00539 eq(const char_type& __c1, const char_type& __c2) noexcept 00540 { return __c1 == __c2; } 00541 00542 static constexpr bool 00543 lt(const char_type& __c1, const char_type& __c2) noexcept 00544 { return __c1 < __c2; } 00545 00546 static _GLIBCXX17_CONSTEXPR int 00547 compare(const char_type* __s1, const char_type* __s2, size_t __n) 00548 { 00549 for (size_t __i = 0; __i < __n; ++__i) 00550 if (lt(__s1[__i], __s2[__i])) 00551 return -1; 00552 else if (lt(__s2[__i], __s1[__i])) 00553 return 1; 00554 return 0; 00555 } 00556 00557 static _GLIBCXX17_CONSTEXPR size_t 00558 length(const char_type* __s) 00559 { 00560 size_t __i = 0; 00561 while (!eq(__s[__i], char_type())) 00562 ++__i; 00563 return __i; 00564 } 00565 00566 static _GLIBCXX17_CONSTEXPR const char_type* 00567 find(const char_type* __s, size_t __n, const char_type& __a) 00568 { 00569 for (size_t __i = 0; __i < __n; ++__i) 00570 if (eq(__s[__i], __a)) 00571 return __s + __i; 00572 return 0; 00573 } 00574 00575 static char_type* 00576 move(char_type* __s1, const char_type* __s2, size_t __n) 00577 { 00578 if (__n == 0) 00579 return __s1; 00580 return (static_cast<char_type*> 00581 (__builtin_memmove(__s1, __s2, __n * sizeof(char_type)))); 00582 } 00583 00584 static char_type* 00585 copy(char_type* __s1, const char_type* __s2, size_t __n) 00586 { 00587 if (__n == 0) 00588 return __s1; 00589 return (static_cast<char_type*> 00590 (__builtin_memcpy(__s1, __s2, __n * sizeof(char_type)))); 00591 } 00592 00593 static char_type* 00594 assign(char_type* __s, size_t __n, char_type __a) 00595 { 00596 for (size_t __i = 0; __i < __n; ++__i) 00597 assign(__s[__i], __a); 00598 return __s; 00599 } 00600 00601 static constexpr char_type 00602 to_char_type(const int_type& __c) noexcept 00603 { return char_type(__c); } 00604 00605 static constexpr int_type 00606 to_int_type(const char_type& __c) noexcept 00607 { return int_type(__c); } 00608 00609 static constexpr bool 00610 eq_int_type(const int_type& __c1, const int_type& __c2) noexcept 00611 { return __c1 == __c2; } 00612 00613 static constexpr int_type 00614 eof() noexcept 00615 { return static_cast<int_type>(-1); } 00616 00617 static constexpr int_type 00618 not_eof(const int_type& __c) noexcept 00619 { return eq_int_type(__c, eof()) ? 0 : __c; } 00620 }; 00621 00622 _GLIBCXX_END_NAMESPACE_VERSION 00623 } // namespace 00624 00625 #endif 00626 00627 #endif // _CHAR_TRAITS_H