Skip to content

Commit e759252

Browse files
committed
Implement LWG-3843 and LWG-3940
This only changes aspects of expected that are related to exceptions, so we do not really care about them too much
1 parent 165a06a commit e759252

File tree

3 files changed

+77
-44
lines changed

3 files changed

+77
-44
lines changed

libcudacxx/include/cuda/std/detail/libcxx/include/__expected/expected.h

+20-1
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@
5555
#include <cuda/std/detail/libcxx/include/__type_traits/negation.h>
5656
#include <cuda/std/detail/libcxx/include/__type_traits/remove_cv.h>
5757
#include <cuda/std/detail/libcxx/include/__type_traits/remove_cvref.h>
58+
#include <cuda/std/detail/libcxx/include/__utility/as_const.h>
5859
#include <cuda/std/detail/libcxx/include/__utility/exception_guard.h>
5960
#include <cuda/std/detail/libcxx/include/__utility/forward.h>
6061
#include <cuda/std/detail/libcxx/include/__utility/in_place.h>
@@ -551,6 +552,8 @@ class expected
551552

552553
_LIBCUDACXX_HIDE_FROM_ABI _LIBCUDACXX_INLINE_VISIBILITY constexpr const _Tp& value() const&
553554
{
555+
static_assert(_LIBCUDACXX_TRAIT(is_copy_constructible, _Err),
556+
"expected::value() const& requires is_copy_constructible_v<E>");
554557
if (!this->__has_val_)
555558
{
556559
__throw_bad_expected_access<_Err>(this->__union_.__unex_);
@@ -560,15 +563,21 @@ class expected
560563

561564
_LIBCUDACXX_HIDE_FROM_ABI _LIBCUDACXX_INLINE_VISIBILITY constexpr _Tp& value() &
562565
{
566+
static_assert(_LIBCUDACXX_TRAIT(is_copy_constructible, _Err),
567+
"expected::value() & requires is_copy_constructible_v<E>");
563568
if (!this->__has_val_)
564569
{
565-
__throw_bad_expected_access<_Err>(this->__union_.__unex_);
570+
__throw_bad_expected_access<_Err>(_CUDA_VSTD::as_const(this->__union_.__unex_));
566571
}
567572
return this->__union_.__val_;
568573
}
569574

570575
_LIBCUDACXX_HIDE_FROM_ABI _LIBCUDACXX_INLINE_VISIBILITY constexpr const _Tp&& value() const&&
571576
{
577+
static_assert(_LIBCUDACXX_TRAIT(is_copy_constructible, _Err),
578+
"expected::value() const&& requires is_copy_constructible_v<E>");
579+
static_assert(_LIBCUDACXX_TRAIT(is_constructible, _Err, decltype(_CUDA_VSTD::move(error()))),
580+
"expected::value() const&& requires is_constructible_v<E, decltype(_CUDA_VSTD::move(error()))>");
572581
if (!this->__has_val_)
573582
{
574583
__throw_bad_expected_access<_Err>(_CUDA_VSTD::move(this->__union_.__unex_));
@@ -578,6 +587,10 @@ class expected
578587

579588
_LIBCUDACXX_HIDE_FROM_ABI _LIBCUDACXX_INLINE_VISIBILITY constexpr _Tp&& value() &&
580589
{
590+
static_assert(_LIBCUDACXX_TRAIT(is_copy_constructible, _Err),
591+
"expected::value() const&& requires is_copy_constructible_v<E>");
592+
static_assert(_LIBCUDACXX_TRAIT(is_constructible, _Err, decltype(_CUDA_VSTD::move(error()))),
593+
"expected::value() const&& requires is_constructible_v<E, decltype(_CUDA_VSTD::move(error()))>");
581594
if (!this->__has_val_)
582595
{
583596
__throw_bad_expected_access<_Err>(_CUDA_VSTD::move(this->__union_.__unex_));
@@ -1473,6 +1486,8 @@ class expected<void, _Err>
14731486

14741487
_LIBCUDACXX_HIDE_FROM_ABI _LIBCUDACXX_INLINE_VISIBILITY constexpr void value() const&
14751488
{
1489+
static_assert(_LIBCUDACXX_TRAIT(is_copy_constructible, _Err),
1490+
"expected::value() const& requires is_copy_constructible_v<E>");
14761491
if (!this->__has_val_)
14771492
{
14781493
__throw_bad_expected_access<_Err>(this->__union_.__unex_);
@@ -1481,6 +1496,10 @@ class expected<void, _Err>
14811496

14821497
_LIBCUDACXX_HIDE_FROM_ABI _LIBCUDACXX_INLINE_VISIBILITY constexpr void value() &&
14831498
{
1499+
static_assert(_LIBCUDACXX_TRAIT(is_copy_constructible, _Err),
1500+
"expected::value() && requires is_copy_constructible_v<E>");
1501+
static_assert(_LIBCUDACXX_TRAIT(is_move_constructible, _Err),
1502+
"expected::value() && requires is_move_constructible_v<E>");
14841503
if (!this->__has_val_)
14851504
{
14861505
__throw_bad_expected_access<_Err>(_CUDA_VSTD::move(this->__union_.__unex_));

libcudacxx/test/libcudacxx/std/utilities/expected/expected.expected/observers/value.pass.cpp

+51-21
Original file line numberDiff line numberDiff line change
@@ -65,34 +65,64 @@ __host__ __device__ constexpr bool test()
6565
}
6666

6767
#ifndef TEST_HAS_NO_EXCEPTIONS
68+
struct Error
69+
{
70+
enum
71+
{
72+
Default,
73+
MutableRefCalled,
74+
ConstRefCalled
75+
} From = Default;
76+
Error() = default;
77+
Error(const Error&)
78+
{
79+
From = ConstRefCalled;
80+
}
81+
Error(Error&)
82+
{
83+
From = MutableRefCalled;
84+
}
85+
Error(Error&& e)
86+
{
87+
From = e.From;
88+
}
89+
};
90+
6891
void test_exceptions()
6992
{
70-
// int
93+
try
7194
{
7295
const cuda::std::expected<int, int> e(cuda::std::unexpect, 5);
73-
try
74-
{
75-
(void) e.value();
76-
assert(false);
77-
}
78-
catch (const cuda::std::bad_expected_access<int>& ex)
79-
{
80-
assert(ex.error() == 5);
81-
}
96+
(void) e.value();
97+
assert(false);
98+
}
99+
catch (const cuda::std::bad_expected_access<int>& ex)
100+
{
101+
assert(ex.error() == 5);
82102
}
83103

84-
// MoveOnly
104+
// Test & overload
105+
try
106+
{
107+
cuda::std::expected<int, Error> e(cuda::std::unexpect, Error());
108+
(void) e.value();
109+
assert(false);
110+
}
111+
catch (const cuda::std::bad_expected_access<Error>& ex)
112+
{
113+
assert(ex.error().From == Error::ConstRefCalled);
114+
}
115+
116+
// Test const& overload
117+
try
118+
{
119+
const cuda::std::expected<int, Error> e(cuda::std::unexpect, Error());
120+
(void) e.value();
121+
assert(false);
122+
}
123+
catch (const cuda::std::bad_expected_access<Error>& ex)
85124
{
86-
cuda::std::expected<int, MoveOnly> e(cuda::std::unexpect, 5);
87-
try
88-
{
89-
(void) cuda::std::move(e).value();
90-
assert(false);
91-
}
92-
catch (const cuda::std::bad_expected_access<MoveOnly>& ex)
93-
{
94-
assert(ex.error() == 5);
95-
}
125+
assert(ex.error().From == Error::ConstRefCalled);
96126
}
97127
}
98128
#endif // !TEST_HAS_NO_EXCEPTIONS

libcudacxx/test/libcudacxx/std/utilities/expected/expected.void/observers/value.pass.cpp

+6-22
Original file line numberDiff line numberDiff line change
@@ -57,32 +57,16 @@ __host__ __device__ constexpr bool test()
5757
#ifndef TEST_HAS_NO_EXCEPTIONS
5858
void test_exceptions()
5959
{
60-
// int
60+
// Test const& overload
61+
try
6162
{
6263
const cuda::std::expected<void, int> e(cuda::std::unexpect, 5);
63-
try
64-
{
65-
e.value();
66-
assert(false);
67-
}
68-
catch (const cuda::std::bad_expected_access<int>& ex)
69-
{
70-
assert(ex.error() == 5);
71-
}
64+
e.value();
65+
assert(false);
7266
}
73-
74-
// MoveOnly
67+
catch (const cuda::std::bad_expected_access<int>& ex)
7568
{
76-
cuda::std::expected<void, MoveOnly> e(cuda::std::unexpect, 5);
77-
try
78-
{
79-
cuda::std::move(e).value();
80-
assert(false);
81-
}
82-
catch (const cuda::std::bad_expected_access<MoveOnly>& ex)
83-
{
84-
assert(ex.error() == 5);
85-
}
69+
assert(ex.error() == 5);
8670
}
8771
}
8872
#endif // !TEST_HAS_NO_EXCEPTIONS

0 commit comments

Comments
 (0)