VCCC  2024.05
VisualCamp Common C++ library
is_invocable.hpp
Go to the documentation of this file.
1 //
2 // Created by yonggyulee on 2023/12/29.
3 //
4 
5 #ifndef VCCC_TYPE_TRAITS_IS_INVOCABLE_HPP
6 #define VCCC_TYPE_TRAITS_IS_INVOCABLE_HPP
7 
8 #include <type_traits>
9 
19 
20 namespace vccc {
21 namespace detail {
22 
23 template<typename T>
24 struct satisfies_invocable_type : disjunction<is_complete<T>, std::is_void<T>, is_unbounded_array<T>> {};
25 
26 template<typename R, typename F, typename ...Args>
27 struct is_invocable_r_impl {
28  // TODO: handle requirements
29  // static_assert(satisfies_invocable_type<R>::value, "invocable: Return type does not meet the requirements");
30  // static_assert(satisfies_invocable_type<F>::value, "invocable: Callable type does not meet the requirements");
31  // static_assert(conjunction<satisfies_invocable_type<Args>...>::value,
32  // "invocable: Argument types do not meet the requirements");
33  private:
34  template<typename F2, typename ...Args2>
35  static auto test(int)
36  noexcept(noexcept(detail::INVOKE(std::declval<F2>(), std::declval<Args2>()...)))
37  -> decltype(detail::INVOKE(std::declval<F2>(), std::declval<Args2>()...));
38  template<typename F2, typename ...Args2>
39  static auto test(...) -> empty;
40 
41  public:
42  using test_return_type = decltype(test<F, Args...>(0));
43  using convertible = disjunction<std::is_void<R>, std::is_convertible<test_return_type, R>>;
44  using invocable = conjunction<negation<std::is_same<test_return_type, empty>>, convertible>;
45  using nothrow_invocable = conjunction<invocable, bool_constant<noexcept(test<F, Args...>(0))>>;
46 };
47 
48 } // namespace detail
49 
52 
58 template<typename F, typename ...Args>
60  : std::conditional_t<
61  detail::is_invocable_r_impl<void, F, Args...>::invocable::value,
62  type_identity<typename detail::is_invocable_r_impl<void, F, Args...>::test_return_type>,
63  empty> {};
64 
65 template<typename F, typename ...Args>
66 using invoke_result_t = typename invoke_result<F, Args...>::type;
67 
76 template<typename F, typename ...Args>
77 struct is_invocable : detail::is_invocable_r_impl<void, F, Args...>::invocable {};
78 
79 
80 
83 template<typename R, typename F, typename ...Args>
84 struct is_invocable_r : detail::is_invocable_r_impl<R, F, Args...>::invocable {};
85 
86 
87 
90 template<typename F, typename ...Args>
91 struct is_nothrow_invocable : detail::is_invocable_r_impl<void, F, Args...>::nothrow_invocable {};
92 
93 
94 
97 template<typename R, typename F, typename ...Args>
98 struct is_nothrow_invocable_r : detail::is_invocable_r_impl<R, F, Args...>::nothrow_invocable {};
99 
102 
103 } // namespace vccc
104 
105 #endif // VCCC_TYPE_TRAITS_IS_INVOCABLE_HPP
constexpr VCCC_INLINE_OR_STATIC detail::empty_niebloid empty
checks whether a range is empty
Definition: empty.hpp:116
std::integral_constant< bool, v > bool_constant
Definition: bool_constant.hpp:19
typename invoke_result< F, Args... >::type invoke_result_t
Definition: is_invocable.hpp:66
Definition: directory.h:12
specifies that a callable type can be invoked with a given set of argument types
Definition: invocable.hpp:52
deduces the result type of invoking a callable object with a set of arguments
Definition: is_invocable.hpp:63
Determines whether INVOKE<R>(std::declval<Fn>(), std::declval<ArgTypes>()...) is well formed when tre...
Definition: is_invocable.hpp:84
Determines whether INVOKE(std::declval<Fn>(), std::declval<ArgTypes>()...) is well formed when treate...
Definition: is_invocable.hpp:77
Determines whether INVOKE<R>(std::declval<Fn>(), std::declval<ArgTypes>()...) is well formed when tre...
Definition: is_invocable.hpp:98
Determines whether INVOKE(std::declval<Fn>(), std::declval<ArgTypes>()...) is well formed when treate...
Definition: is_invocable.hpp:91