814 lines · c
1// -*- C++ -*-2//===----------------------------------------------------------------------===//3//4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.5// See https://llvm.org/LICENSE.txt for license information.6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception7//8//===----------------------------------------------------------------------===//9 10#ifndef _LIBCPP___FUNCTIONAL_FUNCTION_H11#define _LIBCPP___FUNCTIONAL_FUNCTION_H12 13#include <__assert>14#include <__config>15#include <__cstddef/nullptr_t.h>16#include <__exception/exception.h>17#include <__functional/binary_function.h>18#include <__functional/unary_function.h>19#include <__memory/addressof.h>20#include <__type_traits/aligned_storage.h>21#include <__type_traits/decay.h>22#include <__type_traits/invoke.h>23#include <__type_traits/is_scalar.h>24#include <__type_traits/is_trivially_constructible.h>25#include <__type_traits/is_trivially_destructible.h>26#include <__type_traits/strip_signature.h>27#include <__utility/forward.h>28#include <__utility/move.h>29#include <__utility/swap.h>30#include <tuple>31#include <typeinfo>32 33#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)34# pragma GCC system_header35#endif36 37_LIBCPP_PUSH_MACROS38#include <__undef_macros>39 40#ifndef _LIBCPP_CXX03_LANG41 42_LIBCPP_BEGIN_NAMESPACE_STD43 44// bad_function_call45 46_LIBCPP_DIAGNOSTIC_PUSH47# if !_LIBCPP_AVAILABILITY_HAS_BAD_FUNCTION_CALL_KEY_FUNCTION48_LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wweak-vtables")49# endif50class _LIBCPP_EXPORTED_FROM_ABI bad_function_call : public exception {51public:52 _LIBCPP_HIDE_FROM_ABI bad_function_call() _NOEXCEPT = default;53 _LIBCPP_HIDE_FROM_ABI bad_function_call(const bad_function_call&) _NOEXCEPT = default;54 _LIBCPP_HIDE_FROM_ABI bad_function_call& operator=(const bad_function_call&) _NOEXCEPT = default;55// Note that when a key function is not used, every translation unit that uses56// bad_function_call will end up containing a weak definition of the vtable and57// typeinfo.58# if _LIBCPP_AVAILABILITY_HAS_BAD_FUNCTION_CALL_KEY_FUNCTION59 ~bad_function_call() _NOEXCEPT override;60# else61 _LIBCPP_HIDE_FROM_ABI_VIRTUAL ~bad_function_call() _NOEXCEPT override {}62# endif63 64# if _LIBCPP_AVAILABILITY_HAS_BAD_FUNCTION_CALL_GOOD_WHAT_MESSAGE65 const char* what() const _NOEXCEPT override;66# endif67};68_LIBCPP_DIAGNOSTIC_POP69 70[[__noreturn__]] inline _LIBCPP_HIDE_FROM_ABI void __throw_bad_function_call() {71# if _LIBCPP_HAS_EXCEPTIONS72 throw bad_function_call();73# else74 _LIBCPP_VERBOSE_ABORT("bad_function_call was thrown in -fno-exceptions mode");75# endif76}77 78template <class _Fp>79class function; // undefined80 81namespace __function {82 83template <class _Rp>84struct __maybe_derive_from_unary_function {};85 86template <class _Rp, class _A1>87struct __maybe_derive_from_unary_function<_Rp(_A1)> : public __unary_function<_A1, _Rp> {};88 89template <class _Rp>90struct __maybe_derive_from_binary_function {};91 92template <class _Rp, class _A1, class _A2>93struct __maybe_derive_from_binary_function<_Rp(_A1, _A2)> : public __binary_function<_A1, _A2, _Rp> {};94 95template <class _Fp>96_LIBCPP_HIDE_FROM_ABI bool __is_null(_Fp const&) {97 return false;98}99 100template <class _Fp>101_LIBCPP_HIDE_FROM_ABI bool __is_null(_Fp* __ptr) {102 return !__ptr;103}104 105template <class _Ret, class _Class>106_LIBCPP_HIDE_FROM_ABI bool __is_null(_Ret _Class::* __ptr) {107 return !__ptr;108}109 110template <class _Fp>111_LIBCPP_HIDE_FROM_ABI bool __is_null(function<_Fp> const& __f) {112 return !__f;113}114 115# if __has_extension(blocks)116template <class _Rp, class... _Args>117_LIBCPP_HIDE_FROM_ABI bool __is_null(_Rp (^__p)(_Args...)) {118 return !__p;119}120# endif121 122} // namespace __function123 124namespace __function {125 126// __base provides an abstract interface for copyable functors.127 128template <class _Fp>129class __base;130 131template <class _Rp, class... _ArgTypes>132class __base<_Rp(_ArgTypes...)> {133public:134 __base(const __base&) = delete;135 __base& operator=(const __base&) = delete;136 137 _LIBCPP_HIDE_FROM_ABI __base() {}138 _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual ~__base() {}139 virtual __base* __clone() const = 0;140 virtual void __clone(__base*) const = 0;141 virtual void destroy() _NOEXCEPT = 0;142 virtual void destroy_deallocate() _NOEXCEPT = 0;143 virtual _Rp operator()(_ArgTypes&&...) = 0;144# if _LIBCPP_HAS_RTTI145 virtual const void* target(const type_info&) const _NOEXCEPT = 0;146 virtual const std::type_info& target_type() const _NOEXCEPT = 0;147# endif // _LIBCPP_HAS_RTTI148};149 150// __func implements __base for a given functor type.151 152template <class _FD, class _FB>153class __func;154 155template <class _Fp, class _Rp, class... _ArgTypes>156class __func<_Fp, _Rp(_ArgTypes...)> : public __base<_Rp(_ArgTypes...)> {157 _Fp __func_;158 159public:160 _LIBCPP_HIDE_FROM_ABI explicit __func(_Fp&& __f) : __func_(std::move(__f)) {}161 _LIBCPP_HIDE_FROM_ABI explicit __func(const _Fp& __f) : __func_(__f) {}162 163 _LIBCPP_HIDE_FROM_ABI_VIRTUAL __base<_Rp(_ArgTypes...)>* __clone() const override { return new __func(__func_); }164 165 _LIBCPP_HIDE_FROM_ABI_VIRTUAL void __clone(__base<_Rp(_ArgTypes...)>* __p) const override {166 ::new ((void*)__p) __func(__func_);167 }168 169 _LIBCPP_HIDE_FROM_ABI_VIRTUAL void destroy() _NOEXCEPT override { __func_.~_Fp(); }170 _LIBCPP_HIDE_FROM_ABI_VIRTUAL void destroy_deallocate() _NOEXCEPT override { delete this; }171 _LIBCPP_HIDE_FROM_ABI_VIRTUAL _Rp operator()(_ArgTypes&&... __arg) override {172 return std::__invoke_r<_Rp>(__func_, std::forward<_ArgTypes>(__arg)...);173 }174# if _LIBCPP_HAS_RTTI175 _LIBCPP_HIDE_FROM_ABI_VIRTUAL const void* target(const type_info& __ti) const _NOEXCEPT override {176 if (__ti == typeid(_Fp))177 return std::addressof(__func_);178 return nullptr;179 }180 _LIBCPP_HIDE_FROM_ABI_VIRTUAL const std::type_info& target_type() const _NOEXCEPT override { return typeid(_Fp); }181# endif // _LIBCPP_HAS_RTTI182};183 184// __value_func creates a value-type from a __func.185 186template <class _Fp>187class __value_func;188 189template <class _Rp, class... _ArgTypes>190class __value_func<_Rp(_ArgTypes...)> {191 _LIBCPP_SUPPRESS_DEPRECATED_PUSH192 typename aligned_storage<3 * sizeof(void*)>::type __buf_;193 _LIBCPP_SUPPRESS_DEPRECATED_POP194 195 typedef __base<_Rp(_ArgTypes...)> __func;196 __func* __f_;197 198 _LIBCPP_HIDE_FROM_ABI _LIBCPP_NO_CFI static __func* __as_base(void* __p) { return reinterpret_cast<__func*>(__p); }199 200public:201 _LIBCPP_HIDE_FROM_ABI __value_func() _NOEXCEPT : __f_(nullptr) {}202 203 template <class _Fp, __enable_if_t<!is_same<__decay_t<_Fp>, __value_func>::value, int> = 0>204 _LIBCPP_HIDE_FROM_ABI explicit __value_func(_Fp&& __f) : __f_(nullptr) {205 typedef __function::__func<_Fp, _Rp(_ArgTypes...)> _Fun;206 207 if (__function::__is_null(__f))208 return;209 210 if (sizeof(_Fun) <= sizeof(__buf_) && is_nothrow_copy_constructible<_Fp>::value) {211 __f_ = ::new (std::addressof(__buf_)) _Fun(std::move(__f));212 } else {213 __f_ = new _Fun(std::move(__f));214 }215 }216 217 _LIBCPP_HIDE_FROM_ABI __value_func(const __value_func& __f) {218 if (__f.__f_ == nullptr)219 __f_ = nullptr;220 else if ((void*)__f.__f_ == &__f.__buf_) {221 __f_ = __as_base(&__buf_);222 __f.__f_->__clone(__f_);223 } else224 __f_ = __f.__f_->__clone();225 }226 227 _LIBCPP_HIDE_FROM_ABI __value_func(__value_func&& __f) _NOEXCEPT {228 if (__f.__f_ == nullptr)229 __f_ = nullptr;230 else if ((void*)__f.__f_ == &__f.__buf_) {231 __f_ = __as_base(&__buf_);232 __f.__f_->__clone(__f_);233 } else {234 __f_ = __f.__f_;235 __f.__f_ = nullptr;236 }237 }238 239 _LIBCPP_HIDE_FROM_ABI ~__value_func() {240 if ((void*)__f_ == &__buf_)241 __f_->destroy();242 else if (__f_)243 __f_->destroy_deallocate();244 }245 246 _LIBCPP_HIDE_FROM_ABI __value_func& operator=(__value_func&& __f) {247 *this = nullptr;248 if (__f.__f_ == nullptr)249 __f_ = nullptr;250 else if ((void*)__f.__f_ == &__f.__buf_) {251 __f_ = __as_base(&__buf_);252 __f.__f_->__clone(__f_);253 } else {254 __f_ = __f.__f_;255 __f.__f_ = nullptr;256 }257 return *this;258 }259 260 _LIBCPP_HIDE_FROM_ABI __value_func& operator=(nullptr_t) {261 __func* __f = __f_;262 __f_ = nullptr;263 if ((void*)__f == &__buf_)264 __f->destroy();265 else if (__f)266 __f->destroy_deallocate();267 return *this;268 }269 270 _LIBCPP_HIDE_FROM_ABI _Rp operator()(_ArgTypes&&... __args) const {271 if (__f_ == nullptr)272 std::__throw_bad_function_call();273 return (*__f_)(std::forward<_ArgTypes>(__args)...);274 }275 276 _LIBCPP_HIDE_FROM_ABI void swap(__value_func& __f) _NOEXCEPT {277 if (std::addressof(__f) == this)278 return;279 if ((void*)__f_ == &__buf_ && (void*)__f.__f_ == &__f.__buf_) {280 _LIBCPP_SUPPRESS_DEPRECATED_PUSH281 typename aligned_storage<sizeof(__buf_)>::type __tempbuf;282 _LIBCPP_SUPPRESS_DEPRECATED_POP283 __func* __t = __as_base(&__tempbuf);284 __f_->__clone(__t);285 __f_->destroy();286 __f_ = nullptr;287 __f.__f_->__clone(__as_base(&__buf_));288 __f.__f_->destroy();289 __f.__f_ = nullptr;290 __f_ = __as_base(&__buf_);291 __t->__clone(__as_base(&__f.__buf_));292 __t->destroy();293 __f.__f_ = __as_base(&__f.__buf_);294 } else if ((void*)__f_ == &__buf_) {295 __f_->__clone(__as_base(&__f.__buf_));296 __f_->destroy();297 __f_ = __f.__f_;298 __f.__f_ = __as_base(&__f.__buf_);299 } else if ((void*)__f.__f_ == &__f.__buf_) {300 __f.__f_->__clone(__as_base(&__buf_));301 __f.__f_->destroy();302 __f.__f_ = __f_;303 __f_ = __as_base(&__buf_);304 } else305 std::swap(__f_, __f.__f_);306 }307 308 _LIBCPP_HIDE_FROM_ABI explicit operator bool() const _NOEXCEPT { return __f_ != nullptr; }309 310# if _LIBCPP_HAS_RTTI311 _LIBCPP_HIDE_FROM_ABI const std::type_info& target_type() const _NOEXCEPT {312 if (__f_ == nullptr)313 return typeid(void);314 return __f_->target_type();315 }316 317 template <typename _Tp>318 _LIBCPP_HIDE_FROM_ABI const _Tp* target() const _NOEXCEPT {319 if (__f_ == nullptr)320 return nullptr;321 return (const _Tp*)__f_->target(typeid(_Tp));322 }323# endif // _LIBCPP_HAS_RTTI324};325 326// Storage for a functor object, to be used with __policy to manage copy and327// destruction.328union __policy_storage {329 mutable char __small[sizeof(void*) * 2];330 void* __large;331};332 333// True if _Fun can safely be held in __policy_storage.__small.334template <typename _Fun>335struct __use_small_storage336 : public integral_constant<337 bool,338 sizeof(_Fun) <= sizeof(__policy_storage)&& _LIBCPP_ALIGNOF(_Fun) <= _LIBCPP_ALIGNOF(__policy_storage) &&339 is_trivially_copy_constructible<_Fun>::value && is_trivially_destructible<_Fun>::value> {};340 341// Policy contains information about how to copy, destroy, and move the342// underlying functor. You can think of it as a vtable of sorts.343struct __policy {344 // Used to copy or destroy __large values. null for trivial objects.345 void* (*const __clone)(const void*);346 void (*const __destroy)(void*);347 348 // True if this is the null policy (no value).349 const bool __is_null;350 351 // The target type. May be null if RTTI is disabled.352 const std::type_info* const __type_info;353 354 // Returns a pointer to a static policy object suitable for the functor355 // type.356 template <typename _Fun>357 _LIBCPP_HIDE_FROM_ABI static const __policy* __create() {358 if constexpr (__use_small_storage<_Fun>::value) {359 static constexpr __policy __policy = {360 nullptr,361 nullptr,362 false,363# if _LIBCPP_HAS_RTTI364 &typeid(_Fun)365# else366 nullptr367# endif368 };369 return &__policy;370 } else {371 static constexpr __policy __policy = {372 std::addressof(__large_clone<_Fun>),373 std::addressof(__large_destroy<_Fun>),374 false,375# if _LIBCPP_HAS_RTTI376 &typeid(_Fun)377# else378 nullptr379# endif380 };381 return &__policy;382 }383 }384 385 _LIBCPP_HIDE_FROM_ABI static const __policy* __create_empty() {386 static constexpr __policy __policy = {387 nullptr,388 nullptr,389 true,390# if _LIBCPP_HAS_RTTI391 &typeid(void)392# else393 nullptr394# endif395 };396 return &__policy;397 }398 399private:400 template <typename _Fun>401 _LIBCPP_HIDE_FROM_ABI static void* __large_clone(const void* __s) {402 const _Fun* __f = static_cast<const _Fun*>(__s);403 return new _Fun(*__f);404 }405 406 template <typename _Fun>407 _LIBCPP_HIDE_FROM_ABI static void __large_destroy(void* __s) {408 delete static_cast<_Fun*>(__s);409 }410};411 412// Used to choose between perfect forwarding or pass-by-value. Pass-by-value is413// faster for types that can be passed in registers.414template <typename _Tp>415using __fast_forward _LIBCPP_NODEBUG = __conditional_t<is_scalar<_Tp>::value, _Tp, _Tp&&>;416 417// __policy_func uses a __policy to create a type-erased, copyable functor.418 419template <class _Fp>420class __policy_func;421 422template <class _Rp, class... _ArgTypes>423class __policy_func<_Rp(_ArgTypes...)> {424 // Inline storage for small objects.425 __policy_storage __buf_;426 427 using _ErasedFunc _LIBCPP_NODEBUG = _Rp(const __policy_storage*, __fast_forward<_ArgTypes>...);428 429 _ErasedFunc* __func_;430 431 // The policy that describes how to move / copy / destroy __buf_. Never432 // null, even if the function is empty.433 const __policy* __policy_;434 435 _LIBCPP_HIDE_FROM_ABI static _Rp __empty_func(const __policy_storage*, __fast_forward<_ArgTypes>...) {436 std::__throw_bad_function_call();437 }438 439 template <class _Fun>440 _LIBCPP_HIDE_FROM_ABI static _Rp __call_func(const __policy_storage* __buf, __fast_forward<_ArgTypes>... __args) {441 _Fun* __func = reinterpret_cast<_Fun*>(__use_small_storage<_Fun>::value ? &__buf->__small : __buf->__large);442 443 return std::__invoke_r<_Rp>(*__func, std::forward<_ArgTypes>(__args)...);444 }445 446public:447 _LIBCPP_HIDE_FROM_ABI __policy_func() : __func_(__empty_func), __policy_(__policy::__create_empty()) {}448 449 template <class _Fp, __enable_if_t<!is_same<__decay_t<_Fp>, __policy_func>::value, int> = 0>450 _LIBCPP_HIDE_FROM_ABI explicit __policy_func(_Fp&& __f) : __policy_(__policy::__create_empty()) {451 if (__function::__is_null(__f))452 return;453 454 __func_ = __call_func<_Fp>;455 __policy_ = __policy::__create<_Fp>();456 if (__use_small_storage<_Fp>()) {457 ::new ((void*)&__buf_.__small) _Fp(std::move(__f));458 } else {459 __buf_.__large = ::new _Fp(std::move(__f));460 }461 }462 463 _LIBCPP_HIDE_FROM_ABI __policy_func(const __policy_func& __f)464 : __buf_(__f.__buf_), __func_(__f.__func_), __policy_(__f.__policy_) {465 if (__policy_->__clone)466 __buf_.__large = __policy_->__clone(__f.__buf_.__large);467 }468 469 _LIBCPP_HIDE_FROM_ABI __policy_func(__policy_func&& __f)470 : __buf_(__f.__buf_), __func_(__f.__func_), __policy_(__f.__policy_) {471 if (__policy_->__destroy) {472 __f.__policy_ = __policy::__create_empty();473 __f.__func_ = {};474 }475 }476 477 _LIBCPP_HIDE_FROM_ABI ~__policy_func() {478 if (__policy_->__destroy)479 __policy_->__destroy(__buf_.__large);480 }481 482 _LIBCPP_HIDE_FROM_ABI __policy_func& operator=(__policy_func&& __f) {483 *this = nullptr;484 __buf_ = __f.__buf_;485 __func_ = __f.__func_;486 __policy_ = __f.__policy_;487 __f.__policy_ = __policy::__create_empty();488 __f.__func_ = {};489 return *this;490 }491 492 _LIBCPP_HIDE_FROM_ABI __policy_func& operator=(nullptr_t) {493 const __policy* __p = __policy_;494 __policy_ = __policy::__create_empty();495 __func_ = {};496 if (__p->__destroy)497 __p->__destroy(__buf_.__large);498 return *this;499 }500 501 _LIBCPP_HIDE_FROM_ABI _Rp operator()(_ArgTypes&&... __args) const {502 return __func_(std::addressof(__buf_), std::forward<_ArgTypes>(__args)...);503 }504 505 _LIBCPP_HIDE_FROM_ABI void swap(__policy_func& __f) {506 std::swap(__func_, __f.__func_);507 std::swap(__policy_, __f.__policy_);508 std::swap(__buf_, __f.__buf_);509 }510 511 _LIBCPP_HIDE_FROM_ABI explicit operator bool() const _NOEXCEPT { return !__policy_->__is_null; }512 513# if _LIBCPP_HAS_RTTI514 _LIBCPP_HIDE_FROM_ABI const std::type_info& target_type() const _NOEXCEPT { return *__policy_->__type_info; }515 516 template <typename _Tp>517 _LIBCPP_HIDE_FROM_ABI const _Tp* target() const _NOEXCEPT {518 if (__policy_->__is_null || typeid(_Tp) != *__policy_->__type_info)519 return nullptr;520 if (__policy_->__clone) // Out of line storage.521 return reinterpret_cast<const _Tp*>(__buf_.__large);522 else523 return reinterpret_cast<const _Tp*>(&__buf_.__small);524 }525# endif // _LIBCPP_HAS_RTTI526};527 528# if _LIBCPP_HAS_BLOCKS_RUNTIME529 530extern "C" void* _Block_copy(const void*);531extern "C" void _Block_release(const void*);532 533template <class _Rp1, class... _ArgTypes1, class _Rp, class... _ArgTypes>534class __func<_Rp1 (^)(_ArgTypes1...), _Rp(_ArgTypes...)> : public __base<_Rp(_ArgTypes...)> {535 typedef _Rp1 (^__block_type)(_ArgTypes1...);536 __block_type __f_;537 538public:539 _LIBCPP_HIDE_FROM_ABI explicit __func(__block_type const& __f)540# if __has_feature(objc_arc)541 : __f_(__f)542# else543 : __f_(reinterpret_cast<__block_type>(__f ? _Block_copy(__f) : nullptr))544# endif545 {546 }547 548 // [TODO] add && to save on a retain549 550 _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual __base<_Rp(_ArgTypes...)>* __clone() const {551 _LIBCPP_ASSERT_INTERNAL(552 false,553 "Block pointers are just pointers, so they should always fit into "554 "std::function's small buffer optimization. This function should "555 "never be invoked.");556 return nullptr;557 }558 559 _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void __clone(__base<_Rp(_ArgTypes...)>* __p) const {560 ::new ((void*)__p) __func(__f_);561 }562 563 _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void destroy() _NOEXCEPT {564# if !__has_feature(objc_arc)565 if (__f_)566 _Block_release(__f_);567# endif568 __f_ = 0;569 }570 571 _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void destroy_deallocate() _NOEXCEPT {572 _LIBCPP_ASSERT_INTERNAL(573 false,574 "Block pointers are just pointers, so they should always fit into "575 "std::function's small buffer optimization. This function should "576 "never be invoked.");577 }578 579 _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual _Rp operator()(_ArgTypes&&... __arg) {580 return std::__invoke(__f_, std::forward<_ArgTypes>(__arg)...);581 }582 583# if _LIBCPP_HAS_RTTI584 _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual const void* target(type_info const& __ti) const _NOEXCEPT {585 if (__ti == typeid(__func::__block_type))586 return &__f_;587 return (const void*)nullptr;588 }589 590 _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual const std::type_info& target_type() const _NOEXCEPT {591 return typeid(__func::__block_type);592 }593# endif // _LIBCPP_HAS_RTTI594};595 596# endif // _LIBCPP_HAS_BLOCKS_RUNTIME597 598} // namespace __function599 600template <class _Rp, class... _ArgTypes>601class function<_Rp(_ArgTypes...)>602 : public __function::__maybe_derive_from_unary_function<_Rp(_ArgTypes...)>,603 public __function::__maybe_derive_from_binary_function<_Rp(_ArgTypes...)> {604# ifndef _LIBCPP_ABI_OPTIMIZED_FUNCTION605 typedef __function::__value_func<_Rp(_ArgTypes...)> __func;606# else607 typedef __function::__policy_func<_Rp(_ArgTypes...)> __func;608# endif609 610 __func __f_;611 612 template <class _Fp>613 using _EnableIfLValueCallable _LIBCPP_NODEBUG = __enable_if_t<614 _And<_IsNotSame<__remove_cvref_t<_Fp>, function>, __is_invocable_r<_Rp, _Fp&, _ArgTypes...>>::value>;615 616public:617 typedef _Rp result_type;618 619 // construct/copy/destroy:620 _LIBCPP_HIDE_FROM_ABI function() _NOEXCEPT {}621 _LIBCPP_HIDE_FROM_ABI function(nullptr_t) _NOEXCEPT {}622 _LIBCPP_HIDE_FROM_ABI function(const function&);623 _LIBCPP_HIDE_FROM_ABI function(function&&) _NOEXCEPT;624 template <class _Fp, class = _EnableIfLValueCallable<_Fp>>625 _LIBCPP_HIDE_FROM_ABI function(_Fp);626 627# if _LIBCPP_STD_VER <= 14628 template <class _Alloc>629 _LIBCPP_HIDE_FROM_ABI function(allocator_arg_t, const _Alloc&) _NOEXCEPT {}630 template <class _Alloc>631 _LIBCPP_HIDE_FROM_ABI function(allocator_arg_t, const _Alloc&, nullptr_t) _NOEXCEPT {}632 template <class _Alloc>633 _LIBCPP_HIDE_FROM_ABI function(allocator_arg_t, const _Alloc&, const function&);634 template <class _Alloc>635 _LIBCPP_HIDE_FROM_ABI function(allocator_arg_t, const _Alloc&, function&&);636 template <class _Fp, class _Alloc, class = _EnableIfLValueCallable<_Fp>>637 _LIBCPP_HIDE_FROM_ABI function(allocator_arg_t, const _Alloc& __a, _Fp __f);638# endif639 640 _LIBCPP_HIDE_FROM_ABI function& operator=(const function&);641 _LIBCPP_HIDE_FROM_ABI function& operator=(function&&) _NOEXCEPT;642 _LIBCPP_HIDE_FROM_ABI function& operator=(nullptr_t) _NOEXCEPT;643 template <class _Fp, class = _EnableIfLValueCallable<__decay_t<_Fp>>>644 _LIBCPP_HIDE_FROM_ABI function& operator=(_Fp&&);645 646 _LIBCPP_HIDE_FROM_ABI ~function();647 648 // function modifiers:649 _LIBCPP_HIDE_FROM_ABI void swap(function&) _NOEXCEPT;650 651# if _LIBCPP_STD_VER <= 14652 template <class _Fp, class _Alloc>653 _LIBCPP_HIDE_FROM_ABI void assign(_Fp&& __f, const _Alloc& __a) {654 function(allocator_arg, __a, std::forward<_Fp>(__f)).swap(*this);655 }656# endif657 658 // function capacity:659 _LIBCPP_HIDE_FROM_ABI explicit operator bool() const _NOEXCEPT { return static_cast<bool>(__f_); }660 661 // deleted overloads close possible hole in the type system662 template <class _R2, class... _ArgTypes2>663 bool operator==(const function<_R2(_ArgTypes2...)>&) const = delete;664# if _LIBCPP_STD_VER <= 17665 template <class _R2, class... _ArgTypes2>666 bool operator!=(const function<_R2(_ArgTypes2...)>&) const = delete;667# endif668 669public:670 // function invocation:671 _LIBCPP_HIDE_FROM_ABI _Rp operator()(_ArgTypes...) const;672 673# if _LIBCPP_HAS_RTTI674 // function target access:675 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const std::type_info& target_type() const _NOEXCEPT;676 template <typename _Tp>677 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _Tp* target() _NOEXCEPT;678 template <typename _Tp>679 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const _Tp* target() const _NOEXCEPT;680# endif // _LIBCPP_HAS_RTTI681};682 683# if _LIBCPP_STD_VER >= 17684template <class _Rp, class... _Ap>685function(_Rp (*)(_Ap...)) -> function<_Rp(_Ap...)>;686 687template <class _Fp, class _Stripped = typename __strip_signature<decltype(&_Fp::operator())>::type>688function(_Fp) -> function<_Stripped>;689# endif // _LIBCPP_STD_VER >= 17690 691template <class _Rp, class... _ArgTypes>692function<_Rp(_ArgTypes...)>::function(const function& __f) : __f_(__f.__f_) {}693 694# if _LIBCPP_STD_VER <= 14695template <class _Rp, class... _ArgTypes>696template <class _Alloc>697function<_Rp(_ArgTypes...)>::function(allocator_arg_t, const _Alloc&, const function& __f) : __f_(__f.__f_) {}698# endif699 700template <class _Rp, class... _ArgTypes>701function<_Rp(_ArgTypes...)>::function(function&& __f) _NOEXCEPT : __f_(std::move(__f.__f_)) {}702 703# if _LIBCPP_STD_VER <= 14704template <class _Rp, class... _ArgTypes>705template <class _Alloc>706function<_Rp(_ArgTypes...)>::function(allocator_arg_t, const _Alloc&, function&& __f) : __f_(std::move(__f.__f_)) {}707# endif708 709template <class _Rp, class... _ArgTypes>710template <class _Fp, class>711function<_Rp(_ArgTypes...)>::function(_Fp __f) : __f_(std::move(__f)) {}712 713# if _LIBCPP_STD_VER <= 14714template <class _Rp, class... _ArgTypes>715template <class _Fp, class _Alloc, class>716function<_Rp(_ArgTypes...)>::function(allocator_arg_t, const _Alloc&, _Fp __f) : __f_(std::move(__f)) {}717# endif718 719template <class _Rp, class... _ArgTypes>720function<_Rp(_ArgTypes...)>& function<_Rp(_ArgTypes...)>::operator=(const function& __f) {721 function(__f).swap(*this);722 return *this;723}724 725template <class _Rp, class... _ArgTypes>726function<_Rp(_ArgTypes...)>& function<_Rp(_ArgTypes...)>::operator=(function&& __f) _NOEXCEPT {727 __f_ = std::move(__f.__f_);728 return *this;729}730 731template <class _Rp, class... _ArgTypes>732function<_Rp(_ArgTypes...)>& function<_Rp(_ArgTypes...)>::operator=(nullptr_t) _NOEXCEPT {733 __f_ = nullptr;734 return *this;735}736 737template <class _Rp, class... _ArgTypes>738template <class _Fp, class>739function<_Rp(_ArgTypes...)>& function<_Rp(_ArgTypes...)>::operator=(_Fp&& __f) {740 function(std::forward<_Fp>(__f)).swap(*this);741 return *this;742}743 744template <class _Rp, class... _ArgTypes>745function<_Rp(_ArgTypes...)>::~function() {}746 747template <class _Rp, class... _ArgTypes>748void function<_Rp(_ArgTypes...)>::swap(function& __f) _NOEXCEPT {749 __f_.swap(__f.__f_);750}751 752template <class _Rp, class... _ArgTypes>753_Rp function<_Rp(_ArgTypes...)>::operator()(_ArgTypes... __arg) const {754 return __f_(std::forward<_ArgTypes>(__arg)...);755}756 757# if _LIBCPP_HAS_RTTI758 759template <class _Rp, class... _ArgTypes>760const std::type_info& function<_Rp(_ArgTypes...)>::target_type() const _NOEXCEPT {761 return __f_.target_type();762}763 764template <class _Rp, class... _ArgTypes>765template <typename _Tp>766_Tp* function<_Rp(_ArgTypes...)>::target() _NOEXCEPT {767 return (_Tp*)(__f_.template target<_Tp>());768}769 770template <class _Rp, class... _ArgTypes>771template <typename _Tp>772const _Tp* function<_Rp(_ArgTypes...)>::target() const _NOEXCEPT {773 return __f_.template target<_Tp>();774}775 776# endif // _LIBCPP_HAS_RTTI777 778template <class _Rp, class... _ArgTypes>779inline _LIBCPP_HIDE_FROM_ABI bool operator==(const function<_Rp(_ArgTypes...)>& __f, nullptr_t) _NOEXCEPT {780 return !__f;781}782 783# if _LIBCPP_STD_VER <= 17784 785template <class _Rp, class... _ArgTypes>786inline _LIBCPP_HIDE_FROM_ABI bool operator==(nullptr_t, const function<_Rp(_ArgTypes...)>& __f) _NOEXCEPT {787 return !__f;788}789 790template <class _Rp, class... _ArgTypes>791inline _LIBCPP_HIDE_FROM_ABI bool operator!=(const function<_Rp(_ArgTypes...)>& __f, nullptr_t) _NOEXCEPT {792 return (bool)__f;793}794 795template <class _Rp, class... _ArgTypes>796inline _LIBCPP_HIDE_FROM_ABI bool operator!=(nullptr_t, const function<_Rp(_ArgTypes...)>& __f) _NOEXCEPT {797 return (bool)__f;798}799 800# endif // _LIBCPP_STD_VER <= 17801 802template <class _Rp, class... _ArgTypes>803inline _LIBCPP_HIDE_FROM_ABI void swap(function<_Rp(_ArgTypes...)>& __x, function<_Rp(_ArgTypes...)>& __y) _NOEXCEPT {804 return __x.swap(__y);805}806 807_LIBCPP_END_NAMESPACE_STD808 809#endif // _LIBCPP_CXX03_LANG810 811_LIBCPP_POP_MACROS812 813#endif // _LIBCPP___FUNCTIONAL_FUNCTION_H814