[libcxx] Implement P0318: unwrap_ref_decay and unwrap_reference

Summary:
This was voted into C++20 in San Diego. Note that there was a revision
D0318R2 which did include unwrap_reference_t, but we mistakingly voted
P0318R1 into the C++20 Working Draft (which does not include
unwrap_reference_t). This patch implements D0318R2, which is what
we'll end up with in the Working Draft once this mistake has been
fixed.

Reviewers: EricWF, mclow.lists

Subscribers: christof, dexonsmith, libcxx-commits

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

llvm-svn: 348138
Cr-Mirrored-From: sso://chromium.googlesource.com/_direct/external/github.com/llvm/llvm-project
Cr-Mirrored-Commit: bb9ca6d0bfc2d2111025d8e342279163458a8639
diff --git a/include/functional b/include/functional
index 61c87b0..1bddb9f 100644
--- a/include/functional
+++ b/include/functional
@@ -68,6 +68,11 @@
 template <class T> void cref(const T&& t) = delete;
 template <class T> reference_wrapper<const T> cref(reference_wrapper<T> t) noexcept;
 
+template <class T> struct unwrap_reference;                                       // since C++20
+template <class T> struct unwrap_ref_decay : unwrap_reference<decay_t<T>> { };    // since C++20
+template <class T> using unwrap_reference_t = typename unwrap_reference<T>::type; // since C++20
+template <class T> using unwrap_ref_decay_t = typename unwrap_ref_decay<T>::type; // since C++20
+
 template <class T> // <class T=void> in C++14
 struct plus : binary_function<T, T, T>
 {
@@ -2527,6 +2532,14 @@
 
 #endif // _LIBCPP_STD_VER > 14
 
+#if _LIBCPP_STD_VER > 17
+template <class _Tp>
+using unwrap_reference_t = typename unwrap_reference<_Tp>::type;
+
+template <class _Tp>
+using unwrap_ref_decay_t = typename unwrap_ref_decay<_Tp>::type;
+#endif // > C++17
+
 _LIBCPP_END_NAMESPACE_STD
 
 #endif  // _LIBCPP_FUNCTIONAL