File indexing completed on 2025-12-16 09:40:42
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037 #ifndef ABSL_BASE_INTERNAL_INVOKE_H_
0038 #define ABSL_BASE_INTERNAL_INVOKE_H_
0039
0040 #include "absl/base/config.h"
0041
0042 #if ABSL_INTERNAL_CPLUSPLUS_LANG >= 201703L
0043
0044 #include <functional>
0045
0046 namespace absl {
0047 ABSL_NAMESPACE_BEGIN
0048 namespace base_internal {
0049
0050 using std::invoke;
0051 using std::invoke_result_t;
0052 using std::is_invocable_r;
0053
0054 }
0055 ABSL_NAMESPACE_END
0056 }
0057
0058 #else
0059
0060 #include <algorithm>
0061 #include <type_traits>
0062 #include <utility>
0063
0064 #include "absl/meta/type_traits.h"
0065
0066
0067
0068
0069 namespace absl {
0070 ABSL_NAMESPACE_BEGIN
0071 namespace base_internal {
0072
0073
0074
0075
0076
0077
0078
0079
0080
0081 template <typename Derived>
0082 struct StrippedAccept {
0083 template <typename... Args>
0084 struct Accept : Derived::template AcceptImpl<typename std::remove_cv<
0085 typename std::remove_reference<Args>::type>::type...> {};
0086 };
0087
0088
0089
0090
0091 struct MemFunAndRef : StrippedAccept<MemFunAndRef> {
0092 template <typename... Args>
0093 struct AcceptImpl : std::false_type {};
0094
0095 template <typename MemFunType, typename C, typename Obj, typename... Args>
0096 struct AcceptImpl<MemFunType C::*, Obj, Args...>
0097 : std::integral_constant<bool, std::is_base_of<C, Obj>::value &&
0098 absl::is_function<MemFunType>::value> {
0099 };
0100
0101 template <typename MemFun, typename Obj, typename... Args>
0102 static decltype((std::declval<Obj>().*
0103 std::declval<MemFun>())(std::declval<Args>()...))
0104 Invoke(MemFun&& mem_fun, Obj&& obj, Args&&... args) {
0105
0106
0107 #if ABSL_INTERNAL_HAVE_MIN_GNUC_VERSION(11, 0)
0108 #pragma GCC diagnostic push
0109 #pragma GCC diagnostic ignored "-Warray-bounds"
0110 #pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
0111 #endif
0112 return (std::forward<Obj>(obj).*
0113 std::forward<MemFun>(mem_fun))(std::forward<Args>(args)...);
0114 #if ABSL_INTERNAL_HAVE_MIN_GNUC_VERSION(11, 0)
0115 #pragma GCC diagnostic pop
0116 #endif
0117 }
0118 };
0119
0120
0121
0122 struct MemFunAndPtr : StrippedAccept<MemFunAndPtr> {
0123 template <typename... Args>
0124 struct AcceptImpl : std::false_type {};
0125
0126 template <typename MemFunType, typename C, typename Ptr, typename... Args>
0127 struct AcceptImpl<MemFunType C::*, Ptr, Args...>
0128 : std::integral_constant<bool, !std::is_base_of<C, Ptr>::value &&
0129 absl::is_function<MemFunType>::value> {
0130 };
0131
0132 template <typename MemFun, typename Ptr, typename... Args>
0133 static decltype(((*std::declval<Ptr>()).*
0134 std::declval<MemFun>())(std::declval<Args>()...))
0135 Invoke(MemFun&& mem_fun, Ptr&& ptr, Args&&... args) {
0136 return ((*std::forward<Ptr>(ptr)).*
0137 std::forward<MemFun>(mem_fun))(std::forward<Args>(args)...);
0138 }
0139 };
0140
0141
0142
0143
0144 struct DataMemAndRef : StrippedAccept<DataMemAndRef> {
0145 template <typename... Args>
0146 struct AcceptImpl : std::false_type {};
0147
0148 template <typename R, typename C, typename Obj>
0149 struct AcceptImpl<R C::*, Obj>
0150 : std::integral_constant<bool, std::is_base_of<C, Obj>::value &&
0151 !absl::is_function<R>::value> {};
0152
0153 template <typename DataMem, typename Ref>
0154 static decltype(std::declval<Ref>().*std::declval<DataMem>()) Invoke(
0155 DataMem&& data_mem, Ref&& ref) {
0156 return std::forward<Ref>(ref).*std::forward<DataMem>(data_mem);
0157 }
0158 };
0159
0160
0161
0162 struct DataMemAndPtr : StrippedAccept<DataMemAndPtr> {
0163 template <typename... Args>
0164 struct AcceptImpl : std::false_type {};
0165
0166 template <typename R, typename C, typename Ptr>
0167 struct AcceptImpl<R C::*, Ptr>
0168 : std::integral_constant<bool, !std::is_base_of<C, Ptr>::value &&
0169 !absl::is_function<R>::value> {};
0170
0171 template <typename DataMem, typename Ptr>
0172 static decltype((*std::declval<Ptr>()).*std::declval<DataMem>()) Invoke(
0173 DataMem&& data_mem, Ptr&& ptr) {
0174 return (*std::forward<Ptr>(ptr)).*std::forward<DataMem>(data_mem);
0175 }
0176 };
0177
0178
0179 struct Callable {
0180
0181
0182 template <typename F, typename... Args>
0183 static decltype(std::declval<F>()(std::declval<Args>()...)) Invoke(
0184 F&& f, Args&&... args) {
0185 return std::forward<F>(f)(std::forward<Args>(args)...);
0186 }
0187 };
0188
0189
0190 template <typename... Args>
0191 struct Invoker {
0192 typedef typename std::conditional<
0193 MemFunAndRef::Accept<Args...>::value, MemFunAndRef,
0194 typename std::conditional<
0195 MemFunAndPtr::Accept<Args...>::value, MemFunAndPtr,
0196 typename std::conditional<
0197 DataMemAndRef::Accept<Args...>::value, DataMemAndRef,
0198 typename std::conditional<DataMemAndPtr::Accept<Args...>::value,
0199 DataMemAndPtr, Callable>::type>::type>::
0200 type>::type type;
0201 };
0202
0203
0204 template <typename F, typename... Args>
0205 using invoke_result_t = decltype(Invoker<F, Args...>::type::Invoke(
0206 std::declval<F>(), std::declval<Args>()...));
0207
0208
0209
0210 template <typename F, typename... Args>
0211 invoke_result_t<F, Args...> invoke(F&& f, Args&&... args) {
0212 return Invoker<F, Args...>::type::Invoke(std::forward<F>(f),
0213 std::forward<Args>(args)...);
0214 }
0215
0216 template <typename AlwaysVoid, typename, typename, typename...>
0217 struct IsInvocableRImpl : std::false_type {};
0218
0219 template <typename R, typename F, typename... Args>
0220 struct IsInvocableRImpl<
0221 absl::void_t<absl::base_internal::invoke_result_t<F, Args...> >, R, F,
0222 Args...>
0223 : std::integral_constant<
0224 bool,
0225 std::is_convertible<absl::base_internal::invoke_result_t<F, Args...>,
0226 R>::value ||
0227 std::is_void<R>::value> {};
0228
0229
0230
0231
0232 template <typename R, typename F, typename... Args>
0233 using is_invocable_r = IsInvocableRImpl<void, R, F, Args...>;
0234
0235 }
0236 ABSL_NAMESPACE_END
0237 }
0238
0239 #endif
0240
0241 #endif