Skip to content

Commit 652f44f

Browse files
committed
[libc++] implement 'std::generator'
1 parent 176b313 commit 652f44f

File tree

11 files changed

+148
-13
lines changed

11 files changed

+148
-13
lines changed

libcxx/include/generator

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -206,11 +206,10 @@ private:
206206

207207
public:
208208
_LIBCPP_HIDE_FROM_ABI __gen_promise_base() noexcept
209-
: __data_{.__root =
210-
{
211-
.__value_ptr = nullptr,
212-
.__active = coroutine_handle<__gen_promise_base>::from_promise(*this),
213-
}},
209+
: __data_{.__root{
210+
.__value_ptr{nullptr},
211+
.__active{coroutine_handle<__gen_promise_base>::from_promise(*this)},
212+
}},
214213
__tag_{false} {}
215214

216215
_LIBCPP_HIDE_FROM_ABI ~__gen_promise_base() noexcept {
@@ -230,11 +229,12 @@ public:
230229
return {};
231230
}
232231

233-
_LIBCPP_HIDE_FROM_ABI auto yield_value(const remove_reference_t<_Yielded>& __value)
232+
_LIBCPP_HIDE_FROM_ABI auto yield_value(const remove_reference_t<_Yielded>& __value) noexcept(
233+
is_nothrow_constructible_v<remove_cvref_t<_Yielded>, const remove_reference_t<_Yielded>&>)
234234
requires is_rvalue_reference_v<_Yielded> &&
235235
constructible_from<remove_cvref_t<_Yielded>, const remove_reference_t<_Yielded>&>
236236
{
237-
return __element_awaiter{.__value = __value};
237+
return __element_awaiter{.__value{__value}};
238238
}
239239

240240
template <class _Ref2, class _Val2, class _Allocator2, class _Unused>
@@ -304,7 +304,9 @@ public:
304304

305305
_LIBCPP_HIDE_FROM_ABI void operator++(int) { ++*this; }
306306

307-
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI bool operator==(default_sentinel_t) const noexcept { return __coroutine_.done(); }
307+
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI friend bool operator==(const __gen_iter& __iter, default_sentinel_t) noexcept {
308+
return __iter.__coroutine_.done();
309+
}
308310

309311
private:
310312
coroutine_handle<__gen_promise_base<__gen_yielded<_Ref, _Val>>> __coroutine_;
@@ -363,7 +365,7 @@ private:
363365
_LIBCPP_HIDE_FROM_ABI explicit generator(coroutine_handle<promise_type> __coroutine) noexcept
364366
: __coroutine_{__coroutine} {}
365367

366-
coroutine_handle<promise_type> __coroutine_ = nullptr;
368+
coroutine_handle<promise_type> __coroutine_;
367369
};
368370

369371
_LIBCPP_END_NAMESPACE_STD

libcxx/test/libcxx/transitive_includes/cxx03.csv

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -370,6 +370,15 @@ future thread
370370
future type_traits
371371
future typeinfo
372372
future version
373+
generator compare
374+
generator cstddef
375+
generator cstdint
376+
generator cstdlib
377+
generator cstring
378+
generator initializer_list
379+
generator limits
380+
generator new
381+
generator typeinfo
373382
initializer_list cstddef
374383
iomanip istream
375384
iomanip version

libcxx/test/libcxx/transitive_includes/cxx11.csv

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -372,6 +372,15 @@ future thread
372372
future type_traits
373373
future typeinfo
374374
future version
375+
generator compare
376+
generator cstddef
377+
generator cstdint
378+
generator cstdlib
379+
generator cstring
380+
generator initializer_list
381+
generator limits
382+
generator new
383+
generator typeinfo
375384
initializer_list cstddef
376385
iomanip istream
377386
iomanip version

libcxx/test/libcxx/transitive_includes/cxx14.csv

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -375,6 +375,15 @@ future thread
375375
future type_traits
376376
future typeinfo
377377
future version
378+
generator compare
379+
generator cstddef
380+
generator cstdint
381+
generator cstdlib
382+
generator cstring
383+
generator initializer_list
384+
generator limits
385+
generator new
386+
generator typeinfo
378387
initializer_list cstddef
379388
iomanip istream
380389
iomanip version

libcxx/test/libcxx/transitive_includes/cxx17.csv

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -375,6 +375,15 @@ future thread
375375
future type_traits
376376
future typeinfo
377377
future version
378+
generator compare
379+
generator cstddef
380+
generator cstdint
381+
generator cstdlib
382+
generator cstring
383+
generator initializer_list
384+
generator limits
385+
generator new
386+
generator typeinfo
378387
initializer_list cstddef
379388
iomanip istream
380389
iomanip version

libcxx/test/libcxx/transitive_includes/cxx20.csv

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -386,6 +386,15 @@ future thread
386386
future type_traits
387387
future typeinfo
388388
future version
389+
generator compare
390+
generator cstddef
391+
generator cstdint
392+
generator cstdlib
393+
generator cstring
394+
generator initializer_list
395+
generator limits
396+
generator new
397+
generator typeinfo
389398
initializer_list cstddef
390399
iomanip istream
391400
iomanip version

libcxx/test/libcxx/transitive_includes/cxx23.csv

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -259,6 +259,15 @@ future string
259259
future thread
260260
future typeinfo
261261
future version
262+
generator compare
263+
generator cstddef
264+
generator cstdint
265+
generator cstdlib
266+
generator cstring
267+
generator initializer_list
268+
generator limits
269+
generator new
270+
generator typeinfo
262271
initializer_list cstddef
263272
iomanip istream
264273
iomanip version

libcxx/test/libcxx/transitive_includes/cxx26.csv

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -282,6 +282,15 @@ future string
282282
future thread
283283
future typeinfo
284284
future version
285+
generator compare
286+
generator cstddef
287+
generator cstdint
288+
generator cstdlib
289+
generator cstring
290+
generator initializer_list
291+
generator limits
292+
generator new
293+
generator typeinfo
285294
initializer_list cstddef
286295
iomanip istream
287296
iomanip version
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
10+
11+
// <generator>
12+
13+
// template<class Ref, class V = void, class Allocator = void>
14+
// class generator;
15+
16+
#include <generator>
17+
18+
#include <cassert>
19+
#include <concepts>
20+
#include <ranges>
21+
#include <type_traits>
22+
23+
template <class G, class V, class R, class RR>
24+
constexpr bool conformance() {
25+
static_assert(std::ranges::range<G>);
26+
static_assert(std::ranges::view<G>);
27+
static_assert(std::ranges::input_range<G>);
28+
static_assert(!std::ranges::forward_range<G>);
29+
static_assert(!std::ranges::borrowed_range<G>);
30+
31+
static_assert(std::same_as<std::ranges::range_value_t<G>, V>);
32+
static_assert(std::same_as<std::ranges::range_reference_t<G>, R>);
33+
static_assert(std::same_as<std::ranges::range_rvalue_reference_t<G>, RR>);
34+
35+
return true;
36+
}
37+
38+
static_assert(conformance<std::generator<int>, int, int&&, int&&>());
39+
static_assert(conformance<std::generator<int, int>, int, int, int>());
40+
41+
static_assert(conformance<std::generator<int&>, int, int&, int&&>());
42+
static_assert(conformance<std::generator<int&, int>, int, int&, int&&>());
43+
static_assert(conformance<std::generator<const int&>, int, const int&, const int&&>());
44+
static_assert(conformance<std::generator<const int&, int>, int, const int&, const int&&>());
45+
46+
static_assert(conformance<std::generator<int&&>, int, int&&, int&&>());
47+
static_assert(conformance<std::generator<int&&, int>, int, int&&, int&&>());
48+
static_assert(conformance<std::generator<const int&&>, int, const int&&, const int&&>());
49+
static_assert(conformance<std::generator<const int&&, int>, int, const int&&, const int&&>());

libcxx/test/std/ranges/coro.generator/generator.pass.cpp

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,10 @@
88

99
// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
1010

11-
// std::generator
11+
// <generator>
12+
13+
// template<class Ref, class V = void, class Allocator = void>
14+
// class generator;
1215

1316
#include <generator>
1417

@@ -25,11 +28,24 @@ std::generator<int> fib() {
2528
}
2629
}
2730

31+
std::generator<const int&> range_fib() {
32+
co_yield std::ranges::elements_of(std::vector<int>{0, 1});
33+
co_yield std::ranges::elements_of(std::vector<int>{1, 2});
34+
co_yield std::ranges::elements_of(std::vector<int>{3, 5});
35+
co_yield std::ranges::elements_of(std::vector<int>{5, 8});
36+
}
37+
2838
bool test() {
2939
{
3040
std::vector<int> expected_fib_vec = {0, 1, 1, 2, 3};
31-
auto fib_vec = fib() | std::views::take(5) | std::ranges::to<std::vector<int>>();
32-
assert(fib_vec == expected_fib_vec);
41+
{
42+
auto fib_vec = fib() | std::views::take(5) | std::ranges::to<std::vector<int>>();
43+
assert(fib_vec == expected_fib_vec);
44+
}
45+
{
46+
auto fib_vec = range_fib() | std::views::take(5) | std::ranges::to<std::vector<int>>();
47+
assert(fib_vec == expected_fib_vec);
48+
}
3349
}
3450
return true;
3551
}

0 commit comments

Comments
 (0)