char_traits.h 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708
  1. // Character Traits for use by standard string and iostream -*- C++ -*-
  2. // Copyright (C) 1997-2018 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. #ifndef _GLIBCXX_ALWAYS_INLINE
  34. #define _GLIBCXX_ALWAYS_INLINE inline __attribute__((__always_inline__))
  35. #endif
  36. namespace __gnu_cxx _GLIBCXX_VISIBILITY(default)
  37. {
  38. _GLIBCXX_BEGIN_NAMESPACE_VERSION
  39. /**
  40. * @brief Mapping from character type to associated types.
  41. *
  42. * @note This is an implementation class for the generic version
  43. * of char_traits. It defines int_type, off_type, pos_type, and
  44. * state_type. By default these are unsigned long, streamoff,
  45. * streampos, and mbstate_t. Users who need a different set of
  46. * types, but who don't need to change the definitions of any function
  47. * defined in char_traits, can specialize __gnu_cxx::_Char_types
  48. * while leaving __gnu_cxx::char_traits alone. */
  49. template<typename _CharT>
  50. struct _Char_types
  51. {
  52. typedef unsigned long int_type;
  53. typedef std::streampos pos_type;
  54. typedef std::streamoff off_type;
  55. typedef std::mbstate_t state_type;
  56. };
  57. /**
  58. * @brief Base class used to implement std::char_traits.
  59. *
  60. * @note For any given actual character type, this definition is
  61. * probably wrong. (Most of the member functions are likely to be
  62. * right, but the int_type and state_type typedefs, and the eof()
  63. * member function, are likely to be wrong.) The reason this class
  64. * exists is so users can specialize it. Classes in namespace std
  65. * may not be specialized for fundamental types, but classes in
  66. * namespace __gnu_cxx may be.
  67. *
  68. * See https://gcc.gnu.org/onlinedocs/libstdc++/manual/strings.html#strings.string.character_types
  69. * for advice on how to make use of this class for @a unusual character
  70. * types. Also, check out include/ext/pod_char_traits.h.
  71. */
  72. template<typename _CharT>
  73. struct char_traits
  74. {
  75. typedef _CharT char_type;
  76. typedef typename _Char_types<_CharT>::int_type int_type;
  77. typedef typename _Char_types<_CharT>::pos_type pos_type;
  78. typedef typename _Char_types<_CharT>::off_type off_type;
  79. typedef typename _Char_types<_CharT>::state_type state_type;
  80. static _GLIBCXX14_CONSTEXPR void
  81. assign(char_type& __c1, const char_type& __c2)
  82. { __c1 = __c2; }
  83. static _GLIBCXX_CONSTEXPR bool
  84. eq(const char_type& __c1, const char_type& __c2)
  85. { return __c1 == __c2; }
  86. static _GLIBCXX_CONSTEXPR bool
  87. lt(const char_type& __c1, const char_type& __c2)
  88. { return __c1 < __c2; }
  89. static _GLIBCXX14_CONSTEXPR int
  90. compare(const char_type* __s1, const char_type* __s2, std::size_t __n);
  91. static _GLIBCXX14_CONSTEXPR std::size_t
  92. length(const char_type* __s);
  93. static _GLIBCXX14_CONSTEXPR const char_type*
  94. find(const char_type* __s, std::size_t __n, const char_type& __a);
  95. static char_type*
  96. move(char_type* __s1, const char_type* __s2, std::size_t __n);
  97. static char_type*
  98. copy(char_type* __s1, const char_type* __s2, std::size_t __n);
  99. static char_type*
  100. assign(char_type* __s, std::size_t __n, char_type __a);
  101. static _GLIBCXX_CONSTEXPR char_type
  102. to_char_type(const int_type& __c)
  103. { return static_cast<char_type>(__c); }
  104. static _GLIBCXX_CONSTEXPR int_type
  105. to_int_type(const char_type& __c)
  106. { return static_cast<int_type>(__c); }
  107. static _GLIBCXX_CONSTEXPR bool
  108. eq_int_type(const int_type& __c1, const int_type& __c2)
  109. { return __c1 == __c2; }
  110. static _GLIBCXX_CONSTEXPR int_type
  111. eof()
  112. { return static_cast<int_type>(_GLIBCXX_STDIO_EOF); }
  113. static _GLIBCXX_CONSTEXPR int_type
  114. not_eof(const int_type& __c)
  115. { return !eq_int_type(__c, eof()) ? __c : to_int_type(char_type()); }
  116. };
  117. template<typename _CharT>
  118. _GLIBCXX14_CONSTEXPR int
  119. char_traits<_CharT>::
  120. compare(const char_type* __s1, const char_type* __s2, std::size_t __n)
  121. {
  122. for (std::size_t __i = 0; __i < __n; ++__i)
  123. if (lt(__s1[__i], __s2[__i]))
  124. return -1;
  125. else if (lt(__s2[__i], __s1[__i]))
  126. return 1;
  127. return 0;
  128. }
  129. template<typename _CharT>
  130. _GLIBCXX14_CONSTEXPR std::size_t
  131. char_traits<_CharT>::
  132. length(const char_type* __p)
  133. {
  134. std::size_t __i = 0;
  135. while (!eq(__p[__i], char_type()))
  136. ++__i;
  137. return __i;
  138. }
  139. template<typename _CharT>
  140. _GLIBCXX14_CONSTEXPR const typename char_traits<_CharT>::char_type*
  141. char_traits<_CharT>::
  142. find(const char_type* __s, std::size_t __n, const char_type& __a)
  143. {
  144. for (std::size_t __i = 0; __i < __n; ++__i)
  145. if (eq(__s[__i], __a))
  146. return __s + __i;
  147. return 0;
  148. }
  149. template<typename _CharT>
  150. typename char_traits<_CharT>::char_type*
  151. char_traits<_CharT>::
  152. move(char_type* __s1, const char_type* __s2, std::size_t __n)
  153. {
  154. if (__n == 0)
  155. return __s1;
  156. return static_cast<_CharT*>(__builtin_memmove(__s1, __s2,
  157. __n * sizeof(char_type)));
  158. }
  159. template<typename _CharT>
  160. typename char_traits<_CharT>::char_type*
  161. char_traits<_CharT>::
  162. copy(char_type* __s1, const char_type* __s2, std::size_t __n)
  163. {
  164. // NB: Inline std::copy so no recursive dependencies.
  165. std::copy(__s2, __s2 + __n, __s1);
  166. return __s1;
  167. }
  168. template<typename _CharT>
  169. typename char_traits<_CharT>::char_type*
  170. char_traits<_CharT>::
  171. assign(char_type* __s, std::size_t __n, char_type __a)
  172. {
  173. // NB: Inline std::fill_n so no recursive dependencies.
  174. std::fill_n(__s, __n, __a);
  175. return __s;
  176. }
  177. _GLIBCXX_END_NAMESPACE_VERSION
  178. } // namespace
  179. namespace std _GLIBCXX_VISIBILITY(default)
  180. {
  181. _GLIBCXX_BEGIN_NAMESPACE_VERSION
  182. #if __cplusplus > 201402
  183. #define __cpp_lib_constexpr_char_traits 201611
  184. /**
  185. * @brief Determine whether the characters of a NULL-terminated
  186. * string are known at compile time.
  187. * @param __s The string.
  188. *
  189. * Assumes that _CharT is a built-in character type.
  190. */
  191. template<typename _CharT>
  192. static _GLIBCXX_ALWAYS_INLINE constexpr bool
  193. __constant_string_p(const _CharT* __s)
  194. {
  195. while (__builtin_constant_p(*__s) && *__s)
  196. __s++;
  197. return __builtin_constant_p(*__s);
  198. }
  199. /**
  200. * @brief Determine whether the characters of a character array are
  201. * known at compile time.
  202. * @param __a The character array.
  203. * @param __n Number of characters.
  204. *
  205. * Assumes that _CharT is a built-in character type.
  206. */
  207. template<typename _CharT>
  208. static _GLIBCXX_ALWAYS_INLINE constexpr bool
  209. __constant_char_array_p(const _CharT* __a, size_t __n)
  210. {
  211. size_t __i = 0;
  212. while (__builtin_constant_p(__a[__i]) && __i < __n)
  213. __i++;
  214. return __i == __n;
  215. }
  216. #endif
  217. // 21.1
  218. /**
  219. * @brief Basis for explicit traits specializations.
  220. *
  221. * @note For any given actual character type, this definition is
  222. * probably wrong. Since this is just a thin wrapper around
  223. * __gnu_cxx::char_traits, it is possible to achieve a more
  224. * appropriate definition by specializing __gnu_cxx::char_traits.
  225. *
  226. * See https://gcc.gnu.org/onlinedocs/libstdc++/manual/strings.html#strings.string.character_types
  227. * for advice on how to make use of this class for @a unusual character
  228. * types. Also, check out include/ext/pod_char_traits.h.
  229. */
  230. template<class _CharT>
  231. struct char_traits : public __gnu_cxx::char_traits<_CharT>
  232. { };
  233. /// 21.1.3.1 char_traits specializations
  234. template<>
  235. struct char_traits<char>
  236. {
  237. typedef char char_type;
  238. typedef int int_type;
  239. typedef streampos pos_type;
  240. typedef streamoff off_type;
  241. typedef mbstate_t state_type;
  242. static _GLIBCXX17_CONSTEXPR void
  243. assign(char_type& __c1, const char_type& __c2) _GLIBCXX_NOEXCEPT
  244. { __c1 = __c2; }
  245. static _GLIBCXX_CONSTEXPR bool
  246. eq(const char_type& __c1, const char_type& __c2) _GLIBCXX_NOEXCEPT
  247. { return __c1 == __c2; }
  248. static _GLIBCXX_CONSTEXPR bool
  249. lt(const char_type& __c1, const char_type& __c2) _GLIBCXX_NOEXCEPT
  250. {
  251. // LWG 467.
  252. return (static_cast<unsigned char>(__c1)
  253. < static_cast<unsigned char>(__c2));
  254. }
  255. static _GLIBCXX17_CONSTEXPR int
  256. compare(const char_type* __s1, const char_type* __s2, size_t __n)
  257. {
  258. #if __cplusplus > 201402
  259. if (__builtin_constant_p(__n)
  260. && __constant_char_array_p(__s1, __n)
  261. && __constant_char_array_p(__s2, __n))
  262. return __gnu_cxx::char_traits<char_type>::compare(__s1, __s2, __n);
  263. #endif
  264. if (__n == 0)
  265. return 0;
  266. return __builtin_memcmp(__s1, __s2, __n);
  267. }
  268. static _GLIBCXX17_CONSTEXPR size_t
  269. length(const char_type* __s)
  270. {
  271. #if __cplusplus > 201402
  272. if (__constant_string_p(__s))
  273. return __gnu_cxx::char_traits<char_type>::length(__s);
  274. #endif
  275. return __builtin_strlen(__s);
  276. }
  277. static _GLIBCXX17_CONSTEXPR const char_type*
  278. find(const char_type* __s, size_t __n, const char_type& __a)
  279. {
  280. #if __cplusplus > 201402
  281. if (__builtin_constant_p(__n)
  282. && __builtin_constant_p(__a)
  283. && __constant_char_array_p(__s, __n))
  284. return __gnu_cxx::char_traits<char_type>::find(__s, __n, __a);
  285. #endif
  286. if (__n == 0)
  287. return 0;
  288. return static_cast<const char_type*>(__builtin_memchr(__s, __a, __n));
  289. }
  290. static char_type*
  291. move(char_type* __s1, const char_type* __s2, size_t __n)
  292. {
  293. if (__n == 0)
  294. return __s1;
  295. return static_cast<char_type*>(__builtin_memmove(__s1, __s2, __n));
  296. }
  297. static char_type*
  298. copy(char_type* __s1, const char_type* __s2, size_t __n)
  299. {
  300. if (__n == 0)
  301. return __s1;
  302. return static_cast<char_type*>(__builtin_memcpy(__s1, __s2, __n));
  303. }
  304. static char_type*
  305. assign(char_type* __s, size_t __n, char_type __a)
  306. {
  307. if (__n == 0)
  308. return __s;
  309. return static_cast<char_type*>(__builtin_memset(__s, __a, __n));
  310. }
  311. static _GLIBCXX_CONSTEXPR char_type
  312. to_char_type(const int_type& __c) _GLIBCXX_NOEXCEPT
  313. { return static_cast<char_type>(__c); }
  314. // To keep both the byte 0xff and the eof symbol 0xffffffff
  315. // from ending up as 0xffffffff.
  316. static _GLIBCXX_CONSTEXPR int_type
  317. to_int_type(const char_type& __c) _GLIBCXX_NOEXCEPT
  318. { return static_cast<int_type>(static_cast<unsigned char>(__c)); }
  319. static _GLIBCXX_CONSTEXPR bool
  320. eq_int_type(const int_type& __c1, const int_type& __c2) _GLIBCXX_NOEXCEPT
  321. { return __c1 == __c2; }
  322. static _GLIBCXX_CONSTEXPR int_type
  323. eof() _GLIBCXX_NOEXCEPT
  324. { return static_cast<int_type>(_GLIBCXX_STDIO_EOF); }
  325. static _GLIBCXX_CONSTEXPR int_type
  326. not_eof(const int_type& __c) _GLIBCXX_NOEXCEPT
  327. { return (__c == eof()) ? 0 : __c; }
  328. };
  329. #ifdef _GLIBCXX_USE_WCHAR_T
  330. /// 21.1.3.2 char_traits specializations
  331. template<>
  332. struct char_traits<wchar_t>
  333. {
  334. typedef wchar_t char_type;
  335. typedef wint_t int_type;
  336. typedef streamoff off_type;
  337. typedef wstreampos pos_type;
  338. typedef mbstate_t state_type;
  339. static _GLIBCXX17_CONSTEXPR void
  340. assign(char_type& __c1, const char_type& __c2) _GLIBCXX_NOEXCEPT
  341. { __c1 = __c2; }
  342. static _GLIBCXX_CONSTEXPR bool
  343. eq(const char_type& __c1, const char_type& __c2) _GLIBCXX_NOEXCEPT
  344. { return __c1 == __c2; }
  345. static _GLIBCXX_CONSTEXPR bool
  346. lt(const char_type& __c1, const char_type& __c2) _GLIBCXX_NOEXCEPT
  347. { return __c1 < __c2; }
  348. static _GLIBCXX17_CONSTEXPR int
  349. compare(const char_type* __s1, const char_type* __s2, size_t __n)
  350. {
  351. #if __cplusplus > 201402
  352. if (__builtin_constant_p(__n)
  353. && __constant_char_array_p(__s1, __n)
  354. && __constant_char_array_p(__s2, __n))
  355. return __gnu_cxx::char_traits<char_type>::compare(__s1, __s2, __n);
  356. #endif
  357. if (__n == 0)
  358. return 0;
  359. else
  360. return wmemcmp(__s1, __s2, __n);
  361. }
  362. static _GLIBCXX17_CONSTEXPR size_t
  363. length(const char_type* __s)
  364. {
  365. #if __cplusplus > 201402
  366. if (__constant_string_p(__s))
  367. return __gnu_cxx::char_traits<char_type>::length(__s);
  368. else
  369. #endif
  370. return wcslen(__s);
  371. }
  372. static _GLIBCXX17_CONSTEXPR const char_type*
  373. find(const char_type* __s, size_t __n, const char_type& __a)
  374. {
  375. #if __cplusplus > 201402
  376. if (__builtin_constant_p(__n)
  377. && __builtin_constant_p(__a)
  378. && __constant_char_array_p(__s, __n))
  379. return __gnu_cxx::char_traits<char_type>::find(__s, __n, __a);
  380. #endif
  381. if (__n == 0)
  382. return 0;
  383. else
  384. return wmemchr(__s, __a, __n);
  385. }
  386. static char_type*
  387. move(char_type* __s1, const char_type* __s2, size_t __n)
  388. {
  389. if (__n == 0)
  390. return __s1;
  391. return wmemmove(__s1, __s2, __n);
  392. }
  393. static char_type*
  394. copy(char_type* __s1, const char_type* __s2, size_t __n)
  395. {
  396. if (__n == 0)
  397. return __s1;
  398. return wmemcpy(__s1, __s2, __n);
  399. }
  400. static char_type*
  401. assign(char_type* __s, size_t __n, char_type __a)
  402. {
  403. if (__n == 0)
  404. return __s;
  405. return wmemset(__s, __a, __n);
  406. }
  407. static _GLIBCXX_CONSTEXPR char_type
  408. to_char_type(const int_type& __c) _GLIBCXX_NOEXCEPT
  409. { return char_type(__c); }
  410. static _GLIBCXX_CONSTEXPR int_type
  411. to_int_type(const char_type& __c) _GLIBCXX_NOEXCEPT
  412. { return int_type(__c); }
  413. static _GLIBCXX_CONSTEXPR bool
  414. eq_int_type(const int_type& __c1, const int_type& __c2) _GLIBCXX_NOEXCEPT
  415. { return __c1 == __c2; }
  416. static _GLIBCXX_CONSTEXPR int_type
  417. eof() _GLIBCXX_NOEXCEPT
  418. { return static_cast<int_type>(WEOF); }
  419. static _GLIBCXX_CONSTEXPR int_type
  420. not_eof(const int_type& __c) _GLIBCXX_NOEXCEPT
  421. { return eq_int_type(__c, eof()) ? 0 : __c; }
  422. };
  423. #endif //_GLIBCXX_USE_WCHAR_T
  424. _GLIBCXX_END_NAMESPACE_VERSION
  425. } // namespace
  426. #if ((__cplusplus >= 201103L) \
  427. && defined(_GLIBCXX_USE_C99_STDINT_TR1))
  428. #include <cstdint>
  429. namespace std _GLIBCXX_VISIBILITY(default)
  430. {
  431. _GLIBCXX_BEGIN_NAMESPACE_VERSION
  432. template<>
  433. struct char_traits<char16_t>
  434. {
  435. typedef char16_t char_type;
  436. typedef uint_least16_t int_type;
  437. typedef streamoff off_type;
  438. typedef u16streampos pos_type;
  439. typedef mbstate_t state_type;
  440. static _GLIBCXX17_CONSTEXPR void
  441. assign(char_type& __c1, const char_type& __c2) noexcept
  442. { __c1 = __c2; }
  443. static constexpr bool
  444. eq(const char_type& __c1, const char_type& __c2) noexcept
  445. { return __c1 == __c2; }
  446. static constexpr bool
  447. lt(const char_type& __c1, const char_type& __c2) noexcept
  448. { return __c1 < __c2; }
  449. static _GLIBCXX17_CONSTEXPR int
  450. compare(const char_type* __s1, const char_type* __s2, size_t __n)
  451. {
  452. for (size_t __i = 0; __i < __n; ++__i)
  453. if (lt(__s1[__i], __s2[__i]))
  454. return -1;
  455. else if (lt(__s2[__i], __s1[__i]))
  456. return 1;
  457. return 0;
  458. }
  459. static _GLIBCXX17_CONSTEXPR size_t
  460. length(const char_type* __s)
  461. {
  462. size_t __i = 0;
  463. while (!eq(__s[__i], char_type()))
  464. ++__i;
  465. return __i;
  466. }
  467. static _GLIBCXX17_CONSTEXPR const char_type*
  468. find(const char_type* __s, size_t __n, const char_type& __a)
  469. {
  470. for (size_t __i = 0; __i < __n; ++__i)
  471. if (eq(__s[__i], __a))
  472. return __s + __i;
  473. return 0;
  474. }
  475. static char_type*
  476. move(char_type* __s1, const char_type* __s2, size_t __n)
  477. {
  478. if (__n == 0)
  479. return __s1;
  480. return (static_cast<char_type*>
  481. (__builtin_memmove(__s1, __s2, __n * sizeof(char_type))));
  482. }
  483. static char_type*
  484. copy(char_type* __s1, const char_type* __s2, size_t __n)
  485. {
  486. if (__n == 0)
  487. return __s1;
  488. return (static_cast<char_type*>
  489. (__builtin_memcpy(__s1, __s2, __n * sizeof(char_type))));
  490. }
  491. static char_type*
  492. assign(char_type* __s, size_t __n, char_type __a)
  493. {
  494. for (size_t __i = 0; __i < __n; ++__i)
  495. assign(__s[__i], __a);
  496. return __s;
  497. }
  498. static constexpr char_type
  499. to_char_type(const int_type& __c) noexcept
  500. { return char_type(__c); }
  501. static constexpr int_type
  502. to_int_type(const char_type& __c) noexcept
  503. { return __c == eof() ? int_type(0xfffd) : int_type(__c); }
  504. static constexpr bool
  505. eq_int_type(const int_type& __c1, const int_type& __c2) noexcept
  506. { return __c1 == __c2; }
  507. static constexpr int_type
  508. eof() noexcept
  509. { return static_cast<int_type>(-1); }
  510. static constexpr int_type
  511. not_eof(const int_type& __c) noexcept
  512. { return eq_int_type(__c, eof()) ? 0 : __c; }
  513. };
  514. template<>
  515. struct char_traits<char32_t>
  516. {
  517. typedef char32_t char_type;
  518. typedef uint_least32_t int_type;
  519. typedef streamoff off_type;
  520. typedef u32streampos pos_type;
  521. typedef mbstate_t state_type;
  522. static _GLIBCXX17_CONSTEXPR void
  523. assign(char_type& __c1, const char_type& __c2) noexcept
  524. { __c1 = __c2; }
  525. static constexpr bool
  526. eq(const char_type& __c1, const char_type& __c2) noexcept
  527. { return __c1 == __c2; }
  528. static constexpr bool
  529. lt(const char_type& __c1, const char_type& __c2) noexcept
  530. { return __c1 < __c2; }
  531. static _GLIBCXX17_CONSTEXPR int
  532. compare(const char_type* __s1, const char_type* __s2, size_t __n)
  533. {
  534. for (size_t __i = 0; __i < __n; ++__i)
  535. if (lt(__s1[__i], __s2[__i]))
  536. return -1;
  537. else if (lt(__s2[__i], __s1[__i]))
  538. return 1;
  539. return 0;
  540. }
  541. static _GLIBCXX17_CONSTEXPR size_t
  542. length(const char_type* __s)
  543. {
  544. size_t __i = 0;
  545. while (!eq(__s[__i], char_type()))
  546. ++__i;
  547. return __i;
  548. }
  549. static _GLIBCXX17_CONSTEXPR const char_type*
  550. find(const char_type* __s, size_t __n, const char_type& __a)
  551. {
  552. for (size_t __i = 0; __i < __n; ++__i)
  553. if (eq(__s[__i], __a))
  554. return __s + __i;
  555. return 0;
  556. }
  557. static char_type*
  558. move(char_type* __s1, const char_type* __s2, size_t __n)
  559. {
  560. if (__n == 0)
  561. return __s1;
  562. return (static_cast<char_type*>
  563. (__builtin_memmove(__s1, __s2, __n * sizeof(char_type))));
  564. }
  565. static char_type*
  566. copy(char_type* __s1, const char_type* __s2, size_t __n)
  567. {
  568. if (__n == 0)
  569. return __s1;
  570. return (static_cast<char_type*>
  571. (__builtin_memcpy(__s1, __s2, __n * sizeof(char_type))));
  572. }
  573. static char_type*
  574. assign(char_type* __s, size_t __n, char_type __a)
  575. {
  576. for (size_t __i = 0; __i < __n; ++__i)
  577. assign(__s[__i], __a);
  578. return __s;
  579. }
  580. static constexpr char_type
  581. to_char_type(const int_type& __c) noexcept
  582. { return char_type(__c); }
  583. static constexpr int_type
  584. to_int_type(const char_type& __c) noexcept
  585. { return int_type(__c); }
  586. static constexpr bool
  587. eq_int_type(const int_type& __c1, const int_type& __c2) noexcept
  588. { return __c1 == __c2; }
  589. static constexpr int_type
  590. eof() noexcept
  591. { return static_cast<int_type>(-1); }
  592. static constexpr int_type
  593. not_eof(const int_type& __c) noexcept
  594. { return eq_int_type(__c, eof()) ? 0 : __c; }
  595. };
  596. _GLIBCXX_END_NAMESPACE_VERSION
  597. } // namespace
  598. #endif
  599. #endif // _CHAR_TRAITS_H