[libcxx-commits] [libcxx] a13c105 - [libc++] [test] Fix LWG3146 "Excessive unwrapping in std::ref/cref"
Arthur O'Dwyer via libcxx-commits
libcxx-commits at lists.llvm.org
Tue Jan 25 16:31:09 PST 2022
Author: Arthur O'Dwyer
Date: 2022-01-25T19:30:32-05:00
New Revision: a13c10588cd57bcef93f2a27a74dd7c32bc6850b
URL: https://github.com/llvm/llvm-project/commit/a13c10588cd57bcef93f2a27a74dd7c32bc6850b
DIFF: https://github.com/llvm/llvm-project/commit/a13c10588cd57bcef93f2a27a74dd7c32bc6850b.diff
LOG: [libc++] [test] Fix LWG3146 "Excessive unwrapping in std::ref/cref"
Drive-by constexprify the existing tests, too.
Differential Revision: https://reviews.llvm.org/D117953
Added:
libcxx/test/std/utilities/function.objects/refwrap/refwrap.helpers/lwg3146.pass.cpp
Modified:
libcxx/docs/Status/Cxx2bIssues.csv
libcxx/include/__functional/reference_wrapper.h
libcxx/test/std/utilities/function.objects/refwrap/refwrap.helpers/cref_1.pass.cpp
libcxx/test/std/utilities/function.objects/refwrap/refwrap.helpers/cref_2.pass.cpp
libcxx/test/std/utilities/function.objects/refwrap/refwrap.helpers/ref_1.pass.cpp
libcxx/test/std/utilities/function.objects/refwrap/refwrap.helpers/ref_2.pass.cpp
Removed:
################################################################################
diff --git a/libcxx/docs/Status/Cxx2bIssues.csv b/libcxx/docs/Status/Cxx2bIssues.csv
index 0ce504816fe3b..b151393e0a50d 100644
--- a/libcxx/docs/Status/Cxx2bIssues.csv
+++ b/libcxx/docs/Status/Cxx2bIssues.csv
@@ -102,7 +102,7 @@
`2762 <https://wg21.link/LWG2762>`__,"``unique_ptr operator*()`` should be ``noexcept``","October 2021","",""
`3121 <https://wg21.link/LWG3121>`__,"``tuple`` constructor constraints for ``UTypes&&...`` overloads","October 2021","",""
`3123 <https://wg21.link/LWG3123>`__,"``duration`` constructor from representation shouldn't be effectively non-throwing","October 2021","","","|chrono|"
-`3146 <https://wg21.link/LWG3146>`__,"Excessive unwrapping in ``std::ref/cref``","October 2021","",""
+`3146 <https://wg21.link/LWG3146>`__,"Excessive unwrapping in ``std::ref/cref``","October 2021","|Complete|","14.0"
`3152 <https://wg21.link/LWG3152>`__,"``common_type`` and ``common_reference`` have flaws in common","October 2021","",""
`3293 <https://wg21.link/LWG3293>`__,"``move_iterator operator+()`` has incorrect constraints","October 2021","","","|ranges|"
`3361 <https://wg21.link/LWG3361>`__,"``safe_range<SomeRange&>`` case","October 2021","","","|ranges|"
diff --git a/libcxx/include/__functional/reference_wrapper.h b/libcxx/include/__functional/reference_wrapper.h
index e1e4abd80c236..c5de5e5f2e8df 100644
--- a/libcxx/include/__functional/reference_wrapper.h
+++ b/libcxx/include/__functional/reference_wrapper.h
@@ -176,7 +176,7 @@ class _LIBCPP_TEMPLATE_VIS reference_wrapper
#endif // _LIBCPP_CXX03_LANG
};
-#if _LIBCPP_STD_VER >= 17
+#if _LIBCPP_STD_VER > 14
template <class _Tp>
reference_wrapper(_Tp&) -> reference_wrapper<_Tp>;
#endif
@@ -194,7 +194,7 @@ inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
reference_wrapper<_Tp>
ref(reference_wrapper<_Tp> __t) _NOEXCEPT
{
- return _VSTD::ref(__t.get());
+ return __t;
}
template <class _Tp>
@@ -210,7 +210,9 @@ inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
reference_wrapper<const _Tp>
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
index 2286d949e657f..c6bc471df2567 100644
--- 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<const int> r = std::cref(i);
+ assert(&r.get() == &i);
+ return true;
+}
+
int main(int, char**)
{
- int i = 0;
- std::reference_wrapper<const int> 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
index d76bcf9245c09..1cf369201894a 100644
--- 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 @@ namespace adl {
void cref(A) {}
}
-int main(int, char**)
+TEST_CONSTEXPR_CXX20 bool test()
{
+ {
const int i = 0;
std::reference_wrapper<const int> r1 = std::cref(i);
std::reference_wrapper<const int> r2 = std::cref(r1);
assert(&r2.get() == &i);
-
- {
+ }
+ {
adl::A a;
std::reference_wrapper<const adl::A> a1 = std::cref(a);
std::reference_wrapper<const adl::A> 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
index 0000000000000..66d254684b9c2
--- /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
+//
+//===----------------------------------------------------------------------===//
+
+// <functional>
+
+// reference_wrapper
+
+// template <ObjectType T> reference_wrapper<T> ref(reference_wrapper<T> t);
+// LWG 3146 "Excessive unwrapping in std::ref/cref"
+
+#include <functional>
+#include <cassert>
+
+#include "test_macros.h"
+
+TEST_CONSTEXPR_CXX20 bool test()
+{
+ {
+ int i = 0;
+ std::reference_wrapper<int> ri(i);
+ std::reference_wrapper<std::reference_wrapper<int> > rri(ri);
+ auto rrj = std::ref(rri);
+ ASSERT_SAME_TYPE(decltype(rrj), std::reference_wrapper<std::reference_wrapper<int> >);
+ assert(&rrj.get() == &ri);
+ }
+ {
+ int i = 0;
+ std::reference_wrapper<int> ri(i);
+ std::reference_wrapper<const std::reference_wrapper<int> > rri(ri);
+ auto rrj = std::ref(rri);
+ ASSERT_SAME_TYPE(decltype(rrj), std::reference_wrapper<const std::reference_wrapper<int> >);
+ assert(&rrj.get() == &ri);
+ }
+ {
+ int i = 0;
+ std::reference_wrapper<int> ri(i);
+ std::reference_wrapper<std::reference_wrapper<int> > rri(ri);
+ auto rrj = std::cref(rri);
+ ASSERT_SAME_TYPE(decltype(rrj), std::reference_wrapper<const std::reference_wrapper<int> >);
+ assert(&rrj.get() == &ri);
+ }
+ {
+ int i = 0;
+ std::reference_wrapper<int> ri(i);
+ std::reference_wrapper<const std::reference_wrapper<int> > rri(ri);
+ auto rrj = std::cref(rri);
+ ASSERT_SAME_TYPE(decltype(rrj), std::reference_wrapper<const std::reference_wrapper<int> >);
+ 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
index 41614d3b2e2a1..8424fcd52096a 100644
--- 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<int> r = std::ref(i);
+ assert(&r.get() == &i);
+ return true;
+}
+
int main(int, char**)
{
- int i = 0;
- std::reference_wrapper<int> 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
index 9ab62a20a8731..97689fc53837c 100644
--- 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 <ObjectType T> reference_wrapper<T> ref(reference_wrapper<T>t);
+// template <ObjectType T> reference_wrapper<T> ref(reference_wrapper<T> t);
#include <functional>
#include <cassert>
@@ -29,22 +29,31 @@ namespace adl {
void ref(A) {}
}
-int main(int, char**)
+TEST_CONSTEXPR_CXX20 bool test()
{
- {
+ {
int i = 0;
std::reference_wrapper<int> r1 = std::ref(i);
std::reference_wrapper<int> r2 = std::ref(r1);
assert(&r2.get() == &i);
- }
- {
+ }
+ {
adl::A a;
std::reference_wrapper<adl::A> a1 = std::ref(a);
std::reference_wrapper<adl::A> 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<bool(*)(int), int> cp(is5);
assert(!cp(6));
assert(cp.count() == 1);
@@ -52,7 +61,7 @@ int main(int, char**)
assert(cp.count() == 1);
assert(call_pred(std::ref(cp)));
assert(cp.count() == 2);
- }
+ }
return 0;
}
More information about the libcxx-commits
mailing list