summaryrefslogtreecommitdiff
path: root/absl/functional/internal/any_invocable.h
diff options
context:
space:
mode:
Diffstat (limited to 'absl/functional/internal/any_invocable.h')
-rw-r--r--absl/functional/internal/any_invocable.h24
1 files changed, 22 insertions, 2 deletions
diff --git a/absl/functional/internal/any_invocable.h b/absl/functional/internal/any_invocable.h
index 35b389d1..8fce4bf6 100644
--- a/absl/functional/internal/any_invocable.h
+++ b/absl/functional/internal/any_invocable.h
@@ -809,11 +809,31 @@ using CanAssignReferenceWrapper = TrueAlias<
: Core(absl::in_place_type<absl::decay_t<T> inv_quals>, \
std::forward<Args>(args)...) {} \
\
+ InvokerType<noex, ReturnType, P...>* ExtractInvoker() cv { \
+ using QualifiedTestType = int cv ref; \
+ auto* invoker = this->invoker_; \
+ if (!std::is_const<QualifiedTestType>::value && \
+ std::is_rvalue_reference<QualifiedTestType>::value) { \
+ ABSL_HARDENING_ASSERT([this]() { \
+ /* We checked that this isn't const above, so const_cast is safe */ \
+ const_cast<Impl*>(this)->invoker_ = \
+ [](TypeErasedState*, \
+ ForwardedParameterType<P>...) noexcept(noex) -> ReturnType { \
+ ABSL_HARDENING_ASSERT(false && "AnyInvocable use-after-move"); \
+ std::terminate(); \
+ }; \
+ return this->HasValue(); \
+ }()); \
+ } \
+ return invoker; \
+ } \
+ \
/*The actual invocation operation with the proper signature*/ \
ReturnType operator()(P... args) cv ref noexcept(noex) { \
assert(this->invoker_ != nullptr); \
- return this->invoker_(const_cast<TypeErasedState*>(&this->state_), \
- static_cast<ForwardedParameterType<P>>(args)...); \
+ return this->ExtractInvoker()( \
+ const_cast<TypeErasedState*>(&this->state_), \
+ static_cast<ForwardedParameterType<P>>(args)...); \
} \
}