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 return static_cast<_CharT*>(__builtin_memmove(__s1, __s2, 00187 __n * sizeof(char_type))); 00188 } 00189 00190 template<typename _CharT> 00191 typename char_traits<_CharT>::char_type* 00192 char_traits<_CharT>:: 00193 copy(char_type* __s1, const char_type* __s2, std::size_t __n) 00194 { 00195 // NB: Inline std::copy so no recursive dependencies. 00196 std::copy(__s2, __s2 + __n, __s1); 00197 return __s1; 00198 } 00199 00200 template<typename _CharT> 00201 typename char_traits<_CharT>::char_type* 00202 char_traits<_CharT>:: 00203 assign(char_type* __s, std::size_t __n, char_type __a) 00204 { 00205 // NB: Inline std::fill_n so no recursive dependencies. 00206 std::fill_n(__s, __n, __a); 00207 return __s; 00208 } 00209 00210 _GLIBCXX_END_NAMESPACE_VERSION 00211 } // namespace 00212 00213 namespace std _GLIBCXX_VISIBILITY(default) 00214 { 00215 _GLIBCXX_BEGIN_NAMESPACE_VERSION 00216 00217 #if __cplusplus > 201402 00218 #define __cpp_lib_constexpr_char_traits 201611 00219 00220 /** 00221 * @brief Determine whether the characters of a NULL-terminated 00222 * string are known at compile time. 00223 * @param __s The string. 00224 * 00225 * Assumes that _CharT is a built-in character type. 00226 */ 00227 template<typename _CharT> 00228 static _GLIBCXX_ALWAYS_INLINE constexpr bool 00229 __constant_string_p(const _CharT* __s) 00230 { 00231 while (__builtin_constant_p(*__s) && *__s) 00232 __s++; 00233 return __builtin_constant_p(*__s); 00234 } 00235 00236 /** 00237 * @brief Determine whether the characters of a character array are 00238 * known at compile time. 00239 * @param __a The character array. 00240 * @param __n Number of characters. 00241 * 00242 * Assumes that _CharT is a built-in character type. 00243 */ 00244 template<typename _CharT> 00245 static _GLIBCXX_ALWAYS_INLINE constexpr bool 00246 __constant_char_array_p(const _CharT* __a, size_t __n) 00247 { 00248 size_t __i = 0; 00249 while (__builtin_constant_p(__a[__i]) && __i < __n) 00250 __i++; 00251 return __i == __n; 00252 } 00253 #endif 00254 00255 // 21.1 00256 /** 00257 * @brief Basis for explicit traits specializations. 00258 * 00259 * @note For any given actual character type, this definition is 00260 * probably wrong. Since this is just a thin wrapper around 00261 * __gnu_cxx::char_traits, it is possible to achieve a more 00262 * appropriate definition by specializing __gnu_cxx::char_traits. 00263 * 00264 * See https://gcc.gnu.org/onlinedocs/libstdc++/manual/strings.html#strings.string.character_types 00265 * for advice on how to make use of this class for @a unusual character 00266 * types. Also, check out include/ext/pod_char_traits.h. 00267 */ 00268 template<class _CharT> 00269 struct char_traits : public __gnu_cxx::char_traits<_CharT> 00270 { }; 00271 00272 00273 /// 21.1.3.1 char_traits specializations 00274 template<> 00275 struct char_traits<char> 00276 { 00277 typedef char char_type; 00278 typedef int int_type; 00279 typedef streampos pos_type; 00280 typedef streamoff off_type; 00281 typedef mbstate_t state_type; 00282 00283 static _GLIBCXX17_CONSTEXPR void 00284 assign(char_type& __c1, const char_type& __c2) _GLIBCXX_NOEXCEPT 00285 { __c1 = __c2; } 00286 00287 static _GLIBCXX_CONSTEXPR bool 00288 eq(const char_type& __c1, const char_type& __c2) _GLIBCXX_NOEXCEPT 00289 { return __c1 == __c2; } 00290 00291 static _GLIBCXX_CONSTEXPR bool 00292 lt(const char_type& __c1, const char_type& __c2) _GLIBCXX_NOEXCEPT 00293 { 00294 // LWG 467. 00295 return (static_cast<unsigned char>(__c1) 00296 < static_cast<unsigned char>(__c2)); 00297 } 00298 00299 static _GLIBCXX17_CONSTEXPR int 00300 compare(const char_type* __s1, const char_type* __s2, size_t __n) 00301 { 00302 #if __cplusplus > 201402 00303 if (__builtin_constant_p(__n) 00304 && __constant_char_array_p(__s1, __n) 00305 && __constant_char_array_p(__s2, __n)) 00306 return __gnu_cxx::char_traits<char_type>::compare(__s1, __s2, __n); 00307 #endif 00308 if (__n == 0) 00309 return 0; 00310 return __builtin_memcmp(__s1, __s2, __n); 00311 } 00312 00313 static _GLIBCXX17_CONSTEXPR size_t 00314 length(const char_type* __s) 00315 { 00316 #if __cplusplus > 201402 00317 if (__constant_string_p(__s)) 00318 return __gnu_cxx::char_traits<char_type>::length(__s); 00319 #endif 00320 return __builtin_strlen(__s); 00321 } 00322 00323 static _GLIBCXX17_CONSTEXPR const char_type* 00324 find(const char_type* __s, size_t __n, const char_type& __a) 00325 { 00326 #if __cplusplus > 201402 00327 if (__builtin_constant_p(__n) 00328 && __builtin_constant_p(__a) 00329 && __constant_char_array_p(__s, __n)) 00330 return __gnu_cxx::char_traits<char_type>::find(__s, __n, __a); 00331 #endif 00332 if (__n == 0) 00333 return 0; 00334 return static_cast<const char_type*>(__builtin_memchr(__s, __a, __n)); 00335 } 00336 00337 static char_type* 00338 move(char_type* __s1, const char_type* __s2, size_t __n) 00339 { 00340 if (__n == 0) 00341 return __s1; 00342 return static_cast<char_type*>(__builtin_memmove(__s1, __s2, __n)); 00343 } 00344 00345 static char_type* 00346 copy(char_type* __s1, const char_type* __s2, size_t __n) 00347 { 00348 if (__n == 0) 00349 return __s1; 00350 return static_cast<char_type*>(__builtin_memcpy(__s1, __s2, __n)); 00351 } 00352 00353 static char_type* 00354 assign(char_type* __s, size_t __n, char_type __a) 00355 { 00356 if (__n == 0) 00357 return __s; 00358 return static_cast<char_type*>(__builtin_memset(__s, __a, __n)); 00359 } 00360 00361 static _GLIBCXX_CONSTEXPR char_type 00362 to_char_type(const int_type& __c) _GLIBCXX_NOEXCEPT 00363 { return static_cast<char_type>(__c); } 00364 00365 // To keep both the byte 0xff and the eof symbol 0xffffffff 00366 // from ending up as 0xffffffff. 00367 static _GLIBCXX_CONSTEXPR int_type 00368 to_int_type(const char_type& __c) _GLIBCXX_NOEXCEPT 00369 { return static_cast<int_type>(static_cast<unsigned char>(__c)); } 00370 00371 static _GLIBCXX_CONSTEXPR bool 00372 eq_int_type(const int_type& __c1, const int_type& __c2) _GLIBCXX_NOEXCEPT 00373 { return __c1 == __c2; } 00374 00375 static _GLIBCXX_CONSTEXPR int_type 00376 eof() _GLIBCXX_NOEXCEPT 00377 { return static_cast<int_type>(_GLIBCXX_STDIO_EOF); } 00378 00379 static _GLIBCXX_CONSTEXPR int_type 00380 not_eof(const int_type& __c) _GLIBCXX_NOEXCEPT 00381 { return (__c == eof()) ? 0 : __c; } 00382 }; 00383 00384 00385 #ifdef _GLIBCXX_USE_WCHAR_T 00386 /// 21.1.3.2 char_traits specializations 00387 template<> 00388 struct char_traits<wchar_t> 00389 { 00390 typedef wchar_t char_type; 00391 typedef wint_t int_type; 00392 typedef streamoff off_type; 00393 typedef wstreampos pos_type; 00394 typedef mbstate_t state_type; 00395 00396 static _GLIBCXX17_CONSTEXPR void 00397 assign(char_type& __c1, const char_type& __c2) _GLIBCXX_NOEXCEPT 00398 { __c1 = __c2; } 00399 00400 static _GLIBCXX_CONSTEXPR bool 00401 eq(const char_type& __c1, const char_type& __c2) _GLIBCXX_NOEXCEPT 00402 { return __c1 == __c2; } 00403 00404 static _GLIBCXX_CONSTEXPR bool 00405 lt(const char_type& __c1, const char_type& __c2) _GLIBCXX_NOEXCEPT 00406 { return __c1 < __c2; } 00407 00408 static _GLIBCXX17_CONSTEXPR int 00409 compare(const char_type* __s1, const char_type* __s2, size_t __n) 00410 { 00411 #if __cplusplus > 201402 00412 if (__builtin_constant_p(__n) 00413 && __constant_char_array_p(__s1, __n) 00414 && __constant_char_array_p(__s2, __n)) 00415 return __gnu_cxx::char_traits<char_type>::compare(__s1, __s2, __n); 00416 #endif 00417 if (__n == 0) 00418 return 0; 00419 else 00420 return wmemcmp(__s1, __s2, __n); 00421 } 00422 00423 static _GLIBCXX17_CONSTEXPR size_t 00424 length(const char_type* __s) 00425 { 00426 #if __cplusplus > 201402 00427 if (__constant_string_p(__s)) 00428 return __gnu_cxx::char_traits<char_type>::length(__s); 00429 else 00430 #endif 00431 return wcslen(__s); 00432 } 00433 00434 static _GLIBCXX17_CONSTEXPR const char_type* 00435 find(const char_type* __s, size_t __n, const char_type& __a) 00436 { 00437 #if __cplusplus > 201402 00438 if (__builtin_constant_p(__n) 00439 && __builtin_constant_p(__a) 00440 && __constant_char_array_p(__s, __n)) 00441 return __gnu_cxx::char_traits<char_type>::find(__s, __n, __a); 00442 #endif 00443 if (__n == 0) 00444 return 0; 00445 else 00446 return wmemchr(__s, __a, __n); 00447 } 00448 00449 static char_type* 00450 move(char_type* __s1, const char_type* __s2, size_t __n) 00451 { 00452 if (__n == 0) 00453 return __s1; 00454 return wmemmove(__s1, __s2, __n); 00455 } 00456 00457 static char_type* 00458 copy(char_type* __s1, const char_type* __s2, size_t __n) 00459 { 00460 if (__n == 0) 00461 return __s1; 00462 return wmemcpy(__s1, __s2, __n); 00463 } 00464 00465 static char_type* 00466 assign(char_type* __s, size_t __n, char_type __a) 00467 { 00468 if (__n == 0) 00469 return __s; 00470 return wmemset(__s, __a, __n); 00471 } 00472 00473 static _GLIBCXX_CONSTEXPR char_type 00474 to_char_type(const int_type& __c) _GLIBCXX_NOEXCEPT 00475 { return char_type(__c); } 00476 00477 static _GLIBCXX_CONSTEXPR int_type 00478 to_int_type(const char_type& __c) _GLIBCXX_NOEXCEPT 00479 { return int_type(__c); } 00480 00481 static _GLIBCXX_CONSTEXPR bool 00482 eq_int_type(const int_type& __c1, const int_type& __c2) _GLIBCXX_NOEXCEPT 00483 { return __c1 == __c2; } 00484 00485 static _GLIBCXX_CONSTEXPR int_type 00486 eof() _GLIBCXX_NOEXCEPT 00487 { return static_cast<int_type>(WEOF); } 00488 00489 static _GLIBCXX_CONSTEXPR int_type 00490 not_eof(const int_type& __c) _GLIBCXX_NOEXCEPT 00491 { return eq_int_type(__c, eof()) ? 0 : __c; } 00492 }; 00493 #endif //_GLIBCXX_USE_WCHAR_T 00494 00495 _GLIBCXX_END_NAMESPACE_VERSION 00496 } // namespace 00497 00498 #if ((__cplusplus >= 201103L) \ 00499 && defined(_GLIBCXX_USE_C99_STDINT_TR1)) 00500 00501 #include <cstdint> 00502 00503 namespace std _GLIBCXX_VISIBILITY(default) 00504 { 00505 _GLIBCXX_BEGIN_NAMESPACE_VERSION 00506 00507 template<> 00508 struct char_traits<char16_t> 00509 { 00510 typedef char16_t char_type; 00511 typedef uint_least16_t int_type; 00512 typedef streamoff off_type; 00513 typedef u16streampos pos_type; 00514 typedef mbstate_t state_type; 00515 00516 static _GLIBCXX17_CONSTEXPR void 00517 assign(char_type& __c1, const char_type& __c2) noexcept 00518 { __c1 = __c2; } 00519 00520 static constexpr bool 00521 eq(const char_type& __c1, const char_type& __c2) noexcept 00522 { return __c1 == __c2; } 00523 00524 static constexpr bool 00525 lt(const char_type& __c1, const char_type& __c2) noexcept 00526 { return __c1 < __c2; } 00527 00528 static _GLIBCXX17_CONSTEXPR int 00529 compare(const char_type* __s1, const char_type* __s2, size_t __n) 00530 { 00531 for (size_t __i = 0; __i < __n; ++__i) 00532 if (lt(__s1[__i], __s2[__i])) 00533 return -1; 00534 else if (lt(__s2[__i], __s1[__i])) 00535 return 1; 00536 return 0; 00537 } 00538 00539 static _GLIBCXX17_CONSTEXPR size_t 00540 length(const char_type* __s) 00541 { 00542 size_t __i = 0; 00543 while (!eq(__s[__i], char_type())) 00544 ++__i; 00545 return __i; 00546 } 00547 00548 static _GLIBCXX17_CONSTEXPR const char_type* 00549 find(const char_type* __s, size_t __n, const char_type& __a) 00550 { 00551 for (size_t __i = 0; __i < __n; ++__i) 00552 if (eq(__s[__i], __a)) 00553 return __s + __i; 00554 return 0; 00555 } 00556 00557 static char_type* 00558 move(char_type* __s1, const char_type* __s2, size_t __n) 00559 { 00560 if (__n == 0) 00561 return __s1; 00562 return (static_cast<char_type*> 00563 (__builtin_memmove(__s1, __s2, __n * sizeof(char_type)))); 00564 } 00565 00566 static char_type* 00567 copy(char_type* __s1, const char_type* __s2, size_t __n) 00568 { 00569 if (__n == 0) 00570 return __s1; 00571 return (static_cast<char_type*> 00572 (__builtin_memcpy(__s1, __s2, __n * sizeof(char_type)))); 00573 } 00574 00575 static char_type* 00576 assign(char_type* __s, size_t __n, char_type __a) 00577 { 00578 for (size_t __i = 0; __i < __n; ++__i) 00579 assign(__s[__i], __a); 00580 return __s; 00581 } 00582 00583 static constexpr char_type 00584 to_char_type(const int_type& __c) noexcept 00585 { return char_type(__c); } 00586 00587 static constexpr int_type 00588 to_int_type(const char_type& __c) noexcept 00589 { return __c == eof() ? int_type(0xfffd) : int_type(__c); } 00590 00591 static constexpr bool 00592 eq_int_type(const int_type& __c1, const int_type& __c2) noexcept 00593 { return __c1 == __c2; } 00594 00595 static constexpr int_type 00596 eof() noexcept 00597 { return static_cast<int_type>(-1); } 00598 00599 static constexpr int_type 00600 not_eof(const int_type& __c) noexcept 00601 { return eq_int_type(__c, eof()) ? 0 : __c; } 00602 }; 00603 00604 template<> 00605 struct char_traits<char32_t> 00606 { 00607 typedef char32_t char_type; 00608 typedef uint_least32_t int_type; 00609 typedef streamoff off_type; 00610 typedef u32streampos pos_type; 00611 typedef mbstate_t state_type; 00612 00613 static _GLIBCXX17_CONSTEXPR void 00614 assign(char_type& __c1, const char_type& __c2) noexcept 00615 { __c1 = __c2; } 00616 00617 static constexpr bool 00618 eq(const char_type& __c1, const char_type& __c2) noexcept 00619 { return __c1 == __c2; } 00620 00621 static constexpr bool 00622 lt(const char_type& __c1, const char_type& __c2) noexcept 00623 { return __c1 < __c2; } 00624 00625 static _GLIBCXX17_CONSTEXPR int 00626 compare(const char_type* __s1, const char_type* __s2, size_t __n) 00627 { 00628 for (size_t __i = 0; __i < __n; ++__i) 00629 if (lt(__s1[__i], __s2[__i])) 00630 return -1; 00631 else if (lt(__s2[__i], __s1[__i])) 00632 return 1; 00633 return 0; 00634 } 00635 00636 static _GLIBCXX17_CONSTEXPR size_t 00637 length(const char_type* __s) 00638 { 00639 size_t __i = 0; 00640 while (!eq(__s[__i], char_type())) 00641 ++__i; 00642 return __i; 00643 } 00644 00645 static _GLIBCXX17_CONSTEXPR const char_type* 00646 find(const char_type* __s, size_t __n, const char_type& __a) 00647 { 00648 for (size_t __i = 0; __i < __n; ++__i) 00649 if (eq(__s[__i], __a)) 00650 return __s + __i; 00651 return 0; 00652 } 00653 00654 static char_type* 00655 move(char_type* __s1, const char_type* __s2, size_t __n) 00656 { 00657 if (__n == 0) 00658 return __s1; 00659 return (static_cast<char_type*> 00660 (__builtin_memmove(__s1, __s2, __n * sizeof(char_type)))); 00661 } 00662 00663 static char_type* 00664 copy(char_type* __s1, const char_type* __s2, size_t __n) 00665 { 00666 if (__n == 0) 00667 return __s1; 00668 return (static_cast<char_type*> 00669 (__builtin_memcpy(__s1, __s2, __n * sizeof(char_type)))); 00670 } 00671 00672 static char_type* 00673 assign(char_type* __s, size_t __n, char_type __a) 00674 { 00675 for (size_t __i = 0; __i < __n; ++__i) 00676 assign(__s[__i], __a); 00677 return __s; 00678 } 00679 00680 static constexpr char_type 00681 to_char_type(const int_type& __c) noexcept 00682 { return char_type(__c); } 00683 00684 static constexpr int_type 00685 to_int_type(const char_type& __c) noexcept 00686 { return int_type(__c); } 00687 00688 static constexpr bool 00689 eq_int_type(const int_type& __c1, const int_type& __c2) noexcept 00690 { return __c1 == __c2; } 00691 00692 static constexpr int_type 00693 eof() noexcept 00694 { return static_cast<int_type>(-1); } 00695 00696 static constexpr int_type 00697 not_eof(const int_type& __c) noexcept 00698 { return eq_int_type(__c, eof()) ? 0 : __c; } 00699 }; 00700 00701 _GLIBCXX_END_NAMESPACE_VERSION 00702 } // namespace 00703 00704 #endif 00705 00706 #endif // _CHAR_TRAITS_H