Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
8 changes: 8 additions & 0 deletions stl/inc/expected
Original file line number Diff line number Diff line change
Expand Up @@ -258,6 +258,8 @@ public:
is_trivially_copy_constructible_v<_Ty> && is_trivially_copy_constructible_v<_Err> = default;
// clang-format on

expected(const expected&) = delete;

constexpr expected(expected&& _Other) noexcept(
is_nothrow_move_constructible_v<_Ty> && is_nothrow_move_constructible_v<_Err>)
requires (!(is_trivially_move_constructible_v<_Ty> && is_trivially_move_constructible_v<_Err>)
Expand Down Expand Up @@ -441,6 +443,8 @@ public:
&& _Trivially_copy_constructible_assignable_destructible<_Err>
= default;

expected& operator=(const expected&) = delete;

constexpr expected& operator=(expected&& _Other) noexcept(
is_nothrow_move_constructible_v<_Ty> && is_nothrow_move_constructible_v<_Err>
&& is_nothrow_move_assignable_v<_Ty> && is_nothrow_move_assignable_v<_Err>)
Expand Down Expand Up @@ -1243,6 +1247,8 @@ public:
expected(const expected&) requires is_trivially_copy_constructible_v<_Err> = default;
// clang-format on

expected(const expected&) = delete;

constexpr expected(expected&& _Other) noexcept(is_nothrow_move_constructible_v<_Err>)
requires (!is_trivially_move_constructible_v<_Err> && is_move_constructible_v<_Err>)
: _Has_value(_Other._Has_value) {
Expand Down Expand Up @@ -1344,6 +1350,8 @@ public:
requires _Expected_unary_copy_assignable<_Err> && _Trivially_copy_constructible_assignable_destructible<_Err>
= default;

expected& operator=(const expected&) = delete;

constexpr expected& operator=(expected&& _Other) noexcept(
is_nothrow_move_constructible_v<_Err> && is_nothrow_move_assignable_v<_Err>)
requires _Expected_unary_move_assignable<_Err>
Expand Down
47 changes: 47 additions & 0 deletions tests/std/tests/P0323R12_expected/test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2343,6 +2343,53 @@ constexpr bool test_inherited_constructors() {

static_assert(test_inherited_constructors());

// Test GH-4279 "Add deleted function overloads to expected"

template <class T, class E>
struct ambiguating_expected_copy_constructor_caller {
struct const_lvalue_taker {
const_lvalue_taker(const expected<T, E>&) {}
};

void operator()(expected<T, E>) {}
void operator()(const_lvalue_taker) {}
};

template <class T, class E>
struct ambiguating_expected_assignment_source {
operator const expected<T, E>&() && {
return ex;
}

operator expected<T, E>&&() && {
return move(ex);
}

expected<T, E> ex;
};

struct move_only {
move_only() = default;
move_only(move_only&&) = default;
move_only& operator=(move_only&&) = default;
};

static_assert(is_invocable_v<ambiguating_expected_copy_constructor_caller<int, char>, const expected<int, char>&>);
static_assert(is_invocable_v<ambiguating_expected_copy_constructor_caller<void, int>, const expected<void, int>&>);
static_assert(
!is_invocable_v<ambiguating_expected_copy_constructor_caller<move_only, char>, const expected<move_only, char>&>);
static_assert(
!is_invocable_v<ambiguating_expected_copy_constructor_caller<void, move_only>, const expected<void, move_only>&>);

#ifndef __EDG__ // TRANSITION, VSO-1601179
static_assert(!is_assignable_v<expected<int, char>&, ambiguating_expected_assignment_source<int, char>>);
static_assert(!is_assignable_v<expected<void, int>&, ambiguating_expected_assignment_source<void, int>>);
#endif // ^^^ no workaround ^^^
#ifndef __EDG__ // TRANSITION, VSO-2188364
static_assert(!is_assignable_v<expected<move_only, char>&, ambiguating_expected_assignment_source<move_only, char>>);
static_assert(!is_assignable_v<expected<void, move_only>&, ambiguating_expected_assignment_source<void, move_only>>);
#endif // ^^^ no workaround ^^^

int main() {
test_unexpected::test_all();
static_assert(test_unexpected::test_all());
Expand Down