ttg 1.0.0
Template Task Graph (TTG): flowgraph-based programming model for high-performance distributed-memory algorithms
Loading...
Searching...
No Matches
is_invocable_impl.hpp
Go to the documentation of this file.
1
10#ifndef BOOST_CLBL_TRTS_IS_INVOCABLE_IMPL_HPP
11#define BOOST_CLBL_TRTS_IS_INVOCABLE_IMPL_HPP
12
16#include <type_traits>
17#include <utility>
18
19namespace boost { namespace callable_traits { namespace detail {
20
21 template<typename T>
23 {
24 template<typename>
25 struct check {};
26
27 template<typename U>
28 static std::int8_t test(
29 check<typename std::remove_reference<decltype(*std::declval<U>())>::type>*
30 );
31
32 template<typename>
33 static std::int16_t test(...);
34
35 static constexpr const bool value =
36 sizeof(test<T>(nullptr)) == sizeof(std::int8_t);
37 };
38
39 //returns std::true_type for pointers and smart pointers
40 template<typename T>
41 using can_dereference = std::integral_constant<bool,
43
44
45 template<typename T, typename = std::true_type>
46 struct generalize_t {
47 using type = T;
48 };
49
50 template<typename T>
51 struct generalize_t<T, std::integral_constant<bool,
52 can_dereference<T>::value && !is_reference_wrapper<T>::value
53 >>{
54 using type = decltype(*std::declval<T>());
55 };
56
57 template<typename T>
59 using type = decltype(std::declval<T>().get());
60 };
61
62 // When T is a pointer, generalize<T> is the resulting type of the
63 // pointer dereferenced. When T is an std::reference_wrapper, generalize<T>
64 // is the underlying reference type. Otherwise, generalize<T> is T.
65 template<typename T>
67
68 // handles the member pointer rules of INVOKE
69 template<typename Base, typename T,
70 typename IsBaseOf = std::is_base_of<Base, shallow_decay<T>>,
71 typename IsSame = std::is_same<Base, shallow_decay<T>>>
72 using generalize_if_dissimilar = typename std::conditional<
73 IsBaseOf::value || IsSame::value, T, generalize<T>>::type;
74
75 template<typename Traits, bool = Traits::is_const_member::value
76 || Traits::is_volatile_member::value
77 || Traits::is_lvalue_reference_member::value
78 || Traits::is_rvalue_reference_member::value>
79 struct test_invoke {
80
81 template<typename... Rgs,
82 typename U = typename Traits::type>
83 auto operator()(int, Rgs&&... rgs) const ->
84 success<decltype(std::declval<U>()(static_cast<Rgs&&>(rgs)...))>;
85
86 auto operator()(long, ...) const -> substitution_failure;
87 };
88
89 template<typename F>
90 struct test_invoke<function<F>, true /*abominable*/> {
91 auto operator()(...) const -> substitution_failure;
92 };
93
94 template<typename Pmf, bool Ignored>
95 struct test_invoke<pmf<Pmf>, Ignored> {
96
97 using class_t = typename pmf<Pmf>::class_type;
98
99 template<typename U, typename... Rgs,
101 auto operator()(int, U&& u, Rgs&&... rgs) const ->
102 success<decltype((std::declval<Obj>().*std::declval<Pmf>())(static_cast<Rgs&&>(rgs)...))>;
103
104 auto operator()(long, ...) const -> substitution_failure;
105 };
106
107 template<typename Pmd, bool Ignored>
108 struct test_invoke<pmd<Pmd>, Ignored> {
109
111
112 template<typename U,
114 auto operator()(int, U&& u) const ->
115 success<decltype(std::declval<Obj>().*std::declval<Pmd>())>;
116
117 auto operator()(long, ...) const -> substitution_failure;
118 };
119
120 template<typename T, typename... Args>
124 using result = decltype(test{}(0, ::std::declval<Args>()...));
125 using type = std::integral_constant<bool, result::value>;
126 };
127
128 template<typename... Args>
129 struct is_invocable_impl<void, Args...> {
130 using type = std::false_type;
131 };
132
133 template<typename IsInvocable, typename Ret, typename T, typename... Args>
137 using result = decltype(test{}(0, ::std::declval<Args>()...));
138 using type = std::integral_constant<bool,
139 std::is_convertible<typename result::_::type, Ret>::value
140 || std::is_same<Ret, void>::value>;
141 };
142
143 template<typename Ret, typename T, typename... Args>
144 struct is_invocable_r_impl<std::false_type, Ret, T, Args...> {
145 using type = std::false_type;
146 };
147
148}}} // namespace boost::callable_traits::detail
149
150#endif // #ifndef BOOST_CLBL_TRTS_IS_INVOCABLE_IMPL_HPP
std::integral_constant< bool, can_dereference_t< T >::value > can_dereference
typename std::conditional< IsBaseOf::value||IsSame::value, T, generalize< T > >::type generalize_if_dissimilar
typename BOOST_CLBL_TRTS_DISJUNCTION(function_object< unwrap_reference< T > >, function< T >, pmf< T >, pmd< T >, default_callable_traits< T >)::traits traits
Definition traits.hpp:25
typename is_reference_wrapper_t< shallow_decay< T > >::type is_reference_wrapper
Definition utility.hpp:93
typename generalize_t< T >::type generalize
STL namespace.
static std::int8_t test(check< typename std::remove_reference< decltype(*std::declval< U >())>::type > *)
decltype(test{}(0, ::std::declval< Args >()...)) result
std::integral_constant< bool, result::value > type
decltype(test{}(0, ::std::declval< Args >()...)) result
std::integral_constant< bool, std::is_convertible< typename result::_::type, Ret >::value||std::is_same< Ret, void >::value > type
auto operator()(long,...) const -> substitution_failure
auto operator()(int, U &&u) const -> success< decltype(std::declval< Obj >().*std::declval< Pmd >())>
auto operator()(long,...) const -> substitution_failure
auto operator()(int, U &&u, Rgs &&... rgs) const -> success< decltype((std::declval< Obj >().*std::declval< Pmf >())(static_cast< Rgs && >(rgs)...))>
auto operator()(int, Rgs &&... rgs) const -> success< decltype(std::declval< U >()(static_cast< Rgs && >(rgs)...))>
auto operator()(long,...) const -> substitution_failure