Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

P2502R2 <generator>: Synchronous Coroutine Generator For Ranges #4953

Merged
merged 72 commits into from
Sep 19, 2024
Merged
Show file tree
Hide file tree
Changes from 71 commits
Commits
Show all changes
72 commits
Select commit Hold shift + click to select a range
8055612
`generator` WIP (#4342)
CaseyCarter Jan 26, 2024
fb6a4cb
`<generator>`: Mark strengthened noexcept (plus tiny drive-by changes…
cpplearner Jan 31, 2024
95c294b
Merge branch 'main' into merge-generator
StephanTLavavej Jan 31, 2024
9bb121c
Merge pull request #4354 from StephanTLavavej/merge-generator
StephanTLavavej Jan 31, 2024
7710f6c
Merge branch 'main' into merge-generator
StephanTLavavej Feb 6, 2024
12621be
`concepts_latest_matrix.lst` => `usual_latest_matrix.lst`
StephanTLavavej Feb 6, 2024
53bf3a4
Adjust VSO_0157762_feature_test_macros to match yvals_core.h.
StephanTLavavej Feb 6, 2024
84a6efe
Update `<generator>`'s `_HAS_CXX23` guard and message.
StephanTLavavej Feb 6, 2024
f7e6bf1
Work around VSO-1951821 by skipping `stateful_alloc` coverage for EDG.
StephanTLavavej Feb 6, 2024
e432c39
std.ixx: Guard `<generator>` with `_HAS_CXX23`.
StephanTLavavej Feb 6, 2024
d2aa714
Guard `import <generator>;` with `#if TEST_STANDARD >= 23`.
StephanTLavavej Feb 6, 2024
af01b63
Use `^^^ no workaround ^^^` comments around good code.
StephanTLavavej Feb 6, 2024
5d949f1
Merge pull request #4370 from StephanTLavavej/merge-generator
StephanTLavavej Feb 7, 2024
553c0c5
Merge branch 'main' into merge-generator
StephanTLavavej Feb 16, 2024
6bfb4ee
Merge pull request #4398 from StephanTLavavej/merge-generator
StephanTLavavej Feb 16, 2024
d5c525d
`<generator>`: Make nested types of `generator` ADL-proof (#4464)
frederick-vs-ja Mar 12, 2024
14bbb8e
`<generator>`: Various fixes and cleanups (#4471)
StephanTLavavej Mar 13, 2024
dde15f8
Merge branch 'main' into merge-generator
StephanTLavavej Mar 16, 2024
ac3369a
Merge pull request #4484 from StephanTLavavej/merge-generator
StephanTLavavej Mar 16, 2024
7f04044
`<generator>`: Test `generator::promise_type` (#4534)
JMazurkiewicz Mar 27, 2024
45c7fd9
`<generator>`: Add death tests (#4558)
JMazurkiewicz Apr 3, 2024
ffe74c1
Merge branch 'main' into merge-generator
StephanTLavavej Apr 12, 2024
6d55986
Merge pull request #4582 from StephanTLavavej/merge-generator
StephanTLavavej Apr 12, 2024
7928387
`<generator>`: Test `generator::iterator` (#4574)
JMazurkiewicz Apr 17, 2024
6fb9fa3
Merge branch 'main' into merge-generator
StephanTLavavej Apr 19, 2024
9efb2a5
Merge pull request #4603 from StephanTLavavej/merge-generator
StephanTLavavej Apr 19, 2024
c2b0579
`<generator>`: Don't include `<ranges>` (#4620)
JMazurkiewicz May 10, 2024
7ad2c73
`<generator>`: Don't use `operator new[]` and `operator delete[]` (#4…
JMazurkiewicz May 10, 2024
0191658
`<generator>`: An attempt to merge `_Top` and `_Info` (#4619)
JMazurkiewicz May 10, 2024
c76bb86
Merge branch 'main' into merge-generator
StephanTLavavej May 23, 2024
c41dcde
Merge pull request #4692 from StephanTLavavej/merge-generator
StephanTLavavej May 23, 2024
62bb92b
`<generator>`: Cleanup `P2502R2_generator/test.cpp` (#4722)
JMazurkiewicz Jun 14, 2024
7e5c8c3
Merge branch 'main' into merge-generator
StephanTLavavej Jun 18, 2024
9f8ea18
Merge pull request #4737 from StephanTLavavej/merge-generator
StephanTLavavej Jun 18, 2024
5d4e965
Merge branch 'main' into merge-generator
StephanTLavavej Jul 11, 2024
156b2dd
`_NODISCARD_FRIEND` => `_NODISCARD friend`
StephanTLavavej Jul 11, 2024
e07fc91
Merge pull request #4834 from StephanTLavavej/merge-generator
StephanTLavavej Jul 12, 2024
cf0bf1a
`<generator>`: Revert unnecessary ADL firewall for `_Gen_promise_base…
frederick-vs-ja Jul 17, 2024
874880f
Implement P2787R1 `pmr::generator` (#4869)
frederick-vs-ja Aug 1, 2024
b66813a
Merge branch 'main' into merge-generator
StephanTLavavej Aug 15, 2024
91aceaa
Merge pull request #4893 from StephanTLavavej/merge-generator
StephanTLavavej Aug 15, 2024
6d2d6bf
Merge branch 'main' into reformat-generator
StephanTLavavej Sep 12, 2024
d19a53a
Merge pull request #4950 from StephanTLavavej/reformat-generator
StephanTLavavej Sep 12, 2024
89283a6
Polish `std::generator` (#4952)
CaseyCarter Sep 13, 2024
bb573d3
`forward` `expected` in `test_one`
CaseyCarter Sep 13, 2024
b61b7ba
Insert namespace `_Gen_detail` to hold implementation details
CaseyCarter Sep 17, 2024
4d372ed
Rename `_Allocator_is_stateless` to `_Stateless_allocator`
CaseyCarter Sep 17, 2024
6482abe
Rename `_Has_real_pointers` to `_Valid_allocator`
CaseyCarter Sep 17, 2024
2f9cf38
Rename `_Coro_promise_allocator` to `_Promise_allocator`
CaseyCarter Sep 17, 2024
483d091
Rename `_Gen_value_t` to `_Value_t`
CaseyCarter Sep 17, 2024
402b5d8
Rename `_Gen_reference_t` to `_Reference_t`
CaseyCarter Sep 17, 2024
6c957a2
Rename `_Gen_yield_t` to `_Yield_t`
CaseyCarter Sep 17, 2024
43ed77d
Rename `_Gen_iter_provider` to `_Iter_provider`
CaseyCarter Sep 17, 2024
bba8c2e
Rename `_Gen_promise_base` to `_Promise_base`
CaseyCarter Sep 17, 2024
c4a4d6e
Rename `_Gen_secret_tag` to `_Secret_tag`
CaseyCarter Sep 17, 2024
9da3deb
Clarify comments
CaseyCarter Sep 17, 2024
a4a6b55
Rewrap some messages and reformat
CaseyCarter Sep 17, 2024
3ab2a88
Avoid `#pragma once` in product code.
StephanTLavavej Sep 16, 2024
215c774
Default to `_Alloc = _Alloc()` for consistency.
StephanTLavavej Sep 16, 2024
c16ccbb
Add `_NODISCARD` and `_NODISCARD_RAW_PTR_ALLOC`.
StephanTLavavej Sep 17, 2024
124dc45
Add `_STL_INTERNAL_STATIC_ASSERT` for stateless/stateful.
StephanTLavavej Sep 17, 2024
332e3a6
Extract `_Get_allocator_address()`.
StephanTLavavej Sep 17, 2024
1532f08
Use `construct_at` with properly-typed `_Alloc*`.
StephanTLavavej Sep 17, 2024
75144b6
Consistently use `sizeof(_Dealloc_fn)`.
StephanTLavavej Sep 17, 2024
44658f2
Drop unnecessary parens in `requires`.
StephanTLavavej Sep 17, 2024
8573013
Style: Attach brace.
StephanTLavavej Sep 17, 2024
586e6fa
Too many secrets.
StephanTLavavej Sep 17, 2024
61a1651
test_generator_support.hpp stopped using `<cstdlib>` and `<memory_res…
StephanTLavavej Sep 17, 2024
55516dd
STL's product code review comments
CaseyCarter Sep 17, 2024
1f86f07
STL's review comments
CaseyCarter Sep 18, 2024
cebe620
`<random>` is now unused in `P2502R2_generator`
CaseyCarter Sep 18, 2024
89ebb33
Work around EDG ICE VSO-2254804.
StephanTLavavej Sep 19, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions stl/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ set(HEADERS
${CMAKE_CURRENT_LIST_DIR}/inc/fstream
${CMAKE_CURRENT_LIST_DIR}/inc/functional
${CMAKE_CURRENT_LIST_DIR}/inc/future
${CMAKE_CURRENT_LIST_DIR}/inc/generator
${CMAKE_CURRENT_LIST_DIR}/inc/hash_map
${CMAKE_CURRENT_LIST_DIR}/inc/hash_set
${CMAKE_CURRENT_LIST_DIR}/inc/header-units.json
Expand Down
1 change: 1 addition & 0 deletions stl/inc/__msvc_all_public_headers.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@
#include <forward_list>
#include <fstream>
#include <functional>
#include <generator>
#include <hash_map>
#include <hash_set>
#include <iomanip>
Expand Down
14 changes: 7 additions & 7 deletions stl/inc/coroutine
Original file line number Diff line number Diff line change
Expand Up @@ -92,12 +92,12 @@ private:
void* _Ptr = nullptr;
};

_EXPORT_STD template <class _Promise>
_EXPORT_STD template <class _CoroPromise>
struct coroutine_handle {
constexpr coroutine_handle() noexcept = default;
constexpr coroutine_handle(nullptr_t) noexcept {}

_NODISCARD static coroutine_handle from_promise(_Promise& _Prom) noexcept { // strengthened
_NODISCARD static coroutine_handle from_promise(_CoroPromise& _Prom) noexcept { // strengthened
const auto _Prom_ptr = const_cast<void*>(static_cast<const volatile void*>(_STD addressof(_Prom)));
const auto _Frame_ptr = __builtin_coro_promise(_Prom_ptr, 0, true);
coroutine_handle _Result;
Expand Down Expand Up @@ -144,8 +144,8 @@ struct coroutine_handle {
__builtin_coro_destroy(_Ptr);
}

_NODISCARD _Promise& promise() const noexcept { // strengthened
return *reinterpret_cast<_Promise*>(__builtin_coro_promise(_Ptr, 0, false));
_NODISCARD _CoroPromise& promise() const noexcept { // strengthened
return *reinterpret_cast<_CoroPromise*>(__builtin_coro_promise(_Ptr, 0, false));
}

private:
Expand Down Expand Up @@ -184,10 +184,10 @@ _NODISCARD constexpr bool operator>=(const coroutine_handle<> _Left, const corou
}
#endif // ^^^ !_HAS_CXX20 ^^^

template <class _Promise>
struct hash<coroutine_handle<_Promise>> {
template <class _CoroPromise>
struct hash<coroutine_handle<_CoroPromise>> {
_NODISCARD _STATIC_CALL_OPERATOR size_t operator()(
const coroutine_handle<_Promise>& _Coro) _CONST_CALL_OPERATOR noexcept {
const coroutine_handle<_CoroPromise>& _Coro) _CONST_CALL_OPERATOR noexcept {
return _Hash_representation(_Coro.address());
}
};
Expand Down
606 changes: 606 additions & 0 deletions stl/inc/generator

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions stl/inc/header-units.json
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@
"fstream",
"functional",
"future",
"generator",
// "hash_map", // non-Standard, will be removed soon
// "hash_set", // non-Standard, will be removed soon
"initializer_list",
Expand Down
22 changes: 22 additions & 0 deletions stl/inc/xmemory
Original file line number Diff line number Diff line change
Expand Up @@ -2588,6 +2588,28 @@ template <class _Ty>
concept _Transparent = _Is_transparent_v<_Ty>;
#endif // _HAS_CXX20

#if _HAS_CXX23
namespace ranges {
#if defined(__cpp_lib_byte)
_EXPORT_STD template <range _Rng, class _Alloc = allocator<byte>>
#else // ^^^ defined(__cpp_lib_byte) / !defined(__cpp_lib_byte) vvv
_EXPORT_STD template <range _Rng, class _Alloc>
#endif // ^^^ !defined(__cpp_lib_byte) ^^^
struct elements_of {
/* [[no_unique_address]] */ _Rng range;
/* [[no_unique_address]] */ _Alloc allocator{};
};

#if defined(__cpp_lib_byte)
template <class _Rng, class _Alloc = allocator<byte>>
elements_of(_Rng&&, _Alloc = _Alloc()) -> elements_of<_Rng&&, _Alloc>;
#else // ^^^ defined(__cpp_lib_byte) / !defined(__cpp_lib_byte) vvv
template <class _Rng, class _Alloc>
elements_of(_Rng&&, _Alloc) -> elements_of<_Rng&&, _Alloc>;
#endif // ^^^ !defined(__cpp_lib_byte) ^^^
} // namespace ranges
#endif // _HAS_CXX23

template <class _Elem, class _UTy>
_NODISCARD _Elem* _UIntegral_to_buff(_Elem* _RNext, _UTy _UVal) { // used by both to_string and thread::id output
// format _UVal into buffer *ending at* _RNext
Expand Down
3 changes: 3 additions & 0 deletions stl/inc/yvals_core.h
Original file line number Diff line number Diff line change
Expand Up @@ -379,6 +379,7 @@
// P2474R2 views::repeat
// P2494R2 Relaxing Range Adaptors To Allow Move-Only Types
// P2499R0 string_view Range Constructor Should Be explicit
// P2502R2 <generator>: Synchronous Coroutine Generator For Ranges
// P2505R5 Monadic Functions For expected
// P2539R4 Synchronizing print() With The Underlying Stream
// P2540R1 Empty Product For Certain Views
Expand All @@ -391,6 +392,7 @@
// P2693R1 Formatting thread::id And stacktrace
// P2713R1 Escaping Improvements In std::format
// P2763R1 Fixing layout_stride's Default Constructor For Fully Static Extents
// P2787R1 pmr::generator
// P2833R2 Freestanding Library: inout expected span
// (except for __cpp_lib_span which also covers C++26 span::at)
// P2836R1 basic_const_iterator Should Follow Its Underlying Type's Convertibility
Expand Down Expand Up @@ -1764,6 +1766,7 @@ _EMIT_STL_ERROR(STL1004, "C++98 unexpected() is incompatible with C++23 unexpect
#define __cpp_lib_forward_like 202207L
#define __cpp_lib_freestanding_expected 202311L
#define __cpp_lib_freestanding_mdspan 202311L
#define __cpp_lib_generator 202207L
#define __cpp_lib_invoke_r 202106L
#define __cpp_lib_ios_noreplace 202207L
#define __cpp_lib_is_scoped_enum 202011L
Expand Down
3 changes: 3 additions & 0 deletions stl/modules/std.ixx
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,9 @@ export module std;
#include <fstream>
#include <functional>
#include <future>
#if _HAS_CXX23
#include <generator>
#endif // _HAS_CXX23
#include <initializer_list>
#include <iomanip>
#include <ios>
Expand Down
148 changes: 148 additions & 0 deletions tests/std/include/test_generator_support.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
// Copyright (c) Microsoft Corporation.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception

#pragma once

#include <concepts>
#include <cstddef>
#include <generator>
#include <memory>
#include <type_traits>

template <class R, class V = void, class A = void>
struct gen_traits;

template <class R>
struct gen_traits<R> {
using generator = std::generator<R>;
using value = std::remove_cvref_t<R>;
using reference = R&&;
using yielded = reference;

// Verify the default template arguments
static_assert(std::same_as<std::generator<R>, std::generator<R, void>>);
static_assert(std::same_as<std::generator<R, void>, std::generator<R, void, void>>);
};
template <class R, class V>
struct gen_traits<R, V> {
using generator = std::generator<R, V>;
using value = V;
using reference = R;
using yielded = std::conditional_t<std::is_reference_v<R>, R, const R&>;

// Ditto verify default template arguments
static_assert(std::same_as<std::generator<R, V>, std::generator<R, V, void>>);
};
template <class R, class V, class A>
struct gen_traits : gen_traits<R, V> {
using generator = std::generator<R, V, A>;
};

template <class Ref, class V>
using gen_value_t = gen_traits<Ref, V>::value;

template <class Ref, class V>
using gen_reference_t = gen_traits<Ref, V>::reference;

template <class T, class AlwaysEqual = std::true_type, std::signed_integral DifferenceType = std::ptrdiff_t>
class StatelessAlloc {
public:
using value_type = T;
using is_always_equal = AlwaysEqual;
using difference_type = DifferenceType;
using size_type = std::make_unsigned_t<difference_type>;

StatelessAlloc() = default;

template <class U>
StatelessAlloc(const StatelessAlloc<U, AlwaysEqual, DifferenceType>&) {}

T* allocate(const size_type s) {
return std::allocator<T>{}.allocate(s);
}

void deallocate(T* const p, const size_type n) noexcept {
std::allocator<T>{}.deallocate(p, n);
}

template <class U>
bool operator==(const StatelessAlloc<U, AlwaysEqual, DifferenceType>&) const noexcept {
return true;
}
};

static_assert(std::default_initializable<StatelessAlloc<int>>);

template <class T>
class StatefulAlloc {
public:
using value_type = T;

explicit StatefulAlloc(int dom) noexcept : domain{dom} {}

template <class U>
StatefulAlloc(const StatefulAlloc<U>& that) noexcept : domain{that.domain} {}

T* allocate(const size_t n) {
return std::allocator<T>{}.allocate(n);
}

void deallocate(T* const p, const size_t n) noexcept {
return std::allocator<T>{}.deallocate(p, n);
}

template <class U>
bool operator==(const StatefulAlloc<U>& that) noexcept {
return domain == that.domain;
}

private:
int domain;

template <class U>
friend class StatefulAlloc;
};

static_assert(!std::default_initializable<StatefulAlloc<int>>);

struct MoveOnly {
MoveOnly() = default;
MoveOnly(const MoveOnly&) = delete;
MoveOnly& operator=(const MoveOnly&) = delete;
MoveOnly(MoveOnly&&) = default;
MoveOnly& operator=(MoveOnly&&) = default;
};

static_assert(std::movable<MoveOnly>);
static_assert(!std::copyable<MoveOnly>);

struct Immovable {
Immovable() = default;
Immovable(Immovable&&) = delete;
Immovable& operator=(Immovable&&) = delete;
};

static_assert(!std::movable<Immovable>);

template <class T>
class Proxy {
public:
Proxy(const T&) {}
};

template <std::equality_comparable T>
class Proxy<T> {
public:
Proxy(const T& _value_) : value(_value_) {}

bool operator==(const Proxy& other) const {
return value == other.value;
}

bool operator==(const T& x) const {
return value == x;
}

private:
const T& value;
};
17 changes: 17 additions & 0 deletions tests/std/include/test_header_units_and_modules.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -284,6 +284,20 @@ void test_future() {
assert(f.get() == 1729);
}

#if TEST_STANDARD >= 23
void test_generator() {
using namespace std;
puts("Testing <generator>.");
auto some_ints = [](int hi) -> generator<int> {
for (int i = 0; i < hi; ++i) {
co_yield i;
}
};
constexpr int bound = 42;
assert(ranges::equal(some_ints(bound), views::iota(0, bound)));
}
#endif // TEST_STANDARD >= 23

void test_initializer_list() {
using namespace std;
puts("Testing <initializer_list>.");
Expand Down Expand Up @@ -1182,6 +1196,9 @@ void all_cpp_header_tests() {
test_fstream();
test_functional();
test_future();
#if TEST_STANDARD >= 23
test_generator();
#endif // TEST_STANDARD >= 23
test_initializer_list();
test_iomanip();
test_ios();
Expand Down
4 changes: 4 additions & 0 deletions tests/std/test.lst
Original file line number Diff line number Diff line change
Expand Up @@ -670,6 +670,10 @@ tests\P2467R1_exclusive_mode_fstreams
tests\P2474R2_views_repeat
tests\P2474R2_views_repeat_death
tests\P2494R2_move_only_range_adaptors
tests\P2502R2_generator
tests\P2502R2_generator_death
tests\P2502R2_generator_iterator
tests\P2502R2_generator_promise
tests\P2505R5_monadic_functions_for_std_expected
tests\P2510R3_text_formatting_pointers
tests\P2517R1_apply_conditional_noexcept
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
"fstream",
"functional",
"future",
"generator",
"initializer_list",
"iomanip",
"ios",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,9 @@ import <forward_list>;
import <fstream>;
import <functional>;
import <future>;
#if TEST_STANDARD >= 23
import <generator>;
#endif // TEST_STANDARD >= 23
import <initializer_list>;
import <iomanip>;
import <ios>;
Expand Down
4 changes: 4 additions & 0 deletions tests/std/tests/P2502R2_generator/env.lst
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# Copyright (c) Microsoft Corporation.
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception

RUNALL_INCLUDE ..\usual_latest_matrix.lst
Loading