Skip to content

Commit 002fcac

Browse files
committed
[libc++] P3379R1: Constrain 'std::expected' equality operators
1 parent 7fc71f7 commit 002fcac

File tree

1 file changed

+20
-2
lines changed

1 file changed

+20
-2
lines changed

libcxx/include/__expected/expected.h

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#define _LIBCPP___EXPECTED_EXPECTED_H
1111

1212
#include <__assert>
13+
#include <__concepts/convertible_to.h>
1314
#include <__config>
1415
#include <__expected/bad_expected_access.h>
1516
#include <__expected/unexpect.h>
@@ -1139,7 +1140,11 @@ class expected : private __expected_base<_Tp, _Err> {
11391140

11401141
// [expected.object.eq], equality operators
11411142
template <class _T2, class _E2>
1142-
requires(!is_void_v<_T2>)
1143+
requires(!is_void_v<_T2> &&
1144+
requires(const _Tp& __tp, const _T2& __t2, const _Err& __err, const _E2& __e2) {
1145+
{ __tp == __t2 } -> convertible_to<bool>;
1146+
{ __err == __e2 } -> convertible_to<bool>;
1147+
})
11431148
_LIBCPP_HIDE_FROM_ABI friend constexpr bool operator==(const expected& __x, const expected<_T2, _E2>& __y) {
11441149
if (__x.__has_val() != __y.__has_val()) {
11451150
return false;
@@ -1153,11 +1158,18 @@ class expected : private __expected_base<_Tp, _Err> {
11531158
}
11541159

11551160
template <class _T2>
1161+
requires(!__is_std_expected<_T2>::value &&
1162+
requires(const _Tp& __tp, const _T2& __t2) {
1163+
{ __tp == __t2 } -> convertible_to<bool>;
1164+
})
11561165
_LIBCPP_HIDE_FROM_ABI friend constexpr bool operator==(const expected& __x, const _T2& __v) {
11571166
return __x.__has_val() && static_cast<bool>(__x.__val() == __v);
11581167
}
11591168

11601169
template <class _E2>
1170+
requires requires(const _Err& __err, const _E2& __e2) {
1171+
{ __err == __e2 } -> convertible_to<bool>;
1172+
}
11611173
_LIBCPP_HIDE_FROM_ABI friend constexpr bool operator==(const expected& __x, const unexpected<_E2>& __e) {
11621174
return !__x.__has_val() && static_cast<bool>(__x.__unex() == __e.error());
11631175
}
@@ -1850,7 +1862,10 @@ class expected<_Tp, _Err> : private __expected_void_base<_Err> {
18501862

18511863
// [expected.void.eq], equality operators
18521864
template <class _T2, class _E2>
1853-
requires is_void_v<_T2>
1865+
requires(is_void_v<_T2> &&
1866+
requires(const _Err& __err, const _E2& __e2) {
1867+
{ __err == __e2 } -> convertible_to<bool>;
1868+
})
18541869
_LIBCPP_HIDE_FROM_ABI friend constexpr bool operator==(const expected& __x, const expected<_T2, _E2>& __y) {
18551870
if (__x.__has_val() != __y.__has_val()) {
18561871
return false;
@@ -1860,6 +1875,9 @@ class expected<_Tp, _Err> : private __expected_void_base<_Err> {
18601875
}
18611876

18621877
template <class _E2>
1878+
requires requires(const _Err& __err, const _E2& __e2) {
1879+
{ __err == __e2 } -> convertible_to<bool>;
1880+
}
18631881
_LIBCPP_HIDE_FROM_ABI friend constexpr bool operator==(const expected& __x, const unexpected<_E2>& __y) {
18641882
return !__x.__has_val() && static_cast<bool>(__x.__unex() == __y.error());
18651883
}

0 commit comments

Comments
 (0)