Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

944 lines
28KB

  1. // Character Traits for use by standard string and iostream -*- C++ -*-
  2. // Copyright (C) 1997-2020 Free Software Foundation, Inc.
  3. //
  4. // This file is part of the GNU ISO C++ Library. This library is free
  5. // software; you can redistribute it and/or modify it under the
  6. // terms of the GNU General Public License as published by the
  7. // Free Software Foundation; either version 3, or (at your option)
  8. // any later version.
  9. // This library is distributed in the hope that it will be useful,
  10. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. // GNU General Public License for more details.
  13. // Under Section 7 of GPL version 3, you are granted additional
  14. // permissions described in the GCC Runtime Library Exception, version
  15. // 3.1, as published by the Free Software Foundation.
  16. // You should have received a copy of the GNU General Public License and
  17. // a copy of the GCC Runtime Library Exception along with this program;
  18. // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
  19. // <http://www.gnu.org/licenses/>.
  20. /** @file bits/char_traits.h
  21. * This is an internal header file, included by other library headers.
  22. * Do not attempt to use it directly. @headername{string}
  23. */
  24. //
  25. // ISO C++ 14882: 21 Strings library
  26. //
  27. #ifndef _CHAR_TRAITS_H
  28. #define _CHAR_TRAITS_H 1
  29. #pragma GCC system_header
  30. #include <bits/stl_algobase.h> // std::copy, std::fill_n
  31. #include <bits/postypes.h> // For streampos
  32. #include <cwchar> // For WEOF, wmemmove, wmemset, etc.
  33. #if __cplusplus > 201703L
  34. # include <compare>
  35. #endif
  36. #ifndef _GLIBCXX_ALWAYS_INLINE
  37. # define _GLIBCXX_ALWAYS_INLINE inline __attribute__((__always_inline__))
  38. #endif
  39. namespace __gnu_cxx _GLIBCXX_VISIBILITY(default)
  40. {
  41. _GLIBCXX_BEGIN_NAMESPACE_VERSION
  42. /**
  43. * @brief Mapping from character type to associated types.
  44. *
  45. * @note This is an implementation class for the generic version
  46. * of char_traits. It defines int_type, off_type, pos_type, and
  47. * state_type. By default these are unsigned long, streamoff,
  48. * streampos, and mbstate_t. Users who need a different set of
  49. * types, but who don't need to change the definitions of any function
  50. * defined in char_traits, can specialize __gnu_cxx::_Char_types
  51. * while leaving __gnu_cxx::char_traits alone. */
  52. template<typename _CharT>
  53. struct _Char_types
  54. {
  55. typedef unsigned long int_type;
  56. typedef std::streampos pos_type;
  57. typedef std::streamoff off_type;
  58. typedef std::mbstate_t state_type;
  59. };
  60. /**
  61. * @brief Base class used to implement std::char_traits.
  62. *
  63. * @note For any given actual character type, this definition is
  64. * probably wrong. (Most of the member functions are likely to be
  65. * right, but the int_type and state_type typedefs, and the eof()
  66. * member function, are likely to be wrong.) The reason this class
  67. * exists is so users can specialize it. Classes in namespace std
  68. * may not be specialized for fundamental types, but classes in
  69. * namespace __gnu_cxx may be.
  70. *
  71. * See https://gcc.gnu.org/onlinedocs/libstdc++/manual/strings.html#strings.string.character_types
  72. * for advice on how to make use of this class for @a unusual character
  73. * types. Also, check out include/ext/pod_char_traits.h.
  74. */
  75. template<typename _CharT>
  76. struct char_traits
  77. {
  78. typedef _CharT char_type;
  79. typedef typename _Char_types<_CharT>::int_type int_type;
  80. typedef typename _Char_types<_CharT>::pos_type pos_type;
  81. typedef typename _Char_types<_CharT>::off_type off_type;
  82. typedef typename _Char_types<_CharT>::state_type state_type;
  83. #if __cpp_lib_three_way_comparison
  84. using comparison_category = std::strong_ordering;
  85. #endif
  86. static _GLIBCXX14_CONSTEXPR void
  87. assign(char_type& __c1, const char_type& __c2)
  88. { __c1 = __c2; }
  89. static _GLIBCXX_CONSTEXPR bool
  90. eq(const char_type& __c1, const char_type& __c2)
  91. { return __c1 == __c2; }
  92. static _GLIBCXX_CONSTEXPR bool
  93. lt(const char_type& __c1, const char_type& __c2)
  94. { return __c1 < __c2; }
  95. static _GLIBCXX14_CONSTEXPR int
  96. compare(const char_type* __s1, const char_type* __s2, std::size_t __n);
  97. static _GLIBCXX14_CONSTEXPR std::size_t
  98. length(const char_type* __s);
  99. static _GLIBCXX14_CONSTEXPR const char_type*
  100. find(const char_type* __s, std::size_t __n, const char_type& __a);
  101. static _GLIBCXX20_CONSTEXPR char_type*
  102. move(char_type* __s1, const char_type* __s2, std::size_t __n);
  103. static _GLIBCXX20_CONSTEXPR char_type*
  104. copy(char_type* __s1, const char_type* __s2, std::size_t __n);
  105. static _GLIBCXX20_CONSTEXPR char_type*
  106. assign(char_type* __s, std::size_t __n, char_type __a);
  107. static _GLIBCXX_CONSTEXPR char_type
  108. to_char_type(const int_type& __c)
  109. { return static_cast<char_type>(__c); }
  110. static _GLIBCXX_CONSTEXPR int_type
  111. to_int_type(const char_type& __c)
  112. { return static_cast<int_type>(__c); }
  113. static _GLIBCXX_CONSTEXPR bool
  114. eq_int_type(const int_type& __c1, const int_type& __c2)
  115. { return __c1 == __c2; }
  116. static _GLIBCXX_CONSTEXPR int_type
  117. eof()
  118. { return static_cast<int_type>(_GLIBCXX_STDIO_EOF); }
  119. static _GLIBCXX_CONSTEXPR int_type
  120. not_eof(const int_type& __c)
  121. { return !eq_int_type(__c, eof()) ? __c : to_int_type(char_type()); }
  122. };
  123. template<typename _CharT>
  124. _GLIBCXX14_CONSTEXPR int
  125. char_traits<_CharT>::
  126. compare(const char_type* __s1, const char_type* __s2, std::size_t __n)
  127. {
  128. for (std::size_t __i = 0; __i < __n; ++__i)
  129. if (lt(__s1[__i], __s2[__i]))
  130. return -1;
  131. else if (lt(__s2[__i], __s1[__i]))
  132. return 1;
  133. return 0;
  134. }
  135. template<typename _CharT>
  136. _GLIBCXX14_CONSTEXPR std::size_t
  137. char_traits<_CharT>::
  138. length(const char_type* __p)
  139. {
  140. std::size_t __i = 0;
  141. while (!eq(__p[__i], char_type()))
  142. ++__i;
  143. return __i;
  144. }
  145. template<typename _CharT>
  146. _GLIBCXX14_CONSTEXPR const typename char_traits<_CharT>::char_type*
  147. char_traits<_CharT>::
  148. find(const char_type* __s, std::size_t __n, const char_type& __a)
  149. {
  150. for (std::size_t __i = 0; __i < __n; ++__i)
  151. if (eq(__s[__i], __a))
  152. return __s + __i;
  153. return 0;
  154. }
  155. template<typename _CharT>
  156. _GLIBCXX20_CONSTEXPR
  157. typename char_traits<_CharT>::char_type*
  158. char_traits<_CharT>::
  159. move(char_type* __s1, const char_type* __s2, std::size_t __n)
  160. {
  161. if (__n == 0)
  162. return __s1;
  163. #ifdef __cpp_lib_is_constant_evaluated
  164. if (std::is_constant_evaluated())
  165. {
  166. if (__s1 > __s2 && __s1 < __s2 + __n)
  167. std::copy_backward(__s2, __s2 + __n, __s1);
  168. else
  169. std::copy(__s2, __s2 + __n, __s1);
  170. return __s1;
  171. }
  172. #endif
  173. return static_cast<_CharT*>(__builtin_memmove(__s1, __s2,
  174. __n * sizeof(char_type)));
  175. }
  176. template<typename _CharT>
  177. _GLIBCXX20_CONSTEXPR
  178. typename char_traits<_CharT>::char_type*
  179. char_traits<_CharT>::
  180. copy(char_type* __s1, const char_type* __s2, std::size_t __n)
  181. {
  182. // NB: Inline std::copy so no recursive dependencies.
  183. std::copy(__s2, __s2 + __n, __s1);
  184. return __s1;
  185. }
  186. template<typename _CharT>
  187. _GLIBCXX20_CONSTEXPR
  188. typename char_traits<_CharT>::char_type*
  189. char_traits<_CharT>::
  190. assign(char_type* __s, std::size_t __n, char_type __a)
  191. {
  192. // NB: Inline std::fill_n so no recursive dependencies.
  193. std::fill_n(__s, __n, __a);
  194. return __s;
  195. }
  196. _GLIBCXX_END_NAMESPACE_VERSION
  197. } // namespace
  198. namespace std _GLIBCXX_VISIBILITY(default)
  199. {
  200. _GLIBCXX_BEGIN_NAMESPACE_VERSION
  201. #if __cplusplus >= 201703L
  202. #define __cpp_lib_constexpr_char_traits 201611
  203. /**
  204. * @brief Determine whether the characters of a NULL-terminated
  205. * string are known at compile time.
  206. * @param __s The string.
  207. *
  208. * Assumes that _CharT is a built-in character type.
  209. */
  210. template<typename _CharT>
  211. static _GLIBCXX_ALWAYS_INLINE constexpr bool
  212. __constant_string_p(const _CharT* __s)
  213. {
  214. #ifdef _GLIBCXX_HAVE_BUILTIN_IS_CONSTANT_EVALUATED
  215. (void) __s;
  216. // In constexpr contexts all strings should be constant.
  217. return __builtin_is_constant_evaluated();
  218. #else
  219. while (__builtin_constant_p(*__s) && *__s)
  220. __s++;
  221. return __builtin_constant_p(*__s);
  222. #endif
  223. }
  224. /**
  225. * @brief Determine whether the characters of a character array are
  226. * known at compile time.
  227. * @param __a The character array.
  228. * @param __n Number of characters.
  229. *
  230. * Assumes that _CharT is a built-in character type.
  231. */
  232. template<typename _CharT>
  233. static _GLIBCXX_ALWAYS_INLINE constexpr bool
  234. __constant_char_array_p(const _CharT* __a, size_t __n)
  235. {
  236. #ifdef _GLIBCXX_HAVE_BUILTIN_IS_CONSTANT_EVALUATED
  237. (void) __a;
  238. (void) __n;
  239. // In constexpr contexts all character arrays should be constant.
  240. return __builtin_is_constant_evaluated();
  241. #else
  242. size_t __i = 0;
  243. while (__i < __n && __builtin_constant_p(__a[__i]))
  244. __i++;
  245. return __i == __n;
  246. #endif
  247. }
  248. #endif
  249. // 21.1
  250. /**
  251. * @brief Basis for explicit traits specializations.
  252. *
  253. * @note For any given actual character type, this definition is
  254. * probably wrong. Since this is just a thin wrapper around
  255. * __gnu_cxx::char_traits, it is possible to achieve a more
  256. * appropriate definition by specializing __gnu_cxx::char_traits.
  257. *
  258. * See https://gcc.gnu.org/onlinedocs/libstdc++/manual/strings.html#strings.string.character_types
  259. * for advice on how to make use of this class for @a unusual character
  260. * types. Also, check out include/ext/pod_char_traits.h.
  261. */
  262. template<class _CharT>
  263. struct char_traits : public __gnu_cxx::char_traits<_CharT>
  264. { };
  265. /// 21.1.3.1 char_traits specializations
  266. template<>
  267. struct char_traits<char>
  268. {
  269. typedef char char_type;
  270. typedef int int_type;
  271. typedef streampos pos_type;
  272. typedef streamoff off_type;
  273. typedef mbstate_t state_type;
  274. #if __cpp_lib_three_way_comparison
  275. using comparison_category = strong_ordering;
  276. #endif
  277. static _GLIBCXX17_CONSTEXPR void
  278. assign(char_type& __c1, const char_type& __c2) _GLIBCXX_NOEXCEPT
  279. { __c1 = __c2; }
  280. static _GLIBCXX_CONSTEXPR bool
  281. eq(const char_type& __c1, const char_type& __c2) _GLIBCXX_NOEXCEPT
  282. { return __c1 == __c2; }
  283. static _GLIBCXX_CONSTEXPR bool
  284. lt(const char_type& __c1, const char_type& __c2) _GLIBCXX_NOEXCEPT
  285. {
  286. // LWG 467.
  287. return (static_cast<unsigned char>(__c1)
  288. < static_cast<unsigned char>(__c2));
  289. }
  290. static _GLIBCXX17_CONSTEXPR int
  291. compare(const char_type* __s1, const char_type* __s2, size_t __n)
  292. {
  293. if (__n == 0)
  294. return 0;
  295. #if __cplusplus >= 201703L
  296. if (__builtin_constant_p(__n)
  297. && __constant_char_array_p(__s1, __n)
  298. && __constant_char_array_p(__s2, __n))
  299. return __gnu_cxx::char_traits<char_type>::compare(__s1, __s2, __n);
  300. #endif
  301. return __builtin_memcmp(__s1, __s2, __n);
  302. }
  303. static _GLIBCXX17_CONSTEXPR size_t
  304. length(const char_type* __s)
  305. {
  306. #if __cplusplus >= 201703L
  307. if (__constant_string_p(__s))
  308. return __gnu_cxx::char_traits<char_type>::length(__s);
  309. #endif
  310. return __builtin_strlen(__s);
  311. }
  312. static _GLIBCXX17_CONSTEXPR const char_type*
  313. find(const char_type* __s, size_t __n, const char_type& __a)
  314. {
  315. if (__n == 0)
  316. return 0;
  317. #if __cplusplus >= 201703L
  318. if (__builtin_constant_p(__n)
  319. && __builtin_constant_p(__a)
  320. && __constant_char_array_p(__s, __n))
  321. return __gnu_cxx::char_traits<char_type>::find(__s, __n, __a);
  322. #endif
  323. return static_cast<const char_type*>(__builtin_memchr(__s, __a, __n));
  324. }
  325. static _GLIBCXX20_CONSTEXPR char_type*
  326. move(char_type* __s1, const char_type* __s2, size_t __n)
  327. {
  328. if (__n == 0)
  329. return __s1;
  330. #ifdef __cpp_lib_is_constant_evaluated
  331. if (std::is_constant_evaluated())
  332. return __gnu_cxx::char_traits<char_type>::move(__s1, __s2, __n);
  333. #endif
  334. return static_cast<char_type*>(__builtin_memmove(__s1, __s2, __n));
  335. }
  336. static _GLIBCXX20_CONSTEXPR char_type*
  337. copy(char_type* __s1, const char_type* __s2, size_t __n)
  338. {
  339. if (__n == 0)
  340. return __s1;
  341. #ifdef __cpp_lib_is_constant_evaluated
  342. if (std::is_constant_evaluated())
  343. return __gnu_cxx::char_traits<char_type>::copy(__s1, __s2, __n);
  344. #endif
  345. return static_cast<char_type*>(__builtin_memcpy(__s1, __s2, __n));
  346. }
  347. static _GLIBCXX20_CONSTEXPR char_type*
  348. assign(char_type* __s, size_t __n, char_type __a)
  349. {
  350. if (__n == 0)
  351. return __s;
  352. #ifdef __cpp_lib_is_constant_evaluated
  353. if (std::is_constant_evaluated())
  354. return __gnu_cxx::char_traits<char_type>::assign(__s, __n, __a);
  355. #endif
  356. return static_cast<char_type*>(__builtin_memset(__s, __a, __n));
  357. }
  358. static _GLIBCXX_CONSTEXPR char_type
  359. to_char_type(const int_type& __c) _GLIBCXX_NOEXCEPT
  360. { return static_cast<char_type>(__c); }
  361. // To keep both the byte 0xff and the eof symbol 0xffffffff
  362. // from ending up as 0xffffffff.
  363. static _GLIBCXX_CONSTEXPR int_type
  364. to_int_type(const char_type& __c) _GLIBCXX_NOEXCEPT
  365. { return static_cast<int_type>(static_cast<unsigned char>(__c)); }
  366. static _GLIBCXX_CONSTEXPR bool
  367. eq_int_type(const int_type& __c1, const int_type& __c2) _GLIBCXX_NOEXCEPT
  368. { return __c1 == __c2; }
  369. static _GLIBCXX_CONSTEXPR int_type
  370. eof() _GLIBCXX_NOEXCEPT
  371. { return static_cast<int_type>(_GLIBCXX_STDIO_EOF); }
  372. static _GLIBCXX_CONSTEXPR int_type
  373. not_eof(const int_type& __c) _GLIBCXX_NOEXCEPT
  374. { return (__c == eof()) ? 0 : __c; }
  375. };
  376. #ifdef _GLIBCXX_USE_WCHAR_T
  377. /// 21.1.3.2 char_traits specializations
  378. template<>
  379. struct char_traits<wchar_t>
  380. {
  381. typedef wchar_t char_type;
  382. typedef wint_t int_type;
  383. typedef streamoff off_type;
  384. typedef wstreampos pos_type;
  385. typedef mbstate_t state_type;
  386. #if __cpp_lib_three_way_comparison
  387. using comparison_category = strong_ordering;
  388. #endif
  389. static _GLIBCXX17_CONSTEXPR void
  390. assign(char_type& __c1, const char_type& __c2) _GLIBCXX_NOEXCEPT
  391. { __c1 = __c2; }
  392. static _GLIBCXX_CONSTEXPR bool
  393. eq(const char_type& __c1, const char_type& __c2) _GLIBCXX_NOEXCEPT
  394. { return __c1 == __c2; }
  395. static _GLIBCXX_CONSTEXPR bool
  396. lt(const char_type& __c1, const char_type& __c2) _GLIBCXX_NOEXCEPT
  397. { return __c1 < __c2; }
  398. static _GLIBCXX17_CONSTEXPR int
  399. compare(const char_type* __s1, const char_type* __s2, size_t __n)
  400. {
  401. if (__n == 0)
  402. return 0;
  403. #if __cplusplus >= 201703L
  404. if (__builtin_constant_p(__n)
  405. && __constant_char_array_p(__s1, __n)
  406. && __constant_char_array_p(__s2, __n))
  407. return __gnu_cxx::char_traits<char_type>::compare(__s1, __s2, __n);
  408. #endif
  409. return wmemcmp(__s1, __s2, __n);
  410. }
  411. static _GLIBCXX17_CONSTEXPR size_t
  412. length(const char_type* __s)
  413. {
  414. #if __cplusplus >= 201703L
  415. if (__constant_string_p(__s))
  416. return __gnu_cxx::char_traits<char_type>::length(__s);
  417. #endif
  418. return wcslen(__s);
  419. }
  420. static _GLIBCXX17_CONSTEXPR const char_type*
  421. find(const char_type* __s, size_t __n, const char_type& __a)
  422. {
  423. if (__n == 0)
  424. return 0;
  425. #if __cplusplus >= 201703L
  426. if (__builtin_constant_p(__n)
  427. && __builtin_constant_p(__a)
  428. && __constant_char_array_p(__s, __n))
  429. return __gnu_cxx::char_traits<char_type>::find(__s, __n, __a);
  430. #endif
  431. return wmemchr(__s, __a, __n);
  432. }
  433. static _GLIBCXX20_CONSTEXPR char_type*
  434. move(char_type* __s1, const char_type* __s2, size_t __n)
  435. {
  436. if (__n == 0)
  437. return __s1;
  438. #ifdef __cpp_lib_is_constant_evaluated
  439. if (std::is_constant_evaluated())
  440. return __gnu_cxx::char_traits<char_type>::move(__s1, __s2, __n);
  441. #endif
  442. return wmemmove(__s1, __s2, __n);
  443. }
  444. static _GLIBCXX20_CONSTEXPR char_type*
  445. copy(char_type* __s1, const char_type* __s2, size_t __n)
  446. {
  447. if (__n == 0)
  448. return __s1;
  449. #ifdef __cpp_lib_is_constant_evaluated
  450. if (std::is_constant_evaluated())
  451. return __gnu_cxx::char_traits<char_type>::copy(__s1, __s2, __n);
  452. #endif
  453. return wmemcpy(__s1, __s2, __n);
  454. }
  455. static _GLIBCXX20_CONSTEXPR char_type*
  456. assign(char_type* __s, size_t __n, char_type __a)
  457. {
  458. if (__n == 0)
  459. return __s;
  460. #ifdef __cpp_lib_is_constant_evaluated
  461. if (std::is_constant_evaluated())
  462. return __gnu_cxx::char_traits<char_type>::assign(__s, __n, __a);
  463. #endif
  464. return wmemset(__s, __a, __n);
  465. }
  466. static _GLIBCXX_CONSTEXPR char_type
  467. to_char_type(const int_type& __c) _GLIBCXX_NOEXCEPT
  468. { return char_type(__c); }
  469. static _GLIBCXX_CONSTEXPR int_type
  470. to_int_type(const char_type& __c) _GLIBCXX_NOEXCEPT
  471. { return int_type(__c); }
  472. static _GLIBCXX_CONSTEXPR bool
  473. eq_int_type(const int_type& __c1, const int_type& __c2) _GLIBCXX_NOEXCEPT
  474. { return __c1 == __c2; }
  475. static _GLIBCXX_CONSTEXPR int_type
  476. eof() _GLIBCXX_NOEXCEPT
  477. { return static_cast<int_type>(WEOF); }
  478. static _GLIBCXX_CONSTEXPR int_type
  479. not_eof(const int_type& __c) _GLIBCXX_NOEXCEPT
  480. { return eq_int_type(__c, eof()) ? 0 : __c; }
  481. };
  482. #endif //_GLIBCXX_USE_WCHAR_T
  483. #ifdef _GLIBCXX_USE_CHAR8_T
  484. template<>
  485. struct char_traits<char8_t>
  486. {
  487. typedef char8_t char_type;
  488. typedef unsigned int int_type;
  489. typedef u8streampos pos_type;
  490. typedef streamoff off_type;
  491. typedef mbstate_t state_type;
  492. #if __cpp_lib_three_way_comparison
  493. using comparison_category = strong_ordering;
  494. #endif
  495. static _GLIBCXX17_CONSTEXPR void
  496. assign(char_type& __c1, const char_type& __c2) _GLIBCXX_NOEXCEPT
  497. { __c1 = __c2; }
  498. static _GLIBCXX_CONSTEXPR bool
  499. eq(const char_type& __c1, const char_type& __c2) _GLIBCXX_NOEXCEPT
  500. { return __c1 == __c2; }
  501. static _GLIBCXX_CONSTEXPR bool
  502. lt(const char_type& __c1, const char_type& __c2) _GLIBCXX_NOEXCEPT
  503. { return __c1 < __c2; }
  504. static _GLIBCXX17_CONSTEXPR int
  505. compare(const char_type* __s1, const char_type* __s2, size_t __n)
  506. {
  507. if (__n == 0)
  508. return 0;
  509. #if __cplusplus > 201402
  510. if (__builtin_constant_p(__n)
  511. && __constant_char_array_p(__s1, __n)
  512. && __constant_char_array_p(__s2, __n))
  513. return __gnu_cxx::char_traits<char_type>::compare(__s1, __s2, __n);
  514. #endif
  515. return __builtin_memcmp(__s1, __s2, __n);
  516. }
  517. static _GLIBCXX17_CONSTEXPR size_t
  518. length(const char_type* __s)
  519. {
  520. #if __cplusplus > 201402
  521. if (__constant_string_p(__s))
  522. return __gnu_cxx::char_traits<char_type>::length(__s);
  523. #endif
  524. size_t __i = 0;
  525. while (!eq(__s[__i], char_type()))
  526. ++__i;
  527. return __i;
  528. }
  529. static _GLIBCXX17_CONSTEXPR const char_type*
  530. find(const char_type* __s, size_t __n, const char_type& __a)
  531. {
  532. if (__n == 0)
  533. return 0;
  534. #if __cplusplus > 201402
  535. if (__builtin_constant_p(__n)
  536. && __builtin_constant_p(__a)
  537. && __constant_char_array_p(__s, __n))
  538. return __gnu_cxx::char_traits<char_type>::find(__s, __n, __a);
  539. #endif
  540. return static_cast<const char_type*>(__builtin_memchr(__s, __a, __n));
  541. }
  542. static _GLIBCXX20_CONSTEXPR char_type*
  543. move(char_type* __s1, const char_type* __s2, size_t __n)
  544. {
  545. if (__n == 0)
  546. return __s1;
  547. #ifdef __cpp_lib_is_constant_evaluated
  548. if (std::is_constant_evaluated())
  549. return __gnu_cxx::char_traits<char_type>::move(__s1, __s2, __n);
  550. #endif
  551. return static_cast<char_type*>(__builtin_memmove(__s1, __s2, __n));
  552. }
  553. static _GLIBCXX20_CONSTEXPR char_type*
  554. copy(char_type* __s1, const char_type* __s2, size_t __n)
  555. {
  556. if (__n == 0)
  557. return __s1;
  558. #ifdef __cpp_lib_is_constant_evaluated
  559. if (std::is_constant_evaluated())
  560. return __gnu_cxx::char_traits<char_type>::copy(__s1, __s2, __n);
  561. #endif
  562. return static_cast<char_type*>(__builtin_memcpy(__s1, __s2, __n));
  563. }
  564. static _GLIBCXX20_CONSTEXPR char_type*
  565. assign(char_type* __s, size_t __n, char_type __a)
  566. {
  567. if (__n == 0)
  568. return __s;
  569. #ifdef __cpp_lib_is_constant_evaluated
  570. if (std::is_constant_evaluated())
  571. return __gnu_cxx::char_traits<char_type>::assign(__s, __n, __a);
  572. #endif
  573. return static_cast<char_type*>(__builtin_memset(__s, __a, __n));
  574. }
  575. static _GLIBCXX_CONSTEXPR char_type
  576. to_char_type(const int_type& __c) _GLIBCXX_NOEXCEPT
  577. { return char_type(__c); }
  578. static _GLIBCXX_CONSTEXPR int_type
  579. to_int_type(const char_type& __c) _GLIBCXX_NOEXCEPT
  580. { return int_type(__c); }
  581. static _GLIBCXX_CONSTEXPR bool
  582. eq_int_type(const int_type& __c1, const int_type& __c2) _GLIBCXX_NOEXCEPT
  583. { return __c1 == __c2; }
  584. static _GLIBCXX_CONSTEXPR int_type
  585. eof() _GLIBCXX_NOEXCEPT
  586. { return static_cast<int_type>(-1); }
  587. static _GLIBCXX_CONSTEXPR int_type
  588. not_eof(const int_type& __c) _GLIBCXX_NOEXCEPT
  589. { return eq_int_type(__c, eof()) ? 0 : __c; }
  590. };
  591. #endif //_GLIBCXX_USE_CHAR8_T
  592. _GLIBCXX_END_NAMESPACE_VERSION
  593. } // namespace
  594. #if __cplusplus >= 201103L
  595. #include <cstdint>
  596. namespace std _GLIBCXX_VISIBILITY(default)
  597. {
  598. _GLIBCXX_BEGIN_NAMESPACE_VERSION
  599. template<>
  600. struct char_traits<char16_t>
  601. {
  602. typedef char16_t char_type;
  603. #ifdef _GLIBCXX_USE_C99_STDINT_TR1
  604. typedef uint_least16_t int_type;
  605. #elif defined __UINT_LEAST16_TYPE__
  606. typedef __UINT_LEAST16_TYPE__ int_type;
  607. #else
  608. typedef make_unsigned<char16_t>::type int_type;
  609. #endif
  610. typedef streamoff off_type;
  611. typedef u16streampos pos_type;
  612. typedef mbstate_t state_type;
  613. #if __cpp_lib_three_way_comparison
  614. using comparison_category = strong_ordering;
  615. #endif
  616. static _GLIBCXX17_CONSTEXPR void
  617. assign(char_type& __c1, const char_type& __c2) noexcept
  618. { __c1 = __c2; }
  619. static constexpr bool
  620. eq(const char_type& __c1, const char_type& __c2) noexcept
  621. { return __c1 == __c2; }
  622. static constexpr bool
  623. lt(const char_type& __c1, const char_type& __c2) noexcept
  624. { return __c1 < __c2; }
  625. static _GLIBCXX17_CONSTEXPR int
  626. compare(const char_type* __s1, const char_type* __s2, size_t __n)
  627. {
  628. for (size_t __i = 0; __i < __n; ++__i)
  629. if (lt(__s1[__i], __s2[__i]))
  630. return -1;
  631. else if (lt(__s2[__i], __s1[__i]))
  632. return 1;
  633. return 0;
  634. }
  635. static _GLIBCXX17_CONSTEXPR size_t
  636. length(const char_type* __s)
  637. {
  638. size_t __i = 0;
  639. while (!eq(__s[__i], char_type()))
  640. ++__i;
  641. return __i;
  642. }
  643. static _GLIBCXX17_CONSTEXPR const char_type*
  644. find(const char_type* __s, size_t __n, const char_type& __a)
  645. {
  646. for (size_t __i = 0; __i < __n; ++__i)
  647. if (eq(__s[__i], __a))
  648. return __s + __i;
  649. return 0;
  650. }
  651. static _GLIBCXX20_CONSTEXPR char_type*
  652. move(char_type* __s1, const char_type* __s2, size_t __n)
  653. {
  654. if (__n == 0)
  655. return __s1;
  656. #ifdef __cpp_lib_is_constant_evaluated
  657. if (std::is_constant_evaluated())
  658. return __gnu_cxx::char_traits<char_type>::move(__s1, __s2, __n);
  659. #endif
  660. return (static_cast<char_type*>
  661. (__builtin_memmove(__s1, __s2, __n * sizeof(char_type))));
  662. }
  663. static _GLIBCXX20_CONSTEXPR char_type*
  664. copy(char_type* __s1, const char_type* __s2, size_t __n)
  665. {
  666. if (__n == 0)
  667. return __s1;
  668. #ifdef __cpp_lib_is_constant_evaluated
  669. if (std::is_constant_evaluated())
  670. return __gnu_cxx::char_traits<char_type>::copy(__s1, __s2, __n);
  671. #endif
  672. return (static_cast<char_type*>
  673. (__builtin_memcpy(__s1, __s2, __n * sizeof(char_type))));
  674. }
  675. static _GLIBCXX20_CONSTEXPR char_type*
  676. assign(char_type* __s, size_t __n, char_type __a)
  677. {
  678. for (size_t __i = 0; __i < __n; ++__i)
  679. assign(__s[__i], __a);
  680. return __s;
  681. }
  682. static constexpr char_type
  683. to_char_type(const int_type& __c) noexcept
  684. { return char_type(__c); }
  685. static constexpr int_type
  686. to_int_type(const char_type& __c) noexcept
  687. { return __c == eof() ? int_type(0xfffd) : int_type(__c); }
  688. static constexpr bool
  689. eq_int_type(const int_type& __c1, const int_type& __c2) noexcept
  690. { return __c1 == __c2; }
  691. static constexpr int_type
  692. eof() noexcept
  693. { return static_cast<int_type>(-1); }
  694. static constexpr int_type
  695. not_eof(const int_type& __c) noexcept
  696. { return eq_int_type(__c, eof()) ? 0 : __c; }
  697. };
  698. template<>
  699. struct char_traits<char32_t>
  700. {
  701. typedef char32_t char_type;
  702. #ifdef _GLIBCXX_USE_C99_STDINT_TR1
  703. typedef uint_least32_t int_type;
  704. #elif defined __UINT_LEAST32_TYPE__
  705. typedef __UINT_LEAST32_TYPE__ int_type;
  706. #else
  707. typedef make_unsigned<char32_t>::type int_type;
  708. #endif
  709. typedef streamoff off_type;
  710. typedef u32streampos pos_type;
  711. typedef mbstate_t state_type;
  712. #if __cpp_lib_three_way_comparison
  713. using comparison_category = strong_ordering;
  714. #endif
  715. static _GLIBCXX17_CONSTEXPR void
  716. assign(char_type& __c1, const char_type& __c2) noexcept
  717. { __c1 = __c2; }
  718. static constexpr bool
  719. eq(const char_type& __c1, const char_type& __c2) noexcept
  720. { return __c1 == __c2; }
  721. static constexpr bool
  722. lt(const char_type& __c1, const char_type& __c2) noexcept
  723. { return __c1 < __c2; }
  724. static _GLIBCXX17_CONSTEXPR int
  725. compare(const char_type* __s1, const char_type* __s2, size_t __n)
  726. {
  727. for (size_t __i = 0; __i < __n; ++__i)
  728. if (lt(__s1[__i], __s2[__i]))
  729. return -1;
  730. else if (lt(__s2[__i], __s1[__i]))
  731. return 1;
  732. return 0;
  733. }
  734. static _GLIBCXX17_CONSTEXPR size_t
  735. length(const char_type* __s)
  736. {
  737. size_t __i = 0;
  738. while (!eq(__s[__i], char_type()))
  739. ++__i;
  740. return __i;
  741. }
  742. static _GLIBCXX17_CONSTEXPR const char_type*
  743. find(const char_type* __s, size_t __n, const char_type& __a)
  744. {
  745. for (size_t __i = 0; __i < __n; ++__i)
  746. if (eq(__s[__i], __a))
  747. return __s + __i;
  748. return 0;
  749. }
  750. static _GLIBCXX20_CONSTEXPR char_type*
  751. move(char_type* __s1, const char_type* __s2, size_t __n)
  752. {
  753. if (__n == 0)
  754. return __s1;
  755. #ifdef __cpp_lib_is_constant_evaluated
  756. if (std::is_constant_evaluated())
  757. return __gnu_cxx::char_traits<char_type>::move(__s1, __s2, __n);
  758. #endif
  759. return (static_cast<char_type*>
  760. (__builtin_memmove(__s1, __s2, __n * sizeof(char_type))));
  761. }
  762. static _GLIBCXX20_CONSTEXPR char_type*
  763. copy(char_type* __s1, const char_type* __s2, size_t __n)
  764. {
  765. if (__n == 0)
  766. return __s1;
  767. #ifdef __cpp_lib_is_constant_evaluated
  768. if (std::is_constant_evaluated())
  769. return __gnu_cxx::char_traits<char_type>::copy(__s1, __s2, __n);
  770. #endif
  771. return (static_cast<char_type*>
  772. (__builtin_memcpy(__s1, __s2, __n * sizeof(char_type))));
  773. }
  774. static _GLIBCXX20_CONSTEXPR char_type*
  775. assign(char_type* __s, size_t __n, char_type __a)
  776. {
  777. for (size_t __i = 0; __i < __n; ++__i)
  778. assign(__s[__i], __a);
  779. return __s;
  780. }
  781. static constexpr char_type
  782. to_char_type(const int_type& __c) noexcept
  783. { return char_type(__c); }
  784. static constexpr int_type
  785. to_int_type(const char_type& __c) noexcept
  786. { return int_type(__c); }
  787. static constexpr bool
  788. eq_int_type(const int_type& __c1, const int_type& __c2) noexcept
  789. { return __c1 == __c2; }
  790. static constexpr int_type
  791. eof() noexcept
  792. { return static_cast<int_type>(-1); }
  793. static constexpr int_type
  794. not_eof(const int_type& __c) noexcept
  795. { return eq_int_type(__c, eof()) ? 0 : __c; }
  796. };
  797. #if __cpp_lib_three_way_comparison
  798. namespace __detail
  799. {
  800. template<typename _ChTraits>
  801. constexpr auto
  802. __char_traits_cmp_cat(int __cmp) noexcept
  803. {
  804. if constexpr (requires { typename _ChTraits::comparison_category; })
  805. {
  806. using _Cat = typename _ChTraits::comparison_category;
  807. static_assert( !is_void_v<common_comparison_category_t<_Cat>> );
  808. return static_cast<_Cat>(__cmp <=> 0);
  809. }
  810. else
  811. return static_cast<weak_ordering>(__cmp <=> 0);
  812. }
  813. } // namespace __detail
  814. #endif // C++20
  815. _GLIBCXX_END_NAMESPACE_VERSION
  816. } // namespace
  817. #endif // C++11
  818. #endif // _CHAR_TRAITS_H