|
template <class... _Types>
|
|
struct _Invoke_traits<void_t<decltype(_STD invoke(_STD declval<_Types>()...))>,
|
|
_Types...> { // selected when _Callable is callable with _Args
|
|
using type = decltype(_STD invoke(_STD declval<_Types>()...));
|
|
using _Is_invocable = true_type;
|
|
using _Is_nothrow_invocable = bool_constant<noexcept(_STD invoke(_STD declval<_Types>()...))>;
|
|
template <class _Rx>
|
|
using _Is_invocable_r = bool_constant<disjunction_v<is_void<_Rx>, is_convertible<type, _Rx>>>;
|
|
template <class _Rx>
|
|
using _Is_nothrow_invocable_r = bool_constant<
|
|
conjunction_v<_Is_nothrow_invocable, disjunction<is_void<_Rx>, _Is_nothrow_convertible<type, _Rx>>>>;
|
|
};
|
The compiler front-end team has advised us that repeating _STD invoke(_STD declval<_Types>()...) here is unusually expensive. Preserving the distinction between _Callable, _Args... and replacing this with the equivalent _Invoker::_Call() expression should significantly improve throughput (~25% faster).
STL/stl/inc/type_traits
Lines 1685 to 1696 in 19067f6
The compiler front-end team has advised us that repeating
_STD invoke(_STD declval<_Types>()...)here is unusually expensive. Preserving the distinction between_Callable, _Args...and replacing this with the equivalent_Invoker::_Call()expression should significantly improve throughput (~25% faster).