Skip to content

Commit 2050d2e

Browse files
authored
[libc++] Simplify std::function further after removing allocator support (#144443)
Since we've removed allocator support, we can remove a few support structures. This only affects the policy implementation, so this shouldn't even be ABI sensitive.
1 parent 32dbaf1 commit 2050d2e

File tree

1 file changed

+37
-90
lines changed

1 file changed

+37
-90
lines changed

libcxx/include/__functional/function.h

Lines changed: 37 additions & 90 deletions
Original file line numberDiff line numberDiff line change
@@ -125,31 +125,6 @@ _LIBCPP_HIDE_FROM_ABI bool __not_null(_Rp (^__p)(_Args...)) {
125125

126126
namespace __function {
127127

128-
template <class _Fp, class _FB>
129-
class __default_alloc_func;
130-
131-
template <class _Fp, class _Rp, class... _ArgTypes>
132-
class __default_alloc_func<_Fp, _Rp(_ArgTypes...)> {
133-
_Fp __f_;
134-
135-
public:
136-
using _Target _LIBCPP_NODEBUG = _Fp;
137-
138-
_LIBCPP_HIDE_FROM_ABI const _Target& __target() const { return __f_; }
139-
140-
_LIBCPP_HIDE_FROM_ABI explicit __default_alloc_func(_Target&& __f) : __f_(std::move(__f)) {}
141-
142-
_LIBCPP_HIDE_FROM_ABI explicit __default_alloc_func(const _Target& __f) : __f_(__f) {}
143-
144-
_LIBCPP_HIDE_FROM_ABI _Rp operator()(_ArgTypes&&... __arg) {
145-
return std::__invoke_r<_Rp>(__f_, std::forward<_ArgTypes>(__arg)...);
146-
}
147-
148-
_LIBCPP_HIDE_FROM_ABI __default_alloc_func* __clone() const { return new __default_alloc_func(__f_); }
149-
150-
_LIBCPP_HIDE_FROM_ABI void destroy() _NOEXCEPT { __f_.~_Target(); }
151-
};
152-
153128
// __base provides an abstract interface for copyable functors.
154129

155130
template <class _Fp>
@@ -402,7 +377,7 @@ struct __policy {
402377
template <typename _Fun>
403378
_LIBCPP_HIDE_FROM_ABI static void* __large_clone(const void* __s) {
404379
const _Fun* __f = static_cast<const _Fun*>(__s);
405-
return __f->__clone();
380+
return new _Fun(*__f);
406381
}
407382

408383
template <typename _Fun>
@@ -417,7 +392,7 @@ struct __policy {
417392
std::addressof(__large_destroy<_Fun>),
418393
false,
419394
# if _LIBCPP_HAS_RTTI
420-
&typeid(typename _Fun::_Target)
395+
&typeid(_Fun)
421396
# else
422397
nullptr
423398
# endif
@@ -432,7 +407,7 @@ struct __policy {
432407
nullptr,
433408
false,
434409
# if _LIBCPP_HAS_RTTI
435-
&typeid(typename _Fun::_Target)
410+
&typeid(_Fun)
436411
# else
437412
nullptr
438413
# endif
@@ -446,42 +421,7 @@ struct __policy {
446421
template <typename _Tp>
447422
using __fast_forward _LIBCPP_NODEBUG = __conditional_t<is_scalar<_Tp>::value, _Tp, _Tp&&>;
448423

449-
// __policy_invoker calls an instance of __default_alloc_func held in __policy_storage.
450-
451-
template <class _Fp>
452-
struct __policy_invoker;
453-
454-
template <class _Rp, class... _ArgTypes>
455-
struct __policy_invoker<_Rp(_ArgTypes...)> {
456-
typedef _Rp (*__Call)(const __policy_storage*, __fast_forward<_ArgTypes>...);
457-
458-
__Call __call_;
459-
460-
// Creates an invoker that throws bad_function_call.
461-
_LIBCPP_HIDE_FROM_ABI __policy_invoker() : __call_(&__call_empty) {}
462-
463-
// Creates an invoker that calls the given instance of __func.
464-
template <typename _Fun>
465-
_LIBCPP_HIDE_FROM_ABI static __policy_invoker __create() {
466-
return __policy_invoker(std::addressof(__call_impl<_Fun>));
467-
}
468-
469-
private:
470-
_LIBCPP_HIDE_FROM_ABI explicit __policy_invoker(__Call __c) : __call_(__c) {}
471-
472-
_LIBCPP_HIDE_FROM_ABI static _Rp __call_empty(const __policy_storage*, __fast_forward<_ArgTypes>...) {
473-
std::__throw_bad_function_call();
474-
}
475-
476-
template <typename _Fun>
477-
_LIBCPP_HIDE_FROM_ABI static _Rp __call_impl(const __policy_storage* __buf, __fast_forward<_ArgTypes>... __args) {
478-
_Fun* __f = reinterpret_cast<_Fun*>(__use_small_storage<_Fun>::value ? &__buf->__small : __buf->__large);
479-
return (*__f)(std::forward<_ArgTypes>(__args)...);
480-
}
481-
};
482-
483-
// __policy_func uses a __policy and __policy_invoker to create a type-erased,
484-
// copyable functor.
424+
// __policy_func uses a __policy to create a type-erased, copyable functor.
485425

486426
template <class _Fp>
487427
class __policy_func;
@@ -491,45 +431,52 @@ class __policy_func<_Rp(_ArgTypes...)> {
491431
// Inline storage for small objects.
492432
__policy_storage __buf_;
493433

494-
// Calls the value stored in __buf_. This could technically be part of
495-
// policy, but storing it here eliminates a level of indirection inside
496-
// operator().
497-
typedef __function::__policy_invoker<_Rp(_ArgTypes...)> __invoker;
498-
__invoker __invoker_;
434+
using _ErasedFunc _LIBCPP_NODEBUG = _Rp(const __policy_storage*, __fast_forward<_ArgTypes>...);
435+
436+
_ErasedFunc* __func_;
499437

500438
// The policy that describes how to move / copy / destroy __buf_. Never
501439
// null, even if the function is empty.
502440
const __policy* __policy_;
503441

442+
_LIBCPP_HIDE_FROM_ABI static _Rp __empty_func(const __policy_storage*, __fast_forward<_ArgTypes>...) {
443+
std::__throw_bad_function_call();
444+
}
445+
446+
template <class _Fun>
447+
_LIBCPP_HIDE_FROM_ABI static _Rp __call_func(const __policy_storage* __buf, __fast_forward<_ArgTypes>... __args) {
448+
_Fun* __func = reinterpret_cast<_Fun*>(__use_small_storage<_Fun>::value ? &__buf->__small : __buf->__large);
449+
450+
return std::__invoke_r<_Rp>(*__func, std::forward<_ArgTypes>(__args)...);
451+
}
452+
504453
public:
505-
_LIBCPP_HIDE_FROM_ABI __policy_func() : __policy_(__policy::__create_empty()) {}
454+
_LIBCPP_HIDE_FROM_ABI __policy_func() : __func_(__empty_func), __policy_(__policy::__create_empty()) {}
506455

507456
template <class _Fp, __enable_if_t<!is_same<__decay_t<_Fp>, __policy_func>::value, int> = 0>
508457
_LIBCPP_HIDE_FROM_ABI explicit __policy_func(_Fp&& __f) : __policy_(__policy::__create_empty()) {
509-
typedef __default_alloc_func<_Fp, _Rp(_ArgTypes...)> _Fun;
510-
511458
if (__function::__not_null(__f)) {
512-
__invoker_ = __invoker::template __create<_Fun>();
513-
__policy_ = __policy::__create<_Fun>();
514-
if (__use_small_storage<_Fun>()) {
515-
::new ((void*)&__buf_.__small) _Fun(std::move(__f));
459+
__func_ = __call_func<_Fp>;
460+
__policy_ = __policy::__create<_Fp>();
461+
if (__use_small_storage<_Fp>()) {
462+
::new ((void*)&__buf_.__small) _Fp(std::move(__f));
516463
} else {
517-
__buf_.__large = ::new _Fun(std::move(__f));
464+
__buf_.__large = ::new _Fp(std::move(__f));
518465
}
519466
}
520467
}
521468

522469
_LIBCPP_HIDE_FROM_ABI __policy_func(const __policy_func& __f)
523-
: __buf_(__f.__buf_), __invoker_(__f.__invoker_), __policy_(__f.__policy_) {
470+
: __buf_(__f.__buf_), __func_(__f.__func_), __policy_(__f.__policy_) {
524471
if (__policy_->__clone)
525472
__buf_.__large = __policy_->__clone(__f.__buf_.__large);
526473
}
527474

528475
_LIBCPP_HIDE_FROM_ABI __policy_func(__policy_func&& __f)
529-
: __buf_(__f.__buf_), __invoker_(__f.__invoker_), __policy_(__f.__policy_) {
476+
: __buf_(__f.__buf_), __func_(__f.__func_), __policy_(__f.__policy_) {
530477
if (__policy_->__destroy) {
531-
__f.__policy_ = __policy::__create_empty();
532-
__f.__invoker_ = __invoker();
478+
__f.__policy_ = __policy::__create_empty();
479+
__f.__func_ = {};
533480
}
534481
}
535482

@@ -539,30 +486,30 @@ class __policy_func<_Rp(_ArgTypes...)> {
539486
}
540487

541488
_LIBCPP_HIDE_FROM_ABI __policy_func& operator=(__policy_func&& __f) {
542-
*this = nullptr;
543-
__buf_ = __f.__buf_;
544-
__invoker_ = __f.__invoker_;
545-
__policy_ = __f.__policy_;
546-
__f.__policy_ = __policy::__create_empty();
547-
__f.__invoker_ = __invoker();
489+
*this = nullptr;
490+
__buf_ = __f.__buf_;
491+
__func_ = __f.__func_;
492+
__policy_ = __f.__policy_;
493+
__f.__policy_ = __policy::__create_empty();
494+
__f.__func_ = {};
548495
return *this;
549496
}
550497

551498
_LIBCPP_HIDE_FROM_ABI __policy_func& operator=(nullptr_t) {
552499
const __policy* __p = __policy_;
553500
__policy_ = __policy::__create_empty();
554-
__invoker_ = __invoker();
501+
__func_ = {};
555502
if (__p->__destroy)
556503
__p->__destroy(__buf_.__large);
557504
return *this;
558505
}
559506

560507
_LIBCPP_HIDE_FROM_ABI _Rp operator()(_ArgTypes&&... __args) const {
561-
return __invoker_.__call_(std::addressof(__buf_), std::forward<_ArgTypes>(__args)...);
508+
return __func_(std::addressof(__buf_), std::forward<_ArgTypes>(__args)...);
562509
}
563510

564511
_LIBCPP_HIDE_FROM_ABI void swap(__policy_func& __f) {
565-
std::swap(__invoker_, __f.__invoker_);
512+
std::swap(__func_, __f.__func_);
566513
std::swap(__policy_, __f.__policy_);
567514
std::swap(__buf_, __f.__buf_);
568515
}

0 commit comments

Comments
 (0)