1050b064fSChristopher Di Bella // -*- C++ -*- 2050b064fSChristopher Di Bella //===----------------------------------------------------------------------===// 3050b064fSChristopher Di Bella // 4050b064fSChristopher Di Bella // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 5050b064fSChristopher Di Bella // See https://llvm.org/LICENSE.txt for license information. 6050b064fSChristopher Di Bella // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 7050b064fSChristopher Di Bella // 8050b064fSChristopher Di Bella //===----------------------------------------------------------------------===// 9050b064fSChristopher Di Bella 10050b064fSChristopher Di Bella #ifndef _LIBCPP___FUNCTIONAL_FUNCTION_H 11050b064fSChristopher Di Bella #define _LIBCPP___FUNCTIONAL_FUNCTION_H 12050b064fSChristopher Di Bella 13f87aa19bSLouis Dionne #include <__assert> 14050b064fSChristopher Di Bella #include <__config> 155acc4a3dSNikolas Klauser #include <__cstddef/nullptr_t.h> 16c9d36bd8SNikolas Klauser #include <__exception/exception.h> 17050b064fSChristopher Di Bella #include <__functional/binary_function.h> 18050b064fSChristopher Di Bella #include <__functional/invoke.h> 19050b064fSChristopher Di Bella #include <__functional/unary_function.h> 20050b064fSChristopher Di Bella #include <__iterator/iterator_traits.h> 21e24ddb60SLouis Dionne #include <__memory/addressof.h> 22d5e26775SNikolas Klauser #include <__memory/allocator.h> 2359ef4b36SNikolas Klauser #include <__memory/allocator_destructor.h> 24050b064fSChristopher Di Bella #include <__memory/allocator_traits.h> 25050b064fSChristopher Di Bella #include <__memory/compressed_pair.h> 26d5e26775SNikolas Klauser #include <__memory/unique_ptr.h> 270a4aa8a1SNikolas Klauser #include <__type_traits/aligned_storage.h> 2879702f7fSIan Anderson #include <__type_traits/decay.h> 2979702f7fSIan Anderson #include <__type_traits/is_core_convertible.h> 3079702f7fSIan Anderson #include <__type_traits/is_scalar.h> 31580f6048SNikolas Klauser #include <__type_traits/is_trivially_constructible.h> 320a4aa8a1SNikolas Klauser #include <__type_traits/is_trivially_destructible.h> 3379702f7fSIan Anderson #include <__type_traits/is_void.h> 343ec6c997SNikolas Klauser #include <__type_traits/strip_signature.h> 35ea2206d7SArthur O'Dwyer #include <__utility/forward.h> 36ea2206d7SArthur O'Dwyer #include <__utility/move.h> 37d5e26775SNikolas Klauser #include <__utility/piecewise_construct.h> 3852915d78SNikolas Klauser #include <__utility/swap.h> 3916d1b0e1SNikolas Klauser #include <__verbose_abort> 40d5e26775SNikolas Klauser #include <tuple> 41d5e26775SNikolas Klauser #include <typeinfo> 42050b064fSChristopher Di Bella 43050b064fSChristopher Di Bella #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 44050b064fSChristopher Di Bella # pragma GCC system_header 45050b064fSChristopher Di Bella #endif 46050b064fSChristopher Di Bella 477b462251SLouis Dionne _LIBCPP_PUSH_MACROS 487b462251SLouis Dionne #include <__undef_macros> 497b462251SLouis Dionne 50dbe60caaSNikolas Klauser #ifndef _LIBCPP_CXX03_LANG 51dbe60caaSNikolas Klauser 52050b064fSChristopher Di Bella _LIBCPP_BEGIN_NAMESPACE_STD 53050b064fSChristopher Di Bella 54050b064fSChristopher Di Bella // bad_function_call 55050b064fSChristopher Di Bella 5655cb62f3SNikolas Klauser _LIBCPP_DIAGNOSTIC_PUSH 5722629bb2SLouis Dionne # if !_LIBCPP_AVAILABILITY_HAS_BAD_FUNCTION_CALL_KEY_FUNCTION 5855cb62f3SNikolas Klauser _LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wweak-vtables") 5922629bb2SLouis Dionne # endif 609783f28cSLouis Dionne class _LIBCPP_EXPORTED_FROM_ABI bad_function_call : public exception { 61050b064fSChristopher Di Bella public: 6270248920SIgor Zhukov _LIBCPP_HIDE_FROM_ABI bad_function_call() _NOEXCEPT = default; 6370248920SIgor Zhukov _LIBCPP_HIDE_FROM_ABI bad_function_call(const bad_function_call&) _NOEXCEPT = default; 6470248920SIgor Zhukov _LIBCPP_HIDE_FROM_ABI bad_function_call& operator=(const bad_function_call&) _NOEXCEPT = default; 65434dc0a5SKonstantin Varlamov // Note that when a key function is not used, every translation unit that uses 66434dc0a5SKonstantin Varlamov // bad_function_call will end up containing a weak definition of the vtable and 67434dc0a5SKonstantin Varlamov // typeinfo. 6822629bb2SLouis Dionne # if _LIBCPP_AVAILABILITY_HAS_BAD_FUNCTION_CALL_KEY_FUNCTION 694262b523SNikolas Klauser ~bad_function_call() _NOEXCEPT override; 70434dc0a5SKonstantin Varlamov # else 7183ce1397SNikolas Klauser _LIBCPP_HIDE_FROM_ABI_VIRTUAL ~bad_function_call() _NOEXCEPT override {} 72434dc0a5SKonstantin Varlamov # endif 73050b064fSChristopher Di Bella 74434dc0a5SKonstantin Varlamov # ifdef _LIBCPP_ABI_BAD_FUNCTION_CALL_GOOD_WHAT_MESSAGE 754262b523SNikolas Klauser const char* what() const _NOEXCEPT override; 76050b064fSChristopher Di Bella # endif 77050b064fSChristopher Di Bella }; 7855cb62f3SNikolas Klauser _LIBCPP_DIAGNOSTIC_POP 79050b064fSChristopher Di Bella 80748023dcSNikolas Klauser [[__noreturn__]] inline _LIBCPP_HIDE_FROM_ABI void __throw_bad_function_call() { 81ba87515fSNikolas Klauser # if _LIBCPP_HAS_EXCEPTIONS 82050b064fSChristopher Di Bella throw bad_function_call(); 83050b064fSChristopher Di Bella # else 84308bcb3fSNikolas Klauser _LIBCPP_VERBOSE_ABORT("bad_function_call was thrown in -fno-exceptions mode"); 85050b064fSChristopher Di Bella # endif 86050b064fSChristopher Di Bella } 87050b064fSChristopher Di Bella 889783f28cSLouis Dionne template <class _Fp> 899783f28cSLouis Dionne class _LIBCPP_TEMPLATE_VIS function; // undefined 90050b064fSChristopher Di Bella 919783f28cSLouis Dionne namespace __function { 92050b064fSChristopher Di Bella 93050b064fSChristopher Di Bella template <class _Rp> 949783f28cSLouis Dionne struct __maybe_derive_from_unary_function {}; 95050b064fSChristopher Di Bella 96050b064fSChristopher Di Bella template <class _Rp, class _A1> 979783f28cSLouis Dionne struct __maybe_derive_from_unary_function<_Rp(_A1)> : public __unary_function<_A1, _Rp> {}; 98050b064fSChristopher Di Bella 99050b064fSChristopher Di Bella template <class _Rp> 1009783f28cSLouis Dionne struct __maybe_derive_from_binary_function {}; 101050b064fSChristopher Di Bella 102050b064fSChristopher Di Bella template <class _Rp, class _A1, class _A2> 1039783f28cSLouis Dionne struct __maybe_derive_from_binary_function<_Rp(_A1, _A2)> : public __binary_function<_A1, _A2, _Rp> {}; 104050b064fSChristopher Di Bella 105050b064fSChristopher Di Bella template <class _Fp> 1069783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI bool __not_null(_Fp const&) { 1079783f28cSLouis Dionne return true; 1089783f28cSLouis Dionne } 109050b064fSChristopher Di Bella 110050b064fSChristopher Di Bella template <class _Fp> 1119783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI bool __not_null(_Fp* __ptr) { 1129783f28cSLouis Dionne return __ptr; 1139783f28cSLouis Dionne } 114050b064fSChristopher Di Bella 115050b064fSChristopher Di Bella template <class _Ret, class _Class> 1169783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI bool __not_null(_Ret _Class::*__ptr) { 1179783f28cSLouis Dionne return __ptr; 1189783f28cSLouis Dionne } 119050b064fSChristopher Di Bella 120050b064fSChristopher Di Bella template <class _Fp> 1219783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI bool __not_null(function<_Fp> const& __f) { 1229783f28cSLouis Dionne return !!__f; 1239783f28cSLouis Dionne } 124050b064fSChristopher Di Bella 125ba87515fSNikolas Klauser # if _LIBCPP_HAS_EXTENSION_BLOCKS 126050b064fSChristopher Di Bella template <class _Rp, class... _Args> 1279783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI bool __not_null(_Rp (^__p)(_Args...)) { 1289783f28cSLouis Dionne return __p; 1299783f28cSLouis Dionne } 130050b064fSChristopher Di Bella # endif 131050b064fSChristopher Di Bella 132050b064fSChristopher Di Bella } // namespace __function 133050b064fSChristopher Di Bella 134050b064fSChristopher Di Bella namespace __function { 135050b064fSChristopher Di Bella 136050b064fSChristopher Di Bella // __alloc_func holds a functor and an allocator. 137050b064fSChristopher Di Bella 1389783f28cSLouis Dionne template <class _Fp, class _Ap, class _FB> 1399783f28cSLouis Dionne class __alloc_func; 140050b064fSChristopher Di Bella template <class _Fp, class _FB> 141050b064fSChristopher Di Bella class __default_alloc_func; 142050b064fSChristopher Di Bella 143050b064fSChristopher Di Bella template <class _Fp, class _Ap, class _Rp, class... _ArgTypes> 1449783f28cSLouis Dionne class __alloc_func<_Fp, _Ap, _Rp(_ArgTypes...)> { 14527c83382SNikolas Klauser _LIBCPP_COMPRESSED_PAIR(_Fp, __func_, _Ap, __alloc_); 146050b064fSChristopher Di Bella 147050b064fSChristopher Di Bella public: 1483b8faee6SNikolas Klauser using _Target _LIBCPP_NODEBUG = _Fp; 1493b8faee6SNikolas Klauser using _Alloc _LIBCPP_NODEBUG = _Ap; 150050b064fSChristopher Di Bella 15127c83382SNikolas Klauser _LIBCPP_HIDE_FROM_ABI const _Target& __target() const { return __func_; } 152050b064fSChristopher Di Bella 153050b064fSChristopher Di Bella // WIN32 APIs may define __allocator, so use __get_allocator instead. 15427c83382SNikolas Klauser _LIBCPP_HIDE_FROM_ABI const _Alloc& __get_allocator() const { return __alloc_; } 155050b064fSChristopher Di Bella 15627c83382SNikolas Klauser _LIBCPP_HIDE_FROM_ABI explicit __alloc_func(_Target&& __f) : __func_(std::move(__f)), __alloc_() {} 157050b064fSChristopher Di Bella 15827c83382SNikolas Klauser _LIBCPP_HIDE_FROM_ABI explicit __alloc_func(const _Target& __f, const _Alloc& __a) : __func_(__f), __alloc_(__a) {} 159050b064fSChristopher Di Bella 1609783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI explicit __alloc_func(const _Target& __f, _Alloc&& __a) 16127c83382SNikolas Klauser : __func_(__f), __alloc_(std::move(__a)) {} 162050b064fSChristopher Di Bella 1639783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI explicit __alloc_func(_Target&& __f, _Alloc&& __a) 16427c83382SNikolas Klauser : __func_(std::move(__f)), __alloc_(std::move(__a)) {} 165050b064fSChristopher Di Bella 1669783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI _Rp operator()(_ArgTypes&&... __arg) { 167*0fa05456SNikolas Klauser return std::__invoke_r<_Rp>(__func_, std::forward<_ArgTypes>(__arg)...); 168050b064fSChristopher Di Bella } 169050b064fSChristopher Di Bella 1709783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI __alloc_func* __clone() const { 171050b064fSChristopher Di Bella typedef allocator_traits<_Alloc> __alloc_traits; 172d7d586e5SNikolas Klauser typedef __rebind_alloc<__alloc_traits, __alloc_func> _AA; 17327c83382SNikolas Klauser _AA __a(__alloc_); 174050b064fSChristopher Di Bella typedef __allocator_destructor<_AA> _Dp; 175050b064fSChristopher Di Bella unique_ptr<__alloc_func, _Dp> __hold(__a.allocate(1), _Dp(__a, 1)); 17627c83382SNikolas Klauser ::new ((void*)__hold.get()) __alloc_func(__func_, _Alloc(__a)); 177050b064fSChristopher Di Bella return __hold.release(); 178050b064fSChristopher Di Bella } 179050b064fSChristopher Di Bella 18027c83382SNikolas Klauser _LIBCPP_HIDE_FROM_ABI void destroy() _NOEXCEPT { 18127c83382SNikolas Klauser __func_.~_Fp(); 18227c83382SNikolas Klauser __alloc_.~_Alloc(); 18327c83382SNikolas Klauser } 184050b064fSChristopher Di Bella 18583ce1397SNikolas Klauser _LIBCPP_HIDE_FROM_ABI static void __destroy_and_delete(__alloc_func* __f) { 186050b064fSChristopher Di Bella typedef allocator_traits<_Alloc> __alloc_traits; 187d7d586e5SNikolas Klauser typedef __rebind_alloc<__alloc_traits, __alloc_func> _FunAlloc; 188050b064fSChristopher Di Bella _FunAlloc __a(__f->__get_allocator()); 189050b064fSChristopher Di Bella __f->destroy(); 190050b064fSChristopher Di Bella __a.deallocate(__f, 1); 191050b064fSChristopher Di Bella } 192050b064fSChristopher Di Bella }; 193050b064fSChristopher Di Bella 194cedb44afSLouis Dionne template <class _Tp> 195cedb44afSLouis Dionne struct __deallocating_deleter { 196cedb44afSLouis Dionne _LIBCPP_HIDE_FROM_ABI void operator()(void* __p) const { 197cedb44afSLouis Dionne std::__libcpp_deallocate<_Tp>(static_cast<_Tp*>(__p), __element_count(1)); 198cedb44afSLouis Dionne } 199cedb44afSLouis Dionne }; 200cedb44afSLouis Dionne 201050b064fSChristopher Di Bella template <class _Fp, class _Rp, class... _ArgTypes> 202050b064fSChristopher Di Bella class __default_alloc_func<_Fp, _Rp(_ArgTypes...)> { 203050b064fSChristopher Di Bella _Fp __f_; 204050b064fSChristopher Di Bella 205050b064fSChristopher Di Bella public: 2063b8faee6SNikolas Klauser using _Target _LIBCPP_NODEBUG = _Fp; 207050b064fSChristopher Di Bella 2089783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI const _Target& __target() const { return __f_; } 209050b064fSChristopher Di Bella 2109783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI explicit __default_alloc_func(_Target&& __f) : __f_(std::move(__f)) {} 211050b064fSChristopher Di Bella 2129783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI explicit __default_alloc_func(const _Target& __f) : __f_(__f) {} 213050b064fSChristopher Di Bella 2149783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI _Rp operator()(_ArgTypes&&... __arg) { 215*0fa05456SNikolas Klauser return std::__invoke_r<_Rp>(__f_, std::forward<_ArgTypes>(__arg)...); 216050b064fSChristopher Di Bella } 217050b064fSChristopher Di Bella 2189783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI __default_alloc_func* __clone() const { 219cedb44afSLouis Dionne using _Self = __default_alloc_func; 220cedb44afSLouis Dionne unique_ptr<_Self, __deallocating_deleter<_Self>> __hold(std::__libcpp_allocate<_Self>(__element_count(1))); 221cedb44afSLouis Dionne _Self* __res = ::new ((void*)__hold.get()) _Self(__f_); 222050b064fSChristopher Di Bella (void)__hold.release(); 223050b064fSChristopher Di Bella return __res; 224050b064fSChristopher Di Bella } 225050b064fSChristopher Di Bella 2269783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI void destroy() _NOEXCEPT { __f_.~_Target(); } 227050b064fSChristopher Di Bella 22883ce1397SNikolas Klauser _LIBCPP_HIDE_FROM_ABI static void __destroy_and_delete(__default_alloc_func* __f) { 229050b064fSChristopher Di Bella __f->destroy(); 230cedb44afSLouis Dionne std::__libcpp_deallocate<__default_alloc_func>(__f, __element_count(1)); 231050b064fSChristopher Di Bella } 232050b064fSChristopher Di Bella }; 233050b064fSChristopher Di Bella 234050b064fSChristopher Di Bella // __base provides an abstract interface for copyable functors. 235050b064fSChristopher Di Bella 2369783f28cSLouis Dionne template <class _Fp> 2379783f28cSLouis Dionne class _LIBCPP_TEMPLATE_VIS __base; 238050b064fSChristopher Di Bella 239050b064fSChristopher Di Bella template <class _Rp, class... _ArgTypes> 2409783f28cSLouis Dionne class __base<_Rp(_ArgTypes...)> { 241050b064fSChristopher Di Bella public: 242bbe4a806SNikolas Klauser __base(const __base&) = delete; 243bbe4a806SNikolas Klauser __base& operator=(const __base&) = delete; 244bbe4a806SNikolas Klauser 2454c198542SLouis Dionne _LIBCPP_HIDE_FROM_ABI __base() {} 2465efc8116SLouis Dionne _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual ~__base() {} 247050b064fSChristopher Di Bella virtual __base* __clone() const = 0; 248050b064fSChristopher Di Bella virtual void __clone(__base*) const = 0; 249050b064fSChristopher Di Bella virtual void destroy() _NOEXCEPT = 0; 250050b064fSChristopher Di Bella virtual void destroy_deallocate() _NOEXCEPT = 0; 251050b064fSChristopher Di Bella virtual _Rp operator()(_ArgTypes&&...) = 0; 252ba87515fSNikolas Klauser # if _LIBCPP_HAS_RTTI 253050b064fSChristopher Di Bella virtual const void* target(const type_info&) const _NOEXCEPT = 0; 254050b064fSChristopher Di Bella virtual const std::type_info& target_type() const _NOEXCEPT = 0; 255ba87515fSNikolas Klauser # endif // _LIBCPP_HAS_RTTI 256050b064fSChristopher Di Bella }; 257050b064fSChristopher Di Bella 258050b064fSChristopher Di Bella // __func implements __base for a given functor type. 259050b064fSChristopher Di Bella 2609783f28cSLouis Dionne template <class _FD, class _Alloc, class _FB> 2619783f28cSLouis Dionne class __func; 262050b064fSChristopher Di Bella 263050b064fSChristopher Di Bella template <class _Fp, class _Alloc, class _Rp, class... _ArgTypes> 2649783f28cSLouis Dionne class __func<_Fp, _Alloc, _Rp(_ArgTypes...)> : public __base<_Rp(_ArgTypes...)> { 265050b064fSChristopher Di Bella __alloc_func<_Fp, _Alloc, _Rp(_ArgTypes...)> __f_; 2669783f28cSLouis Dionne 267050b064fSChristopher Di Bella public: 2689783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI explicit __func(_Fp&& __f) : __f_(std::move(__f)) {} 269050b064fSChristopher Di Bella 2709783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI explicit __func(const _Fp& __f, const _Alloc& __a) : __f_(__f, __a) {} 271050b064fSChristopher Di Bella 2729783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI explicit __func(const _Fp& __f, _Alloc&& __a) : __f_(__f, std::move(__a)) {} 273050b064fSChristopher Di Bella 2749783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI explicit __func(_Fp&& __f, _Alloc&& __a) : __f_(std::move(__f), std::move(__a)) {} 275050b064fSChristopher Di Bella 27683ce1397SNikolas Klauser _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual __base<_Rp(_ArgTypes...)>* __clone() const; 27783ce1397SNikolas Klauser _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void __clone(__base<_Rp(_ArgTypes...)>*) const; 27883ce1397SNikolas Klauser _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void destroy() _NOEXCEPT; 27983ce1397SNikolas Klauser _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void destroy_deallocate() _NOEXCEPT; 28083ce1397SNikolas Klauser _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual _Rp operator()(_ArgTypes&&... __arg); 281ba87515fSNikolas Klauser # if _LIBCPP_HAS_RTTI 28283ce1397SNikolas Klauser _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual const void* target(const type_info&) const _NOEXCEPT; 28383ce1397SNikolas Klauser _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual const std::type_info& target_type() const _NOEXCEPT; 284ba87515fSNikolas Klauser # endif // _LIBCPP_HAS_RTTI 285050b064fSChristopher Di Bella }; 286050b064fSChristopher Di Bella 287050b064fSChristopher Di Bella template <class _Fp, class _Alloc, class _Rp, class... _ArgTypes> 2889783f28cSLouis Dionne __base<_Rp(_ArgTypes...)>* __func<_Fp, _Alloc, _Rp(_ArgTypes...)>::__clone() const { 289050b064fSChristopher Di Bella typedef allocator_traits<_Alloc> __alloc_traits; 290d7d586e5SNikolas Klauser typedef __rebind_alloc<__alloc_traits, __func> _Ap; 291050b064fSChristopher Di Bella _Ap __a(__f_.__get_allocator()); 292050b064fSChristopher Di Bella typedef __allocator_destructor<_Ap> _Dp; 293050b064fSChristopher Di Bella unique_ptr<__func, _Dp> __hold(__a.allocate(1), _Dp(__a, 1)); 294050b064fSChristopher Di Bella ::new ((void*)__hold.get()) __func(__f_.__target(), _Alloc(__a)); 295050b064fSChristopher Di Bella return __hold.release(); 296050b064fSChristopher Di Bella } 297050b064fSChristopher Di Bella 298050b064fSChristopher Di Bella template <class _Fp, class _Alloc, class _Rp, class... _ArgTypes> 2999783f28cSLouis Dionne void __func<_Fp, _Alloc, _Rp(_ArgTypes...)>::__clone(__base<_Rp(_ArgTypes...)>* __p) const { 300050b064fSChristopher Di Bella ::new ((void*)__p) __func(__f_.__target(), __f_.__get_allocator()); 301050b064fSChristopher Di Bella } 302050b064fSChristopher Di Bella 303050b064fSChristopher Di Bella template <class _Fp, class _Alloc, class _Rp, class... _ArgTypes> 3049783f28cSLouis Dionne void __func<_Fp, _Alloc, _Rp(_ArgTypes...)>::destroy() _NOEXCEPT { 305050b064fSChristopher Di Bella __f_.destroy(); 306050b064fSChristopher Di Bella } 307050b064fSChristopher Di Bella 308050b064fSChristopher Di Bella template <class _Fp, class _Alloc, class _Rp, class... _ArgTypes> 3099783f28cSLouis Dionne void __func<_Fp, _Alloc, _Rp(_ArgTypes...)>::destroy_deallocate() _NOEXCEPT { 310050b064fSChristopher Di Bella typedef allocator_traits<_Alloc> __alloc_traits; 311d7d586e5SNikolas Klauser typedef __rebind_alloc<__alloc_traits, __func> _Ap; 312050b064fSChristopher Di Bella _Ap __a(__f_.__get_allocator()); 313050b064fSChristopher Di Bella __f_.destroy(); 314050b064fSChristopher Di Bella __a.deallocate(this, 1); 315050b064fSChristopher Di Bella } 316050b064fSChristopher Di Bella 317050b064fSChristopher Di Bella template <class _Fp, class _Alloc, class _Rp, class... _ArgTypes> 3189783f28cSLouis Dionne _Rp __func<_Fp, _Alloc, _Rp(_ArgTypes...)>::operator()(_ArgTypes&&... __arg) { 31977a00c0dSLouis Dionne return __f_(std::forward<_ArgTypes>(__arg)...); 320050b064fSChristopher Di Bella } 321050b064fSChristopher Di Bella 322ba87515fSNikolas Klauser # if _LIBCPP_HAS_RTTI 323050b064fSChristopher Di Bella 324050b064fSChristopher Di Bella template <class _Fp, class _Alloc, class _Rp, class... _ArgTypes> 3259783f28cSLouis Dionne const void* __func<_Fp, _Alloc, _Rp(_ArgTypes...)>::target(const type_info& __ti) const _NOEXCEPT { 326050b064fSChristopher Di Bella if (__ti == typeid(_Fp)) 32777a00c0dSLouis Dionne return std::addressof(__f_.__target()); 328050b064fSChristopher Di Bella return nullptr; 329050b064fSChristopher Di Bella } 330050b064fSChristopher Di Bella 331050b064fSChristopher Di Bella template <class _Fp, class _Alloc, class _Rp, class... _ArgTypes> 3329783f28cSLouis Dionne const std::type_info& __func<_Fp, _Alloc, _Rp(_ArgTypes...)>::target_type() const _NOEXCEPT { 333050b064fSChristopher Di Bella return typeid(_Fp); 334050b064fSChristopher Di Bella } 335050b064fSChristopher Di Bella 336ba87515fSNikolas Klauser # endif // _LIBCPP_HAS_RTTI 337050b064fSChristopher Di Bella 338050b064fSChristopher Di Bella // __value_func creates a value-type from a __func. 339050b064fSChristopher Di Bella 3409783f28cSLouis Dionne template <class _Fp> 3419783f28cSLouis Dionne class __value_func; 342050b064fSChristopher Di Bella 3439783f28cSLouis Dionne template <class _Rp, class... _ArgTypes> 3449783f28cSLouis Dionne class __value_func<_Rp(_ArgTypes...)> { 345987f08feSNikolas Klauser _LIBCPP_SUPPRESS_DEPRECATED_PUSH 346050b064fSChristopher Di Bella typename aligned_storage<3 * sizeof(void*)>::type __buf_; 347987f08feSNikolas Klauser _LIBCPP_SUPPRESS_DEPRECATED_POP 348050b064fSChristopher Di Bella 349050b064fSChristopher Di Bella typedef __base<_Rp(_ArgTypes...)> __func; 350050b064fSChristopher Di Bella __func* __f_; 351050b064fSChristopher Di Bella 3529783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI _LIBCPP_NO_CFI static __func* __as_base(void* __p) { return reinterpret_cast<__func*>(__p); } 353050b064fSChristopher Di Bella 354050b064fSChristopher Di Bella public: 3559783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI __value_func() _NOEXCEPT : __f_(nullptr) {} 356050b064fSChristopher Di Bella 357050b064fSChristopher Di Bella template <class _Fp, class _Alloc> 3589783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI __value_func(_Fp&& __f, const _Alloc& __a) : __f_(nullptr) { 359050b064fSChristopher Di Bella typedef allocator_traits<_Alloc> __alloc_traits; 360050b064fSChristopher Di Bella typedef __function::__func<_Fp, _Alloc, _Rp(_ArgTypes...)> _Fun; 361d7d586e5SNikolas Klauser typedef __rebind_alloc<__alloc_traits, _Fun> _FunAlloc; 362050b064fSChristopher Di Bella 3639783f28cSLouis Dionne if (__function::__not_null(__f)) { 364050b064fSChristopher Di Bella _FunAlloc __af(__a); 3659783f28cSLouis Dionne if (sizeof(_Fun) <= sizeof(__buf_) && is_nothrow_copy_constructible<_Fp>::value && 3669783f28cSLouis Dionne is_nothrow_copy_constructible<_FunAlloc>::value) { 3679783f28cSLouis Dionne __f_ = ::new ((void*)&__buf_) _Fun(std::move(__f), _Alloc(__af)); 3689783f28cSLouis Dionne } else { 369050b064fSChristopher Di Bella typedef __allocator_destructor<_FunAlloc> _Dp; 370050b064fSChristopher Di Bella unique_ptr<__func, _Dp> __hold(__af.allocate(1), _Dp(__af, 1)); 37177a00c0dSLouis Dionne ::new ((void*)__hold.get()) _Fun(std::move(__f), _Alloc(__a)); 372050b064fSChristopher Di Bella __f_ = __hold.release(); 373050b064fSChristopher Di Bella } 374050b064fSChristopher Di Bella } 375050b064fSChristopher Di Bella } 376050b064fSChristopher Di Bella 3776256ccfdSNikolas Klauser template <class _Fp, __enable_if_t<!is_same<__decay_t<_Fp>, __value_func>::value, int> = 0> 3789783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI explicit __value_func(_Fp&& __f) : __value_func(std::forward<_Fp>(__f), allocator<_Fp>()) {} 379050b064fSChristopher Di Bella 3809783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI __value_func(const __value_func& __f) { 381050b064fSChristopher Di Bella if (__f.__f_ == nullptr) 382050b064fSChristopher Di Bella __f_ = nullptr; 3839783f28cSLouis Dionne else if ((void*)__f.__f_ == &__f.__buf_) { 384050b064fSChristopher Di Bella __f_ = __as_base(&__buf_); 385050b064fSChristopher Di Bella __f.__f_->__clone(__f_); 3869783f28cSLouis Dionne } else 387050b064fSChristopher Di Bella __f_ = __f.__f_->__clone(); 388050b064fSChristopher Di Bella } 389050b064fSChristopher Di Bella 3909783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI __value_func(__value_func&& __f) _NOEXCEPT { 391050b064fSChristopher Di Bella if (__f.__f_ == nullptr) 392050b064fSChristopher Di Bella __f_ = nullptr; 3939783f28cSLouis Dionne else if ((void*)__f.__f_ == &__f.__buf_) { 394050b064fSChristopher Di Bella __f_ = __as_base(&__buf_); 395050b064fSChristopher Di Bella __f.__f_->__clone(__f_); 3969783f28cSLouis Dionne } else { 397050b064fSChristopher Di Bella __f_ = __f.__f_; 398050b064fSChristopher Di Bella __f.__f_ = nullptr; 399050b064fSChristopher Di Bella } 400050b064fSChristopher Di Bella } 401050b064fSChristopher Di Bella 4029783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI ~__value_func() { 403050b064fSChristopher Di Bella if ((void*)__f_ == &__buf_) 404050b064fSChristopher Di Bella __f_->destroy(); 405050b064fSChristopher Di Bella else if (__f_) 406050b064fSChristopher Di Bella __f_->destroy_deallocate(); 407050b064fSChristopher Di Bella } 408050b064fSChristopher Di Bella 4099783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI __value_func& operator=(__value_func&& __f) { 410050b064fSChristopher Di Bella *this = nullptr; 411050b064fSChristopher Di Bella if (__f.__f_ == nullptr) 412050b064fSChristopher Di Bella __f_ = nullptr; 4139783f28cSLouis Dionne else if ((void*)__f.__f_ == &__f.__buf_) { 414050b064fSChristopher Di Bella __f_ = __as_base(&__buf_); 415050b064fSChristopher Di Bella __f.__f_->__clone(__f_); 4169783f28cSLouis Dionne } else { 417050b064fSChristopher Di Bella __f_ = __f.__f_; 418050b064fSChristopher Di Bella __f.__f_ = nullptr; 419050b064fSChristopher Di Bella } 420050b064fSChristopher Di Bella return *this; 421050b064fSChristopher Di Bella } 422050b064fSChristopher Di Bella 4239783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI __value_func& operator=(nullptr_t) { 424050b064fSChristopher Di Bella __func* __f = __f_; 425050b064fSChristopher Di Bella __f_ = nullptr; 426050b064fSChristopher Di Bella if ((void*)__f == &__buf_) 427050b064fSChristopher Di Bella __f->destroy(); 428050b064fSChristopher Di Bella else if (__f) 429050b064fSChristopher Di Bella __f->destroy_deallocate(); 430050b064fSChristopher Di Bella return *this; 431050b064fSChristopher Di Bella } 432050b064fSChristopher Di Bella 4339783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI _Rp operator()(_ArgTypes&&... __args) const { 434050b064fSChristopher Di Bella if (__f_ == nullptr) 435050b064fSChristopher Di Bella __throw_bad_function_call(); 43677a00c0dSLouis Dionne return (*__f_)(std::forward<_ArgTypes>(__args)...); 437050b064fSChristopher Di Bella } 438050b064fSChristopher Di Bella 4399783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI void swap(__value_func& __f) _NOEXCEPT { 440050b064fSChristopher Di Bella if (&__f == this) 441050b064fSChristopher Di Bella return; 4429783f28cSLouis Dionne if ((void*)__f_ == &__buf_ && (void*)__f.__f_ == &__f.__buf_) { 443987f08feSNikolas Klauser _LIBCPP_SUPPRESS_DEPRECATED_PUSH 444050b064fSChristopher Di Bella typename aligned_storage<sizeof(__buf_)>::type __tempbuf; 445987f08feSNikolas Klauser _LIBCPP_SUPPRESS_DEPRECATED_POP 446050b064fSChristopher Di Bella __func* __t = __as_base(&__tempbuf); 447050b064fSChristopher Di Bella __f_->__clone(__t); 448050b064fSChristopher Di Bella __f_->destroy(); 449050b064fSChristopher Di Bella __f_ = nullptr; 450050b064fSChristopher Di Bella __f.__f_->__clone(__as_base(&__buf_)); 451050b064fSChristopher Di Bella __f.__f_->destroy(); 452050b064fSChristopher Di Bella __f.__f_ = nullptr; 453050b064fSChristopher Di Bella __f_ = __as_base(&__buf_); 454050b064fSChristopher Di Bella __t->__clone(__as_base(&__f.__buf_)); 455050b064fSChristopher Di Bella __t->destroy(); 456050b064fSChristopher Di Bella __f.__f_ = __as_base(&__f.__buf_); 4579783f28cSLouis Dionne } else if ((void*)__f_ == &__buf_) { 458050b064fSChristopher Di Bella __f_->__clone(__as_base(&__f.__buf_)); 459050b064fSChristopher Di Bella __f_->destroy(); 460050b064fSChristopher Di Bella __f_ = __f.__f_; 461050b064fSChristopher Di Bella __f.__f_ = __as_base(&__f.__buf_); 4629783f28cSLouis Dionne } else if ((void*)__f.__f_ == &__f.__buf_) { 463050b064fSChristopher Di Bella __f.__f_->__clone(__as_base(&__buf_)); 464050b064fSChristopher Di Bella __f.__f_->destroy(); 465050b064fSChristopher Di Bella __f.__f_ = __f_; 466050b064fSChristopher Di Bella __f_ = __as_base(&__buf_); 4679783f28cSLouis Dionne } else 46877a00c0dSLouis Dionne std::swap(__f_, __f.__f_); 469050b064fSChristopher Di Bella } 470050b064fSChristopher Di Bella 4719783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI explicit operator bool() const _NOEXCEPT { return __f_ != nullptr; } 472050b064fSChristopher Di Bella 473ba87515fSNikolas Klauser # if _LIBCPP_HAS_RTTI 4749783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI const std::type_info& target_type() const _NOEXCEPT { 475050b064fSChristopher Di Bella if (__f_ == nullptr) 476050b064fSChristopher Di Bella return typeid(void); 477050b064fSChristopher Di Bella return __f_->target_type(); 478050b064fSChristopher Di Bella } 479050b064fSChristopher Di Bella 480050b064fSChristopher Di Bella template <typename _Tp> 4819783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI const _Tp* target() const _NOEXCEPT { 482050b064fSChristopher Di Bella if (__f_ == nullptr) 483050b064fSChristopher Di Bella return nullptr; 484050b064fSChristopher Di Bella return (const _Tp*)__f_->target(typeid(_Tp)); 485050b064fSChristopher Di Bella } 486ba87515fSNikolas Klauser # endif // _LIBCPP_HAS_RTTI 487050b064fSChristopher Di Bella }; 488050b064fSChristopher Di Bella 489050b064fSChristopher Di Bella // Storage for a functor object, to be used with __policy to manage copy and 490050b064fSChristopher Di Bella // destruction. 4919783f28cSLouis Dionne union __policy_storage { 492050b064fSChristopher Di Bella mutable char __small[sizeof(void*) * 2]; 493050b064fSChristopher Di Bella void* __large; 494050b064fSChristopher Di Bella }; 495050b064fSChristopher Di Bella 496050b064fSChristopher Di Bella // True if _Fun can safely be held in __policy_storage.__small. 497050b064fSChristopher Di Bella template <typename _Fun> 498050b064fSChristopher Di Bella struct __use_small_storage 499050b064fSChristopher Di Bella : public integral_constant< 5009783f28cSLouis Dionne bool, 5019783f28cSLouis Dionne sizeof(_Fun) <= sizeof(__policy_storage)&& _LIBCPP_ALIGNOF(_Fun) <= _LIBCPP_ALIGNOF(__policy_storage) && 5029783f28cSLouis Dionne is_trivially_copy_constructible<_Fun>::value && is_trivially_destructible<_Fun>::value> {}; 503050b064fSChristopher Di Bella 504050b064fSChristopher Di Bella // Policy contains information about how to copy, destroy, and move the 505050b064fSChristopher Di Bella // underlying functor. You can think of it as a vtable of sorts. 5069783f28cSLouis Dionne struct __policy { 507050b064fSChristopher Di Bella // Used to copy or destroy __large values. null for trivial objects. 508050b064fSChristopher Di Bella void* (*const __clone)(const void*); 509050b064fSChristopher Di Bella void (*const __destroy)(void*); 510050b064fSChristopher Di Bella 511050b064fSChristopher Di Bella // True if this is the null policy (no value). 512050b064fSChristopher Di Bella const bool __is_null; 513050b064fSChristopher Di Bella 514050b064fSChristopher Di Bella // The target type. May be null if RTTI is disabled. 515050b064fSChristopher Di Bella const std::type_info* const __type_info; 516050b064fSChristopher Di Bella 517050b064fSChristopher Di Bella // Returns a pointer to a static policy object suitable for the functor 518050b064fSChristopher Di Bella // type. 519050b064fSChristopher Di Bella template <typename _Fun> 5209783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI static const __policy* __create() { 521050b064fSChristopher Di Bella return __choose_policy<_Fun>(__use_small_storage<_Fun>()); 522050b064fSChristopher Di Bella } 523050b064fSChristopher Di Bella 5249783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI static const __policy* __create_empty() { 5251f98ac09SNikolas Klauser static constexpr __policy __policy = { 5269783f28cSLouis Dionne nullptr, 5279783f28cSLouis Dionne nullptr, 528050b064fSChristopher Di Bella true, 529ba87515fSNikolas Klauser # if _LIBCPP_HAS_RTTI 530050b064fSChristopher Di Bella &typeid(void) 531050b064fSChristopher Di Bella # else 532050b064fSChristopher Di Bella nullptr 533050b064fSChristopher Di Bella # endif 534050b064fSChristopher Di Bella }; 535d05f8895SNikolas Klauser return &__policy; 536050b064fSChristopher Di Bella } 537050b064fSChristopher Di Bella 538050b064fSChristopher Di Bella private: 53983ce1397SNikolas Klauser template <typename _Fun> 5409783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI static void* __large_clone(const void* __s) { 541050b064fSChristopher Di Bella const _Fun* __f = static_cast<const _Fun*>(__s); 542050b064fSChristopher Di Bella return __f->__clone(); 543050b064fSChristopher Di Bella } 544050b064fSChristopher Di Bella 545050b064fSChristopher Di Bella template <typename _Fun> 54683ce1397SNikolas Klauser _LIBCPP_HIDE_FROM_ABI static void __large_destroy(void* __s) { 547050b064fSChristopher Di Bella _Fun::__destroy_and_delete(static_cast<_Fun*>(__s)); 548050b064fSChristopher Di Bella } 549050b064fSChristopher Di Bella 550050b064fSChristopher Di Bella template <typename _Fun> 5519783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI static const __policy* __choose_policy(/* is_small = */ false_type) { 5521f98ac09SNikolas Klauser static constexpr __policy __policy = { 5539783f28cSLouis Dionne &__large_clone<_Fun>, 5549783f28cSLouis Dionne &__large_destroy<_Fun>, 5559783f28cSLouis Dionne false, 556ba87515fSNikolas Klauser # if _LIBCPP_HAS_RTTI 557050b064fSChristopher Di Bella &typeid(typename _Fun::_Target) 558050b064fSChristopher Di Bella # else 559050b064fSChristopher Di Bella nullptr 560050b064fSChristopher Di Bella # endif 561050b064fSChristopher Di Bella }; 562d05f8895SNikolas Klauser return &__policy; 563050b064fSChristopher Di Bella } 564050b064fSChristopher Di Bella 565050b064fSChristopher Di Bella template <typename _Fun> 5669783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI static const __policy* __choose_policy(/* is_small = */ true_type) { 5671f98ac09SNikolas Klauser static constexpr __policy __policy = { 5689783f28cSLouis Dionne nullptr, 5699783f28cSLouis Dionne nullptr, 5709783f28cSLouis Dionne false, 571ba87515fSNikolas Klauser # if _LIBCPP_HAS_RTTI 572050b064fSChristopher Di Bella &typeid(typename _Fun::_Target) 573050b064fSChristopher Di Bella # else 574050b064fSChristopher Di Bella nullptr 575050b064fSChristopher Di Bella # endif 576050b064fSChristopher Di Bella }; 577d05f8895SNikolas Klauser return &__policy; 578050b064fSChristopher Di Bella } 579050b064fSChristopher Di Bella }; 580050b064fSChristopher Di Bella 581050b064fSChristopher Di Bella // Used to choose between perfect forwarding or pass-by-value. Pass-by-value is 582050b064fSChristopher Di Bella // faster for types that can be passed in registers. 583050b064fSChristopher Di Bella template <typename _Tp> 584f6958523SNikolas Klauser using __fast_forward _LIBCPP_NODEBUG = __conditional_t<is_scalar<_Tp>::value, _Tp, _Tp&&>; 585050b064fSChristopher Di Bella 586050b064fSChristopher Di Bella // __policy_invoker calls an instance of __alloc_func held in __policy_storage. 587050b064fSChristopher Di Bella 5889783f28cSLouis Dionne template <class _Fp> 5899783f28cSLouis Dionne struct __policy_invoker; 590050b064fSChristopher Di Bella 591050b064fSChristopher Di Bella template <class _Rp, class... _ArgTypes> 5929783f28cSLouis Dionne struct __policy_invoker<_Rp(_ArgTypes...)> { 5939783f28cSLouis Dionne typedef _Rp (*__Call)(const __policy_storage*, __fast_forward<_ArgTypes>...); 594050b064fSChristopher Di Bella 595050b064fSChristopher Di Bella __Call __call_; 596050b064fSChristopher Di Bella 597050b064fSChristopher Di Bella // Creates an invoker that throws bad_function_call. 5989783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI __policy_invoker() : __call_(&__call_empty) {} 599050b064fSChristopher Di Bella 600050b064fSChristopher Di Bella // Creates an invoker that calls the given instance of __func. 601050b064fSChristopher Di Bella template <typename _Fun> 6029783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI static __policy_invoker __create() { 603050b064fSChristopher Di Bella return __policy_invoker(&__call_impl<_Fun>); 604050b064fSChristopher Di Bella } 605050b064fSChristopher Di Bella 606050b064fSChristopher Di Bella private: 6079783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI explicit __policy_invoker(__Call __c) : __call_(__c) {} 608050b064fSChristopher Di Bella 6099783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI static _Rp __call_empty(const __policy_storage*, __fast_forward<_ArgTypes>...) { 610050b064fSChristopher Di Bella __throw_bad_function_call(); 611050b064fSChristopher Di Bella } 612050b064fSChristopher Di Bella 613050b064fSChristopher Di Bella template <typename _Fun> 6149783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI static _Rp __call_impl(const __policy_storage* __buf, __fast_forward<_ArgTypes>... __args) { 6159783f28cSLouis Dionne _Fun* __f = reinterpret_cast<_Fun*>(__use_small_storage<_Fun>::value ? &__buf->__small : __buf->__large); 61677a00c0dSLouis Dionne return (*__f)(std::forward<_ArgTypes>(__args)...); 617050b064fSChristopher Di Bella } 618050b064fSChristopher Di Bella }; 619050b064fSChristopher Di Bella 620050b064fSChristopher Di Bella // __policy_func uses a __policy and __policy_invoker to create a type-erased, 621050b064fSChristopher Di Bella // copyable functor. 622050b064fSChristopher Di Bella 6239783f28cSLouis Dionne template <class _Fp> 6249783f28cSLouis Dionne class __policy_func; 625050b064fSChristopher Di Bella 6269783f28cSLouis Dionne template <class _Rp, class... _ArgTypes> 6279783f28cSLouis Dionne class __policy_func<_Rp(_ArgTypes...)> { 628050b064fSChristopher Di Bella // Inline storage for small objects. 629050b064fSChristopher Di Bella __policy_storage __buf_; 630050b064fSChristopher Di Bella 631050b064fSChristopher Di Bella // Calls the value stored in __buf_. This could technically be part of 632050b064fSChristopher Di Bella // policy, but storing it here eliminates a level of indirection inside 633050b064fSChristopher Di Bella // operator(). 634050b064fSChristopher Di Bella typedef __function::__policy_invoker<_Rp(_ArgTypes...)> __invoker; 635050b064fSChristopher Di Bella __invoker __invoker_; 636050b064fSChristopher Di Bella 637050b064fSChristopher Di Bella // The policy that describes how to move / copy / destroy __buf_. Never 638050b064fSChristopher Di Bella // null, even if the function is empty. 639050b064fSChristopher Di Bella const __policy* __policy_; 640050b064fSChristopher Di Bella 641050b064fSChristopher Di Bella public: 6429783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI __policy_func() : __policy_(__policy::__create_empty()) {} 643050b064fSChristopher Di Bella 644050b064fSChristopher Di Bella template <class _Fp, class _Alloc> 6459783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI __policy_func(_Fp&& __f, const _Alloc& __a) : __policy_(__policy::__create_empty()) { 646050b064fSChristopher Di Bella typedef __alloc_func<_Fp, _Alloc, _Rp(_ArgTypes...)> _Fun; 647050b064fSChristopher Di Bella typedef allocator_traits<_Alloc> __alloc_traits; 648d7d586e5SNikolas Klauser typedef __rebind_alloc<__alloc_traits, _Fun> _FunAlloc; 649050b064fSChristopher Di Bella 6509783f28cSLouis Dionne if (__function::__not_null(__f)) { 651050b064fSChristopher Di Bella __invoker_ = __invoker::template __create<_Fun>(); 652050b064fSChristopher Di Bella __policy_ = __policy::__create<_Fun>(); 653050b064fSChristopher Di Bella 654050b064fSChristopher Di Bella _FunAlloc __af(__a); 6559783f28cSLouis Dionne if (__use_small_storage<_Fun>()) { 6569783f28cSLouis Dionne ::new ((void*)&__buf_.__small) _Fun(std::move(__f), _Alloc(__af)); 6579783f28cSLouis Dionne } else { 658050b064fSChristopher Di Bella typedef __allocator_destructor<_FunAlloc> _Dp; 659050b064fSChristopher Di Bella unique_ptr<_Fun, _Dp> __hold(__af.allocate(1), _Dp(__af, 1)); 6609783f28cSLouis Dionne ::new ((void*)__hold.get()) _Fun(std::move(__f), _Alloc(__af)); 661050b064fSChristopher Di Bella __buf_.__large = __hold.release(); 662050b064fSChristopher Di Bella } 663050b064fSChristopher Di Bella } 664050b064fSChristopher Di Bella } 665050b064fSChristopher Di Bella 6666256ccfdSNikolas Klauser template <class _Fp, __enable_if_t<!is_same<__decay_t<_Fp>, __policy_func>::value, int> = 0> 6679783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI explicit __policy_func(_Fp&& __f) : __policy_(__policy::__create_empty()) { 668050b064fSChristopher Di Bella typedef __default_alloc_func<_Fp, _Rp(_ArgTypes...)> _Fun; 669050b064fSChristopher Di Bella 670050b064fSChristopher Di Bella if (__function::__not_null(__f)) { 671050b064fSChristopher Di Bella __invoker_ = __invoker::template __create<_Fun>(); 672050b064fSChristopher Di Bella __policy_ = __policy::__create<_Fun>(); 673050b064fSChristopher Di Bella if (__use_small_storage<_Fun>()) { 67477a00c0dSLouis Dionne ::new ((void*)&__buf_.__small) _Fun(std::move(__f)); 675050b064fSChristopher Di Bella } else { 676cedb44afSLouis Dionne unique_ptr<_Fun, __deallocating_deleter<_Fun>> __hold(std::__libcpp_allocate<_Fun>(__element_count(1))); 67777a00c0dSLouis Dionne __buf_.__large = ::new ((void*)__hold.get()) _Fun(std::move(__f)); 678050b064fSChristopher Di Bella (void)__hold.release(); 679050b064fSChristopher Di Bella } 680050b064fSChristopher Di Bella } 681050b064fSChristopher Di Bella } 682050b064fSChristopher Di Bella 6839783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI __policy_func(const __policy_func& __f) 6849783f28cSLouis Dionne : __buf_(__f.__buf_), __invoker_(__f.__invoker_), __policy_(__f.__policy_) { 685050b064fSChristopher Di Bella if (__policy_->__clone) 686050b064fSChristopher Di Bella __buf_.__large = __policy_->__clone(__f.__buf_.__large); 687050b064fSChristopher Di Bella } 688050b064fSChristopher Di Bella 6899783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI __policy_func(__policy_func&& __f) 6909783f28cSLouis Dionne : __buf_(__f.__buf_), __invoker_(__f.__invoker_), __policy_(__f.__policy_) { 6919783f28cSLouis Dionne if (__policy_->__destroy) { 692050b064fSChristopher Di Bella __f.__policy_ = __policy::__create_empty(); 693050b064fSChristopher Di Bella __f.__invoker_ = __invoker(); 694050b064fSChristopher Di Bella } 695050b064fSChristopher Di Bella } 696050b064fSChristopher Di Bella 6979783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI ~__policy_func() { 698050b064fSChristopher Di Bella if (__policy_->__destroy) 699050b064fSChristopher Di Bella __policy_->__destroy(__buf_.__large); 700050b064fSChristopher Di Bella } 701050b064fSChristopher Di Bella 7029783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI __policy_func& operator=(__policy_func&& __f) { 703050b064fSChristopher Di Bella *this = nullptr; 704050b064fSChristopher Di Bella __buf_ = __f.__buf_; 705050b064fSChristopher Di Bella __invoker_ = __f.__invoker_; 706050b064fSChristopher Di Bella __policy_ = __f.__policy_; 707050b064fSChristopher Di Bella __f.__policy_ = __policy::__create_empty(); 708050b064fSChristopher Di Bella __f.__invoker_ = __invoker(); 709050b064fSChristopher Di Bella return *this; 710050b064fSChristopher Di Bella } 711050b064fSChristopher Di Bella 7129783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI __policy_func& operator=(nullptr_t) { 713050b064fSChristopher Di Bella const __policy* __p = __policy_; 714050b064fSChristopher Di Bella __policy_ = __policy::__create_empty(); 715050b064fSChristopher Di Bella __invoker_ = __invoker(); 716050b064fSChristopher Di Bella if (__p->__destroy) 717050b064fSChristopher Di Bella __p->__destroy(__buf_.__large); 718050b064fSChristopher Di Bella return *this; 719050b064fSChristopher Di Bella } 720050b064fSChristopher Di Bella 7219783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI _Rp operator()(_ArgTypes&&... __args) const { 7229783f28cSLouis Dionne return __invoker_.__call_(std::addressof(__buf_), std::forward<_ArgTypes>(__args)...); 723050b064fSChristopher Di Bella } 724050b064fSChristopher Di Bella 7259783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI void swap(__policy_func& __f) { 72677a00c0dSLouis Dionne std::swap(__invoker_, __f.__invoker_); 72777a00c0dSLouis Dionne std::swap(__policy_, __f.__policy_); 72877a00c0dSLouis Dionne std::swap(__buf_, __f.__buf_); 729050b064fSChristopher Di Bella } 730050b064fSChristopher Di Bella 7319783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI explicit operator bool() const _NOEXCEPT { return !__policy_->__is_null; } 732050b064fSChristopher Di Bella 733ba87515fSNikolas Klauser # if _LIBCPP_HAS_RTTI 7349783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI const std::type_info& target_type() const _NOEXCEPT { return *__policy_->__type_info; } 735050b064fSChristopher Di Bella 736050b064fSChristopher Di Bella template <typename _Tp> 7379783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI const _Tp* target() const _NOEXCEPT { 738050b064fSChristopher Di Bella if (__policy_->__is_null || typeid(_Tp) != *__policy_->__type_info) 739050b064fSChristopher Di Bella return nullptr; 740050b064fSChristopher Di Bella if (__policy_->__clone) // Out of line storage. 741050b064fSChristopher Di Bella return reinterpret_cast<const _Tp*>(__buf_.__large); 742050b064fSChristopher Di Bella else 743050b064fSChristopher Di Bella return reinterpret_cast<const _Tp*>(&__buf_.__small); 744050b064fSChristopher Di Bella } 745ba87515fSNikolas Klauser # endif // _LIBCPP_HAS_RTTI 746050b064fSChristopher Di Bella }; 747050b064fSChristopher Di Bella 748ba87515fSNikolas Klauser # if _LIBCPP_HAS_BLOCKS_RUNTIME 749050b064fSChristopher Di Bella 750050b064fSChristopher Di Bella extern "C" void* _Block_copy(const void*); 751050b064fSChristopher Di Bella extern "C" void _Block_release(const void*); 752050b064fSChristopher Di Bella 753050b064fSChristopher Di Bella template <class _Rp1, class... _ArgTypes1, class _Alloc, class _Rp, class... _ArgTypes> 7549783f28cSLouis Dionne class __func<_Rp1 (^)(_ArgTypes1...), _Alloc, _Rp(_ArgTypes...)> : public __base<_Rp(_ArgTypes...)> { 755050b064fSChristopher Di Bella typedef _Rp1 (^__block_type)(_ArgTypes1...); 756050b064fSChristopher Di Bella __block_type __f_; 757050b064fSChristopher Di Bella 758050b064fSChristopher Di Bella public: 7599783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI explicit __func(__block_type const& __f) 760ba87515fSNikolas Klauser # if _LIBCPP_HAS_OBJC_ARC 7610e4802bfSLouis Dionne : __f_(__f) 7620e4802bfSLouis Dionne # else 763050b064fSChristopher Di Bella : __f_(reinterpret_cast<__block_type>(__f ? _Block_copy(__f) : nullptr)) 7640e4802bfSLouis Dionne # endif 7659783f28cSLouis Dionne { 7669783f28cSLouis Dionne } 767050b064fSChristopher Di Bella 768050b064fSChristopher Di Bella // [TODO] add && to save on a retain 769050b064fSChristopher Di Bella 7709783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI explicit __func(__block_type __f, const _Alloc& /* unused */) 771ba87515fSNikolas Klauser # if _LIBCPP_HAS_OBJC_ARC 7720e4802bfSLouis Dionne : __f_(__f) 7730e4802bfSLouis Dionne # else 774050b064fSChristopher Di Bella : __f_(reinterpret_cast<__block_type>(__f ? _Block_copy(__f) : nullptr)) 7750e4802bfSLouis Dionne # endif 7769783f28cSLouis Dionne { 7779783f28cSLouis Dionne } 778050b064fSChristopher Di Bella 7796cc8d54aSLouis Dionne _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual __base<_Rp(_ArgTypes...)>* __clone() const { 7809783f28cSLouis Dionne _LIBCPP_ASSERT_INTERNAL( 7819783f28cSLouis Dionne false, 782050b064fSChristopher Di Bella "Block pointers are just pointers, so they should always fit into " 783050b064fSChristopher Di Bella "std::function's small buffer optimization. This function should " 784050b064fSChristopher Di Bella "never be invoked."); 785050b064fSChristopher Di Bella return nullptr; 786050b064fSChristopher Di Bella } 787050b064fSChristopher Di Bella 7886cc8d54aSLouis Dionne _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void __clone(__base<_Rp(_ArgTypes...)>* __p) const { 7896cc8d54aSLouis Dionne ::new ((void*)__p) __func(__f_); 7906cc8d54aSLouis Dionne } 791050b064fSChristopher Di Bella 7926cc8d54aSLouis Dionne _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void destroy() _NOEXCEPT { 793ba87515fSNikolas Klauser # if !_LIBCPP_HAS_OBJC_ARC 794050b064fSChristopher Di Bella if (__f_) 795050b064fSChristopher Di Bella _Block_release(__f_); 7960e4802bfSLouis Dionne # endif 797050b064fSChristopher Di Bella __f_ = 0; 798050b064fSChristopher Di Bella } 799050b064fSChristopher Di Bella 8006cc8d54aSLouis Dionne _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void destroy_deallocate() _NOEXCEPT { 8019783f28cSLouis Dionne _LIBCPP_ASSERT_INTERNAL( 8029783f28cSLouis Dionne false, 803050b064fSChristopher Di Bella "Block pointers are just pointers, so they should always fit into " 804050b064fSChristopher Di Bella "std::function's small buffer optimization. This function should " 805050b064fSChristopher Di Bella "never be invoked."); 806050b064fSChristopher Di Bella } 807050b064fSChristopher Di Bella 8086cc8d54aSLouis Dionne _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual _Rp operator()(_ArgTypes&&... __arg) { 8096cc8d54aSLouis Dionne return std::__invoke(__f_, std::forward<_ArgTypes>(__arg)...); 8106cc8d54aSLouis Dionne } 811050b064fSChristopher Di Bella 812ba87515fSNikolas Klauser # if _LIBCPP_HAS_RTTI 8136cc8d54aSLouis Dionne _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual const void* target(type_info const& __ti) const _NOEXCEPT { 814050b064fSChristopher Di Bella if (__ti == typeid(__func::__block_type)) 815050b064fSChristopher Di Bella return &__f_; 816050b064fSChristopher Di Bella return (const void*)nullptr; 817050b064fSChristopher Di Bella } 818050b064fSChristopher Di Bella 8196cc8d54aSLouis Dionne _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual const std::type_info& target_type() const _NOEXCEPT { 8206cc8d54aSLouis Dionne return typeid(__func::__block_type); 8216cc8d54aSLouis Dionne } 822ba87515fSNikolas Klauser # endif // _LIBCPP_HAS_RTTI 823050b064fSChristopher Di Bella }; 824050b064fSChristopher Di Bella 8250e4802bfSLouis Dionne # endif // _LIBCPP_HAS_EXTENSION_BLOCKS 826050b064fSChristopher Di Bella 827d2b0df35SNikolas Klauser } // namespace __function 828050b064fSChristopher Di Bella 829050b064fSChristopher Di Bella template <class _Rp, class... _ArgTypes> 830050b064fSChristopher Di Bella class _LIBCPP_TEMPLATE_VIS function<_Rp(_ArgTypes...)> 831050b064fSChristopher Di Bella : public __function::__maybe_derive_from_unary_function<_Rp(_ArgTypes...)>, 8329783f28cSLouis Dionne public __function::__maybe_derive_from_binary_function<_Rp(_ArgTypes...)> { 833050b064fSChristopher Di Bella # ifndef _LIBCPP_ABI_OPTIMIZED_FUNCTION 834050b064fSChristopher Di Bella typedef __function::__value_func<_Rp(_ArgTypes...)> __func; 835050b064fSChristopher Di Bella # else 836050b064fSChristopher Di Bella typedef __function::__policy_func<_Rp(_ArgTypes...)> __func; 837050b064fSChristopher Di Bella # endif 838050b064fSChristopher Di Bella 839050b064fSChristopher Di Bella __func __f_; 840050b064fSChristopher Di Bella 8419783f28cSLouis Dionne template <class _Fp, 842*0fa05456SNikolas Klauser bool = _And<_IsNotSame<__remove_cvref_t<_Fp>, function>, __is_invocable<_Fp, _ArgTypes...> >::value> 843050b064fSChristopher Di Bella struct __callable; 844050b064fSChristopher Di Bella template <class _Fp> 8459783f28cSLouis Dionne struct __callable<_Fp, true> { 8469783f28cSLouis Dionne static const bool value = 847*0fa05456SNikolas Klauser is_void<_Rp>::value || __is_core_convertible<__invoke_result_t<_Fp, _ArgTypes...>, _Rp>::value; 848050b064fSChristopher Di Bella }; 849050b064fSChristopher Di Bella template <class _Fp> 8509783f28cSLouis Dionne struct __callable<_Fp, false> { 851050b064fSChristopher Di Bella static const bool value = false; 852050b064fSChristopher Di Bella }; 853050b064fSChristopher Di Bella 854050b064fSChristopher Di Bella template <class _Fp> 855f6958523SNikolas Klauser using _EnableIfLValueCallable _LIBCPP_NODEBUG = __enable_if_t<__callable<_Fp&>::value>; 8569783f28cSLouis Dionne 857050b064fSChristopher Di Bella public: 858050b064fSChristopher Di Bella typedef _Rp result_type; 859050b064fSChristopher Di Bella 860050b064fSChristopher Di Bella // construct/copy/destroy: 8619783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI function() _NOEXCEPT {} 862dab6463eSLoS _LIBCPP_HIDE_FROM_ABI function(nullptr_t) _NOEXCEPT {} 86383ce1397SNikolas Klauser _LIBCPP_HIDE_FROM_ABI function(const function&); 86483ce1397SNikolas Klauser _LIBCPP_HIDE_FROM_ABI function(function&&) _NOEXCEPT; 865050b064fSChristopher Di Bella template <class _Fp, class = _EnableIfLValueCallable<_Fp>> 86683ce1397SNikolas Klauser _LIBCPP_HIDE_FROM_ABI function(_Fp); 867050b064fSChristopher Di Bella 868050b064fSChristopher Di Bella # if _LIBCPP_STD_VER <= 14 869050b064fSChristopher Di Bella template <class _Alloc> 8709783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI function(allocator_arg_t, const _Alloc&) _NOEXCEPT {} 871050b064fSChristopher Di Bella template <class _Alloc> 8729783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI function(allocator_arg_t, const _Alloc&, nullptr_t) _NOEXCEPT {} 873050b064fSChristopher Di Bella template <class _Alloc> 87483ce1397SNikolas Klauser _LIBCPP_HIDE_FROM_ABI function(allocator_arg_t, const _Alloc&, const function&); 875050b064fSChristopher Di Bella template <class _Alloc> 87683ce1397SNikolas Klauser _LIBCPP_HIDE_FROM_ABI function(allocator_arg_t, const _Alloc&, function&&); 877050b064fSChristopher Di Bella template <class _Fp, class _Alloc, class = _EnableIfLValueCallable<_Fp>> 87883ce1397SNikolas Klauser _LIBCPP_HIDE_FROM_ABI function(allocator_arg_t, const _Alloc& __a, _Fp __f); 879050b064fSChristopher Di Bella # endif 880050b064fSChristopher Di Bella 88183ce1397SNikolas Klauser _LIBCPP_HIDE_FROM_ABI function& operator=(const function&); 88283ce1397SNikolas Klauser _LIBCPP_HIDE_FROM_ABI function& operator=(function&&) _NOEXCEPT; 88383ce1397SNikolas Klauser _LIBCPP_HIDE_FROM_ABI function& operator=(nullptr_t) _NOEXCEPT; 884173476eaSNikolas Klauser template <class _Fp, class = _EnableIfLValueCallable<__decay_t<_Fp>>> 88583ce1397SNikolas Klauser _LIBCPP_HIDE_FROM_ABI function& operator=(_Fp&&); 886050b064fSChristopher Di Bella 88783ce1397SNikolas Klauser _LIBCPP_HIDE_FROM_ABI ~function(); 888050b064fSChristopher Di Bella 889050b064fSChristopher Di Bella // function modifiers: 89083ce1397SNikolas Klauser _LIBCPP_HIDE_FROM_ABI void swap(function&) _NOEXCEPT; 891050b064fSChristopher Di Bella 892050b064fSChristopher Di Bella # if _LIBCPP_STD_VER <= 14 893050b064fSChristopher Di Bella template <class _Fp, class _Alloc> 8949783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI void assign(_Fp&& __f, const _Alloc& __a) { 8959783f28cSLouis Dionne function(allocator_arg, __a, std::forward<_Fp>(__f)).swap(*this); 8969783f28cSLouis Dionne } 897050b064fSChristopher Di Bella # endif 898050b064fSChristopher Di Bella 899050b064fSChristopher Di Bella // function capacity: 9009783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI explicit operator bool() const _NOEXCEPT { return static_cast<bool>(__f_); } 901050b064fSChristopher Di Bella 902050b064fSChristopher Di Bella // deleted overloads close possible hole in the type system 903050b064fSChristopher Di Bella template <class _R2, class... _ArgTypes2> 904050b064fSChristopher Di Bella bool operator==(const function<_R2(_ArgTypes2...)>&) const = delete; 9059a6ca673SHristo Hristov # if _LIBCPP_STD_VER <= 17 906050b064fSChristopher Di Bella template <class _R2, class... _ArgTypes2> 907050b064fSChristopher Di Bella bool operator!=(const function<_R2(_ArgTypes2...)>&) const = delete; 9089a6ca673SHristo Hristov # endif 9099783f28cSLouis Dionne 910050b064fSChristopher Di Bella public: 911050b064fSChristopher Di Bella // function invocation: 91283ce1397SNikolas Klauser _LIBCPP_HIDE_FROM_ABI _Rp operator()(_ArgTypes...) const; 913050b064fSChristopher Di Bella 914ba87515fSNikolas Klauser # if _LIBCPP_HAS_RTTI 915050b064fSChristopher Di Bella // function target access: 91683ce1397SNikolas Klauser _LIBCPP_HIDE_FROM_ABI const std::type_info& target_type() const _NOEXCEPT; 91783ce1397SNikolas Klauser template <typename _Tp> 91883ce1397SNikolas Klauser _LIBCPP_HIDE_FROM_ABI _Tp* target() _NOEXCEPT; 91983ce1397SNikolas Klauser template <typename _Tp> 92083ce1397SNikolas Klauser _LIBCPP_HIDE_FROM_ABI const _Tp* target() const _NOEXCEPT; 921ba87515fSNikolas Klauser # endif // _LIBCPP_HAS_RTTI 922050b064fSChristopher Di Bella }; 923050b064fSChristopher Di Bella 92401666904SLouis Dionne # if _LIBCPP_STD_VER >= 17 925050b064fSChristopher Di Bella template <class _Rp, class... _Ap> 926050b064fSChristopher Di Bella function(_Rp (*)(_Ap...)) -> function<_Rp(_Ap...)>; 927050b064fSChristopher Di Bella 928050b064fSChristopher Di Bella template <class _Fp, class _Stripped = typename __strip_signature<decltype(&_Fp::operator())>::type> 929050b064fSChristopher Di Bella function(_Fp) -> function<_Stripped>; 93001666904SLouis Dionne # endif // _LIBCPP_STD_VER >= 17 931050b064fSChristopher Di Bella 932050b064fSChristopher Di Bella template <class _Rp, class... _ArgTypes> 933050b064fSChristopher Di Bella function<_Rp(_ArgTypes...)>::function(const function& __f) : __f_(__f.__f_) {} 934050b064fSChristopher Di Bella 935050b064fSChristopher Di Bella # if _LIBCPP_STD_VER <= 14 936050b064fSChristopher Di Bella template <class _Rp, class... _ArgTypes> 937050b064fSChristopher Di Bella template <class _Alloc> 9389783f28cSLouis Dionne function<_Rp(_ArgTypes...)>::function(allocator_arg_t, const _Alloc&, const function& __f) : __f_(__f.__f_) {} 939050b064fSChristopher Di Bella # endif 940050b064fSChristopher Di Bella 941050b064fSChristopher Di Bella template <class _Rp, class... _ArgTypes> 9429783f28cSLouis Dionne function<_Rp(_ArgTypes...)>::function(function&& __f) _NOEXCEPT : __f_(std::move(__f.__f_)) {} 943050b064fSChristopher Di Bella 944050b064fSChristopher Di Bella # if _LIBCPP_STD_VER <= 14 945050b064fSChristopher Di Bella template <class _Rp, class... _ArgTypes> 946050b064fSChristopher Di Bella template <class _Alloc> 9479783f28cSLouis Dionne function<_Rp(_ArgTypes...)>::function(allocator_arg_t, const _Alloc&, function&& __f) : __f_(std::move(__f.__f_)) {} 948050b064fSChristopher Di Bella # endif 949050b064fSChristopher Di Bella 950050b064fSChristopher Di Bella template <class _Rp, class... _ArgTypes> 951050b064fSChristopher Di Bella template <class _Fp, class> 95277a00c0dSLouis Dionne function<_Rp(_ArgTypes...)>::function(_Fp __f) : __f_(std::move(__f)) {} 953050b064fSChristopher Di Bella 954050b064fSChristopher Di Bella # if _LIBCPP_STD_VER <= 14 955050b064fSChristopher Di Bella template <class _Rp, class... _ArgTypes> 956050b064fSChristopher Di Bella template <class _Fp, class _Alloc, class> 9579783f28cSLouis Dionne function<_Rp(_ArgTypes...)>::function(allocator_arg_t, const _Alloc& __a, _Fp __f) : __f_(std::move(__f), __a) {} 958050b064fSChristopher Di Bella # endif 959050b064fSChristopher Di Bella 960050b064fSChristopher Di Bella template <class _Rp, class... _ArgTypes> 9619783f28cSLouis Dionne function<_Rp(_ArgTypes...)>& function<_Rp(_ArgTypes...)>::operator=(const function& __f) { 962050b064fSChristopher Di Bella function(__f).swap(*this); 963050b064fSChristopher Di Bella return *this; 964050b064fSChristopher Di Bella } 965050b064fSChristopher Di Bella 966050b064fSChristopher Di Bella template <class _Rp, class... _ArgTypes> 9679783f28cSLouis Dionne function<_Rp(_ArgTypes...)>& function<_Rp(_ArgTypes...)>::operator=(function&& __f) _NOEXCEPT { 96877a00c0dSLouis Dionne __f_ = std::move(__f.__f_); 969050b064fSChristopher Di Bella return *this; 970050b064fSChristopher Di Bella } 971050b064fSChristopher Di Bella 972050b064fSChristopher Di Bella template <class _Rp, class... _ArgTypes> 9739783f28cSLouis Dionne function<_Rp(_ArgTypes...)>& function<_Rp(_ArgTypes...)>::operator=(nullptr_t) _NOEXCEPT { 974050b064fSChristopher Di Bella __f_ = nullptr; 975050b064fSChristopher Di Bella return *this; 976050b064fSChristopher Di Bella } 977050b064fSChristopher Di Bella 978050b064fSChristopher Di Bella template <class _Rp, class... _ArgTypes> 979050b064fSChristopher Di Bella template <class _Fp, class> 9809783f28cSLouis Dionne function<_Rp(_ArgTypes...)>& function<_Rp(_ArgTypes...)>::operator=(_Fp&& __f) { 98177a00c0dSLouis Dionne function(std::forward<_Fp>(__f)).swap(*this); 982050b064fSChristopher Di Bella return *this; 983050b064fSChristopher Di Bella } 984050b064fSChristopher Di Bella 985050b064fSChristopher Di Bella template <class _Rp, class... _ArgTypes> 986050b064fSChristopher Di Bella function<_Rp(_ArgTypes...)>::~function() {} 987050b064fSChristopher Di Bella 988050b064fSChristopher Di Bella template <class _Rp, class... _ArgTypes> 9899783f28cSLouis Dionne void function<_Rp(_ArgTypes...)>::swap(function& __f) _NOEXCEPT { 990050b064fSChristopher Di Bella __f_.swap(__f.__f_); 991050b064fSChristopher Di Bella } 992050b064fSChristopher Di Bella 993050b064fSChristopher Di Bella template <class _Rp, class... _ArgTypes> 9949783f28cSLouis Dionne _Rp function<_Rp(_ArgTypes...)>::operator()(_ArgTypes... __arg) const { 99577a00c0dSLouis Dionne return __f_(std::forward<_ArgTypes>(__arg)...); 996050b064fSChristopher Di Bella } 997050b064fSChristopher Di Bella 998ba87515fSNikolas Klauser # if _LIBCPP_HAS_RTTI 999050b064fSChristopher Di Bella 1000050b064fSChristopher Di Bella template <class _Rp, class... _ArgTypes> 10019783f28cSLouis Dionne const std::type_info& function<_Rp(_ArgTypes...)>::target_type() const _NOEXCEPT { 1002050b064fSChristopher Di Bella return __f_.target_type(); 1003050b064fSChristopher Di Bella } 1004050b064fSChristopher Di Bella 1005050b064fSChristopher Di Bella template <class _Rp, class... _ArgTypes> 1006050b064fSChristopher Di Bella template <typename _Tp> 10079783f28cSLouis Dionne _Tp* function<_Rp(_ArgTypes...)>::target() _NOEXCEPT { 1008050b064fSChristopher Di Bella return (_Tp*)(__f_.template target<_Tp>()); 1009050b064fSChristopher Di Bella } 1010050b064fSChristopher Di Bella 1011050b064fSChristopher Di Bella template <class _Rp, class... _ArgTypes> 1012050b064fSChristopher Di Bella template <typename _Tp> 10139783f28cSLouis Dionne const _Tp* function<_Rp(_ArgTypes...)>::target() const _NOEXCEPT { 1014050b064fSChristopher Di Bella return __f_.template target<_Tp>(); 1015050b064fSChristopher Di Bella } 1016050b064fSChristopher Di Bella 1017ba87515fSNikolas Klauser # endif // _LIBCPP_HAS_RTTI 1018050b064fSChristopher Di Bella 1019050b064fSChristopher Di Bella template <class _Rp, class... _ArgTypes> 10209783f28cSLouis Dionne inline _LIBCPP_HIDE_FROM_ABI bool operator==(const function<_Rp(_ArgTypes...)>& __f, nullptr_t) _NOEXCEPT { 10219783f28cSLouis Dionne return !__f; 10229783f28cSLouis Dionne } 1023050b064fSChristopher Di Bella 10249a6ca673SHristo Hristov # if _LIBCPP_STD_VER <= 17 10259a6ca673SHristo Hristov 1026050b064fSChristopher Di Bella template <class _Rp, class... _ArgTypes> 10279783f28cSLouis Dionne inline _LIBCPP_HIDE_FROM_ABI bool operator==(nullptr_t, const function<_Rp(_ArgTypes...)>& __f) _NOEXCEPT { 10289783f28cSLouis Dionne return !__f; 10299783f28cSLouis Dionne } 1030050b064fSChristopher Di Bella 1031050b064fSChristopher Di Bella template <class _Rp, class... _ArgTypes> 10329783f28cSLouis Dionne inline _LIBCPP_HIDE_FROM_ABI bool operator!=(const function<_Rp(_ArgTypes...)>& __f, nullptr_t) _NOEXCEPT { 10339783f28cSLouis Dionne return (bool)__f; 10349783f28cSLouis Dionne } 1035050b064fSChristopher Di Bella 1036050b064fSChristopher Di Bella template <class _Rp, class... _ArgTypes> 10379783f28cSLouis Dionne inline _LIBCPP_HIDE_FROM_ABI bool operator!=(nullptr_t, const function<_Rp(_ArgTypes...)>& __f) _NOEXCEPT { 10389783f28cSLouis Dionne return (bool)__f; 10399783f28cSLouis Dionne } 1040050b064fSChristopher Di Bella 10419a6ca673SHristo Hristov # endif // _LIBCPP_STD_VER <= 17 10429a6ca673SHristo Hristov 1043050b064fSChristopher Di Bella template <class _Rp, class... _ArgTypes> 10449783f28cSLouis Dionne inline _LIBCPP_HIDE_FROM_ABI void swap(function<_Rp(_ArgTypes...)>& __x, function<_Rp(_ArgTypes...)>& __y) _NOEXCEPT { 10459783f28cSLouis Dionne return __x.swap(__y); 10469783f28cSLouis Dionne } 1047050b064fSChristopher Di Bella 1048dbe60caaSNikolas Klauser _LIBCPP_END_NAMESPACE_STD 1049050b064fSChristopher Di Bella 1050c475e31aSNikolas Klauser #endif // _LIBCPP_CXX03_LANG 1051050b064fSChristopher Di Bella 10527b462251SLouis Dionne _LIBCPP_POP_MACROS 10537b462251SLouis Dionne 1054050b064fSChristopher Di Bella #endif // _LIBCPP___FUNCTIONAL_FUNCTION_H 1055