1fe6060f1SDimitry Andric // -*- C++ -*- 2fe6060f1SDimitry Andric //===----------------------------------------------------------------------===// 3fe6060f1SDimitry Andric // 4fe6060f1SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 5fe6060f1SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 6fe6060f1SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 7fe6060f1SDimitry Andric // 8fe6060f1SDimitry Andric //===----------------------------------------------------------------------===// 9fe6060f1SDimitry Andric 10fe6060f1SDimitry Andric #ifndef _LIBCPP___FUNCTIONAL_FUNCTION_H 11fe6060f1SDimitry Andric #define _LIBCPP___FUNCTIONAL_FUNCTION_H 12fe6060f1SDimitry Andric 1381ad6265SDimitry Andric #include <__assert> 14fe6060f1SDimitry Andric #include <__config> 1506c3fb27SDimitry Andric #include <__exception/exception.h> 16fe6060f1SDimitry Andric #include <__functional/binary_function.h> 17fe6060f1SDimitry Andric #include <__functional/invoke.h> 18fe6060f1SDimitry Andric #include <__functional/unary_function.h> 19fe6060f1SDimitry Andric #include <__iterator/iterator_traits.h> 2004eeddc0SDimitry Andric #include <__memory/addressof.h> 21bdd1243dSDimitry Andric #include <__memory/allocator.h> 22bdd1243dSDimitry Andric #include <__memory/allocator_destructor.h> 23fe6060f1SDimitry Andric #include <__memory/allocator_traits.h> 24bdd1243dSDimitry Andric #include <__memory/builtin_new_allocator.h> 25fe6060f1SDimitry Andric #include <__memory/compressed_pair.h> 26bdd1243dSDimitry Andric #include <__memory/unique_ptr.h> 2706c3fb27SDimitry Andric #include <__type_traits/aligned_storage.h> 2806c3fb27SDimitry Andric #include <__type_traits/decay.h> 2906c3fb27SDimitry Andric #include <__type_traits/is_core_convertible.h> 3006c3fb27SDimitry Andric #include <__type_traits/is_scalar.h> 3106c3fb27SDimitry Andric #include <__type_traits/is_trivially_copy_constructible.h> 3206c3fb27SDimitry Andric #include <__type_traits/is_trivially_destructible.h> 3306c3fb27SDimitry Andric #include <__type_traits/is_void.h> 34bdd1243dSDimitry Andric #include <__type_traits/strip_signature.h> 3581ad6265SDimitry Andric #include <__utility/forward.h> 3681ad6265SDimitry Andric #include <__utility/move.h> 37bdd1243dSDimitry Andric #include <__utility/piecewise_construct.h> 3881ad6265SDimitry Andric #include <__utility/swap.h> 3906c3fb27SDimitry Andric #include <__verbose_abort> 40bdd1243dSDimitry Andric #include <new> 41bdd1243dSDimitry Andric #include <tuple> 42bdd1243dSDimitry Andric #include <typeinfo> 43fe6060f1SDimitry Andric 44fe6060f1SDimitry Andric #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 45fe6060f1SDimitry Andric # pragma GCC system_header 46fe6060f1SDimitry Andric #endif 47fe6060f1SDimitry Andric 48bdd1243dSDimitry Andric #ifndef _LIBCPP_CXX03_LANG 49bdd1243dSDimitry Andric 50fe6060f1SDimitry Andric _LIBCPP_BEGIN_NAMESPACE_STD 51fe6060f1SDimitry Andric 52fe6060f1SDimitry Andric // bad_function_call 53fe6060f1SDimitry Andric 5481ad6265SDimitry Andric _LIBCPP_DIAGNOSTIC_PUSH 5581ad6265SDimitry Andric _LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wweak-vtables") 56*cb14a3feSDimitry Andric class _LIBCPP_EXPORTED_FROM_ABI bad_function_call : public exception { 57fe6060f1SDimitry Andric public: 585f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI bad_function_call() _NOEXCEPT = default; 595f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI bad_function_call(const bad_function_call&) _NOEXCEPT = default; 605f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI bad_function_call& operator=(const bad_function_call&) _NOEXCEPT = default; 61349cc55cSDimitry Andric // Note that when a key function is not used, every translation unit that uses 62349cc55cSDimitry Andric // bad_function_call will end up containing a weak definition of the vtable and 63349cc55cSDimitry Andric // typeinfo. 64349cc55cSDimitry Andric # ifdef _LIBCPP_ABI_BAD_FUNCTION_CALL_KEY_FUNCTION 65bdd1243dSDimitry Andric ~bad_function_call() _NOEXCEPT override; 66349cc55cSDimitry Andric # else 6706c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI_VIRTUAL ~bad_function_call() _NOEXCEPT override {} 68349cc55cSDimitry Andric # endif 69fe6060f1SDimitry Andric 70349cc55cSDimitry Andric # ifdef _LIBCPP_ABI_BAD_FUNCTION_CALL_GOOD_WHAT_MESSAGE 71bdd1243dSDimitry Andric const char* what() const _NOEXCEPT override; 72fe6060f1SDimitry Andric # endif 73fe6060f1SDimitry Andric }; 7481ad6265SDimitry Andric _LIBCPP_DIAGNOSTIC_POP 75fe6060f1SDimitry Andric 76*cb14a3feSDimitry Andric _LIBCPP_NORETURN inline _LIBCPP_HIDE_FROM_ABI void __throw_bad_function_call() { 7706c3fb27SDimitry Andric # ifndef _LIBCPP_HAS_NO_EXCEPTIONS 78fe6060f1SDimitry Andric throw bad_function_call(); 79fe6060f1SDimitry Andric # else 8006c3fb27SDimitry Andric _LIBCPP_VERBOSE_ABORT("bad_function_call was thrown in -fno-exceptions mode"); 81fe6060f1SDimitry Andric # endif 82fe6060f1SDimitry Andric } 83fe6060f1SDimitry Andric 84*cb14a3feSDimitry Andric template <class _Fp> 85*cb14a3feSDimitry Andric class _LIBCPP_TEMPLATE_VIS function; // undefined 86fe6060f1SDimitry Andric 87*cb14a3feSDimitry Andric namespace __function { 88fe6060f1SDimitry Andric 89fe6060f1SDimitry Andric template <class _Rp> 90*cb14a3feSDimitry Andric struct __maybe_derive_from_unary_function {}; 91fe6060f1SDimitry Andric 92fe6060f1SDimitry Andric template <class _Rp, class _A1> 93*cb14a3feSDimitry Andric struct __maybe_derive_from_unary_function<_Rp(_A1)> : public __unary_function<_A1, _Rp> {}; 94fe6060f1SDimitry Andric 95fe6060f1SDimitry Andric template <class _Rp> 96*cb14a3feSDimitry Andric struct __maybe_derive_from_binary_function {}; 97fe6060f1SDimitry Andric 98fe6060f1SDimitry Andric template <class _Rp, class _A1, class _A2> 99*cb14a3feSDimitry Andric struct __maybe_derive_from_binary_function<_Rp(_A1, _A2)> : public __binary_function<_A1, _A2, _Rp> {}; 100fe6060f1SDimitry Andric 101fe6060f1SDimitry Andric template <class _Fp> 102*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI bool __not_null(_Fp const&) { 103*cb14a3feSDimitry Andric return true; 104*cb14a3feSDimitry Andric } 105fe6060f1SDimitry Andric 106fe6060f1SDimitry Andric template <class _Fp> 107*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI bool __not_null(_Fp* __ptr) { 108*cb14a3feSDimitry Andric return __ptr; 109*cb14a3feSDimitry Andric } 110fe6060f1SDimitry Andric 111fe6060f1SDimitry Andric template <class _Ret, class _Class> 112*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI bool __not_null(_Ret _Class::*__ptr) { 113*cb14a3feSDimitry Andric return __ptr; 114*cb14a3feSDimitry Andric } 115fe6060f1SDimitry Andric 116fe6060f1SDimitry Andric template <class _Fp> 117*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI bool __not_null(function<_Fp> const& __f) { 118*cb14a3feSDimitry Andric return !!__f; 119*cb14a3feSDimitry Andric } 120fe6060f1SDimitry Andric 121fe6060f1SDimitry Andric # ifdef _LIBCPP_HAS_EXTENSION_BLOCKS 122fe6060f1SDimitry Andric template <class _Rp, class... _Args> 123*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI bool __not_null(_Rp (^__p)(_Args...)) { 124*cb14a3feSDimitry Andric return __p; 125*cb14a3feSDimitry Andric } 126fe6060f1SDimitry Andric # endif 127fe6060f1SDimitry Andric 128fe6060f1SDimitry Andric } // namespace __function 129fe6060f1SDimitry Andric 130fe6060f1SDimitry Andric namespace __function { 131fe6060f1SDimitry Andric 132fe6060f1SDimitry Andric // __alloc_func holds a functor and an allocator. 133fe6060f1SDimitry Andric 134*cb14a3feSDimitry Andric template <class _Fp, class _Ap, class _FB> 135*cb14a3feSDimitry Andric class __alloc_func; 136fe6060f1SDimitry Andric template <class _Fp, class _FB> 137fe6060f1SDimitry Andric class __default_alloc_func; 138fe6060f1SDimitry Andric 139fe6060f1SDimitry Andric template <class _Fp, class _Ap, class _Rp, class... _ArgTypes> 140*cb14a3feSDimitry Andric class __alloc_func<_Fp, _Ap, _Rp(_ArgTypes...)> { 141fe6060f1SDimitry Andric __compressed_pair<_Fp, _Ap> __f_; 142fe6060f1SDimitry Andric 143fe6060f1SDimitry Andric public: 144349cc55cSDimitry Andric typedef _LIBCPP_NODEBUG _Fp _Target; 145349cc55cSDimitry Andric typedef _LIBCPP_NODEBUG _Ap _Alloc; 146fe6060f1SDimitry Andric 147*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI const _Target& __target() const { return __f_.first(); } 148fe6060f1SDimitry Andric 149fe6060f1SDimitry Andric // WIN32 APIs may define __allocator, so use __get_allocator instead. 150*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI const _Alloc& __get_allocator() const { return __f_.second(); } 151fe6060f1SDimitry Andric 152*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI explicit __alloc_func(_Target&& __f) 153*cb14a3feSDimitry Andric : __f_(piecewise_construct, std::forward_as_tuple(std::move(__f)), std::forward_as_tuple()) {} 154fe6060f1SDimitry Andric 155*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI explicit __alloc_func(const _Target& __f, const _Alloc& __a) 156*cb14a3feSDimitry Andric : __f_(piecewise_construct, std::forward_as_tuple(__f), std::forward_as_tuple(__a)) {} 157fe6060f1SDimitry Andric 158*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI explicit __alloc_func(const _Target& __f, _Alloc&& __a) 159*cb14a3feSDimitry Andric : __f_(piecewise_construct, std::forward_as_tuple(__f), std::forward_as_tuple(std::move(__a))) {} 160fe6060f1SDimitry Andric 161*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI explicit __alloc_func(_Target&& __f, _Alloc&& __a) 162*cb14a3feSDimitry Andric : __f_(piecewise_construct, std::forward_as_tuple(std::move(__f)), std::forward_as_tuple(std::move(__a))) {} 163fe6060f1SDimitry Andric 164*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _Rp operator()(_ArgTypes&&... __arg) { 165fe6060f1SDimitry Andric typedef __invoke_void_return_wrapper<_Rp> _Invoker; 166*cb14a3feSDimitry Andric return _Invoker::__call(__f_.first(), std::forward<_ArgTypes>(__arg)...); 167fe6060f1SDimitry Andric } 168fe6060f1SDimitry Andric 169*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI __alloc_func* __clone() const { 170fe6060f1SDimitry Andric typedef allocator_traits<_Alloc> __alloc_traits; 171bdd1243dSDimitry Andric typedef __rebind_alloc<__alloc_traits, __alloc_func> _AA; 172fe6060f1SDimitry Andric _AA __a(__f_.second()); 173fe6060f1SDimitry Andric typedef __allocator_destructor<_AA> _Dp; 174fe6060f1SDimitry Andric unique_ptr<__alloc_func, _Dp> __hold(__a.allocate(1), _Dp(__a, 1)); 175fe6060f1SDimitry Andric ::new ((void*)__hold.get()) __alloc_func(__f_.first(), _Alloc(__a)); 176fe6060f1SDimitry Andric return __hold.release(); 177fe6060f1SDimitry Andric } 178fe6060f1SDimitry Andric 179*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI void destroy() _NOEXCEPT { __f_.~__compressed_pair<_Target, _Alloc>(); } 180fe6060f1SDimitry Andric 18106c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI static void __destroy_and_delete(__alloc_func* __f) { 182fe6060f1SDimitry Andric typedef allocator_traits<_Alloc> __alloc_traits; 183bdd1243dSDimitry Andric typedef __rebind_alloc<__alloc_traits, __alloc_func> _FunAlloc; 184fe6060f1SDimitry Andric _FunAlloc __a(__f->__get_allocator()); 185fe6060f1SDimitry Andric __f->destroy(); 186fe6060f1SDimitry Andric __a.deallocate(__f, 1); 187fe6060f1SDimitry Andric } 188fe6060f1SDimitry Andric }; 189fe6060f1SDimitry Andric 190fe6060f1SDimitry Andric template <class _Fp, class _Rp, class... _ArgTypes> 191fe6060f1SDimitry Andric class __default_alloc_func<_Fp, _Rp(_ArgTypes...)> { 192fe6060f1SDimitry Andric _Fp __f_; 193fe6060f1SDimitry Andric 194fe6060f1SDimitry Andric public: 195349cc55cSDimitry Andric typedef _LIBCPP_NODEBUG _Fp _Target; 196fe6060f1SDimitry Andric 197*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI const _Target& __target() const { return __f_; } 198fe6060f1SDimitry Andric 199*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI explicit __default_alloc_func(_Target&& __f) : __f_(std::move(__f)) {} 200fe6060f1SDimitry Andric 201*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI explicit __default_alloc_func(const _Target& __f) : __f_(__f) {} 202fe6060f1SDimitry Andric 203*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _Rp operator()(_ArgTypes&&... __arg) { 204fe6060f1SDimitry Andric typedef __invoke_void_return_wrapper<_Rp> _Invoker; 2055f757f3fSDimitry Andric return _Invoker::__call(__f_, std::forward<_ArgTypes>(__arg)...); 206fe6060f1SDimitry Andric } 207fe6060f1SDimitry Andric 208*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI __default_alloc_func* __clone() const { 209*cb14a3feSDimitry Andric __builtin_new_allocator::__holder_t __hold = __builtin_new_allocator::__allocate_type<__default_alloc_func>(1); 210*cb14a3feSDimitry Andric __default_alloc_func* __res = ::new ((void*)__hold.get()) __default_alloc_func(__f_); 211fe6060f1SDimitry Andric (void)__hold.release(); 212fe6060f1SDimitry Andric return __res; 213fe6060f1SDimitry Andric } 214fe6060f1SDimitry Andric 215*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI void destroy() _NOEXCEPT { __f_.~_Target(); } 216fe6060f1SDimitry Andric 21706c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI static void __destroy_and_delete(__default_alloc_func* __f) { 218fe6060f1SDimitry Andric __f->destroy(); 219fe6060f1SDimitry Andric __builtin_new_allocator::__deallocate_type<__default_alloc_func>(__f, 1); 220fe6060f1SDimitry Andric } 221fe6060f1SDimitry Andric }; 222fe6060f1SDimitry Andric 223fe6060f1SDimitry Andric // __base provides an abstract interface for copyable functors. 224fe6060f1SDimitry Andric 225*cb14a3feSDimitry Andric template <class _Fp> 226*cb14a3feSDimitry Andric class _LIBCPP_TEMPLATE_VIS __base; 227fe6060f1SDimitry Andric 228fe6060f1SDimitry Andric template <class _Rp, class... _ArgTypes> 229*cb14a3feSDimitry Andric class __base<_Rp(_ArgTypes...)> { 230fe6060f1SDimitry Andric __base(const __base&); 231fe6060f1SDimitry Andric __base& operator=(const __base&); 232*cb14a3feSDimitry Andric 233fe6060f1SDimitry Andric public: 2345f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI __base() {} 235bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual ~__base() {} 236fe6060f1SDimitry Andric virtual __base* __clone() const = 0; 237fe6060f1SDimitry Andric virtual void __clone(__base*) const = 0; 238fe6060f1SDimitry Andric virtual void destroy() _NOEXCEPT = 0; 239fe6060f1SDimitry Andric virtual void destroy_deallocate() _NOEXCEPT = 0; 240fe6060f1SDimitry Andric virtual _Rp operator()(_ArgTypes&&...) = 0; 2411ac55f4cSDimitry Andric # ifndef _LIBCPP_HAS_NO_RTTI 242fe6060f1SDimitry Andric virtual const void* target(const type_info&) const _NOEXCEPT = 0; 243fe6060f1SDimitry Andric virtual const std::type_info& target_type() const _NOEXCEPT = 0; 2441ac55f4cSDimitry Andric # endif // _LIBCPP_HAS_NO_RTTI 245fe6060f1SDimitry Andric }; 246fe6060f1SDimitry Andric 247fe6060f1SDimitry Andric // __func implements __base for a given functor type. 248fe6060f1SDimitry Andric 249*cb14a3feSDimitry Andric template <class _FD, class _Alloc, class _FB> 250*cb14a3feSDimitry Andric class __func; 251fe6060f1SDimitry Andric 252fe6060f1SDimitry Andric template <class _Fp, class _Alloc, class _Rp, class... _ArgTypes> 253*cb14a3feSDimitry Andric class __func<_Fp, _Alloc, _Rp(_ArgTypes...)> : public __base<_Rp(_ArgTypes...)> { 254fe6060f1SDimitry Andric __alloc_func<_Fp, _Alloc, _Rp(_ArgTypes...)> __f_; 255*cb14a3feSDimitry Andric 256fe6060f1SDimitry Andric public: 257*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI explicit __func(_Fp&& __f) : __f_(std::move(__f)) {} 258fe6060f1SDimitry Andric 259*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI explicit __func(const _Fp& __f, const _Alloc& __a) : __f_(__f, __a) {} 260fe6060f1SDimitry Andric 261*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI explicit __func(const _Fp& __f, _Alloc&& __a) : __f_(__f, std::move(__a)) {} 262fe6060f1SDimitry Andric 263*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI explicit __func(_Fp&& __f, _Alloc&& __a) : __f_(std::move(__f), std::move(__a)) {} 264fe6060f1SDimitry Andric 26506c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual __base<_Rp(_ArgTypes...)>* __clone() const; 26606c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void __clone(__base<_Rp(_ArgTypes...)>*) const; 26706c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void destroy() _NOEXCEPT; 26806c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void destroy_deallocate() _NOEXCEPT; 26906c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual _Rp operator()(_ArgTypes&&... __arg); 2701ac55f4cSDimitry Andric # ifndef _LIBCPP_HAS_NO_RTTI 27106c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual const void* target(const type_info&) const _NOEXCEPT; 27206c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual const std::type_info& target_type() const _NOEXCEPT; 2731ac55f4cSDimitry Andric # endif // _LIBCPP_HAS_NO_RTTI 274fe6060f1SDimitry Andric }; 275fe6060f1SDimitry Andric 276fe6060f1SDimitry Andric template <class _Fp, class _Alloc, class _Rp, class... _ArgTypes> 277*cb14a3feSDimitry Andric __base<_Rp(_ArgTypes...)>* __func<_Fp, _Alloc, _Rp(_ArgTypes...)>::__clone() const { 278fe6060f1SDimitry Andric typedef allocator_traits<_Alloc> __alloc_traits; 279bdd1243dSDimitry Andric typedef __rebind_alloc<__alloc_traits, __func> _Ap; 280fe6060f1SDimitry Andric _Ap __a(__f_.__get_allocator()); 281fe6060f1SDimitry Andric typedef __allocator_destructor<_Ap> _Dp; 282fe6060f1SDimitry Andric unique_ptr<__func, _Dp> __hold(__a.allocate(1), _Dp(__a, 1)); 283fe6060f1SDimitry Andric ::new ((void*)__hold.get()) __func(__f_.__target(), _Alloc(__a)); 284fe6060f1SDimitry Andric return __hold.release(); 285fe6060f1SDimitry Andric } 286fe6060f1SDimitry Andric 287fe6060f1SDimitry Andric template <class _Fp, class _Alloc, class _Rp, class... _ArgTypes> 288*cb14a3feSDimitry Andric void __func<_Fp, _Alloc, _Rp(_ArgTypes...)>::__clone(__base<_Rp(_ArgTypes...)>* __p) const { 289fe6060f1SDimitry Andric ::new ((void*)__p) __func(__f_.__target(), __f_.__get_allocator()); 290fe6060f1SDimitry Andric } 291fe6060f1SDimitry Andric 292fe6060f1SDimitry Andric template <class _Fp, class _Alloc, class _Rp, class... _ArgTypes> 293*cb14a3feSDimitry Andric void __func<_Fp, _Alloc, _Rp(_ArgTypes...)>::destroy() _NOEXCEPT { 294fe6060f1SDimitry Andric __f_.destroy(); 295fe6060f1SDimitry Andric } 296fe6060f1SDimitry Andric 297fe6060f1SDimitry Andric template <class _Fp, class _Alloc, class _Rp, class... _ArgTypes> 298*cb14a3feSDimitry Andric void __func<_Fp, _Alloc, _Rp(_ArgTypes...)>::destroy_deallocate() _NOEXCEPT { 299fe6060f1SDimitry Andric typedef allocator_traits<_Alloc> __alloc_traits; 300bdd1243dSDimitry Andric typedef __rebind_alloc<__alloc_traits, __func> _Ap; 301fe6060f1SDimitry Andric _Ap __a(__f_.__get_allocator()); 302fe6060f1SDimitry Andric __f_.destroy(); 303fe6060f1SDimitry Andric __a.deallocate(this, 1); 304fe6060f1SDimitry Andric } 305fe6060f1SDimitry Andric 306fe6060f1SDimitry Andric template <class _Fp, class _Alloc, class _Rp, class... _ArgTypes> 307*cb14a3feSDimitry Andric _Rp __func<_Fp, _Alloc, _Rp(_ArgTypes...)>::operator()(_ArgTypes&&... __arg) { 3085f757f3fSDimitry Andric return __f_(std::forward<_ArgTypes>(__arg)...); 309fe6060f1SDimitry Andric } 310fe6060f1SDimitry Andric 3111ac55f4cSDimitry Andric # ifndef _LIBCPP_HAS_NO_RTTI 312fe6060f1SDimitry Andric 313fe6060f1SDimitry Andric template <class _Fp, class _Alloc, class _Rp, class... _ArgTypes> 314*cb14a3feSDimitry Andric const void* __func<_Fp, _Alloc, _Rp(_ArgTypes...)>::target(const type_info& __ti) const _NOEXCEPT { 315fe6060f1SDimitry Andric if (__ti == typeid(_Fp)) 3165f757f3fSDimitry Andric return std::addressof(__f_.__target()); 317fe6060f1SDimitry Andric return nullptr; 318fe6060f1SDimitry Andric } 319fe6060f1SDimitry Andric 320fe6060f1SDimitry Andric template <class _Fp, class _Alloc, class _Rp, class... _ArgTypes> 321*cb14a3feSDimitry Andric const std::type_info& __func<_Fp, _Alloc, _Rp(_ArgTypes...)>::target_type() const _NOEXCEPT { 322fe6060f1SDimitry Andric return typeid(_Fp); 323fe6060f1SDimitry Andric } 324fe6060f1SDimitry Andric 3251ac55f4cSDimitry Andric # endif // _LIBCPP_HAS_NO_RTTI 326fe6060f1SDimitry Andric 327fe6060f1SDimitry Andric // __value_func creates a value-type from a __func. 328fe6060f1SDimitry Andric 329*cb14a3feSDimitry Andric template <class _Fp> 330*cb14a3feSDimitry Andric class __value_func; 331fe6060f1SDimitry Andric 332*cb14a3feSDimitry Andric template <class _Rp, class... _ArgTypes> 333*cb14a3feSDimitry Andric class __value_func<_Rp(_ArgTypes...)> { 334bdd1243dSDimitry Andric _LIBCPP_SUPPRESS_DEPRECATED_PUSH 335fe6060f1SDimitry Andric typename aligned_storage<3 * sizeof(void*)>::type __buf_; 336bdd1243dSDimitry Andric _LIBCPP_SUPPRESS_DEPRECATED_POP 337fe6060f1SDimitry Andric 338fe6060f1SDimitry Andric typedef __base<_Rp(_ArgTypes...)> __func; 339fe6060f1SDimitry Andric __func* __f_; 340fe6060f1SDimitry Andric 341*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_NO_CFI static __func* __as_base(void* __p) { return reinterpret_cast<__func*>(__p); } 342fe6060f1SDimitry Andric 343fe6060f1SDimitry Andric public: 344*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI __value_func() _NOEXCEPT : __f_(nullptr) {} 345fe6060f1SDimitry Andric 346fe6060f1SDimitry Andric template <class _Fp, class _Alloc> 347*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI __value_func(_Fp&& __f, const _Alloc& __a) : __f_(nullptr) { 348fe6060f1SDimitry Andric typedef allocator_traits<_Alloc> __alloc_traits; 349fe6060f1SDimitry Andric typedef __function::__func<_Fp, _Alloc, _Rp(_ArgTypes...)> _Fun; 350bdd1243dSDimitry Andric typedef __rebind_alloc<__alloc_traits, _Fun> _FunAlloc; 351fe6060f1SDimitry Andric 352*cb14a3feSDimitry Andric if (__function::__not_null(__f)) { 353fe6060f1SDimitry Andric _FunAlloc __af(__a); 354*cb14a3feSDimitry Andric if (sizeof(_Fun) <= sizeof(__buf_) && is_nothrow_copy_constructible<_Fp>::value && 355*cb14a3feSDimitry Andric is_nothrow_copy_constructible<_FunAlloc>::value) { 356*cb14a3feSDimitry Andric __f_ = ::new ((void*)&__buf_) _Fun(std::move(__f), _Alloc(__af)); 357*cb14a3feSDimitry Andric } else { 358fe6060f1SDimitry Andric typedef __allocator_destructor<_FunAlloc> _Dp; 359fe6060f1SDimitry Andric unique_ptr<__func, _Dp> __hold(__af.allocate(1), _Dp(__af, 1)); 3605f757f3fSDimitry Andric ::new ((void*)__hold.get()) _Fun(std::move(__f), _Alloc(__a)); 361fe6060f1SDimitry Andric __f_ = __hold.release(); 362fe6060f1SDimitry Andric } 363fe6060f1SDimitry Andric } 364fe6060f1SDimitry Andric } 365fe6060f1SDimitry Andric 3665f757f3fSDimitry Andric template <class _Fp, __enable_if_t<!is_same<__decay_t<_Fp>, __value_func>::value, int> = 0> 367*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI explicit __value_func(_Fp&& __f) : __value_func(std::forward<_Fp>(__f), allocator<_Fp>()) {} 368fe6060f1SDimitry Andric 369*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI __value_func(const __value_func& __f) { 370fe6060f1SDimitry Andric if (__f.__f_ == nullptr) 371fe6060f1SDimitry Andric __f_ = nullptr; 372*cb14a3feSDimitry Andric else if ((void*)__f.__f_ == &__f.__buf_) { 373fe6060f1SDimitry Andric __f_ = __as_base(&__buf_); 374fe6060f1SDimitry Andric __f.__f_->__clone(__f_); 375*cb14a3feSDimitry Andric } else 376fe6060f1SDimitry Andric __f_ = __f.__f_->__clone(); 377fe6060f1SDimitry Andric } 378fe6060f1SDimitry Andric 379*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI __value_func(__value_func&& __f) _NOEXCEPT { 380fe6060f1SDimitry Andric if (__f.__f_ == nullptr) 381fe6060f1SDimitry Andric __f_ = nullptr; 382*cb14a3feSDimitry Andric else if ((void*)__f.__f_ == &__f.__buf_) { 383fe6060f1SDimitry Andric __f_ = __as_base(&__buf_); 384fe6060f1SDimitry Andric __f.__f_->__clone(__f_); 385*cb14a3feSDimitry Andric } else { 386fe6060f1SDimitry Andric __f_ = __f.__f_; 387fe6060f1SDimitry Andric __f.__f_ = nullptr; 388fe6060f1SDimitry Andric } 389fe6060f1SDimitry Andric } 390fe6060f1SDimitry Andric 391*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI ~__value_func() { 392fe6060f1SDimitry Andric if ((void*)__f_ == &__buf_) 393fe6060f1SDimitry Andric __f_->destroy(); 394fe6060f1SDimitry Andric else if (__f_) 395fe6060f1SDimitry Andric __f_->destroy_deallocate(); 396fe6060f1SDimitry Andric } 397fe6060f1SDimitry Andric 398*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI __value_func& operator=(__value_func&& __f) { 399fe6060f1SDimitry Andric *this = nullptr; 400fe6060f1SDimitry Andric if (__f.__f_ == nullptr) 401fe6060f1SDimitry Andric __f_ = nullptr; 402*cb14a3feSDimitry Andric else if ((void*)__f.__f_ == &__f.__buf_) { 403fe6060f1SDimitry Andric __f_ = __as_base(&__buf_); 404fe6060f1SDimitry Andric __f.__f_->__clone(__f_); 405*cb14a3feSDimitry Andric } else { 406fe6060f1SDimitry Andric __f_ = __f.__f_; 407fe6060f1SDimitry Andric __f.__f_ = nullptr; 408fe6060f1SDimitry Andric } 409fe6060f1SDimitry Andric return *this; 410fe6060f1SDimitry Andric } 411fe6060f1SDimitry Andric 412*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI __value_func& operator=(nullptr_t) { 413fe6060f1SDimitry Andric __func* __f = __f_; 414fe6060f1SDimitry Andric __f_ = nullptr; 415fe6060f1SDimitry Andric if ((void*)__f == &__buf_) 416fe6060f1SDimitry Andric __f->destroy(); 417fe6060f1SDimitry Andric else if (__f) 418fe6060f1SDimitry Andric __f->destroy_deallocate(); 419fe6060f1SDimitry Andric return *this; 420fe6060f1SDimitry Andric } 421fe6060f1SDimitry Andric 422*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _Rp operator()(_ArgTypes&&... __args) const { 423fe6060f1SDimitry Andric if (__f_ == nullptr) 424fe6060f1SDimitry Andric __throw_bad_function_call(); 4255f757f3fSDimitry Andric return (*__f_)(std::forward<_ArgTypes>(__args)...); 426fe6060f1SDimitry Andric } 427fe6060f1SDimitry Andric 428*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI void swap(__value_func& __f) _NOEXCEPT { 429fe6060f1SDimitry Andric if (&__f == this) 430fe6060f1SDimitry Andric return; 431*cb14a3feSDimitry Andric if ((void*)__f_ == &__buf_ && (void*)__f.__f_ == &__f.__buf_) { 432bdd1243dSDimitry Andric _LIBCPP_SUPPRESS_DEPRECATED_PUSH 433fe6060f1SDimitry Andric typename aligned_storage<sizeof(__buf_)>::type __tempbuf; 434bdd1243dSDimitry Andric _LIBCPP_SUPPRESS_DEPRECATED_POP 435fe6060f1SDimitry Andric __func* __t = __as_base(&__tempbuf); 436fe6060f1SDimitry Andric __f_->__clone(__t); 437fe6060f1SDimitry Andric __f_->destroy(); 438fe6060f1SDimitry Andric __f_ = nullptr; 439fe6060f1SDimitry Andric __f.__f_->__clone(__as_base(&__buf_)); 440fe6060f1SDimitry Andric __f.__f_->destroy(); 441fe6060f1SDimitry Andric __f.__f_ = nullptr; 442fe6060f1SDimitry Andric __f_ = __as_base(&__buf_); 443fe6060f1SDimitry Andric __t->__clone(__as_base(&__f.__buf_)); 444fe6060f1SDimitry Andric __t->destroy(); 445fe6060f1SDimitry Andric __f.__f_ = __as_base(&__f.__buf_); 446*cb14a3feSDimitry Andric } else if ((void*)__f_ == &__buf_) { 447fe6060f1SDimitry Andric __f_->__clone(__as_base(&__f.__buf_)); 448fe6060f1SDimitry Andric __f_->destroy(); 449fe6060f1SDimitry Andric __f_ = __f.__f_; 450fe6060f1SDimitry Andric __f.__f_ = __as_base(&__f.__buf_); 451*cb14a3feSDimitry Andric } else if ((void*)__f.__f_ == &__f.__buf_) { 452fe6060f1SDimitry Andric __f.__f_->__clone(__as_base(&__buf_)); 453fe6060f1SDimitry Andric __f.__f_->destroy(); 454fe6060f1SDimitry Andric __f.__f_ = __f_; 455fe6060f1SDimitry Andric __f_ = __as_base(&__buf_); 456*cb14a3feSDimitry Andric } else 4575f757f3fSDimitry Andric std::swap(__f_, __f.__f_); 458fe6060f1SDimitry Andric } 459fe6060f1SDimitry Andric 460*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI explicit operator bool() const _NOEXCEPT { return __f_ != nullptr; } 461fe6060f1SDimitry Andric 4621ac55f4cSDimitry Andric # ifndef _LIBCPP_HAS_NO_RTTI 463*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI const std::type_info& target_type() const _NOEXCEPT { 464fe6060f1SDimitry Andric if (__f_ == nullptr) 465fe6060f1SDimitry Andric return typeid(void); 466fe6060f1SDimitry Andric return __f_->target_type(); 467fe6060f1SDimitry Andric } 468fe6060f1SDimitry Andric 469fe6060f1SDimitry Andric template <typename _Tp> 470*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI const _Tp* target() const _NOEXCEPT { 471fe6060f1SDimitry Andric if (__f_ == nullptr) 472fe6060f1SDimitry Andric return nullptr; 473fe6060f1SDimitry Andric return (const _Tp*)__f_->target(typeid(_Tp)); 474fe6060f1SDimitry Andric } 4751ac55f4cSDimitry Andric # endif // _LIBCPP_HAS_NO_RTTI 476fe6060f1SDimitry Andric }; 477fe6060f1SDimitry Andric 478fe6060f1SDimitry Andric // Storage for a functor object, to be used with __policy to manage copy and 479fe6060f1SDimitry Andric // destruction. 480*cb14a3feSDimitry Andric union __policy_storage { 481fe6060f1SDimitry Andric mutable char __small[sizeof(void*) * 2]; 482fe6060f1SDimitry Andric void* __large; 483fe6060f1SDimitry Andric }; 484fe6060f1SDimitry Andric 485fe6060f1SDimitry Andric // True if _Fun can safely be held in __policy_storage.__small. 486fe6060f1SDimitry Andric template <typename _Fun> 487fe6060f1SDimitry Andric struct __use_small_storage 488fe6060f1SDimitry Andric : public integral_constant< 489*cb14a3feSDimitry Andric bool, 490*cb14a3feSDimitry Andric sizeof(_Fun) <= sizeof(__policy_storage)&& _LIBCPP_ALIGNOF(_Fun) <= _LIBCPP_ALIGNOF(__policy_storage) && 491*cb14a3feSDimitry Andric is_trivially_copy_constructible<_Fun>::value && is_trivially_destructible<_Fun>::value> {}; 492fe6060f1SDimitry Andric 493fe6060f1SDimitry Andric // Policy contains information about how to copy, destroy, and move the 494fe6060f1SDimitry Andric // underlying functor. You can think of it as a vtable of sorts. 495*cb14a3feSDimitry Andric struct __policy { 496fe6060f1SDimitry Andric // Used to copy or destroy __large values. null for trivial objects. 497fe6060f1SDimitry Andric void* (*const __clone)(const void*); 498fe6060f1SDimitry Andric void (*const __destroy)(void*); 499fe6060f1SDimitry Andric 500fe6060f1SDimitry Andric // True if this is the null policy (no value). 501fe6060f1SDimitry Andric const bool __is_null; 502fe6060f1SDimitry Andric 503fe6060f1SDimitry Andric // The target type. May be null if RTTI is disabled. 504fe6060f1SDimitry Andric const std::type_info* const __type_info; 505fe6060f1SDimitry Andric 506fe6060f1SDimitry Andric // Returns a pointer to a static policy object suitable for the functor 507fe6060f1SDimitry Andric // type. 508fe6060f1SDimitry Andric template <typename _Fun> 509*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI static const __policy* __create() { 510fe6060f1SDimitry Andric return __choose_policy<_Fun>(__use_small_storage<_Fun>()); 511fe6060f1SDimitry Andric } 512fe6060f1SDimitry Andric 513*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI static const __policy* __create_empty() { 514*cb14a3feSDimitry Andric static const _LIBCPP_CONSTEXPR __policy __policy = { 515*cb14a3feSDimitry Andric nullptr, 516*cb14a3feSDimitry Andric nullptr, 517fe6060f1SDimitry Andric true, 5181ac55f4cSDimitry Andric # ifndef _LIBCPP_HAS_NO_RTTI 519fe6060f1SDimitry Andric &typeid(void) 520fe6060f1SDimitry Andric # else 521fe6060f1SDimitry Andric nullptr 522fe6060f1SDimitry Andric # endif 523fe6060f1SDimitry Andric }; 52406c3fb27SDimitry Andric return &__policy; 525fe6060f1SDimitry Andric } 526fe6060f1SDimitry Andric 527fe6060f1SDimitry Andric private: 52806c3fb27SDimitry Andric template <typename _Fun> 529*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI static void* __large_clone(const void* __s) { 530fe6060f1SDimitry Andric const _Fun* __f = static_cast<const _Fun*>(__s); 531fe6060f1SDimitry Andric return __f->__clone(); 532fe6060f1SDimitry Andric } 533fe6060f1SDimitry Andric 534fe6060f1SDimitry Andric template <typename _Fun> 53506c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI static void __large_destroy(void* __s) { 536fe6060f1SDimitry Andric _Fun::__destroy_and_delete(static_cast<_Fun*>(__s)); 537fe6060f1SDimitry Andric } 538fe6060f1SDimitry Andric 539fe6060f1SDimitry Andric template <typename _Fun> 540*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI static const __policy* __choose_policy(/* is_small = */ false_type) { 54106c3fb27SDimitry Andric static const _LIBCPP_CONSTEXPR __policy __policy = { 542*cb14a3feSDimitry Andric &__large_clone<_Fun>, 543*cb14a3feSDimitry Andric &__large_destroy<_Fun>, 544*cb14a3feSDimitry Andric false, 5451ac55f4cSDimitry Andric # ifndef _LIBCPP_HAS_NO_RTTI 546fe6060f1SDimitry Andric &typeid(typename _Fun::_Target) 547fe6060f1SDimitry Andric # else 548fe6060f1SDimitry Andric nullptr 549fe6060f1SDimitry Andric # endif 550fe6060f1SDimitry Andric }; 55106c3fb27SDimitry Andric return &__policy; 552fe6060f1SDimitry Andric } 553fe6060f1SDimitry Andric 554fe6060f1SDimitry Andric template <typename _Fun> 555*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI static const __policy* __choose_policy(/* is_small = */ true_type) { 55606c3fb27SDimitry Andric static const _LIBCPP_CONSTEXPR __policy __policy = { 557*cb14a3feSDimitry Andric nullptr, 558*cb14a3feSDimitry Andric nullptr, 559*cb14a3feSDimitry Andric false, 5601ac55f4cSDimitry Andric # ifndef _LIBCPP_HAS_NO_RTTI 561fe6060f1SDimitry Andric &typeid(typename _Fun::_Target) 562fe6060f1SDimitry Andric # else 563fe6060f1SDimitry Andric nullptr 564fe6060f1SDimitry Andric # endif 565fe6060f1SDimitry Andric }; 56606c3fb27SDimitry Andric return &__policy; 567fe6060f1SDimitry Andric } 568fe6060f1SDimitry Andric }; 569fe6060f1SDimitry Andric 570fe6060f1SDimitry Andric // Used to choose between perfect forwarding or pass-by-value. Pass-by-value is 571fe6060f1SDimitry Andric // faster for types that can be passed in registers. 572fe6060f1SDimitry Andric template <typename _Tp> 573bdd1243dSDimitry Andric using __fast_forward = __conditional_t<is_scalar<_Tp>::value, _Tp, _Tp&&>; 574fe6060f1SDimitry Andric 575fe6060f1SDimitry Andric // __policy_invoker calls an instance of __alloc_func held in __policy_storage. 576fe6060f1SDimitry Andric 577*cb14a3feSDimitry Andric template <class _Fp> 578*cb14a3feSDimitry Andric struct __policy_invoker; 579fe6060f1SDimitry Andric 580fe6060f1SDimitry Andric template <class _Rp, class... _ArgTypes> 581*cb14a3feSDimitry Andric struct __policy_invoker<_Rp(_ArgTypes...)> { 582*cb14a3feSDimitry Andric typedef _Rp (*__Call)(const __policy_storage*, __fast_forward<_ArgTypes>...); 583fe6060f1SDimitry Andric 584fe6060f1SDimitry Andric __Call __call_; 585fe6060f1SDimitry Andric 586fe6060f1SDimitry Andric // Creates an invoker that throws bad_function_call. 587*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI __policy_invoker() : __call_(&__call_empty) {} 588fe6060f1SDimitry Andric 589fe6060f1SDimitry Andric // Creates an invoker that calls the given instance of __func. 590fe6060f1SDimitry Andric template <typename _Fun> 591*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI static __policy_invoker __create() { 592fe6060f1SDimitry Andric return __policy_invoker(&__call_impl<_Fun>); 593fe6060f1SDimitry Andric } 594fe6060f1SDimitry Andric 595fe6060f1SDimitry Andric private: 596*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI explicit __policy_invoker(__Call __c) : __call_(__c) {} 597fe6060f1SDimitry Andric 598*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI static _Rp __call_empty(const __policy_storage*, __fast_forward<_ArgTypes>...) { 599fe6060f1SDimitry Andric __throw_bad_function_call(); 600fe6060f1SDimitry Andric } 601fe6060f1SDimitry Andric 602fe6060f1SDimitry Andric template <typename _Fun> 603*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI static _Rp __call_impl(const __policy_storage* __buf, __fast_forward<_ArgTypes>... __args) { 604*cb14a3feSDimitry Andric _Fun* __f = reinterpret_cast<_Fun*>(__use_small_storage<_Fun>::value ? &__buf->__small : __buf->__large); 6055f757f3fSDimitry Andric return (*__f)(std::forward<_ArgTypes>(__args)...); 606fe6060f1SDimitry Andric } 607fe6060f1SDimitry Andric }; 608fe6060f1SDimitry Andric 609fe6060f1SDimitry Andric // __policy_func uses a __policy and __policy_invoker to create a type-erased, 610fe6060f1SDimitry Andric // copyable functor. 611fe6060f1SDimitry Andric 612*cb14a3feSDimitry Andric template <class _Fp> 613*cb14a3feSDimitry Andric class __policy_func; 614fe6060f1SDimitry Andric 615*cb14a3feSDimitry Andric template <class _Rp, class... _ArgTypes> 616*cb14a3feSDimitry Andric class __policy_func<_Rp(_ArgTypes...)> { 617fe6060f1SDimitry Andric // Inline storage for small objects. 618fe6060f1SDimitry Andric __policy_storage __buf_; 619fe6060f1SDimitry Andric 620fe6060f1SDimitry Andric // Calls the value stored in __buf_. This could technically be part of 621fe6060f1SDimitry Andric // policy, but storing it here eliminates a level of indirection inside 622fe6060f1SDimitry Andric // operator(). 623fe6060f1SDimitry Andric typedef __function::__policy_invoker<_Rp(_ArgTypes...)> __invoker; 624fe6060f1SDimitry Andric __invoker __invoker_; 625fe6060f1SDimitry Andric 626fe6060f1SDimitry Andric // The policy that describes how to move / copy / destroy __buf_. Never 627fe6060f1SDimitry Andric // null, even if the function is empty. 628fe6060f1SDimitry Andric const __policy* __policy_; 629fe6060f1SDimitry Andric 630fe6060f1SDimitry Andric public: 631*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI __policy_func() : __policy_(__policy::__create_empty()) {} 632fe6060f1SDimitry Andric 633fe6060f1SDimitry Andric template <class _Fp, class _Alloc> 634*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI __policy_func(_Fp&& __f, const _Alloc& __a) : __policy_(__policy::__create_empty()) { 635fe6060f1SDimitry Andric typedef __alloc_func<_Fp, _Alloc, _Rp(_ArgTypes...)> _Fun; 636fe6060f1SDimitry Andric typedef allocator_traits<_Alloc> __alloc_traits; 637bdd1243dSDimitry Andric typedef __rebind_alloc<__alloc_traits, _Fun> _FunAlloc; 638fe6060f1SDimitry Andric 639*cb14a3feSDimitry Andric if (__function::__not_null(__f)) { 640fe6060f1SDimitry Andric __invoker_ = __invoker::template __create<_Fun>(); 641fe6060f1SDimitry Andric __policy_ = __policy::__create<_Fun>(); 642fe6060f1SDimitry Andric 643fe6060f1SDimitry Andric _FunAlloc __af(__a); 644*cb14a3feSDimitry Andric if (__use_small_storage<_Fun>()) { 645*cb14a3feSDimitry Andric ::new ((void*)&__buf_.__small) _Fun(std::move(__f), _Alloc(__af)); 646*cb14a3feSDimitry Andric } else { 647fe6060f1SDimitry Andric typedef __allocator_destructor<_FunAlloc> _Dp; 648fe6060f1SDimitry Andric unique_ptr<_Fun, _Dp> __hold(__af.allocate(1), _Dp(__af, 1)); 649*cb14a3feSDimitry Andric ::new ((void*)__hold.get()) _Fun(std::move(__f), _Alloc(__af)); 650fe6060f1SDimitry Andric __buf_.__large = __hold.release(); 651fe6060f1SDimitry Andric } 652fe6060f1SDimitry Andric } 653fe6060f1SDimitry Andric } 654fe6060f1SDimitry Andric 6555f757f3fSDimitry Andric template <class _Fp, __enable_if_t<!is_same<__decay_t<_Fp>, __policy_func>::value, int> = 0> 656*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI explicit __policy_func(_Fp&& __f) : __policy_(__policy::__create_empty()) { 657fe6060f1SDimitry Andric typedef __default_alloc_func<_Fp, _Rp(_ArgTypes...)> _Fun; 658fe6060f1SDimitry Andric 659fe6060f1SDimitry Andric if (__function::__not_null(__f)) { 660fe6060f1SDimitry Andric __invoker_ = __invoker::template __create<_Fun>(); 661fe6060f1SDimitry Andric __policy_ = __policy::__create<_Fun>(); 662fe6060f1SDimitry Andric if (__use_small_storage<_Fun>()) { 6635f757f3fSDimitry Andric ::new ((void*)&__buf_.__small) _Fun(std::move(__f)); 664fe6060f1SDimitry Andric } else { 665*cb14a3feSDimitry Andric __builtin_new_allocator::__holder_t __hold = __builtin_new_allocator::__allocate_type<_Fun>(1); 6665f757f3fSDimitry Andric __buf_.__large = ::new ((void*)__hold.get()) _Fun(std::move(__f)); 667fe6060f1SDimitry Andric (void)__hold.release(); 668fe6060f1SDimitry Andric } 669fe6060f1SDimitry Andric } 670fe6060f1SDimitry Andric } 671fe6060f1SDimitry Andric 672*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI __policy_func(const __policy_func& __f) 673*cb14a3feSDimitry Andric : __buf_(__f.__buf_), __invoker_(__f.__invoker_), __policy_(__f.__policy_) { 674fe6060f1SDimitry Andric if (__policy_->__clone) 675fe6060f1SDimitry Andric __buf_.__large = __policy_->__clone(__f.__buf_.__large); 676fe6060f1SDimitry Andric } 677fe6060f1SDimitry Andric 678*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI __policy_func(__policy_func&& __f) 679*cb14a3feSDimitry Andric : __buf_(__f.__buf_), __invoker_(__f.__invoker_), __policy_(__f.__policy_) { 680*cb14a3feSDimitry Andric if (__policy_->__destroy) { 681fe6060f1SDimitry Andric __f.__policy_ = __policy::__create_empty(); 682fe6060f1SDimitry Andric __f.__invoker_ = __invoker(); 683fe6060f1SDimitry Andric } 684fe6060f1SDimitry Andric } 685fe6060f1SDimitry Andric 686*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI ~__policy_func() { 687fe6060f1SDimitry Andric if (__policy_->__destroy) 688fe6060f1SDimitry Andric __policy_->__destroy(__buf_.__large); 689fe6060f1SDimitry Andric } 690fe6060f1SDimitry Andric 691*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI __policy_func& operator=(__policy_func&& __f) { 692fe6060f1SDimitry Andric *this = nullptr; 693fe6060f1SDimitry Andric __buf_ = __f.__buf_; 694fe6060f1SDimitry Andric __invoker_ = __f.__invoker_; 695fe6060f1SDimitry Andric __policy_ = __f.__policy_; 696fe6060f1SDimitry Andric __f.__policy_ = __policy::__create_empty(); 697fe6060f1SDimitry Andric __f.__invoker_ = __invoker(); 698fe6060f1SDimitry Andric return *this; 699fe6060f1SDimitry Andric } 700fe6060f1SDimitry Andric 701*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI __policy_func& operator=(nullptr_t) { 702fe6060f1SDimitry Andric const __policy* __p = __policy_; 703fe6060f1SDimitry Andric __policy_ = __policy::__create_empty(); 704fe6060f1SDimitry Andric __invoker_ = __invoker(); 705fe6060f1SDimitry Andric if (__p->__destroy) 706fe6060f1SDimitry Andric __p->__destroy(__buf_.__large); 707fe6060f1SDimitry Andric return *this; 708fe6060f1SDimitry Andric } 709fe6060f1SDimitry Andric 710*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _Rp operator()(_ArgTypes&&... __args) const { 711*cb14a3feSDimitry Andric return __invoker_.__call_(std::addressof(__buf_), std::forward<_ArgTypes>(__args)...); 712fe6060f1SDimitry Andric } 713fe6060f1SDimitry Andric 714*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI void swap(__policy_func& __f) { 7155f757f3fSDimitry Andric std::swap(__invoker_, __f.__invoker_); 7165f757f3fSDimitry Andric std::swap(__policy_, __f.__policy_); 7175f757f3fSDimitry Andric std::swap(__buf_, __f.__buf_); 718fe6060f1SDimitry Andric } 719fe6060f1SDimitry Andric 720*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI explicit operator bool() const _NOEXCEPT { return !__policy_->__is_null; } 721fe6060f1SDimitry Andric 7221ac55f4cSDimitry Andric # ifndef _LIBCPP_HAS_NO_RTTI 723*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI const std::type_info& target_type() const _NOEXCEPT { return *__policy_->__type_info; } 724fe6060f1SDimitry Andric 725fe6060f1SDimitry Andric template <typename _Tp> 726*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI const _Tp* target() const _NOEXCEPT { 727fe6060f1SDimitry Andric if (__policy_->__is_null || typeid(_Tp) != *__policy_->__type_info) 728fe6060f1SDimitry Andric return nullptr; 729fe6060f1SDimitry Andric if (__policy_->__clone) // Out of line storage. 730fe6060f1SDimitry Andric return reinterpret_cast<const _Tp*>(__buf_.__large); 731fe6060f1SDimitry Andric else 732fe6060f1SDimitry Andric return reinterpret_cast<const _Tp*>(&__buf_.__small); 733fe6060f1SDimitry Andric } 7341ac55f4cSDimitry Andric # endif // _LIBCPP_HAS_NO_RTTI 735fe6060f1SDimitry Andric }; 736fe6060f1SDimitry Andric 737f3fd488fSDimitry Andric # if defined(_LIBCPP_HAS_BLOCKS_RUNTIME) 738fe6060f1SDimitry Andric 739fe6060f1SDimitry Andric extern "C" void* _Block_copy(const void*); 740fe6060f1SDimitry Andric extern "C" void _Block_release(const void*); 741fe6060f1SDimitry Andric 742fe6060f1SDimitry Andric template <class _Rp1, class... _ArgTypes1, class _Alloc, class _Rp, class... _ArgTypes> 743*cb14a3feSDimitry Andric class __func<_Rp1 (^)(_ArgTypes1...), _Alloc, _Rp(_ArgTypes...)> : public __base<_Rp(_ArgTypes...)> { 744fe6060f1SDimitry Andric typedef _Rp1 (^__block_type)(_ArgTypes1...); 745fe6060f1SDimitry Andric __block_type __f_; 746fe6060f1SDimitry Andric 747fe6060f1SDimitry Andric public: 748*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI explicit __func(__block_type const& __f) 749f3fd488fSDimitry Andric # ifdef _LIBCPP_HAS_OBJC_ARC 750f3fd488fSDimitry Andric : __f_(__f) 751f3fd488fSDimitry Andric # else 752fe6060f1SDimitry Andric : __f_(reinterpret_cast<__block_type>(__f ? _Block_copy(__f) : nullptr)) 753f3fd488fSDimitry Andric # endif 754*cb14a3feSDimitry Andric { 755*cb14a3feSDimitry Andric } 756fe6060f1SDimitry Andric 757fe6060f1SDimitry Andric // [TODO] add && to save on a retain 758fe6060f1SDimitry Andric 759*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI explicit __func(__block_type __f, const _Alloc& /* unused */) 760f3fd488fSDimitry Andric # ifdef _LIBCPP_HAS_OBJC_ARC 761f3fd488fSDimitry Andric : __f_(__f) 762f3fd488fSDimitry Andric # else 763fe6060f1SDimitry Andric : __f_(reinterpret_cast<__block_type>(__f ? _Block_copy(__f) : nullptr)) 764f3fd488fSDimitry Andric # endif 765*cb14a3feSDimitry Andric { 766*cb14a3feSDimitry Andric } 767fe6060f1SDimitry Andric 768fe6060f1SDimitry Andric virtual __base<_Rp(_ArgTypes...)>* __clone() const { 769*cb14a3feSDimitry Andric _LIBCPP_ASSERT_INTERNAL( 770*cb14a3feSDimitry Andric false, 771fe6060f1SDimitry Andric "Block pointers are just pointers, so they should always fit into " 772fe6060f1SDimitry Andric "std::function's small buffer optimization. This function should " 773fe6060f1SDimitry Andric "never be invoked."); 774fe6060f1SDimitry Andric return nullptr; 775fe6060f1SDimitry Andric } 776fe6060f1SDimitry Andric 777*cb14a3feSDimitry Andric virtual void __clone(__base<_Rp(_ArgTypes...)>* __p) const { ::new ((void*)__p) __func(__f_); } 778fe6060f1SDimitry Andric 779fe6060f1SDimitry Andric virtual void destroy() _NOEXCEPT { 780f3fd488fSDimitry Andric # ifndef _LIBCPP_HAS_OBJC_ARC 781fe6060f1SDimitry Andric if (__f_) 782fe6060f1SDimitry Andric _Block_release(__f_); 783f3fd488fSDimitry Andric # endif 784fe6060f1SDimitry Andric __f_ = 0; 785fe6060f1SDimitry Andric } 786fe6060f1SDimitry Andric 787fe6060f1SDimitry Andric virtual void destroy_deallocate() _NOEXCEPT { 788*cb14a3feSDimitry Andric _LIBCPP_ASSERT_INTERNAL( 789*cb14a3feSDimitry Andric false, 790fe6060f1SDimitry Andric "Block pointers are just pointers, so they should always fit into " 791fe6060f1SDimitry Andric "std::function's small buffer optimization. This function should " 792fe6060f1SDimitry Andric "never be invoked."); 793fe6060f1SDimitry Andric } 794fe6060f1SDimitry Andric 795*cb14a3feSDimitry Andric virtual _Rp operator()(_ArgTypes&&... __arg) { return std::__invoke(__f_, std::forward<_ArgTypes>(__arg)...); } 796fe6060f1SDimitry Andric 7971ac55f4cSDimitry Andric # ifndef _LIBCPP_HAS_NO_RTTI 798fe6060f1SDimitry Andric virtual const void* target(type_info const& __ti) const _NOEXCEPT { 799fe6060f1SDimitry Andric if (__ti == typeid(__func::__block_type)) 800fe6060f1SDimitry Andric return &__f_; 801fe6060f1SDimitry Andric return (const void*)nullptr; 802fe6060f1SDimitry Andric } 803fe6060f1SDimitry Andric 804*cb14a3feSDimitry Andric virtual const std::type_info& target_type() const _NOEXCEPT { return typeid(__func::__block_type); } 8051ac55f4cSDimitry Andric # endif // _LIBCPP_HAS_NO_RTTI 806fe6060f1SDimitry Andric }; 807fe6060f1SDimitry Andric 808f3fd488fSDimitry Andric # endif // _LIBCPP_HAS_EXTENSION_BLOCKS 809fe6060f1SDimitry Andric 8100eae32dcSDimitry Andric } // namespace __function 811fe6060f1SDimitry Andric 812fe6060f1SDimitry Andric template <class _Rp, class... _ArgTypes> 813fe6060f1SDimitry Andric class _LIBCPP_TEMPLATE_VIS function<_Rp(_ArgTypes...)> 814fe6060f1SDimitry Andric : public __function::__maybe_derive_from_unary_function<_Rp(_ArgTypes...)>, 815*cb14a3feSDimitry Andric public __function::__maybe_derive_from_binary_function<_Rp(_ArgTypes...)> { 816fe6060f1SDimitry Andric # ifndef _LIBCPP_ABI_OPTIMIZED_FUNCTION 817fe6060f1SDimitry Andric typedef __function::__value_func<_Rp(_ArgTypes...)> __func; 818fe6060f1SDimitry Andric # else 819fe6060f1SDimitry Andric typedef __function::__policy_func<_Rp(_ArgTypes...)> __func; 820fe6060f1SDimitry Andric # endif 821fe6060f1SDimitry Andric 822fe6060f1SDimitry Andric __func __f_; 823fe6060f1SDimitry Andric 824*cb14a3feSDimitry Andric template <class _Fp, 825*cb14a3feSDimitry Andric bool = _And< _IsNotSame<__remove_cvref_t<_Fp>, function>, __invokable<_Fp, _ArgTypes...> >::value> 826fe6060f1SDimitry Andric struct __callable; 827fe6060f1SDimitry Andric template <class _Fp> 828*cb14a3feSDimitry Andric struct __callable<_Fp, true> { 829*cb14a3feSDimitry Andric static const bool value = 830*cb14a3feSDimitry Andric is_void<_Rp>::value || __is_core_convertible<typename __invoke_of<_Fp, _ArgTypes...>::type, _Rp>::value; 831fe6060f1SDimitry Andric }; 832fe6060f1SDimitry Andric template <class _Fp> 833*cb14a3feSDimitry Andric struct __callable<_Fp, false> { 834fe6060f1SDimitry Andric static const bool value = false; 835fe6060f1SDimitry Andric }; 836fe6060f1SDimitry Andric 837fe6060f1SDimitry Andric template <class _Fp> 8385f757f3fSDimitry Andric using _EnableIfLValueCallable = __enable_if_t<__callable<_Fp&>::value>; 839*cb14a3feSDimitry Andric 840fe6060f1SDimitry Andric public: 841fe6060f1SDimitry Andric typedef _Rp result_type; 842fe6060f1SDimitry Andric 843fe6060f1SDimitry Andric // construct/copy/destroy: 844*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI function() _NOEXCEPT {} 845*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_HIDE_FROM_ABI function(nullptr_t) _NOEXCEPT {} 84606c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI function(const function&); 84706c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI function(function&&) _NOEXCEPT; 848fe6060f1SDimitry Andric template <class _Fp, class = _EnableIfLValueCallable<_Fp>> 84906c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI function(_Fp); 850fe6060f1SDimitry Andric 851fe6060f1SDimitry Andric # if _LIBCPP_STD_VER <= 14 852fe6060f1SDimitry Andric template <class _Alloc> 853*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI function(allocator_arg_t, const _Alloc&) _NOEXCEPT {} 854fe6060f1SDimitry Andric template <class _Alloc> 855*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI function(allocator_arg_t, const _Alloc&, nullptr_t) _NOEXCEPT {} 856fe6060f1SDimitry Andric template <class _Alloc> 85706c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI function(allocator_arg_t, const _Alloc&, const function&); 858fe6060f1SDimitry Andric template <class _Alloc> 85906c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI function(allocator_arg_t, const _Alloc&, function&&); 860fe6060f1SDimitry Andric template <class _Fp, class _Alloc, class = _EnableIfLValueCallable<_Fp>> 86106c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI function(allocator_arg_t, const _Alloc& __a, _Fp __f); 862fe6060f1SDimitry Andric # endif 863fe6060f1SDimitry Andric 86406c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI function& operator=(const function&); 86506c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI function& operator=(function&&) _NOEXCEPT; 86606c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI function& operator=(nullptr_t) _NOEXCEPT; 86706c3fb27SDimitry Andric template <class _Fp, class = _EnableIfLValueCallable<__decay_t<_Fp>>> 86806c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI function& operator=(_Fp&&); 869fe6060f1SDimitry Andric 87006c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI ~function(); 871fe6060f1SDimitry Andric 872fe6060f1SDimitry Andric // function modifiers: 87306c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI void swap(function&) _NOEXCEPT; 874fe6060f1SDimitry Andric 875fe6060f1SDimitry Andric # if _LIBCPP_STD_VER <= 14 876fe6060f1SDimitry Andric template <class _Fp, class _Alloc> 877*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI void assign(_Fp&& __f, const _Alloc& __a) { 878*cb14a3feSDimitry Andric function(allocator_arg, __a, std::forward<_Fp>(__f)).swap(*this); 879*cb14a3feSDimitry Andric } 880fe6060f1SDimitry Andric # endif 881fe6060f1SDimitry Andric 882fe6060f1SDimitry Andric // function capacity: 883*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI explicit operator bool() const _NOEXCEPT { return static_cast<bool>(__f_); } 884fe6060f1SDimitry Andric 885fe6060f1SDimitry Andric // deleted overloads close possible hole in the type system 886fe6060f1SDimitry Andric template <class _R2, class... _ArgTypes2> 887fe6060f1SDimitry Andric bool operator==(const function<_R2(_ArgTypes2...)>&) const = delete; 88806c3fb27SDimitry Andric # if _LIBCPP_STD_VER <= 17 889fe6060f1SDimitry Andric template <class _R2, class... _ArgTypes2> 890fe6060f1SDimitry Andric bool operator!=(const function<_R2(_ArgTypes2...)>&) const = delete; 89106c3fb27SDimitry Andric # endif 892*cb14a3feSDimitry Andric 893fe6060f1SDimitry Andric public: 894fe6060f1SDimitry Andric // function invocation: 89506c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI _Rp operator()(_ArgTypes...) const; 896fe6060f1SDimitry Andric 8971ac55f4cSDimitry Andric # ifndef _LIBCPP_HAS_NO_RTTI 898fe6060f1SDimitry Andric // function target access: 89906c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI const std::type_info& target_type() const _NOEXCEPT; 90006c3fb27SDimitry Andric template <typename _Tp> 90106c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI _Tp* target() _NOEXCEPT; 90206c3fb27SDimitry Andric template <typename _Tp> 90306c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI const _Tp* target() const _NOEXCEPT; 9041ac55f4cSDimitry Andric # endif // _LIBCPP_HAS_NO_RTTI 905fe6060f1SDimitry Andric }; 906fe6060f1SDimitry Andric 907349cc55cSDimitry Andric # if _LIBCPP_STD_VER >= 17 908fe6060f1SDimitry Andric template <class _Rp, class... _Ap> 909fe6060f1SDimitry Andric function(_Rp (*)(_Ap...)) -> function<_Rp(_Ap...)>; 910fe6060f1SDimitry Andric 911fe6060f1SDimitry Andric template <class _Fp, class _Stripped = typename __strip_signature<decltype(&_Fp::operator())>::type> 912fe6060f1SDimitry Andric function(_Fp) -> function<_Stripped>; 913349cc55cSDimitry Andric # endif // _LIBCPP_STD_VER >= 17 914fe6060f1SDimitry Andric 915fe6060f1SDimitry Andric template <class _Rp, class... _ArgTypes> 916fe6060f1SDimitry Andric function<_Rp(_ArgTypes...)>::function(const function& __f) : __f_(__f.__f_) {} 917fe6060f1SDimitry Andric 918fe6060f1SDimitry Andric # if _LIBCPP_STD_VER <= 14 919fe6060f1SDimitry Andric template <class _Rp, class... _ArgTypes> 920fe6060f1SDimitry Andric template <class _Alloc> 921*cb14a3feSDimitry Andric function<_Rp(_ArgTypes...)>::function(allocator_arg_t, const _Alloc&, const function& __f) : __f_(__f.__f_) {} 922fe6060f1SDimitry Andric # endif 923fe6060f1SDimitry Andric 924fe6060f1SDimitry Andric template <class _Rp, class... _ArgTypes> 925*cb14a3feSDimitry Andric function<_Rp(_ArgTypes...)>::function(function&& __f) _NOEXCEPT : __f_(std::move(__f.__f_)) {} 926fe6060f1SDimitry Andric 927fe6060f1SDimitry Andric # if _LIBCPP_STD_VER <= 14 928fe6060f1SDimitry Andric template <class _Rp, class... _ArgTypes> 929fe6060f1SDimitry Andric template <class _Alloc> 930*cb14a3feSDimitry Andric function<_Rp(_ArgTypes...)>::function(allocator_arg_t, const _Alloc&, function&& __f) : __f_(std::move(__f.__f_)) {} 931fe6060f1SDimitry Andric # endif 932fe6060f1SDimitry Andric 933fe6060f1SDimitry Andric template <class _Rp, class... _ArgTypes> 934fe6060f1SDimitry Andric template <class _Fp, class> 9355f757f3fSDimitry Andric function<_Rp(_ArgTypes...)>::function(_Fp __f) : __f_(std::move(__f)) {} 936fe6060f1SDimitry Andric 937fe6060f1SDimitry Andric # if _LIBCPP_STD_VER <= 14 938fe6060f1SDimitry Andric template <class _Rp, class... _ArgTypes> 939fe6060f1SDimitry Andric template <class _Fp, class _Alloc, class> 940*cb14a3feSDimitry Andric function<_Rp(_ArgTypes...)>::function(allocator_arg_t, const _Alloc& __a, _Fp __f) : __f_(std::move(__f), __a) {} 941fe6060f1SDimitry Andric # endif 942fe6060f1SDimitry Andric 943fe6060f1SDimitry Andric template <class _Rp, class... _ArgTypes> 944*cb14a3feSDimitry Andric function<_Rp(_ArgTypes...)>& function<_Rp(_ArgTypes...)>::operator=(const function& __f) { 945fe6060f1SDimitry Andric function(__f).swap(*this); 946fe6060f1SDimitry Andric return *this; 947fe6060f1SDimitry Andric } 948fe6060f1SDimitry Andric 949fe6060f1SDimitry Andric template <class _Rp, class... _ArgTypes> 950*cb14a3feSDimitry Andric function<_Rp(_ArgTypes...)>& function<_Rp(_ArgTypes...)>::operator=(function&& __f) _NOEXCEPT { 9515f757f3fSDimitry Andric __f_ = std::move(__f.__f_); 952fe6060f1SDimitry Andric return *this; 953fe6060f1SDimitry Andric } 954fe6060f1SDimitry Andric 955fe6060f1SDimitry Andric template <class _Rp, class... _ArgTypes> 956*cb14a3feSDimitry Andric function<_Rp(_ArgTypes...)>& function<_Rp(_ArgTypes...)>::operator=(nullptr_t) _NOEXCEPT { 957fe6060f1SDimitry Andric __f_ = nullptr; 958fe6060f1SDimitry Andric return *this; 959fe6060f1SDimitry Andric } 960fe6060f1SDimitry Andric 961fe6060f1SDimitry Andric template <class _Rp, class... _ArgTypes> 962fe6060f1SDimitry Andric template <class _Fp, class> 963*cb14a3feSDimitry Andric function<_Rp(_ArgTypes...)>& function<_Rp(_ArgTypes...)>::operator=(_Fp&& __f) { 9645f757f3fSDimitry Andric function(std::forward<_Fp>(__f)).swap(*this); 965fe6060f1SDimitry Andric return *this; 966fe6060f1SDimitry Andric } 967fe6060f1SDimitry Andric 968fe6060f1SDimitry Andric template <class _Rp, class... _ArgTypes> 969fe6060f1SDimitry Andric function<_Rp(_ArgTypes...)>::~function() {} 970fe6060f1SDimitry Andric 971fe6060f1SDimitry Andric template <class _Rp, class... _ArgTypes> 972*cb14a3feSDimitry Andric void function<_Rp(_ArgTypes...)>::swap(function& __f) _NOEXCEPT { 973fe6060f1SDimitry Andric __f_.swap(__f.__f_); 974fe6060f1SDimitry Andric } 975fe6060f1SDimitry Andric 976fe6060f1SDimitry Andric template <class _Rp, class... _ArgTypes> 977*cb14a3feSDimitry Andric _Rp function<_Rp(_ArgTypes...)>::operator()(_ArgTypes... __arg) const { 9785f757f3fSDimitry Andric return __f_(std::forward<_ArgTypes>(__arg)...); 979fe6060f1SDimitry Andric } 980fe6060f1SDimitry Andric 9811ac55f4cSDimitry Andric # ifndef _LIBCPP_HAS_NO_RTTI 982fe6060f1SDimitry Andric 983fe6060f1SDimitry Andric template <class _Rp, class... _ArgTypes> 984*cb14a3feSDimitry Andric const std::type_info& function<_Rp(_ArgTypes...)>::target_type() const _NOEXCEPT { 985fe6060f1SDimitry Andric return __f_.target_type(); 986fe6060f1SDimitry Andric } 987fe6060f1SDimitry Andric 988fe6060f1SDimitry Andric template <class _Rp, class... _ArgTypes> 989fe6060f1SDimitry Andric template <typename _Tp> 990*cb14a3feSDimitry Andric _Tp* function<_Rp(_ArgTypes...)>::target() _NOEXCEPT { 991fe6060f1SDimitry Andric return (_Tp*)(__f_.template target<_Tp>()); 992fe6060f1SDimitry Andric } 993fe6060f1SDimitry Andric 994fe6060f1SDimitry Andric template <class _Rp, class... _ArgTypes> 995fe6060f1SDimitry Andric template <typename _Tp> 996*cb14a3feSDimitry Andric const _Tp* function<_Rp(_ArgTypes...)>::target() const _NOEXCEPT { 997fe6060f1SDimitry Andric return __f_.template target<_Tp>(); 998fe6060f1SDimitry Andric } 999fe6060f1SDimitry Andric 10001ac55f4cSDimitry Andric # endif // _LIBCPP_HAS_NO_RTTI 1001fe6060f1SDimitry Andric 1002fe6060f1SDimitry Andric template <class _Rp, class... _ArgTypes> 1003*cb14a3feSDimitry Andric inline _LIBCPP_HIDE_FROM_ABI bool operator==(const function<_Rp(_ArgTypes...)>& __f, nullptr_t) _NOEXCEPT { 1004*cb14a3feSDimitry Andric return !__f; 1005*cb14a3feSDimitry Andric } 1006fe6060f1SDimitry Andric 100706c3fb27SDimitry Andric # if _LIBCPP_STD_VER <= 17 100806c3fb27SDimitry Andric 1009fe6060f1SDimitry Andric template <class _Rp, class... _ArgTypes> 1010*cb14a3feSDimitry Andric inline _LIBCPP_HIDE_FROM_ABI bool operator==(nullptr_t, const function<_Rp(_ArgTypes...)>& __f) _NOEXCEPT { 1011*cb14a3feSDimitry Andric return !__f; 1012*cb14a3feSDimitry Andric } 1013fe6060f1SDimitry Andric 1014fe6060f1SDimitry Andric template <class _Rp, class... _ArgTypes> 1015*cb14a3feSDimitry Andric inline _LIBCPP_HIDE_FROM_ABI bool operator!=(const function<_Rp(_ArgTypes...)>& __f, nullptr_t) _NOEXCEPT { 1016*cb14a3feSDimitry Andric return (bool)__f; 1017*cb14a3feSDimitry Andric } 1018fe6060f1SDimitry Andric 1019fe6060f1SDimitry Andric template <class _Rp, class... _ArgTypes> 1020*cb14a3feSDimitry Andric inline _LIBCPP_HIDE_FROM_ABI bool operator!=(nullptr_t, const function<_Rp(_ArgTypes...)>& __f) _NOEXCEPT { 1021*cb14a3feSDimitry Andric return (bool)__f; 1022*cb14a3feSDimitry Andric } 1023fe6060f1SDimitry Andric 102406c3fb27SDimitry Andric # endif // _LIBCPP_STD_VER <= 17 102506c3fb27SDimitry Andric 1026fe6060f1SDimitry Andric template <class _Rp, class... _ArgTypes> 1027*cb14a3feSDimitry Andric inline _LIBCPP_HIDE_FROM_ABI void swap(function<_Rp(_ArgTypes...)>& __x, function<_Rp(_ArgTypes...)>& __y) _NOEXCEPT { 1028*cb14a3feSDimitry Andric return __x.swap(__y); 1029*cb14a3feSDimitry Andric } 1030fe6060f1SDimitry Andric 1031bdd1243dSDimitry Andric _LIBCPP_END_NAMESPACE_STD 1032fe6060f1SDimitry Andric 103381ad6265SDimitry Andric #endif // _LIBCPP_CXX03_LANG 1034fe6060f1SDimitry Andric 1035fe6060f1SDimitry Andric #endif // _LIBCPP___FUNCTIONAL_FUNCTION_H 1036