template<typename _Fn, typename... _ArgTypes>
struct __is_invocable
+#if _GLIBCXX_USE_BUILTIN_TRAIT(__is_invocable)
+ : __bool_constant<__is_invocable(_Fn, _ArgTypes...)>
+#else
: __is_invocable_impl<__invoke_result<_Fn, _ArgTypes...>, void>::type
+#endif
{ };
template<typename _Fn, typename _Tp, typename... _Args>
// __is_nothrow_invocable (std::is_nothrow_invocable for C++11)
template<typename _Fn, typename... _Args>
struct __is_nothrow_invocable
+#if _GLIBCXX_USE_BUILTIN_TRAIT(__is_nothrow_invocable)
+ : __bool_constant<__is_nothrow_invocable(_Fn, _Args...)>
+#else
: __and_<__is_invocable<_Fn, _Args...>,
__call_is_nothrow_<_Fn, _Args...>>::type
+#endif
{ };
#pragma GCC diagnostic push
inline constexpr bool is_convertible_v = is_convertible<_From, _To>::value;
#endif
template<typename _Fn, typename... _Args>
- inline constexpr bool is_invocable_v = is_invocable<_Fn, _Args...>::value;
+ inline constexpr bool is_invocable_v
+#if _GLIBCXX_USE_BUILTIN_TRAIT(__is_invocable)
+ = __is_invocable(_Fn, _Args...);
+#else
+ = is_invocable<_Fn, _Args...>::value;
+#endif
template<typename _Fn, typename... _Args>
inline constexpr bool is_nothrow_invocable_v
+#if _GLIBCXX_USE_BUILTIN_TRAIT(__is_nothrow_invocable)
+ = __is_nothrow_invocable(_Fn, _Args...);
+#else
= is_nothrow_invocable<_Fn, _Args...>::value;
+#endif
template<typename _Ret, typename _Fn, typename... _Args>
inline constexpr bool is_invocable_r_v
= is_invocable_r<_Ret, _Fn, _Args...>::value;