K-ballo updated this revision to Diff 123813.
K-ballo added a comment.

Full context diff.


https://reviews.llvm.org/D40259

Files:
  include/__functional_base
  include/functional
  
test/std/utilities/function.objects/refwrap/refwrap.assign/copy_assign.pass.cpp
  
test/std/utilities/function.objects/refwrap/refwrap.const/type_conv_ctor.fail.cpp
  
test/std/utilities/function.objects/refwrap/refwrap.const/type_conv_ctor.pass.cpp
  test/std/utilities/function.objects/refwrap/refwrap.const/type_ctor.pass.cpp

Index: test/std/utilities/function.objects/refwrap/refwrap.const/type_ctor.pass.cpp
===================================================================
--- test/std/utilities/function.objects/refwrap/refwrap.const/type_ctor.pass.cpp
+++ test/std/utilities/function.objects/refwrap/refwrap.const/type_ctor.pass.cpp
@@ -15,6 +15,7 @@
 
 #include <functional>
 #include <cassert>
+#include <type_traits>
 
 class functor1
 {
@@ -41,4 +42,19 @@
     test(i);
     const int j = 0;
     test(j);
+
+    {
+    using Ref = std::reference_wrapper<int>;
+    static_assert((std::is_constructible<Ref, int&>::value), "");
+    static_assert((!std::is_constructible<Ref, int>::value), "");
+    static_assert((!std::is_constructible<Ref, int&&>::value), "");
+    }
+
+#if TEST_STD_VER >= 11
+    {
+    using Ref = std::reference_wrapper<int>;
+    static_assert((std::is_nothrow_constructible<Ref, int&>::value), "");
+    static_assert((!std::is_nothrow_constructible<Ref, int>::value), "");
+    }
+#endif
 }
Index: test/std/utilities/function.objects/refwrap/refwrap.const/type_conv_ctor.pass.cpp
===================================================================
--- /dev/null
+++ test/std/utilities/function.objects/refwrap/refwrap.const/type_conv_ctor.pass.cpp
@@ -0,0 +1,82 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <functional>
+
+// reference_wrapper
+
+// template <class U>
+//   reference_wrapper(U&&) noexcept(see below);
+
+// XFAIL: c++98, c++03
+
+#include <functional>
+#include <cassert>
+
+struct convertible_to_int_ref {
+    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; }
+};
+
+struct convertible_from_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()
+{
+    convertible_to_int_ref convi;
+    test(convi);
+    convertible_to_int_ref const convic;
+    test(convic);
+
+    {
+    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), "");
+    }
+
+    {
+    meow(0);
+    (true) ? purr() : 0;
+    }
+
+#ifdef __cpp_deduction_guides
+    {
+    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
+}
Index: test/std/utilities/function.objects/refwrap/refwrap.const/type_conv_ctor.fail.cpp
===================================================================
--- /dev/null
+++ test/std/utilities/function.objects/refwrap/refwrap.const/type_conv_ctor.fail.cpp
@@ -0,0 +1,31 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <functional>
+
+// reference_wrapper
+
+// template <class U>
+//   reference_wrapper(U&&) noexcept(see below);
+
+// XFAIL: c++98, c++03
+
+#include <functional>
+#include <cassert>
+
+struct convertible_to_float_ref {
+    float val = 0;
+    operator float const&() const { return val; }
+};
+
+int main()
+{
+    convertible_to_float_ref convf;
+    std::reference_wrapper<const int> r(convf);
+}
Index: test/std/utilities/function.objects/refwrap/refwrap.assign/copy_assign.pass.cpp
===================================================================
--- test/std/utilities/function.objects/refwrap/refwrap.assign/copy_assign.pass.cpp
+++ test/std/utilities/function.objects/refwrap/refwrap.assign/copy_assign.pass.cpp
@@ -15,11 +15,18 @@
 
 #include <functional>
 #include <cassert>
+#include <type_traits>
 
 class functor1
 {
 };
 
+struct convertible_to_int_ref {
+    int val = 0;
+    operator int&() { return val; }
+    operator int const&() const { return val; }
+};
+
 template <class T>
 void
 test(T& t)
@@ -54,4 +61,18 @@
     test(i);
     const int j = 0;
     test(j);
+
+#if TEST_STD_VER >= 11
+    convertible_to_int_ref convi;
+    test(convi);
+    convertible_to_int_ref const convic;
+    test(convic);
+
+    {
+    using Ref = std::reference_wrapper<int>;
+    static_assert((std::is_assignable<Ref&, int&>::value), "");
+    static_assert((!std::is_assignable<Ref&, int>::value), "");
+    static_assert((!std::is_assignable<Ref&, int&&>::value), "");
+    }
+#endif
 }
Index: include/functional
===================================================================
--- include/functional
+++ include/functional
@@ -43,8 +43,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&&) noexcept(see below);
     reference_wrapper(const reference_wrapper<T>& x) noexcept;
 
     // assignment
@@ -60,6 +60,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;
Index: include/__functional_base
===================================================================
--- include/__functional_base
+++ include/__functional_base
@@ -381,12 +381,24 @@
 private:
     type* __f_;
 
+    static _LIBCPP_INLINE_VISIBILITY
+    _Tp& __bind(_Tp& r) _NOEXCEPT { return r; }
+
+#ifndef _LIBCPP_CXX03_LANG
+    static _Tp& __bind(_Tp&& r) = delete;
+#endif
+
 public:
     // construct/copy/destroy
+#ifndef _LIBCPP_CXX03_LANG
+    template <class _Up, class = typename enable_if<
+        !is_same<__uncvref_t<_Up>, reference_wrapper>::value
+    >::type, bool _IsNothrow = noexcept(__bind(_VSTD::declval<_Up>()))>
+    _LIBCPP_INLINE_VISIBILITY reference_wrapper(_Up&& __u) _NOEXCEPT_(_IsNothrow)
+        : __f_(_VSTD::addressof(__bind(_VSTD::forward<_Up>(__u)))) {}
+#else
     _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
 #endif
 
     // access
@@ -509,6 +521,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
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to