1/* Copyright 2016-2017 Joaquin M Lopez Munoz.
2 * Distributed under the Boost Software License, Version 1.0.
3 * (See accompanying file LICENSE_1_0.txt or copy at
4 * http://www.boost.org/LICENSE_1_0.txt)
5 *
6 * See http://www.boost.org/libs/poly_collection for library home page.
7 */
8
9#ifndef BOOST_POLY_COLLECTION_DETAIL_IS_INVOCABLE_HPP
10#define BOOST_POLY_COLLECTION_DETAIL_IS_INVOCABLE_HPP
11
12#if defined(_MSC_VER)
13#pragma once
14#endif
15
16#include <functional>
17#include <type_traits>
18
19/* technique explained at
20 * http://bannalia.blogspot.com/2016/09/compile-time-checking-existence-of.html
21 */
22
23namespace boost{
24namespace poly_collection{
25namespace detail{
26namespace is_invocable_fallback{
27
28template <typename F,typename... Args>
29struct is_invocable:
30 std::is_constructible<
31 std::function<void(Args...)>,
32 std::reference_wrapper<typename std::remove_reference<F>::type>
33 >
34{};
35
36template <typename R,typename F,typename... Args>
37struct is_invocable_r:
38 std::is_constructible<
39 std::function<R(Args...)>,
40 std::reference_wrapper<typename std::remove_reference<F>::type>
41 >
42{};
43
44struct hook{};
45
46}}}}
47
48namespace std{
49
50template<>
51struct is_void< ::boost::poly_collection::detail::is_invocable_fallback::hook>:
52 std::false_type
53{
54 template<typename F,typename... Args>
55 static constexpr bool is_invocable_f()
56 {
57 using namespace ::boost::poly_collection::detail::is_invocable_fallback;
58 return is_invocable<F,Args...>::value;
59 }
60
61 template<typename R,typename F,typename... Args>
62 static constexpr bool is_invocable_r_f()
63 {
64 using namespace ::boost::poly_collection::detail::is_invocable_fallback;
65 return is_invocable_r<R,F,Args...>::value;
66 }
67};
68
69} /* namespace std */
70
71namespace boost{
72
73namespace poly_collection{
74
75namespace detail{
76
77template<typename F,typename... Args>
78struct is_invocable:std::integral_constant<
79 bool,
80 std::is_void<is_invocable_fallback::hook>::template
81 is_invocable_f<F,Args...>()
82>{};
83
84template<typename R,typename F,typename... Args>
85struct is_invocable_r:std::integral_constant<
86 bool,
87 std::is_void<is_invocable_fallback::hook>::template
88 is_invocable_r_f<R,F,Args...>()
89>{};
90
91} /* namespace poly_collection::detail */
92
93} /* namespace poly_collection */
94
95} /* namespace boost */
96
97#endif
98

source code of boost/libs/poly_collection/include/boost/poly_collection/detail/is_invocable.hpp