diff options
| author | Louis Dionne <ldionne@apple.com> | 2018-12-03 14:03:27 +0000 |
|---|---|---|
| committer | Louis Dionne <ldionne@apple.com> | 2018-12-03 14:03:27 +0000 |
| commit | bb9ca6d0bfc2d2111025d8e342279163458a8639 (patch) | |
| tree | de9d6f83bc4205763d4f8e00c0c5f8a3d7638f12 | |
| parent | a17f855698d91c28a6e8d05b19f3638e256d911e (diff) | |
| download | bcm5719-llvm-bb9ca6d0bfc2d2111025d8e342279163458a8639.tar.gz bcm5719-llvm-bb9ca6d0bfc2d2111025d8e342279163458a8639.zip | |
[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
| -rw-r--r-- | libcxx/include/functional | 13 | ||||
| -rw-r--r-- | libcxx/include/tuple | 22 | ||||
| -rw-r--r-- | libcxx/include/utility | 35 | ||||
| -rw-r--r-- | libcxx/test/std/utilities/function.objects/refwrap/unwrap_ref_decay.pass.cpp | 58 | ||||
| -rw-r--r-- | libcxx/test/std/utilities/function.objects/refwrap/unwrap_reference.pass.cpp | 51 | ||||
| -rw-r--r-- | libcxx/www/cxx2a_status.html | 2 |
6 files changed, 145 insertions, 36 deletions
diff --git a/libcxx/include/functional b/libcxx/include/functional index 61c87b02c70..1bddb9fadf4 100644 --- a/libcxx/include/functional +++ b/libcxx/include/functional @@ -68,6 +68,11 @@ template <class T> reference_wrapper<const T> cref(const T& t) noexcept; 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 @@ private: #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 diff --git a/libcxx/include/tuple b/libcxx/include/tuple index 766f2e3c49b..2e54a5f6664 100644 --- a/libcxx/include/tuple +++ b/libcxx/include/tuple @@ -1078,30 +1078,12 @@ namespace { _LIBCPP_INLINE_VAR constexpr __ignore_t<unsigned char> ignore = __ignore_t<unsigned char>(); } -template <class _Tp> -struct __make_tuple_return_impl -{ - typedef _Tp type; -}; - -template <class _Tp> -struct __make_tuple_return_impl<reference_wrapper<_Tp> > -{ - typedef _Tp& type; -}; - -template <class _Tp> -struct __make_tuple_return -{ - typedef typename __make_tuple_return_impl<typename decay<_Tp>::type>::type type; -}; - template <class... _Tp> inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 -tuple<typename __make_tuple_return<_Tp>::type...> +tuple<typename __unwrap_ref_decay<_Tp>::type...> make_tuple(_Tp&&... __t) { - return tuple<typename __make_tuple_return<_Tp>::type...>(_VSTD::forward<_Tp>(__t)...); + return tuple<typename __unwrap_ref_decay<_Tp>::type...>(_VSTD::forward<_Tp>(__t)...); } template <class... _Tp> diff --git a/libcxx/include/utility b/libcxx/include/utility index 1dce49df4da..ddfa27e2223 100644 --- a/libcxx/include/utility +++ b/libcxx/include/utility @@ -616,32 +616,37 @@ swap(pair<_T1, _T2>& __x, pair<_T1, _T2>& __y) __x.swap(__y); } -#ifndef _LIBCPP_CXX03_LANG +template <class _Tp> +struct __unwrap_reference { typedef _Tp type; }; template <class _Tp> -struct __make_pair_return_impl -{ - typedef _Tp type; -}; +struct __unwrap_reference<reference_wrapper<_Tp> > { typedef _Tp& type; }; +#if _LIBCPP_STD_VER > 17 template <class _Tp> -struct __make_pair_return_impl<reference_wrapper<_Tp>> -{ - typedef _Tp& type; -}; +struct unwrap_reference : __unwrap_reference<_Tp> { }; template <class _Tp> -struct __make_pair_return -{ - typedef typename __make_pair_return_impl<typename decay<_Tp>::type>::type type; -}; +struct unwrap_ref_decay : unwrap_reference<typename decay<_Tp>::type> { }; +#endif // > C++17 + +template <class _Tp> +struct __unwrap_ref_decay +#if _LIBCPP_STD_VER > 17 + : unwrap_ref_decay<_Tp> +#else + : __unwrap_reference<typename decay<_Tp>::type> +#endif +{ }; + +#ifndef _LIBCPP_CXX03_LANG template <class _T1, class _T2> inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 -pair<typename __make_pair_return<_T1>::type, typename __make_pair_return<_T2>::type> +pair<typename __unwrap_ref_decay<_T1>::type, typename __unwrap_ref_decay<_T2>::type> make_pair(_T1&& __t1, _T2&& __t2) { - return pair<typename __make_pair_return<_T1>::type, typename __make_pair_return<_T2>::type> + return pair<typename __unwrap_ref_decay<_T1>::type, typename __unwrap_ref_decay<_T2>::type> (_VSTD::forward<_T1>(__t1), _VSTD::forward<_T2>(__t2)); } diff --git a/libcxx/test/std/utilities/function.objects/refwrap/unwrap_ref_decay.pass.cpp b/libcxx/test/std/utilities/function.objects/refwrap/unwrap_ref_decay.pass.cpp new file mode 100644 index 00000000000..a63dc5b15f4 --- /dev/null +++ b/libcxx/test/std/utilities/function.objects/refwrap/unwrap_ref_decay.pass.cpp @@ -0,0 +1,58 @@ +//===----------------------------------------------------------------------===// +// +// 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> +// +// template <class T> +// struct unwrap_ref_decay; +// +// template <class T> +// using unwrap_ref_decay_t = typename unwrap_ref_decay<T>::type; + +// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17 + +#include <functional> +#include <type_traits> + + +template <typename T, typename Result> +void check() { + static_assert(std::is_same_v<typename std::unwrap_ref_decay<T>::type, Result>); + static_assert(std::is_same_v<typename std::unwrap_ref_decay<T>::type, std::unwrap_ref_decay_t<T>>); +} + +struct T { }; + +int main() { + check<T, T>(); + check<T&, T>(); + check<T const, T>(); + check<T const&, T>(); + check<T*, T*>(); + check<T const*, T const*>(); + check<T[3], T*>(); + check<T const [3], T const*>(); + check<T (), T (*)()>(); + check<T (int) const, T (int) const>(); + check<T (int) &, T (int) &>(); + check<T (int) &&, T (int) &&>(); + + check<std::reference_wrapper<T>, T&>(); + check<std::reference_wrapper<T>&, T&>(); + check<std::reference_wrapper<T const>, T const&>(); + check<std::reference_wrapper<T const>&, T const&>(); + check<std::reference_wrapper<T*>, T*&>(); + check<std::reference_wrapper<T*>&, T*&>(); + check<std::reference_wrapper<T const*>, T const*&>(); + check<std::reference_wrapper<T const*>&, T const*&>(); + check<std::reference_wrapper<T[3]>, T (&)[3]>(); + check<std::reference_wrapper<T[3]>&, T (&)[3]>(); + check<std::reference_wrapper<T ()>, T (&)()>(); + check<std::reference_wrapper<T ()>&, T (&)()>(); +} diff --git a/libcxx/test/std/utilities/function.objects/refwrap/unwrap_reference.pass.cpp b/libcxx/test/std/utilities/function.objects/refwrap/unwrap_reference.pass.cpp new file mode 100644 index 00000000000..441ddf4bd56 --- /dev/null +++ b/libcxx/test/std/utilities/function.objects/refwrap/unwrap_reference.pass.cpp @@ -0,0 +1,51 @@ +//===----------------------------------------------------------------------===// +// +// 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> +// +// template <class T> +// struct unwrap_reference; +// +// template <class T> +// using unwrap_reference_t = typename unwrap_reference<T>::type; + +// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17 + +#include <functional> +#include <type_traits> + + +template <typename T, typename Expected> +void check_equal() { + static_assert(std::is_same_v<typename std::unwrap_reference<T>::type, Expected>); + static_assert(std::is_same_v<typename std::unwrap_reference<T>::type, std::unwrap_reference_t<T>>); +} + +template <typename T> +void check() { + check_equal<T, T>(); + check_equal<T&, T&>(); + check_equal<T const, T const>(); + check_equal<T const&, T const&>(); + + check_equal<std::reference_wrapper<T>, T&>(); + check_equal<std::reference_wrapper<T const>, T const&>(); +} + +struct T { }; + +int main() { + check<T>(); + check<int>(); + check<float>(); + + check<T*>(); + check<int*>(); + check<float*>(); +} diff --git a/libcxx/www/cxx2a_status.html b/libcxx/www/cxx2a_status.html index 5b090a088a9..349d3c2bf34 100644 --- a/libcxx/www/cxx2a_status.html +++ b/libcxx/www/cxx2a_status.html @@ -108,7 +108,7 @@ <tr><td><a href="https://wg21.link/P1120R0">P1120R0</a></td><td>CWG</td><td>Consistency improvements for <=> and other comparison operators</td><td>Rapperswil</td><td></td><td></td></tr> <tr><td></td><td></td><td></td><td></td><td></td><td></td></tr> - <tr><td><a href="https://wg21.link/P0318R1">P0318R1</a></td><td>LWG</td><td>unwrap_ref_decay and unwrap_reference</td><td>San Diego</td><td><i> </i></td><td></td></tr> + <tr><td><a href="https://wg21.link/P0318R1">P0318R1</a></td><td>LWG</td><td>unwrap_ref_decay and unwrap_reference</td><td>San Diego</td><td>Complete</td><td>8.0</td></tr> <tr><td><a href="https://wg21.link/P0356R5">P0356R5</a></td><td>LWG</td><td>Simplified partial function application</td><td>San Diego</td><td><i> </i></td><td></td></tr> <tr><td><a href="https://wg21.link/P0357R3">P0357R3</a></td><td>LWG</td><td>reference_wrapper for incomplete types</td><td>San Diego</td><td><i> </i></td><td></td></tr> <tr><td><a href="https://wg21.link/P0482R6">P0482R6</a></td><td>CWG</td><td>char8_t: A type for UTF-8 characters and strings</td><td>San Diego</td><td><i> </i></td><td></td></tr> |

