libstdc++
|
00001 // Character Traits for use by standard string and iostream -*- C++ -*- 00002 00003 // Copyright (C) 1997-2015 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 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 int 00104 compare(const char_type* __s1, const char_type* __s2, std::size_t __n); 00105 00106 static std::size_t 00107 length(const char_type* __s); 00108 00109 static 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 template<typename _CharT> 00143 int 00144 char_traits<_CharT>:: 00145 compare(const char_type* __s1, const char_type* __s2, std::size_t __n) 00146 { 00147 for (std::size_t __i = 0; __i < __n; ++__i) 00148 if (lt(__s1[__i], __s2[__i])) 00149 return -1; 00150 else if (lt(__s2[__i], __s1[__i])) 00151 return 1; 00152 return 0; 00153 } 00154 00155 template<typename _CharT> 00156 std::size_t 00157 char_traits<_CharT>:: 00158 length(const char_type* __p) 00159 { 00160 std::size_t __i = 0; 00161 while (!eq(__p[__i], char_type())) 00162 ++__i; 00163 return __i; 00164 } 00165 00166 template<typename _CharT> 00167 const typename char_traits<_CharT>::char_type* 00168 char_traits<_CharT>:: 00169 find(const char_type* __s, std::size_t __n, const char_type& __a) 00170 { 00171 for (std::size_t __i = 0; __i < __n; ++__i) 00172 if (eq(__s[__i], __a)) 00173 return __s + __i; 00174 return 0; 00175 } 00176 00177 template<typename _CharT> 00178 typename char_traits<_CharT>::char_type* 00179 char_traits<_CharT>:: 00180 move(char_type* __s1, const char_type* __s2, std::size_t __n) 00181 { 00182 return static_cast<_CharT*>(__builtin_memmove(__s1, __s2, 00183 __n * sizeof(char_type))); 00184 } 00185 00186 template<typename _CharT> 00187 typename char_traits<_CharT>::char_type* 00188 char_traits<_CharT>:: 00189 copy(char_type* __s1, const char_type* __s2, std::size_t __n) 00190 { 00191 // NB: Inline std::copy so no recursive dependencies. 00192 std::copy(__s2, __s2 + __n, __s1); 00193 return __s1; 00194 } 00195 00196 template<typename _CharT> 00197 typename char_traits<_CharT>::char_type* 00198 char_traits<_CharT>:: 00199 assign(char_type* __s, std::size_t __n, char_type __a) 00200 { 00201 // NB: Inline std::fill_n so no recursive dependencies. 00202 std::fill_n(__s, __n, __a); 00203 return __s; 00204 } 00205 00206 _GLIBCXX_END_NAMESPACE_VERSION 00207 } // namespace 00208 00209 namespace std _GLIBCXX_VISIBILITY(default) 00210 { 00211 _GLIBCXX_BEGIN_NAMESPACE_VERSION 00212 00213 // 21.1 00214 /** 00215 * @brief Basis for explicit traits specializations. 00216 * 00217 * @note For any given actual character type, this definition is 00218 * probably wrong. Since this is just a thin wrapper around 00219 * __gnu_cxx::char_traits, it is possible to achieve a more 00220 * appropriate definition by specializing __gnu_cxx::char_traits. 00221 * 00222 * See https://gcc.gnu.org/onlinedocs/libstdc++/manual/strings.html#strings.string.character_types 00223 * for advice on how to make use of this class for @a unusual character 00224 * types. Also, check out include/ext/pod_char_traits.h. 00225 */ 00226 template<class _CharT> 00227 struct char_traits : public __gnu_cxx::char_traits<_CharT> 00228 { }; 00229 00230 00231 /// 21.1.3.1 char_traits specializations 00232 template<> 00233 struct char_traits<char> 00234 { 00235 typedef char char_type; 00236 typedef int int_type; 00237 typedef streampos pos_type; 00238 typedef streamoff off_type; 00239 typedef mbstate_t state_type; 00240 00241 static void 00242 assign(char_type& __c1, const char_type& __c2) _GLIBCXX_NOEXCEPT 00243 { __c1 = __c2; } 00244 00245 static _GLIBCXX_CONSTEXPR bool 00246 eq(const char_type& __c1, const char_type& __c2) _GLIBCXX_NOEXCEPT 00247 { return __c1 == __c2; } 00248 00249 static _GLIBCXX_CONSTEXPR bool 00250 lt(const char_type& __c1, const char_type& __c2) _GLIBCXX_NOEXCEPT 00251 { 00252 // LWG 467. 00253 return (static_cast<unsigned char>(__c1) 00254 < static_cast<unsigned char>(__c2)); 00255 } 00256 00257 static int 00258 compare(const char_type* __s1, const char_type* __s2, size_t __n) 00259 { 00260 if (__n == 0) 00261 return 0; 00262 return __builtin_memcmp(__s1, __s2, __n); 00263 } 00264 00265 static size_t 00266 length(const char_type* __s) 00267 { return __builtin_strlen(__s); } 00268 00269 static const char_type* 00270 find(const char_type* __s, size_t __n, const char_type& __a) 00271 { 00272 if (__n == 0) 00273 return 0; 00274 return static_cast<const char_type*>(__builtin_memchr(__s, __a, __n)); 00275 } 00276 00277 static char_type* 00278 move(char_type* __s1, const char_type* __s2, size_t __n) 00279 { 00280 if (__n == 0) 00281 return __s1; 00282 return static_cast<char_type*>(__builtin_memmove(__s1, __s2, __n)); 00283 } 00284 00285 static char_type* 00286 copy(char_type* __s1, const char_type* __s2, size_t __n) 00287 { 00288 if (__n == 0) 00289 return __s1; 00290 return static_cast<char_type*>(__builtin_memcpy(__s1, __s2, __n)); 00291 } 00292 00293 static char_type* 00294 assign(char_type* __s, size_t __n, char_type __a) 00295 { 00296 if (__n == 0) 00297 return __s; 00298 return static_cast<char_type*>(__builtin_memset(__s, __a, __n)); 00299 } 00300 00301 static _GLIBCXX_CONSTEXPR char_type 00302 to_char_type(const int_type& __c) _GLIBCXX_NOEXCEPT 00303 { return static_cast<char_type>(__c); } 00304 00305 // To keep both the byte 0xff and the eof symbol 0xffffffff 00306 // from ending up as 0xffffffff. 00307 static _GLIBCXX_CONSTEXPR int_type 00308 to_int_type(const char_type& __c) _GLIBCXX_NOEXCEPT 00309 { return static_cast<int_type>(static_cast<unsigned char>(__c)); } 00310 00311 static _GLIBCXX_CONSTEXPR bool 00312 eq_int_type(const int_type& __c1, const int_type& __c2) _GLIBCXX_NOEXCEPT 00313 { return __c1 == __c2; } 00314 00315 static _GLIBCXX_CONSTEXPR int_type 00316 eof() _GLIBCXX_NOEXCEPT 00317 { return static_cast<int_type>(_GLIBCXX_STDIO_EOF); } 00318 00319 static _GLIBCXX_CONSTEXPR int_type 00320 not_eof(const int_type& __c) _GLIBCXX_NOEXCEPT 00321 { return (__c == eof()) ? 0 : __c; } 00322 }; 00323 00324 00325 #ifdef _GLIBCXX_USE_WCHAR_T 00326 /// 21.1.3.2 char_traits specializations 00327 template<> 00328 struct char_traits<wchar_t> 00329 { 00330 typedef wchar_t char_type; 00331 typedef wint_t int_type; 00332 typedef streamoff off_type; 00333 typedef wstreampos pos_type; 00334 typedef mbstate_t state_type; 00335 00336 static void 00337 assign(char_type& __c1, const char_type& __c2) _GLIBCXX_NOEXCEPT 00338 { __c1 = __c2; } 00339 00340 static _GLIBCXX_CONSTEXPR bool 00341 eq(const char_type& __c1, const char_type& __c2) _GLIBCXX_NOEXCEPT 00342 { return __c1 == __c2; } 00343 00344 static _GLIBCXX_CONSTEXPR bool 00345 lt(const char_type& __c1, const char_type& __c2) _GLIBCXX_NOEXCEPT 00346 { return __c1 < __c2; } 00347 00348 static int 00349 compare(const char_type* __s1, const char_type* __s2, size_t __n) 00350 { 00351 if (__n == 0) 00352 return 0; 00353 return wmemcmp(__s1, __s2, __n); 00354 } 00355 00356 static size_t 00357 length(const char_type* __s) 00358 { return wcslen(__s); } 00359 00360 static const char_type* 00361 find(const char_type* __s, size_t __n, const char_type& __a) 00362 { 00363 if (__n == 0) 00364 return 0; 00365 return wmemchr(__s, __a, __n); 00366 } 00367 00368 static char_type* 00369 move(char_type* __s1, const char_type* __s2, size_t __n) 00370 { 00371 if (__n == 0) 00372 return __s1; 00373 return wmemmove(__s1, __s2, __n); 00374 } 00375 00376 static char_type* 00377 copy(char_type* __s1, const char_type* __s2, size_t __n) 00378 { 00379 if (__n == 0) 00380 return __s1; 00381 return wmemcpy(__s1, __s2, __n); 00382 } 00383 00384 static char_type* 00385 assign(char_type* __s, size_t __n, char_type __a) 00386 { 00387 if (__n == 0) 00388 return __s; 00389 return wmemset(__s, __a, __n); 00390 } 00391 00392 static _GLIBCXX_CONSTEXPR char_type 00393 to_char_type(const int_type& __c) _GLIBCXX_NOEXCEPT 00394 { return char_type(__c); } 00395 00396 static _GLIBCXX_CONSTEXPR int_type 00397 to_int_type(const char_type& __c) _GLIBCXX_NOEXCEPT 00398 { return int_type(__c); } 00399 00400 static _GLIBCXX_CONSTEXPR bool 00401 eq_int_type(const int_type& __c1, const int_type& __c2) _GLIBCXX_NOEXCEPT 00402 { return __c1 == __c2; } 00403 00404 static _GLIBCXX_CONSTEXPR int_type 00405 eof() _GLIBCXX_NOEXCEPT 00406 { return static_cast<int_type>(WEOF); } 00407 00408 static _GLIBCXX_CONSTEXPR int_type 00409 not_eof(const int_type& __c) _GLIBCXX_NOEXCEPT 00410 { return eq_int_type(__c, eof()) ? 0 : __c; } 00411 }; 00412 #endif //_GLIBCXX_USE_WCHAR_T 00413 00414 _GLIBCXX_END_NAMESPACE_VERSION 00415 } // namespace 00416 00417 #if ((__cplusplus >= 201103L) \ 00418 && defined(_GLIBCXX_USE_C99_STDINT_TR1)) 00419 00420 #include <cstdint> 00421 00422 namespace std _GLIBCXX_VISIBILITY(default) 00423 { 00424 _GLIBCXX_BEGIN_NAMESPACE_VERSION 00425 00426 template<> 00427 struct char_traits<char16_t> 00428 { 00429 typedef char16_t char_type; 00430 typedef uint_least16_t int_type; 00431 typedef streamoff off_type; 00432 typedef u16streampos pos_type; 00433 typedef mbstate_t state_type; 00434 00435 static void 00436 assign(char_type& __c1, const char_type& __c2) noexcept 00437 { __c1 = __c2; } 00438 00439 static constexpr bool 00440 eq(const char_type& __c1, const char_type& __c2) noexcept 00441 { return __c1 == __c2; } 00442 00443 static constexpr bool 00444 lt(const char_type& __c1, const char_type& __c2) noexcept 00445 { return __c1 < __c2; } 00446 00447 static int 00448 compare(const char_type* __s1, const char_type* __s2, size_t __n) 00449 { 00450 for (size_t __i = 0; __i < __n; ++__i) 00451 if (lt(__s1[__i], __s2[__i])) 00452 return -1; 00453 else if (lt(__s2[__i], __s1[__i])) 00454 return 1; 00455 return 0; 00456 } 00457 00458 static size_t 00459 length(const char_type* __s) 00460 { 00461 size_t __i = 0; 00462 while (!eq(__s[__i], char_type())) 00463 ++__i; 00464 return __i; 00465 } 00466 00467 static const char_type* 00468 find(const char_type* __s, size_t __n, const char_type& __a) 00469 { 00470 for (size_t __i = 0; __i < __n; ++__i) 00471 if (eq(__s[__i], __a)) 00472 return __s + __i; 00473 return 0; 00474 } 00475 00476 static char_type* 00477 move(char_type* __s1, const char_type* __s2, size_t __n) 00478 { 00479 if (__n == 0) 00480 return __s1; 00481 return (static_cast<char_type*> 00482 (__builtin_memmove(__s1, __s2, __n * sizeof(char_type)))); 00483 } 00484 00485 static char_type* 00486 copy(char_type* __s1, const char_type* __s2, size_t __n) 00487 { 00488 if (__n == 0) 00489 return __s1; 00490 return (static_cast<char_type*> 00491 (__builtin_memcpy(__s1, __s2, __n * sizeof(char_type)))); 00492 } 00493 00494 static char_type* 00495 assign(char_type* __s, size_t __n, char_type __a) 00496 { 00497 for (size_t __i = 0; __i < __n; ++__i) 00498 assign(__s[__i], __a); 00499 return __s; 00500 } 00501 00502 static constexpr char_type 00503 to_char_type(const int_type& __c) noexcept 00504 { return char_type(__c); } 00505 00506 static constexpr int_type 00507 to_int_type(const char_type& __c) noexcept 00508 { return int_type(__c); } 00509 00510 static constexpr bool 00511 eq_int_type(const int_type& __c1, const int_type& __c2) noexcept 00512 { return __c1 == __c2; } 00513 00514 static constexpr int_type 00515 eof() noexcept 00516 { return static_cast<int_type>(-1); } 00517 00518 static constexpr int_type 00519 not_eof(const int_type& __c) noexcept 00520 { return eq_int_type(__c, eof()) ? 0 : __c; } 00521 }; 00522 00523 template<> 00524 struct char_traits<char32_t> 00525 { 00526 typedef char32_t char_type; 00527 typedef uint_least32_t int_type; 00528 typedef streamoff off_type; 00529 typedef u32streampos pos_type; 00530 typedef mbstate_t state_type; 00531 00532 static void 00533 assign(char_type& __c1, const char_type& __c2) noexcept 00534 { __c1 = __c2; } 00535 00536 static constexpr bool 00537 eq(const char_type& __c1, const char_type& __c2) noexcept 00538 { return __c1 == __c2; } 00539 00540 static constexpr bool 00541 lt(const char_type& __c1, const char_type& __c2) noexcept 00542 { return __c1 < __c2; } 00543 00544 static int 00545 compare(const char_type* __s1, const char_type* __s2, size_t __n) 00546 { 00547 for (size_t __i = 0; __i < __n; ++__i) 00548 if (lt(__s1[__i], __s2[__i])) 00549 return -1; 00550 else if (lt(__s2[__i], __s1[__i])) 00551 return 1; 00552 return 0; 00553 } 00554 00555 static size_t 00556 length(const char_type* __s) 00557 { 00558 size_t __i = 0; 00559 while (!eq(__s[__i], char_type())) 00560 ++__i; 00561 return __i; 00562 } 00563 00564 static const char_type* 00565 find(const char_type* __s, size_t __n, const char_type& __a) 00566 { 00567 for (size_t __i = 0; __i < __n; ++__i) 00568 if (eq(__s[__i], __a)) 00569 return __s + __i; 00570 return 0; 00571 } 00572 00573 static char_type* 00574 move(char_type* __s1, const char_type* __s2, size_t __n) 00575 { 00576 if (__n == 0) 00577 return __s1; 00578 return (static_cast<char_type*> 00579 (__builtin_memmove(__s1, __s2, __n * sizeof(char_type)))); 00580 } 00581 00582 static char_type* 00583 copy(char_type* __s1, const char_type* __s2, size_t __n) 00584 { 00585 if (__n == 0) 00586 return __s1; 00587 return (static_cast<char_type*> 00588 (__builtin_memcpy(__s1, __s2, __n * sizeof(char_type)))); 00589 } 00590 00591 static char_type* 00592 assign(char_type* __s, size_t __n, char_type __a) 00593 { 00594 for (size_t __i = 0; __i < __n; ++__i) 00595 assign(__s[__i], __a); 00596 return __s; 00597 } 00598 00599 static constexpr char_type 00600 to_char_type(const int_type& __c) noexcept 00601 { return char_type(__c); } 00602 00603 static constexpr int_type 00604 to_int_type(const char_type& __c) noexcept 00605 { return int_type(__c); } 00606 00607 static constexpr bool 00608 eq_int_type(const int_type& __c1, const int_type& __c2) noexcept 00609 { return __c1 == __c2; } 00610 00611 static constexpr int_type 00612 eof() noexcept 00613 { return static_cast<int_type>(-1); } 00614 00615 static constexpr int_type 00616 not_eof(const int_type& __c) noexcept 00617 { return eq_int_type(__c, eof()) ? 0 : __c; } 00618 }; 00619 00620 _GLIBCXX_END_NAMESPACE_VERSION 00621 } // namespace 00622 00623 #endif 00624 00625 #endif // _CHAR_TRAITS_H