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> 31*0fca6ea1SDimitry Andric #include <__type_traits/is_trivially_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 48b3edf446SDimitry Andric _LIBCPP_PUSH_MACROS 49b3edf446SDimitry Andric #include <__undef_macros> 50b3edf446SDimitry Andric 51bdd1243dSDimitry Andric #ifndef _LIBCPP_CXX03_LANG 52bdd1243dSDimitry Andric 53fe6060f1SDimitry Andric _LIBCPP_BEGIN_NAMESPACE_STD 54fe6060f1SDimitry Andric 55fe6060f1SDimitry Andric // bad_function_call 56fe6060f1SDimitry Andric 5781ad6265SDimitry Andric _LIBCPP_DIAGNOSTIC_PUSH 58*0fca6ea1SDimitry Andric # if !_LIBCPP_AVAILABILITY_HAS_BAD_FUNCTION_CALL_KEY_FUNCTION 5981ad6265SDimitry Andric _LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wweak-vtables") 60*0fca6ea1SDimitry Andric # endif 61cb14a3feSDimitry Andric class _LIBCPP_EXPORTED_FROM_ABI bad_function_call : public exception { 62fe6060f1SDimitry Andric public: 635f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI bad_function_call() _NOEXCEPT = default; 645f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI bad_function_call(const bad_function_call&) _NOEXCEPT = default; 655f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI bad_function_call& operator=(const bad_function_call&) _NOEXCEPT = default; 66349cc55cSDimitry Andric // Note that when a key function is not used, every translation unit that uses 67349cc55cSDimitry Andric // bad_function_call will end up containing a weak definition of the vtable and 68349cc55cSDimitry Andric // typeinfo. 69*0fca6ea1SDimitry Andric # if _LIBCPP_AVAILABILITY_HAS_BAD_FUNCTION_CALL_KEY_FUNCTION 70bdd1243dSDimitry Andric ~bad_function_call() _NOEXCEPT override; 71349cc55cSDimitry Andric # else 7206c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI_VIRTUAL ~bad_function_call() _NOEXCEPT override {} 73349cc55cSDimitry Andric # endif 74fe6060f1SDimitry Andric 75349cc55cSDimitry Andric # ifdef _LIBCPP_ABI_BAD_FUNCTION_CALL_GOOD_WHAT_MESSAGE 76bdd1243dSDimitry Andric const char* what() const _NOEXCEPT override; 77fe6060f1SDimitry Andric # endif 78fe6060f1SDimitry Andric }; 7981ad6265SDimitry Andric _LIBCPP_DIAGNOSTIC_POP 80fe6060f1SDimitry Andric 81cb14a3feSDimitry Andric _LIBCPP_NORETURN inline _LIBCPP_HIDE_FROM_ABI void __throw_bad_function_call() { 8206c3fb27SDimitry Andric # ifndef _LIBCPP_HAS_NO_EXCEPTIONS 83fe6060f1SDimitry Andric throw bad_function_call(); 84fe6060f1SDimitry Andric # else 8506c3fb27SDimitry Andric _LIBCPP_VERBOSE_ABORT("bad_function_call was thrown in -fno-exceptions mode"); 86fe6060f1SDimitry Andric # endif 87fe6060f1SDimitry Andric } 88fe6060f1SDimitry Andric 89cb14a3feSDimitry Andric template <class _Fp> 90cb14a3feSDimitry Andric class _LIBCPP_TEMPLATE_VIS function; // undefined 91fe6060f1SDimitry Andric 92cb14a3feSDimitry Andric namespace __function { 93fe6060f1SDimitry Andric 94fe6060f1SDimitry Andric template <class _Rp> 95cb14a3feSDimitry Andric struct __maybe_derive_from_unary_function {}; 96fe6060f1SDimitry Andric 97fe6060f1SDimitry Andric template <class _Rp, class _A1> 98cb14a3feSDimitry Andric struct __maybe_derive_from_unary_function<_Rp(_A1)> : public __unary_function<_A1, _Rp> {}; 99fe6060f1SDimitry Andric 100fe6060f1SDimitry Andric template <class _Rp> 101cb14a3feSDimitry Andric struct __maybe_derive_from_binary_function {}; 102fe6060f1SDimitry Andric 103fe6060f1SDimitry Andric template <class _Rp, class _A1, class _A2> 104cb14a3feSDimitry Andric struct __maybe_derive_from_binary_function<_Rp(_A1, _A2)> : public __binary_function<_A1, _A2, _Rp> {}; 105fe6060f1SDimitry Andric 106fe6060f1SDimitry Andric template <class _Fp> 107cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI bool __not_null(_Fp const&) { 108cb14a3feSDimitry Andric return true; 109cb14a3feSDimitry Andric } 110fe6060f1SDimitry Andric 111fe6060f1SDimitry Andric template <class _Fp> 112cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI bool __not_null(_Fp* __ptr) { 113cb14a3feSDimitry Andric return __ptr; 114cb14a3feSDimitry Andric } 115fe6060f1SDimitry Andric 116fe6060f1SDimitry Andric template <class _Ret, class _Class> 117cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI bool __not_null(_Ret _Class::*__ptr) { 118cb14a3feSDimitry Andric return __ptr; 119cb14a3feSDimitry Andric } 120fe6060f1SDimitry Andric 121fe6060f1SDimitry Andric template <class _Fp> 122cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI bool __not_null(function<_Fp> const& __f) { 123cb14a3feSDimitry Andric return !!__f; 124cb14a3feSDimitry Andric } 125fe6060f1SDimitry Andric 126fe6060f1SDimitry Andric # ifdef _LIBCPP_HAS_EXTENSION_BLOCKS 127fe6060f1SDimitry Andric template <class _Rp, class... _Args> 128cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI bool __not_null(_Rp (^__p)(_Args...)) { 129cb14a3feSDimitry Andric return __p; 130cb14a3feSDimitry Andric } 131fe6060f1SDimitry Andric # endif 132fe6060f1SDimitry Andric 133fe6060f1SDimitry Andric } // namespace __function 134fe6060f1SDimitry Andric 135fe6060f1SDimitry Andric namespace __function { 136fe6060f1SDimitry Andric 137fe6060f1SDimitry Andric // __alloc_func holds a functor and an allocator. 138fe6060f1SDimitry Andric 139cb14a3feSDimitry Andric template <class _Fp, class _Ap, class _FB> 140cb14a3feSDimitry Andric class __alloc_func; 141fe6060f1SDimitry Andric template <class _Fp, class _FB> 142fe6060f1SDimitry Andric class __default_alloc_func; 143fe6060f1SDimitry Andric 144fe6060f1SDimitry Andric template <class _Fp, class _Ap, class _Rp, class... _ArgTypes> 145cb14a3feSDimitry Andric class __alloc_func<_Fp, _Ap, _Rp(_ArgTypes...)> { 146fe6060f1SDimitry Andric __compressed_pair<_Fp, _Ap> __f_; 147fe6060f1SDimitry Andric 148fe6060f1SDimitry Andric public: 149349cc55cSDimitry Andric typedef _LIBCPP_NODEBUG _Fp _Target; 150349cc55cSDimitry Andric typedef _LIBCPP_NODEBUG _Ap _Alloc; 151fe6060f1SDimitry Andric 152cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI const _Target& __target() const { return __f_.first(); } 153fe6060f1SDimitry Andric 154fe6060f1SDimitry Andric // WIN32 APIs may define __allocator, so use __get_allocator instead. 155cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI const _Alloc& __get_allocator() const { return __f_.second(); } 156fe6060f1SDimitry Andric 157cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI explicit __alloc_func(_Target&& __f) 158cb14a3feSDimitry Andric : __f_(piecewise_construct, std::forward_as_tuple(std::move(__f)), std::forward_as_tuple()) {} 159fe6060f1SDimitry Andric 160cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI explicit __alloc_func(const _Target& __f, const _Alloc& __a) 161cb14a3feSDimitry Andric : __f_(piecewise_construct, std::forward_as_tuple(__f), std::forward_as_tuple(__a)) {} 162fe6060f1SDimitry Andric 163cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI explicit __alloc_func(const _Target& __f, _Alloc&& __a) 164cb14a3feSDimitry Andric : __f_(piecewise_construct, std::forward_as_tuple(__f), std::forward_as_tuple(std::move(__a))) {} 165fe6060f1SDimitry Andric 166cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI explicit __alloc_func(_Target&& __f, _Alloc&& __a) 167cb14a3feSDimitry Andric : __f_(piecewise_construct, std::forward_as_tuple(std::move(__f)), std::forward_as_tuple(std::move(__a))) {} 168fe6060f1SDimitry Andric 169cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _Rp operator()(_ArgTypes&&... __arg) { 170fe6060f1SDimitry Andric typedef __invoke_void_return_wrapper<_Rp> _Invoker; 171cb14a3feSDimitry Andric return _Invoker::__call(__f_.first(), std::forward<_ArgTypes>(__arg)...); 172fe6060f1SDimitry Andric } 173fe6060f1SDimitry Andric 174cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI __alloc_func* __clone() const { 175fe6060f1SDimitry Andric typedef allocator_traits<_Alloc> __alloc_traits; 176bdd1243dSDimitry Andric typedef __rebind_alloc<__alloc_traits, __alloc_func> _AA; 177fe6060f1SDimitry Andric _AA __a(__f_.second()); 178fe6060f1SDimitry Andric typedef __allocator_destructor<_AA> _Dp; 179fe6060f1SDimitry Andric unique_ptr<__alloc_func, _Dp> __hold(__a.allocate(1), _Dp(__a, 1)); 180fe6060f1SDimitry Andric ::new ((void*)__hold.get()) __alloc_func(__f_.first(), _Alloc(__a)); 181fe6060f1SDimitry Andric return __hold.release(); 182fe6060f1SDimitry Andric } 183fe6060f1SDimitry Andric 184cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI void destroy() _NOEXCEPT { __f_.~__compressed_pair<_Target, _Alloc>(); } 185fe6060f1SDimitry Andric 18606c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI static void __destroy_and_delete(__alloc_func* __f) { 187fe6060f1SDimitry Andric typedef allocator_traits<_Alloc> __alloc_traits; 188bdd1243dSDimitry Andric typedef __rebind_alloc<__alloc_traits, __alloc_func> _FunAlloc; 189fe6060f1SDimitry Andric _FunAlloc __a(__f->__get_allocator()); 190fe6060f1SDimitry Andric __f->destroy(); 191fe6060f1SDimitry Andric __a.deallocate(__f, 1); 192fe6060f1SDimitry Andric } 193fe6060f1SDimitry Andric }; 194fe6060f1SDimitry Andric 195fe6060f1SDimitry Andric template <class _Fp, class _Rp, class... _ArgTypes> 196fe6060f1SDimitry Andric class __default_alloc_func<_Fp, _Rp(_ArgTypes...)> { 197fe6060f1SDimitry Andric _Fp __f_; 198fe6060f1SDimitry Andric 199fe6060f1SDimitry Andric public: 200349cc55cSDimitry Andric typedef _LIBCPP_NODEBUG _Fp _Target; 201fe6060f1SDimitry Andric 202cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI const _Target& __target() const { return __f_; } 203fe6060f1SDimitry Andric 204cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI explicit __default_alloc_func(_Target&& __f) : __f_(std::move(__f)) {} 205fe6060f1SDimitry Andric 206cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI explicit __default_alloc_func(const _Target& __f) : __f_(__f) {} 207fe6060f1SDimitry Andric 208cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _Rp operator()(_ArgTypes&&... __arg) { 209fe6060f1SDimitry Andric typedef __invoke_void_return_wrapper<_Rp> _Invoker; 2105f757f3fSDimitry Andric return _Invoker::__call(__f_, std::forward<_ArgTypes>(__arg)...); 211fe6060f1SDimitry Andric } 212fe6060f1SDimitry Andric 213cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI __default_alloc_func* __clone() const { 214cb14a3feSDimitry Andric __builtin_new_allocator::__holder_t __hold = __builtin_new_allocator::__allocate_type<__default_alloc_func>(1); 215cb14a3feSDimitry Andric __default_alloc_func* __res = ::new ((void*)__hold.get()) __default_alloc_func(__f_); 216fe6060f1SDimitry Andric (void)__hold.release(); 217fe6060f1SDimitry Andric return __res; 218fe6060f1SDimitry Andric } 219fe6060f1SDimitry Andric 220cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI void destroy() _NOEXCEPT { __f_.~_Target(); } 221fe6060f1SDimitry Andric 22206c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI static void __destroy_and_delete(__default_alloc_func* __f) { 223fe6060f1SDimitry Andric __f->destroy(); 224fe6060f1SDimitry Andric __builtin_new_allocator::__deallocate_type<__default_alloc_func>(__f, 1); 225fe6060f1SDimitry Andric } 226fe6060f1SDimitry Andric }; 227fe6060f1SDimitry Andric 228fe6060f1SDimitry Andric // __base provides an abstract interface for copyable functors. 229fe6060f1SDimitry Andric 230cb14a3feSDimitry Andric template <class _Fp> 231cb14a3feSDimitry Andric class _LIBCPP_TEMPLATE_VIS __base; 232fe6060f1SDimitry Andric 233fe6060f1SDimitry Andric template <class _Rp, class... _ArgTypes> 234cb14a3feSDimitry Andric class __base<_Rp(_ArgTypes...)> { 235fe6060f1SDimitry Andric public: 236*0fca6ea1SDimitry Andric __base(const __base&) = delete; 237*0fca6ea1SDimitry Andric __base& operator=(const __base&) = delete; 238*0fca6ea1SDimitry Andric 2395f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI __base() {} 240bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual ~__base() {} 241fe6060f1SDimitry Andric virtual __base* __clone() const = 0; 242fe6060f1SDimitry Andric virtual void __clone(__base*) const = 0; 243fe6060f1SDimitry Andric virtual void destroy() _NOEXCEPT = 0; 244fe6060f1SDimitry Andric virtual void destroy_deallocate() _NOEXCEPT = 0; 245fe6060f1SDimitry Andric virtual _Rp operator()(_ArgTypes&&...) = 0; 2461ac55f4cSDimitry Andric # ifndef _LIBCPP_HAS_NO_RTTI 247fe6060f1SDimitry Andric virtual const void* target(const type_info&) const _NOEXCEPT = 0; 248fe6060f1SDimitry Andric virtual const std::type_info& target_type() const _NOEXCEPT = 0; 2491ac55f4cSDimitry Andric # endif // _LIBCPP_HAS_NO_RTTI 250fe6060f1SDimitry Andric }; 251fe6060f1SDimitry Andric 252fe6060f1SDimitry Andric // __func implements __base for a given functor type. 253fe6060f1SDimitry Andric 254cb14a3feSDimitry Andric template <class _FD, class _Alloc, class _FB> 255cb14a3feSDimitry Andric class __func; 256fe6060f1SDimitry Andric 257fe6060f1SDimitry Andric template <class _Fp, class _Alloc, class _Rp, class... _ArgTypes> 258cb14a3feSDimitry Andric class __func<_Fp, _Alloc, _Rp(_ArgTypes...)> : public __base<_Rp(_ArgTypes...)> { 259fe6060f1SDimitry Andric __alloc_func<_Fp, _Alloc, _Rp(_ArgTypes...)> __f_; 260cb14a3feSDimitry Andric 261fe6060f1SDimitry Andric public: 262cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI explicit __func(_Fp&& __f) : __f_(std::move(__f)) {} 263fe6060f1SDimitry Andric 264cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI explicit __func(const _Fp& __f, const _Alloc& __a) : __f_(__f, __a) {} 265fe6060f1SDimitry Andric 266cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI explicit __func(const _Fp& __f, _Alloc&& __a) : __f_(__f, std::move(__a)) {} 267fe6060f1SDimitry Andric 268cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI explicit __func(_Fp&& __f, _Alloc&& __a) : __f_(std::move(__f), std::move(__a)) {} 269fe6060f1SDimitry Andric 27006c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual __base<_Rp(_ArgTypes...)>* __clone() const; 27106c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void __clone(__base<_Rp(_ArgTypes...)>*) const; 27206c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void destroy() _NOEXCEPT; 27306c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void destroy_deallocate() _NOEXCEPT; 27406c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual _Rp operator()(_ArgTypes&&... __arg); 2751ac55f4cSDimitry Andric # ifndef _LIBCPP_HAS_NO_RTTI 27606c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual const void* target(const type_info&) const _NOEXCEPT; 27706c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual const std::type_info& target_type() const _NOEXCEPT; 2781ac55f4cSDimitry Andric # endif // _LIBCPP_HAS_NO_RTTI 279fe6060f1SDimitry Andric }; 280fe6060f1SDimitry Andric 281fe6060f1SDimitry Andric template <class _Fp, class _Alloc, class _Rp, class... _ArgTypes> 282cb14a3feSDimitry Andric __base<_Rp(_ArgTypes...)>* __func<_Fp, _Alloc, _Rp(_ArgTypes...)>::__clone() const { 283fe6060f1SDimitry Andric typedef allocator_traits<_Alloc> __alloc_traits; 284bdd1243dSDimitry Andric typedef __rebind_alloc<__alloc_traits, __func> _Ap; 285fe6060f1SDimitry Andric _Ap __a(__f_.__get_allocator()); 286fe6060f1SDimitry Andric typedef __allocator_destructor<_Ap> _Dp; 287fe6060f1SDimitry Andric unique_ptr<__func, _Dp> __hold(__a.allocate(1), _Dp(__a, 1)); 288fe6060f1SDimitry Andric ::new ((void*)__hold.get()) __func(__f_.__target(), _Alloc(__a)); 289fe6060f1SDimitry Andric return __hold.release(); 290fe6060f1SDimitry Andric } 291fe6060f1SDimitry Andric 292fe6060f1SDimitry Andric template <class _Fp, class _Alloc, class _Rp, class... _ArgTypes> 293cb14a3feSDimitry Andric void __func<_Fp, _Alloc, _Rp(_ArgTypes...)>::__clone(__base<_Rp(_ArgTypes...)>* __p) const { 294fe6060f1SDimitry Andric ::new ((void*)__p) __func(__f_.__target(), __f_.__get_allocator()); 295fe6060f1SDimitry Andric } 296fe6060f1SDimitry Andric 297fe6060f1SDimitry Andric template <class _Fp, class _Alloc, class _Rp, class... _ArgTypes> 298cb14a3feSDimitry Andric void __func<_Fp, _Alloc, _Rp(_ArgTypes...)>::destroy() _NOEXCEPT { 299fe6060f1SDimitry Andric __f_.destroy(); 300fe6060f1SDimitry Andric } 301fe6060f1SDimitry Andric 302fe6060f1SDimitry Andric template <class _Fp, class _Alloc, class _Rp, class... _ArgTypes> 303cb14a3feSDimitry Andric void __func<_Fp, _Alloc, _Rp(_ArgTypes...)>::destroy_deallocate() _NOEXCEPT { 304fe6060f1SDimitry Andric typedef allocator_traits<_Alloc> __alloc_traits; 305bdd1243dSDimitry Andric typedef __rebind_alloc<__alloc_traits, __func> _Ap; 306fe6060f1SDimitry Andric _Ap __a(__f_.__get_allocator()); 307fe6060f1SDimitry Andric __f_.destroy(); 308fe6060f1SDimitry Andric __a.deallocate(this, 1); 309fe6060f1SDimitry Andric } 310fe6060f1SDimitry Andric 311fe6060f1SDimitry Andric template <class _Fp, class _Alloc, class _Rp, class... _ArgTypes> 312cb14a3feSDimitry Andric _Rp __func<_Fp, _Alloc, _Rp(_ArgTypes...)>::operator()(_ArgTypes&&... __arg) { 3135f757f3fSDimitry Andric return __f_(std::forward<_ArgTypes>(__arg)...); 314fe6060f1SDimitry Andric } 315fe6060f1SDimitry Andric 3161ac55f4cSDimitry Andric # ifndef _LIBCPP_HAS_NO_RTTI 317fe6060f1SDimitry Andric 318fe6060f1SDimitry Andric template <class _Fp, class _Alloc, class _Rp, class... _ArgTypes> 319cb14a3feSDimitry Andric const void* __func<_Fp, _Alloc, _Rp(_ArgTypes...)>::target(const type_info& __ti) const _NOEXCEPT { 320fe6060f1SDimitry Andric if (__ti == typeid(_Fp)) 3215f757f3fSDimitry Andric return std::addressof(__f_.__target()); 322fe6060f1SDimitry Andric return nullptr; 323fe6060f1SDimitry Andric } 324fe6060f1SDimitry Andric 325fe6060f1SDimitry Andric template <class _Fp, class _Alloc, class _Rp, class... _ArgTypes> 326cb14a3feSDimitry Andric const std::type_info& __func<_Fp, _Alloc, _Rp(_ArgTypes...)>::target_type() const _NOEXCEPT { 327fe6060f1SDimitry Andric return typeid(_Fp); 328fe6060f1SDimitry Andric } 329fe6060f1SDimitry Andric 3301ac55f4cSDimitry Andric # endif // _LIBCPP_HAS_NO_RTTI 331fe6060f1SDimitry Andric 332fe6060f1SDimitry Andric // __value_func creates a value-type from a __func. 333fe6060f1SDimitry Andric 334cb14a3feSDimitry Andric template <class _Fp> 335cb14a3feSDimitry Andric class __value_func; 336fe6060f1SDimitry Andric 337cb14a3feSDimitry Andric template <class _Rp, class... _ArgTypes> 338cb14a3feSDimitry Andric class __value_func<_Rp(_ArgTypes...)> { 339bdd1243dSDimitry Andric _LIBCPP_SUPPRESS_DEPRECATED_PUSH 340fe6060f1SDimitry Andric typename aligned_storage<3 * sizeof(void*)>::type __buf_; 341bdd1243dSDimitry Andric _LIBCPP_SUPPRESS_DEPRECATED_POP 342fe6060f1SDimitry Andric 343fe6060f1SDimitry Andric typedef __base<_Rp(_ArgTypes...)> __func; 344fe6060f1SDimitry Andric __func* __f_; 345fe6060f1SDimitry Andric 346cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_NO_CFI static __func* __as_base(void* __p) { return reinterpret_cast<__func*>(__p); } 347fe6060f1SDimitry Andric 348fe6060f1SDimitry Andric public: 349cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI __value_func() _NOEXCEPT : __f_(nullptr) {} 350fe6060f1SDimitry Andric 351fe6060f1SDimitry Andric template <class _Fp, class _Alloc> 352cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI __value_func(_Fp&& __f, const _Alloc& __a) : __f_(nullptr) { 353fe6060f1SDimitry Andric typedef allocator_traits<_Alloc> __alloc_traits; 354fe6060f1SDimitry Andric typedef __function::__func<_Fp, _Alloc, _Rp(_ArgTypes...)> _Fun; 355bdd1243dSDimitry Andric typedef __rebind_alloc<__alloc_traits, _Fun> _FunAlloc; 356fe6060f1SDimitry Andric 357cb14a3feSDimitry Andric if (__function::__not_null(__f)) { 358fe6060f1SDimitry Andric _FunAlloc __af(__a); 359cb14a3feSDimitry Andric if (sizeof(_Fun) <= sizeof(__buf_) && is_nothrow_copy_constructible<_Fp>::value && 360cb14a3feSDimitry Andric is_nothrow_copy_constructible<_FunAlloc>::value) { 361cb14a3feSDimitry Andric __f_ = ::new ((void*)&__buf_) _Fun(std::move(__f), _Alloc(__af)); 362cb14a3feSDimitry Andric } else { 363fe6060f1SDimitry Andric typedef __allocator_destructor<_FunAlloc> _Dp; 364fe6060f1SDimitry Andric unique_ptr<__func, _Dp> __hold(__af.allocate(1), _Dp(__af, 1)); 3655f757f3fSDimitry Andric ::new ((void*)__hold.get()) _Fun(std::move(__f), _Alloc(__a)); 366fe6060f1SDimitry Andric __f_ = __hold.release(); 367fe6060f1SDimitry Andric } 368fe6060f1SDimitry Andric } 369fe6060f1SDimitry Andric } 370fe6060f1SDimitry Andric 3715f757f3fSDimitry Andric template <class _Fp, __enable_if_t<!is_same<__decay_t<_Fp>, __value_func>::value, int> = 0> 372cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI explicit __value_func(_Fp&& __f) : __value_func(std::forward<_Fp>(__f), allocator<_Fp>()) {} 373fe6060f1SDimitry Andric 374cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI __value_func(const __value_func& __f) { 375fe6060f1SDimitry Andric if (__f.__f_ == nullptr) 376fe6060f1SDimitry Andric __f_ = nullptr; 377cb14a3feSDimitry Andric else if ((void*)__f.__f_ == &__f.__buf_) { 378fe6060f1SDimitry Andric __f_ = __as_base(&__buf_); 379fe6060f1SDimitry Andric __f.__f_->__clone(__f_); 380cb14a3feSDimitry Andric } else 381fe6060f1SDimitry Andric __f_ = __f.__f_->__clone(); 382fe6060f1SDimitry Andric } 383fe6060f1SDimitry Andric 384cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI __value_func(__value_func&& __f) _NOEXCEPT { 385fe6060f1SDimitry Andric if (__f.__f_ == nullptr) 386fe6060f1SDimitry Andric __f_ = nullptr; 387cb14a3feSDimitry Andric else if ((void*)__f.__f_ == &__f.__buf_) { 388fe6060f1SDimitry Andric __f_ = __as_base(&__buf_); 389fe6060f1SDimitry Andric __f.__f_->__clone(__f_); 390cb14a3feSDimitry Andric } else { 391fe6060f1SDimitry Andric __f_ = __f.__f_; 392fe6060f1SDimitry Andric __f.__f_ = nullptr; 393fe6060f1SDimitry Andric } 394fe6060f1SDimitry Andric } 395fe6060f1SDimitry Andric 396cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI ~__value_func() { 397fe6060f1SDimitry Andric if ((void*)__f_ == &__buf_) 398fe6060f1SDimitry Andric __f_->destroy(); 399fe6060f1SDimitry Andric else if (__f_) 400fe6060f1SDimitry Andric __f_->destroy_deallocate(); 401fe6060f1SDimitry Andric } 402fe6060f1SDimitry Andric 403cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI __value_func& operator=(__value_func&& __f) { 404fe6060f1SDimitry Andric *this = nullptr; 405fe6060f1SDimitry Andric if (__f.__f_ == nullptr) 406fe6060f1SDimitry Andric __f_ = nullptr; 407cb14a3feSDimitry Andric else if ((void*)__f.__f_ == &__f.__buf_) { 408fe6060f1SDimitry Andric __f_ = __as_base(&__buf_); 409fe6060f1SDimitry Andric __f.__f_->__clone(__f_); 410cb14a3feSDimitry Andric } else { 411fe6060f1SDimitry Andric __f_ = __f.__f_; 412fe6060f1SDimitry Andric __f.__f_ = nullptr; 413fe6060f1SDimitry Andric } 414fe6060f1SDimitry Andric return *this; 415fe6060f1SDimitry Andric } 416fe6060f1SDimitry Andric 417cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI __value_func& operator=(nullptr_t) { 418fe6060f1SDimitry Andric __func* __f = __f_; 419fe6060f1SDimitry Andric __f_ = nullptr; 420fe6060f1SDimitry Andric if ((void*)__f == &__buf_) 421fe6060f1SDimitry Andric __f->destroy(); 422fe6060f1SDimitry Andric else if (__f) 423fe6060f1SDimitry Andric __f->destroy_deallocate(); 424fe6060f1SDimitry Andric return *this; 425fe6060f1SDimitry Andric } 426fe6060f1SDimitry Andric 427cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _Rp operator()(_ArgTypes&&... __args) const { 428fe6060f1SDimitry Andric if (__f_ == nullptr) 429fe6060f1SDimitry Andric __throw_bad_function_call(); 4305f757f3fSDimitry Andric return (*__f_)(std::forward<_ArgTypes>(__args)...); 431fe6060f1SDimitry Andric } 432fe6060f1SDimitry Andric 433cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI void swap(__value_func& __f) _NOEXCEPT { 434fe6060f1SDimitry Andric if (&__f == this) 435fe6060f1SDimitry Andric return; 436cb14a3feSDimitry Andric if ((void*)__f_ == &__buf_ && (void*)__f.__f_ == &__f.__buf_) { 437bdd1243dSDimitry Andric _LIBCPP_SUPPRESS_DEPRECATED_PUSH 438fe6060f1SDimitry Andric typename aligned_storage<sizeof(__buf_)>::type __tempbuf; 439bdd1243dSDimitry Andric _LIBCPP_SUPPRESS_DEPRECATED_POP 440fe6060f1SDimitry Andric __func* __t = __as_base(&__tempbuf); 441fe6060f1SDimitry Andric __f_->__clone(__t); 442fe6060f1SDimitry Andric __f_->destroy(); 443fe6060f1SDimitry Andric __f_ = nullptr; 444fe6060f1SDimitry Andric __f.__f_->__clone(__as_base(&__buf_)); 445fe6060f1SDimitry Andric __f.__f_->destroy(); 446fe6060f1SDimitry Andric __f.__f_ = nullptr; 447fe6060f1SDimitry Andric __f_ = __as_base(&__buf_); 448fe6060f1SDimitry Andric __t->__clone(__as_base(&__f.__buf_)); 449fe6060f1SDimitry Andric __t->destroy(); 450fe6060f1SDimitry Andric __f.__f_ = __as_base(&__f.__buf_); 451cb14a3feSDimitry Andric } else if ((void*)__f_ == &__buf_) { 452fe6060f1SDimitry Andric __f_->__clone(__as_base(&__f.__buf_)); 453fe6060f1SDimitry Andric __f_->destroy(); 454fe6060f1SDimitry Andric __f_ = __f.__f_; 455fe6060f1SDimitry Andric __f.__f_ = __as_base(&__f.__buf_); 456cb14a3feSDimitry Andric } else if ((void*)__f.__f_ == &__f.__buf_) { 457fe6060f1SDimitry Andric __f.__f_->__clone(__as_base(&__buf_)); 458fe6060f1SDimitry Andric __f.__f_->destroy(); 459fe6060f1SDimitry Andric __f.__f_ = __f_; 460fe6060f1SDimitry Andric __f_ = __as_base(&__buf_); 461cb14a3feSDimitry Andric } else 4625f757f3fSDimitry Andric std::swap(__f_, __f.__f_); 463fe6060f1SDimitry Andric } 464fe6060f1SDimitry Andric 465cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI explicit operator bool() const _NOEXCEPT { return __f_ != nullptr; } 466fe6060f1SDimitry Andric 4671ac55f4cSDimitry Andric # ifndef _LIBCPP_HAS_NO_RTTI 468cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI const std::type_info& target_type() const _NOEXCEPT { 469fe6060f1SDimitry Andric if (__f_ == nullptr) 470fe6060f1SDimitry Andric return typeid(void); 471fe6060f1SDimitry Andric return __f_->target_type(); 472fe6060f1SDimitry Andric } 473fe6060f1SDimitry Andric 474fe6060f1SDimitry Andric template <typename _Tp> 475cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI const _Tp* target() const _NOEXCEPT { 476fe6060f1SDimitry Andric if (__f_ == nullptr) 477fe6060f1SDimitry Andric return nullptr; 478fe6060f1SDimitry Andric return (const _Tp*)__f_->target(typeid(_Tp)); 479fe6060f1SDimitry Andric } 4801ac55f4cSDimitry Andric # endif // _LIBCPP_HAS_NO_RTTI 481fe6060f1SDimitry Andric }; 482fe6060f1SDimitry Andric 483fe6060f1SDimitry Andric // Storage for a functor object, to be used with __policy to manage copy and 484fe6060f1SDimitry Andric // destruction. 485cb14a3feSDimitry Andric union __policy_storage { 486fe6060f1SDimitry Andric mutable char __small[sizeof(void*) * 2]; 487fe6060f1SDimitry Andric void* __large; 488fe6060f1SDimitry Andric }; 489fe6060f1SDimitry Andric 490fe6060f1SDimitry Andric // True if _Fun can safely be held in __policy_storage.__small. 491fe6060f1SDimitry Andric template <typename _Fun> 492fe6060f1SDimitry Andric struct __use_small_storage 493fe6060f1SDimitry Andric : public integral_constant< 494cb14a3feSDimitry Andric bool, 495cb14a3feSDimitry Andric sizeof(_Fun) <= sizeof(__policy_storage)&& _LIBCPP_ALIGNOF(_Fun) <= _LIBCPP_ALIGNOF(__policy_storage) && 496cb14a3feSDimitry Andric is_trivially_copy_constructible<_Fun>::value && is_trivially_destructible<_Fun>::value> {}; 497fe6060f1SDimitry Andric 498fe6060f1SDimitry Andric // Policy contains information about how to copy, destroy, and move the 499fe6060f1SDimitry Andric // underlying functor. You can think of it as a vtable of sorts. 500cb14a3feSDimitry Andric struct __policy { 501fe6060f1SDimitry Andric // Used to copy or destroy __large values. null for trivial objects. 502fe6060f1SDimitry Andric void* (*const __clone)(const void*); 503fe6060f1SDimitry Andric void (*const __destroy)(void*); 504fe6060f1SDimitry Andric 505fe6060f1SDimitry Andric // True if this is the null policy (no value). 506fe6060f1SDimitry Andric const bool __is_null; 507fe6060f1SDimitry Andric 508fe6060f1SDimitry Andric // The target type. May be null if RTTI is disabled. 509fe6060f1SDimitry Andric const std::type_info* const __type_info; 510fe6060f1SDimitry Andric 511fe6060f1SDimitry Andric // Returns a pointer to a static policy object suitable for the functor 512fe6060f1SDimitry Andric // type. 513fe6060f1SDimitry Andric template <typename _Fun> 514cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI static const __policy* __create() { 515fe6060f1SDimitry Andric return __choose_policy<_Fun>(__use_small_storage<_Fun>()); 516fe6060f1SDimitry Andric } 517fe6060f1SDimitry Andric 518cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI static const __policy* __create_empty() { 519*0fca6ea1SDimitry Andric static constexpr __policy __policy = { 520cb14a3feSDimitry Andric nullptr, 521cb14a3feSDimitry Andric nullptr, 522fe6060f1SDimitry Andric true, 5231ac55f4cSDimitry Andric # ifndef _LIBCPP_HAS_NO_RTTI 524fe6060f1SDimitry Andric &typeid(void) 525fe6060f1SDimitry Andric # else 526fe6060f1SDimitry Andric nullptr 527fe6060f1SDimitry Andric # endif 528fe6060f1SDimitry Andric }; 52906c3fb27SDimitry Andric return &__policy; 530fe6060f1SDimitry Andric } 531fe6060f1SDimitry Andric 532fe6060f1SDimitry Andric private: 53306c3fb27SDimitry Andric template <typename _Fun> 534cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI static void* __large_clone(const void* __s) { 535fe6060f1SDimitry Andric const _Fun* __f = static_cast<const _Fun*>(__s); 536fe6060f1SDimitry Andric return __f->__clone(); 537fe6060f1SDimitry Andric } 538fe6060f1SDimitry Andric 539fe6060f1SDimitry Andric template <typename _Fun> 54006c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI static void __large_destroy(void* __s) { 541fe6060f1SDimitry Andric _Fun::__destroy_and_delete(static_cast<_Fun*>(__s)); 542fe6060f1SDimitry Andric } 543fe6060f1SDimitry Andric 544fe6060f1SDimitry Andric template <typename _Fun> 545cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI static const __policy* __choose_policy(/* is_small = */ false_type) { 546*0fca6ea1SDimitry Andric static constexpr __policy __policy = { 547cb14a3feSDimitry Andric &__large_clone<_Fun>, 548cb14a3feSDimitry Andric &__large_destroy<_Fun>, 549cb14a3feSDimitry Andric false, 5501ac55f4cSDimitry Andric # ifndef _LIBCPP_HAS_NO_RTTI 551fe6060f1SDimitry Andric &typeid(typename _Fun::_Target) 552fe6060f1SDimitry Andric # else 553fe6060f1SDimitry Andric nullptr 554fe6060f1SDimitry Andric # endif 555fe6060f1SDimitry Andric }; 55606c3fb27SDimitry Andric return &__policy; 557fe6060f1SDimitry Andric } 558fe6060f1SDimitry Andric 559fe6060f1SDimitry Andric template <typename _Fun> 560cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI static const __policy* __choose_policy(/* is_small = */ true_type) { 561*0fca6ea1SDimitry Andric static constexpr __policy __policy = { 562cb14a3feSDimitry Andric nullptr, 563cb14a3feSDimitry Andric nullptr, 564cb14a3feSDimitry Andric false, 5651ac55f4cSDimitry Andric # ifndef _LIBCPP_HAS_NO_RTTI 566fe6060f1SDimitry Andric &typeid(typename _Fun::_Target) 567fe6060f1SDimitry Andric # else 568fe6060f1SDimitry Andric nullptr 569fe6060f1SDimitry Andric # endif 570fe6060f1SDimitry Andric }; 57106c3fb27SDimitry Andric return &__policy; 572fe6060f1SDimitry Andric } 573fe6060f1SDimitry Andric }; 574fe6060f1SDimitry Andric 575fe6060f1SDimitry Andric // Used to choose between perfect forwarding or pass-by-value. Pass-by-value is 576fe6060f1SDimitry Andric // faster for types that can be passed in registers. 577fe6060f1SDimitry Andric template <typename _Tp> 578bdd1243dSDimitry Andric using __fast_forward = __conditional_t<is_scalar<_Tp>::value, _Tp, _Tp&&>; 579fe6060f1SDimitry Andric 580fe6060f1SDimitry Andric // __policy_invoker calls an instance of __alloc_func held in __policy_storage. 581fe6060f1SDimitry Andric 582cb14a3feSDimitry Andric template <class _Fp> 583cb14a3feSDimitry Andric struct __policy_invoker; 584fe6060f1SDimitry Andric 585fe6060f1SDimitry Andric template <class _Rp, class... _ArgTypes> 586cb14a3feSDimitry Andric struct __policy_invoker<_Rp(_ArgTypes...)> { 587cb14a3feSDimitry Andric typedef _Rp (*__Call)(const __policy_storage*, __fast_forward<_ArgTypes>...); 588fe6060f1SDimitry Andric 589fe6060f1SDimitry Andric __Call __call_; 590fe6060f1SDimitry Andric 591fe6060f1SDimitry Andric // Creates an invoker that throws bad_function_call. 592cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI __policy_invoker() : __call_(&__call_empty) {} 593fe6060f1SDimitry Andric 594fe6060f1SDimitry Andric // Creates an invoker that calls the given instance of __func. 595fe6060f1SDimitry Andric template <typename _Fun> 596cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI static __policy_invoker __create() { 597fe6060f1SDimitry Andric return __policy_invoker(&__call_impl<_Fun>); 598fe6060f1SDimitry Andric } 599fe6060f1SDimitry Andric 600fe6060f1SDimitry Andric private: 601cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI explicit __policy_invoker(__Call __c) : __call_(__c) {} 602fe6060f1SDimitry Andric 603cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI static _Rp __call_empty(const __policy_storage*, __fast_forward<_ArgTypes>...) { 604fe6060f1SDimitry Andric __throw_bad_function_call(); 605fe6060f1SDimitry Andric } 606fe6060f1SDimitry Andric 607fe6060f1SDimitry Andric template <typename _Fun> 608cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI static _Rp __call_impl(const __policy_storage* __buf, __fast_forward<_ArgTypes>... __args) { 609cb14a3feSDimitry Andric _Fun* __f = reinterpret_cast<_Fun*>(__use_small_storage<_Fun>::value ? &__buf->__small : __buf->__large); 6105f757f3fSDimitry Andric return (*__f)(std::forward<_ArgTypes>(__args)...); 611fe6060f1SDimitry Andric } 612fe6060f1SDimitry Andric }; 613fe6060f1SDimitry Andric 614fe6060f1SDimitry Andric // __policy_func uses a __policy and __policy_invoker to create a type-erased, 615fe6060f1SDimitry Andric // copyable functor. 616fe6060f1SDimitry Andric 617cb14a3feSDimitry Andric template <class _Fp> 618cb14a3feSDimitry Andric class __policy_func; 619fe6060f1SDimitry Andric 620cb14a3feSDimitry Andric template <class _Rp, class... _ArgTypes> 621cb14a3feSDimitry Andric class __policy_func<_Rp(_ArgTypes...)> { 622fe6060f1SDimitry Andric // Inline storage for small objects. 623fe6060f1SDimitry Andric __policy_storage __buf_; 624fe6060f1SDimitry Andric 625fe6060f1SDimitry Andric // Calls the value stored in __buf_. This could technically be part of 626fe6060f1SDimitry Andric // policy, but storing it here eliminates a level of indirection inside 627fe6060f1SDimitry Andric // operator(). 628fe6060f1SDimitry Andric typedef __function::__policy_invoker<_Rp(_ArgTypes...)> __invoker; 629fe6060f1SDimitry Andric __invoker __invoker_; 630fe6060f1SDimitry Andric 631fe6060f1SDimitry Andric // The policy that describes how to move / copy / destroy __buf_. Never 632fe6060f1SDimitry Andric // null, even if the function is empty. 633fe6060f1SDimitry Andric const __policy* __policy_; 634fe6060f1SDimitry Andric 635fe6060f1SDimitry Andric public: 636cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI __policy_func() : __policy_(__policy::__create_empty()) {} 637fe6060f1SDimitry Andric 638fe6060f1SDimitry Andric template <class _Fp, class _Alloc> 639cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI __policy_func(_Fp&& __f, const _Alloc& __a) : __policy_(__policy::__create_empty()) { 640fe6060f1SDimitry Andric typedef __alloc_func<_Fp, _Alloc, _Rp(_ArgTypes...)> _Fun; 641fe6060f1SDimitry Andric typedef allocator_traits<_Alloc> __alloc_traits; 642bdd1243dSDimitry Andric typedef __rebind_alloc<__alloc_traits, _Fun> _FunAlloc; 643fe6060f1SDimitry Andric 644cb14a3feSDimitry Andric if (__function::__not_null(__f)) { 645fe6060f1SDimitry Andric __invoker_ = __invoker::template __create<_Fun>(); 646fe6060f1SDimitry Andric __policy_ = __policy::__create<_Fun>(); 647fe6060f1SDimitry Andric 648fe6060f1SDimitry Andric _FunAlloc __af(__a); 649cb14a3feSDimitry Andric if (__use_small_storage<_Fun>()) { 650cb14a3feSDimitry Andric ::new ((void*)&__buf_.__small) _Fun(std::move(__f), _Alloc(__af)); 651cb14a3feSDimitry Andric } else { 652fe6060f1SDimitry Andric typedef __allocator_destructor<_FunAlloc> _Dp; 653fe6060f1SDimitry Andric unique_ptr<_Fun, _Dp> __hold(__af.allocate(1), _Dp(__af, 1)); 654cb14a3feSDimitry Andric ::new ((void*)__hold.get()) _Fun(std::move(__f), _Alloc(__af)); 655fe6060f1SDimitry Andric __buf_.__large = __hold.release(); 656fe6060f1SDimitry Andric } 657fe6060f1SDimitry Andric } 658fe6060f1SDimitry Andric } 659fe6060f1SDimitry Andric 6605f757f3fSDimitry Andric template <class _Fp, __enable_if_t<!is_same<__decay_t<_Fp>, __policy_func>::value, int> = 0> 661cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI explicit __policy_func(_Fp&& __f) : __policy_(__policy::__create_empty()) { 662fe6060f1SDimitry Andric typedef __default_alloc_func<_Fp, _Rp(_ArgTypes...)> _Fun; 663fe6060f1SDimitry Andric 664fe6060f1SDimitry Andric if (__function::__not_null(__f)) { 665fe6060f1SDimitry Andric __invoker_ = __invoker::template __create<_Fun>(); 666fe6060f1SDimitry Andric __policy_ = __policy::__create<_Fun>(); 667fe6060f1SDimitry Andric if (__use_small_storage<_Fun>()) { 6685f757f3fSDimitry Andric ::new ((void*)&__buf_.__small) _Fun(std::move(__f)); 669fe6060f1SDimitry Andric } else { 670cb14a3feSDimitry Andric __builtin_new_allocator::__holder_t __hold = __builtin_new_allocator::__allocate_type<_Fun>(1); 6715f757f3fSDimitry Andric __buf_.__large = ::new ((void*)__hold.get()) _Fun(std::move(__f)); 672fe6060f1SDimitry Andric (void)__hold.release(); 673fe6060f1SDimitry Andric } 674fe6060f1SDimitry Andric } 675fe6060f1SDimitry Andric } 676fe6060f1SDimitry Andric 677cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI __policy_func(const __policy_func& __f) 678cb14a3feSDimitry Andric : __buf_(__f.__buf_), __invoker_(__f.__invoker_), __policy_(__f.__policy_) { 679fe6060f1SDimitry Andric if (__policy_->__clone) 680fe6060f1SDimitry Andric __buf_.__large = __policy_->__clone(__f.__buf_.__large); 681fe6060f1SDimitry Andric } 682fe6060f1SDimitry Andric 683cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI __policy_func(__policy_func&& __f) 684cb14a3feSDimitry Andric : __buf_(__f.__buf_), __invoker_(__f.__invoker_), __policy_(__f.__policy_) { 685cb14a3feSDimitry Andric if (__policy_->__destroy) { 686fe6060f1SDimitry Andric __f.__policy_ = __policy::__create_empty(); 687fe6060f1SDimitry Andric __f.__invoker_ = __invoker(); 688fe6060f1SDimitry Andric } 689fe6060f1SDimitry Andric } 690fe6060f1SDimitry Andric 691cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI ~__policy_func() { 692fe6060f1SDimitry Andric if (__policy_->__destroy) 693fe6060f1SDimitry Andric __policy_->__destroy(__buf_.__large); 694fe6060f1SDimitry Andric } 695fe6060f1SDimitry Andric 696cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI __policy_func& operator=(__policy_func&& __f) { 697fe6060f1SDimitry Andric *this = nullptr; 698fe6060f1SDimitry Andric __buf_ = __f.__buf_; 699fe6060f1SDimitry Andric __invoker_ = __f.__invoker_; 700fe6060f1SDimitry Andric __policy_ = __f.__policy_; 701fe6060f1SDimitry Andric __f.__policy_ = __policy::__create_empty(); 702fe6060f1SDimitry Andric __f.__invoker_ = __invoker(); 703fe6060f1SDimitry Andric return *this; 704fe6060f1SDimitry Andric } 705fe6060f1SDimitry Andric 706cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI __policy_func& operator=(nullptr_t) { 707fe6060f1SDimitry Andric const __policy* __p = __policy_; 708fe6060f1SDimitry Andric __policy_ = __policy::__create_empty(); 709fe6060f1SDimitry Andric __invoker_ = __invoker(); 710fe6060f1SDimitry Andric if (__p->__destroy) 711fe6060f1SDimitry Andric __p->__destroy(__buf_.__large); 712fe6060f1SDimitry Andric return *this; 713fe6060f1SDimitry Andric } 714fe6060f1SDimitry Andric 715cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _Rp operator()(_ArgTypes&&... __args) const { 716cb14a3feSDimitry Andric return __invoker_.__call_(std::addressof(__buf_), std::forward<_ArgTypes>(__args)...); 717fe6060f1SDimitry Andric } 718fe6060f1SDimitry Andric 719cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI void swap(__policy_func& __f) { 7205f757f3fSDimitry Andric std::swap(__invoker_, __f.__invoker_); 7215f757f3fSDimitry Andric std::swap(__policy_, __f.__policy_); 7225f757f3fSDimitry Andric std::swap(__buf_, __f.__buf_); 723fe6060f1SDimitry Andric } 724fe6060f1SDimitry Andric 725cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI explicit operator bool() const _NOEXCEPT { return !__policy_->__is_null; } 726fe6060f1SDimitry Andric 7271ac55f4cSDimitry Andric # ifndef _LIBCPP_HAS_NO_RTTI 728cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI const std::type_info& target_type() const _NOEXCEPT { return *__policy_->__type_info; } 729fe6060f1SDimitry Andric 730fe6060f1SDimitry Andric template <typename _Tp> 731cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI const _Tp* target() const _NOEXCEPT { 732fe6060f1SDimitry Andric if (__policy_->__is_null || typeid(_Tp) != *__policy_->__type_info) 733fe6060f1SDimitry Andric return nullptr; 734fe6060f1SDimitry Andric if (__policy_->__clone) // Out of line storage. 735fe6060f1SDimitry Andric return reinterpret_cast<const _Tp*>(__buf_.__large); 736fe6060f1SDimitry Andric else 737fe6060f1SDimitry Andric return reinterpret_cast<const _Tp*>(&__buf_.__small); 738fe6060f1SDimitry Andric } 7391ac55f4cSDimitry Andric # endif // _LIBCPP_HAS_NO_RTTI 740fe6060f1SDimitry Andric }; 741fe6060f1SDimitry Andric 742f3fd488fSDimitry Andric # if defined(_LIBCPP_HAS_BLOCKS_RUNTIME) 743fe6060f1SDimitry Andric 744fe6060f1SDimitry Andric extern "C" void* _Block_copy(const void*); 745fe6060f1SDimitry Andric extern "C" void _Block_release(const void*); 746fe6060f1SDimitry Andric 747fe6060f1SDimitry Andric template <class _Rp1, class... _ArgTypes1, class _Alloc, class _Rp, class... _ArgTypes> 748cb14a3feSDimitry Andric class __func<_Rp1 (^)(_ArgTypes1...), _Alloc, _Rp(_ArgTypes...)> : public __base<_Rp(_ArgTypes...)> { 749fe6060f1SDimitry Andric typedef _Rp1 (^__block_type)(_ArgTypes1...); 750fe6060f1SDimitry Andric __block_type __f_; 751fe6060f1SDimitry Andric 752fe6060f1SDimitry Andric public: 753cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI explicit __func(__block_type const& __f) 754f3fd488fSDimitry Andric # ifdef _LIBCPP_HAS_OBJC_ARC 755f3fd488fSDimitry Andric : __f_(__f) 756f3fd488fSDimitry Andric # else 757fe6060f1SDimitry Andric : __f_(reinterpret_cast<__block_type>(__f ? _Block_copy(__f) : nullptr)) 758f3fd488fSDimitry Andric # endif 759cb14a3feSDimitry Andric { 760cb14a3feSDimitry Andric } 761fe6060f1SDimitry Andric 762fe6060f1SDimitry Andric // [TODO] add && to save on a retain 763fe6060f1SDimitry Andric 764cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI explicit __func(__block_type __f, const _Alloc& /* unused */) 765f3fd488fSDimitry Andric # ifdef _LIBCPP_HAS_OBJC_ARC 766f3fd488fSDimitry Andric : __f_(__f) 767f3fd488fSDimitry Andric # else 768fe6060f1SDimitry Andric : __f_(reinterpret_cast<__block_type>(__f ? _Block_copy(__f) : nullptr)) 769f3fd488fSDimitry Andric # endif 770cb14a3feSDimitry Andric { 771cb14a3feSDimitry Andric } 772fe6060f1SDimitry Andric 773*0fca6ea1SDimitry Andric _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual __base<_Rp(_ArgTypes...)>* __clone() const { 774cb14a3feSDimitry Andric _LIBCPP_ASSERT_INTERNAL( 775cb14a3feSDimitry Andric false, 776fe6060f1SDimitry Andric "Block pointers are just pointers, so they should always fit into " 777fe6060f1SDimitry Andric "std::function's small buffer optimization. This function should " 778fe6060f1SDimitry Andric "never be invoked."); 779fe6060f1SDimitry Andric return nullptr; 780fe6060f1SDimitry Andric } 781fe6060f1SDimitry Andric 782*0fca6ea1SDimitry Andric _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void __clone(__base<_Rp(_ArgTypes...)>* __p) const { 783*0fca6ea1SDimitry Andric ::new ((void*)__p) __func(__f_); 784*0fca6ea1SDimitry Andric } 785fe6060f1SDimitry Andric 786*0fca6ea1SDimitry Andric _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void destroy() _NOEXCEPT { 787f3fd488fSDimitry Andric # ifndef _LIBCPP_HAS_OBJC_ARC 788fe6060f1SDimitry Andric if (__f_) 789fe6060f1SDimitry Andric _Block_release(__f_); 790f3fd488fSDimitry Andric # endif 791fe6060f1SDimitry Andric __f_ = 0; 792fe6060f1SDimitry Andric } 793fe6060f1SDimitry Andric 794*0fca6ea1SDimitry Andric _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void destroy_deallocate() _NOEXCEPT { 795cb14a3feSDimitry Andric _LIBCPP_ASSERT_INTERNAL( 796cb14a3feSDimitry Andric false, 797fe6060f1SDimitry Andric "Block pointers are just pointers, so they should always fit into " 798fe6060f1SDimitry Andric "std::function's small buffer optimization. This function should " 799fe6060f1SDimitry Andric "never be invoked."); 800fe6060f1SDimitry Andric } 801fe6060f1SDimitry Andric 802*0fca6ea1SDimitry Andric _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual _Rp operator()(_ArgTypes&&... __arg) { 803*0fca6ea1SDimitry Andric return std::__invoke(__f_, std::forward<_ArgTypes>(__arg)...); 804*0fca6ea1SDimitry Andric } 805fe6060f1SDimitry Andric 8061ac55f4cSDimitry Andric # ifndef _LIBCPP_HAS_NO_RTTI 807*0fca6ea1SDimitry Andric _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual const void* target(type_info const& __ti) const _NOEXCEPT { 808fe6060f1SDimitry Andric if (__ti == typeid(__func::__block_type)) 809fe6060f1SDimitry Andric return &__f_; 810fe6060f1SDimitry Andric return (const void*)nullptr; 811fe6060f1SDimitry Andric } 812fe6060f1SDimitry Andric 813*0fca6ea1SDimitry Andric _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual const std::type_info& target_type() const _NOEXCEPT { 814*0fca6ea1SDimitry Andric return typeid(__func::__block_type); 815*0fca6ea1SDimitry Andric } 8161ac55f4cSDimitry Andric # endif // _LIBCPP_HAS_NO_RTTI 817fe6060f1SDimitry Andric }; 818fe6060f1SDimitry Andric 819f3fd488fSDimitry Andric # endif // _LIBCPP_HAS_EXTENSION_BLOCKS 820fe6060f1SDimitry Andric 8210eae32dcSDimitry Andric } // namespace __function 822fe6060f1SDimitry Andric 823fe6060f1SDimitry Andric template <class _Rp, class... _ArgTypes> 824fe6060f1SDimitry Andric class _LIBCPP_TEMPLATE_VIS function<_Rp(_ArgTypes...)> 825fe6060f1SDimitry Andric : public __function::__maybe_derive_from_unary_function<_Rp(_ArgTypes...)>, 826cb14a3feSDimitry Andric public __function::__maybe_derive_from_binary_function<_Rp(_ArgTypes...)> { 827fe6060f1SDimitry Andric # ifndef _LIBCPP_ABI_OPTIMIZED_FUNCTION 828fe6060f1SDimitry Andric typedef __function::__value_func<_Rp(_ArgTypes...)> __func; 829fe6060f1SDimitry Andric # else 830fe6060f1SDimitry Andric typedef __function::__policy_func<_Rp(_ArgTypes...)> __func; 831fe6060f1SDimitry Andric # endif 832fe6060f1SDimitry Andric 833fe6060f1SDimitry Andric __func __f_; 834fe6060f1SDimitry Andric 835cb14a3feSDimitry Andric template <class _Fp, 836cb14a3feSDimitry Andric bool = _And< _IsNotSame<__remove_cvref_t<_Fp>, function>, __invokable<_Fp, _ArgTypes...> >::value> 837fe6060f1SDimitry Andric struct __callable; 838fe6060f1SDimitry Andric template <class _Fp> 839cb14a3feSDimitry Andric struct __callable<_Fp, true> { 840cb14a3feSDimitry Andric static const bool value = 841cb14a3feSDimitry Andric is_void<_Rp>::value || __is_core_convertible<typename __invoke_of<_Fp, _ArgTypes...>::type, _Rp>::value; 842fe6060f1SDimitry Andric }; 843fe6060f1SDimitry Andric template <class _Fp> 844cb14a3feSDimitry Andric struct __callable<_Fp, false> { 845fe6060f1SDimitry Andric static const bool value = false; 846fe6060f1SDimitry Andric }; 847fe6060f1SDimitry Andric 848fe6060f1SDimitry Andric template <class _Fp> 8495f757f3fSDimitry Andric using _EnableIfLValueCallable = __enable_if_t<__callable<_Fp&>::value>; 850cb14a3feSDimitry Andric 851fe6060f1SDimitry Andric public: 852fe6060f1SDimitry Andric typedef _Rp result_type; 853fe6060f1SDimitry Andric 854fe6060f1SDimitry Andric // construct/copy/destroy: 855cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI function() _NOEXCEPT {} 856cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_HIDE_FROM_ABI function(nullptr_t) _NOEXCEPT {} 85706c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI function(const function&); 85806c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI function(function&&) _NOEXCEPT; 859fe6060f1SDimitry Andric template <class _Fp, class = _EnableIfLValueCallable<_Fp>> 86006c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI function(_Fp); 861fe6060f1SDimitry Andric 862fe6060f1SDimitry Andric # if _LIBCPP_STD_VER <= 14 863fe6060f1SDimitry Andric template <class _Alloc> 864cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI function(allocator_arg_t, const _Alloc&) _NOEXCEPT {} 865fe6060f1SDimitry Andric template <class _Alloc> 866cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI function(allocator_arg_t, const _Alloc&, nullptr_t) _NOEXCEPT {} 867fe6060f1SDimitry Andric template <class _Alloc> 86806c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI function(allocator_arg_t, const _Alloc&, const function&); 869fe6060f1SDimitry Andric template <class _Alloc> 87006c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI function(allocator_arg_t, const _Alloc&, function&&); 871fe6060f1SDimitry Andric template <class _Fp, class _Alloc, class = _EnableIfLValueCallable<_Fp>> 87206c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI function(allocator_arg_t, const _Alloc& __a, _Fp __f); 873fe6060f1SDimitry Andric # endif 874fe6060f1SDimitry Andric 87506c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI function& operator=(const function&); 87606c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI function& operator=(function&&) _NOEXCEPT; 87706c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI function& operator=(nullptr_t) _NOEXCEPT; 87806c3fb27SDimitry Andric template <class _Fp, class = _EnableIfLValueCallable<__decay_t<_Fp>>> 87906c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI function& operator=(_Fp&&); 880fe6060f1SDimitry Andric 88106c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI ~function(); 882fe6060f1SDimitry Andric 883fe6060f1SDimitry Andric // function modifiers: 88406c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI void swap(function&) _NOEXCEPT; 885fe6060f1SDimitry Andric 886fe6060f1SDimitry Andric # if _LIBCPP_STD_VER <= 14 887fe6060f1SDimitry Andric template <class _Fp, class _Alloc> 888cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI void assign(_Fp&& __f, const _Alloc& __a) { 889cb14a3feSDimitry Andric function(allocator_arg, __a, std::forward<_Fp>(__f)).swap(*this); 890cb14a3feSDimitry Andric } 891fe6060f1SDimitry Andric # endif 892fe6060f1SDimitry Andric 893fe6060f1SDimitry Andric // function capacity: 894cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI explicit operator bool() const _NOEXCEPT { return static_cast<bool>(__f_); } 895fe6060f1SDimitry Andric 896fe6060f1SDimitry Andric // deleted overloads close possible hole in the type system 897fe6060f1SDimitry Andric template <class _R2, class... _ArgTypes2> 898fe6060f1SDimitry Andric bool operator==(const function<_R2(_ArgTypes2...)>&) const = delete; 89906c3fb27SDimitry Andric # if _LIBCPP_STD_VER <= 17 900fe6060f1SDimitry Andric template <class _R2, class... _ArgTypes2> 901fe6060f1SDimitry Andric bool operator!=(const function<_R2(_ArgTypes2...)>&) const = delete; 90206c3fb27SDimitry Andric # endif 903cb14a3feSDimitry Andric 904fe6060f1SDimitry Andric public: 905fe6060f1SDimitry Andric // function invocation: 90606c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI _Rp operator()(_ArgTypes...) const; 907fe6060f1SDimitry Andric 9081ac55f4cSDimitry Andric # ifndef _LIBCPP_HAS_NO_RTTI 909fe6060f1SDimitry Andric // function target access: 91006c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI const std::type_info& target_type() const _NOEXCEPT; 91106c3fb27SDimitry Andric template <typename _Tp> 91206c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI _Tp* target() _NOEXCEPT; 91306c3fb27SDimitry Andric template <typename _Tp> 91406c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI const _Tp* target() const _NOEXCEPT; 9151ac55f4cSDimitry Andric # endif // _LIBCPP_HAS_NO_RTTI 916fe6060f1SDimitry Andric }; 917fe6060f1SDimitry Andric 918349cc55cSDimitry Andric # if _LIBCPP_STD_VER >= 17 919fe6060f1SDimitry Andric template <class _Rp, class... _Ap> 920fe6060f1SDimitry Andric function(_Rp (*)(_Ap...)) -> function<_Rp(_Ap...)>; 921fe6060f1SDimitry Andric 922fe6060f1SDimitry Andric template <class _Fp, class _Stripped = typename __strip_signature<decltype(&_Fp::operator())>::type> 923fe6060f1SDimitry Andric function(_Fp) -> function<_Stripped>; 924349cc55cSDimitry Andric # endif // _LIBCPP_STD_VER >= 17 925fe6060f1SDimitry Andric 926fe6060f1SDimitry Andric template <class _Rp, class... _ArgTypes> 927fe6060f1SDimitry Andric function<_Rp(_ArgTypes...)>::function(const function& __f) : __f_(__f.__f_) {} 928fe6060f1SDimitry Andric 929fe6060f1SDimitry Andric # if _LIBCPP_STD_VER <= 14 930fe6060f1SDimitry Andric template <class _Rp, class... _ArgTypes> 931fe6060f1SDimitry Andric template <class _Alloc> 932cb14a3feSDimitry Andric function<_Rp(_ArgTypes...)>::function(allocator_arg_t, const _Alloc&, const function& __f) : __f_(__f.__f_) {} 933fe6060f1SDimitry Andric # endif 934fe6060f1SDimitry Andric 935fe6060f1SDimitry Andric template <class _Rp, class... _ArgTypes> 936cb14a3feSDimitry Andric function<_Rp(_ArgTypes...)>::function(function&& __f) _NOEXCEPT : __f_(std::move(__f.__f_)) {} 937fe6060f1SDimitry Andric 938fe6060f1SDimitry Andric # if _LIBCPP_STD_VER <= 14 939fe6060f1SDimitry Andric template <class _Rp, class... _ArgTypes> 940fe6060f1SDimitry Andric template <class _Alloc> 941cb14a3feSDimitry Andric function<_Rp(_ArgTypes...)>::function(allocator_arg_t, const _Alloc&, function&& __f) : __f_(std::move(__f.__f_)) {} 942fe6060f1SDimitry Andric # endif 943fe6060f1SDimitry Andric 944fe6060f1SDimitry Andric template <class _Rp, class... _ArgTypes> 945fe6060f1SDimitry Andric template <class _Fp, class> 9465f757f3fSDimitry Andric function<_Rp(_ArgTypes...)>::function(_Fp __f) : __f_(std::move(__f)) {} 947fe6060f1SDimitry Andric 948fe6060f1SDimitry Andric # if _LIBCPP_STD_VER <= 14 949fe6060f1SDimitry Andric template <class _Rp, class... _ArgTypes> 950fe6060f1SDimitry Andric template <class _Fp, class _Alloc, class> 951cb14a3feSDimitry Andric function<_Rp(_ArgTypes...)>::function(allocator_arg_t, const _Alloc& __a, _Fp __f) : __f_(std::move(__f), __a) {} 952fe6060f1SDimitry Andric # endif 953fe6060f1SDimitry Andric 954fe6060f1SDimitry Andric template <class _Rp, class... _ArgTypes> 955cb14a3feSDimitry Andric function<_Rp(_ArgTypes...)>& function<_Rp(_ArgTypes...)>::operator=(const function& __f) { 956fe6060f1SDimitry Andric function(__f).swap(*this); 957fe6060f1SDimitry Andric return *this; 958fe6060f1SDimitry Andric } 959fe6060f1SDimitry Andric 960fe6060f1SDimitry Andric template <class _Rp, class... _ArgTypes> 961cb14a3feSDimitry Andric function<_Rp(_ArgTypes...)>& function<_Rp(_ArgTypes...)>::operator=(function&& __f) _NOEXCEPT { 9625f757f3fSDimitry Andric __f_ = std::move(__f.__f_); 963fe6060f1SDimitry Andric return *this; 964fe6060f1SDimitry Andric } 965fe6060f1SDimitry Andric 966fe6060f1SDimitry Andric template <class _Rp, class... _ArgTypes> 967cb14a3feSDimitry Andric function<_Rp(_ArgTypes...)>& function<_Rp(_ArgTypes...)>::operator=(nullptr_t) _NOEXCEPT { 968fe6060f1SDimitry Andric __f_ = nullptr; 969fe6060f1SDimitry Andric return *this; 970fe6060f1SDimitry Andric } 971fe6060f1SDimitry Andric 972fe6060f1SDimitry Andric template <class _Rp, class... _ArgTypes> 973fe6060f1SDimitry Andric template <class _Fp, class> 974cb14a3feSDimitry Andric function<_Rp(_ArgTypes...)>& function<_Rp(_ArgTypes...)>::operator=(_Fp&& __f) { 9755f757f3fSDimitry Andric function(std::forward<_Fp>(__f)).swap(*this); 976fe6060f1SDimitry Andric return *this; 977fe6060f1SDimitry Andric } 978fe6060f1SDimitry Andric 979fe6060f1SDimitry Andric template <class _Rp, class... _ArgTypes> 980fe6060f1SDimitry Andric function<_Rp(_ArgTypes...)>::~function() {} 981fe6060f1SDimitry Andric 982fe6060f1SDimitry Andric template <class _Rp, class... _ArgTypes> 983cb14a3feSDimitry Andric void function<_Rp(_ArgTypes...)>::swap(function& __f) _NOEXCEPT { 984fe6060f1SDimitry Andric __f_.swap(__f.__f_); 985fe6060f1SDimitry Andric } 986fe6060f1SDimitry Andric 987fe6060f1SDimitry Andric template <class _Rp, class... _ArgTypes> 988cb14a3feSDimitry Andric _Rp function<_Rp(_ArgTypes...)>::operator()(_ArgTypes... __arg) const { 9895f757f3fSDimitry Andric return __f_(std::forward<_ArgTypes>(__arg)...); 990fe6060f1SDimitry Andric } 991fe6060f1SDimitry Andric 9921ac55f4cSDimitry Andric # ifndef _LIBCPP_HAS_NO_RTTI 993fe6060f1SDimitry Andric 994fe6060f1SDimitry Andric template <class _Rp, class... _ArgTypes> 995cb14a3feSDimitry Andric const std::type_info& function<_Rp(_ArgTypes...)>::target_type() const _NOEXCEPT { 996fe6060f1SDimitry Andric return __f_.target_type(); 997fe6060f1SDimitry Andric } 998fe6060f1SDimitry Andric 999fe6060f1SDimitry Andric template <class _Rp, class... _ArgTypes> 1000fe6060f1SDimitry Andric template <typename _Tp> 1001cb14a3feSDimitry Andric _Tp* function<_Rp(_ArgTypes...)>::target() _NOEXCEPT { 1002fe6060f1SDimitry Andric return (_Tp*)(__f_.template target<_Tp>()); 1003fe6060f1SDimitry Andric } 1004fe6060f1SDimitry Andric 1005fe6060f1SDimitry Andric template <class _Rp, class... _ArgTypes> 1006fe6060f1SDimitry Andric template <typename _Tp> 1007cb14a3feSDimitry Andric const _Tp* function<_Rp(_ArgTypes...)>::target() const _NOEXCEPT { 1008fe6060f1SDimitry Andric return __f_.template target<_Tp>(); 1009fe6060f1SDimitry Andric } 1010fe6060f1SDimitry Andric 10111ac55f4cSDimitry Andric # endif // _LIBCPP_HAS_NO_RTTI 1012fe6060f1SDimitry Andric 1013fe6060f1SDimitry Andric template <class _Rp, class... _ArgTypes> 1014cb14a3feSDimitry Andric inline _LIBCPP_HIDE_FROM_ABI bool operator==(const function<_Rp(_ArgTypes...)>& __f, nullptr_t) _NOEXCEPT { 1015cb14a3feSDimitry Andric return !__f; 1016cb14a3feSDimitry Andric } 1017fe6060f1SDimitry Andric 101806c3fb27SDimitry Andric # if _LIBCPP_STD_VER <= 17 101906c3fb27SDimitry Andric 1020fe6060f1SDimitry Andric template <class _Rp, class... _ArgTypes> 1021cb14a3feSDimitry Andric inline _LIBCPP_HIDE_FROM_ABI bool operator==(nullptr_t, const function<_Rp(_ArgTypes...)>& __f) _NOEXCEPT { 1022cb14a3feSDimitry Andric return !__f; 1023cb14a3feSDimitry Andric } 1024fe6060f1SDimitry Andric 1025fe6060f1SDimitry Andric template <class _Rp, class... _ArgTypes> 1026cb14a3feSDimitry Andric inline _LIBCPP_HIDE_FROM_ABI bool operator!=(const function<_Rp(_ArgTypes...)>& __f, nullptr_t) _NOEXCEPT { 1027cb14a3feSDimitry Andric return (bool)__f; 1028cb14a3feSDimitry Andric } 1029fe6060f1SDimitry Andric 1030fe6060f1SDimitry Andric template <class _Rp, class... _ArgTypes> 1031cb14a3feSDimitry Andric inline _LIBCPP_HIDE_FROM_ABI bool operator!=(nullptr_t, const function<_Rp(_ArgTypes...)>& __f) _NOEXCEPT { 1032cb14a3feSDimitry Andric return (bool)__f; 1033cb14a3feSDimitry Andric } 1034fe6060f1SDimitry Andric 103506c3fb27SDimitry Andric # endif // _LIBCPP_STD_VER <= 17 103606c3fb27SDimitry Andric 1037fe6060f1SDimitry Andric template <class _Rp, class... _ArgTypes> 1038cb14a3feSDimitry Andric inline _LIBCPP_HIDE_FROM_ABI void swap(function<_Rp(_ArgTypes...)>& __x, function<_Rp(_ArgTypes...)>& __y) _NOEXCEPT { 1039cb14a3feSDimitry Andric return __x.swap(__y); 1040cb14a3feSDimitry Andric } 1041fe6060f1SDimitry Andric 1042bdd1243dSDimitry Andric _LIBCPP_END_NAMESPACE_STD 1043fe6060f1SDimitry Andric 104481ad6265SDimitry Andric #endif // _LIBCPP_CXX03_LANG 1045fe6060f1SDimitry Andric 1046b3edf446SDimitry Andric _LIBCPP_POP_MACROS 1047b3edf446SDimitry Andric 1048fe6060f1SDimitry Andric #endif // _LIBCPP___FUNCTIONAL_FUNCTION_H 1049