Skip to content

Commit b6ffcb1

Browse files
committed
[libc++] Implement LWG3973(Monadic operations should be ADL-proof)
Signed-off-by: nwh <[email protected]>
1 parent 15e9478 commit b6ffcb1

File tree

3 files changed

+21
-21
lines changed

3 files changed

+21
-21
lines changed

libcxx/docs/Status/Cxx2cIssues.csv

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@
3434
"`3957 <https://wg21.link/LWG3957>`__","[container.alloc.reqmts] The value category of v should be claimed","Kona November 2023","","",""
3535
"`3965 <https://wg21.link/LWG3965>`__","Incorrect example in [format.string.escaped] p3 for formatting of combining characters","Kona November 2023","","","|format|"
3636
"`3970 <https://wg21.link/LWG3970>`__","[mdspan.syn] Missing definition of ``full_extent_t`` and ``full_extent``","Kona November 2023","","",""
37-
"`3973 <https://wg21.link/LWG3973>`__","Monadic operations should be ADL-proof","Kona November 2023","","",""
37+
"`3973 <https://wg21.link/LWG3973>`__","Monadic operations should be ADL-proof","Kona November 2023","|Complete|","19.0",""
3838
"`3974 <https://wg21.link/LWG3974>`__","``mdspan::operator[]`` should not copy ``OtherIndexTypes``","Kona November 2023","","",""
3939
"`3987 <https://wg21.link/LWG3987>`__","Including ``<flat_foo>`` doesn't provide ``std::begin``/``end``","Kona November 2023","","","|flat_containers|"
4040
"`3990 <https://wg21.link/LWG3990>`__","Program-defined specializations of ``std::tuple`` and ``std::variant`` can't be properly supported","Kona November 2023","","",""

libcxx/include/__expected/expected.h

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -920,9 +920,9 @@ class expected : private __expected_base<_Tp, _Err> {
920920
requires is_constructible_v<_Err, _Err&>
921921
_LIBCPP_HIDE_FROM_ABI constexpr auto and_then(_Func&& __f) & {
922922
using _Up = remove_cvref_t<invoke_result_t<_Func, _Tp&>>;
923-
static_assert(__is_std_expected<_Up>::value, "The result of f(**this) must be a specialization of std::expected");
923+
static_assert(__is_std_expected<_Up>::value, "The result of f(value()) must be a specialization of std::expected");
924924
static_assert(is_same_v<typename _Up::error_type, _Err>,
925-
"The result of f(**this) must have the same error_type as this expected");
925+
"The result of f(value()) must have the same error_type as this expected");
926926
if (has_value()) {
927927
return std::invoke(std::forward<_Func>(__f), this->__val());
928928
}
@@ -933,9 +933,9 @@ class expected : private __expected_base<_Tp, _Err> {
933933
requires is_constructible_v<_Err, const _Err&>
934934
_LIBCPP_HIDE_FROM_ABI constexpr auto and_then(_Func&& __f) const& {
935935
using _Up = remove_cvref_t<invoke_result_t<_Func, const _Tp&>>;
936-
static_assert(__is_std_expected<_Up>::value, "The result of f(**this) must be a specialization of std::expected");
936+
static_assert(__is_std_expected<_Up>::value, "The result of f(value()) must be a specialization of std::expected");
937937
static_assert(is_same_v<typename _Up::error_type, _Err>,
938-
"The result of f(**this) must have the same error_type as this expected");
938+
"The result of f(value()) must have the same error_type as this expected");
939939
if (has_value()) {
940940
return std::invoke(std::forward<_Func>(__f), this->__val());
941941
}
@@ -947,9 +947,9 @@ class expected : private __expected_base<_Tp, _Err> {
947947
_LIBCPP_HIDE_FROM_ABI constexpr auto and_then(_Func&& __f) && {
948948
using _Up = remove_cvref_t<invoke_result_t<_Func, _Tp&&>>;
949949
static_assert(
950-
__is_std_expected<_Up>::value, "The result of f(std::move(**this)) must be a specialization of std::expected");
950+
__is_std_expected<_Up>::value, "The result of f(std::move(value())) must be a specialization of std::expected");
951951
static_assert(is_same_v<typename _Up::error_type, _Err>,
952-
"The result of f(std::move(**this)) must have the same error_type as this expected");
952+
"The result of f(std::move(value())) must have the same error_type as this expected");
953953
if (has_value()) {
954954
return std::invoke(std::forward<_Func>(__f), std::move(this->__val()));
955955
}
@@ -961,9 +961,9 @@ class expected : private __expected_base<_Tp, _Err> {
961961
_LIBCPP_HIDE_FROM_ABI constexpr auto and_then(_Func&& __f) const&& {
962962
using _Up = remove_cvref_t<invoke_result_t<_Func, const _Tp&&>>;
963963
static_assert(
964-
__is_std_expected<_Up>::value, "The result of f(std::move(**this)) must be a specialization of std::expected");
964+
__is_std_expected<_Up>::value, "The result of f(std::move(value())) must be a specialization of std::expected");
965965
static_assert(is_same_v<typename _Up::error_type, _Err>,
966-
"The result of f(std::move(**this)) must have the same error_type as this expected");
966+
"The result of f(std::move(value())) must have the same error_type as this expected");
967967
if (has_value()) {
968968
return std::invoke(std::forward<_Func>(__f), std::move(this->__val()));
969969
}

libcxx/test/libcxx/utilities/expected/expected.expected/and_then.mandates.verify.cpp

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -11,22 +11,22 @@
1111
// Test the mandates
1212
// template<class F> constexpr auto and_then(F&& f) &;
1313
// Mandates:
14-
// Let U be std::remove_cvref_t<std::invoke_result<F, decltype(**this)>>
14+
// Let U be std::remove_cvref_t<std::invoke_result<F, decltype(value())>>
1515
// U is a specialization of std::expected and std::is_same_v<U:error_type, E> is true
1616

1717
// template<class F> constexpr auto and_then(F&& f) const &;
1818
// Mandates:
19-
// Let U be std::remove_cvref_t<std::invoke_result<F, decltype(**this)>>
19+
// Let U be std::remove_cvref_t<std::invoke_result<F, decltype(value())>>
2020
// U is a specialization of std::expected and std::is_same_v<U:error_type, E> is true
2121

2222
// template<class F> constexpr auto and_then(F&& f) &&;
2323
// Mandates:
24-
// Let U be std::remove_cvref_t<std::invoke_result<F, decltype(**this)>>
24+
// Let U be std::remove_cvref_t<std::invoke_result<F, decltype(value())>>
2525
// U is a specialization of std::expected and std::is_same_v<U:error_type, E> is true
2626

2727
// template<class F> constexpr auto and_then(F&& f) const &&;
2828
// Mandates:
29-
// Let U be std::remove_cvref_t<std::invoke_result<F, decltype(**this)>>
29+
// Let U be std::remove_cvref_t<std::invoke_result<F, decltype(value())>>
3030
// U is a specialization of std::expected and std::is_same_v<U:error_type, E> is true
3131

3232
#include <expected>
@@ -52,7 +52,7 @@ void test() {
5252
{
5353
std::expected<int, int> f1(1);
5454
f1.and_then(lval_return_not_std_expected); // expected-note{{in instantiation of function template specialization 'std::expected<int, int>::and_then<int (&)(int &)>' requested here}}
55-
// expected-error-re@*:* {{static assertion failed {{.*}}The result of f(**this) must be a specialization of std::expected}}
55+
// expected-error-re@*:* {{static assertion failed {{.*}}The result of f(value()) must be a specialization of std::expected}}
5656
// expected-error-re@*:* {{{{.*}}cannot be used prior to '::' because it has no members}}
5757
// expected-error-re@*:* {{no matching constructor for initialization of{{.*}}}}
5858
}
@@ -61,7 +61,7 @@ void test() {
6161
{
6262
std::expected<int, int> f1(1);
6363
f1.and_then(lval_error_type_not_same_as_int); // expected-note{{in instantiation of function template specialization 'std::expected<int, int>::and_then<std::expected<int, NotSameAsInt> (&)(int &)>' requested here}}
64-
// expected-error-re@*:* {{static assertion failed {{.*}}The result of f(**this) must have the same error_type as this expected}}
64+
// expected-error-re@*:* {{static assertion failed {{.*}}The result of f(value()) must have the same error_type as this expected}}
6565
}
6666
}
6767

@@ -71,7 +71,7 @@ void test() {
7171
{
7272
const std::expected<int, int> f1(1);
7373
f1.and_then(clval_return_not_std_expected); // expected-note{{in instantiation of function template specialization 'std::expected<int, int>::and_then<int (&)(const int &)>' requested here}}
74-
// expected-error-re@*:* {{static assertion failed {{.*}}The result of f(**this) must be a specialization of std::expected}}
74+
// expected-error-re@*:* {{static assertion failed {{.*}}The result of f(value()) must be a specialization of std::expected}}
7575
// expected-error-re@*:* {{{{.*}}cannot be used prior to '::' because it has no members}}
7676
// expected-error-re@*:* {{no matching constructor for initialization of{{.*}}}}
7777
}
@@ -80,7 +80,7 @@ void test() {
8080
{
8181
const std::expected<int, int> f1(1);
8282
f1.and_then(clval_error_type_not_same_as_int); // expected-note{{in instantiation of function template specialization 'std::expected<int, int>::and_then<std::expected<int, NotSameAsInt> (&)(const int &)>' requested here}}
83-
// expected-error-re@*:* {{static assertion failed {{.*}}The result of f(**this) must have the same error_type as this expected}}
83+
// expected-error-re@*:* {{static assertion failed {{.*}}The result of f(value()) must have the same error_type as this expected}}
8484

8585
}
8686
}
@@ -91,7 +91,7 @@ void test() {
9191
{
9292
std::expected<int, int> f1(1);
9393
std::move(f1).and_then(rval_return_not_std_expected); // expected-note{{in instantiation of function template specialization 'std::expected<int, int>::and_then<int (&)(int &&)>' requested here}}
94-
// expected-error-re@*:* {{static assertion failed {{.*}}The result of f(std::move(**this)) must be a specialization of std::expected}}
94+
// expected-error-re@*:* {{static assertion failed {{.*}}The result of f(std::move(value())) must be a specialization of std::expected}}
9595
// expected-error-re@*:* {{{{.*}}cannot be used prior to '::' because it has no members}}
9696
// expected-error-re@*:* {{no matching constructor for initialization of{{.*}}}}
9797
}
@@ -100,7 +100,7 @@ void test() {
100100
{
101101
std::expected<int, int> f1(1);
102102
std::move(f1).and_then(rval_error_type_not_same_as_int); // expected-note{{in instantiation of function template specialization 'std::expected<int, int>::and_then<std::expected<int, NotSameAsInt> (&)(int &&)>' requested here}}
103-
// expected-error-re@*:* {{static assertion failed {{.*}}The result of f(std::move(**this)) must have the same error_type as this expected}}
103+
// expected-error-re@*:* {{static assertion failed {{.*}}The result of f(std::move(value())) must have the same error_type as this expected}}
104104
}
105105
}
106106

@@ -110,7 +110,7 @@ void test() {
110110
{
111111
const std::expected<int, int> f1(1);
112112
std::move(f1).and_then(crval_return_not_std_expected); // expected-note{{in instantiation of function template specialization 'std::expected<int, int>::and_then<int (&)(const int &&)>' requested here}}
113-
// expected-error-re@*:* {{static assertion failed {{.*}}The result of f(std::move(**this)) must be a specialization of std::expected}}
113+
// expected-error-re@*:* {{static assertion failed {{.*}}The result of f(std::move(value())) must be a specialization of std::expected}}
114114
// expected-error-re@*:* {{{{.*}}cannot be used prior to '::' because it has no members}}
115115
// expected-error-re@*:* {{no matching constructor for initialization of{{.*}}}}
116116
}
@@ -119,7 +119,7 @@ void test() {
119119
{
120120
const std::expected<int, int> f1(1);
121121
std::move(f1).and_then(crval_error_type_not_same_as_int); // expected-note{{in instantiation of function template specialization 'std::expected<int, int>::and_then<std::expected<int, NotSameAsInt> (&)(const int &&)>' requested here}}
122-
// expected-error-re@*:* {{static assertion failed {{.*}}The result of f(std::move(**this)) must have the same error_type as this expected}}
122+
// expected-error-re@*:* {{static assertion failed {{.*}}The result of f(std::move(value())) must have the same error_type as this expected}}
123123
}
124124
}
125125
}

0 commit comments

Comments
 (0)