30#ifndef _GLIBCXX_UNICODE_H
31#define _GLIBCXX_UNICODE_H 1
33#if __cplusplus >= 202002L
44namespace std _GLIBCXX_VISIBILITY(default)
46_GLIBCXX_BEGIN_NAMESPACE_VERSION
51 __is_scalar_value(
char32_t __c)
53 if (__c < 0xD800) [[likely]]
55 return 0xDFFF < __c && __c <= 0x10FFFF;
59 template<
typename _CharT>
61 __is_single_code_unit(
char32_t __c)
63 if constexpr (__gnu_cxx::__int_traits<_CharT>::__max <= 0xFF)
66 return __c < __gnu_cxx::__int_traits<_CharT>::__max
67 && __is_scalar_value(__c);
75 operator()() const noexcept
79 struct _Null_sentinel_t
81 template<input_iterator _It>
82 requires default_initializable<iter_value_t<_It>>
83 && equality_comparable_with<iter_reference_t<_It>, iter_value_t<_It>>
85 operator==(_It __it, _Null_sentinel_t)
86 {
return *__it == iter_value_t<_It>{}; }
108 template<
typename _FromFmt,
typename _ToFmt,
109 input_iterator _Iter, sentinel_for<_Iter> _Sent = _Iter,
110 typename _ErrorHandler = _Repl>
111 requires convertible_to<iter_value_t<_Iter>, _FromFmt>
114 static_assert(forward_iterator<_Iter> ||
noexcept(_ErrorHandler()()));
117 using value_type = _ToFmt;
118 using difference_type = iter_difference_t<_Iter>;
119 using reference = value_type;
120 using iterator_concept
121 = std::__detail::__clamp_iter_cat<__iter_category_t<_Iter>,
122 bidirectional_iterator_tag>;
124 constexpr _Utf_iterator() =
default;
127 _Utf_iterator(_Iter __first, _Iter __it, _Sent __last)
128 requires bidirectional_iterator<_Iter>
129 : _M_first_and_curr{__first, __it}, _M_last(__last)
131 if (_M_curr() != _M_last)
138 _Utf_iterator(_Iter __it, _Sent __last)
139 requires (!bidirectional_iterator<_Iter>)
140 : _M_first_and_curr{__it}, _M_last(__last)
142 if (_M_curr() != _M_last)
148 template<
class _Iter2,
class _Sent2>
149 requires convertible_to<_Iter2, _Iter> && convertible_to<_Sent2, _Sent>
151 _Utf_iterator(
const _Utf_iterator<_FromFmt, _ToFmt, _Iter2, _Sent2,
152 _ErrorHandler>& __other)
153 : _M_buf(__other._M_buf), _M_first_and_curr(__other._M_first_and_curr),
154 _M_buf_index(__other._M_buf_index), _M_buf_last(__other._M_buf_last),
155 _M_last(__other._M_last)
160 begin() const requires bidirectional_iterator<_Iter>
161 {
return _M_first(); }
165 end()
const {
return _M_last; }
169 base() const requires forward_iterator<_Iter>
170 {
return _M_curr(); }
173 constexpr iter_difference_t<_Iter>
174 _M_units() const requires forward_iterator<_Iter>
175 {
return _M_to_increment; }
179 operator*()
const {
return _M_buf[_M_buf_index]; }
181 constexpr _Utf_iterator&
184 if (_M_buf_index + 1 < _M_buf_last)
186 else if (_M_curr() != _M_last)
190 if constexpr (forward_iterator<_Iter>)
192 if (_M_curr() == _M_last)
201 constexpr _Utf_iterator
209 constexpr _Utf_iterator&
210 operator--()
requires bidirectional_iterator<_Iter>
212 if (_M_buf_index > 0)
214 else if (_M_curr() != _M_first())
217 _M_buf_index = _M_buf_last - 1;
218 ranges::advance(_M_curr(), -_M_to_increment);
224 constexpr _Utf_iterator
233 friend constexpr bool
234 operator==(_Utf_iterator __lhs, _Utf_iterator __rhs)
235 requires forward_iterator<_Iter> ||
requires (_Iter __i) { __i != __i; }
237 if constexpr (forward_iterator<_Iter>)
238 return __lhs._M_curr() == __rhs._M_curr()
239 && __lhs._M_buf_index == __rhs._M_buf_index;
240 else if (__lhs._M_curr() != __rhs._M_curr())
242 else if (__lhs._M_buf_index == __rhs._M_buf_index
243 && __lhs._M_buf_last == __rhs._M_buf_last)
246 return __lhs._M_buf_index == __lhs._M_buf_last
247 && __rhs._M_buf_index == __rhs._M_buf_last;
251 friend constexpr bool
252 operator==(_Utf_iterator __lhs, _Sent __rhs)
254 if constexpr (forward_iterator<_Iter>)
255 return __lhs._M_curr() == __rhs;
257 return __lhs._M_curr() == __rhs
258 && __lhs._M_buf_index == __lhs._M_buf_last;
265 if constexpr (
sizeof(_FromFmt) ==
sizeof(uint8_t))
267 else if constexpr (
sizeof(_FromFmt) ==
sizeof(uint16_t))
271 static_assert(
sizeof(_FromFmt) ==
sizeof(uint32_t));
277 _M_read_reverse()
requires bidirectional_iterator<_Iter>
279 if constexpr (
sizeof(_FromFmt) ==
sizeof(uint8_t))
280 _M_read_reverse_utf8();
281 else if constexpr (
sizeof(_FromFmt) ==
sizeof(uint16_t))
282 _M_read_reverse_utf16();
285 static_assert(
sizeof(_FromFmt) ==
sizeof(uint32_t));
286 _M_read_reverse_utf32();
293 _Guard(
void*, _Iter&) { }
296 template<
typename _It>
requires forward_iterator<_It>
299 constexpr ~_Guard() { _M_this->_M_curr() =
std::move(_M_orig); }
300 _Utf_iterator* _M_this;
307 _Guard<_Iter> __g{
this, _M_curr()};
309 const uint8_t __lo_bound = 0x80, __hi_bound = 0xBF;
310 uint8_t __u = *_M_curr()++;
311 uint8_t __to_incr = 1;
312 auto __incr = [&,
this] {
317 if (__u <= 0x7F) [[likely]]
319 else if (__u < 0xC2) [[unlikely]]
321 else if (_M_curr() == _M_last) [[unlikely]]
323 else if (__u <= 0xDF)
328 if (__u < __lo_bound || __u > __hi_bound) [[unlikely]]
332 __c = (__c << 6) | (__u & 0x3F);
336 else if (__u <= 0xEF)
338 const uint8_t __lo_bound_2 = __u == 0xE0 ? 0xA0 : __lo_bound;
339 const uint8_t __hi_bound_2 = __u == 0xED ? 0x9F : __hi_bound;
344 if (__u < __lo_bound_2 || __u > __hi_bound_2) [[unlikely]]
346 else if (__incr() == _M_last) [[unlikely]]
350 __c = (__c << 6) | (__u & 0x3F);
353 if (__u < __lo_bound || __u > __hi_bound) [[unlikely]]
357 __c = (__c << 6) | (__u & 0x3F);
362 else if (__u <= 0xF4)
364 const uint8_t __lo_bound_2 = __u == 0xF0 ? 0x90 : __lo_bound;
365 const uint8_t __hi_bound_2 = __u == 0xF4 ? 0x8F : __hi_bound;
370 if (__u < __lo_bound_2 || __u > __hi_bound_2) [[unlikely]]
372 else if (__incr() == _M_last) [[unlikely]]
376 __c = (__c << 6) | (__u & 0x3F);
379 if (__u < __lo_bound || __u > __hi_bound) [[unlikely]]
381 else if (__incr() == _M_last) [[unlikely]]
385 __c = (__c << 6) | (__u & 0x3F);
388 if (__u < __lo_bound || __u > __hi_bound) [[unlikely]]
392 __c = (__c << 6) | (__u & 0x3F);
401 _M_update(__c, __to_incr);
409 _Guard<_Iter> __g{
this, _M_curr()};
411 uint16_t __u = *_M_curr()++;
412 uint8_t __to_incr = 1;
414 if (__u < 0xD800 || __u > 0xDFFF) [[likely]]
416 else if (__u < 0xDC00 && _M_curr() != _M_last)
418 uint16_t __u2 = *_M_curr();
419 if (__u2 < 0xDC00 || __u2 > 0xDFFF) [[unlikely]]
425 uint32_t __x = (__u & 0x3F) << 10 | (__u2 & 0x3FF);
426 uint32_t __w = (__u >> 6) & 0x1F;
427 __c = (__w + 1) << 16 | __x;
433 _M_update(__c, __to_incr);
439 _Guard<_Iter> __g{
this, _M_curr()};
440 char32_t __c = *_M_curr()++;
441 if (!__is_scalar_value(__c)) [[unlikely]]
447 _M_read_reverse_utf8()
requires bidirectional_iterator<_Iter>
449 const auto __first = _M_first();
450 auto __curr = _M_curr();
454 uint8_t __u = *--__curr;
456 uint8_t __to_incr = 1;
458 if (__u <= 0x7F) [[likely]]
465 auto __is_continuation = [](uint8_t __b) {
466 return (__b & 0xC0) == 0x80;
470 auto __is_invalid = [](uint8_t __b) {
471 return (__b & 0xFE) == 0xC0 || __b >= 0xF5;
476 while (__is_continuation(__u) && __to_incr < 4 && __curr != __first)
486 if (__is_continuation(__u) || __is_invalid(__u)) [[unlikely]]
490 _M_update(_S_error(), 1);
495 int __seq_length = std::countl_one((
unsigned char)__u);
496 if (__seq_length < __to_incr) [[unlikely]]
501 _M_update(_S_error(), 1);
505 auto __orig = std::__exchange(_M_curr(),
std::move(__curr));
506 if (_M_read_utf8() == _S_error()) [[unlikely]]
508 if (_M_to_increment < __to_incr)
517 _M_read_reverse_utf16()
requires bidirectional_iterator<_Iter>
519 _Guard<_Iter> __g{
this, _M_curr()};
521 uint16_t __u = *--_M_curr();
522 uint8_t __to_incr = 1;
524 if (__u < 0xD800 || __u > 0xDFFF) [[likely]]
526 else if (__u >= 0xDC00 && _M_curr() != _M_first()) [[likely]]
529 uint16_t __u2 = *--_M_curr();
530 if (__u2 < 0xD800 || __u2 >= 0xDC00) [[unlikely]]
535 uint32_t __x = (__u2 & 0x3F) << 10 | (__u & 0x3FF);
536 uint32_t __w = (__u2 >> 6) & 0x1F;
537 __c = (__w + 1) << 16 | __x;
543 _M_update(__c, __to_incr);
547 _M_read_reverse_utf32()
requires bidirectional_iterator<_Iter>
549 _Guard<_Iter> __g{
this, _M_curr()};
550 char32_t __c = *--_M_curr();
551 if (!__is_scalar_value(__c)) [[unlikely]]
558 _M_update(
char32_t __c, uint8_t __to_incr)
560 _M_to_increment = __to_incr;
562 if constexpr (
sizeof(_ToFmt) ==
sizeof(uint32_t))
567 else if constexpr (
sizeof(_ToFmt) ==
sizeof(uint16_t))
569 if (__is_single_code_unit<_ToFmt>(__c))
578 const char32_t __lead_offset = 0xD800 - (0x10000 >> 10);
579 char16_t __lead = __lead_offset + (__c >> 10);
580 char16_t __trail = 0xDC00 + (__c & 0x3FF);
588 static_assert(
sizeof(_ToFmt) == 1);
589 int __bits = std::bit_width((uint32_t)__c);
590 if (__bits <= 7) [[likely]]
593 _M_buf[1] = _M_buf[2] = _M_buf[3] = 0;
596 else if (__bits <= 11)
598 _M_buf[0] = 0xC0 | (__c >> 6);
599 _M_buf[1] = 0x80 | (__c & 0x3F);
600 _M_buf[2] = _M_buf[3] = 0;
603 else if (__bits <= 16)
605 _M_buf[0] = 0xE0 | (__c >> 12);
606 _M_buf[1] = 0x80 | ((__c >> 6) & 0x3F);
607 _M_buf[2] = 0x80 | (__c & 0x3F);
613 _M_buf[0] = 0xF0 | ((__c >> 18) & 0x07);
614 _M_buf[1] = 0x80 | ((__c >> 12) & 0x3F);
615 _M_buf[2] = 0x80 | ((__c >> 6) & 0x3F);
616 _M_buf[3] = 0x80 | (__c & 0x3F);
625 char32_t __c = _ErrorHandler()();
626 __glibcxx_assert(__is_scalar_value(__c));
631 _M_first() const requires bidirectional_iterator<_Iter>
632 {
return _M_first_and_curr._M_first; }
635 _M_curr() {
return _M_first_and_curr._M_curr; }
638 _M_curr()
const {
return _M_first_and_curr._M_curr; }
641 template<
typename _It>
642 struct _First_and_curr
644 _First_and_curr() =
default;
647 _First_and_curr(_It __curr) : _M_curr(__curr) { }
649 template<convertible_to<_It> _It2>
651 _First_and_curr(
const _First_and_curr<_It2>& __other)
652 : _M_curr(__other._M_curr) { }
659 template<
typename _It>
requires bidirectional_iterator<_It>
660 struct _First_and_curr<_It>
662 _First_and_curr() =
default;
665 _First_and_curr(_It __first, _It __curr)
666 : _M_first(__first), _M_curr(__curr) { }
668 template<convertible_to<_It> _It2>
670 _First_and_curr(
const _First_and_curr<_It2>& __other)
671 : _M_first(__other._M_first), _M_curr(__other._M_curr) { }
679 _First_and_curr<_Iter> _M_first_and_curr;
682 [[no_unique_address]] _Sent _M_last;
685 array<value_type, 4 /
sizeof(_ToFmt)> _M_buf;
687 uint8_t _M_buf_index = 0;
688 uint8_t _M_buf_last = 0;
689 uint8_t _M_to_increment = 0;
691 template<
typename _FromFmt2,
typename _ToFmt2,
692 input_iterator _Iter2, sentinel_for<_Iter2> _Sent2,
693 typename _ErrHandler>
694 requires convertible_to<iter_value_t<_Iter2>, _FromFmt2>
695 friend class _Utf_iterator;
698 template<
typename _ToFormat, ranges::input_range _View>
699 requires ranges::view<_View>
701 :
public ranges::view_interface<_Utf_view<_ToFormat, _View>>
703 using _Iterator = _Utf_iterator<ranges::range_value_t<_View>,
704 _ToFormat, ranges::iterator_t<_View>,
705 ranges::sentinel_t<_View>>;
707 template<
typename _Iter,
typename _Sent>
709 _M_begin(_Iter __first, _Sent __last)
711 if constexpr (bidirectional_iterator<_Iter>)
712 return _Iterator(__first, __first, __last);
714 return _Iterator(__first, __last);
717 template<
typename _Iter,
typename _Sent>
719 _M_end(_Iter __first, _Sent __last)
721 if constexpr (!is_same_v<_Iter, _Sent>)
723 else if constexpr (bidirectional_iterator<_Iter>)
724 return _Iterator(__first, __last, __last);
726 return _Iterator(__last, __last);
733 _Utf_view(_View __r) : _M_base(std::
move(__r)) { }
735 constexpr auto begin()
736 {
return _M_begin(ranges::begin(_M_base), ranges::end(_M_base)); }
739 {
return _M_end(ranges::begin(_M_base), ranges::end(_M_base)); }
741 constexpr bool empty()
const {
return ranges::empty(_M_base); }
745 template<
typename _View>
746 using _Utf8_view = _Utf_view<char8_t, _View>;
748 template<
typename _View>
749 using _Utf8_view = _Utf_view<char, _View>;
751 template<
typename _View>
752 using _Utf16_view = _Utf_view<char16_t, _View>;
753 template<
typename _View>
754 using _Utf32_view = _Utf_view<char32_t, _View>;
756inline namespace __v16_0_0
758#define _GLIBCXX_GET_UNICODE_DATA 160000
760#ifdef _GLIBCXX_GET_UNICODE_DATA
761# error "Invalid unicode data"
766 __field_width(
char32_t __c)
noexcept
768 if (__c < __width_edges[0]) [[likely]]
771 auto* __p = std::upper_bound(__width_edges,
std::end(__width_edges), __c);
772 return (__p - __width_edges) % 2 + 1;
777 __should_escape_category(
char32_t __c)
noexcept
779 constexpr uint32_t __mask = 0x01;
780 auto* __end =
std::end(__escape_edges);
781 auto* __p = std::lower_bound(__escape_edges, __end,
783 return __p[-1] & __mask;
788 constexpr _Gcb_property
789 __grapheme_cluster_break_property(
char32_t __c)
noexcept
791 constexpr uint32_t __mask = (1 << __gcb_shift_bits) - 1;
792 auto* __end =
std::end(__gcb_edges);
793 auto* __p = std::lower_bound(__gcb_edges, __end,
794 (__c << __gcb_shift_bits) | __mask);
795 return _Gcb_property(__p[-1] & __mask);
799 __is_incb_linker(
char32_t __c)
noexcept
801 const auto __end =
std::end(__incb_linkers);
803 return _GLIBCXX_STD_A::find(__incb_linkers, __end, __c) != __end;
808 __incb_property(
char32_t __c)
noexcept
810 if ((__c << 2) < __incb_edges[0]) [[likely]]
813 constexpr uint32_t __mask = 0x3;
814 auto* __end =
std::end(__incb_edges);
815 auto* __p = std::lower_bound(__incb_edges, __end, (__c << 2) | __mask);
816 return _InCB(__p[-1] & __mask);
820 __is_extended_pictographic(
char32_t __c)
822 if (__c < __xpicto_edges[0]) [[likely]]
825 auto* __p = std::upper_bound(__xpicto_edges,
std::end(__xpicto_edges), __c);
826 return (__p - __xpicto_edges) % 2;
829 struct _Grapheme_cluster_iterator_base
832 _Gcb_property _M_prop;
833 enum class _XPicto :
unsigned char { _Init, _Zwj, _Matched, _Failed };
834 _XPicto _M_xpicto_seq_state = _XPicto::_Init;
835 unsigned char _M_RI_count = 0;
836 bool _M_incb_linker_seen =
false;
839 _M_reset(
char32_t __c, _Gcb_property __p)
843 _M_xpicto_seq_state = _XPicto::_Init;
845 _M_incb_linker_seen =
false;
849 _M_update_xpicto_seq_state(
char32_t __c, _Gcb_property __p)
851 if (_M_xpicto_seq_state == _XPicto::_Failed)
854 auto __next_state = _XPicto::_Failed;
855 if (_M_xpicto_seq_state != _XPicto::_Zwj)
857 if (__p == _Gcb_property::_Gcb_ZWJ)
859 if (_M_xpicto_seq_state == _XPicto::_Matched)
860 __next_state = _XPicto::_Zwj;
863 else if (__is_extended_pictographic(_M_c))
864 __next_state = _XPicto::_Zwj;
866 else if (__p == _Gcb_property::_Gcb_Extend)
867 __next_state = _M_xpicto_seq_state;
873 if (__p == _Gcb_property::_Gcb_Other
874 && __is_extended_pictographic(__c))
875 __next_state = _XPicto::_Matched;
877 _M_xpicto_seq_state = __next_state;
881 _M_update_ri_count(_Gcb_property __p)
883 if (__p == _Gcb_property::_Gcb_Regional_Indicator)
890 _M_update_incb_state(
char32_t __c, _Gcb_property)
892 if (__is_incb_linker(__c))
893 _M_incb_linker_seen =
true;
898 template<ranges::forward_range _View>
requires ranges::view<_View>
899 class _Grapheme_cluster_view
900 :
public ranges::view_interface<_Grapheme_cluster_view<_View>>
905 _Grapheme_cluster_view(_View __v)
906 : _M_begin(_Utf32_view<_View>(std::
move(__v)).begin())
909 constexpr auto begin()
const {
return _M_begin; }
910 constexpr auto end()
const {
return _M_begin.end(); }
913 struct _Iterator :
private _Grapheme_cluster_iterator_base
917 using _U32_iterator = ranges::iterator_t<_Utf32_view<_View>>;
925 using value_type = char32_t;
926 using iterator_concept = forward_iterator_tag;
927 using difference_type = ptrdiff_t;
930 _Iterator(_U32_iterator __i)
933 if (__i != __i.end())
936 _M_prop = __grapheme_cluster_break_property(_M_c);
953 const auto __end = _M_base.end();
954 if (_M_base != __end)
956 auto __p_prev = _M_prop;
958 while (++__it != __end)
960 char32_t __c = *__it;
961 auto __p = __grapheme_cluster_break_property(*__it);
962 _M_update_xpicto_seq_state(__c, __p);
963 _M_update_ri_count(__p);
964 _M_update_incb_state(__c, __p);
965 if (_M_is_break(__p_prev, __p, __it))
987 operator==(
const _Iterator& __i)
const
988 {
return _M_base == __i._M_base; }
992 operator==(
const ranges::sentinel_t<_View>& __i)
const
993 {
return _M_base == __i; }
996 constexpr auto base()
const {
return _M_base.base(); }
999 constexpr auto end()
const {
return _M_base.end(); }
1003 width() const noexcept
1004 {
return __field_width(_M_c); }
1007 _U32_iterator _M_base;
1015 _M_is_break(_Gcb_property __p1, _Gcb_property __p2,
1016 _U32_iterator __curr)
const
1018 using enum _Gcb_property;
1020 if (__p1 == _Gcb_Control || __p1 == _Gcb_LF)
1023 if (__p1 == _Gcb_CR)
1024 return __p2 != _Gcb_LF;
1027 if (__p2 == _Gcb_Control || __p2 == _Gcb_CR || __p2 == _Gcb_LF)
1044 if (__p1 == _Gcb_LV || __p1 == _Gcb_V)
1055 if (__p1 == _Gcb_LVT || __p1 == _Gcb_T)
1056 return __p2 != _Gcb_T;
1059 if (__p2 == _Gcb_Extend || __p2 == _Gcb_ZWJ)
1066 if (__p2 == _Gcb_SpacingMark)
1069 if (__p1 == _Gcb_Prepend)
1075 if (_M_incb_linker_seen
1076 && __incb_property(_M_c) == _InCB::_Consonant
1077 && __incb_property(*__curr) == _InCB::_Consonant)
1081 bool __have_linker =
false;
1082 auto __it = _M_base;
1083 while (++__it != __curr)
1085 if (__is_incb_linker(*__it))
1086 __have_linker =
true;
1089 auto __incb = __incb_property(*__it);
1090 if (__incb == _InCB::_Consonant)
1091 __have_linker =
false;
1092 else if (__incb != _InCB::_Extend)
1096 if (__it == __curr && __have_linker)
1103 if (__p1 == _Gcb_ZWJ && _M_xpicto_seq_state == _XPicto::_Matched)
1110 if (__p1 == _Gcb_property::_Gcb_Regional_Indicator && __p1 == __p2)
1111 return (_M_RI_count & 1) == 0;
1124 template<
typename _CharT>
1126 __field_width(basic_string_view<_CharT> __s)
1128 if (__s.empty()) [[unlikely]]
1130 _Grapheme_cluster_view<basic_string_view<_CharT>> __gc(__s);
1131 auto __it = __gc.begin();
1132 const auto __end = __gc.end();
1133 size_t __n = __it.width();
1134 while (++__it != __end)
1135 __n += __it.width();
1141 template<
typename _CharT>
1143 __truncate(basic_string_view<_CharT>& __s,
size_t __max)
1145 if (__s.empty()) [[unlikely]]
1148 _Grapheme_cluster_view<basic_string_view<_CharT>> __gc(__s);
1149 auto __it = __gc.begin();
1150 const auto __end = __gc.end();
1151 size_t __n = __it.width();
1157 while (++__it != __end)
1159 size_t __n2 = __n + __it.width();
1162 __s = basic_string_view<_CharT>(__s.begin(), __it.base());
1170 template<
typename _CharT>
1172 __literal_encoding_is_unicode()
1174 if constexpr (is_same_v<_CharT, char16_t>)
1176 else if constexpr (is_same_v<_CharT, char32_t>)
1179 else if constexpr (is_same_v<_CharT, char8_t>)
1183 const char* __enc =
"";
1185#ifdef __GNUC_EXECUTION_CHARSET_NAME
1186 auto __remove_iso10646_prefix = [](
const char* __s) {
1188 if (__s[0] ==
'I' || __s[0] ==
'i')
1189 if (__s[1] ==
'S' || __s[1] ==
's')
1190 if (__s[2] ==
'O' || __s[2] ==
'o')
1191 if (string_view(__s + 3).starts_with(
"-10646/"))
1196 if constexpr (is_same_v<_CharT, char>)
1197 __enc = __remove_iso10646_prefix(__GNUC_EXECUTION_CHARSET_NAME);
1198# if defined _GLIBCXX_USE_WCHAR_T && defined __GNUC_WIDE_EXECUTION_CHARSET_NAME
1200 __enc = __remove_iso10646_prefix(__GNUC_WIDE_EXECUTION_CHARSET_NAME);
1203 if ((__enc[0] ==
'U' || __enc[0] ==
'u')
1204 && (__enc[1] ==
'T' || __enc[1] ==
't')
1205 && (__enc[2] ==
'F' || __enc[2] ==
'f'))
1208 if (__enc[0] ==
'-')
1210 if (__enc[0] ==
'8')
1211 return __enc[1] ==
'\0' || string_view(__enc + 1) ==
"//";
1212 else if constexpr (!is_same_v<_CharT, char>)
1214 string_view __s(__enc);
1215 if (__s.ends_with(
"//"))
1216 __s.remove_suffix(2);
1217 if (__s.ends_with(
"LE") || __s.ends_with(
"BE"))
1218 __s.remove_suffix(2);
1219 return __s ==
"16" || __s ==
"32";
1222#elif defined __clang_literal_encoding__
1223 if constexpr (is_same_v<_CharT, char>)
1224 __enc = __clang_literal_encoding__;
1225# if defined _GLIBCXX_USE_WCHAR_T && defined __clang_wide_literal_encoding__
1227 __enc = __clang_wide_literal_encoding__;
1230 string_view __s(__enc);
1233 else if constexpr (!is_same_v<_CharT, char>)
1234 return __s ==
"UTF-16" || __s ==
"UTF-32";
1241 __literal_encoding_is_utf8()
1242 {
return __literal_encoding_is_unicode<char>(); }
1245 __literal_encoding_is_extended_ascii()
1247 return '0' == 0x30 &&
'A' == 0x41 &&
'Z' == 0x5a
1248 &&
'a' == 0x61 &&
'z' == 0x7a;
1253 __charset_alias_match(string_view __a, string_view __b)
1256 auto __map = [](
char __c,
bool& __num) ->
unsigned char {
1257 if (__c ==
'0') [[unlikely]]
1258 return __num ? 0 : 127;
1259 const auto __v = __detail::__from_chars_alnum_to_val(__c);
1264 auto __ptr_a = __a.begin(), __end_a = __a.end();
1265 auto __ptr_b = __b.begin(), __end_b = __b.end();
1266 bool __num_a =
false, __num_b =
false;
1271 unsigned char __val_a{}, __val_b{};
1272 while (__ptr_a != __end_a
1273 && (__val_a = __map(*__ptr_a, __num_a)) == 127)
1275 while (__ptr_b != __end_b
1276 && (__val_b = __map(*__ptr_b, __num_b)) == 127)
1279 if (__ptr_a == __end_a)
1280 return __ptr_b == __end_b;
1281 else if (__ptr_b == __end_b)
1283 else if (__val_a != __val_b)
1295 template<
typename _To,
typename _Range>
1296 inline constexpr bool
1297 enable_borrowed_range<std::__unicode::_Utf_view<_To, _Range>>
1298 = enable_borrowed_range<_Range>;
1300 template<
typename _Range>
1301 inline constexpr bool
1302 enable_borrowed_range<std::__unicode::_Grapheme_cluster_view<_Range>>
1303 = enable_borrowed_range<_Range>;
1306_GLIBCXX_END_NAMESPACE_VERSION
constexpr std::remove_reference< _Tp >::type && move(_Tp &&__t) noexcept
Convert a value to an rvalue.
_Tp * end(valarray< _Tp > &__va) noexcept
Return an iterator pointing to one past the last element of the valarray.
ISO C++ entities toplevel namespace is std.
constexpr void advance(_InputIterator &__i, _Distance __n)
A generalization of pointer arithmetic.