xref: /aosp_15_r20/external/abseil-cpp/absl/functional/internal/any_invocable.h (revision 9356374a3709195abf420251b3e825997ff56c0f)
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