// <generator> -*- C++ -*-

// Copyright (C) 2023-2025 Free Software Foundation, Inc.
//
// 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/generator
 *  This is a Standard C++ Library header.
 */

#ifndef _GLIBCXX_GENERATOR
#define _GLIBCXX_GENERATOR

#include <ranges>
#ifdef _GLIBCXX_SYSHDR
#pragma GCC system_header
#endif

#include <bits/c++config.h>

#define __glibcxx_want_generator
#include <bits/version.h>

#ifdef __cpp_lib_generator  // C++ >= 23 && __glibcxx_coroutine
#include <new>
#include <bits/move.h>
#include <bits/ranges_util.h>
#include <bits/elements_of.h>
#include <bits/uses_allocator.h>
#include <bits/exception_ptr.h>
#include <cstddef>
#include <cstdint>
#include <cstring>
#include <coroutine>

#include <type_traits>
#include <variant>
#include <concepts>

#if _GLIBCXX_HOSTED
# include <bits/memory_resource.h>
#endif // HOSTED

namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION

  /**
   * @defgroup generator_coros Range generator coroutines
   * @addtogroup ranges
   * @since C++23
   * @{
   */

  /** @brief A range specified using a yielding coroutine.
   *
   * `std::generator` is a utility class for defining ranges using coroutines
   * that yield elements as a range.  Generator coroutines are synchronous.
   *
   * @headerfile generator
   * @since C++23
   */
  template<typename _Ref, typename _Val = void, typename _Alloc = void>
    class generator;

  /// @cond undocumented
  namespace __gen
  {
    /// _Reference type for a generator whose reference (first argument) and
    /// value (second argument) types are _Ref and _Val.
    template<typename _Ref, typename _Val>
    using _Reference_t = __conditional_t<is_void_v<_Val>,
					 _Ref&&, _Ref>;

    /// Type yielded by a generator whose _Reference type is _Reference.
    template<typename _Reference>
    using _Yield_t = __conditional_t<is_reference_v<_Reference>,
				     _Reference,
				     const _Reference&>;

    /// _Yield_t * _Reference_t
    template<typename _Ref, typename _Val>
    using _Yield2_t = _Yield_t<_Reference_t<_Ref, _Val>>;

    template<typename> constexpr bool __is_generator = false;
    template<typename _Val, typename _Ref, typename _Alloc>
    constexpr bool __is_generator<std::generator<_Val, _Ref, _Alloc>> = true;

    /// Allocator and value type erased generator promise type.
    /// \tparam _Yielded The corresponding generators yielded type.
    template<typename _Yielded>
      class _Promise_erased
      {
	static_assert(is_reference_v<_Yielded>);
	using _Yielded_deref = remove_reference_t<_Yielded>;
	using _Yielded_decvref = remove_cvref_t<_Yielded>;
	using _ValuePtr = add_pointer_t<_Yielded>;
	using _Coro_handle = std::coroutine_handle<_Promise_erased>;

	template<typename, typename, typename>
	friend class std::generator;

	template<typename _Gen>
	  struct _Recursive_awaiter;
	template<typename>
	friend struct _Recursive_awaiter;
	struct _Copy_awaiter;
	struct _Subyield_state;
	struct _Final_awaiter;
      public:
	suspend_always
	initial_suspend() const noexcept
	{ return {}; }

	suspend_always
	yield_value(_Yielded __val) noexcept
	{
	  _M_bottom_value() = ::std::addressof(__val);
	  return {};
	}

	auto
	yield_value(const _Yielded_deref& __val)
	  noexcept (is_nothrow_constructible_v<_Yielded_decvref,
		    const _Yielded_deref&>)
	  requires (is_rvalue_reference_v<_Yielded>
		    && constructible_from<_Yielded_decvref,
		    const _Yielded_deref&>)
	{ return _Copy_awaiter(_Yielded_decvref(__val), _M_bottom_value()); }

	template<typename _R2, typename _V2, typename _A2, typename _U2>
	requires std::same_as<_Yield2_t<_R2, _V2>, _Yielded>
	auto
	yield_value(ranges::elements_of<generator<_R2, _V2, _A2>&&, _U2> __r)
	  noexcept
	{ return _Recursive_awaiter { std::move(__r.range) }; }

	template<ranges::input_range _R, typename _Alloc>
	requires convertible_to<ranges::range_reference_t<_R>, _Yielded>
	auto
	yield_value(ranges::elements_of<_R, _Alloc> __r)
	{
	  auto __n = [] (allocator_arg_t, _Alloc,
			 ranges::iterator_t<_R> __i,
			 ranges::sentinel_t<_R> __s)
	    -> generator<_Yielded, ranges::range_value_t<_R>, _Alloc> {
	    for (; __i != __s; ++__i)
	      co_yield static_cast<_Yielded>(*__i);
	  };
	  return yield_value(ranges::elements_of(__n(allocator_arg,
						     __r.allocator,
						     ranges::begin(__r.range),
						     ranges::end(__r.range))));
	}


	_Final_awaiter
	final_suspend() noexcept
	{ return {}; }

	void
	unhandled_exception()
	{
	  // To get to this point, this coroutine must have been active.  In that
	  // case, it must be the top of the stack.  The current coroutine is
	  // the sole entry of the stack iff it is both the top and the bottom.  As
	  // it is the top implicitly in this context it will be the sole entry iff
	  // it is the bottom.
	  if (_M_nest._M_is_bottom())
	    throw;
	  else
	    this->_M_except = std::current_exception();
	}

	void await_transform() = delete;
	void return_void() const noexcept {}

      private:
	_ValuePtr&
	_M_bottom_value() noexcept
	{ return _M_nest._M_bottom_value(*this); }

	_ValuePtr&
	_M_value() noexcept
	{ return _M_nest._M_value(*this); }

	_Subyield_state _M_nest;
	std::exception_ptr _M_except;
      };

    template<typename _Yielded>
      struct _Promise_erased<_Yielded>::_Subyield_state
      {
	struct _Frame
	{
	  _Coro_handle _M_bottom;
	  _Coro_handle _M_parent;
	};

	struct _Bottom_frame
	{
	  _Coro_handle _M_top;
	  _ValuePtr _M_value = nullptr;
	};

	std::variant<
	  _Bottom_frame,
	  _Frame
	  > _M_stack;

	bool
	_M_is_bottom() const noexcept
	{ return !std::holds_alternative<_Frame>(this->_M_stack); }

	_Coro_handle&
	_M_top() noexcept
	{
	  if (auto __f = std::get_if<_Frame>(&this->_M_stack))
	    return __f->_M_bottom.promise()._M_nest._M_top();

	  auto __bf = std::get_if<_Bottom_frame>(&this->_M_stack);
	  __glibcxx_assert(__bf);
	  return __bf->_M_top;
	}

	void
	_M_push(_Coro_handle __current, _Coro_handle __subyield) noexcept
	{
	  __glibcxx_assert(&__current.promise()._M_nest == this);
	  __glibcxx_assert(this->_M_top() == __current);

	  __subyield.promise()._M_nest._M_jump_in(__current, __subyield);
	}

	std::coroutine_handle<>
	_M_pop() noexcept
	{
	  if (auto __f = std::get_if<_Frame>(&this->_M_stack))
	    {
	      // We aren't a bottom coroutine.  Restore the parent to the top
	      // and resume.
	      auto __p = this->_M_top() = __f->_M_parent;
	      return __p;
	    }
	  else
	    // Otherwise, there's nothing to resume.
	    return std::noop_coroutine();
	}

	void
	_M_jump_in(_Coro_handle __rest, _Coro_handle __new) noexcept
	{
	  __glibcxx_assert(&__new.promise()._M_nest == this);
	  __glibcxx_assert(this->_M_is_bottom());
	  // We're bottom.  We're also top if top is unset (note that this is
	  // not true if something was added to the coro stack and then popped,
	  // but in that case we can't possibly be yielded from, as it would
	  // require rerunning begin()).
	  __glibcxx_assert(!this->_M_top());

	  auto& __rn = __rest.promise()._M_nest;
	  __rn._M_top() = __new;

	  // Presume we're the second frame...
	  auto __bott = __rest;
	  if (auto __f = std::get_if<_Frame>(&__rn._M_stack))
	    // But, if we aren't, get the actual bottom.  We're only the second
	    // frame if our parent is the bottom frame, i.e. it doesn't have a
	    // _Frame member.
	    __bott = __f->_M_bottom;

	  this->_M_stack = _Frame {
	    ._M_bottom = __bott,
	    ._M_parent = __rest
	  };
	}

	_ValuePtr&
	_M_bottom_value(_Promise_erased& __current) noexcept
	{
	  __glibcxx_assert(&__current._M_nest == this);
	  if (auto __bf = std::get_if<_Bottom_frame>(&this->_M_stack))
	    return __bf->_M_value;
	  auto __f = std::get_if<_Frame>(&this->_M_stack);
	  __glibcxx_assert(__f);
	  auto& __p = __f->_M_bottom.promise();
	  return __p._M_nest._M_value(__p);
	}

	_ValuePtr&
	_M_value(_Promise_erased& __current) noexcept
	{
	  __glibcxx_assert(&__current._M_nest == this);
	  auto __bf = std::get_if<_Bottom_frame>(&this->_M_stack);
	  __glibcxx_assert(__bf);
	  return __bf->_M_value;
	}
      };

    template<typename _Yielded>
      struct _Promise_erased<_Yielded>::_Final_awaiter
      {
	bool await_ready() noexcept
	{ return false; }

	template<typename _Promise>
	auto await_suspend(std::coroutine_handle<_Promise> __c) noexcept
	{
#ifdef __glibcxx_is_pointer_interconvertible
	  static_assert(is_pointer_interconvertible_base_of_v<
			_Promise_erased, _Promise>);
#endif

	  auto& __n = __c.promise()._M_nest;
	  return __n._M_pop();
	}

	void await_resume() noexcept {}
      };

    template<typename _Yielded>
      struct _Promise_erased<_Yielded>::_Copy_awaiter
      {
	_Yielded_decvref _M_value;
	_ValuePtr& _M_bottom_value;

	constexpr bool await_ready() noexcept
	{ return false; }

	template<typename _Promise>
	void await_suspend(std::coroutine_handle<_Promise>) noexcept
	{
#ifdef __glibcxx_is_pointer_interconvertible
	  static_assert(is_pointer_interconvertible_base_of_v<
			_Promise_erased, _Promise>);
#endif
	  _M_bottom_value = ::std::addressof(_M_value);
	}

	constexpr void
	await_resume() const noexcept
	{}
      };

    template<typename _Yielded>
    template<typename _Gen>
      struct _Promise_erased<_Yielded>::_Recursive_awaiter
      {
	_Gen _M_gen;
	static_assert(__is_generator<_Gen>);
	static_assert(std::same_as<typename _Gen::yielded, _Yielded>);

	_Recursive_awaiter(_Gen __gen) noexcept
	  : _M_gen(std::move(__gen))
	{ this->_M_gen._M_mark_as_started(); }

	constexpr bool
	await_ready() const noexcept
	{ return false; }


	template<typename _Promise>
	std::coroutine_handle<>
	await_suspend(std::coroutine_handle<_Promise> __p) noexcept
	{
#ifdef __glibcxx_is_pointer_interconvertible
	  static_assert(is_pointer_interconvertible_base_of_v<
			_Promise_erased, _Promise>);
#endif

	  auto __c = _Coro_handle::from_address(__p.address());
	  auto __t = _Coro_handle::from_address(this->_M_gen._M_coro.address());
	  __p.promise()._M_nest._M_push(__c, __t);
	  return __t;
	}

	void await_resume()
	{
	  if (auto __e = _M_gen._M_coro.promise()._M_except)
	    std::rethrow_exception(__e);
	}
      };

    struct _Alloc_block
    {
      alignas(__STDCPP_DEFAULT_NEW_ALIGNMENT__)
      char _M_data[__STDCPP_DEFAULT_NEW_ALIGNMENT__];

      static auto
      _M_cnt(std::size_t __sz) noexcept
      {
	auto __blksz = sizeof(_Alloc_block);
	return (__sz + __blksz - 1) / __blksz;
      }
    };

    template<typename _All>
    concept _Stateless_alloc = (allocator_traits<_All>::is_always_equal::value
				&& default_initializable<_All>);

    template<typename _Allocator>
      class _Promise_alloc
      {
	using _Rebound = __alloc_rebind<_Allocator, _Alloc_block>;
	using _Rebound_ATr = allocator_traits<_Rebound>;
	static_assert(is_pointer_v<typename _Rebound_ATr::pointer>,
		      "Must use allocators for true pointers with generators");

	static auto
	_M_alloc_address(std::uintptr_t __fn, std::uintptr_t __fsz) noexcept
	{
	  auto __an = __fn + __fsz;
	  auto __ba = alignof(_Rebound);
	  return reinterpret_cast<_Rebound*>(((__an + __ba - 1) / __ba) * __ba);
	}

	static auto
	_M_alloc_size(std::size_t __csz) noexcept
	{
	  auto __ba = alignof(_Rebound);
	  // Our desired layout is placing the coroutine frame, then pad out to
	  // align, then place the allocator.  The total size of that is the
	  // size of the coroutine frame, plus up to __ba bytes, plus the size
	  // of the allocator.
	  return __csz + __ba + sizeof(_Rebound);
	}

	static void*
	_M_allocate(_Rebound __b, std::size_t __csz)
	{
	  if constexpr (_Stateless_alloc<_Rebound>)
	    // Only need room for the coroutine.
	    return __b.allocate(_Alloc_block::_M_cnt(__csz));
	  else
	    {
	      auto __nsz = _Alloc_block::_M_cnt(_M_alloc_size(__csz));
	      auto __f = __b.allocate(__nsz);
	      auto __fn = reinterpret_cast<std::uintptr_t>(__f);
	      auto __an = _M_alloc_address(__fn, __csz);
	      ::new (__an) _Rebound(std::move(__b));
	      return __f;
	    }
	}

      public:
	void*
	operator new(std::size_t __sz)
	  requires default_initializable<_Rebound> // _Allocator is non-void
	{ return _M_allocate({}, __sz); }

	// _GLIBCXX_RESOLVE_LIB_DEFECTS
	// 3900. The allocator_arg_t overloads of promise_type::operator new
	// should not be constrained
	template<typename _Alloc, typename... _Args>
	void*
	operator new(std::size_t __sz,
		     allocator_arg_t, const _Alloc& __a,
		     const _Args&...)
	{
	  static_assert(convertible_to<const _Alloc&, _Allocator>,
			"the allocator argument to the coroutine must be "
			"convertible to the generator's allocator type");
	  return _M_allocate(_Rebound(_Allocator(__a)), __sz);
	}

	template<typename _This, typename _Alloc, typename... _Args>
	void*
	operator new(std::size_t __sz,
		     const _This&,
		     allocator_arg_t, const _Alloc& __a,
		     const _Args&...)
	{
	  static_assert(convertible_to<const _Alloc&, _Allocator>,
			"the allocator argument to the coroutine must be "
			"convertible to the generator's allocator type");
	  return _M_allocate(_Rebound(_Allocator(__a)), __sz);
	}

	void
	operator delete(void* __ptr, std::size_t __csz) noexcept
	{
	  if constexpr (_Stateless_alloc<_Rebound>)
	    {
	      _Rebound __b;
	      return __b.deallocate(reinterpret_cast<_Alloc_block*>(__ptr),
				    _Alloc_block::_M_cnt(__csz));
	    }
	  else
	    {
	      auto __nsz = _Alloc_block::_M_cnt(_M_alloc_size(__csz));
	      auto __fn = reinterpret_cast<std::uintptr_t>(__ptr);
	      auto __an = _M_alloc_address(__fn, __csz);
	      _Rebound __b(std::move(*__an));
	      __an->~_Rebound();
	      __b.deallocate(reinterpret_cast<_Alloc_block*>(__ptr), __nsz);
	    }
	}
      };

    template<>
      class _Promise_alloc<void>
      {
	using _Dealloc_fn = void (*)(void*, std::size_t);

	static auto
	_M_dealloc_address(std::uintptr_t __fn, std::uintptr_t __fsz) noexcept
	{
	  auto __an = __fn + __fsz;
	  auto __ba = alignof(_Dealloc_fn);
	  auto __aligned = ((__an + __ba - 1) / __ba) * __ba;
	  return reinterpret_cast<_Dealloc_fn*>(__aligned);
	}

	template<typename _Rebound>
	static auto
	_M_alloc_address(std::uintptr_t __fn, std::uintptr_t __fsz) noexcept
	  requires (!_Stateless_alloc<_Rebound>)
	{
	  auto __ba = alignof(_Rebound);
	  auto __da = _M_dealloc_address(__fn, __fsz);
	  auto __aan = reinterpret_cast<std::uintptr_t>(__da);
	  __aan += sizeof(_Dealloc_fn);
	  auto __aligned = ((__aan + __ba - 1) / __ba) * __ba;
	  return reinterpret_cast<_Rebound*>(__aligned);
	}

	template<typename _Rebound>
	static auto
	_M_alloc_size(std::size_t __csz) noexcept
	{
	  // This time, we want the coroutine frame, then the deallocator
	  // pointer, then the allocator itself, if any.
	  std::size_t __aa = 0;
	  std::size_t __as = 0;
	  if constexpr (!std::same_as<_Rebound, void>)
	    {
	      __aa = alignof(_Rebound);
	      __as = sizeof(_Rebound);
	    }
	  auto __ba = __aa + alignof(_Dealloc_fn);
	  return __csz + __ba + __as + sizeof(_Dealloc_fn);
	}

	template<typename _Rebound>
	static void
	_M_deallocator(void* __ptr, std::size_t __csz) noexcept
	{
	  auto __asz = _M_alloc_size<_Rebound>(__csz);
	  auto __nblk = _Alloc_block::_M_cnt(__asz);

	  if constexpr (_Stateless_alloc<_Rebound>)
	    {
	      _Rebound __b;
	      __b.deallocate(reinterpret_cast<_Alloc_block*>(__ptr), __nblk);
	    }
	  else
	    {
	      auto __fn = reinterpret_cast<std::uintptr_t>(__ptr);
	      auto __an = _M_alloc_address<_Rebound>(__fn, __csz);
	      _Rebound __b(std::move(*__an));
	      __an->~_Rebound();
	      __b.deallocate(reinterpret_cast<_Alloc_block*>(__ptr), __nblk);
	    }
	}

	template<typename _Alloc>
	static void*
	_M_allocate(const _Alloc& __a, std::size_t __csz)
	{
	  using _Rebound = __alloc_rebind<_Alloc, _Alloc_block>;
	  using _Rebound_ATr = allocator_traits<_Rebound>;

	  static_assert(is_pointer_v<typename _Rebound_ATr::pointer>,
			"Must use allocators for true pointers with generators");

	  _Dealloc_fn __d = &_M_deallocator<_Rebound>;
	  auto __b = static_cast<_Rebound>(__a);
	  auto __asz = _M_alloc_size<_Rebound>(__csz);
	  auto __nblk = _Alloc_block::_M_cnt(__asz);
	  void* __p = __b.allocate(__nblk);
	  auto __pn = reinterpret_cast<std::uintptr_t>(__p);
	  *_M_dealloc_address(__pn, __csz) = __d;
	  if constexpr (!_Stateless_alloc<_Rebound>)
	    {
	      auto __an = _M_alloc_address<_Rebound>(__pn, __csz);
	      ::new (__an) _Rebound(std::move(__b));
	    }
	  return __p;
	}
      public:
	void*
	operator new(std::size_t __sz)
	{
	  auto __nsz = _M_alloc_size<void>(__sz);
	  _Dealloc_fn __d = [] (void* __ptr, std::size_t __sz)
	  {
	    ::operator delete(__ptr, _M_alloc_size<void>(__sz));
	  };
	  auto __p = ::operator new(__nsz);
	  auto __pn = reinterpret_cast<uintptr_t>(__p);
	  *_M_dealloc_address(__pn, __sz) = __d;
	  return __p;
	}

	template<typename _Alloc, typename... _Args>
	void*
	operator new(std::size_t __sz,
		     allocator_arg_t, const _Alloc& __a,
		     const _Args&...)
	{ return _M_allocate(__a, __sz); }

	template<typename _This, typename _Alloc, typename... _Args>
	void*
	operator new(std::size_t __sz,
		     const _This&,
		     allocator_arg_t, const _Alloc& __a,
		     const _Args&...)
	{ return _M_allocate(__a, __sz); }

	void
	operator delete(void* __ptr, std::size_t __sz) noexcept
	{
	  _Dealloc_fn __d;
	  auto __pn = reinterpret_cast<uintptr_t>(__ptr);
	  __d = *_M_dealloc_address(__pn, __sz);
	  __d(__ptr, __sz);
	}
      };

    template<typename _Tp>
    concept _Cv_unqualified_object = is_object_v<_Tp>
      && same_as<_Tp, remove_cv_t<_Tp>>;
  } // namespace __gen
  /// @endcond

  template<typename _Ref, typename _Val, typename _Alloc>
    class generator
      : public ranges::view_interface<generator<_Ref, _Val, _Alloc>>
    {
      using _Value = __conditional_t<is_void_v<_Val>,
				     remove_cvref_t<_Ref>,
				     _Val>;
      static_assert(__gen::_Cv_unqualified_object<_Value>,
		    "Generator value must be a cv-unqualified object type");
      using _Reference = __gen::_Reference_t<_Ref, _Val>;
      static_assert(is_reference_v<_Reference>
		    || (__gen::_Cv_unqualified_object<_Reference>
			&& copy_constructible<_Reference>),
		    "Generator reference type must be either a cv-unqualified "
		    "object type that is trivially constructible or a "
		    "reference type");

      using _RRef = __conditional_t<
	is_reference_v<_Reference>,
	remove_reference_t<_Reference>&&,
	_Reference>;

      /* Required to model indirectly_readable, and input_iterator.  */
      static_assert(common_reference_with<_Reference&&, _Value&&>);
      static_assert(common_reference_with<_Reference&&, _RRef&&>);
      static_assert(common_reference_with<_RRef&&, const _Value&>);

      using _Yielded = __gen::_Yield_t<_Reference>;
      using _Erased_promise = __gen::_Promise_erased<_Yielded>;

      struct _Iterator;

      friend _Erased_promise;
      friend struct _Erased_promise::_Subyield_state;
    public:
      using yielded = _Yielded;

      struct promise_type : _Erased_promise, __gen::_Promise_alloc<_Alloc>
      {
	generator get_return_object() noexcept
	{ return { coroutine_handle<promise_type>::from_promise(*this) }; }
      };

#ifdef __glibcxx_is_pointer_interconvertible
      static_assert(is_pointer_interconvertible_base_of_v<_Erased_promise,
		    promise_type>);
#endif

      generator(const generator&) = delete;

      generator(generator&& __other) noexcept
	: _M_coro(std::__exchange(__other._M_coro, nullptr)),
	  _M_began(std::__exchange(__other._M_began, false))
      {}

      ~generator()
      {
	if (auto& __c = this->_M_coro)
	  __c.destroy();
      }

      generator&
      operator=(generator __other) noexcept
      {
	swap(__other._M_coro, this->_M_coro);
	swap(__other._M_began, this->_M_began);
	return *this;
      }

      _Iterator
      begin()
      {
	this->_M_mark_as_started();
	auto __h = _Coro_handle::from_promise(_M_coro.promise());
	__h.promise()._M_nest._M_top() = __h;
	return { __h };
      }

      default_sentinel_t
      end() const noexcept
      { return default_sentinel; }

    private:
      using _Coro_handle = std::coroutine_handle<_Erased_promise>;

      generator(coroutine_handle<promise_type> __coro) noexcept
	: _M_coro { move(__coro) }
      {}

      void
      _M_mark_as_started() noexcept
      {
	__glibcxx_assert(!this->_M_began);
	this->_M_began = true;
      }

      coroutine_handle<promise_type> _M_coro;
      bool _M_began = false;
    };

  template<class _Ref, class _Val, class _Alloc>
    struct generator<_Ref, _Val, _Alloc>::_Iterator
    {
      using value_type = _Value;
      using difference_type = ptrdiff_t;

      friend bool
      operator==(const _Iterator& __i, default_sentinel_t) noexcept
      { return __i._M_coro.done(); }

      friend class generator;

      _Iterator(_Iterator&& __o) noexcept
	: _M_coro(std::__exchange(__o._M_coro, {}))
      {}

      _Iterator&
      operator=(_Iterator&& __o) noexcept
      {
	this->_M_coro = std::__exchange(__o._M_coro, {});
	return *this;
      }

      _Iterator&
      operator++()
      {
	_M_next();
	return *this;
      }

      void
      operator++(int)
      { this->operator++(); }

      _Reference
      operator*()
	const noexcept(is_nothrow_move_constructible_v<_Reference>)
      {
	auto& __p = this->_M_coro.promise();
	return static_cast<_Reference>(*__p._M_value());
      }

    private:
      friend class generator;

      _Iterator(_Coro_handle __g)
	: _M_coro { __g }
      { this->_M_next(); }

      void _M_next()
      {
	auto& __t = this->_M_coro.promise()._M_nest._M_top();
	__t.resume();
      }

      _Coro_handle _M_coro;
    };

  /// @}

#if _GLIBCXX_HOSTED
  namespace pmr {
    template<typename _Ref, typename _Val = void>
    using generator = std::generator<_Ref, _Val, polymorphic_allocator<std::byte>>;
  }
#endif // HOSTED

_GLIBCXX_END_NAMESPACE_VERSION
} // namespace std
#endif  // __cpp_lib_generator

#endif  // _GLIBCXX_GENERATOR
