diff --git a/libcxx/docs/Status/Cxx2bIssues.csv b/libcxx/docs/Status/Cxx2bIssues.csv --- a/libcxx/docs/Status/Cxx2bIssues.csv +++ b/libcxx/docs/Status/Cxx2bIssues.csv @@ -102,7 +102,7 @@ `2762 `__,"``unique_ptr operator*()`` should be ``noexcept``","October 2021","","" `3121 `__,"``tuple`` constructor constraints for ``UTypes&&...`` overloads","October 2021","","" `3123 `__,"``duration`` constructor from representation shouldn't be effectively non-throwing","October 2021","","","|chrono|" -`3146 `__,"Excessive unwrapping in ``std::ref/cref``","October 2021","","" +`3146 `__,"Excessive unwrapping in ``std::ref/cref``","October 2021","|Complete|","14.0" `3152 `__,"``common_type`` and ``common_reference`` have flaws in common","October 2021","","" `3293 `__,"``move_iterator operator+()`` has incorrect constraints","October 2021","","","|ranges|" `3361 `__,"``safe_range`` case","October 2021","","","|ranges|" diff --git a/libcxx/include/__functional/reference_wrapper.h b/libcxx/include/__functional/reference_wrapper.h --- a/libcxx/include/__functional/reference_wrapper.h +++ b/libcxx/include/__functional/reference_wrapper.h @@ -176,7 +176,7 @@ #endif // _LIBCPP_CXX03_LANG }; -#if _LIBCPP_STD_VER >= 17 +#if _LIBCPP_STD_VER > 14 template reference_wrapper(_Tp&) -> reference_wrapper<_Tp>; #endif @@ -194,7 +194,7 @@ reference_wrapper<_Tp> ref(reference_wrapper<_Tp> __t) _NOEXCEPT { - return _VSTD::ref(__t.get()); + return __t; } template @@ -210,7 +210,9 @@ reference_wrapper cref(reference_wrapper<_Tp> __t) _NOEXCEPT { - return _VSTD::cref(__t.get()); + // C++20 says "return __t", but C++03 lacks the relevant + // converting constructor. This should be equivalent. + return __t.get(); } #ifndef _LIBCPP_CXX03_LANG diff --git a/libcxx/test/std/utilities/function.objects/refwrap/refwrap.helpers/cref_1.pass.cpp b/libcxx/test/std/utilities/function.objects/refwrap/refwrap.helpers/cref_1.pass.cpp --- a/libcxx/test/std/utilities/function.objects/refwrap/refwrap.helpers/cref_1.pass.cpp +++ b/libcxx/test/std/utilities/function.objects/refwrap/refwrap.helpers/cref_1.pass.cpp @@ -17,11 +17,20 @@ #include "test_macros.h" +TEST_CONSTEXPR_CXX20 bool test() +{ + int i = 0; + std::reference_wrapper r = std::cref(i); + assert(&r.get() == &i); + return true; +} + int main(int, char**) { - int i = 0; - std::reference_wrapper r = std::cref(i); - assert(&r.get() == &i); + test(); +#if TEST_STD_VER > 17 + static_assert(test()); +#endif return 0; } diff --git a/libcxx/test/std/utilities/function.objects/refwrap/refwrap.helpers/cref_2.pass.cpp b/libcxx/test/std/utilities/function.objects/refwrap/refwrap.helpers/cref_2.pass.cpp --- a/libcxx/test/std/utilities/function.objects/refwrap/refwrap.helpers/cref_2.pass.cpp +++ b/libcxx/test/std/utilities/function.objects/refwrap/refwrap.helpers/cref_2.pass.cpp @@ -22,19 +22,29 @@ void cref(A) {} } -int main(int, char**) +TEST_CONSTEXPR_CXX20 bool test() { + { const int i = 0; std::reference_wrapper r1 = std::cref(i); std::reference_wrapper r2 = std::cref(r1); assert(&r2.get() == &i); - - { + } + { adl::A a; std::reference_wrapper a1 = std::cref(a); std::reference_wrapper a2 = std::cref(a1); assert(&a2.get() == &a); - } + } + return true; +} + +int main(int, char**) +{ + test(); +#if TEST_STD_VER > 17 + static_assert(test()); +#endif return 0; } diff --git a/libcxx/test/std/utilities/function.objects/refwrap/refwrap.helpers/lwg3146.pass.cpp b/libcxx/test/std/utilities/function.objects/refwrap/refwrap.helpers/lwg3146.pass.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/std/utilities/function.objects/refwrap/refwrap.helpers/lwg3146.pass.cpp @@ -0,0 +1,66 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// + +// reference_wrapper + +// template reference_wrapper ref(reference_wrapper t); +// LWG 3146 "Excessive unwrapping in std::ref/cref" + +#include +#include + +#include "test_macros.h" + +TEST_CONSTEXPR_CXX20 bool test() +{ + { + int i = 0; + std::reference_wrapper ri(i); + std::reference_wrapper > rri(ri); + auto rrj = std::ref(rri); + ASSERT_SAME_TYPE(decltype(rrj), std::reference_wrapper >); + assert(&rrj.get() == &ri); + } + { + int i = 0; + std::reference_wrapper ri(i); + std::reference_wrapper > rri(ri); + auto rrj = std::ref(rri); + ASSERT_SAME_TYPE(decltype(rrj), std::reference_wrapper >); + assert(&rrj.get() == &ri); + } + { + int i = 0; + std::reference_wrapper ri(i); + std::reference_wrapper > rri(ri); + auto rrj = std::cref(rri); + ASSERT_SAME_TYPE(decltype(rrj), std::reference_wrapper >); + assert(&rrj.get() == &ri); + } + { + int i = 0; + std::reference_wrapper ri(i); + std::reference_wrapper > rri(ri); + auto rrj = std::cref(rri); + ASSERT_SAME_TYPE(decltype(rrj), std::reference_wrapper >); + assert(&rrj.get() == &ri); + } + return true; +} + +int main(int, char**) +{ + test(); +#if TEST_STD_VER > 17 + static_assert(test()); +#endif + + return 0; +} diff --git a/libcxx/test/std/utilities/function.objects/refwrap/refwrap.helpers/ref_1.pass.cpp b/libcxx/test/std/utilities/function.objects/refwrap/refwrap.helpers/ref_1.pass.cpp --- a/libcxx/test/std/utilities/function.objects/refwrap/refwrap.helpers/ref_1.pass.cpp +++ b/libcxx/test/std/utilities/function.objects/refwrap/refwrap.helpers/ref_1.pass.cpp @@ -17,11 +17,20 @@ #include "test_macros.h" +TEST_CONSTEXPR_CXX20 bool test() +{ + int i = 0; + std::reference_wrapper r = std::ref(i); + assert(&r.get() == &i); + return true; +} + int main(int, char**) { - int i = 0; - std::reference_wrapper r = std::ref(i); - assert(&r.get() == &i); + test(); +#if TEST_STD_VER > 17 + static_assert(test()); +#endif return 0; } diff --git a/libcxx/test/std/utilities/function.objects/refwrap/refwrap.helpers/ref_2.pass.cpp b/libcxx/test/std/utilities/function.objects/refwrap/refwrap.helpers/ref_2.pass.cpp --- a/libcxx/test/std/utilities/function.objects/refwrap/refwrap.helpers/ref_2.pass.cpp +++ b/libcxx/test/std/utilities/function.objects/refwrap/refwrap.helpers/ref_2.pass.cpp @@ -10,7 +10,7 @@ // reference_wrapper -// template reference_wrapper ref(reference_wrappert); +// template reference_wrapper ref(reference_wrapper t); #include #include @@ -29,22 +29,31 @@ void ref(A) {} } -int main(int, char**) +TEST_CONSTEXPR_CXX20 bool test() { - { + { int i = 0; std::reference_wrapper r1 = std::ref(i); std::reference_wrapper r2 = std::ref(r1); assert(&r2.get() == &i); - } - { + } + { adl::A a; std::reference_wrapper a1 = std::ref(a); std::reference_wrapper a2 = std::ref(a1); assert(&a2.get() == &a); - } + } + return true; +} + +int main(int, char**) +{ + test(); +#if TEST_STD_VER > 17 + static_assert(test()); +#endif - { + { unary_counting_predicate cp(is5); assert(!cp(6)); assert(cp.count() == 1); @@ -52,7 +61,7 @@ assert(cp.count() == 1); assert(call_pred(std::ref(cp))); assert(cp.count() == 2); - } + } return 0; }