libstdc++
|
00001 // Character Traits for use by standard string and iostream -*- C++ -*- 00002 00003 // Copyright (C) 1997-2018 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 #ifndef _GLIBCXX_ALWAYS_INLINE 00044 #define _GLIBCXX_ALWAYS_INLINE inline __attribute__((__always_inline__)) 00045 #endif 00046 00047 namespace __gnu_cxx _GLIBCXX_VISIBILITY(default) 00048 { 00049 _GLIBCXX_BEGIN_NAMESPACE_VERSION 00050 00051 /** 00052 * @brief Mapping from character type to associated types. 00053 * 00054 * @note This is an implementation class for the generic version 00055 * of char_traits. It defines int_type, off_type, pos_type, and 00056 * state_type. By default these are unsigned long, streamoff, 00057 * streampos, and mbstate_t. Users who need a different set of 00058 * types, but who don't need to change the definitions of any function 00059 * defined in char_traits, can specialize __gnu_cxx::_Char_types 00060 * while leaving __gnu_cxx::char_traits alone. */ 00061 template<typename _CharT> 00062 struct _Char_types 00063 { 00064 typedef unsigned long int_type; 00065 typedef std::streampos pos_type; 00066 typedef std::streamoff off_type; 00067 typedef std::mbstate_t state_type; 00068 }; 00069 00070 00071 /** 00072 * @brief Base class used to implement std::char_traits. 00073 * 00074 * @note For any given actual character type, this definition is 00075 * probably wrong. (Most of the member functions are likely to be 00076 * right, but the int_type and state_type typedefs, and the eof() 00077 * member function, are likely to be wrong.) The reason this class 00078 * exists is so users can specialize it. Classes in namespace std 00079 * may not be specialized for fundamental types, but classes in 00080 * namespace __gnu_cxx may be. 00081 * 00082 * See https://gcc.gnu.org/onlinedocs/libstdc++/manual/strings.html#strings.string.character_types 00083 * for advice on how to make use of this class for @a unusual character 00084 * types. Also, check out include/ext/pod_char_traits.h. 00085 */ 00086 template<typename _CharT> 00087 struct char_traits 00088 { 00089 typedef _CharT char_type; 00090 typedef typename _Char_types<_CharT>::int_type int_type; 00091 typedef typename _Char_types<_CharT>::pos_type pos_type; 00092 typedef typename _Char_types<_CharT>::off_type off_type; 00093 typedef typename _Char_types<_CharT>::state_type state_type; 00094 00095 static _GLIBCXX14_CONSTEXPR void 00096 assign(char_type& __c1, const char_type& __c2) 00097 { __c1 = __c2; } 00098 00099 static _GLIBCXX_CONSTEXPR bool 00100 eq(const char_type& __c1, const char_type& __c2) 00101 { return __c1 == __c2; } 00102 00103 static _GLIBCXX_CONSTEXPR bool 00104 lt(const char_type& __c1, const char_type& __c2) 00105 { return __c1 < __c2; } 00106 00107 static _GLIBCXX14_CONSTEXPR int 00108 compare(const char_type* __s1, const char_type* __s2, std::size_t __n); 00109 00110 static _GLIBCXX14_CONSTEXPR std::size_t 00111 length(const char_type* __s); 00112 00113 static _GLIBCXX14_CONSTEXPR const char_type* 00114 find(const char_type* __s, std::size_t __n, const char_type& __a); 00115 00116 static char_type* 00117 move(char_type* __s1, const char_type* __s2, std::size_t __n); 00118 00119 static char_type* 00120 copy(char_type* __s1, const char_type* __s2, std::size_t __n); 00121 00122 static char_type* 00123 assign(char_type* __s, std::size_t __n, char_type __a); 00124 00125 static _GLIBCXX_CONSTEXPR char_type 00126 to_char_type(const int_type& __c) 00127 { return static_cast<char_type>(__c); } 00128 00129 static _GLIBCXX_CONSTEXPR int_type 00130 to_int_type(const char_type& __c) 00131 { return static_cast<int_type>(__c); } 00132 00133 static _GLIBCXX_CONSTEXPR bool 00134 eq_int_type(const int_type& __c1, const int_type& __c2) 00135 { return __c1 == __c2; } 00136 00137 static _GLIBCXX_CONSTEXPR int_type 00138 eof() 00139 { return static_cast<int_type>(_GLIBCXX_STDIO_EOF); } 00140 00141 static _GLIBCXX_CONSTEXPR int_type 00142 not_eof(const int_type& __c) 00143 { return !eq_int_type(__c, eof()) ? __c : to_int_type(char_type()); } 00144 }; 00145 00146 template<typename _CharT> 00147 _GLIBCXX14_CONSTEXPR int 00148 char_traits<_CharT>:: 00149 compare(const char_type* __s1, const char_type* __s2, std::size_t __n) 00150 { 00151 for (std::size_t __i = 0; __i < __n; ++__i) 00152 if (lt(__s1[__i], __s2[__i])) 00153 return -1; 00154 else if (lt(__s2[__i], __s1[__i])) 00155 return 1; 00156 return 0; 00157 } 00158 00159 template<typename _CharT> 00160 _GLIBCXX14_CONSTEXPR std::size_t 00161 char_traits<_CharT>:: 00162 length(const char_type* __p) 00163 { 00164 std::size_t __i = 0; 00165 while (!eq(__p[__i], char_type())) 00166 ++__i; 00167 return __i; 00168 } 00169 00170 template<typename _CharT> 00171 _GLIBCXX14_CONSTEXPR const typename char_traits<_CharT>::char_type* 00172 char_traits<_CharT>:: 00173 find(const char_type* __s, std::size_t __n, const char_type& __a) 00174 { 00175 for (std::size_t __i = 0; __i < __n; ++__i) 00176 if (eq(__s[__i], __a)) 00177 return __s + __i; 00178 return 0; 00179 } 00180 00181 template<typename _CharT> 00182 typename char_traits<_CharT>::char_type* 00183 char_traits<_CharT>:: 00184 move(char_type* __s1, const char_type* __s2, std::size_t __n) 00185 { 00186 if (__n == 0) 00187 return __s1; 00188 return static_cast<_CharT*>(__builtin_memmove(__s1, __s2, 00189 __n * sizeof(char_type))); 00190 } 00191 00192 template<typename _CharT> 00193 typename char_traits<_CharT>::char_type* 00194 char_traits<_CharT>:: 00195 copy(char_type* __s1, const char_type* __s2, std::size_t __n) 00196 { 00197 // NB: Inline std::copy so no recursive dependencies. 00198 std::copy(__s2, __s2 + __n, __s1); 00199 return __s1; 00200 } 00201 00202 template<typename _CharT> 00203 typename char_traits<_CharT>::char_type* 00204 char_traits<_CharT>:: 00205 assign(char_type* __s, std::size_t __n, char_type __a) 00206 { 00207 // NB: Inline std::fill_n so no recursive dependencies. 00208 std::fill_n(__s, __n, __a); 00209 return __s; 00210 } 00211 00212 _GLIBCXX_END_NAMESPACE_VERSION 00213 } // namespace 00214 00215 namespace std _GLIBCXX_VISIBILITY(default) 00216 { 00217 _GLIBCXX_BEGIN_NAMESPACE_VERSION 00218 00219 #if __cplusplus > 201402 00220 #define __cpp_lib_constexpr_char_traits 201611 00221 00222 /** 00223 * @brief Determine whether the characters of a NULL-terminated 00224 * string are known at compile time. 00225 * @param __s The string. 00226 * 00227 * Assumes that _CharT is a built-in character type. 00228 */ 00229 template<typename _CharT> 00230 static _GLIBCXX_ALWAYS_INLINE constexpr bool 00231 __constant_string_p(const _CharT* __s) 00232 { 00233 while (__builtin_constant_p(*__s) && *__s) 00234 __s++; 00235 return __builtin_constant_p(*__s); 00236 } 00237 00238 /** 00239 * @brief Determine whether the characters of a character array are 00240 * known at compile time. 00241 * @param __a The character array. 00242 * @param __n Number of characters. 00243 * 00244 * Assumes that _CharT is a built-in character type. 00245 */ 00246 template<typename _CharT> 00247 static _GLIBCXX_ALWAYS_INLINE constexpr bool 00248 __constant_char_array_p(const _CharT* __a, size_t __n) 00249 { 00250 size_t __i = 0; 00251 while (__i < __n && __builtin_constant_p(__a[__i])) 00252 __i++; 00253 return __i == __n; 00254 } 00255 #endif 00256 00257 // 21.1 00258 /** 00259 * @brief Basis for explicit traits specializations. 00260 * 00261 * @note For any given actual character type, this definition is 00262 * probably wrong. Since this is just a thin wrapper around 00263 * __gnu_cxx::char_traits, it is possible to achieve a more 00264 * appropriate definition by specializing __gnu_cxx::char_traits. 00265 * 00266 * See https://gcc.gnu.org/onlinedocs/libstdc++/manual/strings.html#strings.string.character_types 00267 * for advice on how to make use of this class for @a unusual character 00268 * types. Also, check out include/ext/pod_char_traits.h. 00269 */ 00270 template<class _CharT> 00271 struct char_traits : public __gnu_cxx::char_traits<_CharT> 00272 { }; 00273 00274 00275 /// 21.1.3.1 char_traits specializations 00276 template<> 00277 struct char_traits<char> 00278 { 00279 typedef char char_type; 00280 typedef int int_type; 00281 typedef streampos pos_type; 00282 typedef streamoff off_type; 00283 typedef mbstate_t state_type; 00284 00285 static _GLIBCXX17_CONSTEXPR void 00286 assign(char_type& __c1, const char_type& __c2) _GLIBCXX_NOEXCEPT 00287 { __c1 = __c2; } 00288 00289 static _GLIBCXX_CONSTEXPR bool 00290 eq(const char_type& __c1, const char_type& __c2) _GLIBCXX_NOEXCEPT 00291 { return __c1 == __c2; } 00292 00293 static _GLIBCXX_CONSTEXPR bool 00294 lt(const char_type& __c1, const char_type& __c2) _GLIBCXX_NOEXCEPT 00295 { 00296 // LWG 467. 00297 return (static_cast<unsigned char>(__c1) 00298 < static_cast<unsigned char>(__c2)); 00299 } 00300 00301 static _GLIBCXX17_CONSTEXPR int 00302 compare(const char_type* __s1, const char_type* __s2, size_t __n) 00303 { 00304 #if __cplusplus > 201402 00305 if (__builtin_constant_p(__n) 00306 && __constant_char_array_p(__s1, __n) 00307 && __constant_char_array_p(__s2, __n)) 00308 return __gnu_cxx::char_traits<char_type>::compare(__s1, __s2, __n); 00309 #endif 00310 if (__n == 0) 00311 return 0; 00312 return __builtin_memcmp(__s1, __s2, __n); 00313 } 00314 00315 static _GLIBCXX17_CONSTEXPR size_t 00316 length(const char_type* __s) 00317 { 00318 #if __cplusplus > 201402 00319 if (__constant_string_p(__s)) 00320 return __gnu_cxx::char_traits<char_type>::length(__s); 00321 #endif 00322 return __builtin_strlen(__s); 00323 } 00324 00325 static _GLIBCXX17_CONSTEXPR const char_type* 00326 find(const char_type* __s, size_t __n, const char_type& __a) 00327 { 00328 #if __cplusplus > 201402 00329 if (__builtin_constant_p(__n) 00330 && __builtin_constant_p(__a) 00331 && __constant_char_array_p(__s, __n)) 00332 return __gnu_cxx::char_traits<char_type>::find(__s, __n, __a); 00333 #endif 00334 if (__n == 0) 00335 return 0; 00336 return static_cast<const char_type*>(__builtin_memchr(__s, __a, __n)); 00337 } 00338 00339 static char_type* 00340 move(char_type* __s1, const char_type* __s2, size_t __n) 00341 { 00342 if (__n == 0) 00343 return __s1; 00344 return static_cast<char_type*>(__builtin_memmove(__s1, __s2, __n)); 00345 } 00346 00347 static char_type* 00348 copy(char_type* __s1, const char_type* __s2, size_t __n) 00349 { 00350 if (__n == 0) 00351 return __s1; 00352 return static_cast<char_type*>(__builtin_memcpy(__s1, __s2, __n)); 00353 } 00354 00355 static char_type* 00356 assign(char_type* __s, size_t __n, char_type __a) 00357 { 00358 if (__n == 0) 00359 return __s; 00360 return static_cast<char_type*>(__builtin_memset(__s, __a, __n)); 00361 } 00362 00363 static _GLIBCXX_CONSTEXPR char_type 00364 to_char_type(const int_type& __c) _GLIBCXX_NOEXCEPT 00365 { return static_cast<char_type>(__c); } 00366 00367 // To keep both the byte 0xff and the eof symbol 0xffffffff 00368 // from ending up as 0xffffffff. 00369 static _GLIBCXX_CONSTEXPR int_type 00370 to_int_type(const char_type& __c) _GLIBCXX_NOEXCEPT 00371 { return static_cast<int_type>(static_cast<unsigned char>(__c)); } 00372 00373 static _GLIBCXX_CONSTEXPR bool 00374 eq_int_type(const int_type& __c1, const int_type& __c2) _GLIBCXX_NOEXCEPT 00375 { return __c1 == __c2; } 00376 00377 static _GLIBCXX_CONSTEXPR int_type 00378 eof() _GLIBCXX_NOEXCEPT 00379 { return static_cast<int_type>(_GLIBCXX_STDIO_EOF); } 00380 00381 static _GLIBCXX_CONSTEXPR int_type 00382 not_eof(const int_type& __c) _GLIBCXX_NOEXCEPT 00383 { return (__c == eof()) ? 0 : __c; } 00384 }; 00385 00386 00387 #ifdef _GLIBCXX_USE_WCHAR_T 00388 /// 21.1.3.2 char_traits specializations 00389 template<> 00390 struct char_traits<wchar_t> 00391 { 00392 typedef wchar_t char_type; 00393 typedef wint_t int_type; 00394 typedef streamoff off_type; 00395 typedef wstreampos pos_type; 00396 typedef mbstate_t state_type; 00397 00398 static _GLIBCXX17_CONSTEXPR void 00399 assign(char_type& __c1, const char_type& __c2) _GLIBCXX_NOEXCEPT 00400 { __c1 = __c2; } 00401 00402 static _GLIBCXX_CONSTEXPR bool 00403 eq(const char_type& __c1, const char_type& __c2) _GLIBCXX_NOEXCEPT 00404 { return __c1 == __c2; } 00405 00406 static _GLIBCXX_CONSTEXPR bool 00407 lt(const char_type& __c1, const char_type& __c2) _GLIBCXX_NOEXCEPT 00408 { return __c1 < __c2; } 00409 00410 static _GLIBCXX17_CONSTEXPR int 00411 compare(const char_type* __s1, const char_type* __s2, size_t __n) 00412 { 00413 #if __cplusplus > 201402 00414 if (__builtin_constant_p(__n) 00415 && __constant_char_array_p(__s1, __n) 00416 && __constant_char_array_p(__s2, __n)) 00417 return __gnu_cxx::char_traits<char_type>::compare(__s1, __s2, __n); 00418 #endif 00419 if (__n == 0) 00420 return 0; 00421 else 00422 return wmemcmp(__s1, __s2, __n); 00423 } 00424 00425 static _GLIBCXX17_CONSTEXPR size_t 00426 length(const char_type* __s) 00427 { 00428 #if __cplusplus > 201402 00429 if (__constant_string_p(__s)) 00430 return __gnu_cxx::char_traits<char_type>::length(__s); 00431 else 00432 #endif 00433 return wcslen(__s); 00434 } 00435 00436 static _GLIBCXX17_CONSTEXPR const char_type* 00437 find(const char_type* __s, size_t __n, const char_type& __a) 00438 { 00439 #if __cplusplus > 201402 00440 if (__builtin_constant_p(__n) 00441 && __builtin_constant_p(__a) 00442 && __constant_char_array_p(__s, __n)) 00443 return __gnu_cxx::char_traits<char_type>::find(__s, __n, __a); 00444 #endif 00445 if (__n == 0) 00446 return 0; 00447 else 00448 return wmemchr(__s, __a, __n); 00449 } 00450 00451 static char_type* 00452 move(char_type* __s1, const char_type* __s2, size_t __n) 00453 { 00454 if (__n == 0) 00455 return __s1; 00456 return wmemmove(__s1, __s2, __n); 00457 } 00458 00459 static char_type* 00460 copy(char_type* __s1, const char_type* __s2, size_t __n) 00461 { 00462 if (__n == 0) 00463 return __s1; 00464 return wmemcpy(__s1, __s2, __n); 00465 } 00466 00467 static char_type* 00468 assign(char_type* __s, size_t __n, char_type __a) 00469 { 00470 if (__n == 0) 00471 return __s; 00472 return wmemset(__s, __a, __n); 00473 } 00474 00475 static _GLIBCXX_CONSTEXPR char_type 00476 to_char_type(const int_type& __c) _GLIBCXX_NOEXCEPT 00477 { return char_type(__c); } 00478 00479 static _GLIBCXX_CONSTEXPR int_type 00480 to_int_type(const char_type& __c) _GLIBCXX_NOEXCEPT 00481 { return int_type(__c); } 00482 00483 static _GLIBCXX_CONSTEXPR bool 00484 eq_int_type(const int_type& __c1, const int_type& __c2) _GLIBCXX_NOEXCEPT 00485 { return __c1 == __c2; } 00486 00487 static _GLIBCXX_CONSTEXPR int_type 00488 eof() _GLIBCXX_NOEXCEPT 00489 { return static_cast<int_type>(WEOF); } 00490 00491 static _GLIBCXX_CONSTEXPR int_type 00492 not_eof(const int_type& __c) _GLIBCXX_NOEXCEPT 00493 { return eq_int_type(__c, eof()) ? 0 : __c; } 00494 }; 00495 #endif //_GLIBCXX_USE_WCHAR_T 00496 00497 _GLIBCXX_END_NAMESPACE_VERSION 00498 } // namespace 00499 00500 #if ((__cplusplus >= 201103L) \ 00501 && defined(_GLIBCXX_USE_C99_STDINT_TR1)) 00502 00503 #include <cstdint> 00504 00505 namespace std _GLIBCXX_VISIBILITY(default) 00506 { 00507 _GLIBCXX_BEGIN_NAMESPACE_VERSION 00508 00509 template<> 00510 struct char_traits<char16_t> 00511 { 00512 typedef char16_t char_type; 00513 typedef uint_least16_t int_type; 00514 typedef streamoff off_type; 00515 typedef u16streampos pos_type; 00516 typedef mbstate_t state_type; 00517 00518 static _GLIBCXX17_CONSTEXPR void 00519 assign(char_type& __c1, const char_type& __c2) noexcept 00520 { __c1 = __c2; } 00521 00522 static constexpr bool 00523 eq(const char_type& __c1, const char_type& __c2) noexcept 00524 { return __c1 == __c2; } 00525 00526 static constexpr bool 00527 lt(const char_type& __c1, const char_type& __c2) noexcept 00528 { return __c1 < __c2; } 00529 00530 static _GLIBCXX17_CONSTEXPR int 00531 compare(const char_type* __s1, const char_type* __s2, size_t __n) 00532 { 00533 for (size_t __i = 0; __i < __n; ++__i) 00534 if (lt(__s1[__i], __s2[__i])) 00535 return -1; 00536 else if (lt(__s2[__i], __s1[__i])) 00537 return 1; 00538 return 0; 00539 } 00540 00541 static _GLIBCXX17_CONSTEXPR size_t 00542 length(const char_type* __s) 00543 { 00544 size_t __i = 0; 00545 while (!eq(__s[__i], char_type())) 00546 ++__i; 00547 return __i; 00548 } 00549 00550 static _GLIBCXX17_CONSTEXPR const char_type* 00551 find(const char_type* __s, size_t __n, const char_type& __a) 00552 { 00553 for (size_t __i = 0; __i < __n; ++__i) 00554 if (eq(__s[__i], __a)) 00555 return __s + __i; 00556 return 0; 00557 } 00558 00559 static char_type* 00560 move(char_type* __s1, const char_type* __s2, size_t __n) 00561 { 00562 if (__n == 0) 00563 return __s1; 00564 return (static_cast<char_type*> 00565 (__builtin_memmove(__s1, __s2, __n * sizeof(char_type)))); 00566 } 00567 00568 static char_type* 00569 copy(char_type* __s1, const char_type* __s2, size_t __n) 00570 { 00571 if (__n == 0) 00572 return __s1; 00573 return (static_cast<char_type*> 00574 (__builtin_memcpy(__s1, __s2, __n * sizeof(char_type)))); 00575 } 00576 00577 static char_type* 00578 assign(char_type* __s, size_t __n, char_type __a) 00579 { 00580 for (size_t __i = 0; __i < __n; ++__i) 00581 assign(__s[__i], __a); 00582 return __s; 00583 } 00584 00585 static constexpr char_type 00586 to_char_type(const int_type& __c) noexcept 00587 { return char_type(__c); } 00588 00589 static constexpr int_type 00590 to_int_type(const char_type& __c) noexcept 00591 { return __c == eof() ? int_type(0xfffd) : int_type(__c); } 00592 00593 static constexpr bool 00594 eq_int_type(const int_type& __c1, const int_type& __c2) noexcept 00595 { return __c1 == __c2; } 00596 00597 static constexpr int_type 00598 eof() noexcept 00599 { return static_cast<int_type>(-1); } 00600 00601 static constexpr int_type 00602 not_eof(const int_type& __c) noexcept 00603 { return eq_int_type(__c, eof()) ? 0 : __c; } 00604 }; 00605 00606 template<> 00607 struct char_traits<char32_t> 00608 { 00609 typedef char32_t char_type; 00610 typedef uint_least32_t int_type; 00611 typedef streamoff off_type; 00612 typedef u32streampos pos_type; 00613 typedef mbstate_t state_type; 00614 00615 static _GLIBCXX17_CONSTEXPR void 00616 assign(char_type& __c1, const char_type& __c2) noexcept 00617 { __c1 = __c2; } 00618 00619 static constexpr bool 00620 eq(const char_type& __c1, const char_type& __c2) noexcept 00621 { return __c1 == __c2; } 00622 00623 static constexpr bool 00624 lt(const char_type& __c1, const char_type& __c2) noexcept 00625 { return __c1 < __c2; } 00626 00627 static _GLIBCXX17_CONSTEXPR int 00628 compare(const char_type* __s1, const char_type* __s2, size_t __n) 00629 { 00630 for (size_t __i = 0; __i < __n; ++__i) 00631 if (lt(__s1[__i], __s2[__i])) 00632 return -1; 00633 else if (lt(__s2[__i], __s1[__i])) 00634 return 1; 00635 return 0; 00636 } 00637 00638 static _GLIBCXX17_CONSTEXPR size_t 00639 length(const char_type* __s) 00640 { 00641 size_t __i = 0; 00642 while (!eq(__s[__i], char_type())) 00643 ++__i; 00644 return __i; 00645 } 00646 00647 static _GLIBCXX17_CONSTEXPR const char_type* 00648 find(const char_type* __s, size_t __n, const char_type& __a) 00649 { 00650 for (size_t __i = 0; __i < __n; ++__i) 00651 if (eq(__s[__i], __a)) 00652 return __s + __i; 00653 return 0; 00654 } 00655 00656 static char_type* 00657 move(char_type* __s1, const char_type* __s2, size_t __n) 00658 { 00659 if (__n == 0) 00660 return __s1; 00661 return (static_cast<char_type*> 00662 (__builtin_memmove(__s1, __s2, __n * sizeof(char_type)))); 00663 } 00664 00665 static char_type* 00666 copy(char_type* __s1, const char_type* __s2, size_t __n) 00667 { 00668 if (__n == 0) 00669 return __s1; 00670 return (static_cast<char_type*> 00671 (__builtin_memcpy(__s1, __s2, __n * sizeof(char_type)))); 00672 } 00673 00674 static char_type* 00675 assign(char_type* __s, size_t __n, char_type __a) 00676 { 00677 for (size_t __i = 0; __i < __n; ++__i) 00678 assign(__s[__i], __a); 00679 return __s; 00680 } 00681 00682 static constexpr char_type 00683 to_char_type(const int_type& __c) noexcept 00684 { return char_type(__c); } 00685 00686 static constexpr int_type 00687 to_int_type(const char_type& __c) noexcept 00688 { return int_type(__c); } 00689 00690 static constexpr bool 00691 eq_int_type(const int_type& __c1, const int_type& __c2) noexcept 00692 { return __c1 == __c2; } 00693 00694 static constexpr int_type 00695 eof() noexcept 00696 { return static_cast<int_type>(-1); } 00697 00698 static constexpr int_type 00699 not_eof(const int_type& __c) noexcept 00700 { return eq_int_type(__c, eof()) ? 0 : __c; } 00701 }; 00702 00703 _GLIBCXX_END_NAMESPACE_VERSION 00704 } // namespace 00705 00706 #endif 00707 00708 #endif // _CHAR_TRAITS_H