You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

any_invocable.h 45 kB

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