Thanks to visit codestin.com
Credit goes to github.com

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
17 changes: 15 additions & 2 deletions stl/inc/expected
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,11 @@ public:
}

friend constexpr void swap(unexpected& _Left, unexpected& _Right) noexcept(is_nothrow_swappable_v<_Err>)
#if defined(__clang__) || defined(__EDG__) // TRANSITION, /permissive
requires is_swappable_v<_Err>
#else // ^^^ no workaround / workaround vvv
requires is_swappable<_Err>::value
#endif // ^^^ workaround ^^^
{
_Left.swap(_Right);
}
Expand Down Expand Up @@ -601,7 +605,11 @@ public:
friend constexpr void swap(expected& _Lhs, expected& _Rhs) noexcept(
is_nothrow_move_constructible_v<_Ty> && is_nothrow_swappable_v<_Ty> && is_nothrow_move_constructible_v<_Err>
&& is_nothrow_swappable_v<_Err>)
requires is_swappable_v<_Ty> && is_swappable_v<_Err> //
#if defined(__clang__) || defined(__EDG__) // TRANSITION, /permissive
requires is_swappable_v<_Ty> && is_swappable_v<_Err>
#else // ^^^ no workaround / workaround vvv
requires is_swappable<_Ty>::value && is_swappable<_Err>::value
#endif // ^^^ workaround ^^^
&& is_move_constructible_v<_Ty> && is_move_constructible_v<_Err>
&& (is_nothrow_move_constructible_v<_Ty> || is_nothrow_move_constructible_v<_Err>)
{
Expand Down Expand Up @@ -1429,7 +1437,12 @@ public:

friend constexpr void swap(expected& _Left, expected& _Right) noexcept(
is_nothrow_move_constructible_v<_Err> && is_nothrow_swappable_v<_Err>)
requires is_swappable_v<_Err> && is_move_constructible_v<_Err>
#if defined(__clang__) || defined(__EDG__) // TRANSITION, /permissive
requires is_swappable_v<_Err>
#else // ^^^ no workaround / workaround vvv
requires is_swappable<_Err>::value
#endif // ^^^ workaround ^^^
&& is_move_constructible_v<_Err>
{
_Left.swap(_Right);
}
Expand Down
10 changes: 10 additions & 0 deletions stl/inc/iterator
Original file line number Diff line number Diff line change
Expand Up @@ -498,6 +498,11 @@ _NODISCARD bool operator!=(
}
#endif // !_HAS_CXX20

#if _HAS_CXX20 && !defined(__clang__) && !defined(__EDG__) // TRANSITION, /permissive, avoid checking constraints
template <class _Elem, class _Traits>
constexpr bool _Iterator_is_contiguous<istreambuf_iterator<_Elem, _Traits>> = false;
#endif // ^^^ workaround ^^^

_EXPORT_STD template <class _Elem, class _Traits>
class ostreambuf_iterator {
public:
Expand Down Expand Up @@ -548,6 +553,11 @@ private:
streambuf_type* _Strbuf;
};

#if _HAS_CXX20 && !defined(__clang__) && !defined(__EDG__) // TRANSITION, /permissive, avoid checking constraints
template <class _Elem, class _Traits>
constexpr bool _Iterator_is_contiguous<ostreambuf_iterator<_Elem, _Traits>> = false;
#endif // ^^^ workaround ^^^

#if _HAS_CXX20
enum class _Variantish_state : unsigned char { _Nothing, _Holds_first, _Holds_second };

Expand Down
1 change: 1 addition & 0 deletions tests/std/test.lst
Original file line number Diff line number Diff line change
Expand Up @@ -245,6 +245,7 @@ tests\GH_004388_unordered_meow_operator_equal
tests\GH_004477_mdspan_warning_5246
tests\GH_004618_mixed_operator_usage_keeps_statistical_properties
tests\GH_004618_normal_distribution_avoids_resets
tests\GH_004657_expected_constraints_permissive
tests\LWG2381_num_get_floating_point
tests\LWG2597_complex_branch_cut
tests\LWG3018_shared_ptr_function
Expand Down
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
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// Copyright (c) Microsoft Corporation.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception

#include <expected>
// <locale> provides several explicit template instantiation definitions that might break constraints checking
// and hence cause errors in /permissive modes.
#include <locale>
#include <string>
#include <utility>

using namespace std;

expected<int, string> test_expected_int_constraints() {
return 42;
}

expected<pair<int, int>, string> test_expected_pair_constraints() {
return pair<int, int>{42, 1729};
}

expected<void, string> test_expected_void_constraints() {
return {};
}

unexpected<string> test_unexpected_constraints() {
return unexpected<string>{string{}};
}
2 changes: 1 addition & 1 deletion tests/std/tests/P0323R12_expected/env.lst
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Copyright (c) Microsoft Corporation.
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception

RUNALL_INCLUDE ..\strict_latest_matrix.lst
RUNALL_INCLUDE ..\usual_latest_matrix.lst
48 changes: 25 additions & 23 deletions tests/std/tests/P0323R12_expected/test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
#include <utility>
#include <vector>

#include <is_permissive.hpp> // noexcept operator possibly gives wrong values in permissive modes

using namespace std;

enum class IsDefaultConstructible : bool { Not, Yes };
Expand Down Expand Up @@ -82,31 +84,31 @@ namespace test_unexpected {
// [expected.un.ctor]
const int& input = 1;
Unexpect in_place_lvalue_constructed{in_place, input};
static_assert(noexcept(Unexpect{in_place, input}) == copy_construction_is_noexcept);
static_assert(noexcept(Unexpect{in_place, input}) == copy_construction_is_noexcept || is_permissive);
assert(in_place_lvalue_constructed == Unexpect{test_error{1}});

Unexpect in_place_rvalue_constructed{in_place, 42};
static_assert(noexcept(Unexpect{in_place, 42}) == move_construction_is_noexcept);
static_assert(noexcept(Unexpect{in_place, 42}) == move_construction_is_noexcept || is_permissive);
assert(in_place_rvalue_constructed == Unexpect{test_error{42}});

Unexpect in_place_ilist_lvalue_constructed{in_place, {2}, input};
static_assert(noexcept(Unexpect{in_place, {2}, input}) == copy_construction_is_noexcept);
static_assert(noexcept(Unexpect{in_place, {2}, input}) == copy_construction_is_noexcept || is_permissive);
assert(in_place_ilist_lvalue_constructed == Unexpect{test_error{1}});

Unexpect in_place_ilist_rvalue_constructed{in_place, {2}, 1337};
static_assert(noexcept(Unexpect{in_place, {2}, 1337}) == move_construction_is_noexcept);
static_assert(noexcept(Unexpect{in_place, {2}, 1337}) == move_construction_is_noexcept || is_permissive);
assert(in_place_ilist_rvalue_constructed == Unexpect{test_error{1337}});

Unexpect base_error_constructed{test_error{3}};
static_assert(noexcept(Unexpect{test_error{3}}) == move_construction_is_noexcept);
static_assert(noexcept(Unexpect{test_error{3}}) == move_construction_is_noexcept || is_permissive);
assert(base_error_constructed.error()._val == 3);

Unexpect conversion_error_constructed{convertible{4}};
static_assert(noexcept(Unexpect{convertible{4}}) == move_construction_is_noexcept);
static_assert(noexcept(Unexpect{convertible{4}}) == move_construction_is_noexcept || is_permissive);
assert(conversion_error_constructed.error()._val == 4);

Unexpect brace_error_constructed{{5}};
static_assert(noexcept(Unexpect{{5}}) == move_construction_is_noexcept);
static_assert(noexcept(Unexpect{{5}}) == move_construction_is_noexcept || is_permissive);
assert(brace_error_constructed.error()._val == 5);

// [expected.un.eq]
Expand Down Expand Up @@ -500,12 +502,12 @@ namespace test_expected {
const Expected copy_constructed_value{const_input_value};
assert(copy_constructed_value);
assert(copy_constructed_value.value() == 3);
static_assert(noexcept(Expected{const_input_value}) == should_be_noexcept);
static_assert(noexcept(Expected{const_input_value}) == should_be_noexcept || is_permissive);

const Expected move_constructed_value{Input{}};
assert(move_constructed_value);
assert(move_constructed_value.value() == 42);
static_assert(noexcept(Expected{Input{}}) == should_be_noexcept);
static_assert(noexcept(Expected{Input{}}) == should_be_noexcept || is_permissive);

const Expected brace_constructed_value{{}};
assert(brace_constructed_value);
Expand All @@ -528,7 +530,7 @@ namespace test_expected {
const Expected move_constructed_value{Input{in_place}};
assert(move_constructed_value);
assert(move_constructed_value.value() == 42);
static_assert(noexcept(Expected{Input{in_place}}) == should_be_noexcept);
static_assert(noexcept(Expected{Input{in_place}}) == should_be_noexcept || is_permissive);

const Input const_input_error{unexpect};
const Expected copy_constructed_error{const_input_error};
Expand All @@ -539,7 +541,7 @@ namespace test_expected {
const Expected move_constructed_error{Input{unexpect}};
assert(!move_constructed_error);
assert(move_constructed_error.error() == 42);
static_assert(noexcept(Expected{Input{unexpect}}) == should_be_noexcept);
static_assert(noexcept(Expected{Input{unexpect}}) == should_be_noexcept || is_permissive);
}

{ // converting from unexpected
Expand All @@ -550,12 +552,12 @@ namespace test_expected {
const Expected copy_constructed{const_input};
assert(!copy_constructed);
assert(copy_constructed.error() == 3);
static_assert(noexcept(Expected{const_input}) == should_be_noexcept);
static_assert(noexcept(Expected{const_input}) == should_be_noexcept || is_permissive);

const Expected move_constructed{Input{in_place}};
assert(!move_constructed);
assert(move_constructed.error() == 42);
static_assert(noexcept(Expected{Input{in_place}}) == should_be_noexcept);
static_assert(noexcept(Expected{Input{in_place}}) == should_be_noexcept || is_permissive);
}

{ // in place payload
Expand All @@ -568,12 +570,12 @@ namespace test_expected {
const Expected value_constructed{in_place, convertible{}};
assert(value_constructed);
assert(value_constructed.value() == 42);
static_assert(noexcept(Expected{in_place, convertible{}}) == should_be_noexcept);
static_assert(noexcept(Expected{in_place, convertible{}}) == should_be_noexcept || is_permissive);

const Expected ilist_value_constructed{in_place, {1}, convertible{}};
assert(ilist_value_constructed);
assert(ilist_value_constructed.value() == 1337);
static_assert(noexcept(Expected{in_place, {1}, convertible{}}) == should_be_noexcept);
static_assert(noexcept(Expected{in_place, {1}, convertible{}}) == should_be_noexcept || is_permissive);
}

{ // in place error
Expand All @@ -586,12 +588,12 @@ namespace test_expected {
const Expected value_constructed{unexpect, convertible{}};
assert(!value_constructed);
assert(value_constructed.error() == 42);
static_assert(noexcept(Expected{unexpect, convertible{}}) == should_be_noexcept);
static_assert(noexcept(Expected{unexpect, convertible{}}) == should_be_noexcept || is_permissive);

const Expected ilist_value_constructed{unexpect, {1}, convertible{}};
assert(!ilist_value_constructed);
assert(ilist_value_constructed.error() == 1337);
static_assert(noexcept(Expected{unexpect, {1}, convertible{}}) == should_be_noexcept);
static_assert(noexcept(Expected{unexpect, {1}, convertible{}}) == should_be_noexcept || is_permissive);
}

{ // expected<void, E>: converting from different expected
Expand All @@ -609,7 +611,7 @@ namespace test_expected {
const Expected move_constructed_value{Input{in_place}};
assert(move_constructed_value);
move_constructed_value.value();
static_assert(noexcept(Expected{Input{in_place}}) == should_be_noexcept);
static_assert(noexcept(Expected{Input{in_place}}) == should_be_noexcept || is_permissive);

const Input const_input_error{unexpect};
const Expected copy_constructed_error{const_input_error};
Expand All @@ -620,7 +622,7 @@ namespace test_expected {
const Expected move_constructed_error{Input{unexpect}};
assert(!move_constructed_error);
assert(move_constructed_error.error() == 42);
static_assert(noexcept(Expected{Input{unexpect}}) == should_be_noexcept);
static_assert(noexcept(Expected{Input{unexpect}}) == should_be_noexcept || is_permissive);
}

{ // expected<void, E>: converting from unexpected
Expand All @@ -631,12 +633,12 @@ namespace test_expected {
const Expected copy_constructed{const_input};
assert(!copy_constructed);
assert(copy_constructed.error() == 3);
static_assert(noexcept(Expected{const_input}) == should_be_noexcept);
static_assert(noexcept(Expected{const_input}) == should_be_noexcept || is_permissive);

const Expected move_constructed{Input{in_place}};
assert(!move_constructed);
assert(move_constructed.error() == 42);
static_assert(noexcept(Expected{Input{in_place}}) == should_be_noexcept);
static_assert(noexcept(Expected{Input{in_place}}) == should_be_noexcept || is_permissive);
}

{ // expected<void, E>: in place payload
Expand All @@ -657,12 +659,12 @@ namespace test_expected {
const Expected value_constructed{unexpect, convertible{}};
assert(!value_constructed);
assert(value_constructed.error() == 42);
static_assert(noexcept(Expected{unexpect, convertible{}}) == should_be_noexcept);
static_assert(noexcept(Expected{unexpect, convertible{}}) == should_be_noexcept || is_permissive);

const Expected ilist_value_constructed{unexpect, {1}, convertible{}};
assert(!ilist_value_constructed);
assert(ilist_value_constructed.error() == 1337);
static_assert(noexcept(Expected{unexpect, {1}, convertible{}}) == should_be_noexcept);
static_assert(noexcept(Expected{unexpect, {1}, convertible{}}) == should_be_noexcept || is_permissive);
}
}

Expand Down