8#ifndef INCLUDE_GUARD_ARENE_BASE_ARENE_BASE_TYPE_TRAITS_IS_INVOCABLE_HPP_
9#define INCLUDE_GUARD_ARENE_BASE_ARENE_BASE_TYPE_TRAITS_IS_INVOCABLE_HPP_
14#include "arene/base/constraints/constraints.hpp"
15#include "arene/base/stdlib_choice/cstddef.hpp"
16#include "arene/base/stdlib_choice/declval.hpp"
17#include "arene/base/stdlib_choice/enable_if.hpp"
18#include "arene/base/stdlib_choice/integral_constant.hpp"
19#include "arene/base/stdlib_choice/is_convertible.hpp"
20#include "arene/base/stdlib_choice/is_same.hpp"
21#include "arene/base/stdlib_choice/is_void.hpp"
22#include "arene/base/stdlib_choice/remove_cv.hpp"
23#include "arene/base/stdlib_choice/remove_reference.hpp"
24#include "arene/base/type_list/type_list.hpp"
25#include "arene/base/type_traits/is_reference_wrapper.hpp"
26#include "arene/base/type_traits/remove_cvref.hpp"
31namespace is_invocable_detail {
35struct invalid_return {};
42template <
typename Fn,
typename... Args>
43class is_invocable_impl {
51 template <
typename MemFuncPtr,
typename Instance,
typename... Params>
52 static auto try_invoke(std::nullptr_t dummy
53 )
noexcept(
noexcept((std::declval<Instance>().*std::declval<MemFuncPtr>())(std::declval<Params>()...)))
54 ->
decltype((std::declval<Instance>().*std::declval<MemFuncPtr>())(std::declval<Params>()...));
61 template <
typename MemPtr,
typename Instance>
62 static auto try_invoke(std::nullptr_t dummy)
noexcept ->
decltype((std::declval<Instance>().*std::declval<MemPtr>()));
70 template <
typename MemFuncPtr,
typename Pointer,
typename... Params>
71 static auto try_invoke(std::nullptr_t dummy
72 )
noexcept(
noexcept(((*std::declval<Pointer>()).*std::declval<MemFuncPtr>())(std::declval<Params>()...)))
73 ->
decltype(((*std::declval<Pointer>()).*std::declval<MemFuncPtr>())(std::declval<Params>()...));
80 template <
typename MemPtr,
typename Pointer>
81 static auto try_invoke(std::nullptr_t dummy)
noexcept(
noexcept((*std::declval<Pointer>()).*std::declval<MemPtr>()))
82 ->
decltype(((*std::declval<Pointer>()).*std::declval<MemPtr>()));
94 constraints<std::enable_if_t<is_reference_wrapper_v<remove_cvref_t<RefWrap>>>> =
nullptr>
95 static auto try_invoke(std::nullptr_t dummy
96 )
noexcept(
noexcept((std::declval<RefWrap>().get().*std::declval<MemFuncPtr>())(std::declval<Params>()...)))
97 ->
decltype((std::declval<RefWrap>().get().*std::declval<MemFuncPtr>())(std::declval<Params>()...));
107 constraints<std::enable_if_t<is_reference_wrapper_v<remove_cvref_t<RefWrap>>>> =
nullptr>
108 static auto try_invoke(std::nullptr_t dummy)
noexcept
109 ->
decltype((std::declval<RefWrap>().get().*std::declval<MemPtr>()));
116 template <
typename Callable,
typename... Params>
117 static auto try_invoke(std::nullptr_t dummy)
noexcept(
noexcept(std::declval<Callable>()(std::declval<Params>()...)))
118 ->
decltype(std::declval<Callable>()(std::declval<Params>()...));
123 template <
typename...>
124 static auto try_invoke(
void* dummy) -> invalid_return;
127 using result =
decltype(is_invocable_impl::try_invoke<Fn, Args...>(
nullptr));
131 static constexpr bool is_noexcept{
noexcept(is_invocable_impl::try_invoke<Fn, Args...>(
nullptr))};
142template <
bool RequireNoThrow,
typename Ret,
typename Fn,
typename... Args>
143struct is_invocable_r final {
145 using invoke_detail = is_invocable_impl<Fn, Args...>;
148 static constexpr bool noexcept_ok{!RequireNoThrow || invoke_detail::is_noexcept};
151 static constexpr bool return_valid{!std::is_same<
typename invoke_detail::result, invalid_return>::value};
154 static constexpr bool return_ok{
155 std::is_void<Ret>::value || std::is_convertible<
typename invoke_detail::result, Ret>::value
159 static constexpr bool value{noexcept_ok && return_valid && return_ok};
170template <
typename Fn,
typename Args,
typename = constraints<>>
171class invoke_result {};
181template <
typename Fn,
typename... Args>
186 std::enable_if_t<!std::is_same<invalid_return,
typename is_invocable_impl<Fn, Args...>::result>::value>>> {
189 using type =
typename is_invocable_impl<Fn, Args...>::result;
199template <
typename Fn,
typename... Args>
207template <
typename Fn,
typename...
Args>
214template <
typename Ret,
typename Fn,
typename... Args>
223template <
typename Ret,
typename Fn,
typename...
Args>
230template <
typename Fn,
typename... Args>
238template <
typename Fn,
typename...
Args>
246template <
typename Ret,
typename Fn,
typename... Args>
255template <
typename Ret,
typename Fn,
typename...
Args>
262template <
typename Fn,
typename... Args>
270template <
typename Fn,
typename... Args>
Determines the return type of a functor invoked with the specified arguments.
Definition is_invocable.hpp:263
Determine if a functor type is invocable with the specified return and argument types.
Definition is_invocable.hpp:216
Determine if a functor type is invocable with the specified argument types.
Definition is_invocable.hpp:201
Determine if a functor type is no-throw invocable with the specified return and argument types.
Definition is_invocable.hpp:248
Determine if a functor type is no-throw invocable with the specified argument types.
Definition is_invocable.hpp:232
Definition array_exceptions_disabled.cpp:11
constexpr bool is_invocable_v
Determine if a functor type is invocable with the specified argument types.
constexpr bool is_invocable_r_v
Determine if a functor type is invocable with the specified return and argument types.
constexpr bool is_nothrow_invocable_r_v
Determine if a functor type is no-throw invocable with the specified return and argument types.
constexpr bool is_nothrow_invocable_v
Determine if a functor type is no-throw invocable with the specified argument types.
Copyright 2026, Toyota Motor Corporation.
Definition array_exceptions_disabled.cpp:10