1 //  Copyright (c) 2011-present, Facebook, Inc.  All rights reserved.
2 //  This source code is licensed under both the GPLv2 (found in the
3 //  COPYING file in the root directory) and Apache 2.0 License
4 //  (found in the LICENSE.Apache file in the root directory).
5 
6 #pragma once
7 
8 #include <folly/Traits.h>
9 
10 #include <functional>
11 #include <type_traits>
12 
13 namespace folly {
14 namespace invoke_detail {
15 template <typename F, typename... Args>
16 using invoke_result_ = decltype(std::declval<F>()(std::declval<Args>()...));
17 
18 template <typename Void, typename F, typename... Args>
19 struct is_invocable : std::false_type {};
20 
21 template <typename F, typename... Args>
22 struct is_invocable<void_t<invoke_result_<F, Args...>>, F, Args...>
23     : std::true_type {};
24 
25 template <typename Void, typename R, typename F, typename... Args>
26 struct is_invocable_r : std::false_type {};
27 
28 template <typename R, typename F, typename... Args>
29 struct is_invocable_r<void_t<invoke_result_<F, Args...>>, R, F, Args...>
30     : std::is_convertible<invoke_result_<F, Args...>, R> {};
31 } // namespace invoke_detail
32 
33 //  mimic: std::is_invocable, C++17
34 template <typename F, typename... Args>
35 struct is_invocable : invoke_detail::is_invocable<void, F, Args...> {};
36 
37 //  mimic: std::is_invocable_r, C++17
38 template <typename R, typename F, typename... Args>
39 struct is_invocable_r : invoke_detail::is_invocable_r<void, R, F, Args...> {};
40 } // namespace folly
41