[libcxx-commits] [libcxx] c99a585 - [libc++] Make C++03 reference_wrapper more like C++11.

Arthur O'Dwyer via libcxx-commits libcxx-commits at lists.llvm.org
Wed Jan 26 16:37:46 PST 2022


Author: Arthur O'Dwyer
Date: 2022-01-26T19:34:03-05:00
New Revision: c99a585399381dd7d7391d2d93e9a2cbdf59d955

URL: https://github.com/llvm/llvm-project/commit/c99a585399381dd7d7391d2d93e9a2cbdf59d955
DIFF: https://github.com/llvm/llvm-project/commit/c99a585399381dd7d7391d2d93e9a2cbdf59d955.diff

LOG: [libc++] Make C++03 reference_wrapper more like C++11.

Remove a bunch of LIBCPP_CXX03_LANG. This is the result of a
rabbithole to re-eliminate the workaround I introduced into
std::cref in D117953. It turns out that Clang's C++03 mode
(the only compiler we care about C++03 for) now supports all
the things we were originally eschewing via LIBCPP_CXX03_LANG;
we can fully support these reference_wrapper features in
C++03 mode, and un-XFAIL the relevant tests.

Drive-by constexprify a few more tests.

Differential Revision: https://reviews.llvm.org/D117974

Added: 
    

Modified: 
    libcxx/include/__functional/reference_wrapper.h
    libcxx/test/std/utilities/function.objects/refwrap/refwrap.const/type_conv_ctor.pass.cpp
    libcxx/test/std/utilities/function.objects/refwrap/refwrap.const/type_conv_ctor2.pass.cpp
    libcxx/test/std/utilities/function.objects/refwrap/refwrap.const/type_ctor.compile.fail.cpp
    libcxx/test/std/utilities/function.objects/refwrap/refwrap.helpers/ref_1.compile.fail.cpp

Removed: 
    


################################################################################
diff  --git a/libcxx/include/__functional/reference_wrapper.h b/libcxx/include/__functional/reference_wrapper.h
index c5de5e5f2e8df..d04d51568beb3 100644
--- a/libcxx/include/__functional/reference_wrapper.h
+++ b/libcxx/include/__functional/reference_wrapper.h
@@ -34,25 +34,16 @@ class _LIBCPP_TEMPLATE_VIS reference_wrapper
 private:
     type* __f_;
 
-#ifndef _LIBCPP_CXX03_LANG
     static void __fun(_Tp&) _NOEXCEPT;
     static void __fun(_Tp&&) = delete;
-#endif
 
 public:
-    // construct/copy/destroy
-#ifdef _LIBCPP_CXX03_LANG
-    _LIBCPP_INLINE_VISIBILITY
-    reference_wrapper(type& __f) _NOEXCEPT
-        : __f_(_VSTD::addressof(__f)) {}
-#else
-    template <class _Up, class = __enable_if_t<!__is_same_uncvref<_Up, reference_wrapper>::value, decltype(__fun(declval<_Up>())) >>
+    template <class _Up, class = __enable_if_t<!__is_same_uncvref<_Up, reference_wrapper>::value, decltype(__fun(declval<_Up>())) > >
     _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
     reference_wrapper(_Up&& __u) _NOEXCEPT_(noexcept(__fun(declval<_Up>()))) {
         type& __f = static_cast<_Up&&>(__u);
         __f_ = _VSTD::addressof(__f);
     }
-#endif
 
     // access
     _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
@@ -210,15 +201,11 @@ inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
 reference_wrapper<const _Tp>
 cref(reference_wrapper<_Tp> __t) _NOEXCEPT
 {
-    // C++20 says "return __t", but C++03 lacks the relevant
-    // converting constructor. This should be equivalent.
-    return __t.get();
+    return __t;
 }
 
-#ifndef _LIBCPP_CXX03_LANG
 template <class _Tp> void ref(const _Tp&&) = delete;
 template <class _Tp> void cref(const _Tp&&) = delete;
-#endif
 
 _LIBCPP_END_NAMESPACE_STD
 

diff  --git a/libcxx/test/std/utilities/function.objects/refwrap/refwrap.const/type_conv_ctor.pass.cpp b/libcxx/test/std/utilities/function.objects/refwrap/refwrap.const/type_conv_ctor.pass.cpp
index be9261a5c55c2..2759b921fabe0 100644
--- a/libcxx/test/std/utilities/function.objects/refwrap/refwrap.const/type_conv_ctor.pass.cpp
+++ b/libcxx/test/std/utilities/function.objects/refwrap/refwrap.const/type_conv_ctor.pass.cpp
@@ -6,8 +6,6 @@
 //
 //===----------------------------------------------------------------------===//
 
-// UNSUPPORTED: c++03
-
 // <functional>
 //
 // reference_wrapper
@@ -21,65 +19,58 @@
 #include "test_macros.h"
 
 struct convertible_to_int_ref {
-    int val = 0;
-    operator int&() { return val; }
-    operator int const&() const { return val; }
+  int val = 0;
+  operator int&() { return val; }
+  operator int const&() const { return val; }
 };
 
 template <bool IsNothrow>
 struct nothrow_convertible {
-    int val = 0;
-    operator int&() noexcept(IsNothrow) { return val; }
+  int val = 0;
+  operator int&() TEST_NOEXCEPT_COND(IsNothrow) { return val; }
 };
 
 struct convertible_from_int {
-    convertible_from_int(int) {}
+  convertible_from_int(int) {}
 };
 
 void meow(std::reference_wrapper<int>) {}
 void meow(convertible_from_int) {}
 
-int gi;
-std::reference_wrapper<int> purr() { return gi; };
-
-template <class T>
-void
-test(T& t)
-{
-    std::reference_wrapper<T> r(t);
-    assert(&r.get() == &t);
-}
-
-void f() {}
-
 int main(int, char**)
 {
-    convertible_to_int_ref convi;
-    test(convi);
-    convertible_to_int_ref const convic;
-    test(convic);
-
-    {
+  {
+    convertible_to_int_ref t;
+    std::reference_wrapper<convertible_to_int_ref> r(t);
+    assert(&r.get() == &t);
+  }
+  {
+    const convertible_to_int_ref t;
+    std::reference_wrapper<const convertible_to_int_ref> r(t);
+    assert(&r.get() == &t);
+  }
+  {
     using Ref = std::reference_wrapper<int>;
-    static_assert((std::is_nothrow_constructible<Ref, nothrow_convertible<true>>::value), "");
-    static_assert((!std::is_nothrow_constructible<Ref, nothrow_convertible<false>>::value), "");
-    }
-
-    {
+    ASSERT_NOEXCEPT(Ref(nothrow_convertible<true>()));
+    ASSERT_NOT_NOEXCEPT(Ref(nothrow_convertible<false>()));
+  }
+  {
     meow(0);
-    (true) ? purr() : 0;
-    }
-
-#if TEST_STD_VER >= 17
-    {
+  }
+  {
+    extern std::reference_wrapper<int> purr();
+    ASSERT_SAME_TYPE(decltype(true ? purr() : 0), int);
+  }
+#if TEST_STD_VER > 14
+  {
     int i = 0;
     std::reference_wrapper ri(i);
     static_assert((std::is_same<decltype(ri), std::reference_wrapper<int>>::value), "" );
     const int j = 0;
     std::reference_wrapper rj(j);
     static_assert((std::is_same<decltype(rj), std::reference_wrapper<const int>>::value), "" );
-    }
+  }
 #endif
 
-    return 0;
+  return 0;
 }

diff  --git a/libcxx/test/std/utilities/function.objects/refwrap/refwrap.const/type_conv_ctor2.pass.cpp b/libcxx/test/std/utilities/function.objects/refwrap/refwrap.const/type_conv_ctor2.pass.cpp
index 30d7cdb4a38b4..0ef87ade87c9d 100644
--- a/libcxx/test/std/utilities/function.objects/refwrap/refwrap.const/type_conv_ctor2.pass.cpp
+++ b/libcxx/test/std/utilities/function.objects/refwrap/refwrap.const/type_conv_ctor2.pass.cpp
@@ -6,8 +6,6 @@
 //
 //===----------------------------------------------------------------------===//
 
-// UNSUPPORTED: c++03
-
 // <functional>
 //
 // reference_wrapper
@@ -20,46 +18,48 @@
 
 #include "test_macros.h"
 
-struct B {} b;
+struct B {};
 
 struct A1 {
-    operator B& () const { return b; }
+  mutable B b_;
+  TEST_CONSTEXPR operator B&() const { return b_; }
 };
+
 struct A2 {
-    operator B& () const noexcept { return b; }
+  mutable B b_;
+  TEST_CONSTEXPR operator B&() const TEST_NOEXCEPT { return b_; }
 };
 
-int main(int, char**)
-{
-    {
-    std::reference_wrapper<B> b1 = A1();
-    assert(&b1.get() == &b);
-    b1 = A1();
-    assert(&b1.get() == &b);
+void implicitly_convert(std::reference_wrapper<B>) TEST_NOEXCEPT;
 
-    static_assert(std::is_convertible<A1, std::reference_wrapper<B>>::value, "");
-    static_assert(!std::is_nothrow_constructible<std::reference_wrapper<B>, A1>::value, "");
-#if TEST_STD_VER >= 20
-    static_assert(!std::is_nothrow_convertible_v<A1, std::reference_wrapper<B>>);
-#endif
-    static_assert(std::is_assignable<std::reference_wrapper<B>, A1>::value, "");
-    static_assert(!std::is_nothrow_assignable<std::reference_wrapper<B>, A1>::value, "");
-    }
-
-    {
-    std::reference_wrapper<B> b2 = A2();
-    assert(&b2.get() == &b);
-    b2 = A2();
-    assert(&b2.get() == &b);
+TEST_CONSTEXPR_CXX20 bool test()
+{
+  {
+    A1 a;
+    ASSERT_NOT_NOEXCEPT(implicitly_convert(a));
+    std::reference_wrapper<B> b1 = a;
+    assert(&b1.get() == &a.b_);
+    ASSERT_NOT_NOEXCEPT(b1 = a);
+    b1 = a;
+    assert(&b1.get() == &a.b_);
+  }
+  {
+    A2 a;
+    ASSERT_NOEXCEPT(implicitly_convert(a));
+    std::reference_wrapper<B> b2 = a;
+    assert(&b2.get() == &a.b_);
+    ASSERT_NOEXCEPT(b2 = a);
+    b2 = a;
+    assert(&b2.get() == &a.b_);
+  }
+  return true;
+}
 
-    static_assert(std::is_convertible<A2, std::reference_wrapper<B>>::value, "");
-    static_assert(std::is_nothrow_constructible<std::reference_wrapper<B>, A2>::value, "");
-#if TEST_STD_VER >= 20
-    static_assert(std::is_nothrow_convertible_v<A2, std::reference_wrapper<B>>);
+int main(int, char**) {
+  test();
+#if TEST_STD_VER > 17
+  static_assert(test());
 #endif
-    static_assert(std::is_assignable<std::reference_wrapper<B>, A2>::value, "");
-    static_assert(std::is_nothrow_assignable<std::reference_wrapper<B>, A2>::value, "");
-    }
 
-    return 0;
+  return 0;
 }

diff  --git a/libcxx/test/std/utilities/function.objects/refwrap/refwrap.const/type_ctor.compile.fail.cpp b/libcxx/test/std/utilities/function.objects/refwrap/refwrap.const/type_ctor.compile.fail.cpp
index c067dd942a542..b9792105046d5 100644
--- a/libcxx/test/std/utilities/function.objects/refwrap/refwrap.const/type_ctor.compile.fail.cpp
+++ b/libcxx/test/std/utilities/function.objects/refwrap/refwrap.const/type_ctor.compile.fail.cpp
@@ -12,8 +12,6 @@
 
 // reference_wrapper(T&&) = delete;
 
-// XFAIL: c++03
-
 #include <functional>
 #include <cassert>
 

diff  --git a/libcxx/test/std/utilities/function.objects/refwrap/refwrap.helpers/ref_1.compile.fail.cpp b/libcxx/test/std/utilities/function.objects/refwrap/refwrap.helpers/ref_1.compile.fail.cpp
index 9f45b94e828f8..3721b9bd47f87 100644
--- a/libcxx/test/std/utilities/function.objects/refwrap/refwrap.helpers/ref_1.compile.fail.cpp
+++ b/libcxx/test/std/utilities/function.objects/refwrap/refwrap.helpers/ref_1.compile.fail.cpp
@@ -14,8 +14,6 @@
 
 // Don't allow binding to a temp
 
-// XFAIL: c++03
-
 #include <functional>
 
 struct A {};


        


More information about the libcxx-commits mailing list