// Unicode utilities -*- C++ -*-

// Copyright The GNU Toolchain Authors.
//
// This file is part of the GNU ISO C++ Library.  This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.

// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.

// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.

// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
// <http://www.gnu.org/licenses/>.

/** @file include/bits/unicode.h
 *  This is an internal header file, included by other library headers.
 *  Do not attempt to use it directly. @headername{format}
 */

#ifndef _GLIBCXX_UNICODE_H
#define _GLIBCXX_UNICODE_H 1

#if __cplusplus >= 202002L
#include <array>
#include <bit>      // bit_width
#include <charconv> // __detail::__from_chars_alnum_to_val_table
#include <string_view>
#include <cstdint>
#include <bits/stl_algo.h>
#include <bits/stl_iterator.h>
#include <bits/ranges_base.h> // iterator_t, sentinel_t, input_range, etc.
#include <bits/ranges_util.h> // view_interface

namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
namespace __unicode
{
  // A Unicode code point that is not a high or low surrogate.
  constexpr bool
  __is_scalar_value(char32_t __c)
  {
    if (__c < 0xD800) [[likely]]
      return true;
    return 0xDFFF < __c && __c <= 0x10FFFF;
  }

  // A code point that can be encoded in a single code unit of type _CharT.
  template<typename _CharT>
    constexpr bool
    __is_single_code_unit(char32_t __c)
    {
      if constexpr (__gnu_cxx::__int_traits<_CharT>::__max <= 0xFF)
	return __c <= 0x7F; // ASCII character
      else
	return __c < __gnu_cxx::__int_traits<_CharT>::__max
		       && __is_scalar_value(__c);
    }

  // Based on https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2728r6.html#add-the-transcoding-iterator-template

  struct _Repl
  {
    constexpr char32_t
    operator()() const noexcept
    { return 0xFFFD; }
  };

  struct _Null_sentinel_t
  {
    template<input_iterator _It>
      requires default_initializable<iter_value_t<_It>>
	&& equality_comparable_with<iter_reference_t<_It>, iter_value_t<_It>>
      friend constexpr auto
      operator==(_It __it, _Null_sentinel_t)
      { return *__it == iter_value_t<_It>{}; }
  };

  // An iterator over an input range of FromFmt code units that yields either
  // UTF-8, UTF-16, or UTF-32, as a range of ToFmt code units.
  // The code units from the input range are interpreted as Unicode code points
  // and the iterator produces the individual code unit for each code point.
  // Invalid sequences in the input are replaced with U+FFDD so that the result
  // is always valid UTF-8, UTF-16, or UTF-32.
  //
  // The iterator knows the bounds of the underlying input range and will not
  // read outside those bounds (incrementing or decrementing at the boundary
  // is erroneously idempotent).
  //
  // On construction, the iterator attempts to decode a single code point from
  // the input range and then encode it into an internal buffer in the output
  // format, e.g. if the input is UTF-8 and the output is UTF-16, it might read
  // three char8_t code units from the input and store two char16_t code units
  // in its buffer. Incrementing the iterator will first iterate over buffer,
  // yielding each code unit in turn, and then extract another code point from
  // the input. Failure to extract a valid code point from the input will store
  // U+FFFD in the buffer, encoded as the appropriate code units of type ToFmt.
  template<typename _FromFmt, typename _ToFmt,
	   input_iterator _Iter, sentinel_for<_Iter> _Sent = _Iter,
	   typename _ErrorHandler = _Repl>
    requires convertible_to<iter_value_t<_Iter>, _FromFmt>
    class _Utf_iterator
    {
      static_assert(forward_iterator<_Iter> || noexcept(_ErrorHandler()()));

    public:
      using value_type = _ToFmt;
      using difference_type = iter_difference_t<_Iter>;
      using reference = value_type;
      using iterator_concept
	= std::__detail::__clamp_iter_cat<__iter_category_t<_Iter>,
					  bidirectional_iterator_tag>;

      constexpr _Utf_iterator() = default;

      constexpr
      _Utf_iterator(_Iter __first, _Iter __it, _Sent __last)
      requires bidirectional_iterator<_Iter>
      : _M_first_and_curr{__first, __it}, _M_last(__last)
      {
	if (_M_curr() != _M_last)
	  _M_read();
	else
	  _M_buf = {};
      }

      constexpr
      _Utf_iterator(_Iter __it, _Sent __last)
      requires (!bidirectional_iterator<_Iter>)
      : _M_first_and_curr{__it}, _M_last(__last)
      {
	if (_M_curr() != _M_last)
	  _M_read();
	else
	  _M_buf = {};
      }

      template<class _Iter2, class _Sent2>
	requires convertible_to<_Iter2, _Iter> && convertible_to<_Sent2, _Sent>
	constexpr
	_Utf_iterator(const _Utf_iterator<_FromFmt, _ToFmt, _Iter2, _Sent2,
					  _ErrorHandler>& __other)
	: _M_buf(__other._M_buf), _M_first_and_curr(__other._M_first_and_curr),
	  _M_buf_index(__other._M_buf_index), _M_buf_last(__other._M_buf_last),
	  _M_last(__other._M_last)
	{ }

      [[nodiscard]]
      constexpr _Iter
      begin() const requires bidirectional_iterator<_Iter>
      { return _M_first(); }

      [[nodiscard]]
      constexpr _Sent
      end() const { return _M_last; }

      [[nodiscard]]
      constexpr _Iter
      base() const requires forward_iterator<_Iter>
      { return _M_curr(); }

      [[nodiscard]]
      constexpr iter_difference_t<_Iter> 
      _M_units() const requires forward_iterator<_Iter>
      { return _M_to_increment; }

      [[nodiscard]]
      constexpr value_type
      operator*() const { return _M_buf[_M_buf_index]; }

      constexpr _Utf_iterator&
      operator++()
      {
	if (_M_buf_index + 1 < _M_buf_last)
	  ++_M_buf_index; // Move to the next code unit in the buffer.
	else if (_M_curr() != _M_last)
	  {
	    // Advance past the current code point (for non-forward iterators
	    // we already moved there after decoding the last code point).
	    if constexpr (forward_iterator<_Iter>)
	      std::advance(_M_curr(), _M_to_increment);
	    if (_M_curr() == _M_last)
	      _M_buf_index = 0;
	    else // Decode next code point from the input and update buffer.
	      _M_read();
	  }
	// else erroneous, but ignored for now.
	return *this;
      }

      constexpr _Utf_iterator
      operator++(int)
      {
	auto __tmp = *this;
	++*this;
	return __tmp;
      }

      constexpr _Utf_iterator&
      operator--() requires bidirectional_iterator<_Iter>
      {
	if (_M_buf_index > 0)
	  --_M_buf_index;
	else if (_M_curr() != _M_first())
	  {
	    _M_read_reverse();
	    _M_buf_index = _M_buf_last - 1;
	    ranges::advance(_M_curr(), -_M_to_increment);
	  }
	// else erroneous, but ignored for now.
	return *this;
      }

      constexpr _Utf_iterator
      operator--(int)
      {
	auto __tmp = *this;
	--*this;
	return __tmp;
      }

      [[nodiscard]]
      friend constexpr bool
      operator==(_Utf_iterator __lhs, _Utf_iterator __rhs)
      requires forward_iterator<_Iter> || requires (_Iter __i) { __i != __i; }
      {
	if constexpr (forward_iterator<_Iter>)
	  return __lhs._M_curr() == __rhs._M_curr()
		   && __lhs._M_buf_index == __rhs._M_buf_index;
	else if (__lhs._M_curr() != __rhs._M_curr())
	  return false;
	else if (__lhs._M_buf_index == __rhs._M_buf_index
		   && __lhs._M_buf_last == __rhs._M_buf_last)
	  return true;
	else
	  return __lhs._M_buf_index == __lhs._M_buf_last
		   && __rhs._M_buf_index == __rhs._M_buf_last;
      }

      [[nodiscard]]
      friend constexpr bool
      operator==(_Utf_iterator __lhs, _Sent __rhs)
      {
	if constexpr (forward_iterator<_Iter>)
	  return __lhs._M_curr() == __rhs;
	else
	  return __lhs._M_curr() == __rhs
		   && __lhs._M_buf_index == __lhs._M_buf_last;
      }

    private:
      constexpr void
      _M_read()
      {
	if constexpr (sizeof(_FromFmt) == sizeof(uint8_t))
	  _M_read_utf8();
	else if constexpr (sizeof(_FromFmt) == sizeof(uint16_t))
	  _M_read_utf16();
	else
	  {
	    static_assert(sizeof(_FromFmt) == sizeof(uint32_t));
	    _M_read_utf32();
	  }
      }

      constexpr void
      _M_read_reverse() requires bidirectional_iterator<_Iter>
      {
	if constexpr (sizeof(_FromFmt) == sizeof(uint8_t))
	  _M_read_reverse_utf8();
	else if constexpr (sizeof(_FromFmt) == sizeof(uint16_t))
	  _M_read_reverse_utf16();
	else
	  {
	    static_assert(sizeof(_FromFmt) == sizeof(uint32_t));
	    _M_read_reverse_utf32();
	  }
      }

      template<typename>
	struct _Guard
	{
	  _Guard(void*, _Iter&) { }
	};

      template<typename _It> requires forward_iterator<_It>
	struct _Guard<_It>
	{
	  constexpr ~_Guard() { _M_this->_M_curr() = std::move(_M_orig); }
	  _Utf_iterator* _M_this;
	  _It _M_orig;
	};

      constexpr char32_t
      _M_read_utf8()
      {
	_Guard<_Iter> __g{this, _M_curr()};
	char32_t __c{};
	const uint8_t __lo_bound = 0x80, __hi_bound = 0xBF;
	uint8_t __u = *_M_curr()++;
	uint8_t __to_incr = 1;
	auto __incr = [&, this] {
	  ++__to_incr;
	  return ++_M_curr();
	};

	if (__u <= 0x7F) [[likely]]      // 0x00 to 0x7F
	  __c = __u;
	else if (__u < 0xC2) [[unlikely]]
	  __c = _S_error();
	else if (_M_curr() == _M_last) [[unlikely]]
	  __c = _S_error();
	else if (__u <= 0xDF) // 0xC2 to 0xDF
	  {
	    __c = __u & 0x1F;
	    __u = *_M_curr();

	    if (__u < __lo_bound || __u > __hi_bound) [[unlikely]]
	      __c = _S_error();
	    else
	      {
		__c = (__c << 6) | (__u & 0x3F);
		__incr();
	      }
	  }
	else if (__u <= 0xEF) // 0xE0 to 0xEF
	  {
	    const uint8_t __lo_bound_2 = __u == 0xE0 ? 0xA0 : __lo_bound;
	    const uint8_t __hi_bound_2 = __u == 0xED ? 0x9F : __hi_bound;

	    __c = __u & 0x0F;
	    __u = *_M_curr();

	    if (__u < __lo_bound_2 || __u > __hi_bound_2) [[unlikely]]
	      __c = _S_error();
	    else if (__incr() == _M_last) [[unlikely]]
	      __c = _S_error();
	    else
	      {
		__c = (__c << 6) | (__u & 0x3F);
		__u = *_M_curr();

		if (__u < __lo_bound || __u > __hi_bound) [[unlikely]]
		  __c = _S_error();
		else
		  {
		    __c = (__c << 6) | (__u & 0x3F);
		    __incr();
		  }
	      }
	  }
	else if (__u <= 0xF4) // 0xF0 to 0xF4
	  {
	    const uint8_t __lo_bound_2 = __u == 0xF0 ? 0x90 : __lo_bound;
	    const uint8_t __hi_bound_2 = __u == 0xF4 ? 0x8F : __hi_bound;

	    __c = __u & 0x07;
	    __u = *_M_curr();

	    if (__u < __lo_bound_2 || __u > __hi_bound_2) [[unlikely]]
	      __c = _S_error();
	    else if (__incr() == _M_last) [[unlikely]]
	      __c = _S_error();
	    else
	      {
		__c = (__c << 6) | (__u & 0x3F);
		__u = *_M_curr();

		if (__u < __lo_bound || __u > __hi_bound) [[unlikely]]
		  __c = _S_error();
		else if (__incr() == _M_last) [[unlikely]]
		  __c = _S_error();
		else
		  {
		    __c = (__c << 6) | (__u & 0x3F);
		    __u = *_M_curr();

		    if (__u < __lo_bound || __u > __hi_bound) [[unlikely]]
		      __c = _S_error();
		    else
		      {
			__c = (__c << 6) | (__u & 0x3F);
			__incr();
		      }
		  }
	      }
	  }
	else [[unlikely]]
	  __c = _S_error();

	_M_update(__c, __to_incr);

	return __c;
      }

      constexpr void
      _M_read_utf16()
      {
	_Guard<_Iter> __g{this, _M_curr()};
	char32_t __c{};
	uint16_t __u = *_M_curr()++;
	uint8_t __to_incr = 1;

	if (__u < 0xD800 || __u > 0xDFFF) [[likely]]
	  __c = __u;
	else if (__u < 0xDC00 && _M_curr() != _M_last)
	  {
	    uint16_t __u2 = *_M_curr();
	    if (__u2 < 0xDC00 || __u2 > 0xDFFF) [[unlikely]]
	      __c = _S_error();
	    else
	      {
		++_M_curr();
		__to_incr = 2;
		uint32_t __x = (__u & 0x3F) << 10 | (__u2 & 0x3FF);
		uint32_t __w = (__u >> 6) & 0x1F;
		__c = (__w + 1) << 16 | __x;
	      }
	  }
	else
	  __c = _S_error();

	_M_update(__c, __to_incr);
      }

      constexpr void
      _M_read_utf32()
      {
	_Guard<_Iter> __g{this, _M_curr()};
	char32_t __c = *_M_curr()++;
	if (!__is_scalar_value(__c)) [[unlikely]]
	  __c = _S_error();
	_M_update(__c, 1);
      }

      constexpr void
      _M_read_reverse_utf8() requires bidirectional_iterator<_Iter>
      {
	const auto __first = _M_first();
	auto __curr = _M_curr();
	// The code point we decode:
	char32_t __c{};
	// The last code unit read:
	uint8_t __u = *--__curr;
	// Count of bytes read:
	uint8_t __to_incr = 1;

	if (__u <= 0x7F) [[likely]]
	  {
	    _M_update(__u, 1);
	    return;
	  }

	// Continuation bytes match 10xxxxxx
	auto __is_continuation = [](uint8_t __b) {
	  return (__b & 0xC0) == 0x80;
	};
	// 0xC0 and 0xC1 would produce overlong encodings of ASCII characters.
	// 0xF5-0xFF would produce code points above U+10FFFF
	auto __is_invalid = [](uint8_t __b) {
	  return (__b & 0xFE) == 0xC0 || __b >= 0xF5;
	};

	// No valid or invalid multibyte sequence is longer than 4 bytes,
	// so skip back over at most four bytes.
	while (__is_continuation(__u) && __to_incr < 4 && __curr != __first)
	  {
	    ++__to_incr;
	    __u = *--__curr;
	  }

	// If the last byte read was a continuation byte then either we read
	// four continuation bytes, or stopped at the start of the sequence.
	// Either way, the maximal subparts are the individual continuation
	// bytes so each one should be replaced with U+FFFD.
	if (__is_continuation(__u) || __is_invalid(__u)) [[unlikely]]
	  {
	    // Either found four continuation bytes (maximum allowed is three)
	    // or first non-continuation byte is an invalid UTF-8 code unit.
	    _M_update(_S_error(), 1);
	    return;
	  }
	// __u is a valid start byte so use countl_one to get the expected
	// length of the multibyte sequence that starts with this byte.
	int __seq_length = std::countl_one((unsigned char)__u);
	if (__seq_length < __to_incr) [[unlikely]]
	  {
	    // If the expected number of continuation bytes is less than
	    // the number we found, then the last continuation byte is a
	    // maximal subpart and the decremented iterator points to it.
	    _M_update(_S_error(), 1);
	    return;
	  }

	auto __orig = std::__exchange(_M_curr(), std::move(__curr));
	if (_M_read_utf8() == _S_error()) [[unlikely]]
	  {
	    if (_M_to_increment < __to_incr) // Read truncated sequence, set
	      _M_to_increment = 1;           // curr to last continuation byte.
	  }

	_M_curr() = std::move(__orig);
	// operator--() will move back by _M_to_increment
      }

      constexpr void
      _M_read_reverse_utf16() requires bidirectional_iterator<_Iter>
      {
	_Guard<_Iter> __g{this, _M_curr()};
	char32_t __c{};
	uint16_t __u = *--_M_curr();
	uint8_t __to_incr = 1;

	if (__u < 0xD800 || __u > 0xDFFF) [[likely]]
	  __c = __u;
	else if (__u >= 0xDC00 && _M_curr() != _M_first()) [[likely]]
	  {
	    // read a low surrogate, expect a high surrogate before it.
	    uint16_t __u2 = *--_M_curr();
	    if (__u2 < 0xD800 || __u2 >= 0xDC00) [[unlikely]]
	      __c = _S_error(); // unpaired low surrogate
	    else
	      {
		__to_incr = 2;
		uint32_t __x = (__u2 & 0x3F) << 10 | (__u & 0x3FF);
		uint32_t __w = (__u2 >> 6) & 0x1F;
		__c = (__w + 1) << 16 | __x;
	      }
	  }
	else
	  __c = _S_error(); // unpaired surrogate

	_M_update(__c, __to_incr);
      }

      constexpr void
      _M_read_reverse_utf32() requires bidirectional_iterator<_Iter>
      {
	_Guard<_Iter> __g{this, _M_curr()};
	char32_t __c = *--_M_curr();
	if (!__is_scalar_value(__c)) [[unlikely]]
	  __c = _S_error();
	_M_update(__c, 1);
      }

      // Encode the code point __c as one or more code units in _M_buf.
      constexpr void
      _M_update(char32_t __c, uint8_t __to_incr)
      {
	_M_to_increment = __to_incr;
	_M_buf_index = 0;
	if constexpr (sizeof(_ToFmt) == sizeof(uint32_t))
	  {
	    _M_buf[0] = __c;
	    _M_buf_last = 1;
	  }
	else if constexpr (sizeof(_ToFmt) == sizeof(uint16_t))
	  {
	    if (__is_single_code_unit<_ToFmt>(__c))
	      {
		_M_buf[0] = __c;
		_M_buf[1] = 0;
		_M_buf_last = 1;
	      }
	    else
	      {
		// From http://www.unicode.org/faq/utf_bom.html#utf16-4
		const char32_t __lead_offset = 0xD800 - (0x10000 >> 10);
		char16_t __lead = __lead_offset + (__c >> 10);
		char16_t __trail = 0xDC00 + (__c & 0x3FF);
		_M_buf[0] = __lead;
		_M_buf[1] = __trail;
		_M_buf_last = 2;
	      }
	  }
	else
	  {
	    static_assert(sizeof(_ToFmt) == 1);
	    int __bits = std::bit_width((uint32_t)__c);
	    if (__bits <= 7) [[likely]]
	      {
		_M_buf[0] = __c;
		_M_buf[1] = _M_buf[2] = _M_buf[3] = 0;
		_M_buf_last = 1;
	      }
	    else if (__bits <= 11)
	      {
		_M_buf[0] = 0xC0 | (__c >> 6);
		_M_buf[1] = 0x80 | (__c & 0x3F);
		_M_buf[2] = _M_buf[3] = 0;
		_M_buf_last = 2;
	      }
	    else if (__bits <= 16)
	      {
		_M_buf[0] = 0xE0 | (__c >> 12);
		_M_buf[1] = 0x80 | ((__c >> 6) & 0x3F);
		_M_buf[2] = 0x80 | (__c & 0x3F);
		_M_buf[3] = 0;
		_M_buf_last = 3;
	      }
	    else
	      {
		_M_buf[0] = 0xF0 | ((__c >> 18) & 0x07);
		_M_buf[1] = 0x80 | ((__c >> 12) & 0x3F);
		_M_buf[2] = 0x80 | ((__c >> 6) & 0x3F);
		_M_buf[3] = 0x80 | (__c & 0x3F);
		_M_buf_last = 4;
	      }
	  }
      }

      constexpr char32_t
      _S_error()
      {
	char32_t __c = _ErrorHandler()();
	__glibcxx_assert(__is_scalar_value(__c));
	return __c;
      }

      constexpr _Iter
      _M_first() const requires bidirectional_iterator<_Iter>
      { return _M_first_and_curr._M_first; }

      constexpr _Iter&
      _M_curr() { return _M_first_and_curr._M_curr; }

      constexpr _Iter
      _M_curr() const { return _M_first_and_curr._M_curr; }

      // _M_first is not needed for non-bidirectional ranges.
      template<typename _It>
	struct _First_and_curr
	{
	  _First_and_curr() = default;

	  constexpr
	  _First_and_curr(_It __curr) : _M_curr(__curr) { }

	  template<convertible_to<_It> _It2>
	    constexpr
	    _First_and_curr(const _First_and_curr<_It2>& __other)
	    : _M_curr(__other._M_curr) { }

	  // First code unit of the current code point for forward iterators,
	  // past-the-end of the current code point for input iterators.
	  _It _M_curr;
	};

      template<typename _It> requires bidirectional_iterator<_It>
	struct _First_and_curr<_It>
	{
	  _First_and_curr() = default;

	  constexpr
	  _First_and_curr(_It __first, _It __curr)
	  : _M_first(__first), _M_curr(__curr) { }

	  template<convertible_to<_It> _It2>
	    constexpr
	    _First_and_curr(const _First_and_curr<_It2>& __other)
	    : _M_first(__other._M_first), _M_curr(__other._M_curr) { }

	  _It _M_first; // Start of the underlying range.
	  _It _M_curr;  // First code unit of the current code point.
	};

      // Iterators pointing to the start of the underlying range and to the
      // start (or end, for non-forward iterators) of the current code point.
      _First_and_curr<_Iter> _M_first_and_curr;

      // The end of the underlying input range.
      [[no_unique_address]] _Sent _M_last;

      // Buffer holding the individual code units of the current code point.
      array<value_type, 4 / sizeof(_ToFmt)> _M_buf;

      uint8_t _M_buf_index = 0;    // Index of current code unit in the buffer.
      uint8_t _M_buf_last = 0;     // Number of code units in the buffer.
      uint8_t _M_to_increment = 0; // How far to advance _M_curr on increment.

      template<typename _FromFmt2, typename _ToFmt2,
	       input_iterator _Iter2, sentinel_for<_Iter2> _Sent2,
	       typename _ErrHandler>
	requires convertible_to<iter_value_t<_Iter2>, _FromFmt2>
	friend class _Utf_iterator;
    };

  template<typename _ToFormat, ranges::input_range _View>
    requires ranges::view<_View>
    class _Utf_view
    : public ranges::view_interface<_Utf_view<_ToFormat, _View>>
    {
      using _Iterator = _Utf_iterator<ranges::range_value_t<_View>,
				      _ToFormat, ranges::iterator_t<_View>,
				      ranges::sentinel_t<_View>>;

      template<typename _Iter, typename _Sent>
	constexpr auto
	_M_begin(_Iter __first, _Sent __last)
	{
	  if constexpr (bidirectional_iterator<_Iter>)
	    return _Iterator(__first, __first, __last);
	  else
	    return _Iterator(__first, __last);
	}

      template<typename _Iter, typename _Sent>
	constexpr auto
	_M_end(_Iter __first, _Sent __last)
	{
	  if constexpr (!is_same_v<_Iter, _Sent>)
	    return __last;
	  else if constexpr (bidirectional_iterator<_Iter>)
	    return _Iterator(__first, __last, __last);
	  else
	    return _Iterator(__last, __last);
	}

      _View _M_base;

    public:
      constexpr explicit
      _Utf_view(_View __r) : _M_base(std::move(__r)) { }

      constexpr auto begin()
      { return _M_begin(ranges::begin(_M_base), ranges::end(_M_base)); }

      constexpr auto end()
      { return _M_end(ranges::begin(_M_base), ranges::end(_M_base)); }

      constexpr bool empty() const { return ranges::empty(_M_base); }
    };

#ifdef __cpp_char8_t
  template<typename _View>
    using _Utf8_view = _Utf_view<char8_t, _View>;
#else
  template<typename _View>
    using _Utf8_view = _Utf_view<char, _View>;
#endif
  template<typename _View>
    using _Utf16_view = _Utf_view<char16_t, _View>;
  template<typename _View>
    using _Utf32_view = _Utf_view<char32_t, _View>;

inline namespace __v16_0_0
{
#define _GLIBCXX_GET_UNICODE_DATA 160000
#include "unicode-data.h"
#ifdef _GLIBCXX_GET_UNICODE_DATA
# error "Invalid unicode data"
#endif

  // The field width of a code point.
  constexpr int
  __field_width(char32_t __c) noexcept
  {
    if (__c < __width_edges[0]) [[likely]]
      return 1;

    auto* __p = std::upper_bound(__width_edges, std::end(__width_edges), __c);
    return (__p - __width_edges) % 2 + 1;
  }

  // @pre c <= 0x10FFFF
  constexpr bool
  __should_escape_category(char32_t __c) noexcept
  {
    constexpr uint32_t __mask = 0x01;
    auto* __end = std::end(__escape_edges);
    auto* __p = std::lower_bound(__escape_edges, __end,
				 (__c << 1u) + 2);
    return __p[-1] & __mask;
  }


  // @pre c <= 0x10FFFF
  constexpr _Gcb_property
  __grapheme_cluster_break_property(char32_t __c) noexcept
  {
    constexpr uint32_t __mask = (1 << __gcb_shift_bits) - 1;
    auto* __end = std::end(__gcb_edges);
    auto* __p = std::lower_bound(__gcb_edges, __end,
				 (__c << __gcb_shift_bits) | __mask);
    return _Gcb_property(__p[-1] & __mask);
  }

  constexpr bool
  __is_incb_linker(char32_t __c) noexcept
  {
    const auto __end = std::end(__incb_linkers);
    // Array is small enough that linear search is faster than binary search.
    return _GLIBCXX_STD_A::find(__incb_linkers, __end, __c) != __end;
  }

  // @pre c <= 0x10FFFF
  constexpr _InCB
  __incb_property(char32_t __c) noexcept
  {
    if ((__c << 2) < __incb_edges[0]) [[likely]]
      return _InCB(0);

    constexpr uint32_t __mask = 0x3;
    auto* __end = std::end(__incb_edges);
    auto* __p = std::lower_bound(__incb_edges, __end, (__c << 2) | __mask);
    return _InCB(__p[-1] & __mask);
  }

  constexpr bool
  __is_extended_pictographic(char32_t __c)
  {
    if (__c < __xpicto_edges[0]) [[likely]]
      return 0;

    auto* __p = std::upper_bound(__xpicto_edges, std::end(__xpicto_edges), __c);
    return (__p - __xpicto_edges) % 2;
  }

  struct _Grapheme_cluster_iterator_base
  {
    char32_t _M_c; // First code point in the cluster.
    _Gcb_property _M_prop; // GCB property of _M_c.
    enum class _XPicto : unsigned char { _Init, _Zwj, _Matched, _Failed };
    _XPicto _M_xpicto_seq_state = _XPicto::_Init;
    unsigned char _M_RI_count = 0;
    bool _M_incb_linker_seen = false;

    constexpr void
    _M_reset(char32_t __c, _Gcb_property __p)
    {
      _M_c = __c;
      _M_prop = __p;
      _M_xpicto_seq_state = _XPicto::_Init;
      _M_RI_count = 0;
      _M_incb_linker_seen = false;
    }

    constexpr void
    _M_update_xpicto_seq_state(char32_t __c, _Gcb_property __p)
    {
      if (_M_xpicto_seq_state == _XPicto::_Failed)
	return;

      auto __next_state = _XPicto::_Failed;
      if (_M_xpicto_seq_state != _XPicto::_Zwj) // i.e. Init or Matched
	{
	  if (__p == _Gcb_property::_Gcb_ZWJ)
	    {
	      if (_M_xpicto_seq_state == _XPicto::_Matched)
		__next_state = _XPicto::_Zwj;
	      // We check _M_c here so that we do the lookup at most once,
	      // and only for clusters containing at least one ZWJ.
	      else if (__is_extended_pictographic(_M_c))
		__next_state = _XPicto::_Zwj;
	    }
	  else if (__p == _Gcb_property::_Gcb_Extend)
	    __next_state = _M_xpicto_seq_state; // no change
	}
      else // Zwj
	{
	  // This assumes that all \p{Extended_Pictographic} emoji have
	  // Grapheme_Cluster_Break=Other.
	  if (__p == _Gcb_property::_Gcb_Other
		&& __is_extended_pictographic(__c))
	    __next_state = _XPicto::_Matched;
	}
      _M_xpicto_seq_state = __next_state;
    }

    constexpr void
    _M_update_ri_count(_Gcb_property __p)
    {
      if (__p == _Gcb_property::_Gcb_Regional_Indicator)
	++_M_RI_count;
      else
	_M_RI_count = 0;
    }

    constexpr void
    _M_update_incb_state(char32_t __c, _Gcb_property)
    {
      if (__is_incb_linker(__c))
	_M_incb_linker_seen = true;
    }
  };

  // Split a range into extended grapheme clusters.
  template<ranges::forward_range _View> requires ranges::view<_View>
    class _Grapheme_cluster_view
    : public ranges::view_interface<_Grapheme_cluster_view<_View>>
    {
    public:

      constexpr
      _Grapheme_cluster_view(_View __v)
      : _M_begin(_Utf32_view<_View>(std::move(__v)).begin())
      { }

      constexpr auto begin() const { return _M_begin; }
      constexpr auto end() const { return _M_begin.end(); }

    private:
      struct _Iterator : private _Grapheme_cluster_iterator_base
      {
      private:
	// Iterator over the underlying code points.
	using _U32_iterator = ranges::iterator_t<_Utf32_view<_View>>;

      public:
	// TODO: Change value_type to be subrange<_U32_iterator> instead?
	// Alternatively, value_type could be _Utf32_view<iterator_t<_View>>.
	// That would be the whole cluster, not just the first code point.
	// Would need to store two iterators and find end of current cluster
	// on increment, so operator* returns value_type(_M_base, _M_next).
	using value_type = char32_t;
	using iterator_concept = forward_iterator_tag;
	using difference_type = ptrdiff_t;

	constexpr
	_Iterator(_U32_iterator __i)
	: _M_base(__i)
	{
	  if (__i != __i.end())
	    {
	      _M_c = *__i;
	      _M_prop = __grapheme_cluster_break_property(_M_c);
	    }
	}

	// The first code point of the current extended grapheme cluster.
	constexpr value_type
	operator*() const
	{ return _M_c; }

	constexpr auto
	operator->() const
	{ return &_M_c; }

	// Move to the next extended grapheme cluster.
	constexpr _Iterator&
	operator++()
	{
	  const auto __end = _M_base.end();
	  if (_M_base != __end)
	    {
	      auto __p_prev = _M_prop;
	      auto __it = _M_base;
	      while (++__it != __end)
		{
		  char32_t __c = *__it;
		  auto __p = __grapheme_cluster_break_property(*__it);
		  _M_update_xpicto_seq_state(__c, __p);
		  _M_update_ri_count(__p);
		  _M_update_incb_state(__c, __p);
		  if (_M_is_break(__p_prev, __p, __it))
		    {
		      // Found a grapheme cluster break
		      _M_reset(__c, __p);
		      break;
		    }
		  __p_prev = __p;
		}
	      _M_base = __it;
	    }
	  return *this;
	}

	constexpr _Iterator
	operator++(int)
	{
	  auto __tmp = *this;
	  ++*this;
	  return __tmp;
	}

	constexpr bool
	operator==(const _Iterator& __i) const
	{ return _M_base == __i._M_base; }

	// This supports iter != iter.end()
	constexpr bool
	operator==(const ranges::sentinel_t<_View>& __i) const
	{ return _M_base == __i; }

	// Iterator to the start of the current cluster.
	constexpr auto base() const { return _M_base.base(); }

	// The end of the underlying view (not the end of the current cluster!)
	constexpr auto end() const { return _M_base.end(); }

	// Field width of the first code point in the cluster.
	constexpr int
	width() const noexcept
	{ return __field_width(_M_c); }

      private:
	_U32_iterator _M_base;

	// Implement the Grapheme Cluster Boundary Rules from Unicode Annex #29
	// http://www.unicode.org/reports/tr29/#Grapheme_Cluster_Boundary_Rules
	// This implements the rules from TR29 revision 43 in Unicode 15.1.0.
	// Return true if there is a break between code point with property p1
	// and code point with property p2.
	constexpr bool
	_M_is_break(_Gcb_property __p1, _Gcb_property __p2,
		    _U32_iterator __curr) const
	{
	  using enum _Gcb_property;

	  if (__p1 == _Gcb_Control || __p1 == _Gcb_LF)
	    return true; // Break after Control or LF.

	  if (__p1 == _Gcb_CR)
	    return __p2 != _Gcb_LF; // Do not break between a CR and LF.

	  // Rule GB5
	  if (__p2 == _Gcb_Control || __p2 == _Gcb_CR || __p2 == _Gcb_LF)
	    return true; // Break before Control, CR or LF.

	  // Rule GB6
	  if (__p1 == _Gcb_L)
	    switch (__p2)
	    {
	      case _Gcb_L:
	      case _Gcb_V:
	      case _Gcb_LV:
	      case _Gcb_LVT:
		return false; // Do not break Hangul syllable sequences.
	      default:
		return true;
	      }

	  // Rule GB7
	  if (__p1 == _Gcb_LV || __p1 == _Gcb_V)
	    switch (__p2)
	    {
	      case _Gcb_V:
	      case _Gcb_T:
		return false; // Do not break Hangul syllable sequences.
	      default:
		return true;
	      }

	  // Rule GB8
	  if (__p1 == _Gcb_LVT || __p1 == _Gcb_T)
	    return __p2 != _Gcb_T; // Do not break Hangul syllable sequences.

	  // Rule GB9
	  if (__p2 == _Gcb_Extend || __p2 == _Gcb_ZWJ)
	    return false; // Do not break before extending characters or ZWJ.

	  // The following GB9x rules only apply to extended grapheme clusters,
	  // which is what the C++ standard uses (not legacy grapheme clusters).

	  // Rule GB9a
	  if (__p2 == _Gcb_SpacingMark)
	    return false; // Do not break before SpacingMarks,
	  // Rule GB9b
	  if (__p1 == _Gcb_Prepend)
	    return false; // or after Prepend characters.

	  // Rule GB9c (Unicode 15.1.0)
	  // Do not break within certain combinations with
	  // Indic_Conjunct_Break (InCB)=Linker.
	  if (_M_incb_linker_seen
		&& __incb_property(_M_c) == _InCB::_Consonant
		&& __incb_property(*__curr) == _InCB::_Consonant)
	    {
	      // Match [_M_base, __curr] against regular expression
	      // Consonant ([Extend Linker]* Linker [Extend Linker]* Consonant)+
	      bool __have_linker = false;
	      auto __it = _M_base;
	      while (++__it != __curr)
		{
		  if (__is_incb_linker(*__it))
		    __have_linker = true;
		  else
		    {
		      auto __incb = __incb_property(*__it);
		      if (__incb == _InCB::_Consonant)
			__have_linker = false;
		      else if (__incb != _InCB::_Extend)
			break;
		    }
		}
	      if (__it == __curr && __have_linker)
		return false;
	    }

	  // Rule GB11
	  // Do not break within emoji modifier sequences
	  // or emoji zwj sequences.
	  if (__p1 == _Gcb_ZWJ && _M_xpicto_seq_state == _XPicto::_Matched)
	    return false;

	  // Rules GB12 and GB13
	  // Do not break within emoji flag sequences. That is, do not break
	  // between regional indicator (RI) symbols if there is an odd number
	  // of RI characters before the break point.
	  if (__p1 == _Gcb_property::_Gcb_Regional_Indicator && __p1 == __p2)
	    return (_M_RI_count & 1) == 0;

	  // Rule GB999
	  return true; // Otherwise, break everywhere.
	}
      };

      _Iterator _M_begin;
    };

} // namespace __v16_0_0

  // Return the field width of a string.
  template<typename _CharT>
    constexpr size_t
    __field_width(basic_string_view<_CharT> __s)
    {
      if (__s.empty()) [[unlikely]]
	return 0;
      _Grapheme_cluster_view<basic_string_view<_CharT>> __gc(__s);
      auto __it = __gc.begin();
      const auto __end = __gc.end();
      size_t __n = __it.width();
      while (++__it != __end)
	__n += __it.width();
      return __n;
    }

  // Truncate a string to at most `__max` field width units, and return the
  // resulting field width.
  template<typename _CharT>
    constexpr size_t
    __truncate(basic_string_view<_CharT>& __s, size_t __max)
    {
      if (__s.empty()) [[unlikely]]
	return 0;

      _Grapheme_cluster_view<basic_string_view<_CharT>> __gc(__s);
      auto __it = __gc.begin();
      const auto __end = __gc.end();
      size_t __n = __it.width();
      if (__n > __max)
	{
	  __s = {};
	  return 0;
	}
      while (++__it != __end)
	{
	  size_t __n2 = __n + __it.width();
	  if (__n2 > __max)
	    {
	      __s = basic_string_view<_CharT>(__s.begin(), __it.base());
	      return __n;
	    }
	  __n = __n2;
	}
      return __n;
    }

  template<typename _CharT>
    consteval bool
    __literal_encoding_is_unicode()
    {
      if constexpr (is_same_v<_CharT, char16_t>)
	return true;
      else if constexpr (is_same_v<_CharT, char32_t>)
	  return true;
#ifdef __cpp_char8_t
      else if constexpr (is_same_v<_CharT, char8_t>)
	return true;
#endif

      const char* __enc = "";

#ifdef __GNUC_EXECUTION_CHARSET_NAME
      auto __remove_iso10646_prefix = [](const char* __s) {
	// GNU iconv allows "ISO-10646/" prefix (case-insensitive).
	if (__s[0] == 'I' || __s[0] == 'i')
	  if (__s[1] == 'S' || __s[1] == 's')
	    if (__s[2] == 'O' || __s[2] == 'o')
	      if (string_view(__s + 3).starts_with("-10646/"))
		return __s + 10;
	return __s;
      };

      if constexpr (is_same_v<_CharT, char>)
	__enc = __remove_iso10646_prefix(__GNUC_EXECUTION_CHARSET_NAME);
# if defined _GLIBCXX_USE_WCHAR_T && defined __GNUC_WIDE_EXECUTION_CHARSET_NAME
      else
	__enc = __remove_iso10646_prefix(__GNUC_WIDE_EXECUTION_CHARSET_NAME);
# endif

      if ((__enc[0] == 'U' || __enc[0] == 'u')
	    && (__enc[1] == 'T' || __enc[1] == 't')
	    && (__enc[2] == 'F' || __enc[2] == 'f'))
	{
	  __enc += 3;
	  if (__enc[0] == '-')
	    ++__enc;
	  if (__enc[0] == '8')
	    return __enc[1] == '\0' || string_view(__enc + 1) == "//";
	  else if constexpr (!is_same_v<_CharT, char>)
	    {
	      string_view __s(__enc);
	      if (__s.ends_with("//"))
		__s.remove_suffix(2);
	      if (__s.ends_with("LE") || __s.ends_with("BE"))
		__s.remove_suffix(2);
	      return __s == "16" || __s == "32";
	    }
	}
#elif defined __clang_literal_encoding__
      if constexpr (is_same_v<_CharT, char>)
	__enc = __clang_literal_encoding__;
# if defined _GLIBCXX_USE_WCHAR_T && defined __clang_wide_literal_encoding__
      else
	__enc = __clang_wide_literal_encoding__;
# endif
      // Clang accepts "-fexec-charset=utf-8" but the macro is still uppercase.
      string_view __s(__enc);
      if (__s == "UTF-8")
	return true;
      else if constexpr (!is_same_v<_CharT, char>)
	return __s == "UTF-16" || __s == "UTF-32";
#endif

      return false;
    }

  consteval bool
  __literal_encoding_is_utf8()
  { return __literal_encoding_is_unicode<char>(); }

  consteval bool
  __literal_encoding_is_extended_ascii()
  {
    return '0' == 0x30 && 'A' == 0x41 && 'Z' == 0x5a
	     && 'a' == 0x61 && 'z' == 0x7a;
  }

  // https://www.unicode.org/reports/tr22/tr22-8.html#Charset_Alias_Matching
  constexpr bool
  __charset_alias_match(string_view __a, string_view __b)
  {
    // Map alphanumeric chars to their base 64 value, everything else to 127.
    auto __map = [](char __c, bool& __num) -> unsigned char {
      if (__c == '0') [[unlikely]]
	return __num ? 0 : 127;
      const auto __v = __detail::__from_chars_alnum_to_val(__c);
      __num = __v < 10;
      return __v;
    };

    auto __ptr_a = __a.begin(), __end_a = __a.end();
    auto __ptr_b = __b.begin(), __end_b = __b.end();
    bool __num_a = false, __num_b = false;

    while (true)
      {
	// Find the value of the next alphanumeric character in each string.
	unsigned char __val_a{}, __val_b{};
	while (__ptr_a != __end_a
		 && (__val_a = __map(*__ptr_a, __num_a)) == 127)
	  ++__ptr_a;
	while (__ptr_b != __end_b
		 && (__val_b = __map(*__ptr_b, __num_b)) == 127)
	  ++__ptr_b;
	// Stop when we reach the end of a string, or get a mismatch.
	if (__ptr_a == __end_a)
	  return __ptr_b == __end_b;
	else if (__ptr_b == __end_b)
	  return false;
	else if (__val_a != __val_b)
	  return false; // Found non-matching characters.
	++__ptr_a;
	++__ptr_b;
      }
    return true;
  }

} // namespace __unicode

namespace ranges
{
  template<typename _To, typename _Range>
    inline constexpr bool
    enable_borrowed_range<std::__unicode::_Utf_view<_To, _Range>>
      = enable_borrowed_range<_Range>;

  template<typename _Range>
    inline constexpr bool
    enable_borrowed_range<std::__unicode::_Grapheme_cluster_view<_Range>>
      = enable_borrowed_range<_Range>;
} // namespace ranges

_GLIBCXX_END_NAMESPACE_VERSION
} // namespace std
#endif // C++20
#endif // _GLIBCXX_UNICODE_H
