"`2981 <https://wg21.link/LWG2981>`__","Remove redundant deduction guides from standard library","Albuquerque","",""
"`2982 <https://wg21.link/LWG2982>`__","Making size_type consistent in associative container deduction guides","Albuquerque","",""
"`2988 <https://wg21.link/LWG2988>`__","Clause 32 cleanup missed one typename","Albuquerque","",""
-"`2993 <https://wg21.link/LWG2993>`__","reference_wrapper<T> conversion from T&&","Albuquerque","",""
+"`2993 <https://wg21.link/LWG2993>`__","reference_wrapper<T> conversion from T&&","Albuquerque","|Complete|","13.0"
"`2998 <https://wg21.link/LWG2998>`__","Requirements on function objects passed to {``forward_``,}list-specific algorithms","Albuquerque","|Nothing To Do|",""
"`3001 <https://wg21.link/LWG3001>`__","weak_ptr::element_type needs remove_extent_t","Albuquerque","",""
"`3024 <https://wg21.link/LWG3024>`__","variant's copies must be deleted instead of disabled via SFINAE","Albuquerque","|Complete|",""
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
#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
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
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;
{
};
+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)
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
+
return 0;
}
--- /dev/null
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14
+// UNSUPPORTED: libcpp-no-deduction-guides
+
+// <functional>
+
+// template <class T>
+// reference_wrapper(T&) -> reference_wrapper<T>;
+
+#include <functional>
+
+int main()
+{
+ int i = 0;
+ std::reference_wrapper ri(i);
+ static_assert(std::is_same_v<decltype(ri), std::reference_wrapper<int>>);
+ std::reference_wrapper ri2(ri);
+ static_assert(std::is_same_v<decltype(ri2), std::reference_wrapper<int>>);
+ const int j = 0;
+ std::reference_wrapper rj(j);
+ static_assert(std::is_same_v<decltype(rj), std::reference_wrapper<const int>>);
+ std::reference_wrapper rj2(rj);
+ static_assert(std::is_same_v<decltype(rj2), std::reference_wrapper<const int>>);
+}
--- /dev/null
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03
+
+// <functional>
+//
+// reference_wrapper
+//
+// template <class U>
+// reference_wrapper(U&&) noexcept(see below);
+
+#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
+}
--- /dev/null
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03
+
+// <functional>
+//
+// reference_wrapper
+//
+// template <class U>
+// reference_wrapper(U&&);
+
+#include <functional>
+#include <cassert>
+
+struct B {} b;
+
+struct A1 {
+ operator B& () const { return b; }
+};
+struct A2 {
+ operator B& () const noexcept { return b; }
+};
+
+int main()
+{
+ {
+ std::reference_wrapper<B> b1 = A1();
+ assert(&b1.get() == &b);
+ b1 = A1();
+ assert(&b1.get() == &b);
+
+ 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);
+
+ 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>>);
+#endif
+ static_assert(std::is_assignable<std::reference_wrapper<B>, A2>::value, "");
+ static_assert(std::is_nothrow_assignable<std::reference_wrapper<B>, A2>::value, "");
+ }
+}
#include <functional>
#include <cassert>
+#include <type_traits>
#include "test_macros.h"
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), "");
+ static_assert((!std::is_nothrow_constructible<Ref, int&&>::value), "");
+ }
+#endif
+
return 0;
}