1*9356374aSAndroid Build Coastguard Worker // Copyright 2017 The Abseil Authors. 2*9356374aSAndroid Build Coastguard Worker // 3*9356374aSAndroid Build Coastguard Worker // Licensed under the Apache License, Version 2.0 (the "License"); 4*9356374aSAndroid Build Coastguard Worker // you may not use this file except in compliance with the License. 5*9356374aSAndroid Build Coastguard Worker // You may obtain a copy of the License at 6*9356374aSAndroid Build Coastguard Worker // 7*9356374aSAndroid Build Coastguard Worker // https://www.apache.org/licenses/LICENSE-2.0 8*9356374aSAndroid Build Coastguard Worker // 9*9356374aSAndroid Build Coastguard Worker // Unless required by applicable law or agreed to in writing, software 10*9356374aSAndroid Build Coastguard Worker // distributed under the License is distributed on an "AS IS" BASIS, 11*9356374aSAndroid Build Coastguard Worker // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12*9356374aSAndroid Build Coastguard Worker // See the License for the specific language governing permissions and 13*9356374aSAndroid Build Coastguard Worker // limitations under the License. 14*9356374aSAndroid Build Coastguard Worker // 15*9356374aSAndroid Build Coastguard Worker // absl::base_internal::invoke(f, args...) is an implementation of 16*9356374aSAndroid Build Coastguard Worker // INVOKE(f, args...) from section [func.require] of the C++ standard. 17*9356374aSAndroid Build Coastguard Worker // When compiled as C++17 and later versions, it is implemented as an alias of 18*9356374aSAndroid Build Coastguard Worker // std::invoke. 19*9356374aSAndroid Build Coastguard Worker // 20*9356374aSAndroid Build Coastguard Worker // [func.require] 21*9356374aSAndroid Build Coastguard Worker // Define INVOKE (f, t1, t2, ..., tN) as follows: 22*9356374aSAndroid Build Coastguard Worker // 1. (t1.*f)(t2, ..., tN) when f is a pointer to a member function of a class T 23*9356374aSAndroid Build Coastguard Worker // and t1 is an object of type T or a reference to an object of type T or a 24*9356374aSAndroid Build Coastguard Worker // reference to an object of a type derived from T; 25*9356374aSAndroid Build Coastguard Worker // 2. ((*t1).*f)(t2, ..., tN) when f is a pointer to a member function of a 26*9356374aSAndroid Build Coastguard Worker // class T and t1 is not one of the types described in the previous item; 27*9356374aSAndroid Build Coastguard Worker // 3. t1.*f when N == 1 and f is a pointer to member data of a class T and t1 is 28*9356374aSAndroid Build Coastguard Worker // an object of type T or a reference to an object of type T or a reference 29*9356374aSAndroid Build Coastguard Worker // to an object of a type derived from T; 30*9356374aSAndroid Build Coastguard Worker // 4. (*t1).*f when N == 1 and f is a pointer to member data of a class T and t1 31*9356374aSAndroid Build Coastguard Worker // is not one of the types described in the previous item; 32*9356374aSAndroid Build Coastguard Worker // 5. f(t1, t2, ..., tN) in all other cases. 33*9356374aSAndroid Build Coastguard Worker // 34*9356374aSAndroid Build Coastguard Worker // The implementation is SFINAE-friendly: substitution failure within invoke() 35*9356374aSAndroid Build Coastguard Worker // isn't an error. 36*9356374aSAndroid Build Coastguard Worker 37*9356374aSAndroid Build Coastguard Worker #ifndef ABSL_BASE_INTERNAL_INVOKE_H_ 38*9356374aSAndroid Build Coastguard Worker #define ABSL_BASE_INTERNAL_INVOKE_H_ 39*9356374aSAndroid Build Coastguard Worker 40*9356374aSAndroid Build Coastguard Worker #include "absl/base/config.h" 41*9356374aSAndroid Build Coastguard Worker 42*9356374aSAndroid Build Coastguard Worker #if ABSL_INTERNAL_CPLUSPLUS_LANG >= 201703L 43*9356374aSAndroid Build Coastguard Worker 44*9356374aSAndroid Build Coastguard Worker #include <functional> 45*9356374aSAndroid Build Coastguard Worker 46*9356374aSAndroid Build Coastguard Worker namespace absl { 47*9356374aSAndroid Build Coastguard Worker ABSL_NAMESPACE_BEGIN 48*9356374aSAndroid Build Coastguard Worker namespace base_internal { 49*9356374aSAndroid Build Coastguard Worker 50*9356374aSAndroid Build Coastguard Worker using std::invoke; 51*9356374aSAndroid Build Coastguard Worker using std::invoke_result_t; 52*9356374aSAndroid Build Coastguard Worker using std::is_invocable_r; 53*9356374aSAndroid Build Coastguard Worker 54*9356374aSAndroid Build Coastguard Worker } // namespace base_internal 55*9356374aSAndroid Build Coastguard Worker ABSL_NAMESPACE_END 56*9356374aSAndroid Build Coastguard Worker } // namespace absl 57*9356374aSAndroid Build Coastguard Worker 58*9356374aSAndroid Build Coastguard Worker #else // ABSL_INTERNAL_CPLUSPLUS_LANG >= 201703L 59*9356374aSAndroid Build Coastguard Worker 60*9356374aSAndroid Build Coastguard Worker #include <algorithm> 61*9356374aSAndroid Build Coastguard Worker #include <type_traits> 62*9356374aSAndroid Build Coastguard Worker #include <utility> 63*9356374aSAndroid Build Coastguard Worker 64*9356374aSAndroid Build Coastguard Worker #include "absl/meta/type_traits.h" 65*9356374aSAndroid Build Coastguard Worker 66*9356374aSAndroid Build Coastguard Worker // The following code is internal implementation detail. See the comment at the 67*9356374aSAndroid Build Coastguard Worker // top of this file for the API documentation. 68*9356374aSAndroid Build Coastguard Worker 69*9356374aSAndroid Build Coastguard Worker namespace absl { 70*9356374aSAndroid Build Coastguard Worker ABSL_NAMESPACE_BEGIN 71*9356374aSAndroid Build Coastguard Worker namespace base_internal { 72*9356374aSAndroid Build Coastguard Worker 73*9356374aSAndroid Build Coastguard Worker // The five classes below each implement one of the clauses from the definition 74*9356374aSAndroid Build Coastguard Worker // of INVOKE. The inner class template Accept<F, Args...> checks whether the 75*9356374aSAndroid Build Coastguard Worker // clause is applicable; static function template Invoke(f, args...) does the 76*9356374aSAndroid Build Coastguard Worker // invocation. 77*9356374aSAndroid Build Coastguard Worker // 78*9356374aSAndroid Build Coastguard Worker // By separating the clause selection logic from invocation we make sure that 79*9356374aSAndroid Build Coastguard Worker // Invoke() does exactly what the standard says. 80*9356374aSAndroid Build Coastguard Worker 81*9356374aSAndroid Build Coastguard Worker template <typename Derived> 82*9356374aSAndroid Build Coastguard Worker struct StrippedAccept { 83*9356374aSAndroid Build Coastguard Worker template <typename... Args> 84*9356374aSAndroid Build Coastguard Worker struct Accept : Derived::template AcceptImpl<typename std::remove_cv< 85*9356374aSAndroid Build Coastguard Worker typename std::remove_reference<Args>::type>::type...> {}; 86*9356374aSAndroid Build Coastguard Worker }; 87*9356374aSAndroid Build Coastguard Worker 88*9356374aSAndroid Build Coastguard Worker // (t1.*f)(t2, ..., tN) when f is a pointer to a member function of a class T 89*9356374aSAndroid Build Coastguard Worker // and t1 is an object of type T or a reference to an object of type T or a 90*9356374aSAndroid Build Coastguard Worker // reference to an object of a type derived from T. 91*9356374aSAndroid Build Coastguard Worker struct MemFunAndRef : StrippedAccept<MemFunAndRef> { 92*9356374aSAndroid Build Coastguard Worker template <typename... Args> 93*9356374aSAndroid Build Coastguard Worker struct AcceptImpl : std::false_type {}; 94*9356374aSAndroid Build Coastguard Worker 95*9356374aSAndroid Build Coastguard Worker template <typename MemFunType, typename C, typename Obj, typename... Args> 96*9356374aSAndroid Build Coastguard Worker struct AcceptImpl<MemFunType C::*, Obj, Args...> 97*9356374aSAndroid Build Coastguard Worker : std::integral_constant<bool, std::is_base_of<C, Obj>::value && 98*9356374aSAndroid Build Coastguard Worker absl::is_function<MemFunType>::value> { 99*9356374aSAndroid Build Coastguard Worker }; 100*9356374aSAndroid Build Coastguard Worker 101*9356374aSAndroid Build Coastguard Worker template <typename MemFun, typename Obj, typename... Args> 102*9356374aSAndroid Build Coastguard Worker static decltype((std::declval<Obj>().* 103*9356374aSAndroid Build Coastguard Worker std::declval<MemFun>())(std::declval<Args>()...)) 104*9356374aSAndroid Build Coastguard Worker Invoke(MemFun&& mem_fun, Obj&& obj, Args&&... args) { 105*9356374aSAndroid Build Coastguard Worker // Ignore bogus GCC warnings on this line. 106*9356374aSAndroid Build Coastguard Worker // See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101436 for similar example. 107*9356374aSAndroid Build Coastguard Worker #if ABSL_INTERNAL_HAVE_MIN_GNUC_VERSION(11, 0) 108*9356374aSAndroid Build Coastguard Worker #pragma GCC diagnostic push 109*9356374aSAndroid Build Coastguard Worker #pragma GCC diagnostic ignored "-Warray-bounds" 110*9356374aSAndroid Build Coastguard Worker #pragma GCC diagnostic ignored "-Wmaybe-uninitialized" 111*9356374aSAndroid Build Coastguard Worker #endif 112*9356374aSAndroid Build Coastguard Worker return (std::forward<Obj>(obj).* 113*9356374aSAndroid Build Coastguard Worker std::forward<MemFun>(mem_fun))(std::forward<Args>(args)...); 114*9356374aSAndroid Build Coastguard Worker #if ABSL_INTERNAL_HAVE_MIN_GNUC_VERSION(11, 0) 115*9356374aSAndroid Build Coastguard Worker #pragma GCC diagnostic pop 116*9356374aSAndroid Build Coastguard Worker #endif 117*9356374aSAndroid Build Coastguard Worker } 118*9356374aSAndroid Build Coastguard Worker }; 119*9356374aSAndroid Build Coastguard Worker 120*9356374aSAndroid Build Coastguard Worker // ((*t1).*f)(t2, ..., tN) when f is a pointer to a member function of a 121*9356374aSAndroid Build Coastguard Worker // class T and t1 is not one of the types described in the previous item. 122*9356374aSAndroid Build Coastguard Worker struct MemFunAndPtr : StrippedAccept<MemFunAndPtr> { 123*9356374aSAndroid Build Coastguard Worker template <typename... Args> 124*9356374aSAndroid Build Coastguard Worker struct AcceptImpl : std::false_type {}; 125*9356374aSAndroid Build Coastguard Worker 126*9356374aSAndroid Build Coastguard Worker template <typename MemFunType, typename C, typename Ptr, typename... Args> 127*9356374aSAndroid Build Coastguard Worker struct AcceptImpl<MemFunType C::*, Ptr, Args...> 128*9356374aSAndroid Build Coastguard Worker : std::integral_constant<bool, !std::is_base_of<C, Ptr>::value && 129*9356374aSAndroid Build Coastguard Worker absl::is_function<MemFunType>::value> { 130*9356374aSAndroid Build Coastguard Worker }; 131*9356374aSAndroid Build Coastguard Worker 132*9356374aSAndroid Build Coastguard Worker template <typename MemFun, typename Ptr, typename... Args> 133*9356374aSAndroid Build Coastguard Worker static decltype(((*std::declval<Ptr>()).* 134*9356374aSAndroid Build Coastguard Worker std::declval<MemFun>())(std::declval<Args>()...)) 135*9356374aSAndroid Build Coastguard Worker Invoke(MemFun&& mem_fun, Ptr&& ptr, Args&&... args) { 136*9356374aSAndroid Build Coastguard Worker return ((*std::forward<Ptr>(ptr)).* 137*9356374aSAndroid Build Coastguard Worker std::forward<MemFun>(mem_fun))(std::forward<Args>(args)...); 138*9356374aSAndroid Build Coastguard Worker } 139*9356374aSAndroid Build Coastguard Worker }; 140*9356374aSAndroid Build Coastguard Worker 141*9356374aSAndroid Build Coastguard Worker // t1.*f when N == 1 and f is a pointer to member data of a class T and t1 is 142*9356374aSAndroid Build Coastguard Worker // an object of type T or a reference to an object of type T or a reference 143*9356374aSAndroid Build Coastguard Worker // to an object of a type derived from T. 144*9356374aSAndroid Build Coastguard Worker struct DataMemAndRef : StrippedAccept<DataMemAndRef> { 145*9356374aSAndroid Build Coastguard Worker template <typename... Args> 146*9356374aSAndroid Build Coastguard Worker struct AcceptImpl : std::false_type {}; 147*9356374aSAndroid Build Coastguard Worker 148*9356374aSAndroid Build Coastguard Worker template <typename R, typename C, typename Obj> 149*9356374aSAndroid Build Coastguard Worker struct AcceptImpl<R C::*, Obj> 150*9356374aSAndroid Build Coastguard Worker : std::integral_constant<bool, std::is_base_of<C, Obj>::value && 151*9356374aSAndroid Build Coastguard Worker !absl::is_function<R>::value> {}; 152*9356374aSAndroid Build Coastguard Worker 153*9356374aSAndroid Build Coastguard Worker template <typename DataMem, typename Ref> 154*9356374aSAndroid Build Coastguard Worker static decltype(std::declval<Ref>().*std::declval<DataMem>()) Invoke( 155*9356374aSAndroid Build Coastguard Worker DataMem&& data_mem, Ref&& ref) { 156*9356374aSAndroid Build Coastguard Worker return std::forward<Ref>(ref).*std::forward<DataMem>(data_mem); 157*9356374aSAndroid Build Coastguard Worker } 158*9356374aSAndroid Build Coastguard Worker }; 159*9356374aSAndroid Build Coastguard Worker 160*9356374aSAndroid Build Coastguard Worker // (*t1).*f when N == 1 and f is a pointer to member data of a class T and t1 161*9356374aSAndroid Build Coastguard Worker // is not one of the types described in the previous item. 162*9356374aSAndroid Build Coastguard Worker struct DataMemAndPtr : StrippedAccept<DataMemAndPtr> { 163*9356374aSAndroid Build Coastguard Worker template <typename... Args> 164*9356374aSAndroid Build Coastguard Worker struct AcceptImpl : std::false_type {}; 165*9356374aSAndroid Build Coastguard Worker 166*9356374aSAndroid Build Coastguard Worker template <typename R, typename C, typename Ptr> 167*9356374aSAndroid Build Coastguard Worker struct AcceptImpl<R C::*, Ptr> 168*9356374aSAndroid Build Coastguard Worker : std::integral_constant<bool, !std::is_base_of<C, Ptr>::value && 169*9356374aSAndroid Build Coastguard Worker !absl::is_function<R>::value> {}; 170*9356374aSAndroid Build Coastguard Worker 171*9356374aSAndroid Build Coastguard Worker template <typename DataMem, typename Ptr> 172*9356374aSAndroid Build Coastguard Worker static decltype((*std::declval<Ptr>()).*std::declval<DataMem>()) Invoke( 173*9356374aSAndroid Build Coastguard Worker DataMem&& data_mem, Ptr&& ptr) { 174*9356374aSAndroid Build Coastguard Worker return (*std::forward<Ptr>(ptr)).*std::forward<DataMem>(data_mem); 175*9356374aSAndroid Build Coastguard Worker } 176*9356374aSAndroid Build Coastguard Worker }; 177*9356374aSAndroid Build Coastguard Worker 178*9356374aSAndroid Build Coastguard Worker // f(t1, t2, ..., tN) in all other cases. 179*9356374aSAndroid Build Coastguard Worker struct Callable { 180*9356374aSAndroid Build Coastguard Worker // Callable doesn't have Accept because it's the last clause that gets picked 181*9356374aSAndroid Build Coastguard Worker // when none of the previous clauses are applicable. 182*9356374aSAndroid Build Coastguard Worker template <typename F, typename... Args> 183*9356374aSAndroid Build Coastguard Worker static decltype(std::declval<F>()(std::declval<Args>()...)) Invoke( 184*9356374aSAndroid Build Coastguard Worker F&& f, Args&&... args) { 185*9356374aSAndroid Build Coastguard Worker return std::forward<F>(f)(std::forward<Args>(args)...); 186*9356374aSAndroid Build Coastguard Worker } 187*9356374aSAndroid Build Coastguard Worker }; 188*9356374aSAndroid Build Coastguard Worker 189*9356374aSAndroid Build Coastguard Worker // Resolves to the first matching clause. 190*9356374aSAndroid Build Coastguard Worker template <typename... Args> 191*9356374aSAndroid Build Coastguard Worker struct Invoker { 192*9356374aSAndroid Build Coastguard Worker typedef typename std::conditional< 193*9356374aSAndroid Build Coastguard Worker MemFunAndRef::Accept<Args...>::value, MemFunAndRef, 194*9356374aSAndroid Build Coastguard Worker typename std::conditional< 195*9356374aSAndroid Build Coastguard Worker MemFunAndPtr::Accept<Args...>::value, MemFunAndPtr, 196*9356374aSAndroid Build Coastguard Worker typename std::conditional< 197*9356374aSAndroid Build Coastguard Worker DataMemAndRef::Accept<Args...>::value, DataMemAndRef, 198*9356374aSAndroid Build Coastguard Worker typename std::conditional<DataMemAndPtr::Accept<Args...>::value, 199*9356374aSAndroid Build Coastguard Worker DataMemAndPtr, Callable>::type>::type>:: 200*9356374aSAndroid Build Coastguard Worker type>::type type; 201*9356374aSAndroid Build Coastguard Worker }; 202*9356374aSAndroid Build Coastguard Worker 203*9356374aSAndroid Build Coastguard Worker // The result type of Invoke<F, Args...>. 204*9356374aSAndroid Build Coastguard Worker template <typename F, typename... Args> 205*9356374aSAndroid Build Coastguard Worker using invoke_result_t = decltype(Invoker<F, Args...>::type::Invoke( 206*9356374aSAndroid Build Coastguard Worker std::declval<F>(), std::declval<Args>()...)); 207*9356374aSAndroid Build Coastguard Worker 208*9356374aSAndroid Build Coastguard Worker // Invoke(f, args...) is an implementation of INVOKE(f, args...) from section 209*9356374aSAndroid Build Coastguard Worker // [func.require] of the C++ standard. 210*9356374aSAndroid Build Coastguard Worker template <typename F, typename... Args> 211*9356374aSAndroid Build Coastguard Worker invoke_result_t<F, Args...> invoke(F&& f, Args&&... args) { 212*9356374aSAndroid Build Coastguard Worker return Invoker<F, Args...>::type::Invoke(std::forward<F>(f), 213*9356374aSAndroid Build Coastguard Worker std::forward<Args>(args)...); 214*9356374aSAndroid Build Coastguard Worker } 215*9356374aSAndroid Build Coastguard Worker 216*9356374aSAndroid Build Coastguard Worker template <typename AlwaysVoid, typename, typename, typename...> 217*9356374aSAndroid Build Coastguard Worker struct IsInvocableRImpl : std::false_type {}; 218*9356374aSAndroid Build Coastguard Worker 219*9356374aSAndroid Build Coastguard Worker template <typename R, typename F, typename... Args> 220*9356374aSAndroid Build Coastguard Worker struct IsInvocableRImpl< 221*9356374aSAndroid Build Coastguard Worker absl::void_t<absl::base_internal::invoke_result_t<F, Args...> >, R, F, 222*9356374aSAndroid Build Coastguard Worker Args...> 223*9356374aSAndroid Build Coastguard Worker : std::integral_constant< 224*9356374aSAndroid Build Coastguard Worker bool, 225*9356374aSAndroid Build Coastguard Worker std::is_convertible<absl::base_internal::invoke_result_t<F, Args...>, 226*9356374aSAndroid Build Coastguard Worker R>::value || 227*9356374aSAndroid Build Coastguard Worker std::is_void<R>::value> {}; 228*9356374aSAndroid Build Coastguard Worker 229*9356374aSAndroid Build Coastguard Worker // Type trait whose member `value` is true if invoking `F` with `Args` is valid, 230*9356374aSAndroid Build Coastguard Worker // and either the return type is convertible to `R`, or `R` is void. 231*9356374aSAndroid Build Coastguard Worker // C++11-compatible version of `std::is_invocable_r`. 232*9356374aSAndroid Build Coastguard Worker template <typename R, typename F, typename... Args> 233*9356374aSAndroid Build Coastguard Worker using is_invocable_r = IsInvocableRImpl<void, R, F, Args...>; 234*9356374aSAndroid Build Coastguard Worker 235*9356374aSAndroid Build Coastguard Worker } // namespace base_internal 236*9356374aSAndroid Build Coastguard Worker ABSL_NAMESPACE_END 237*9356374aSAndroid Build Coastguard Worker } // namespace absl 238*9356374aSAndroid Build Coastguard Worker 239*9356374aSAndroid Build Coastguard Worker #endif // ABSL_INTERNAL_CPLUSPLUS_LANG >= 201703L 240*9356374aSAndroid Build Coastguard Worker 241*9356374aSAndroid Build Coastguard Worker #endif // ABSL_BASE_INTERNAL_INVOKE_H_ 242