Index: libcxx/include/functional =================================================================== --- libcxx/include/functional +++ libcxx/include/functional @@ -68,6 +68,10 @@ template void cref(const T&& t) = delete; template reference_wrapper cref(reference_wrapper t) noexcept; +template struct unwrap_reference; // since C++20 +template struct unwrap_ref_decay : unwrap_reference> { }; // since C++20 +template using unwrap_ref_decay_t = typename unwrap_ref_decay::type; // since C++20 + template // in C++14 struct plus : binary_function { @@ -2527,6 +2531,14 @@ #endif // _LIBCPP_STD_VER > 14 +#if _LIBCPP_STD_VER > 17 +using __detail::unwrap_reference; +using __detail::unwrap_ref_decay; + +template +using unwrap_ref_decay_t = typename unwrap_ref_decay<_Tp>::type; +#endif // >= C++20 + _LIBCPP_END_NAMESPACE_STD #endif // _LIBCPP_FUNCTIONAL Index: libcxx/include/tuple =================================================================== --- libcxx/include/tuple +++ libcxx/include/tuple @@ -1078,30 +1078,12 @@ _LIBCPP_INLINE_VAR constexpr __ignore_t ignore = __ignore_t(); } -template -struct __make_tuple_return_impl -{ - typedef _Tp type; -}; - -template -struct __make_tuple_return_impl > -{ - typedef _Tp& type; -}; - -template -struct __make_tuple_return -{ - typedef typename __make_tuple_return_impl::type>::type type; -}; - template inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 -tuple::type...> +tuple::type...> make_tuple(_Tp&&... __t) { - return tuple::type...>(_VSTD::forward<_Tp>(__t)...); + return tuple::type...>(_VSTD::forward<_Tp>(__t)...); } template Index: libcxx/include/utility =================================================================== --- libcxx/include/utility +++ libcxx/include/utility @@ -616,32 +616,25 @@ __x.swap(__y); } -#ifndef _LIBCPP_CXX03_LANG +namespace __detail { + template + struct unwrap_reference { typedef _Tp type; }; -template -struct __make_pair_return_impl -{ - typedef _Tp type; -}; + template + struct unwrap_reference > { typedef _Tp& type; }; -template -struct __make_pair_return_impl> -{ - typedef _Tp& type; -}; + template + struct unwrap_ref_decay : unwrap_reference::type> { }; +} // end namespace __detail -template -struct __make_pair_return -{ - typedef typename __make_pair_return_impl::type>::type type; -}; +#ifndef _LIBCPP_CXX03_LANG template inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 -pair::type, typename __make_pair_return<_T2>::type> +pair::type, typename __detail::unwrap_ref_decay<_T2>::type> make_pair(_T1&& __t1, _T2&& __t2) { - return pair::type, typename __make_pair_return<_T2>::type> + return pair::type, typename __detail::unwrap_ref_decay<_T2>::type> (_VSTD::forward<_T1>(__t1), _VSTD::forward<_T2>(__t2)); } Index: libcxx/test/std/utilities/function.objects/refwrap/unwrap_ref_decay.pass.cpp =================================================================== --- /dev/null +++ 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. +// +//===----------------------------------------------------------------------===// + +// + +// template +// struct unwrap_ref_decay; +// +// template +// using unwrap_ref_decay_t = typename unwrap_ref_decay::type; + +// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17 + +#include +#include + + +template +void check() { + static_assert(std::is_same_v::type, Result>); + static_assert(std::is_same_v::type, std::unwrap_ref_decay_t>); +} + +struct T { }; + +int main() { + check(); + check(); + check(); + check(); + check(); + check(); + check(); + check(); + check(); + check(); + check(); + check(); + + check, T&>(); + check&, T&>(); + check, T const&>(); + check&, T const&>(); + check, T*&>(); + check&, T*&>(); + check, T const*&>(); + check&, T const*&>(); + check, T (&)[3]>(); + check&, T (&)[3]>(); + check, T (&)()>(); + check&, T (&)()>(); +} Index: libcxx/test/std/utilities/function.objects/refwrap/unwrap_reference.pass.cpp =================================================================== --- /dev/null +++ libcxx/test/std/utilities/function.objects/refwrap/unwrap_reference.pass.cpp @@ -0,0 +1,42 @@ +//===----------------------------------------------------------------------===// +// +// 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. +// +//===----------------------------------------------------------------------===// + +// + +// template +// struct unwrap_reference; + +// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17 + +#include +#include + + +template +void check() { + static_assert(std::is_same_v::type, T>); + static_assert(std::is_same_v::type, T&>); + static_assert(std::is_same_v::type, T const>); + static_assert(std::is_same_v::type, T const&>); + + static_assert(std::is_same_v>::type, T&>); + static_assert(std::is_same_v>::type, T const&>); +} + +struct T { }; + +int main() { + check(); + check(); + check(); + + check(); + check(); + check(); +} Index: libcxx/www/cxx2a_status.html =================================================================== --- libcxx/www/cxx2a_status.html +++ libcxx/www/cxx2a_status.html @@ -108,7 +108,7 @@ P1120R0CWGConsistency improvements for <=> and other comparison operatorsRapperswil - P0318R1LWGunwrap_ref_decay and unwrap_referenceSan Diego + P0318R1LWGunwrap_ref_decay and unwrap_referenceSan DiegoComplete8.0 P0356R5LWGSimplified partial function applicationSan Diego P0357R3LWGreference_wrapper for incomplete typesSan Diego P0482R6CWGchar8_t: A type for UTF-8 characters and stringsSan Diego