[libcxx-commits] [libcxx] [libc++] P2502R2: `std::generator` (PR #201854)

via libcxx-commits libcxx-commits at lists.llvm.org
Fri Jun 5 21:55:45 PDT 2026


llvmorg-github-actions[bot] wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-libcxx

Author: Connector Switch (c8ef)

<details>
<summary>Changes</summary>

- Closes https://github.com/llvm/llvm-project/issues/105226
- Closes https://github.com/llvm/llvm-project/issues/105263
- Closes https://github.com/llvm/llvm-project/issues/105030
- Closes https://github.com/llvm/llvm-project/issues/105274
- Closes https://github.com/llvm/llvm-project/issues/118337
- Closes https://github.com/llvm/llvm-project/issues/118338
- Closes https://github.com/llvm/llvm-project/issues/118351

---

Co-authored-by: Xiaoyang Liu <siujoeng.lau@<!-- -->gmail.com>

---

Patch is 63.45 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/201854.diff


27 Files Affected:

- (modified) libcxx/docs/FeatureTestMacroTable.rst (+2) 
- (modified) libcxx/docs/ReleaseNotes/23.rst (+2) 
- (modified) libcxx/docs/Status/Cxx23Issues.csv (+1-1) 
- (modified) libcxx/docs/Status/Cxx23Papers.csv (+2-2) 
- (modified) libcxx/docs/Status/Cxx2cIssues.csv (+4-4) 
- (modified) libcxx/include/CMakeLists.txt (+1) 
- (added) libcxx/include/generator (+614) 
- (modified) libcxx/include/module.modulemap.in (+5) 
- (modified) libcxx/include/version (+2) 
- (modified) libcxx/modules/std.compat.cppm.in (-3) 
- (modified) libcxx/modules/std.cppm.in (+1-3) 
- (modified) libcxx/modules/std/generator.inc (+6-1) 
- (added) libcxx/test/libcxx/ranges/coro.generator/nodiscard.verify.cpp (+29) 
- (modified) libcxx/test/libcxx/transitive_includes/cxx03.csv (+5) 
- (modified) libcxx/test/libcxx/transitive_includes/cxx11.csv (+5) 
- (modified) libcxx/test/libcxx/transitive_includes/cxx14.csv (+5) 
- (modified) libcxx/test/libcxx/transitive_includes/cxx17.csv (+5) 
- (modified) libcxx/test/libcxx/transitive_includes/cxx23.csv (+9) 
- (modified) libcxx/test/libcxx/transitive_includes/cxx26.csv (+9) 
- (added) libcxx/test/std/language.support/support.limits/support.limits.general/generator.version.compile.pass.cpp (+65) 
- (modified) libcxx/test/std/language.support/support.limits/support.limits.general/version.version.compile.pass.cpp (+30) 
- (added) libcxx/test/std/ranges/coro.generator/allocator.pass.cpp (+123) 
- (added) libcxx/test/std/ranges/coro.generator/generator.compile.pass.cpp (+48) 
- (added) libcxx/test/std/ranges/coro.generator/generator.pass.cpp (+56) 
- (added) libcxx/test/std/ranges/coro.generator/recursive.pass.cpp (+97) 
- (modified) libcxx/utils/generate_feature_test_macro_components.py (+7) 
- (modified) libcxx/utils/libcxx/header_information.py (-1) 


``````````diff
diff --git a/libcxx/docs/FeatureTestMacroTable.rst b/libcxx/docs/FeatureTestMacroTable.rst
index 1b748e37293df..46d83644ff10f 100644
--- a/libcxx/docs/FeatureTestMacroTable.rst
+++ b/libcxx/docs/FeatureTestMacroTable.rst
@@ -344,6 +344,8 @@ Status
     ---------------------------------------------------------- -----------------
     ``__cpp_lib_forward_like``                                 ``202207L``
     ---------------------------------------------------------- -----------------
+    ``__cpp_lib_generator``                                    ``202207L``
+    ---------------------------------------------------------- -----------------
     ``__cpp_lib_invoke_r``                                     ``202106L``
     ---------------------------------------------------------- -----------------
     ``__cpp_lib_ios_noreplace``                                ``202207L``
diff --git a/libcxx/docs/ReleaseNotes/23.rst b/libcxx/docs/ReleaseNotes/23.rst
index 03dabc54dcf79..a53fad86004a6 100644
--- a/libcxx/docs/ReleaseNotes/23.rst
+++ b/libcxx/docs/ReleaseNotes/23.rst
@@ -51,6 +51,8 @@ Implemented Papers
 - P2542R8: ``views::concat`` (`Github <https://llvm.org/PR105419>`__)
 - P3383R3: ``mdspan.at()`` (`Github <https://llvm.org/PR175213>`__)
 - P3508R0: Wording for "constexpr for specialized memory algorithms" (`Github <https://llvm.org/PR118379>`__)
+- P2502R2: ``std::generator``: Synchronous Coroutine Generator for Ranges (`Github <https://llvm.org/PR105226>`__)
+- P2787R1: ``pmr::generator`` - Promise Types are not Values (`Github <https://llvm.org/PR105263>`__)
 
 Improvements and New Features
 -----------------------------
diff --git a/libcxx/docs/Status/Cxx23Issues.csv b/libcxx/docs/Status/Cxx23Issues.csv
index 0a2f0d59484de..b61edbd0a2975 100644
--- a/libcxx/docs/Status/Cxx23Issues.csv
+++ b/libcxx/docs/Status/Cxx23Issues.csv
@@ -217,7 +217,7 @@
 "`LWG3759 <https://wg21.link/LWG3759>`__","``ranges::rotate_copy`` should use ``std::move``","2022-11 (Kona)","|Complete|","15","`#105027 <https://github.com/llvm/llvm-project/issues/105027>`__",""
 "`LWG3760 <https://wg21.link/LWG3760>`__","``cartesian_product_view::iterator``'s ``parent_`` is never valid","2022-11 (Kona)","","","`#105028 <https://github.com/llvm/llvm-project/issues/105028>`__",""
 "`LWG3761 <https://wg21.link/LWG3761>`__","``cartesian_product_view::iterator::operator-`` should pass by reference","2022-11 (Kona)","","","`#105029 <https://github.com/llvm/llvm-project/issues/105029>`__",""
-"`LWG3762 <https://wg21.link/LWG3762>`__","``generator::iterator::operator==`` should pass by reference","2022-11 (Kona)","","","`#105030 <https://github.com/llvm/llvm-project/issues/105030>`__",""
+"`LWG3762 <https://wg21.link/LWG3762>`__","``generator::iterator::operator==`` should pass by reference","2022-11 (Kona)","|Complete|","23","`#105030 <https://github.com/llvm/llvm-project/issues/105030>`__",""
 "`LWG3764 <https://wg21.link/LWG3764>`__","``reference_wrapper::operator()`` should propagate noexcept","2022-11 (Kona)","|Complete|","17","`#105031 <https://github.com/llvm/llvm-project/issues/105031>`__",""
 "`LWG3765 <https://wg21.link/LWG3765>`__","``const_sentinel`` should be constrained","2022-11 (Kona)","","","`#105032 <https://github.com/llvm/llvm-project/issues/105032>`__",""
 "`LWG3766 <https://wg21.link/LWG3766>`__","``view_interface::cbegin`` is underconstrained","2022-11 (Kona)","","","`#105033 <https://github.com/llvm/llvm-project/issues/105033>`__",""
diff --git a/libcxx/docs/Status/Cxx23Papers.csv b/libcxx/docs/Status/Cxx23Papers.csv
index eb580ea891f5b..862461f900dbd 100644
--- a/libcxx/docs/Status/Cxx23Papers.csv
+++ b/libcxx/docs/Status/Cxx23Papers.csv
@@ -80,7 +80,7 @@
 "`P2474R2 <https://wg21.link/P2474R2>`__","``views::repeat``","2022-07 (Virtual)","|Complete|","17","`#105222 <https://github.com/llvm/llvm-project/issues/105222>`__",""
 "`P2494R2 <https://wg21.link/P2494R2>`__","Relaxing range adaptors to allow for move only types","2022-07 (Virtual)","|Complete|","17","`#105224 <https://github.com/llvm/llvm-project/issues/105224>`__",""
 "`P2499R0 <https://wg21.link/P2499R0>`__","``string_view`` range constructor should be ``explicit``","2022-07 (Virtual)","|Complete|","16","`#105225 <https://github.com/llvm/llvm-project/issues/105225>`__",""
-"`P2502R2 <https://wg21.link/P2502R2>`__","``std::generator``: Synchronous Coroutine Generator for Ranges","2022-07 (Virtual)","","","`#105226 <https://github.com/llvm/llvm-project/issues/105226>`__",""
+"`P2502R2 <https://wg21.link/P2502R2>`__","``std::generator``: Synchronous Coroutine Generator for Ranges","2022-07 (Virtual)","|Complete|","23","`#105226 <https://github.com/llvm/llvm-project/issues/105226>`__",""
 "`P2508R1 <https://wg21.link/P2508R1>`__","Exposing ``std::basic-format-string``","2022-07 (Virtual)","|Complete|","15","`#105227 <https://github.com/llvm/llvm-project/issues/105227>`__",""
 "`P2517R1 <https://wg21.link/P2517R1>`__","Add a conditional ``noexcept`` specification to ``std::apply``","2022-07 (Virtual)","|Complete|","3.9","`#105229 <https://github.com/llvm/llvm-project/issues/105229>`__",""
 "`P2520R0 <https://wg21.link/P2520R0>`__","``move_iterator`` should be a random access iterator","2022-07 (Virtual)","|Complete|","17","`#105230 <https://github.com/llvm/llvm-project/issues/105230>`__","Implemented as a DR in C++20"
@@ -115,7 +115,7 @@
 "`P2674R1 <https://wg21.link/P2674R1>`__","A trait for implicit lifetime types","2023-02 (Issaquah)","|Complete|","20","`#105259 <https://github.com/llvm/llvm-project/issues/105259>`__",""
 "`P2655R3 <https://wg21.link/P2655R3>`__","``common_reference_t`` of ``reference_wrapper`` Should Be a Reference Type","2023-02 (Issaquah)","|Complete|","21","`#105260 <https://github.com/llvm/llvm-project/issues/105260>`__","The paper is implemented as a DR to C++20"
 "`P2652R2 <https://wg21.link/P2652R2>`__","Disallow User Specialization of ``allocator_traits``","2023-02 (Issaquah)","|Complete|","19","`#105262 <https://github.com/llvm/llvm-project/issues/105262>`__",""
-"`P2787R1 <https://wg21.link/P2787R1>`__","``pmr::generator`` - Promise Types are not Values","2023-02 (Issaquah)","","","`#105263 <https://github.com/llvm/llvm-project/issues/105263>`__",""
+"`P2787R1 <https://wg21.link/P2787R1>`__","``pmr::generator`` - Promise Types are not Values","2023-02 (Issaquah)","|Complete|","23","`#105263 <https://github.com/llvm/llvm-project/issues/105263>`__",""
 "`P2614R2 <https://wg21.link/P2614R2>`__","Deprecate ``numeric_limits::has_denorm``","2023-02 (Issaquah)","|Complete|","18","`#105264 <https://github.com/llvm/llvm-project/issues/105264>`__",""
 "`P2588R3 <https://wg21.link/P2588R3>`__","``barrier``’s phase completion guarantees","2023-02 (Issaquah)","","","`#105265 <https://github.com/llvm/llvm-project/issues/105265>`__",""
 "`P2763R1 <https://wg21.link/P2763R1>`__","``layout_stride`` static extents default constructor fix","2023-02 (Issaquah)","","","`#105266 <https://github.com/llvm/llvm-project/issues/105266>`__",""
diff --git a/libcxx/docs/Status/Cxx2cIssues.csv b/libcxx/docs/Status/Cxx2cIssues.csv
index 6a836c0491bb6..3ec8ae821ed5d 100644
--- a/libcxx/docs/Status/Cxx2cIssues.csv
+++ b/libcxx/docs/Status/Cxx2cIssues.csv
@@ -4,7 +4,7 @@
 "`LWG3885 <https://wg21.link/LWG3885>`__","``op`` should be in [zombie.names]","2023-06 (Varna)","|Nothing To Do|","","`#105270 <https://github.com/llvm/llvm-project/issues/105270>`__",""
 "`LWG3887 <https://wg21.link/LWG3887>`__","Version macro for ``allocate_at_least``","2023-06 (Varna)","|Complete|","19","`#105271 <https://github.com/llvm/llvm-project/issues/105271>`__",""
 "`LWG3893 <https://wg21.link/LWG3893>`__","LWG 3661 broke ``atomic<shared_ptr<T>> a; a = nullptr;``","2023-06 (Varna)","","","`#105273 <https://github.com/llvm/llvm-project/issues/105273>`__",""
-"`LWG3894 <https://wg21.link/LWG3894>`__","``generator::promise_type::yield_value(ranges::elements_of<Rng, Alloc>)`` should not be ``noexcept``","2023-06 (Varna)","","","`#105274 <https://github.com/llvm/llvm-project/issues/105274>`__",""
+"`LWG3894 <https://wg21.link/LWG3894>`__","``generator::promise_type::yield_value(ranges::elements_of<Rng, Alloc>)`` should not be ``noexcept``","2023-06 (Varna)","|Complete|","23","`#105274 <https://github.com/llvm/llvm-project/issues/105274>`__",""
 "`LWG3903 <https://wg21.link/LWG3903>`__","span destructor is redundantly noexcept","2023-06 (Varna)","|Complete|","7","`#105275 <https://github.com/llvm/llvm-project/issues/105275>`__",""
 "`LWG3904 <https://wg21.link/LWG3904>`__","``lazy_split_view::outer-iterator``'s const-converting constructor isn't setting ``trailing_empty_``","2023-06 (Varna)","","","`#105276 <https://github.com/llvm/llvm-project/issues/105276>`__",""
 "`LWG3905 <https://wg21.link/LWG3905>`__","Type of ``std::fexcept_t``","2023-06 (Varna)","|Complete|","3.4","`#105277 <https://github.com/llvm/llvm-project/issues/105277>`__",""
@@ -79,8 +79,8 @@
 "`LWG3216 <https://wg21.link/LWG3216>`__","Rebinding the allocator before calling ``construct``/``destroy`` in ``allocate_shared``","2024-11 (Wrocław)","","","`#118332 <https://github.com/llvm/llvm-project/issues/118332>`__",""
 "`LWG3436 <https://wg21.link/LWG3436>`__","``std::construct_at`` should support arrays","2024-11 (Wrocław)","","","`#118335 <https://github.com/llvm/llvm-project/issues/118335>`__",""
 "`LWG3886 <https://wg21.link/LWG3886>`__","Monad mo' problems","2024-11 (Wrocław)","|Complete|","22","`#118336 <https://github.com/llvm/llvm-project/issues/118336>`__",""
-"`LWG3899 <https://wg21.link/LWG3899>`__","``co_yield``\ing elements of an lvalue generator is unnecessarily inefficient","2024-11 (Wrocław)","","","`#118337 <https://github.com/llvm/llvm-project/issues/118337>`__",""
-"`LWG3900 <https://wg21.link/LWG3900>`__","The ``allocator_arg_t`` overloads of ``generator::promise_type::operator new`` should not be constrained","2024-11 (Wrocław)","","","`#118338 <https://github.com/llvm/llvm-project/issues/118338>`__",""
+"`LWG3899 <https://wg21.link/LWG3899>`__","``co_yield``\ing elements of an lvalue generator is unnecessarily inefficient","2024-11 (Wrocław)","|Complete|","23","`#118337 <https://github.com/llvm/llvm-project/issues/118337>`__",""
+"`LWG3900 <https://wg21.link/LWG3900>`__","The ``allocator_arg_t`` overloads of ``generator::promise_type::operator new`` should not be constrained","2024-11 (Wrocław)","|Complete|","23","`#118338 <https://github.com/llvm/llvm-project/issues/118338>`__",""
 "`LWG3918 <https://wg21.link/LWG3918>`__","``std::uninitialized_move/_n`` and guaranteed copy elision","2024-11 (Wrocław)","","","`#118339 <https://github.com/llvm/llvm-project/issues/118339>`__",""
 "`LWG4014 <https://wg21.link/LWG4014>`__","LWG 3809 changes behavior of some existing ``std::subtract_with_carry_engine code``","2024-11 (Wrocław)","","","`#118340 <https://github.com/llvm/llvm-project/issues/118340>`__",""
 "`LWG4024 <https://wg21.link/LWG4024>`__","Underspecified destruction of objects created in ``std::make_shared_for_overwrite``/``std::allocate_shared_for_overwrite``","2024-11 (Wrocław)","|Complete|","16","`#118341 <https://github.com/llvm/llvm-project/issues/118341>`__",""
@@ -93,7 +93,7 @@
 "`LWG4088 <https://wg21.link/LWG4088>`__","``println`` ignores the locale imbued in ``std::ostream``","2024-11 (Wrocław)","|Complete|","18","`#118348 <https://github.com/llvm/llvm-project/issues/118348>`__",""
 "`LWG4112 <https://wg21.link/LWG4112>`__","``has-arrow`` should required ``operator->()`` to be ``const``-qualified","2024-11 (Wrocław)","","","`#118349 <https://github.com/llvm/llvm-project/issues/118349>`__",""
 "`LWG4113 <https://wg21.link/LWG4113>`__","Disallow ``has_unique_object_representations<Incomplete[]>``","2024-11 (Wrocław)","|Complete|","","`#118350 <https://github.com/llvm/llvm-project/issues/118350>`__",""
-"`LWG4119 <https://wg21.link/LWG4119>`__","``generator::promise_type::yield_value(ranges::elements_of<R, Alloc>)``'s nested ``generator`` may be ill-formed","2024-11 (Wrocław)","","","`#118351 <https://github.com/llvm/llvm-project/issues/118351>`__",""
+"`LWG4119 <https://wg21.link/LWG4119>`__","``generator::promise_type::yield_value(ranges::elements_of<R, Alloc>)``'s nested ``generator`` may be ill-formed","2024-11 (Wrocław)","|Complete|","23","`#118351 <https://github.com/llvm/llvm-project/issues/118351>`__",""
 "`LWG4124 <https://wg21.link/LWG4124>`__","Cannot format ``zoned_time`` with resolution coarser than ``seconds``","2024-11 (Wrocław)","","","`#118352 <https://github.com/llvm/llvm-project/issues/118352>`__",""
 "`LWG4126 <https://wg21.link/LWG4126>`__","Some feature-test macros for fully freestanding features are not yet marked freestanding","2024-11 (Wrocław)","","","`#118353 <https://github.com/llvm/llvm-project/issues/118353>`__",""
 "`LWG4134 <https://wg21.link/LWG4134>`__","Issue with Philox algorithm specification","2024-11 (Wrocław)","","","`#118354 <https://github.com/llvm/llvm-project/issues/118354>`__",""
diff --git a/libcxx/include/CMakeLists.txt b/libcxx/include/CMakeLists.txt
index 10dfb4b4d58cb..cd77d51924571 100644
--- a/libcxx/include/CMakeLists.txt
+++ b/libcxx/include/CMakeLists.txt
@@ -1043,6 +1043,7 @@ set(files
   fstream
   functional
   future
+  generator
   initializer_list
   iomanip
   ios
diff --git a/libcxx/include/generator b/libcxx/include/generator
new file mode 100644
index 0000000000000..2176ecbaa1e6e
--- /dev/null
+++ b/libcxx/include/generator
@@ -0,0 +1,614 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP_GENERATOR
+#define _LIBCPP_GENERATOR
+
+/*
+
+namespace std {
+  // [coro.generator.class], class template generator
+  template<class Ref, class Val = void, class Allocator = void>
+    class generator;
+
+  namespace pmr {
+    template<class Ref, class Val = void>
+      using generator = std::generator<Ref, Val, polymorphic_allocator<>>;
+  }
+}
+
+*/
+
+#if __cplusplus < 201103L && defined(_LIBCPP_USE_FROZEN_CXX03_HEADERS)
+#  include <__cxx03/__config>
+#else
+#  include <__config>
+
+#  if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#    pragma GCC system_header
+#  endif
+
+_LIBCPP_PUSH_MACROS
+#  include <__undef_macros>
+
+#  if _LIBCPP_STD_VER >= 23
+
+#    include <__algorithm/max.h>
+#    include <__assert>
+#    include <__concepts/common_reference_with.h>
+#    include <__concepts/constructible.h>
+#    include <__concepts/convertible_to.h>
+#    include <__concepts/same_as.h>
+#    include <__coroutine/coroutine_handle.h>
+#    include <__coroutine/coroutine_traits.h>
+#    include <__coroutine/noop_coroutine_handle.h>
+#    include <__coroutine/trivial_awaitables.h>
+#    include <__exception/exception_ptr.h>
+#    include <__iterator/default_sentinel.h>
+#    include <__memory/addressof.h>
+#    include <__memory/allocator_arg_t.h>
+#    include <__memory/allocator_traits.h>
+#    include <__memory/construct_at.h>
+#    include <__memory_resource/polymorphic_allocator.h>
+#    include <__ranges/access.h>
+#    include <__ranges/concepts.h>
+#    include <__ranges/elements_of.h>
+#    include <__ranges/view_interface.h>
+#    include <__type_traits/add_pointer.h>
+#    include <__type_traits/common_reference.h>
+#    include <__type_traits/conditional.h>
+#    include <__type_traits/is_nothrow_constructible.h>
+#    include <__type_traits/is_object.h>
+#    include <__type_traits/is_pointer.h>
+#    include <__type_traits/is_reference.h>
+#    include <__type_traits/is_void.h>
+#    include <__type_traits/remove_cvref.h>
+#    include <__type_traits/remove_reference.h>
+#    include <__utility/exchange.h>
+#    include <__utility/move.h>
+#    include <__utility/swap.h>
+#    include <cstdint>
+#    include <new>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class _Ref, class _Val>
+using __gen_val = conditional_t<is_void_v<_Val>, remove_cvref_t<_Ref>, _Val>;
+
+template <class _Ref, class _Val>
+using __gen_ref = conditional_t<is_void_v<_Val>, _Ref&&, _Ref>;
+
+template <class _Ref, class _Val>
+using __gen_yielded =
+    conditional_t<is_reference_v<__gen_ref<_Ref, _Val>>, __gen_ref<_Ref, _Val>, const __gen_ref<_Ref, _Val>&>;
+
+template <class, class>
+struct __gen_iter_provider {
+  class __iterator;
+};
+
+template <class, class, class>
+class generator;
+
+template <class _Yielded>
+class __gen_promise_base {
+private:
+  template <class, class, class>
+  friend class generator;
+
+  template <class, class>
+  friend struct __gen_iter_provider;
+
+  // Each promise object stores either a `__root_data` when associated with a root generator, or a `__recursive_data`
+  // when associated with a generator that is yielded recursively.
+  struct __root_data {
+    // The client code has access only to the iterator of the root generator. Thus, the root generator must store the
+    // yielded values of recursively-yielded generators, which will then be returned when the client code dereferences
+    // the iterator.
+    add_pointer_t<_Yielded> __value_ptr;
+    // The client code has access only to the iterator of the root generator. Thus, the root generator needs to identify
+    // which generator is currently active. This active generator will then be resumed when the client code increments
+    // the iterator.
+    coroutine_handle<__gen_promise_base> __active;
+  };
+
+  struct __recursive_data {
+    exception_ptr __exception;
+    coroutine_handle<__gen_promise_base> __parent;
+    coroutine_handle<__gen_promise_base> __root;
+  };
+
+  union __union {
+    __root_data __root;
+    __recursive_data __recursive;
+
+    _LIBCPP_HIDE_FROM_ABI ~__union() noexcept {}
+  } __data_;
+
+  // The `__tag_` stores the active member of the `__data_` union:
+  // - `false` indicates that the active member is `__root`.
+  // - `true` indicates that the active member is `__recursive`.
+  // This field can be omitted because `__recursive_data.__root` can store the active member.
+  bool __tag_;
+
+  [[nodiscard]] _LIBCPP_HIDE_FROM_ABI bool __is_root() noexcept { return !__tag_; }
+  [[nodiscard]] _LIBCPP_HIDE_FROM_ABI __root_data& __get_root_data() noexcept {
+    _LIBCPP_ASSERT_INTERNAL(__is_root(), "the active member of `__data_` is not `__root`");
+    return __data_.__root;
+  }
+  _LIBCPP_HIDE_FROM_ABI void __set_root_tag() noexcept { __tag_ = false; }
+
+  [[nodiscard]] _LIBCPP_HIDE_FROM_ABI bool __is_recursive() noexcept { return __tag_; }
+  [[nodiscard]] _LIBCPP_HIDE_FROM_ABI __recursive_data& __get_recursive_data() noexcept {
+    _LIBCPP_ASSERT_INTERNAL(__is_recursive(), "the active member of `__data_` is not `__recursive`");
+    return __data_.__recursive;
+  }
+  _LIBCPP_HIDE_FROM_ABI void __set_recursive_tag() noexcept { __tag_ = true; }
+
+  [[nodiscard]] _LIBCPP_HIDE_FROM_ABI coroutine_handle<__gen_promise_base>& __active() noexcept {
+    _LIBCPP_ASSERT_INTERNAL(__is_root(), "the active member of `__data_` is not `__root`");
+    return __get_root_data().__active;
+  }
+
+  [[nodiscard]] _LIBCPP_HIDE_FROM_ABI add_pointer_t<_Yielded>& __value_ptr() noexcept {
+    _LIBCPP_ASSERT_INTERNAL(__is_root(), "the active member of `__data_` is not `__root`");
+    return __get_root_data().__value_ptr;
+  }
+
+  [[nodiscard]] _LIBCPP_HIDE_FROM_ABI add_pointer_t<_Yielded>& __root_value_ptr() noexcept {
+    if (__is_root()) {
+      return __value_ptr();
+    }
+    return __get_recursive_data().__root.promise().__value_ptr();
+  }
+
+  struct __element_awaiter {
+    [[nodiscard]] _LIBCPP_HIDE_FROM_ABI bool await_ready() noexcept { return false; }
+
+    template <class _Promise>
+    _LIBCPP_HIDE_FROM_ABI void await_suspend(coroutine_handle<_Promise> __current) noexcept {
+      __current.promise().__root_value_ptr() = std::addressof(__value);
+    }
+
+    _LIBCPP_HIDE_FROM_ABI void await_resume() noexcept {}
+
+    remove_cvref_t<_Yielded> __value;
+  };
+
+  struct __final_awaiter {
+    [[nodiscard]] _LIBCPP_HIDE_FROM_ABI bool await_ready() noexcept { return false; }
+
+    template <class _Promise>
+    _LIBCPP_HIDE_FROM_ABI coroutine_handle<> await_suspend(coroutine_handle<_Promise> __current) noexcept {
+      // Checks if the current generator is recursive...
[truncated]

``````````

</details>


https://github.com/llvm/llvm-project/pull/201854


More information about the libcxx-commits mailing list