From: Nikolas Klauser Date: Thu, 7 Apr 2022 11:40:53 +0000 (+0200) Subject: [libc++] Add __is_callable type trait and begin granularizing type_traits X-Git-Tag: upstream/15.0.7~11028 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=08920cc04343e69ee8a56168a5911acddf40e6ba;p=platform%2Fupstream%2Fllvm.git [libc++] Add __is_callable type trait and begin granularizing type_traits `__is_callable` is required to ensure that the classic algorithms are only called with functions or functors. I also begin to granularize ``. Reviewed By: ldionne, #libc Spies: libcxx-commits, mgorny Differential Revision: https://reviews.llvm.org/D123114 --- diff --git a/libcxx/include/CMakeLists.txt b/libcxx/include/CMakeLists.txt index be544cf..5069d06 100644 --- a/libcxx/include/CMakeLists.txt +++ b/libcxx/include/CMakeLists.txt @@ -411,6 +411,8 @@ set(files __threading_support __tree __tuple + __type_traits/integral_constant.h + __type_traits/is_callable.h __undef_macros __utility/as_const.h __utility/auto_cast.h diff --git a/libcxx/include/__type_traits/integral_constant.h b/libcxx/include/__type_traits/integral_constant.h new file mode 100644 index 0000000..2449d1a --- /dev/null +++ b/libcxx/include/__type_traits/integral_constant.h @@ -0,0 +1,50 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___TYPE_TRAITS_INTEGRAL_CONSTANT_H +#define _LIBCPP___TYPE_TRAITS_INTEGRAL_CONSTANT_H + +#include <__config> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +struct _LIBCPP_TEMPLATE_VIS integral_constant +{ + static _LIBCPP_CONSTEXPR const _Tp value = __v; + typedef _Tp value_type; + typedef integral_constant type; + _LIBCPP_INLINE_VISIBILITY + _LIBCPP_CONSTEXPR operator value_type() const _NOEXCEPT {return value;} +#if _LIBCPP_STD_VER > 11 + _LIBCPP_INLINE_VISIBILITY + constexpr value_type operator ()() const _NOEXCEPT {return value;} +#endif +}; + +template +_LIBCPP_CONSTEXPR const _Tp integral_constant<_Tp, __v>::value; + +typedef integral_constant true_type; +typedef integral_constant false_type; + +template +using _BoolConstant _LIBCPP_NODEBUG = integral_constant; + +#if _LIBCPP_STD_VER > 14 +template +using bool_constant = integral_constant; +#endif + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___TYPE_TRAITS_INTEGRAL_CONSTANT_H diff --git a/libcxx/include/__type_traits/is_callable.h b/libcxx/include/__type_traits/is_callable.h new file mode 100644 index 0000000..73f894d --- /dev/null +++ b/libcxx/include/__type_traits/is_callable.h @@ -0,0 +1,32 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___TYPE_TRAITS_IS_CALLABLE_H +#define _LIBCPP___TYPE_TRAITS_IS_CALLABLE_H + +#include <__config> +#include <__type_traits/integral_constant.h> +#include <__utility/declval.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template()(std::declval<_Args>()...))> +true_type __is_callable_helper(int); +template +false_type __is_callable_helper(...); + +template +struct __is_callable : decltype(__is_callable_helper<_Func, _Args...>(0)) {}; + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___TYPE_TRAITS_IS_CALLABLE_H diff --git a/libcxx/include/module.modulemap b/libcxx/include/module.modulemap index cf74a07..0f07fd1 100644 --- a/libcxx/include/module.modulemap +++ b/libcxx/include/module.modulemap @@ -956,6 +956,9 @@ module std [system] { header "type_traits" export functional.__functional.unwrap_ref export * + + module integral_constant { private header "__type_traits/integral_constant.h" } + module is_callable { private header "__type_traits/is_callable.h" } } module typeindex { header "typeindex" diff --git a/libcxx/include/type_traits b/libcxx/include/type_traits index 2ea883f..4f00e90 100644 --- a/libcxx/include/type_traits +++ b/libcxx/include/type_traits @@ -419,6 +419,9 @@ namespace std #include <__assert> // all public C++ headers provide the assertion handler #include <__config> +#include <__type_traits/integral_constant.h> +#include <__type_traits/is_callable.h> +#include <__utility/declval.h> #include #include @@ -432,28 +435,6 @@ template struct _LIBCPP_TEMPLATE_VIS pair; template class _LIBCPP_TEMPLATE_VIS reference_wrapper; template struct _LIBCPP_TEMPLATE_VIS hash; -template -struct _LIBCPP_TEMPLATE_VIS integral_constant -{ - static _LIBCPP_CONSTEXPR const _Tp value = __v; - typedef _Tp value_type; - typedef integral_constant type; - _LIBCPP_INLINE_VISIBILITY - _LIBCPP_CONSTEXPR operator value_type() const _NOEXCEPT {return value;} -#if _LIBCPP_STD_VER > 11 - _LIBCPP_INLINE_VISIBILITY - constexpr value_type operator ()() const _NOEXCEPT {return value;} -#endif -}; - -template -_LIBCPP_CONSTEXPR const _Tp integral_constant<_Tp, __v>::value; - -#if _LIBCPP_STD_VER > 14 -template -using bool_constant = integral_constant; -#endif - template struct _LIBCPP_TEMPLATE_VIS enable_if {}; template struct _LIBCPP_TEMPLATE_VIS enable_if {typedef _Tp type;}; @@ -463,12 +444,6 @@ template using __enable_if_t _LIBCPP_NODEBUG = type template using enable_if_t = typename enable_if<_Bp, _Tp>::type; #endif -typedef integral_constant true_type; -typedef integral_constant false_type; - -template -using _BoolConstant _LIBCPP_NODEBUG = integral_constant; - template struct _MetaBase; template <> struct _MetaBase { @@ -1258,17 +1233,6 @@ template struct _LIBCPP_TEMPLATE_VIS add_rvalue_reference template using add_rvalue_reference_t = typename add_rvalue_reference<_Tp>::type; #endif -// Suppress deprecation notice for volatile-qualified return type resulting -// from volatile-qualified types _Tp. -_LIBCPP_SUPPRESS_DEPRECATED_PUSH -template _Tp&& __declval(int); -template _Tp __declval(long); -_LIBCPP_SUPPRESS_DEPRECATED_POP - -template -decltype(__declval<_Tp>(0)) -declval() _NOEXCEPT; - template struct __unconstref { typedef _LIBCPP_NODEBUG typename remove_const::type>::type type; diff --git a/libcxx/test/libcxx/private_headers.verify.cpp b/libcxx/test/libcxx/private_headers.verify.cpp index f7117dd..f1173ff 100644 --- a/libcxx/test/libcxx/private_headers.verify.cpp +++ b/libcxx/test/libcxx/private_headers.verify.cpp @@ -421,6 +421,8 @@ END-SCRIPT #include <__thread/poll_with_backoff.h> // expected-error@*:* {{use of private header from outside its module: '__thread/poll_with_backoff.h'}} #include <__thread/timed_backoff_policy.h> // expected-error@*:* {{use of private header from outside its module: '__thread/timed_backoff_policy.h'}} #include <__tuple> // expected-error@*:* {{use of private header from outside its module: '__tuple'}} +#include <__type_traits/integral_constant.h> // expected-error@*:* {{use of private header from outside its module: '__type_traits/integral_constant.h'}} +#include <__type_traits/is_callable.h> // expected-error@*:* {{use of private header from outside its module: '__type_traits/is_callable.h'}} #include <__utility/as_const.h> // expected-error@*:* {{use of private header from outside its module: '__utility/as_const.h'}} #include <__utility/auto_cast.h> // expected-error@*:* {{use of private header from outside its module: '__utility/auto_cast.h'}} #include <__utility/cmp.h> // expected-error@*:* {{use of private header from outside its module: '__utility/cmp.h'}} diff --git a/libcxx/test/libcxx/type_traits/is_callable.compile.pass.cpp b/libcxx/test/libcxx/type_traits/is_callable.compile.pass.cpp new file mode 100644 index 0000000..f7f76bb --- /dev/null +++ b/libcxx/test/libcxx/type_traits/is_callable.compile.pass.cpp @@ -0,0 +1,31 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include + +struct Functor { + void operator()(); +}; + +int func(); + +struct NotFunctor { + bool compare(); +}; + +struct ArgumentFunctor { + bool operator()(int, int); +}; + +static_assert(std::__is_callable::value, ""); +static_assert(std::__is_callable::value, ""); +static_assert(!std::__is_callable::value, ""); +static_assert(!std::__is_callable::value, ""); +static_assert(std::__is_callable::value, ""); +static_assert(!std::__is_callable::value, "");