brintos

brintos / llvm-project-archived public Read only

0
0
Text · 25.4 KiB · 121417f Raw
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