diff --git a/libcxx/include/__functional/weak_result_type.h b/libcxx/include/__functional/weak_result_type.h --- a/libcxx/include/__functional/weak_result_type.h +++ b/libcxx/include/__functional/weak_result_type.h @@ -66,6 +66,29 @@ typedef decltype(__test((_Tp*)0)) type; }; +#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS) +template +struct __maybe_has_argument_type {}; + +template +struct __maybe_has_argument_type<_Tp, __void_t > { + using argument_type _LIBCPP_NODEBUG _LIBCPP_DEPRECATED_IN_CXX17 = typename _Tp::argument_type; +}; + +template , typename = __void_t<> > +struct __maybe_has_first_and_second_argument_type {}; + +template +struct __maybe_has_first_and_second_argument_type< + _Tp, + __void_t, + __void_t > { + using first_argument_type _LIBCPP_NODEBUG _LIBCPP_DEPRECATED_IN_CXX17 = typename _Tp::first_argument_type; + using second_argument_type _LIBCPP_NODEBUG _LIBCPP_DEPRECATED_IN_CXX17 = typename _Tp::second_argument_type; +}; + +#endif // _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS) + template ::value> struct __maybe_derive_from_unary_function // bool is true : public __derives_from_unary_function<_Tp>::type @@ -74,6 +97,9 @@ template struct __maybe_derive_from_unary_function<_Tp, false> +#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS) + : public __maybe_has_argument_type<_Tp> +#endif { }; @@ -85,6 +111,9 @@ template struct __maybe_derive_from_binary_function<_Tp, false> +#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS) + : public __maybe_has_first_and_second_argument_type<_Tp> +#endif { }; diff --git a/libcxx/test/libcxx/utilities/function.objects/refwrap/argument_types.verify.cpp b/libcxx/test/libcxx/utilities/function.objects/refwrap/argument_types.verify.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/libcxx/utilities/function.objects/refwrap/argument_types.verify.cpp @@ -0,0 +1,78 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +// REQUIRES: c++11 || c++14 || c++17 + +// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DISABLE_DEPRECATION_WARNINGS + +// + +// reference_wrapper + +// check for types of class reference_wrapper: +// argument_type, first_argument_type, second_argument_type +// C++11 20.8.3 [refwrap] + +#include +#include + +void test() { + { + typedef std::reference_wrapper::argument_type A; // expected-error {{no type named}} + typedef std::reference_wrapper::result_type R; // expected-error {{no type named}} + typedef std::reference_wrapper::first_argument_type A1; // expected-error {{no type named}} + typedef std::reference_wrapper::second_argument_type A2; // expected-error {{no type named}} + } + { + typedef float(F)(int); + typedef std::reference_wrapper::argument_type A; + typedef std::reference_wrapper::result_type R; + static_assert(std::is_same::value, ""); + static_assert(std::is_same::value, ""); + } + { + typedef double(F)(char, int); + typedef std::reference_wrapper::first_argument_type A1; + typedef std::reference_wrapper::second_argument_type A2; + typedef std::reference_wrapper::result_type R; + static_assert(std::is_same::value, ""); + static_assert(std::is_same::value, ""); + static_assert(std::is_same::value, ""); + } + { + struct S {}; + typedef long (S::*P)(void); + typedef std::reference_wrapper

::argument_type A; + static_assert(std::is_same::value, ""); + } + { + struct S {}; + typedef void (S::*P)(int); + typedef std::reference_wrapper

::first_argument_type A1; + typedef std::reference_wrapper

::second_argument_type A2; + static_assert(std::is_same::value, ""); + static_assert(std::is_same::value, ""); + } + { + struct S { + typedef int argument_type; + }; + typedef std::reference_wrapper::argument_type A; + static_assert(std::is_same::value, ""); + } + { + struct S { + typedef char first_argument_type; + typedef int second_argument_type; + }; + typedef std::reference_wrapper::first_argument_type A1; + typedef std::reference_wrapper::second_argument_type A2; + static_assert(std::is_same::value, ""); + static_assert(std::is_same::value, ""); + } +} diff --git a/libcxx/test/std/depr/depr.function.objects/depr.base/refwrap_types.depr.verify.cpp b/libcxx/test/std/depr/depr.function.objects/depr.base/refwrap_types.depr.verify.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/std/depr/depr.function.objects/depr.base/refwrap_types.depr.verify.cpp @@ -0,0 +1,24 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +// REQUIRES: c++17 +// +// Types of class reference_wrapper were removed in C++20 + +// Check that types of class reference_wrapper are marked deprecated + +#include + +typedef float(F1)(int); +typedef double(F2)(char, int); + +std::reference_wrapper::argument_type a; // expected-warning {{'argument_type' is deprecated}} +std::reference_wrapper::result_type r; // expected-warning {{'result_type' is deprecated}} +std::reference_wrapper::first_argument_type a1; // expected-warning {{'first_argument_type' is deprecated}} +std::reference_wrapper::second_argument_type a2; // expected-warning {{'second_argument_type' is deprecated}} +std::reference_wrapper::result_type r1; // expected-warning {{'result_type' is deprecated}}