[libc++] [LWG2993] reference_wrapper<T> conversion from U&&

Implement the resolution of LWG2993. Replace a deleted constructor
with a constructor that SFINAEs away in appropriate circumstances.
Also, now that the constructor is templated, we must have an
explicit deduction guide to make CTAD work.

Some tests have been merged in from Agustín Bergé's D40259.

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

GitOrigin-RevId: eec04092d67b94f47439a9065b6bd4cd60165be2
diff --git a/include/__functional_base b/include/__functional_base
index 1c02e96..caa7460 100644
--- a/include/__functional_base
+++ b/include/__functional_base
@@ -380,13 +380,24 @@
 private:
     type* __f_;
 
+#ifndef _LIBCPP_CXX03_LANG
+    static void __fun(_Tp&) _NOEXCEPT;
+    static void __fun(_Tp&&) = delete;
+#endif
+
 public:
     // construct/copy/destroy
-    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
+#ifdef _LIBCPP_CXX03_LANG
+    _LIBCPP_INLINE_VISIBILITY
     reference_wrapper(type& __f) _NOEXCEPT
         : __f_(_VSTD::addressof(__f)) {}
-#ifndef _LIBCPP_CXX03_LANG
-    private: reference_wrapper(type&&); public: // = delete; // do not bind to temps
+#else
+    template <class _Up, class = _EnableIf<!__is_same_uncvref<_Up, reference_wrapper>::value, decltype(__fun(_VSTD::declval<_Up>())) >>
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
+    reference_wrapper(_Up&& __u) _NOEXCEPT_(noexcept(__fun(_VSTD::declval<_Up>()))) {
+        type& __f = static_cast<_Up&&>(__u);
+        __f_ = _VSTD::addressof(__f);
+    }
 #endif
 
     // access
@@ -511,6 +522,10 @@
 #endif // _LIBCPP_CXX03_LANG
 };
 
+#ifndef _LIBCPP_HAS_NO_DEDUCTION_GUIDES
+template <class _Tp>
+reference_wrapper(_Tp&) -> reference_wrapper<_Tp>;
+#endif
 
 template <class _Tp>
 inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
diff --git a/include/functional b/include/functional
index 67baa5b..f8565e7 100644
--- a/include/functional
+++ b/include/functional
@@ -42,8 +42,8 @@
     typedef see below result_type; // Not always defined
 
     // construct/copy/destroy
-    reference_wrapper(T&) noexcept;
-    reference_wrapper(T&&) = delete; // do not bind to temps
+    template<class U>
+      reference_wrapper(U&&);
     reference_wrapper(const reference_wrapper<T>& x) noexcept;
 
     // assignment
@@ -59,6 +59,9 @@
           operator() (ArgTypes&&...) const;
 };
 
+template <class T>
+  reference_wrapper(T&) -> reference_wrapper<T>;
+
 template <class T> reference_wrapper<T> ref(T& t) noexcept;
 template <class T> void ref(const T&& t) = delete;
 template <class T> reference_wrapper<T> ref(reference_wrapper<T>t) noexcept;