35 #ifndef ABSL_BASE_INTERNAL_INVOKE_H_
36 #define ABSL_BASE_INTERNAL_INVOKE_H_
39 #include <type_traits>
42 #include "absl/meta/type_traits.h"
49 namespace base_internal {
59 template <
typename Derived>
60 struct StrippedAccept {
61 template <
typename...
Args>
63 typename std::remove_reference<Args>::type>::type...> {};
69 struct MemFunAndRef : StrippedAccept<MemFunAndRef> {
70 template <
typename...
Args>
73 template <
typename MemFunType,
typename C,
typename Obj,
typename...
Args>
74 struct AcceptImpl<MemFunType
C::*, Obj,
Args...>
75 : std::integral_constant<bool, std::is_base_of<C, Obj>::value &&
76 absl::is_function<MemFunType>::value> {
79 template <
typename MemFun,
typename Obj,
typename...
Args>
80 static decltype((std::declval<Obj>().*
81 std::declval<MemFun>())(std::declval<Args>()...))
83 return (std::forward<Obj>(
obj).*
84 std::forward<MemFun>(mem_fun))(std::forward<Args>(
args)...);
90 struct MemFunAndPtr : StrippedAccept<MemFunAndPtr> {
91 template <
typename...
Args>
94 template <
typename MemFunType,
typename C,
typename Ptr,
typename...
Args>
95 struct AcceptImpl<MemFunType
C::*, Ptr,
Args...>
96 : std::integral_constant<bool, !std::is_base_of<C, Ptr>::value &&
97 absl::is_function<MemFunType>::value> {
100 template <
typename MemFun,
typename Ptr,
typename...
Args>
101 static decltype(((*std::declval<Ptr>()).*
102 std::declval<MemFun>())(std::declval<Args>()...))
104 return ((*std::forward<Ptr>(
ptr)).*
105 std::forward<MemFun>(mem_fun))(std::forward<Args>(
args)...);
112 struct DataMemAndRef : StrippedAccept<DataMemAndRef> {
113 template <
typename...
Args>
116 template <
typename R,
typename C,
typename Obj>
117 struct AcceptImpl<R
C::*, Obj>
118 : std::integral_constant<bool, std::is_base_of<C, Obj>::value &&
119 !absl::is_function<R>::value> {};
121 template <
typename DataMem,
typename Ref>
122 static decltype(std::declval<Ref>().*std::declval<DataMem>())
Invoke(
123 DataMem&& data_mem,
Ref&&
ref) {
124 return std::forward<Ref>(
ref).*std::forward<DataMem>(data_mem);
130 struct DataMemAndPtr : StrippedAccept<DataMemAndPtr> {
131 template <
typename...
Args>
134 template <
typename R,
typename C,
typename Ptr>
135 struct AcceptImpl<R
C::*, Ptr>
136 : std::integral_constant<bool, !std::is_base_of<C, Ptr>::value &&
137 !absl::is_function<R>::value> {};
139 template <
typename DataMem,
typename Ptr>
140 static decltype((*std::declval<Ptr>()).*std::declval<DataMem>())
Invoke(
141 DataMem&& data_mem, Ptr&&
ptr) {
142 return (*std::forward<Ptr>(
ptr)).*std::forward<DataMem>(data_mem);
150 template <
typename F,
typename...
Args>
151 static decltype(std::declval<F>()(std::declval<Args>()...))
Invoke(
153 return std::forward<F>(f)(std::forward<Args>(
args)...);
158 template <
typename...
Args>
160 typedef typename std::conditional<
161 MemFunAndRef::Accept<
Args...>
::value, MemFunAndRef,
162 typename std::conditional<
163 MemFunAndPtr::Accept<
Args...>
::value, MemFunAndPtr,
164 typename std::conditional<
165 DataMemAndRef::Accept<
Args...>
::value, DataMemAndRef,
166 typename std::conditional<DataMemAndPtr::Accept<
Args...>
::value,
172 template <
typename F,
typename...
Args>
174 std::declval<F>(), std::declval<Args>()...));
178 template <
typename F,
typename...
Args>
181 std::forward<Args>(
args)...);
187 #endif // ABSL_BASE_INTERNAL_INVOKE_H_