1*9356374aSAndroid Build Coastguard Worker // Copyright 2022 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 // Implementation details for `absl::AnyInvocable` 16*9356374aSAndroid Build Coastguard Worker 17*9356374aSAndroid Build Coastguard Worker #ifndef ABSL_FUNCTIONAL_INTERNAL_ANY_INVOCABLE_H_ 18*9356374aSAndroid Build Coastguard Worker #define ABSL_FUNCTIONAL_INTERNAL_ANY_INVOCABLE_H_ 19*9356374aSAndroid Build Coastguard Worker 20*9356374aSAndroid Build Coastguard Worker //////////////////////////////////////////////////////////////////////////////// 21*9356374aSAndroid Build Coastguard Worker // // 22*9356374aSAndroid Build Coastguard Worker // This implementation chooses between local storage and remote storage for // 23*9356374aSAndroid Build Coastguard Worker // the contained target object based on the target object's size, alignment // 24*9356374aSAndroid Build Coastguard Worker // requirements, and whether or not it has a nothrow move constructor. // 25*9356374aSAndroid Build Coastguard Worker // Additional optimizations are performed when the object is a trivially // 26*9356374aSAndroid Build Coastguard Worker // copyable type [basic.types]. // 27*9356374aSAndroid Build Coastguard Worker // // 28*9356374aSAndroid Build Coastguard Worker // There are three datamembers per `AnyInvocable` instance // 29*9356374aSAndroid Build Coastguard Worker // // 30*9356374aSAndroid Build Coastguard Worker // 1) A union containing either // 31*9356374aSAndroid Build Coastguard Worker // - A pointer to the target object referred to via a void*, or // 32*9356374aSAndroid Build Coastguard Worker // - the target object, emplaced into a raw char buffer // 33*9356374aSAndroid Build Coastguard Worker // // 34*9356374aSAndroid Build Coastguard Worker // 2) A function pointer to a "manager" function operation that takes a // 35*9356374aSAndroid Build Coastguard Worker // discriminator and logically branches to either perform a move operation // 36*9356374aSAndroid Build Coastguard Worker // or destroy operation based on that discriminator. // 37*9356374aSAndroid Build Coastguard Worker // // 38*9356374aSAndroid Build Coastguard Worker // 3) A function pointer to an "invoker" function operation that invokes the // 39*9356374aSAndroid Build Coastguard Worker // target object, directly returning the result. // 40*9356374aSAndroid Build Coastguard Worker // // 41*9356374aSAndroid Build Coastguard Worker // When in the logically empty state, the manager function is an empty // 42*9356374aSAndroid Build Coastguard Worker // function and the invoker function is one that would be undefined behavior // 43*9356374aSAndroid Build Coastguard Worker // to call. // 44*9356374aSAndroid Build Coastguard Worker // // 45*9356374aSAndroid Build Coastguard Worker // An additional optimization is performed when converting from one // 46*9356374aSAndroid Build Coastguard Worker // AnyInvocable to another where only the noexcept specification and/or the // 47*9356374aSAndroid Build Coastguard Worker // cv/ref qualifiers of the function type differ. In these cases, the // 48*9356374aSAndroid Build Coastguard Worker // conversion works by "moving the guts", similar to if they were the same // 49*9356374aSAndroid Build Coastguard Worker // exact type, as opposed to having to perform an additional layer of // 50*9356374aSAndroid Build Coastguard Worker // wrapping through remote storage. // 51*9356374aSAndroid Build Coastguard Worker // // 52*9356374aSAndroid Build Coastguard Worker //////////////////////////////////////////////////////////////////////////////// 53*9356374aSAndroid Build Coastguard Worker 54*9356374aSAndroid Build Coastguard Worker // IWYU pragma: private, include "absl/functional/any_invocable.h" 55*9356374aSAndroid Build Coastguard Worker 56*9356374aSAndroid Build Coastguard Worker #include <cassert> 57*9356374aSAndroid Build Coastguard Worker #include <cstddef> 58*9356374aSAndroid Build Coastguard Worker #include <cstring> 59*9356374aSAndroid Build Coastguard Worker #include <exception> 60*9356374aSAndroid Build Coastguard Worker #include <functional> 61*9356374aSAndroid Build Coastguard Worker #include <memory> 62*9356374aSAndroid Build Coastguard Worker #include <new> 63*9356374aSAndroid Build Coastguard Worker #include <type_traits> 64*9356374aSAndroid Build Coastguard Worker #include <utility> 65*9356374aSAndroid Build Coastguard Worker 66*9356374aSAndroid Build Coastguard Worker #include "absl/base/attributes.h" 67*9356374aSAndroid Build Coastguard Worker #include "absl/base/config.h" 68*9356374aSAndroid Build Coastguard Worker #include "absl/base/internal/invoke.h" 69*9356374aSAndroid Build Coastguard Worker #include "absl/base/macros.h" 70*9356374aSAndroid Build Coastguard Worker #include "absl/base/optimization.h" 71*9356374aSAndroid Build Coastguard Worker #include "absl/meta/type_traits.h" 72*9356374aSAndroid Build Coastguard Worker #include "absl/utility/utility.h" 73*9356374aSAndroid Build Coastguard Worker 74*9356374aSAndroid Build Coastguard Worker namespace absl { 75*9356374aSAndroid Build Coastguard Worker ABSL_NAMESPACE_BEGIN 76*9356374aSAndroid Build Coastguard Worker 77*9356374aSAndroid Build Coastguard Worker // Helper macro used to prevent spelling `noexcept` in language versions older 78*9356374aSAndroid Build Coastguard Worker // than C++17, where it is not part of the type system, in order to avoid 79*9356374aSAndroid Build Coastguard Worker // compilation failures and internal compiler errors. 80*9356374aSAndroid Build Coastguard Worker #if ABSL_INTERNAL_CPLUSPLUS_LANG >= 201703L 81*9356374aSAndroid Build Coastguard Worker #define ABSL_INTERNAL_NOEXCEPT_SPEC(noex) noexcept(noex) 82*9356374aSAndroid Build Coastguard Worker #else 83*9356374aSAndroid Build Coastguard Worker #define ABSL_INTERNAL_NOEXCEPT_SPEC(noex) 84*9356374aSAndroid Build Coastguard Worker #endif 85*9356374aSAndroid Build Coastguard Worker 86*9356374aSAndroid Build Coastguard Worker // Defined in functional/any_invocable.h 87*9356374aSAndroid Build Coastguard Worker template <class Sig> 88*9356374aSAndroid Build Coastguard Worker class AnyInvocable; 89*9356374aSAndroid Build Coastguard Worker 90*9356374aSAndroid Build Coastguard Worker namespace internal_any_invocable { 91*9356374aSAndroid Build Coastguard Worker 92*9356374aSAndroid Build Coastguard Worker // Constants relating to the small-object-storage for AnyInvocable 93*9356374aSAndroid Build Coastguard Worker enum StorageProperty : std::size_t { 94*9356374aSAndroid Build Coastguard Worker kAlignment = alignof(std::max_align_t), // The alignment of the storage 95*9356374aSAndroid Build Coastguard Worker kStorageSize = sizeof(void*) * 2 // The size of the storage 96*9356374aSAndroid Build Coastguard Worker }; 97*9356374aSAndroid Build Coastguard Worker 98*9356374aSAndroid Build Coastguard Worker //////////////////////////////////////////////////////////////////////////////// 99*9356374aSAndroid Build Coastguard Worker // 100*9356374aSAndroid Build Coastguard Worker // A metafunction for checking if a type is an AnyInvocable instantiation. 101*9356374aSAndroid Build Coastguard Worker // This is used during conversion operations. 102*9356374aSAndroid Build Coastguard Worker template <class T> 103*9356374aSAndroid Build Coastguard Worker struct IsAnyInvocable : std::false_type {}; 104*9356374aSAndroid Build Coastguard Worker 105*9356374aSAndroid Build Coastguard Worker template <class Sig> 106*9356374aSAndroid Build Coastguard Worker struct IsAnyInvocable<AnyInvocable<Sig>> : std::true_type {}; 107*9356374aSAndroid Build Coastguard Worker // 108*9356374aSAndroid Build Coastguard Worker //////////////////////////////////////////////////////////////////////////////// 109*9356374aSAndroid Build Coastguard Worker 110*9356374aSAndroid Build Coastguard Worker // A type trait that tells us whether or not a target function type should be 111*9356374aSAndroid Build Coastguard Worker // stored locally in the small object optimization storage 112*9356374aSAndroid Build Coastguard Worker template <class T> 113*9356374aSAndroid Build Coastguard Worker using IsStoredLocally = std::integral_constant< 114*9356374aSAndroid Build Coastguard Worker bool, sizeof(T) <= kStorageSize && alignof(T) <= kAlignment && 115*9356374aSAndroid Build Coastguard Worker kAlignment % alignof(T) == 0 && 116*9356374aSAndroid Build Coastguard Worker std::is_nothrow_move_constructible<T>::value>; 117*9356374aSAndroid Build Coastguard Worker 118*9356374aSAndroid Build Coastguard Worker // An implementation of std::remove_cvref_t of C++20. 119*9356374aSAndroid Build Coastguard Worker template <class T> 120*9356374aSAndroid Build Coastguard Worker using RemoveCVRef = 121*9356374aSAndroid Build Coastguard Worker typename std::remove_cv<typename std::remove_reference<T>::type>::type; 122*9356374aSAndroid Build Coastguard Worker 123*9356374aSAndroid Build Coastguard Worker //////////////////////////////////////////////////////////////////////////////// 124*9356374aSAndroid Build Coastguard Worker // 125*9356374aSAndroid Build Coastguard Worker // An implementation of the C++ standard INVOKE<R> pseudo-macro, operation is 126*9356374aSAndroid Build Coastguard Worker // equivalent to std::invoke except that it forces an implicit conversion to the 127*9356374aSAndroid Build Coastguard Worker // specified return type. If "R" is void, the function is executed and the 128*9356374aSAndroid Build Coastguard Worker // return value is simply ignored. 129*9356374aSAndroid Build Coastguard Worker template <class ReturnType, class F, class... P, 130*9356374aSAndroid Build Coastguard Worker typename = absl::enable_if_t<std::is_void<ReturnType>::value>> 131*9356374aSAndroid Build Coastguard Worker void InvokeR(F&& f, P&&... args) { 132*9356374aSAndroid Build Coastguard Worker absl::base_internal::invoke(std::forward<F>(f), std::forward<P>(args)...); 133*9356374aSAndroid Build Coastguard Worker } 134*9356374aSAndroid Build Coastguard Worker 135*9356374aSAndroid Build Coastguard Worker template <class ReturnType, class F, class... P, 136*9356374aSAndroid Build Coastguard Worker absl::enable_if_t<!std::is_void<ReturnType>::value, int> = 0> 137*9356374aSAndroid Build Coastguard Worker ReturnType InvokeR(F&& f, P&&... args) { 138*9356374aSAndroid Build Coastguard Worker // GCC 12 has a false-positive -Wmaybe-uninitialized warning here. 139*9356374aSAndroid Build Coastguard Worker #if ABSL_INTERNAL_HAVE_MIN_GNUC_VERSION(12, 0) 140*9356374aSAndroid Build Coastguard Worker #pragma GCC diagnostic push 141*9356374aSAndroid Build Coastguard Worker #pragma GCC diagnostic ignored "-Wmaybe-uninitialized" 142*9356374aSAndroid Build Coastguard Worker #endif 143*9356374aSAndroid Build Coastguard Worker return absl::base_internal::invoke(std::forward<F>(f), 144*9356374aSAndroid Build Coastguard Worker std::forward<P>(args)...); 145*9356374aSAndroid Build Coastguard Worker #if ABSL_INTERNAL_HAVE_MIN_GNUC_VERSION(12, 0) 146*9356374aSAndroid Build Coastguard Worker #pragma GCC diagnostic pop 147*9356374aSAndroid Build Coastguard Worker #endif 148*9356374aSAndroid Build Coastguard Worker } 149*9356374aSAndroid Build Coastguard Worker 150*9356374aSAndroid Build Coastguard Worker // 151*9356374aSAndroid Build Coastguard Worker //////////////////////////////////////////////////////////////////////////////// 152*9356374aSAndroid Build Coastguard Worker 153*9356374aSAndroid Build Coastguard Worker //////////////////////////////////////////////////////////////////////////////// 154*9356374aSAndroid Build Coastguard Worker /// 155*9356374aSAndroid Build Coastguard Worker // A metafunction that takes a "T" corresponding to a parameter type of the 156*9356374aSAndroid Build Coastguard Worker // user's specified function type, and yields the parameter type to use for the 157*9356374aSAndroid Build Coastguard Worker // type-erased invoker. In order to prevent observable moves, this must be 158*9356374aSAndroid Build Coastguard Worker // either a reference or, if the type is trivial, the original parameter type 159*9356374aSAndroid Build Coastguard Worker // itself. Since the parameter type may be incomplete at the point that this 160*9356374aSAndroid Build Coastguard Worker // metafunction is used, we can only do this optimization for scalar types 161*9356374aSAndroid Build Coastguard Worker // rather than for any trivial type. 162*9356374aSAndroid Build Coastguard Worker template <typename T> 163*9356374aSAndroid Build Coastguard Worker T ForwardImpl(std::true_type); 164*9356374aSAndroid Build Coastguard Worker 165*9356374aSAndroid Build Coastguard Worker template <typename T> 166*9356374aSAndroid Build Coastguard Worker T&& ForwardImpl(std::false_type); 167*9356374aSAndroid Build Coastguard Worker 168*9356374aSAndroid Build Coastguard Worker // NOTE: We deliberately use an intermediate struct instead of a direct alias, 169*9356374aSAndroid Build Coastguard Worker // as a workaround for b/206991861 on MSVC versions < 1924. 170*9356374aSAndroid Build Coastguard Worker template <class T> 171*9356374aSAndroid Build Coastguard Worker struct ForwardedParameter { 172*9356374aSAndroid Build Coastguard Worker using type = decltype(( 173*9356374aSAndroid Build Coastguard Worker ForwardImpl<T>)(std::integral_constant<bool, 174*9356374aSAndroid Build Coastguard Worker std::is_scalar<T>::value>())); 175*9356374aSAndroid Build Coastguard Worker }; 176*9356374aSAndroid Build Coastguard Worker 177*9356374aSAndroid Build Coastguard Worker template <class T> 178*9356374aSAndroid Build Coastguard Worker using ForwardedParameterType = typename ForwardedParameter<T>::type; 179*9356374aSAndroid Build Coastguard Worker // 180*9356374aSAndroid Build Coastguard Worker //////////////////////////////////////////////////////////////////////////////// 181*9356374aSAndroid Build Coastguard Worker 182*9356374aSAndroid Build Coastguard Worker // A discriminator when calling the "manager" function that describes operation 183*9356374aSAndroid Build Coastguard Worker // type-erased operation should be invoked. 184*9356374aSAndroid Build Coastguard Worker // 185*9356374aSAndroid Build Coastguard Worker // "relocate_from_to" specifies that the manager should perform a move. 186*9356374aSAndroid Build Coastguard Worker // 187*9356374aSAndroid Build Coastguard Worker // "dispose" specifies that the manager should perform a destroy. 188*9356374aSAndroid Build Coastguard Worker enum class FunctionToCall : bool { relocate_from_to, dispose }; 189*9356374aSAndroid Build Coastguard Worker 190*9356374aSAndroid Build Coastguard Worker // The portion of `AnyInvocable` state that contains either a pointer to the 191*9356374aSAndroid Build Coastguard Worker // target object or the object itself in local storage 192*9356374aSAndroid Build Coastguard Worker union TypeErasedState { 193*9356374aSAndroid Build Coastguard Worker struct { 194*9356374aSAndroid Build Coastguard Worker // A pointer to the type-erased object when remotely stored 195*9356374aSAndroid Build Coastguard Worker void* target; 196*9356374aSAndroid Build Coastguard Worker // The size of the object for `RemoteManagerTrivial` 197*9356374aSAndroid Build Coastguard Worker std::size_t size; 198*9356374aSAndroid Build Coastguard Worker } remote; 199*9356374aSAndroid Build Coastguard Worker 200*9356374aSAndroid Build Coastguard Worker // Local-storage for the type-erased object when small and trivial enough 201*9356374aSAndroid Build Coastguard Worker alignas(kAlignment) char storage[kStorageSize]; 202*9356374aSAndroid Build Coastguard Worker }; 203*9356374aSAndroid Build Coastguard Worker 204*9356374aSAndroid Build Coastguard Worker // A typed accessor for the object in `TypeErasedState` storage 205*9356374aSAndroid Build Coastguard Worker template <class T> 206*9356374aSAndroid Build Coastguard Worker T& ObjectInLocalStorage(TypeErasedState* const state) { 207*9356374aSAndroid Build Coastguard Worker // We launder here because the storage may be reused with the same type. 208*9356374aSAndroid Build Coastguard Worker #if defined(__cpp_lib_launder) && __cpp_lib_launder >= 201606L 209*9356374aSAndroid Build Coastguard Worker return *std::launder(reinterpret_cast<T*>(&state->storage)); 210*9356374aSAndroid Build Coastguard Worker #elif ABSL_HAVE_BUILTIN(__builtin_launder) 211*9356374aSAndroid Build Coastguard Worker return *__builtin_launder(reinterpret_cast<T*>(&state->storage)); 212*9356374aSAndroid Build Coastguard Worker #else 213*9356374aSAndroid Build Coastguard Worker 214*9356374aSAndroid Build Coastguard Worker // When `std::launder` or equivalent are not available, we rely on undefined 215*9356374aSAndroid Build Coastguard Worker // behavior, which works as intended on Abseil's officially supported 216*9356374aSAndroid Build Coastguard Worker // platforms as of Q2 2022. 217*9356374aSAndroid Build Coastguard Worker #if !defined(__clang__) && defined(__GNUC__) 218*9356374aSAndroid Build Coastguard Worker #pragma GCC diagnostic push 219*9356374aSAndroid Build Coastguard Worker #pragma GCC diagnostic ignored "-Wstrict-aliasing" 220*9356374aSAndroid Build Coastguard Worker #endif 221*9356374aSAndroid Build Coastguard Worker return *reinterpret_cast<T*>(&state->storage); 222*9356374aSAndroid Build Coastguard Worker #if !defined(__clang__) && defined(__GNUC__) 223*9356374aSAndroid Build Coastguard Worker #pragma GCC diagnostic pop 224*9356374aSAndroid Build Coastguard Worker #endif 225*9356374aSAndroid Build Coastguard Worker 226*9356374aSAndroid Build Coastguard Worker #endif 227*9356374aSAndroid Build Coastguard Worker } 228*9356374aSAndroid Build Coastguard Worker 229*9356374aSAndroid Build Coastguard Worker // The type for functions issuing lifetime-related operations: move and dispose 230*9356374aSAndroid Build Coastguard Worker // A pointer to such a function is contained in each `AnyInvocable` instance. 231*9356374aSAndroid Build Coastguard Worker // NOTE: When specifying `FunctionToCall::`dispose, the same state must be 232*9356374aSAndroid Build Coastguard Worker // passed as both "from" and "to". 233*9356374aSAndroid Build Coastguard Worker using ManagerType = void(FunctionToCall /*operation*/, 234*9356374aSAndroid Build Coastguard Worker TypeErasedState* /*from*/, TypeErasedState* /*to*/) 235*9356374aSAndroid Build Coastguard Worker ABSL_INTERNAL_NOEXCEPT_SPEC(true); 236*9356374aSAndroid Build Coastguard Worker 237*9356374aSAndroid Build Coastguard Worker // The type for functions issuing the actual invocation of the object 238*9356374aSAndroid Build Coastguard Worker // A pointer to such a function is contained in each AnyInvocable instance. 239*9356374aSAndroid Build Coastguard Worker template <bool SigIsNoexcept, class ReturnType, class... P> 240*9356374aSAndroid Build Coastguard Worker using InvokerType = ReturnType(TypeErasedState*, ForwardedParameterType<P>...) 241*9356374aSAndroid Build Coastguard Worker ABSL_INTERNAL_NOEXCEPT_SPEC(SigIsNoexcept); 242*9356374aSAndroid Build Coastguard Worker 243*9356374aSAndroid Build Coastguard Worker // The manager that is used when AnyInvocable is empty 244*9356374aSAndroid Build Coastguard Worker inline void EmptyManager(FunctionToCall /*operation*/, 245*9356374aSAndroid Build Coastguard Worker TypeErasedState* /*from*/, 246*9356374aSAndroid Build Coastguard Worker TypeErasedState* /*to*/) noexcept {} 247*9356374aSAndroid Build Coastguard Worker 248*9356374aSAndroid Build Coastguard Worker // The manager that is used when a target function is in local storage and is 249*9356374aSAndroid Build Coastguard Worker // a trivially copyable type. 250*9356374aSAndroid Build Coastguard Worker inline void LocalManagerTrivial(FunctionToCall /*operation*/, 251*9356374aSAndroid Build Coastguard Worker TypeErasedState* const from, 252*9356374aSAndroid Build Coastguard Worker TypeErasedState* const to) noexcept { 253*9356374aSAndroid Build Coastguard Worker // This single statement without branching handles both possible operations. 254*9356374aSAndroid Build Coastguard Worker // 255*9356374aSAndroid Build Coastguard Worker // For FunctionToCall::dispose, "from" and "to" point to the same state, and 256*9356374aSAndroid Build Coastguard Worker // so this assignment logically would do nothing. 257*9356374aSAndroid Build Coastguard Worker // 258*9356374aSAndroid Build Coastguard Worker // Note: Correctness here relies on http://wg21.link/p0593, which has only 259*9356374aSAndroid Build Coastguard Worker // become standard in C++20, though implementations do not break it in 260*9356374aSAndroid Build Coastguard Worker // practice for earlier versions of C++. 261*9356374aSAndroid Build Coastguard Worker // 262*9356374aSAndroid Build Coastguard Worker // The correct way to do this without that paper is to first placement-new a 263*9356374aSAndroid Build Coastguard Worker // default-constructed T in "to->storage" prior to the memmove, but doing so 264*9356374aSAndroid Build Coastguard Worker // requires a different function to be created for each T that is stored 265*9356374aSAndroid Build Coastguard Worker // locally, which can cause unnecessary bloat and be less cache friendly. 266*9356374aSAndroid Build Coastguard Worker *to = *from; 267*9356374aSAndroid Build Coastguard Worker 268*9356374aSAndroid Build Coastguard Worker // Note: Because the type is trivially copyable, the destructor does not need 269*9356374aSAndroid Build Coastguard Worker // to be called ("trivially copyable" requires a trivial destructor). 270*9356374aSAndroid Build Coastguard Worker } 271*9356374aSAndroid Build Coastguard Worker 272*9356374aSAndroid Build Coastguard Worker // The manager that is used when a target function is in local storage and is 273*9356374aSAndroid Build Coastguard Worker // not a trivially copyable type. 274*9356374aSAndroid Build Coastguard Worker template <class T> 275*9356374aSAndroid Build Coastguard Worker void LocalManagerNontrivial(FunctionToCall operation, 276*9356374aSAndroid Build Coastguard Worker TypeErasedState* const from, 277*9356374aSAndroid Build Coastguard Worker TypeErasedState* const to) noexcept { 278*9356374aSAndroid Build Coastguard Worker static_assert(IsStoredLocally<T>::value, 279*9356374aSAndroid Build Coastguard Worker "Local storage must only be used for supported types."); 280*9356374aSAndroid Build Coastguard Worker static_assert(!std::is_trivially_copyable<T>::value, 281*9356374aSAndroid Build Coastguard Worker "Locally stored types must be trivially copyable."); 282*9356374aSAndroid Build Coastguard Worker 283*9356374aSAndroid Build Coastguard Worker T& from_object = (ObjectInLocalStorage<T>)(from); 284*9356374aSAndroid Build Coastguard Worker 285*9356374aSAndroid Build Coastguard Worker switch (operation) { 286*9356374aSAndroid Build Coastguard Worker case FunctionToCall::relocate_from_to: 287*9356374aSAndroid Build Coastguard Worker // NOTE: Requires that the left-hand operand is already empty. 288*9356374aSAndroid Build Coastguard Worker ::new (static_cast<void*>(&to->storage)) T(std::move(from_object)); 289*9356374aSAndroid Build Coastguard Worker ABSL_FALLTHROUGH_INTENDED; 290*9356374aSAndroid Build Coastguard Worker case FunctionToCall::dispose: 291*9356374aSAndroid Build Coastguard Worker from_object.~T(); // Must not throw. // NOLINT 292*9356374aSAndroid Build Coastguard Worker return; 293*9356374aSAndroid Build Coastguard Worker } 294*9356374aSAndroid Build Coastguard Worker ABSL_UNREACHABLE(); 295*9356374aSAndroid Build Coastguard Worker } 296*9356374aSAndroid Build Coastguard Worker 297*9356374aSAndroid Build Coastguard Worker // The invoker that is used when a target function is in local storage 298*9356374aSAndroid Build Coastguard Worker // Note: QualTRef here is the target function type along with cv and reference 299*9356374aSAndroid Build Coastguard Worker // qualifiers that must be used when calling the function. 300*9356374aSAndroid Build Coastguard Worker template <bool SigIsNoexcept, class ReturnType, class QualTRef, class... P> 301*9356374aSAndroid Build Coastguard Worker ReturnType LocalInvoker( 302*9356374aSAndroid Build Coastguard Worker TypeErasedState* const state, 303*9356374aSAndroid Build Coastguard Worker ForwardedParameterType<P>... args) noexcept(SigIsNoexcept) { 304*9356374aSAndroid Build Coastguard Worker using RawT = RemoveCVRef<QualTRef>; 305*9356374aSAndroid Build Coastguard Worker static_assert( 306*9356374aSAndroid Build Coastguard Worker IsStoredLocally<RawT>::value, 307*9356374aSAndroid Build Coastguard Worker "Target object must be in local storage in order to be invoked from it."); 308*9356374aSAndroid Build Coastguard Worker 309*9356374aSAndroid Build Coastguard Worker auto& f = (ObjectInLocalStorage<RawT>)(state); 310*9356374aSAndroid Build Coastguard Worker return (InvokeR<ReturnType>)(static_cast<QualTRef>(f), 311*9356374aSAndroid Build Coastguard Worker static_cast<ForwardedParameterType<P>>(args)...); 312*9356374aSAndroid Build Coastguard Worker } 313*9356374aSAndroid Build Coastguard Worker 314*9356374aSAndroid Build Coastguard Worker // The manager that is used when a target function is in remote storage and it 315*9356374aSAndroid Build Coastguard Worker // has a trivial destructor 316*9356374aSAndroid Build Coastguard Worker inline void RemoteManagerTrivial(FunctionToCall operation, 317*9356374aSAndroid Build Coastguard Worker TypeErasedState* const from, 318*9356374aSAndroid Build Coastguard Worker TypeErasedState* const to) noexcept { 319*9356374aSAndroid Build Coastguard Worker switch (operation) { 320*9356374aSAndroid Build Coastguard Worker case FunctionToCall::relocate_from_to: 321*9356374aSAndroid Build Coastguard Worker // NOTE: Requires that the left-hand operand is already empty. 322*9356374aSAndroid Build Coastguard Worker to->remote = from->remote; 323*9356374aSAndroid Build Coastguard Worker return; 324*9356374aSAndroid Build Coastguard Worker case FunctionToCall::dispose: 325*9356374aSAndroid Build Coastguard Worker #if defined(__cpp_sized_deallocation) 326*9356374aSAndroid Build Coastguard Worker ::operator delete(from->remote.target, from->remote.size); 327*9356374aSAndroid Build Coastguard Worker #else // __cpp_sized_deallocation 328*9356374aSAndroid Build Coastguard Worker ::operator delete(from->remote.target); 329*9356374aSAndroid Build Coastguard Worker #endif // __cpp_sized_deallocation 330*9356374aSAndroid Build Coastguard Worker return; 331*9356374aSAndroid Build Coastguard Worker } 332*9356374aSAndroid Build Coastguard Worker ABSL_UNREACHABLE(); 333*9356374aSAndroid Build Coastguard Worker } 334*9356374aSAndroid Build Coastguard Worker 335*9356374aSAndroid Build Coastguard Worker // The manager that is used when a target function is in remote storage and the 336*9356374aSAndroid Build Coastguard Worker // destructor of the type is not trivial 337*9356374aSAndroid Build Coastguard Worker template <class T> 338*9356374aSAndroid Build Coastguard Worker void RemoteManagerNontrivial(FunctionToCall operation, 339*9356374aSAndroid Build Coastguard Worker TypeErasedState* const from, 340*9356374aSAndroid Build Coastguard Worker TypeErasedState* const to) noexcept { 341*9356374aSAndroid Build Coastguard Worker static_assert(!IsStoredLocally<T>::value, 342*9356374aSAndroid Build Coastguard Worker "Remote storage must only be used for types that do not " 343*9356374aSAndroid Build Coastguard Worker "qualify for local storage."); 344*9356374aSAndroid Build Coastguard Worker 345*9356374aSAndroid Build Coastguard Worker switch (operation) { 346*9356374aSAndroid Build Coastguard Worker case FunctionToCall::relocate_from_to: 347*9356374aSAndroid Build Coastguard Worker // NOTE: Requires that the left-hand operand is already empty. 348*9356374aSAndroid Build Coastguard Worker to->remote.target = from->remote.target; 349*9356374aSAndroid Build Coastguard Worker return; 350*9356374aSAndroid Build Coastguard Worker case FunctionToCall::dispose: 351*9356374aSAndroid Build Coastguard Worker ::delete static_cast<T*>(from->remote.target); // Must not throw. 352*9356374aSAndroid Build Coastguard Worker return; 353*9356374aSAndroid Build Coastguard Worker } 354*9356374aSAndroid Build Coastguard Worker ABSL_UNREACHABLE(); 355*9356374aSAndroid Build Coastguard Worker } 356*9356374aSAndroid Build Coastguard Worker 357*9356374aSAndroid Build Coastguard Worker // The invoker that is used when a target function is in remote storage 358*9356374aSAndroid Build Coastguard Worker template <bool SigIsNoexcept, class ReturnType, class QualTRef, class... P> 359*9356374aSAndroid Build Coastguard Worker ReturnType RemoteInvoker( 360*9356374aSAndroid Build Coastguard Worker TypeErasedState* const state, 361*9356374aSAndroid Build Coastguard Worker ForwardedParameterType<P>... args) noexcept(SigIsNoexcept) { 362*9356374aSAndroid Build Coastguard Worker using RawT = RemoveCVRef<QualTRef>; 363*9356374aSAndroid Build Coastguard Worker static_assert(!IsStoredLocally<RawT>::value, 364*9356374aSAndroid Build Coastguard Worker "Target object must be in remote storage in order to be " 365*9356374aSAndroid Build Coastguard Worker "invoked from it."); 366*9356374aSAndroid Build Coastguard Worker 367*9356374aSAndroid Build Coastguard Worker auto& f = *static_cast<RawT*>(state->remote.target); 368*9356374aSAndroid Build Coastguard Worker return (InvokeR<ReturnType>)(static_cast<QualTRef>(f), 369*9356374aSAndroid Build Coastguard Worker static_cast<ForwardedParameterType<P>>(args)...); 370*9356374aSAndroid Build Coastguard Worker } 371*9356374aSAndroid Build Coastguard Worker 372*9356374aSAndroid Build Coastguard Worker //////////////////////////////////////////////////////////////////////////////// 373*9356374aSAndroid Build Coastguard Worker // 374*9356374aSAndroid Build Coastguard Worker // A metafunction that checks if a type T is an instantiation of 375*9356374aSAndroid Build Coastguard Worker // absl::in_place_type_t (needed for constructor constraints of AnyInvocable). 376*9356374aSAndroid Build Coastguard Worker template <class T> 377*9356374aSAndroid Build Coastguard Worker struct IsInPlaceType : std::false_type {}; 378*9356374aSAndroid Build Coastguard Worker 379*9356374aSAndroid Build Coastguard Worker template <class T> 380*9356374aSAndroid Build Coastguard Worker struct IsInPlaceType<absl::in_place_type_t<T>> : std::true_type {}; 381*9356374aSAndroid Build Coastguard Worker // 382*9356374aSAndroid Build Coastguard Worker //////////////////////////////////////////////////////////////////////////////// 383*9356374aSAndroid Build Coastguard Worker 384*9356374aSAndroid Build Coastguard Worker // A constructor name-tag used with CoreImpl (below) to request the 385*9356374aSAndroid Build Coastguard Worker // conversion-constructor. QualDecayedTRef is the decayed-type of the object to 386*9356374aSAndroid Build Coastguard Worker // wrap, along with the cv and reference qualifiers that must be applied when 387*9356374aSAndroid Build Coastguard Worker // performing an invocation of the wrapped object. 388*9356374aSAndroid Build Coastguard Worker template <class QualDecayedTRef> 389*9356374aSAndroid Build Coastguard Worker struct TypedConversionConstruct {}; 390*9356374aSAndroid Build Coastguard Worker 391*9356374aSAndroid Build Coastguard Worker // A helper base class for all core operations of AnyInvocable. Most notably, 392*9356374aSAndroid Build Coastguard Worker // this class creates the function call operator and constraint-checkers so that 393*9356374aSAndroid Build Coastguard Worker // the top-level class does not have to be a series of partial specializations. 394*9356374aSAndroid Build Coastguard Worker // 395*9356374aSAndroid Build Coastguard Worker // Note: This definition exists (as opposed to being a declaration) so that if 396*9356374aSAndroid Build Coastguard Worker // the user of the top-level template accidentally passes a template argument 397*9356374aSAndroid Build Coastguard Worker // that is not a function type, they will get a static_assert in AnyInvocable's 398*9356374aSAndroid Build Coastguard Worker // class body rather than an error stating that Impl is not defined. 399*9356374aSAndroid Build Coastguard Worker template <class Sig> 400*9356374aSAndroid Build Coastguard Worker class Impl {}; // Note: This is partially-specialized later. 401*9356374aSAndroid Build Coastguard Worker 402*9356374aSAndroid Build Coastguard Worker // A std::unique_ptr deleter that deletes memory allocated via ::operator new. 403*9356374aSAndroid Build Coastguard Worker #if defined(__cpp_sized_deallocation) 404*9356374aSAndroid Build Coastguard Worker class TrivialDeleter { 405*9356374aSAndroid Build Coastguard Worker public: 406*9356374aSAndroid Build Coastguard Worker explicit TrivialDeleter(std::size_t size) : size_(size) {} 407*9356374aSAndroid Build Coastguard Worker 408*9356374aSAndroid Build Coastguard Worker void operator()(void* target) const { 409*9356374aSAndroid Build Coastguard Worker ::operator delete(target, size_); 410*9356374aSAndroid Build Coastguard Worker } 411*9356374aSAndroid Build Coastguard Worker 412*9356374aSAndroid Build Coastguard Worker private: 413*9356374aSAndroid Build Coastguard Worker std::size_t size_; 414*9356374aSAndroid Build Coastguard Worker }; 415*9356374aSAndroid Build Coastguard Worker #else // __cpp_sized_deallocation 416*9356374aSAndroid Build Coastguard Worker class TrivialDeleter { 417*9356374aSAndroid Build Coastguard Worker public: 418*9356374aSAndroid Build Coastguard Worker explicit TrivialDeleter(std::size_t) {} 419*9356374aSAndroid Build Coastguard Worker 420*9356374aSAndroid Build Coastguard Worker void operator()(void* target) const { ::operator delete(target); } 421*9356374aSAndroid Build Coastguard Worker }; 422*9356374aSAndroid Build Coastguard Worker #endif // __cpp_sized_deallocation 423*9356374aSAndroid Build Coastguard Worker 424*9356374aSAndroid Build Coastguard Worker template <bool SigIsNoexcept, class ReturnType, class... P> 425*9356374aSAndroid Build Coastguard Worker class CoreImpl; 426*9356374aSAndroid Build Coastguard Worker 427*9356374aSAndroid Build Coastguard Worker constexpr bool IsCompatibleConversion(void*, void*) { return false; } 428*9356374aSAndroid Build Coastguard Worker template <bool NoExceptSrc, bool NoExceptDest, class... T> 429*9356374aSAndroid Build Coastguard Worker constexpr bool IsCompatibleConversion(CoreImpl<NoExceptSrc, T...>*, 430*9356374aSAndroid Build Coastguard Worker CoreImpl<NoExceptDest, T...>*) { 431*9356374aSAndroid Build Coastguard Worker return !NoExceptDest || NoExceptSrc; 432*9356374aSAndroid Build Coastguard Worker } 433*9356374aSAndroid Build Coastguard Worker 434*9356374aSAndroid Build Coastguard Worker // A helper base class for all core operations of AnyInvocable that do not 435*9356374aSAndroid Build Coastguard Worker // depend on the cv/ref qualifiers of the function type. 436*9356374aSAndroid Build Coastguard Worker template <bool SigIsNoexcept, class ReturnType, class... P> 437*9356374aSAndroid Build Coastguard Worker class CoreImpl { 438*9356374aSAndroid Build Coastguard Worker public: 439*9356374aSAndroid Build Coastguard Worker using result_type = ReturnType; 440*9356374aSAndroid Build Coastguard Worker 441*9356374aSAndroid Build Coastguard Worker CoreImpl() noexcept : manager_(EmptyManager), invoker_(nullptr) {} 442*9356374aSAndroid Build Coastguard Worker 443*9356374aSAndroid Build Coastguard Worker enum class TargetType { 444*9356374aSAndroid Build Coastguard Worker kPointer, 445*9356374aSAndroid Build Coastguard Worker kCompatibleAnyInvocable, 446*9356374aSAndroid Build Coastguard Worker kIncompatibleAnyInvocable, 447*9356374aSAndroid Build Coastguard Worker kOther, 448*9356374aSAndroid Build Coastguard Worker }; 449*9356374aSAndroid Build Coastguard Worker 450*9356374aSAndroid Build Coastguard Worker // Note: QualDecayedTRef here includes the cv-ref qualifiers associated with 451*9356374aSAndroid Build Coastguard Worker // the invocation of the Invocable. The unqualified type is the target object 452*9356374aSAndroid Build Coastguard Worker // type to be stored. 453*9356374aSAndroid Build Coastguard Worker template <class QualDecayedTRef, class F> 454*9356374aSAndroid Build Coastguard Worker explicit CoreImpl(TypedConversionConstruct<QualDecayedTRef>, F&& f) { 455*9356374aSAndroid Build Coastguard Worker using DecayedT = RemoveCVRef<QualDecayedTRef>; 456*9356374aSAndroid Build Coastguard Worker 457*9356374aSAndroid Build Coastguard Worker constexpr TargetType kTargetType = 458*9356374aSAndroid Build Coastguard Worker (std::is_pointer<DecayedT>::value || 459*9356374aSAndroid Build Coastguard Worker std::is_member_pointer<DecayedT>::value) 460*9356374aSAndroid Build Coastguard Worker ? TargetType::kPointer 461*9356374aSAndroid Build Coastguard Worker : IsCompatibleAnyInvocable<DecayedT>::value 462*9356374aSAndroid Build Coastguard Worker ? TargetType::kCompatibleAnyInvocable 463*9356374aSAndroid Build Coastguard Worker : IsAnyInvocable<DecayedT>::value 464*9356374aSAndroid Build Coastguard Worker ? TargetType::kIncompatibleAnyInvocable 465*9356374aSAndroid Build Coastguard Worker : TargetType::kOther; 466*9356374aSAndroid Build Coastguard Worker // NOTE: We only use integers instead of enums as template parameters in 467*9356374aSAndroid Build Coastguard Worker // order to work around a bug on C++14 under MSVC 2017. 468*9356374aSAndroid Build Coastguard Worker // See b/236131881. 469*9356374aSAndroid Build Coastguard Worker Initialize<kTargetType, QualDecayedTRef>(std::forward<F>(f)); 470*9356374aSAndroid Build Coastguard Worker } 471*9356374aSAndroid Build Coastguard Worker 472*9356374aSAndroid Build Coastguard Worker // Note: QualTRef here includes the cv-ref qualifiers associated with the 473*9356374aSAndroid Build Coastguard Worker // invocation of the Invocable. The unqualified type is the target object 474*9356374aSAndroid Build Coastguard Worker // type to be stored. 475*9356374aSAndroid Build Coastguard Worker template <class QualTRef, class... Args> 476*9356374aSAndroid Build Coastguard Worker explicit CoreImpl(absl::in_place_type_t<QualTRef>, Args&&... args) { 477*9356374aSAndroid Build Coastguard Worker InitializeStorage<QualTRef>(std::forward<Args>(args)...); 478*9356374aSAndroid Build Coastguard Worker } 479*9356374aSAndroid Build Coastguard Worker 480*9356374aSAndroid Build Coastguard Worker CoreImpl(CoreImpl&& other) noexcept { 481*9356374aSAndroid Build Coastguard Worker other.manager_(FunctionToCall::relocate_from_to, &other.state_, &state_); 482*9356374aSAndroid Build Coastguard Worker manager_ = other.manager_; 483*9356374aSAndroid Build Coastguard Worker invoker_ = other.invoker_; 484*9356374aSAndroid Build Coastguard Worker other.manager_ = EmptyManager; 485*9356374aSAndroid Build Coastguard Worker other.invoker_ = nullptr; 486*9356374aSAndroid Build Coastguard Worker } 487*9356374aSAndroid Build Coastguard Worker 488*9356374aSAndroid Build Coastguard Worker CoreImpl& operator=(CoreImpl&& other) noexcept { 489*9356374aSAndroid Build Coastguard Worker // Put the left-hand operand in an empty state. 490*9356374aSAndroid Build Coastguard Worker // 491*9356374aSAndroid Build Coastguard Worker // Note: A full reset that leaves us with an object that has its invariants 492*9356374aSAndroid Build Coastguard Worker // intact is necessary in order to handle self-move. This is required by 493*9356374aSAndroid Build Coastguard Worker // types that are used with certain operations of the standard library, such 494*9356374aSAndroid Build Coastguard Worker // as the default definition of std::swap when both operands target the same 495*9356374aSAndroid Build Coastguard Worker // object. 496*9356374aSAndroid Build Coastguard Worker Clear(); 497*9356374aSAndroid Build Coastguard Worker 498*9356374aSAndroid Build Coastguard Worker // Perform the actual move/destroy operation on the target function. 499*9356374aSAndroid Build Coastguard Worker other.manager_(FunctionToCall::relocate_from_to, &other.state_, &state_); 500*9356374aSAndroid Build Coastguard Worker manager_ = other.manager_; 501*9356374aSAndroid Build Coastguard Worker invoker_ = other.invoker_; 502*9356374aSAndroid Build Coastguard Worker other.manager_ = EmptyManager; 503*9356374aSAndroid Build Coastguard Worker other.invoker_ = nullptr; 504*9356374aSAndroid Build Coastguard Worker 505*9356374aSAndroid Build Coastguard Worker return *this; 506*9356374aSAndroid Build Coastguard Worker } 507*9356374aSAndroid Build Coastguard Worker 508*9356374aSAndroid Build Coastguard Worker ~CoreImpl() { manager_(FunctionToCall::dispose, &state_, &state_); } 509*9356374aSAndroid Build Coastguard Worker 510*9356374aSAndroid Build Coastguard Worker // Check whether or not the AnyInvocable is in the empty state. 511*9356374aSAndroid Build Coastguard Worker bool HasValue() const { return invoker_ != nullptr; } 512*9356374aSAndroid Build Coastguard Worker 513*9356374aSAndroid Build Coastguard Worker // Effects: Puts the object into its empty state. 514*9356374aSAndroid Build Coastguard Worker void Clear() { 515*9356374aSAndroid Build Coastguard Worker manager_(FunctionToCall::dispose, &state_, &state_); 516*9356374aSAndroid Build Coastguard Worker manager_ = EmptyManager; 517*9356374aSAndroid Build Coastguard Worker invoker_ = nullptr; 518*9356374aSAndroid Build Coastguard Worker } 519*9356374aSAndroid Build Coastguard Worker 520*9356374aSAndroid Build Coastguard Worker template <TargetType target_type, class QualDecayedTRef, class F, 521*9356374aSAndroid Build Coastguard Worker absl::enable_if_t<target_type == TargetType::kPointer, int> = 0> 522*9356374aSAndroid Build Coastguard Worker void Initialize(F&& f) { 523*9356374aSAndroid Build Coastguard Worker // This condition handles types that decay into pointers, which includes 524*9356374aSAndroid Build Coastguard Worker // function references. Since function references cannot be null, GCC warns 525*9356374aSAndroid Build Coastguard Worker // against comparing their decayed form with nullptr. 526*9356374aSAndroid Build Coastguard Worker // Since this is template-heavy code, we prefer to disable these warnings 527*9356374aSAndroid Build Coastguard Worker // locally instead of adding yet another overload of this function. 528*9356374aSAndroid Build Coastguard Worker #if !defined(__clang__) && defined(__GNUC__) 529*9356374aSAndroid Build Coastguard Worker #pragma GCC diagnostic push 530*9356374aSAndroid Build Coastguard Worker #pragma GCC diagnostic ignored "-Wpragmas" 531*9356374aSAndroid Build Coastguard Worker #pragma GCC diagnostic ignored "-Waddress" 532*9356374aSAndroid Build Coastguard Worker #pragma GCC diagnostic ignored "-Wnonnull-compare" 533*9356374aSAndroid Build Coastguard Worker #endif 534*9356374aSAndroid Build Coastguard Worker if (static_cast<RemoveCVRef<QualDecayedTRef>>(f) == nullptr) { 535*9356374aSAndroid Build Coastguard Worker #if !defined(__clang__) && defined(__GNUC__) 536*9356374aSAndroid Build Coastguard Worker #pragma GCC diagnostic pop 537*9356374aSAndroid Build Coastguard Worker #endif 538*9356374aSAndroid Build Coastguard Worker manager_ = EmptyManager; 539*9356374aSAndroid Build Coastguard Worker invoker_ = nullptr; 540*9356374aSAndroid Build Coastguard Worker return; 541*9356374aSAndroid Build Coastguard Worker } 542*9356374aSAndroid Build Coastguard Worker InitializeStorage<QualDecayedTRef>(std::forward<F>(f)); 543*9356374aSAndroid Build Coastguard Worker } 544*9356374aSAndroid Build Coastguard Worker 545*9356374aSAndroid Build Coastguard Worker template <TargetType target_type, class QualDecayedTRef, class F, 546*9356374aSAndroid Build Coastguard Worker absl::enable_if_t< 547*9356374aSAndroid Build Coastguard Worker target_type == TargetType::kCompatibleAnyInvocable, int> = 0> 548*9356374aSAndroid Build Coastguard Worker void Initialize(F&& f) { 549*9356374aSAndroid Build Coastguard Worker // In this case we can "steal the guts" of the other AnyInvocable. 550*9356374aSAndroid Build Coastguard Worker f.manager_(FunctionToCall::relocate_from_to, &f.state_, &state_); 551*9356374aSAndroid Build Coastguard Worker manager_ = f.manager_; 552*9356374aSAndroid Build Coastguard Worker invoker_ = f.invoker_; 553*9356374aSAndroid Build Coastguard Worker 554*9356374aSAndroid Build Coastguard Worker f.manager_ = EmptyManager; 555*9356374aSAndroid Build Coastguard Worker f.invoker_ = nullptr; 556*9356374aSAndroid Build Coastguard Worker } 557*9356374aSAndroid Build Coastguard Worker 558*9356374aSAndroid Build Coastguard Worker template <TargetType target_type, class QualDecayedTRef, class F, 559*9356374aSAndroid Build Coastguard Worker absl::enable_if_t< 560*9356374aSAndroid Build Coastguard Worker target_type == TargetType::kIncompatibleAnyInvocable, int> = 0> 561*9356374aSAndroid Build Coastguard Worker void Initialize(F&& f) { 562*9356374aSAndroid Build Coastguard Worker if (f.HasValue()) { 563*9356374aSAndroid Build Coastguard Worker InitializeStorage<QualDecayedTRef>(std::forward<F>(f)); 564*9356374aSAndroid Build Coastguard Worker } else { 565*9356374aSAndroid Build Coastguard Worker manager_ = EmptyManager; 566*9356374aSAndroid Build Coastguard Worker invoker_ = nullptr; 567*9356374aSAndroid Build Coastguard Worker } 568*9356374aSAndroid Build Coastguard Worker } 569*9356374aSAndroid Build Coastguard Worker 570*9356374aSAndroid Build Coastguard Worker template <TargetType target_type, class QualDecayedTRef, class F, 571*9356374aSAndroid Build Coastguard Worker typename = absl::enable_if_t<target_type == TargetType::kOther>> 572*9356374aSAndroid Build Coastguard Worker void Initialize(F&& f) { 573*9356374aSAndroid Build Coastguard Worker InitializeStorage<QualDecayedTRef>(std::forward<F>(f)); 574*9356374aSAndroid Build Coastguard Worker } 575*9356374aSAndroid Build Coastguard Worker 576*9356374aSAndroid Build Coastguard Worker // Use local (inline) storage for applicable target object types. 577*9356374aSAndroid Build Coastguard Worker template <class QualTRef, class... Args, 578*9356374aSAndroid Build Coastguard Worker typename = absl::enable_if_t< 579*9356374aSAndroid Build Coastguard Worker IsStoredLocally<RemoveCVRef<QualTRef>>::value>> 580*9356374aSAndroid Build Coastguard Worker void InitializeStorage(Args&&... args) { 581*9356374aSAndroid Build Coastguard Worker using RawT = RemoveCVRef<QualTRef>; 582*9356374aSAndroid Build Coastguard Worker ::new (static_cast<void*>(&state_.storage)) 583*9356374aSAndroid Build Coastguard Worker RawT(std::forward<Args>(args)...); 584*9356374aSAndroid Build Coastguard Worker 585*9356374aSAndroid Build Coastguard Worker invoker_ = LocalInvoker<SigIsNoexcept, ReturnType, QualTRef, P...>; 586*9356374aSAndroid Build Coastguard Worker // We can simplify our manager if we know the type is trivially copyable. 587*9356374aSAndroid Build Coastguard Worker InitializeLocalManager<RawT>(); 588*9356374aSAndroid Build Coastguard Worker } 589*9356374aSAndroid Build Coastguard Worker 590*9356374aSAndroid Build Coastguard Worker // Use remote storage for target objects that cannot be stored locally. 591*9356374aSAndroid Build Coastguard Worker template <class QualTRef, class... Args, 592*9356374aSAndroid Build Coastguard Worker absl::enable_if_t<!IsStoredLocally<RemoveCVRef<QualTRef>>::value, 593*9356374aSAndroid Build Coastguard Worker int> = 0> 594*9356374aSAndroid Build Coastguard Worker void InitializeStorage(Args&&... args) { 595*9356374aSAndroid Build Coastguard Worker InitializeRemoteManager<RemoveCVRef<QualTRef>>(std::forward<Args>(args)...); 596*9356374aSAndroid Build Coastguard Worker // This is set after everything else in case an exception is thrown in an 597*9356374aSAndroid Build Coastguard Worker // earlier step of the initialization. 598*9356374aSAndroid Build Coastguard Worker invoker_ = RemoteInvoker<SigIsNoexcept, ReturnType, QualTRef, P...>; 599*9356374aSAndroid Build Coastguard Worker } 600*9356374aSAndroid Build Coastguard Worker 601*9356374aSAndroid Build Coastguard Worker template <class T, 602*9356374aSAndroid Build Coastguard Worker typename = absl::enable_if_t<std::is_trivially_copyable<T>::value>> 603*9356374aSAndroid Build Coastguard Worker void InitializeLocalManager() { 604*9356374aSAndroid Build Coastguard Worker manager_ = LocalManagerTrivial; 605*9356374aSAndroid Build Coastguard Worker } 606*9356374aSAndroid Build Coastguard Worker 607*9356374aSAndroid Build Coastguard Worker template <class T, 608*9356374aSAndroid Build Coastguard Worker absl::enable_if_t<!std::is_trivially_copyable<T>::value, int> = 0> 609*9356374aSAndroid Build Coastguard Worker void InitializeLocalManager() { 610*9356374aSAndroid Build Coastguard Worker manager_ = LocalManagerNontrivial<T>; 611*9356374aSAndroid Build Coastguard Worker } 612*9356374aSAndroid Build Coastguard Worker 613*9356374aSAndroid Build Coastguard Worker template <class T> 614*9356374aSAndroid Build Coastguard Worker using HasTrivialRemoteStorage = 615*9356374aSAndroid Build Coastguard Worker std::integral_constant<bool, std::is_trivially_destructible<T>::value && 616*9356374aSAndroid Build Coastguard Worker alignof(T) <= 617*9356374aSAndroid Build Coastguard Worker ABSL_INTERNAL_DEFAULT_NEW_ALIGNMENT>; 618*9356374aSAndroid Build Coastguard Worker 619*9356374aSAndroid Build Coastguard Worker template <class T, class... Args, 620*9356374aSAndroid Build Coastguard Worker typename = absl::enable_if_t<HasTrivialRemoteStorage<T>::value>> 621*9356374aSAndroid Build Coastguard Worker void InitializeRemoteManager(Args&&... args) { 622*9356374aSAndroid Build Coastguard Worker // unique_ptr is used for exception-safety in case construction throws. 623*9356374aSAndroid Build Coastguard Worker std::unique_ptr<void, TrivialDeleter> uninitialized_target( 624*9356374aSAndroid Build Coastguard Worker ::operator new(sizeof(T)), TrivialDeleter(sizeof(T))); 625*9356374aSAndroid Build Coastguard Worker ::new (uninitialized_target.get()) T(std::forward<Args>(args)...); 626*9356374aSAndroid Build Coastguard Worker state_.remote.target = uninitialized_target.release(); 627*9356374aSAndroid Build Coastguard Worker state_.remote.size = sizeof(T); 628*9356374aSAndroid Build Coastguard Worker manager_ = RemoteManagerTrivial; 629*9356374aSAndroid Build Coastguard Worker } 630*9356374aSAndroid Build Coastguard Worker 631*9356374aSAndroid Build Coastguard Worker template <class T, class... Args, 632*9356374aSAndroid Build Coastguard Worker absl::enable_if_t<!HasTrivialRemoteStorage<T>::value, int> = 0> 633*9356374aSAndroid Build Coastguard Worker void InitializeRemoteManager(Args&&... args) { 634*9356374aSAndroid Build Coastguard Worker state_.remote.target = ::new T(std::forward<Args>(args)...); 635*9356374aSAndroid Build Coastguard Worker manager_ = RemoteManagerNontrivial<T>; 636*9356374aSAndroid Build Coastguard Worker } 637*9356374aSAndroid Build Coastguard Worker 638*9356374aSAndroid Build Coastguard Worker ////////////////////////////////////////////////////////////////////////////// 639*9356374aSAndroid Build Coastguard Worker // 640*9356374aSAndroid Build Coastguard Worker // Type trait to determine if the template argument is an AnyInvocable whose 641*9356374aSAndroid Build Coastguard Worker // function type is compatible enough with ours such that we can 642*9356374aSAndroid Build Coastguard Worker // "move the guts" out of it when moving, rather than having to place a new 643*9356374aSAndroid Build Coastguard Worker // object into remote storage. 644*9356374aSAndroid Build Coastguard Worker 645*9356374aSAndroid Build Coastguard Worker template <typename Other> 646*9356374aSAndroid Build Coastguard Worker struct IsCompatibleAnyInvocable { 647*9356374aSAndroid Build Coastguard Worker static constexpr bool value = false; 648*9356374aSAndroid Build Coastguard Worker }; 649*9356374aSAndroid Build Coastguard Worker 650*9356374aSAndroid Build Coastguard Worker template <typename Sig> 651*9356374aSAndroid Build Coastguard Worker struct IsCompatibleAnyInvocable<AnyInvocable<Sig>> { 652*9356374aSAndroid Build Coastguard Worker static constexpr bool value = 653*9356374aSAndroid Build Coastguard Worker (IsCompatibleConversion)(static_cast< 654*9356374aSAndroid Build Coastguard Worker typename AnyInvocable<Sig>::CoreImpl*>( 655*9356374aSAndroid Build Coastguard Worker nullptr), 656*9356374aSAndroid Build Coastguard Worker static_cast<CoreImpl*>(nullptr)); 657*9356374aSAndroid Build Coastguard Worker }; 658*9356374aSAndroid Build Coastguard Worker 659*9356374aSAndroid Build Coastguard Worker // 660*9356374aSAndroid Build Coastguard Worker ////////////////////////////////////////////////////////////////////////////// 661*9356374aSAndroid Build Coastguard Worker 662*9356374aSAndroid Build Coastguard Worker TypeErasedState state_; 663*9356374aSAndroid Build Coastguard Worker ManagerType* manager_; 664*9356374aSAndroid Build Coastguard Worker InvokerType<SigIsNoexcept, ReturnType, P...>* invoker_; 665*9356374aSAndroid Build Coastguard Worker }; 666*9356374aSAndroid Build Coastguard Worker 667*9356374aSAndroid Build Coastguard Worker // A constructor name-tag used with Impl to request the 668*9356374aSAndroid Build Coastguard Worker // conversion-constructor 669*9356374aSAndroid Build Coastguard Worker struct ConversionConstruct {}; 670*9356374aSAndroid Build Coastguard Worker 671*9356374aSAndroid Build Coastguard Worker //////////////////////////////////////////////////////////////////////////////// 672*9356374aSAndroid Build Coastguard Worker // 673*9356374aSAndroid Build Coastguard Worker // A metafunction that is normally an identity metafunction except that when 674*9356374aSAndroid Build Coastguard Worker // given a std::reference_wrapper<T>, it yields T&. This is necessary because 675*9356374aSAndroid Build Coastguard Worker // currently std::reference_wrapper's operator() is not conditionally noexcept, 676*9356374aSAndroid Build Coastguard Worker // so when checking if such an Invocable is nothrow-invocable, we must pull out 677*9356374aSAndroid Build Coastguard Worker // the underlying type. 678*9356374aSAndroid Build Coastguard Worker template <class T> 679*9356374aSAndroid Build Coastguard Worker struct UnwrapStdReferenceWrapperImpl { 680*9356374aSAndroid Build Coastguard Worker using type = T; 681*9356374aSAndroid Build Coastguard Worker }; 682*9356374aSAndroid Build Coastguard Worker 683*9356374aSAndroid Build Coastguard Worker template <class T> 684*9356374aSAndroid Build Coastguard Worker struct UnwrapStdReferenceWrapperImpl<std::reference_wrapper<T>> { 685*9356374aSAndroid Build Coastguard Worker using type = T&; 686*9356374aSAndroid Build Coastguard Worker }; 687*9356374aSAndroid Build Coastguard Worker 688*9356374aSAndroid Build Coastguard Worker template <class T> 689*9356374aSAndroid Build Coastguard Worker using UnwrapStdReferenceWrapper = 690*9356374aSAndroid Build Coastguard Worker typename UnwrapStdReferenceWrapperImpl<T>::type; 691*9356374aSAndroid Build Coastguard Worker // 692*9356374aSAndroid Build Coastguard Worker //////////////////////////////////////////////////////////////////////////////// 693*9356374aSAndroid Build Coastguard Worker 694*9356374aSAndroid Build Coastguard Worker // An alias that always yields std::true_type (used with constraints) where 695*9356374aSAndroid Build Coastguard Worker // substitution failures happen when forming the template arguments. 696*9356374aSAndroid Build Coastguard Worker template <class... T> 697*9356374aSAndroid Build Coastguard Worker using TrueAlias = 698*9356374aSAndroid Build Coastguard Worker std::integral_constant<bool, sizeof(absl::void_t<T...>*) != 0>; 699*9356374aSAndroid Build Coastguard Worker 700*9356374aSAndroid Build Coastguard Worker /*SFINAE constraints for the conversion-constructor.*/ 701*9356374aSAndroid Build Coastguard Worker template <class Sig, class F, 702*9356374aSAndroid Build Coastguard Worker class = absl::enable_if_t< 703*9356374aSAndroid Build Coastguard Worker !std::is_same<RemoveCVRef<F>, AnyInvocable<Sig>>::value>> 704*9356374aSAndroid Build Coastguard Worker using CanConvert = TrueAlias< 705*9356374aSAndroid Build Coastguard Worker absl::enable_if_t<!IsInPlaceType<RemoveCVRef<F>>::value>, 706*9356374aSAndroid Build Coastguard Worker absl::enable_if_t<Impl<Sig>::template CallIsValid<F>::value>, 707*9356374aSAndroid Build Coastguard Worker absl::enable_if_t< 708*9356374aSAndroid Build Coastguard Worker Impl<Sig>::template CallIsNoexceptIfSigIsNoexcept<F>::value>, 709*9356374aSAndroid Build Coastguard Worker absl::enable_if_t<std::is_constructible<absl::decay_t<F>, F>::value>>; 710*9356374aSAndroid Build Coastguard Worker 711*9356374aSAndroid Build Coastguard Worker /*SFINAE constraints for the std::in_place constructors.*/ 712*9356374aSAndroid Build Coastguard Worker template <class Sig, class F, class... Args> 713*9356374aSAndroid Build Coastguard Worker using CanEmplace = TrueAlias< 714*9356374aSAndroid Build Coastguard Worker absl::enable_if_t<Impl<Sig>::template CallIsValid<F>::value>, 715*9356374aSAndroid Build Coastguard Worker absl::enable_if_t< 716*9356374aSAndroid Build Coastguard Worker Impl<Sig>::template CallIsNoexceptIfSigIsNoexcept<F>::value>, 717*9356374aSAndroid Build Coastguard Worker absl::enable_if_t<std::is_constructible<absl::decay_t<F>, Args...>::value>>; 718*9356374aSAndroid Build Coastguard Worker 719*9356374aSAndroid Build Coastguard Worker /*SFINAE constraints for the conversion-assign operator.*/ 720*9356374aSAndroid Build Coastguard Worker template <class Sig, class F, 721*9356374aSAndroid Build Coastguard Worker class = absl::enable_if_t< 722*9356374aSAndroid Build Coastguard Worker !std::is_same<RemoveCVRef<F>, AnyInvocable<Sig>>::value>> 723*9356374aSAndroid Build Coastguard Worker using CanAssign = TrueAlias< 724*9356374aSAndroid Build Coastguard Worker absl::enable_if_t<Impl<Sig>::template CallIsValid<F>::value>, 725*9356374aSAndroid Build Coastguard Worker absl::enable_if_t< 726*9356374aSAndroid Build Coastguard Worker Impl<Sig>::template CallIsNoexceptIfSigIsNoexcept<F>::value>, 727*9356374aSAndroid Build Coastguard Worker absl::enable_if_t<std::is_constructible<absl::decay_t<F>, F>::value>>; 728*9356374aSAndroid Build Coastguard Worker 729*9356374aSAndroid Build Coastguard Worker /*SFINAE constraints for the reference-wrapper conversion-assign operator.*/ 730*9356374aSAndroid Build Coastguard Worker template <class Sig, class F> 731*9356374aSAndroid Build Coastguard Worker using CanAssignReferenceWrapper = TrueAlias< 732*9356374aSAndroid Build Coastguard Worker absl::enable_if_t< 733*9356374aSAndroid Build Coastguard Worker Impl<Sig>::template CallIsValid<std::reference_wrapper<F>>::value>, 734*9356374aSAndroid Build Coastguard Worker absl::enable_if_t<Impl<Sig>::template CallIsNoexceptIfSigIsNoexcept< 735*9356374aSAndroid Build Coastguard Worker std::reference_wrapper<F>>::value>>; 736*9356374aSAndroid Build Coastguard Worker 737*9356374aSAndroid Build Coastguard Worker //////////////////////////////////////////////////////////////////////////////// 738*9356374aSAndroid Build Coastguard Worker // 739*9356374aSAndroid Build Coastguard Worker // The constraint for checking whether or not a call meets the noexcept 740*9356374aSAndroid Build Coastguard Worker // callability requirements. This is a preprocessor macro because specifying it 741*9356374aSAndroid Build Coastguard Worker // this way as opposed to a disjunction/branch can improve the user-side error 742*9356374aSAndroid Build Coastguard Worker // messages and avoids an instantiation of std::is_nothrow_invocable_r in the 743*9356374aSAndroid Build Coastguard Worker // cases where the user did not specify a noexcept function type. 744*9356374aSAndroid Build Coastguard Worker // 745*9356374aSAndroid Build Coastguard Worker #define ABSL_INTERNAL_ANY_INVOCABLE_NOEXCEPT_CONSTRAINT(inv_quals, noex) \ 746*9356374aSAndroid Build Coastguard Worker ABSL_INTERNAL_ANY_INVOCABLE_NOEXCEPT_CONSTRAINT_##noex(inv_quals) 747*9356374aSAndroid Build Coastguard Worker 748*9356374aSAndroid Build Coastguard Worker // The disjunction below is because we can't rely on std::is_nothrow_invocable_r 749*9356374aSAndroid Build Coastguard Worker // to give the right result when ReturnType is non-moveable in toolchains that 750*9356374aSAndroid Build Coastguard Worker // don't treat non-moveable result types correctly. For example this was the 751*9356374aSAndroid Build Coastguard Worker // case in libc++ before commit c3a24882 (2022-05). 752*9356374aSAndroid Build Coastguard Worker #define ABSL_INTERNAL_ANY_INVOCABLE_NOEXCEPT_CONSTRAINT_true(inv_quals) \ 753*9356374aSAndroid Build Coastguard Worker absl::enable_if_t<absl::disjunction< \ 754*9356374aSAndroid Build Coastguard Worker std::is_nothrow_invocable_r< \ 755*9356374aSAndroid Build Coastguard Worker ReturnType, UnwrapStdReferenceWrapper<absl::decay_t<F>> inv_quals, \ 756*9356374aSAndroid Build Coastguard Worker P...>, \ 757*9356374aSAndroid Build Coastguard Worker std::conjunction< \ 758*9356374aSAndroid Build Coastguard Worker std::is_nothrow_invocable< \ 759*9356374aSAndroid Build Coastguard Worker UnwrapStdReferenceWrapper<absl::decay_t<F>> inv_quals, P...>, \ 760*9356374aSAndroid Build Coastguard Worker std::is_same< \ 761*9356374aSAndroid Build Coastguard Worker ReturnType, \ 762*9356374aSAndroid Build Coastguard Worker absl::base_internal::invoke_result_t< \ 763*9356374aSAndroid Build Coastguard Worker UnwrapStdReferenceWrapper<absl::decay_t<F>> inv_quals, \ 764*9356374aSAndroid Build Coastguard Worker P...>>>>::value> 765*9356374aSAndroid Build Coastguard Worker 766*9356374aSAndroid Build Coastguard Worker #define ABSL_INTERNAL_ANY_INVOCABLE_NOEXCEPT_CONSTRAINT_false(inv_quals) 767*9356374aSAndroid Build Coastguard Worker // 768*9356374aSAndroid Build Coastguard Worker //////////////////////////////////////////////////////////////////////////////// 769*9356374aSAndroid Build Coastguard Worker 770*9356374aSAndroid Build Coastguard Worker // A macro to generate partial specializations of Impl with the different 771*9356374aSAndroid Build Coastguard Worker // combinations of supported cv/reference qualifiers and noexcept specifier. 772*9356374aSAndroid Build Coastguard Worker // 773*9356374aSAndroid Build Coastguard Worker // Here, `cv` are the cv-qualifiers if any, `ref` is the ref-qualifier if any, 774*9356374aSAndroid Build Coastguard Worker // inv_quals is the reference type to be used when invoking the target, and 775*9356374aSAndroid Build Coastguard Worker // noex is "true" if the function type is noexcept, or false if it is not. 776*9356374aSAndroid Build Coastguard Worker // 777*9356374aSAndroid Build Coastguard Worker // The CallIsValid condition is more complicated than simply using 778*9356374aSAndroid Build Coastguard Worker // absl::base_internal::is_invocable_r because we can't rely on it to give the 779*9356374aSAndroid Build Coastguard Worker // right result when ReturnType is non-moveable in toolchains that don't treat 780*9356374aSAndroid Build Coastguard Worker // non-moveable result types correctly. For example this was the case in libc++ 781*9356374aSAndroid Build Coastguard Worker // before commit c3a24882 (2022-05). 782*9356374aSAndroid Build Coastguard Worker #define ABSL_INTERNAL_ANY_INVOCABLE_IMPL_(cv, ref, inv_quals, noex) \ 783*9356374aSAndroid Build Coastguard Worker template <class ReturnType, class... P> \ 784*9356374aSAndroid Build Coastguard Worker class Impl<ReturnType(P...) cv ref ABSL_INTERNAL_NOEXCEPT_SPEC(noex)> \ 785*9356374aSAndroid Build Coastguard Worker : public CoreImpl<noex, ReturnType, P...> { \ 786*9356374aSAndroid Build Coastguard Worker public: \ 787*9356374aSAndroid Build Coastguard Worker /*The base class, which contains the datamembers and core operations*/ \ 788*9356374aSAndroid Build Coastguard Worker using Core = CoreImpl<noex, ReturnType, P...>; \ 789*9356374aSAndroid Build Coastguard Worker \ 790*9356374aSAndroid Build Coastguard Worker /*SFINAE constraint to check if F is invocable with the proper signature*/ \ 791*9356374aSAndroid Build Coastguard Worker template <class F> \ 792*9356374aSAndroid Build Coastguard Worker using CallIsValid = TrueAlias<absl::enable_if_t<absl::disjunction< \ 793*9356374aSAndroid Build Coastguard Worker absl::base_internal::is_invocable_r<ReturnType, \ 794*9356374aSAndroid Build Coastguard Worker absl::decay_t<F> inv_quals, P...>, \ 795*9356374aSAndroid Build Coastguard Worker std::is_same<ReturnType, \ 796*9356374aSAndroid Build Coastguard Worker absl::base_internal::invoke_result_t< \ 797*9356374aSAndroid Build Coastguard Worker absl::decay_t<F> inv_quals, P...>>>::value>>; \ 798*9356374aSAndroid Build Coastguard Worker \ 799*9356374aSAndroid Build Coastguard Worker /*SFINAE constraint to check if F is nothrow-invocable when necessary*/ \ 800*9356374aSAndroid Build Coastguard Worker template <class F> \ 801*9356374aSAndroid Build Coastguard Worker using CallIsNoexceptIfSigIsNoexcept = \ 802*9356374aSAndroid Build Coastguard Worker TrueAlias<ABSL_INTERNAL_ANY_INVOCABLE_NOEXCEPT_CONSTRAINT(inv_quals, \ 803*9356374aSAndroid Build Coastguard Worker noex)>; \ 804*9356374aSAndroid Build Coastguard Worker \ 805*9356374aSAndroid Build Coastguard Worker /*Put the AnyInvocable into an empty state.*/ \ 806*9356374aSAndroid Build Coastguard Worker Impl() = default; \ 807*9356374aSAndroid Build Coastguard Worker \ 808*9356374aSAndroid Build Coastguard Worker /*The implementation of a conversion-constructor from "f*/ \ 809*9356374aSAndroid Build Coastguard Worker /*This forwards to Core, attaching inv_quals so that the base class*/ \ 810*9356374aSAndroid Build Coastguard Worker /*knows how to properly type-erase the invocation.*/ \ 811*9356374aSAndroid Build Coastguard Worker template <class F> \ 812*9356374aSAndroid Build Coastguard Worker explicit Impl(ConversionConstruct, F&& f) \ 813*9356374aSAndroid Build Coastguard Worker : Core(TypedConversionConstruct< \ 814*9356374aSAndroid Build Coastguard Worker typename std::decay<F>::type inv_quals>(), \ 815*9356374aSAndroid Build Coastguard Worker std::forward<F>(f)) {} \ 816*9356374aSAndroid Build Coastguard Worker \ 817*9356374aSAndroid Build Coastguard Worker /*Forward along the in-place construction parameters.*/ \ 818*9356374aSAndroid Build Coastguard Worker template <class T, class... Args> \ 819*9356374aSAndroid Build Coastguard Worker explicit Impl(absl::in_place_type_t<T>, Args&&... args) \ 820*9356374aSAndroid Build Coastguard Worker : Core(absl::in_place_type<absl::decay_t<T> inv_quals>, \ 821*9356374aSAndroid Build Coastguard Worker std::forward<Args>(args)...) {} \ 822*9356374aSAndroid Build Coastguard Worker \ 823*9356374aSAndroid Build Coastguard Worker /*Raises a fatal error when the AnyInvocable is invoked after a move*/ \ 824*9356374aSAndroid Build Coastguard Worker static ReturnType InvokedAfterMove( \ 825*9356374aSAndroid Build Coastguard Worker TypeErasedState*, \ 826*9356374aSAndroid Build Coastguard Worker ForwardedParameterType<P>...) noexcept(noex) { \ 827*9356374aSAndroid Build Coastguard Worker ABSL_HARDENING_ASSERT(false && "AnyInvocable use-after-move"); \ 828*9356374aSAndroid Build Coastguard Worker std::terminate(); \ 829*9356374aSAndroid Build Coastguard Worker } \ 830*9356374aSAndroid Build Coastguard Worker \ 831*9356374aSAndroid Build Coastguard Worker InvokerType<noex, ReturnType, P...>* ExtractInvoker() cv { \ 832*9356374aSAndroid Build Coastguard Worker using QualifiedTestType = int cv ref; \ 833*9356374aSAndroid Build Coastguard Worker auto* invoker = this->invoker_; \ 834*9356374aSAndroid Build Coastguard Worker if (!std::is_const<QualifiedTestType>::value && \ 835*9356374aSAndroid Build Coastguard Worker std::is_rvalue_reference<QualifiedTestType>::value) { \ 836*9356374aSAndroid Build Coastguard Worker ABSL_ASSERT([this]() { \ 837*9356374aSAndroid Build Coastguard Worker /* We checked that this isn't const above, so const_cast is safe */ \ 838*9356374aSAndroid Build Coastguard Worker const_cast<Impl*>(this)->invoker_ = InvokedAfterMove; \ 839*9356374aSAndroid Build Coastguard Worker return this->HasValue(); \ 840*9356374aSAndroid Build Coastguard Worker }()); \ 841*9356374aSAndroid Build Coastguard Worker } \ 842*9356374aSAndroid Build Coastguard Worker return invoker; \ 843*9356374aSAndroid Build Coastguard Worker } \ 844*9356374aSAndroid Build Coastguard Worker \ 845*9356374aSAndroid Build Coastguard Worker /*The actual invocation operation with the proper signature*/ \ 846*9356374aSAndroid Build Coastguard Worker ReturnType operator()(P... args) cv ref noexcept(noex) { \ 847*9356374aSAndroid Build Coastguard Worker assert(this->invoker_ != nullptr); \ 848*9356374aSAndroid Build Coastguard Worker return this->ExtractInvoker()( \ 849*9356374aSAndroid Build Coastguard Worker const_cast<TypeErasedState*>(&this->state_), \ 850*9356374aSAndroid Build Coastguard Worker static_cast<ForwardedParameterType<P>>(args)...); \ 851*9356374aSAndroid Build Coastguard Worker } \ 852*9356374aSAndroid Build Coastguard Worker } 853*9356374aSAndroid Build Coastguard Worker 854*9356374aSAndroid Build Coastguard Worker // Define the `noexcept(true)` specialization only for C++17 and beyond, when 855*9356374aSAndroid Build Coastguard Worker // `noexcept` is part of the type system. 856*9356374aSAndroid Build Coastguard Worker #if ABSL_INTERNAL_CPLUSPLUS_LANG >= 201703L 857*9356374aSAndroid Build Coastguard Worker // A convenience macro that defines specializations for the noexcept(true) and 858*9356374aSAndroid Build Coastguard Worker // noexcept(false) forms, given the other properties. 859*9356374aSAndroid Build Coastguard Worker #define ABSL_INTERNAL_ANY_INVOCABLE_IMPL(cv, ref, inv_quals) \ 860*9356374aSAndroid Build Coastguard Worker ABSL_INTERNAL_ANY_INVOCABLE_IMPL_(cv, ref, inv_quals, false); \ 861*9356374aSAndroid Build Coastguard Worker ABSL_INTERNAL_ANY_INVOCABLE_IMPL_(cv, ref, inv_quals, true) 862*9356374aSAndroid Build Coastguard Worker #else 863*9356374aSAndroid Build Coastguard Worker #define ABSL_INTERNAL_ANY_INVOCABLE_IMPL(cv, ref, inv_quals) \ 864*9356374aSAndroid Build Coastguard Worker ABSL_INTERNAL_ANY_INVOCABLE_IMPL_(cv, ref, inv_quals, false) 865*9356374aSAndroid Build Coastguard Worker #endif 866*9356374aSAndroid Build Coastguard Worker 867*9356374aSAndroid Build Coastguard Worker // Non-ref-qualified partial specializations 868*9356374aSAndroid Build Coastguard Worker ABSL_INTERNAL_ANY_INVOCABLE_IMPL(, , &); 869*9356374aSAndroid Build Coastguard Worker ABSL_INTERNAL_ANY_INVOCABLE_IMPL(const, , const&); 870*9356374aSAndroid Build Coastguard Worker 871*9356374aSAndroid Build Coastguard Worker // Lvalue-ref-qualified partial specializations 872*9356374aSAndroid Build Coastguard Worker ABSL_INTERNAL_ANY_INVOCABLE_IMPL(, &, &); 873*9356374aSAndroid Build Coastguard Worker ABSL_INTERNAL_ANY_INVOCABLE_IMPL(const, &, const&); 874*9356374aSAndroid Build Coastguard Worker 875*9356374aSAndroid Build Coastguard Worker // Rvalue-ref-qualified partial specializations 876*9356374aSAndroid Build Coastguard Worker ABSL_INTERNAL_ANY_INVOCABLE_IMPL(, &&, &&); 877*9356374aSAndroid Build Coastguard Worker ABSL_INTERNAL_ANY_INVOCABLE_IMPL(const, &&, const&&); 878*9356374aSAndroid Build Coastguard Worker 879*9356374aSAndroid Build Coastguard Worker // Undef the detail-only macros. 880*9356374aSAndroid Build Coastguard Worker #undef ABSL_INTERNAL_ANY_INVOCABLE_IMPL 881*9356374aSAndroid Build Coastguard Worker #undef ABSL_INTERNAL_ANY_INVOCABLE_IMPL_ 882*9356374aSAndroid Build Coastguard Worker #undef ABSL_INTERNAL_ANY_INVOCABLE_NOEXCEPT_CONSTRAINT_false 883*9356374aSAndroid Build Coastguard Worker #undef ABSL_INTERNAL_ANY_INVOCABLE_NOEXCEPT_CONSTRAINT_true 884*9356374aSAndroid Build Coastguard Worker #undef ABSL_INTERNAL_ANY_INVOCABLE_NOEXCEPT_CONSTRAINT 885*9356374aSAndroid Build Coastguard Worker #undef ABSL_INTERNAL_NOEXCEPT_SPEC 886*9356374aSAndroid Build Coastguard Worker 887*9356374aSAndroid Build Coastguard Worker } // namespace internal_any_invocable 888*9356374aSAndroid Build Coastguard Worker ABSL_NAMESPACE_END 889*9356374aSAndroid Build Coastguard Worker } // namespace absl 890*9356374aSAndroid Build Coastguard Worker 891*9356374aSAndroid Build Coastguard Worker #endif // ABSL_FUNCTIONAL_INTERNAL_ANY_INVOCABLE_H_ 892