char_traits.h 29 KB

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