[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