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> 15*06c3fb27SDimitry 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> 27*06c3fb27SDimitry Andric #include <__type_traits/aligned_storage.h> 28*06c3fb27SDimitry Andric #include <__type_traits/decay.h> 29*06c3fb27SDimitry Andric #include <__type_traits/is_core_convertible.h> 30*06c3fb27SDimitry Andric #include <__type_traits/is_scalar.h> 31*06c3fb27SDimitry Andric #include <__type_traits/is_trivially_copy_constructible.h> 32*06c3fb27SDimitry Andric #include <__type_traits/is_trivially_destructible.h> 33*06c3fb27SDimitry 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> 39*06c3fb27SDimitry Andric #include <__verbose_abort> 40bdd1243dSDimitry Andric #include <new> 41bdd1243dSDimitry Andric #include <tuple> 42bdd1243dSDimitry Andric #include <typeinfo> 43fe6060f1SDimitry Andric 44fe6060f1SDimitry Andric #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 45fe6060f1SDimitry Andric # pragma GCC system_header 46fe6060f1SDimitry Andric #endif 47fe6060f1SDimitry Andric 48bdd1243dSDimitry Andric #ifndef _LIBCPP_CXX03_LANG 49bdd1243dSDimitry Andric 50fe6060f1SDimitry Andric _LIBCPP_BEGIN_NAMESPACE_STD 51fe6060f1SDimitry Andric 52fe6060f1SDimitry Andric // bad_function_call 53fe6060f1SDimitry Andric 5481ad6265SDimitry Andric _LIBCPP_DIAGNOSTIC_PUSH 5581ad6265SDimitry Andric _LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wweak-vtables") 56*06c3fb27SDimitry Andric class _LIBCPP_EXPORTED_FROM_ABI bad_function_call 57fe6060f1SDimitry Andric : public exception 58fe6060f1SDimitry Andric { 59fe6060f1SDimitry Andric public: 60349cc55cSDimitry Andric // Note that when a key function is not used, every translation unit that uses 61349cc55cSDimitry Andric // bad_function_call will end up containing a weak definition of the vtable and 62349cc55cSDimitry Andric // typeinfo. 63349cc55cSDimitry Andric #ifdef _LIBCPP_ABI_BAD_FUNCTION_CALL_KEY_FUNCTION 64bdd1243dSDimitry Andric ~bad_function_call() _NOEXCEPT override; 65349cc55cSDimitry Andric #else 66*06c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI_VIRTUAL ~bad_function_call() _NOEXCEPT override {} 67349cc55cSDimitry Andric #endif 68fe6060f1SDimitry Andric 69349cc55cSDimitry Andric #ifdef _LIBCPP_ABI_BAD_FUNCTION_CALL_GOOD_WHAT_MESSAGE 70bdd1243dSDimitry Andric const char* what() const _NOEXCEPT override; 71fe6060f1SDimitry Andric #endif 72fe6060f1SDimitry Andric }; 7381ad6265SDimitry Andric _LIBCPP_DIAGNOSTIC_POP 74fe6060f1SDimitry Andric 75fe6060f1SDimitry Andric _LIBCPP_NORETURN inline _LIBCPP_INLINE_VISIBILITY 76fe6060f1SDimitry Andric void __throw_bad_function_call() 77fe6060f1SDimitry Andric { 78*06c3fb27SDimitry Andric #ifndef _LIBCPP_HAS_NO_EXCEPTIONS 79fe6060f1SDimitry Andric throw bad_function_call(); 80fe6060f1SDimitry Andric #else 81*06c3fb27SDimitry Andric _LIBCPP_VERBOSE_ABORT("bad_function_call was thrown in -fno-exceptions mode"); 82fe6060f1SDimitry Andric #endif 83fe6060f1SDimitry Andric } 84fe6060f1SDimitry Andric 85bdd1243dSDimitry Andric template<class _Fp> class _LIBCPP_TEMPLATE_VIS function; // undefined 86fe6060f1SDimitry Andric 87fe6060f1SDimitry Andric namespace __function 88fe6060f1SDimitry Andric { 89fe6060f1SDimitry Andric 90fe6060f1SDimitry Andric template<class _Rp> 91fe6060f1SDimitry Andric struct __maybe_derive_from_unary_function 92fe6060f1SDimitry Andric { 93fe6060f1SDimitry Andric }; 94fe6060f1SDimitry Andric 95fe6060f1SDimitry Andric template<class _Rp, class _A1> 96fe6060f1SDimitry Andric struct __maybe_derive_from_unary_function<_Rp(_A1)> 9781ad6265SDimitry Andric : public __unary_function<_A1, _Rp> 98fe6060f1SDimitry Andric { 99fe6060f1SDimitry Andric }; 100fe6060f1SDimitry Andric 101fe6060f1SDimitry Andric template<class _Rp> 102fe6060f1SDimitry Andric struct __maybe_derive_from_binary_function 103fe6060f1SDimitry Andric { 104fe6060f1SDimitry Andric }; 105fe6060f1SDimitry Andric 106fe6060f1SDimitry Andric template<class _Rp, class _A1, class _A2> 107fe6060f1SDimitry Andric struct __maybe_derive_from_binary_function<_Rp(_A1, _A2)> 10881ad6265SDimitry Andric : public __binary_function<_A1, _A2, _Rp> 109fe6060f1SDimitry Andric { 110fe6060f1SDimitry Andric }; 111fe6060f1SDimitry Andric 112fe6060f1SDimitry Andric template <class _Fp> 113fe6060f1SDimitry Andric _LIBCPP_INLINE_VISIBILITY 114fe6060f1SDimitry Andric bool __not_null(_Fp const&) { return true; } 115fe6060f1SDimitry Andric 116fe6060f1SDimitry Andric template <class _Fp> 117fe6060f1SDimitry Andric _LIBCPP_INLINE_VISIBILITY 118fe6060f1SDimitry Andric bool __not_null(_Fp* __ptr) { return __ptr; } 119fe6060f1SDimitry Andric 120fe6060f1SDimitry Andric template <class _Ret, class _Class> 121fe6060f1SDimitry Andric _LIBCPP_INLINE_VISIBILITY 122fe6060f1SDimitry Andric bool __not_null(_Ret _Class::*__ptr) { return __ptr; } 123fe6060f1SDimitry Andric 124fe6060f1SDimitry Andric template <class _Fp> 125fe6060f1SDimitry Andric _LIBCPP_INLINE_VISIBILITY 126fe6060f1SDimitry Andric bool __not_null(function<_Fp> const& __f) { return !!__f; } 127fe6060f1SDimitry Andric 128fe6060f1SDimitry Andric #ifdef _LIBCPP_HAS_EXTENSION_BLOCKS 129fe6060f1SDimitry Andric template <class _Rp, class ..._Args> 130fe6060f1SDimitry Andric _LIBCPP_INLINE_VISIBILITY 131fe6060f1SDimitry Andric bool __not_null(_Rp (^__p)(_Args...)) { return __p; } 132fe6060f1SDimitry Andric #endif 133fe6060f1SDimitry Andric 134fe6060f1SDimitry Andric } // namespace __function 135fe6060f1SDimitry Andric 136fe6060f1SDimitry Andric namespace __function { 137fe6060f1SDimitry Andric 138fe6060f1SDimitry Andric // __alloc_func holds a functor and an allocator. 139fe6060f1SDimitry Andric 140fe6060f1SDimitry Andric template <class _Fp, class _Ap, class _FB> 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> 145fe6060f1SDimitry Andric class __alloc_func<_Fp, _Ap, _Rp(_ArgTypes...)> 146fe6060f1SDimitry Andric { 147fe6060f1SDimitry Andric __compressed_pair<_Fp, _Ap> __f_; 148fe6060f1SDimitry Andric 149fe6060f1SDimitry Andric public: 150349cc55cSDimitry Andric typedef _LIBCPP_NODEBUG _Fp _Target; 151349cc55cSDimitry Andric typedef _LIBCPP_NODEBUG _Ap _Alloc; 152fe6060f1SDimitry Andric 153fe6060f1SDimitry Andric _LIBCPP_INLINE_VISIBILITY 154fe6060f1SDimitry Andric const _Target& __target() const { return __f_.first(); } 155fe6060f1SDimitry Andric 156fe6060f1SDimitry Andric // WIN32 APIs may define __allocator, so use __get_allocator instead. 157fe6060f1SDimitry Andric _LIBCPP_INLINE_VISIBILITY 158fe6060f1SDimitry Andric const _Alloc& __get_allocator() const { return __f_.second(); } 159fe6060f1SDimitry Andric 160fe6060f1SDimitry Andric _LIBCPP_INLINE_VISIBILITY 161fe6060f1SDimitry Andric explicit __alloc_func(_Target&& __f) 162fe6060f1SDimitry Andric : __f_(piecewise_construct, _VSTD::forward_as_tuple(_VSTD::move(__f)), 163fe6060f1SDimitry Andric _VSTD::forward_as_tuple()) 164fe6060f1SDimitry Andric { 165fe6060f1SDimitry Andric } 166fe6060f1SDimitry Andric 167fe6060f1SDimitry Andric _LIBCPP_INLINE_VISIBILITY 168fe6060f1SDimitry Andric explicit __alloc_func(const _Target& __f, const _Alloc& __a) 169fe6060f1SDimitry Andric : __f_(piecewise_construct, _VSTD::forward_as_tuple(__f), 170fe6060f1SDimitry Andric _VSTD::forward_as_tuple(__a)) 171fe6060f1SDimitry Andric { 172fe6060f1SDimitry Andric } 173fe6060f1SDimitry Andric 174fe6060f1SDimitry Andric _LIBCPP_INLINE_VISIBILITY 175fe6060f1SDimitry Andric explicit __alloc_func(const _Target& __f, _Alloc&& __a) 176fe6060f1SDimitry Andric : __f_(piecewise_construct, _VSTD::forward_as_tuple(__f), 177fe6060f1SDimitry Andric _VSTD::forward_as_tuple(_VSTD::move(__a))) 178fe6060f1SDimitry Andric { 179fe6060f1SDimitry Andric } 180fe6060f1SDimitry Andric 181fe6060f1SDimitry Andric _LIBCPP_INLINE_VISIBILITY 182fe6060f1SDimitry Andric explicit __alloc_func(_Target&& __f, _Alloc&& __a) 183fe6060f1SDimitry Andric : __f_(piecewise_construct, _VSTD::forward_as_tuple(_VSTD::move(__f)), 184fe6060f1SDimitry Andric _VSTD::forward_as_tuple(_VSTD::move(__a))) 185fe6060f1SDimitry Andric { 186fe6060f1SDimitry Andric } 187fe6060f1SDimitry Andric 188fe6060f1SDimitry Andric _LIBCPP_INLINE_VISIBILITY 189fe6060f1SDimitry Andric _Rp operator()(_ArgTypes&&... __arg) 190fe6060f1SDimitry Andric { 191fe6060f1SDimitry Andric typedef __invoke_void_return_wrapper<_Rp> _Invoker; 192fe6060f1SDimitry Andric return _Invoker::__call(__f_.first(), 193fe6060f1SDimitry Andric _VSTD::forward<_ArgTypes>(__arg)...); 194fe6060f1SDimitry Andric } 195fe6060f1SDimitry Andric 196fe6060f1SDimitry Andric _LIBCPP_INLINE_VISIBILITY 197fe6060f1SDimitry Andric __alloc_func* __clone() const 198fe6060f1SDimitry Andric { 199fe6060f1SDimitry Andric typedef allocator_traits<_Alloc> __alloc_traits; 200bdd1243dSDimitry Andric typedef __rebind_alloc<__alloc_traits, __alloc_func> _AA; 201fe6060f1SDimitry Andric _AA __a(__f_.second()); 202fe6060f1SDimitry Andric typedef __allocator_destructor<_AA> _Dp; 203fe6060f1SDimitry Andric unique_ptr<__alloc_func, _Dp> __hold(__a.allocate(1), _Dp(__a, 1)); 204fe6060f1SDimitry Andric ::new ((void*)__hold.get()) __alloc_func(__f_.first(), _Alloc(__a)); 205fe6060f1SDimitry Andric return __hold.release(); 206fe6060f1SDimitry Andric } 207fe6060f1SDimitry Andric 208fe6060f1SDimitry Andric _LIBCPP_INLINE_VISIBILITY 209fe6060f1SDimitry Andric void destroy() _NOEXCEPT { __f_.~__compressed_pair<_Target, _Alloc>(); } 210fe6060f1SDimitry Andric 211*06c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI static void __destroy_and_delete(__alloc_func* __f) { 212fe6060f1SDimitry Andric typedef allocator_traits<_Alloc> __alloc_traits; 213bdd1243dSDimitry Andric typedef __rebind_alloc<__alloc_traits, __alloc_func> _FunAlloc; 214fe6060f1SDimitry Andric _FunAlloc __a(__f->__get_allocator()); 215fe6060f1SDimitry Andric __f->destroy(); 216fe6060f1SDimitry Andric __a.deallocate(__f, 1); 217fe6060f1SDimitry Andric } 218fe6060f1SDimitry Andric }; 219fe6060f1SDimitry Andric 220fe6060f1SDimitry Andric template <class _Fp, class _Rp, class... _ArgTypes> 221fe6060f1SDimitry Andric class __default_alloc_func<_Fp, _Rp(_ArgTypes...)> { 222fe6060f1SDimitry Andric _Fp __f_; 223fe6060f1SDimitry Andric 224fe6060f1SDimitry Andric public: 225349cc55cSDimitry Andric typedef _LIBCPP_NODEBUG _Fp _Target; 226fe6060f1SDimitry Andric 227fe6060f1SDimitry Andric _LIBCPP_INLINE_VISIBILITY 228fe6060f1SDimitry Andric const _Target& __target() const { return __f_; } 229fe6060f1SDimitry Andric 230fe6060f1SDimitry Andric _LIBCPP_INLINE_VISIBILITY 231fe6060f1SDimitry Andric explicit __default_alloc_func(_Target&& __f) : __f_(_VSTD::move(__f)) {} 232fe6060f1SDimitry Andric 233fe6060f1SDimitry Andric _LIBCPP_INLINE_VISIBILITY 234fe6060f1SDimitry Andric explicit __default_alloc_func(const _Target& __f) : __f_(__f) {} 235fe6060f1SDimitry Andric 236fe6060f1SDimitry Andric _LIBCPP_INLINE_VISIBILITY 237fe6060f1SDimitry Andric _Rp operator()(_ArgTypes&&... __arg) { 238fe6060f1SDimitry Andric typedef __invoke_void_return_wrapper<_Rp> _Invoker; 239fe6060f1SDimitry Andric return _Invoker::__call(__f_, _VSTD::forward<_ArgTypes>(__arg)...); 240fe6060f1SDimitry Andric } 241fe6060f1SDimitry Andric 242fe6060f1SDimitry Andric _LIBCPP_INLINE_VISIBILITY 243fe6060f1SDimitry Andric __default_alloc_func* __clone() const { 244fe6060f1SDimitry Andric __builtin_new_allocator::__holder_t __hold = 245fe6060f1SDimitry Andric __builtin_new_allocator::__allocate_type<__default_alloc_func>(1); 246fe6060f1SDimitry Andric __default_alloc_func* __res = 247fe6060f1SDimitry Andric ::new ((void*)__hold.get()) __default_alloc_func(__f_); 248fe6060f1SDimitry Andric (void)__hold.release(); 249fe6060f1SDimitry Andric return __res; 250fe6060f1SDimitry Andric } 251fe6060f1SDimitry Andric 252fe6060f1SDimitry Andric _LIBCPP_INLINE_VISIBILITY 253fe6060f1SDimitry Andric void destroy() _NOEXCEPT { __f_.~_Target(); } 254fe6060f1SDimitry Andric 255*06c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI static void __destroy_and_delete(__default_alloc_func* __f) { 256fe6060f1SDimitry Andric __f->destroy(); 257fe6060f1SDimitry Andric __builtin_new_allocator::__deallocate_type<__default_alloc_func>(__f, 1); 258fe6060f1SDimitry Andric } 259fe6060f1SDimitry Andric }; 260fe6060f1SDimitry Andric 261fe6060f1SDimitry Andric // __base provides an abstract interface for copyable functors. 262fe6060f1SDimitry Andric 263fe6060f1SDimitry Andric template<class _Fp> class _LIBCPP_TEMPLATE_VIS __base; 264fe6060f1SDimitry Andric 265fe6060f1SDimitry Andric template<class _Rp, class ..._ArgTypes> 266fe6060f1SDimitry Andric class __base<_Rp(_ArgTypes...)> 267fe6060f1SDimitry Andric { 268fe6060f1SDimitry Andric __base(const __base&); 269fe6060f1SDimitry Andric __base& operator=(const __base&); 270fe6060f1SDimitry Andric public: 271fe6060f1SDimitry Andric _LIBCPP_INLINE_VISIBILITY __base() {} 272bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual ~__base() {} 273fe6060f1SDimitry Andric virtual __base* __clone() const = 0; 274fe6060f1SDimitry Andric virtual void __clone(__base*) const = 0; 275fe6060f1SDimitry Andric virtual void destroy() _NOEXCEPT = 0; 276fe6060f1SDimitry Andric virtual void destroy_deallocate() _NOEXCEPT = 0; 277fe6060f1SDimitry Andric virtual _Rp operator()(_ArgTypes&& ...) = 0; 2781ac55f4cSDimitry Andric #ifndef _LIBCPP_HAS_NO_RTTI 279fe6060f1SDimitry Andric virtual const void* target(const type_info&) const _NOEXCEPT = 0; 280fe6060f1SDimitry Andric virtual const std::type_info& target_type() const _NOEXCEPT = 0; 2811ac55f4cSDimitry Andric #endif // _LIBCPP_HAS_NO_RTTI 282fe6060f1SDimitry Andric }; 283fe6060f1SDimitry Andric 284fe6060f1SDimitry Andric // __func implements __base for a given functor type. 285fe6060f1SDimitry Andric 286fe6060f1SDimitry Andric template<class _FD, class _Alloc, class _FB> class __func; 287fe6060f1SDimitry Andric 288fe6060f1SDimitry Andric template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes> 289fe6060f1SDimitry Andric class __func<_Fp, _Alloc, _Rp(_ArgTypes...)> 290fe6060f1SDimitry Andric : public __base<_Rp(_ArgTypes...)> 291fe6060f1SDimitry Andric { 292fe6060f1SDimitry Andric __alloc_func<_Fp, _Alloc, _Rp(_ArgTypes...)> __f_; 293fe6060f1SDimitry Andric public: 294fe6060f1SDimitry Andric _LIBCPP_INLINE_VISIBILITY 295fe6060f1SDimitry Andric explicit __func(_Fp&& __f) 296fe6060f1SDimitry Andric : __f_(_VSTD::move(__f)) {} 297fe6060f1SDimitry Andric 298fe6060f1SDimitry Andric _LIBCPP_INLINE_VISIBILITY 299fe6060f1SDimitry Andric explicit __func(const _Fp& __f, const _Alloc& __a) 300fe6060f1SDimitry Andric : __f_(__f, __a) {} 301fe6060f1SDimitry Andric 302fe6060f1SDimitry Andric _LIBCPP_INLINE_VISIBILITY 303fe6060f1SDimitry Andric explicit __func(const _Fp& __f, _Alloc&& __a) 304fe6060f1SDimitry Andric : __f_(__f, _VSTD::move(__a)) {} 305fe6060f1SDimitry Andric 306fe6060f1SDimitry Andric _LIBCPP_INLINE_VISIBILITY 307fe6060f1SDimitry Andric explicit __func(_Fp&& __f, _Alloc&& __a) 308fe6060f1SDimitry Andric : __f_(_VSTD::move(__f), _VSTD::move(__a)) {} 309fe6060f1SDimitry Andric 310*06c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual __base<_Rp(_ArgTypes...)>* __clone() const; 311*06c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void __clone(__base<_Rp(_ArgTypes...)>*) const; 312*06c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void destroy() _NOEXCEPT; 313*06c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void destroy_deallocate() _NOEXCEPT; 314*06c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual _Rp operator()(_ArgTypes&&... __arg); 3151ac55f4cSDimitry Andric #ifndef _LIBCPP_HAS_NO_RTTI 316*06c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual const void* target(const type_info&) const _NOEXCEPT; 317*06c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual const std::type_info& target_type() const _NOEXCEPT; 3181ac55f4cSDimitry Andric #endif // _LIBCPP_HAS_NO_RTTI 319fe6060f1SDimitry Andric }; 320fe6060f1SDimitry Andric 321fe6060f1SDimitry Andric template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes> 322fe6060f1SDimitry Andric __base<_Rp(_ArgTypes...)>* 323fe6060f1SDimitry Andric __func<_Fp, _Alloc, _Rp(_ArgTypes...)>::__clone() const 324fe6060f1SDimitry Andric { 325fe6060f1SDimitry Andric typedef allocator_traits<_Alloc> __alloc_traits; 326bdd1243dSDimitry Andric typedef __rebind_alloc<__alloc_traits, __func> _Ap; 327fe6060f1SDimitry Andric _Ap __a(__f_.__get_allocator()); 328fe6060f1SDimitry Andric typedef __allocator_destructor<_Ap> _Dp; 329fe6060f1SDimitry Andric unique_ptr<__func, _Dp> __hold(__a.allocate(1), _Dp(__a, 1)); 330fe6060f1SDimitry Andric ::new ((void*)__hold.get()) __func(__f_.__target(), _Alloc(__a)); 331fe6060f1SDimitry Andric return __hold.release(); 332fe6060f1SDimitry Andric } 333fe6060f1SDimitry Andric 334fe6060f1SDimitry Andric template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes> 335fe6060f1SDimitry Andric void 336fe6060f1SDimitry Andric __func<_Fp, _Alloc, _Rp(_ArgTypes...)>::__clone(__base<_Rp(_ArgTypes...)>* __p) const 337fe6060f1SDimitry Andric { 338fe6060f1SDimitry Andric ::new ((void*)__p) __func(__f_.__target(), __f_.__get_allocator()); 339fe6060f1SDimitry Andric } 340fe6060f1SDimitry Andric 341fe6060f1SDimitry Andric template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes> 342fe6060f1SDimitry Andric void 343fe6060f1SDimitry Andric __func<_Fp, _Alloc, _Rp(_ArgTypes...)>::destroy() _NOEXCEPT 344fe6060f1SDimitry Andric { 345fe6060f1SDimitry Andric __f_.destroy(); 346fe6060f1SDimitry Andric } 347fe6060f1SDimitry Andric 348fe6060f1SDimitry Andric template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes> 349fe6060f1SDimitry Andric void 350fe6060f1SDimitry Andric __func<_Fp, _Alloc, _Rp(_ArgTypes...)>::destroy_deallocate() _NOEXCEPT 351fe6060f1SDimitry Andric { 352fe6060f1SDimitry Andric typedef allocator_traits<_Alloc> __alloc_traits; 353bdd1243dSDimitry Andric typedef __rebind_alloc<__alloc_traits, __func> _Ap; 354fe6060f1SDimitry Andric _Ap __a(__f_.__get_allocator()); 355fe6060f1SDimitry Andric __f_.destroy(); 356fe6060f1SDimitry Andric __a.deallocate(this, 1); 357fe6060f1SDimitry Andric } 358fe6060f1SDimitry Andric 359fe6060f1SDimitry Andric template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes> 360fe6060f1SDimitry Andric _Rp 361fe6060f1SDimitry Andric __func<_Fp, _Alloc, _Rp(_ArgTypes...)>::operator()(_ArgTypes&& ... __arg) 362fe6060f1SDimitry Andric { 363fe6060f1SDimitry Andric return __f_(_VSTD::forward<_ArgTypes>(__arg)...); 364fe6060f1SDimitry Andric } 365fe6060f1SDimitry Andric 3661ac55f4cSDimitry Andric #ifndef _LIBCPP_HAS_NO_RTTI 367fe6060f1SDimitry Andric 368fe6060f1SDimitry Andric template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes> 369fe6060f1SDimitry Andric const void* 370fe6060f1SDimitry Andric __func<_Fp, _Alloc, _Rp(_ArgTypes...)>::target(const type_info& __ti) const _NOEXCEPT 371fe6060f1SDimitry Andric { 372fe6060f1SDimitry Andric if (__ti == typeid(_Fp)) 37304eeddc0SDimitry Andric return _VSTD::addressof(__f_.__target()); 374fe6060f1SDimitry Andric return nullptr; 375fe6060f1SDimitry Andric } 376fe6060f1SDimitry Andric 377fe6060f1SDimitry Andric template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes> 378fe6060f1SDimitry Andric const std::type_info& 379fe6060f1SDimitry Andric __func<_Fp, _Alloc, _Rp(_ArgTypes...)>::target_type() const _NOEXCEPT 380fe6060f1SDimitry Andric { 381fe6060f1SDimitry Andric return typeid(_Fp); 382fe6060f1SDimitry Andric } 383fe6060f1SDimitry Andric 3841ac55f4cSDimitry Andric #endif // _LIBCPP_HAS_NO_RTTI 385fe6060f1SDimitry Andric 386fe6060f1SDimitry Andric // __value_func creates a value-type from a __func. 387fe6060f1SDimitry Andric 388fe6060f1SDimitry Andric template <class _Fp> class __value_func; 389fe6060f1SDimitry Andric 390fe6060f1SDimitry Andric template <class _Rp, class... _ArgTypes> class __value_func<_Rp(_ArgTypes...)> 391fe6060f1SDimitry Andric { 392bdd1243dSDimitry Andric _LIBCPP_SUPPRESS_DEPRECATED_PUSH 393fe6060f1SDimitry Andric typename aligned_storage<3 * sizeof(void*)>::type __buf_; 394bdd1243dSDimitry Andric _LIBCPP_SUPPRESS_DEPRECATED_POP 395fe6060f1SDimitry Andric 396fe6060f1SDimitry Andric typedef __base<_Rp(_ArgTypes...)> __func; 397fe6060f1SDimitry Andric __func* __f_; 398fe6060f1SDimitry Andric 399*06c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_NO_CFI static __func* __as_base(void* __p) 400fe6060f1SDimitry Andric { 401753f127fSDimitry Andric return reinterpret_cast<__func*>(__p); 402fe6060f1SDimitry Andric } 403fe6060f1SDimitry Andric 404fe6060f1SDimitry Andric public: 405fe6060f1SDimitry Andric _LIBCPP_INLINE_VISIBILITY 406fe6060f1SDimitry Andric __value_func() _NOEXCEPT : __f_(nullptr) {} 407fe6060f1SDimitry Andric 408fe6060f1SDimitry Andric template <class _Fp, class _Alloc> 409fe6060f1SDimitry Andric _LIBCPP_INLINE_VISIBILITY __value_func(_Fp&& __f, const _Alloc& __a) 410fe6060f1SDimitry Andric : __f_(nullptr) 411fe6060f1SDimitry Andric { 412fe6060f1SDimitry Andric typedef allocator_traits<_Alloc> __alloc_traits; 413fe6060f1SDimitry Andric typedef __function::__func<_Fp, _Alloc, _Rp(_ArgTypes...)> _Fun; 414bdd1243dSDimitry Andric typedef __rebind_alloc<__alloc_traits, _Fun> _FunAlloc; 415fe6060f1SDimitry Andric 416fe6060f1SDimitry Andric if (__function::__not_null(__f)) 417fe6060f1SDimitry Andric { 418fe6060f1SDimitry Andric _FunAlloc __af(__a); 419fe6060f1SDimitry Andric if (sizeof(_Fun) <= sizeof(__buf_) && 420fe6060f1SDimitry Andric is_nothrow_copy_constructible<_Fp>::value && 421fe6060f1SDimitry Andric is_nothrow_copy_constructible<_FunAlloc>::value) 422fe6060f1SDimitry Andric { 423fe6060f1SDimitry Andric __f_ = 424fe6060f1SDimitry Andric ::new ((void*)&__buf_) _Fun(_VSTD::move(__f), _Alloc(__af)); 425fe6060f1SDimitry Andric } 426fe6060f1SDimitry Andric else 427fe6060f1SDimitry Andric { 428fe6060f1SDimitry Andric typedef __allocator_destructor<_FunAlloc> _Dp; 429fe6060f1SDimitry Andric unique_ptr<__func, _Dp> __hold(__af.allocate(1), _Dp(__af, 1)); 430fe6060f1SDimitry Andric ::new ((void*)__hold.get()) _Fun(_VSTD::move(__f), _Alloc(__a)); 431fe6060f1SDimitry Andric __f_ = __hold.release(); 432fe6060f1SDimitry Andric } 433fe6060f1SDimitry Andric } 434fe6060f1SDimitry Andric } 435fe6060f1SDimitry Andric 436fe6060f1SDimitry Andric template <class _Fp, 437*06c3fb27SDimitry Andric class = typename enable_if<!is_same<__decay_t<_Fp>, __value_func>::value>::type> 438fe6060f1SDimitry Andric _LIBCPP_INLINE_VISIBILITY explicit __value_func(_Fp&& __f) 439fe6060f1SDimitry Andric : __value_func(_VSTD::forward<_Fp>(__f), allocator<_Fp>()) {} 440fe6060f1SDimitry Andric 441fe6060f1SDimitry Andric _LIBCPP_INLINE_VISIBILITY 442fe6060f1SDimitry Andric __value_func(const __value_func& __f) 443fe6060f1SDimitry Andric { 444fe6060f1SDimitry Andric if (__f.__f_ == nullptr) 445fe6060f1SDimitry Andric __f_ = nullptr; 446fe6060f1SDimitry Andric else if ((void*)__f.__f_ == &__f.__buf_) 447fe6060f1SDimitry Andric { 448fe6060f1SDimitry Andric __f_ = __as_base(&__buf_); 449fe6060f1SDimitry Andric __f.__f_->__clone(__f_); 450fe6060f1SDimitry Andric } 451fe6060f1SDimitry Andric else 452fe6060f1SDimitry Andric __f_ = __f.__f_->__clone(); 453fe6060f1SDimitry Andric } 454fe6060f1SDimitry Andric 455fe6060f1SDimitry Andric _LIBCPP_INLINE_VISIBILITY 456fe6060f1SDimitry Andric __value_func(__value_func&& __f) _NOEXCEPT 457fe6060f1SDimitry Andric { 458fe6060f1SDimitry Andric if (__f.__f_ == nullptr) 459fe6060f1SDimitry Andric __f_ = nullptr; 460fe6060f1SDimitry Andric else if ((void*)__f.__f_ == &__f.__buf_) 461fe6060f1SDimitry Andric { 462fe6060f1SDimitry Andric __f_ = __as_base(&__buf_); 463fe6060f1SDimitry Andric __f.__f_->__clone(__f_); 464fe6060f1SDimitry Andric } 465fe6060f1SDimitry Andric else 466fe6060f1SDimitry Andric { 467fe6060f1SDimitry Andric __f_ = __f.__f_; 468fe6060f1SDimitry Andric __f.__f_ = nullptr; 469fe6060f1SDimitry Andric } 470fe6060f1SDimitry Andric } 471fe6060f1SDimitry Andric 472fe6060f1SDimitry Andric _LIBCPP_INLINE_VISIBILITY 473fe6060f1SDimitry Andric ~__value_func() 474fe6060f1SDimitry Andric { 475fe6060f1SDimitry Andric if ((void*)__f_ == &__buf_) 476fe6060f1SDimitry Andric __f_->destroy(); 477fe6060f1SDimitry Andric else if (__f_) 478fe6060f1SDimitry Andric __f_->destroy_deallocate(); 479fe6060f1SDimitry Andric } 480fe6060f1SDimitry Andric 481fe6060f1SDimitry Andric _LIBCPP_INLINE_VISIBILITY 482fe6060f1SDimitry Andric __value_func& operator=(__value_func&& __f) 483fe6060f1SDimitry Andric { 484fe6060f1SDimitry Andric *this = nullptr; 485fe6060f1SDimitry Andric if (__f.__f_ == nullptr) 486fe6060f1SDimitry Andric __f_ = nullptr; 487fe6060f1SDimitry Andric else if ((void*)__f.__f_ == &__f.__buf_) 488fe6060f1SDimitry Andric { 489fe6060f1SDimitry Andric __f_ = __as_base(&__buf_); 490fe6060f1SDimitry Andric __f.__f_->__clone(__f_); 491fe6060f1SDimitry Andric } 492fe6060f1SDimitry Andric else 493fe6060f1SDimitry Andric { 494fe6060f1SDimitry Andric __f_ = __f.__f_; 495fe6060f1SDimitry Andric __f.__f_ = nullptr; 496fe6060f1SDimitry Andric } 497fe6060f1SDimitry Andric return *this; 498fe6060f1SDimitry Andric } 499fe6060f1SDimitry Andric 500fe6060f1SDimitry Andric _LIBCPP_INLINE_VISIBILITY 501fe6060f1SDimitry Andric __value_func& operator=(nullptr_t) 502fe6060f1SDimitry Andric { 503fe6060f1SDimitry Andric __func* __f = __f_; 504fe6060f1SDimitry Andric __f_ = nullptr; 505fe6060f1SDimitry Andric if ((void*)__f == &__buf_) 506fe6060f1SDimitry Andric __f->destroy(); 507fe6060f1SDimitry Andric else if (__f) 508fe6060f1SDimitry Andric __f->destroy_deallocate(); 509fe6060f1SDimitry Andric return *this; 510fe6060f1SDimitry Andric } 511fe6060f1SDimitry Andric 512fe6060f1SDimitry Andric _LIBCPP_INLINE_VISIBILITY 513fe6060f1SDimitry Andric _Rp operator()(_ArgTypes&&... __args) const 514fe6060f1SDimitry Andric { 515fe6060f1SDimitry Andric if (__f_ == nullptr) 516fe6060f1SDimitry Andric __throw_bad_function_call(); 517fe6060f1SDimitry Andric return (*__f_)(_VSTD::forward<_ArgTypes>(__args)...); 518fe6060f1SDimitry Andric } 519fe6060f1SDimitry Andric 520fe6060f1SDimitry Andric _LIBCPP_INLINE_VISIBILITY 521fe6060f1SDimitry Andric void swap(__value_func& __f) _NOEXCEPT 522fe6060f1SDimitry Andric { 523fe6060f1SDimitry Andric if (&__f == this) 524fe6060f1SDimitry Andric return; 525fe6060f1SDimitry Andric if ((void*)__f_ == &__buf_ && (void*)__f.__f_ == &__f.__buf_) 526fe6060f1SDimitry Andric { 527bdd1243dSDimitry Andric _LIBCPP_SUPPRESS_DEPRECATED_PUSH 528fe6060f1SDimitry Andric typename aligned_storage<sizeof(__buf_)>::type __tempbuf; 529bdd1243dSDimitry Andric _LIBCPP_SUPPRESS_DEPRECATED_POP 530fe6060f1SDimitry Andric __func* __t = __as_base(&__tempbuf); 531fe6060f1SDimitry Andric __f_->__clone(__t); 532fe6060f1SDimitry Andric __f_->destroy(); 533fe6060f1SDimitry Andric __f_ = nullptr; 534fe6060f1SDimitry Andric __f.__f_->__clone(__as_base(&__buf_)); 535fe6060f1SDimitry Andric __f.__f_->destroy(); 536fe6060f1SDimitry Andric __f.__f_ = nullptr; 537fe6060f1SDimitry Andric __f_ = __as_base(&__buf_); 538fe6060f1SDimitry Andric __t->__clone(__as_base(&__f.__buf_)); 539fe6060f1SDimitry Andric __t->destroy(); 540fe6060f1SDimitry Andric __f.__f_ = __as_base(&__f.__buf_); 541fe6060f1SDimitry Andric } 542fe6060f1SDimitry Andric else if ((void*)__f_ == &__buf_) 543fe6060f1SDimitry Andric { 544fe6060f1SDimitry Andric __f_->__clone(__as_base(&__f.__buf_)); 545fe6060f1SDimitry Andric __f_->destroy(); 546fe6060f1SDimitry Andric __f_ = __f.__f_; 547fe6060f1SDimitry Andric __f.__f_ = __as_base(&__f.__buf_); 548fe6060f1SDimitry Andric } 549fe6060f1SDimitry Andric else if ((void*)__f.__f_ == &__f.__buf_) 550fe6060f1SDimitry Andric { 551fe6060f1SDimitry Andric __f.__f_->__clone(__as_base(&__buf_)); 552fe6060f1SDimitry Andric __f.__f_->destroy(); 553fe6060f1SDimitry Andric __f.__f_ = __f_; 554fe6060f1SDimitry Andric __f_ = __as_base(&__buf_); 555fe6060f1SDimitry Andric } 556fe6060f1SDimitry Andric else 557fe6060f1SDimitry Andric _VSTD::swap(__f_, __f.__f_); 558fe6060f1SDimitry Andric } 559fe6060f1SDimitry Andric 560fe6060f1SDimitry Andric _LIBCPP_INLINE_VISIBILITY 561fe6060f1SDimitry Andric explicit operator bool() const _NOEXCEPT { return __f_ != nullptr; } 562fe6060f1SDimitry Andric 5631ac55f4cSDimitry Andric #ifndef _LIBCPP_HAS_NO_RTTI 564fe6060f1SDimitry Andric _LIBCPP_INLINE_VISIBILITY 565fe6060f1SDimitry Andric const std::type_info& target_type() const _NOEXCEPT 566fe6060f1SDimitry Andric { 567fe6060f1SDimitry Andric if (__f_ == nullptr) 568fe6060f1SDimitry Andric return typeid(void); 569fe6060f1SDimitry Andric return __f_->target_type(); 570fe6060f1SDimitry Andric } 571fe6060f1SDimitry Andric 572fe6060f1SDimitry Andric template <typename _Tp> 573fe6060f1SDimitry Andric _LIBCPP_INLINE_VISIBILITY const _Tp* target() const _NOEXCEPT 574fe6060f1SDimitry Andric { 575fe6060f1SDimitry Andric if (__f_ == nullptr) 576fe6060f1SDimitry Andric return nullptr; 577fe6060f1SDimitry Andric return (const _Tp*)__f_->target(typeid(_Tp)); 578fe6060f1SDimitry Andric } 5791ac55f4cSDimitry Andric #endif // _LIBCPP_HAS_NO_RTTI 580fe6060f1SDimitry Andric }; 581fe6060f1SDimitry Andric 582fe6060f1SDimitry Andric // Storage for a functor object, to be used with __policy to manage copy and 583fe6060f1SDimitry Andric // destruction. 584fe6060f1SDimitry Andric union __policy_storage 585fe6060f1SDimitry Andric { 586fe6060f1SDimitry Andric mutable char __small[sizeof(void*) * 2]; 587fe6060f1SDimitry Andric void* __large; 588fe6060f1SDimitry Andric }; 589fe6060f1SDimitry Andric 590fe6060f1SDimitry Andric // True if _Fun can safely be held in __policy_storage.__small. 591fe6060f1SDimitry Andric template <typename _Fun> 592fe6060f1SDimitry Andric struct __use_small_storage 593fe6060f1SDimitry Andric : public integral_constant< 594fe6060f1SDimitry Andric bool, sizeof(_Fun) <= sizeof(__policy_storage) && 595fe6060f1SDimitry Andric _LIBCPP_ALIGNOF(_Fun) <= _LIBCPP_ALIGNOF(__policy_storage) && 596fe6060f1SDimitry Andric is_trivially_copy_constructible<_Fun>::value && 597fe6060f1SDimitry Andric is_trivially_destructible<_Fun>::value> {}; 598fe6060f1SDimitry Andric 599fe6060f1SDimitry Andric // Policy contains information about how to copy, destroy, and move the 600fe6060f1SDimitry Andric // underlying functor. You can think of it as a vtable of sorts. 601fe6060f1SDimitry Andric struct __policy 602fe6060f1SDimitry Andric { 603fe6060f1SDimitry Andric // Used to copy or destroy __large values. null for trivial objects. 604fe6060f1SDimitry Andric void* (*const __clone)(const void*); 605fe6060f1SDimitry Andric void (*const __destroy)(void*); 606fe6060f1SDimitry Andric 607fe6060f1SDimitry Andric // True if this is the null policy (no value). 608fe6060f1SDimitry Andric const bool __is_null; 609fe6060f1SDimitry Andric 610fe6060f1SDimitry Andric // The target type. May be null if RTTI is disabled. 611fe6060f1SDimitry Andric const std::type_info* const __type_info; 612fe6060f1SDimitry Andric 613fe6060f1SDimitry Andric // Returns a pointer to a static policy object suitable for the functor 614fe6060f1SDimitry Andric // type. 615fe6060f1SDimitry Andric template <typename _Fun> 616fe6060f1SDimitry Andric _LIBCPP_INLINE_VISIBILITY static const __policy* __create() 617fe6060f1SDimitry Andric { 618fe6060f1SDimitry Andric return __choose_policy<_Fun>(__use_small_storage<_Fun>()); 619fe6060f1SDimitry Andric } 620fe6060f1SDimitry Andric 621fe6060f1SDimitry Andric _LIBCPP_INLINE_VISIBILITY 622fe6060f1SDimitry Andric static const __policy* __create_empty() 623fe6060f1SDimitry Andric { 624*06c3fb27SDimitry Andric static const _LIBCPP_CONSTEXPR __policy __policy = {nullptr, nullptr, 625fe6060f1SDimitry Andric true, 6261ac55f4cSDimitry Andric #ifndef _LIBCPP_HAS_NO_RTTI 627fe6060f1SDimitry Andric &typeid(void) 628fe6060f1SDimitry Andric #else 629fe6060f1SDimitry Andric nullptr 630fe6060f1SDimitry Andric #endif 631fe6060f1SDimitry Andric }; 632*06c3fb27SDimitry Andric return &__policy; 633fe6060f1SDimitry Andric } 634fe6060f1SDimitry Andric 635fe6060f1SDimitry Andric private: 636*06c3fb27SDimitry Andric template <typename _Fun> 637*06c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI static void* __large_clone(const void* __s) 638fe6060f1SDimitry Andric { 639fe6060f1SDimitry Andric const _Fun* __f = static_cast<const _Fun*>(__s); 640fe6060f1SDimitry Andric return __f->__clone(); 641fe6060f1SDimitry Andric } 642fe6060f1SDimitry Andric 643fe6060f1SDimitry Andric template <typename _Fun> 644*06c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI static void __large_destroy(void* __s) { 645fe6060f1SDimitry Andric _Fun::__destroy_and_delete(static_cast<_Fun*>(__s)); 646fe6060f1SDimitry Andric } 647fe6060f1SDimitry Andric 648fe6060f1SDimitry Andric template <typename _Fun> 649fe6060f1SDimitry Andric _LIBCPP_INLINE_VISIBILITY static const __policy* 650fe6060f1SDimitry Andric __choose_policy(/* is_small = */ false_type) { 651*06c3fb27SDimitry Andric static const _LIBCPP_CONSTEXPR __policy __policy = { 652fe6060f1SDimitry Andric &__large_clone<_Fun>, &__large_destroy<_Fun>, false, 6531ac55f4cSDimitry Andric #ifndef _LIBCPP_HAS_NO_RTTI 654fe6060f1SDimitry Andric &typeid(typename _Fun::_Target) 655fe6060f1SDimitry Andric #else 656fe6060f1SDimitry Andric nullptr 657fe6060f1SDimitry Andric #endif 658fe6060f1SDimitry Andric }; 659*06c3fb27SDimitry Andric return &__policy; 660fe6060f1SDimitry Andric } 661fe6060f1SDimitry Andric 662fe6060f1SDimitry Andric template <typename _Fun> 663fe6060f1SDimitry Andric _LIBCPP_INLINE_VISIBILITY static const __policy* 664fe6060f1SDimitry Andric __choose_policy(/* is_small = */ true_type) 665fe6060f1SDimitry Andric { 666*06c3fb27SDimitry Andric static const _LIBCPP_CONSTEXPR __policy __policy = { 667fe6060f1SDimitry Andric nullptr, nullptr, false, 6681ac55f4cSDimitry Andric #ifndef _LIBCPP_HAS_NO_RTTI 669fe6060f1SDimitry Andric &typeid(typename _Fun::_Target) 670fe6060f1SDimitry Andric #else 671fe6060f1SDimitry Andric nullptr 672fe6060f1SDimitry Andric #endif 673fe6060f1SDimitry Andric }; 674*06c3fb27SDimitry Andric return &__policy; 675fe6060f1SDimitry Andric } 676fe6060f1SDimitry Andric }; 677fe6060f1SDimitry Andric 678fe6060f1SDimitry Andric // Used to choose between perfect forwarding or pass-by-value. Pass-by-value is 679fe6060f1SDimitry Andric // faster for types that can be passed in registers. 680fe6060f1SDimitry Andric template <typename _Tp> 681bdd1243dSDimitry Andric using __fast_forward = __conditional_t<is_scalar<_Tp>::value, _Tp, _Tp&&>; 682fe6060f1SDimitry Andric 683fe6060f1SDimitry Andric // __policy_invoker calls an instance of __alloc_func held in __policy_storage. 684fe6060f1SDimitry Andric 685fe6060f1SDimitry Andric template <class _Fp> struct __policy_invoker; 686fe6060f1SDimitry Andric 687fe6060f1SDimitry Andric template <class _Rp, class... _ArgTypes> 688fe6060f1SDimitry Andric struct __policy_invoker<_Rp(_ArgTypes...)> 689fe6060f1SDimitry Andric { 690fe6060f1SDimitry Andric typedef _Rp (*__Call)(const __policy_storage*, 691fe6060f1SDimitry Andric __fast_forward<_ArgTypes>...); 692fe6060f1SDimitry Andric 693fe6060f1SDimitry Andric __Call __call_; 694fe6060f1SDimitry Andric 695fe6060f1SDimitry Andric // Creates an invoker that throws bad_function_call. 696fe6060f1SDimitry Andric _LIBCPP_INLINE_VISIBILITY 697fe6060f1SDimitry Andric __policy_invoker() : __call_(&__call_empty) {} 698fe6060f1SDimitry Andric 699fe6060f1SDimitry Andric // Creates an invoker that calls the given instance of __func. 700fe6060f1SDimitry Andric template <typename _Fun> 701fe6060f1SDimitry Andric _LIBCPP_INLINE_VISIBILITY static __policy_invoker __create() 702fe6060f1SDimitry Andric { 703fe6060f1SDimitry Andric return __policy_invoker(&__call_impl<_Fun>); 704fe6060f1SDimitry Andric } 705fe6060f1SDimitry Andric 706fe6060f1SDimitry Andric private: 707fe6060f1SDimitry Andric _LIBCPP_INLINE_VISIBILITY 708fe6060f1SDimitry Andric explicit __policy_invoker(__Call __c) : __call_(__c) {} 709fe6060f1SDimitry Andric 710*06c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI static _Rp __call_empty(const __policy_storage*, 711fe6060f1SDimitry Andric __fast_forward<_ArgTypes>...) 712fe6060f1SDimitry Andric { 713fe6060f1SDimitry Andric __throw_bad_function_call(); 714fe6060f1SDimitry Andric } 715fe6060f1SDimitry Andric 716fe6060f1SDimitry Andric template <typename _Fun> 717*06c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI static _Rp __call_impl(const __policy_storage* __buf, 718fe6060f1SDimitry Andric __fast_forward<_ArgTypes>... __args) 719fe6060f1SDimitry Andric { 720fe6060f1SDimitry Andric _Fun* __f = reinterpret_cast<_Fun*>(__use_small_storage<_Fun>::value 721fe6060f1SDimitry Andric ? &__buf->__small 722fe6060f1SDimitry Andric : __buf->__large); 723fe6060f1SDimitry Andric return (*__f)(_VSTD::forward<_ArgTypes>(__args)...); 724fe6060f1SDimitry Andric } 725fe6060f1SDimitry Andric }; 726fe6060f1SDimitry Andric 727fe6060f1SDimitry Andric // __policy_func uses a __policy and __policy_invoker to create a type-erased, 728fe6060f1SDimitry Andric // copyable functor. 729fe6060f1SDimitry Andric 730fe6060f1SDimitry Andric template <class _Fp> class __policy_func; 731fe6060f1SDimitry Andric 732fe6060f1SDimitry Andric template <class _Rp, class... _ArgTypes> class __policy_func<_Rp(_ArgTypes...)> 733fe6060f1SDimitry Andric { 734fe6060f1SDimitry Andric // Inline storage for small objects. 735fe6060f1SDimitry Andric __policy_storage __buf_; 736fe6060f1SDimitry Andric 737fe6060f1SDimitry Andric // Calls the value stored in __buf_. This could technically be part of 738fe6060f1SDimitry Andric // policy, but storing it here eliminates a level of indirection inside 739fe6060f1SDimitry Andric // operator(). 740fe6060f1SDimitry Andric typedef __function::__policy_invoker<_Rp(_ArgTypes...)> __invoker; 741fe6060f1SDimitry Andric __invoker __invoker_; 742fe6060f1SDimitry Andric 743fe6060f1SDimitry Andric // The policy that describes how to move / copy / destroy __buf_. Never 744fe6060f1SDimitry Andric // null, even if the function is empty. 745fe6060f1SDimitry Andric const __policy* __policy_; 746fe6060f1SDimitry Andric 747fe6060f1SDimitry Andric public: 748fe6060f1SDimitry Andric _LIBCPP_INLINE_VISIBILITY 749fe6060f1SDimitry Andric __policy_func() : __policy_(__policy::__create_empty()) {} 750fe6060f1SDimitry Andric 751fe6060f1SDimitry Andric template <class _Fp, class _Alloc> 752fe6060f1SDimitry Andric _LIBCPP_INLINE_VISIBILITY __policy_func(_Fp&& __f, const _Alloc& __a) 753fe6060f1SDimitry Andric : __policy_(__policy::__create_empty()) 754fe6060f1SDimitry Andric { 755fe6060f1SDimitry Andric typedef __alloc_func<_Fp, _Alloc, _Rp(_ArgTypes...)> _Fun; 756fe6060f1SDimitry Andric typedef allocator_traits<_Alloc> __alloc_traits; 757bdd1243dSDimitry Andric typedef __rebind_alloc<__alloc_traits, _Fun> _FunAlloc; 758fe6060f1SDimitry Andric 759fe6060f1SDimitry Andric if (__function::__not_null(__f)) 760fe6060f1SDimitry Andric { 761fe6060f1SDimitry Andric __invoker_ = __invoker::template __create<_Fun>(); 762fe6060f1SDimitry Andric __policy_ = __policy::__create<_Fun>(); 763fe6060f1SDimitry Andric 764fe6060f1SDimitry Andric _FunAlloc __af(__a); 765fe6060f1SDimitry Andric if (__use_small_storage<_Fun>()) 766fe6060f1SDimitry Andric { 767fe6060f1SDimitry Andric ::new ((void*)&__buf_.__small) 768fe6060f1SDimitry Andric _Fun(_VSTD::move(__f), _Alloc(__af)); 769fe6060f1SDimitry Andric } 770fe6060f1SDimitry Andric else 771fe6060f1SDimitry Andric { 772fe6060f1SDimitry Andric typedef __allocator_destructor<_FunAlloc> _Dp; 773fe6060f1SDimitry Andric unique_ptr<_Fun, _Dp> __hold(__af.allocate(1), _Dp(__af, 1)); 774fe6060f1SDimitry Andric ::new ((void*)__hold.get()) 775fe6060f1SDimitry Andric _Fun(_VSTD::move(__f), _Alloc(__af)); 776fe6060f1SDimitry Andric __buf_.__large = __hold.release(); 777fe6060f1SDimitry Andric } 778fe6060f1SDimitry Andric } 779fe6060f1SDimitry Andric } 780fe6060f1SDimitry Andric 781*06c3fb27SDimitry Andric template <class _Fp, class = typename enable_if<!is_same<__decay_t<_Fp>, __policy_func>::value>::type> 782fe6060f1SDimitry Andric _LIBCPP_INLINE_VISIBILITY explicit __policy_func(_Fp&& __f) 783fe6060f1SDimitry Andric : __policy_(__policy::__create_empty()) { 784fe6060f1SDimitry Andric typedef __default_alloc_func<_Fp, _Rp(_ArgTypes...)> _Fun; 785fe6060f1SDimitry Andric 786fe6060f1SDimitry Andric if (__function::__not_null(__f)) { 787fe6060f1SDimitry Andric __invoker_ = __invoker::template __create<_Fun>(); 788fe6060f1SDimitry Andric __policy_ = __policy::__create<_Fun>(); 789fe6060f1SDimitry Andric if (__use_small_storage<_Fun>()) { 790fe6060f1SDimitry Andric ::new ((void*)&__buf_.__small) _Fun(_VSTD::move(__f)); 791fe6060f1SDimitry Andric } else { 792fe6060f1SDimitry Andric __builtin_new_allocator::__holder_t __hold = 793fe6060f1SDimitry Andric __builtin_new_allocator::__allocate_type<_Fun>(1); 794fe6060f1SDimitry Andric __buf_.__large = ::new ((void*)__hold.get()) _Fun(_VSTD::move(__f)); 795fe6060f1SDimitry Andric (void)__hold.release(); 796fe6060f1SDimitry Andric } 797fe6060f1SDimitry Andric } 798fe6060f1SDimitry Andric } 799fe6060f1SDimitry Andric 800fe6060f1SDimitry Andric _LIBCPP_INLINE_VISIBILITY 801fe6060f1SDimitry Andric __policy_func(const __policy_func& __f) 802fe6060f1SDimitry Andric : __buf_(__f.__buf_), __invoker_(__f.__invoker_), 803fe6060f1SDimitry Andric __policy_(__f.__policy_) 804fe6060f1SDimitry Andric { 805fe6060f1SDimitry Andric if (__policy_->__clone) 806fe6060f1SDimitry Andric __buf_.__large = __policy_->__clone(__f.__buf_.__large); 807fe6060f1SDimitry Andric } 808fe6060f1SDimitry Andric 809fe6060f1SDimitry Andric _LIBCPP_INLINE_VISIBILITY 810fe6060f1SDimitry Andric __policy_func(__policy_func&& __f) 811fe6060f1SDimitry Andric : __buf_(__f.__buf_), __invoker_(__f.__invoker_), 812fe6060f1SDimitry Andric __policy_(__f.__policy_) 813fe6060f1SDimitry Andric { 814fe6060f1SDimitry Andric if (__policy_->__destroy) 815fe6060f1SDimitry Andric { 816fe6060f1SDimitry Andric __f.__policy_ = __policy::__create_empty(); 817fe6060f1SDimitry Andric __f.__invoker_ = __invoker(); 818fe6060f1SDimitry Andric } 819fe6060f1SDimitry Andric } 820fe6060f1SDimitry Andric 821fe6060f1SDimitry Andric _LIBCPP_INLINE_VISIBILITY 822fe6060f1SDimitry Andric ~__policy_func() 823fe6060f1SDimitry Andric { 824fe6060f1SDimitry Andric if (__policy_->__destroy) 825fe6060f1SDimitry Andric __policy_->__destroy(__buf_.__large); 826fe6060f1SDimitry Andric } 827fe6060f1SDimitry Andric 828fe6060f1SDimitry Andric _LIBCPP_INLINE_VISIBILITY 829fe6060f1SDimitry Andric __policy_func& operator=(__policy_func&& __f) 830fe6060f1SDimitry Andric { 831fe6060f1SDimitry Andric *this = nullptr; 832fe6060f1SDimitry Andric __buf_ = __f.__buf_; 833fe6060f1SDimitry Andric __invoker_ = __f.__invoker_; 834fe6060f1SDimitry Andric __policy_ = __f.__policy_; 835fe6060f1SDimitry Andric __f.__policy_ = __policy::__create_empty(); 836fe6060f1SDimitry Andric __f.__invoker_ = __invoker(); 837fe6060f1SDimitry Andric return *this; 838fe6060f1SDimitry Andric } 839fe6060f1SDimitry Andric 840fe6060f1SDimitry Andric _LIBCPP_INLINE_VISIBILITY 841fe6060f1SDimitry Andric __policy_func& operator=(nullptr_t) 842fe6060f1SDimitry Andric { 843fe6060f1SDimitry Andric const __policy* __p = __policy_; 844fe6060f1SDimitry Andric __policy_ = __policy::__create_empty(); 845fe6060f1SDimitry Andric __invoker_ = __invoker(); 846fe6060f1SDimitry Andric if (__p->__destroy) 847fe6060f1SDimitry Andric __p->__destroy(__buf_.__large); 848fe6060f1SDimitry Andric return *this; 849fe6060f1SDimitry Andric } 850fe6060f1SDimitry Andric 851fe6060f1SDimitry Andric _LIBCPP_INLINE_VISIBILITY 852fe6060f1SDimitry Andric _Rp operator()(_ArgTypes&&... __args) const 853fe6060f1SDimitry Andric { 854fe6060f1SDimitry Andric return __invoker_.__call_(_VSTD::addressof(__buf_), 855fe6060f1SDimitry Andric _VSTD::forward<_ArgTypes>(__args)...); 856fe6060f1SDimitry Andric } 857fe6060f1SDimitry Andric 858fe6060f1SDimitry Andric _LIBCPP_INLINE_VISIBILITY 859fe6060f1SDimitry Andric void swap(__policy_func& __f) 860fe6060f1SDimitry Andric { 861fe6060f1SDimitry Andric _VSTD::swap(__invoker_, __f.__invoker_); 862fe6060f1SDimitry Andric _VSTD::swap(__policy_, __f.__policy_); 863fe6060f1SDimitry Andric _VSTD::swap(__buf_, __f.__buf_); 864fe6060f1SDimitry Andric } 865fe6060f1SDimitry Andric 866fe6060f1SDimitry Andric _LIBCPP_INLINE_VISIBILITY 867fe6060f1SDimitry Andric explicit operator bool() const _NOEXCEPT 868fe6060f1SDimitry Andric { 869fe6060f1SDimitry Andric return !__policy_->__is_null; 870fe6060f1SDimitry Andric } 871fe6060f1SDimitry Andric 8721ac55f4cSDimitry Andric #ifndef _LIBCPP_HAS_NO_RTTI 873fe6060f1SDimitry Andric _LIBCPP_INLINE_VISIBILITY 874fe6060f1SDimitry Andric const std::type_info& target_type() const _NOEXCEPT 875fe6060f1SDimitry Andric { 876fe6060f1SDimitry Andric return *__policy_->__type_info; 877fe6060f1SDimitry Andric } 878fe6060f1SDimitry Andric 879fe6060f1SDimitry Andric template <typename _Tp> 880fe6060f1SDimitry Andric _LIBCPP_INLINE_VISIBILITY const _Tp* target() const _NOEXCEPT 881fe6060f1SDimitry Andric { 882fe6060f1SDimitry Andric if (__policy_->__is_null || typeid(_Tp) != *__policy_->__type_info) 883fe6060f1SDimitry Andric return nullptr; 884fe6060f1SDimitry Andric if (__policy_->__clone) // Out of line storage. 885fe6060f1SDimitry Andric return reinterpret_cast<const _Tp*>(__buf_.__large); 886fe6060f1SDimitry Andric else 887fe6060f1SDimitry Andric return reinterpret_cast<const _Tp*>(&__buf_.__small); 888fe6060f1SDimitry Andric } 8891ac55f4cSDimitry Andric #endif // _LIBCPP_HAS_NO_RTTI 890fe6060f1SDimitry Andric }; 891fe6060f1SDimitry Andric 892f3fd488fSDimitry Andric #if defined(_LIBCPP_HAS_BLOCKS_RUNTIME) 893fe6060f1SDimitry Andric 894fe6060f1SDimitry Andric extern "C" void *_Block_copy(const void *); 895fe6060f1SDimitry Andric extern "C" void _Block_release(const void *); 896fe6060f1SDimitry Andric 897fe6060f1SDimitry Andric template<class _Rp1, class ..._ArgTypes1, class _Alloc, class _Rp, class ..._ArgTypes> 898fe6060f1SDimitry Andric class __func<_Rp1(^)(_ArgTypes1...), _Alloc, _Rp(_ArgTypes...)> 899fe6060f1SDimitry Andric : public __base<_Rp(_ArgTypes...)> 900fe6060f1SDimitry Andric { 901fe6060f1SDimitry Andric typedef _Rp1(^__block_type)(_ArgTypes1...); 902fe6060f1SDimitry Andric __block_type __f_; 903fe6060f1SDimitry Andric 904fe6060f1SDimitry Andric public: 905fe6060f1SDimitry Andric _LIBCPP_INLINE_VISIBILITY 906fe6060f1SDimitry Andric explicit __func(__block_type const& __f) 907f3fd488fSDimitry Andric #ifdef _LIBCPP_HAS_OBJC_ARC 908f3fd488fSDimitry Andric : __f_(__f) 909f3fd488fSDimitry Andric #else 910fe6060f1SDimitry Andric : __f_(reinterpret_cast<__block_type>(__f ? _Block_copy(__f) : nullptr)) 911f3fd488fSDimitry Andric #endif 912fe6060f1SDimitry Andric { } 913fe6060f1SDimitry Andric 914fe6060f1SDimitry Andric // [TODO] add && to save on a retain 915fe6060f1SDimitry Andric 916fe6060f1SDimitry Andric _LIBCPP_INLINE_VISIBILITY 917fe6060f1SDimitry Andric explicit __func(__block_type __f, const _Alloc& /* unused */) 918f3fd488fSDimitry Andric #ifdef _LIBCPP_HAS_OBJC_ARC 919f3fd488fSDimitry Andric : __f_(__f) 920f3fd488fSDimitry Andric #else 921fe6060f1SDimitry Andric : __f_(reinterpret_cast<__block_type>(__f ? _Block_copy(__f) : nullptr)) 922f3fd488fSDimitry Andric #endif 923fe6060f1SDimitry Andric { } 924fe6060f1SDimitry Andric 925fe6060f1SDimitry Andric virtual __base<_Rp(_ArgTypes...)>* __clone() const { 926*06c3fb27SDimitry Andric _LIBCPP_ASSERT_INTERNAL(false, 927fe6060f1SDimitry Andric "Block pointers are just pointers, so they should always fit into " 928fe6060f1SDimitry Andric "std::function's small buffer optimization. This function should " 929fe6060f1SDimitry Andric "never be invoked."); 930fe6060f1SDimitry Andric return nullptr; 931fe6060f1SDimitry Andric } 932fe6060f1SDimitry Andric 933fe6060f1SDimitry Andric virtual void __clone(__base<_Rp(_ArgTypes...)>* __p) const { 934fe6060f1SDimitry Andric ::new ((void*)__p) __func(__f_); 935fe6060f1SDimitry Andric } 936fe6060f1SDimitry Andric 937fe6060f1SDimitry Andric virtual void destroy() _NOEXCEPT { 938f3fd488fSDimitry Andric #ifndef _LIBCPP_HAS_OBJC_ARC 939fe6060f1SDimitry Andric if (__f_) 940fe6060f1SDimitry Andric _Block_release(__f_); 941f3fd488fSDimitry Andric #endif 942fe6060f1SDimitry Andric __f_ = 0; 943fe6060f1SDimitry Andric } 944fe6060f1SDimitry Andric 945fe6060f1SDimitry Andric virtual void destroy_deallocate() _NOEXCEPT { 946*06c3fb27SDimitry Andric _LIBCPP_ASSERT_INTERNAL(false, 947fe6060f1SDimitry Andric "Block pointers are just pointers, so they should always fit into " 948fe6060f1SDimitry Andric "std::function's small buffer optimization. This function should " 949fe6060f1SDimitry Andric "never be invoked."); 950fe6060f1SDimitry Andric } 951fe6060f1SDimitry Andric 952fe6060f1SDimitry Andric virtual _Rp operator()(_ArgTypes&& ... __arg) { 953fe6060f1SDimitry Andric return _VSTD::__invoke(__f_, _VSTD::forward<_ArgTypes>(__arg)...); 954fe6060f1SDimitry Andric } 955fe6060f1SDimitry Andric 9561ac55f4cSDimitry Andric #ifndef _LIBCPP_HAS_NO_RTTI 957fe6060f1SDimitry Andric virtual const void* target(type_info const& __ti) const _NOEXCEPT { 958fe6060f1SDimitry Andric if (__ti == typeid(__func::__block_type)) 959fe6060f1SDimitry Andric return &__f_; 960fe6060f1SDimitry Andric return (const void*)nullptr; 961fe6060f1SDimitry Andric } 962fe6060f1SDimitry Andric 963fe6060f1SDimitry Andric virtual const std::type_info& target_type() const _NOEXCEPT { 964fe6060f1SDimitry Andric return typeid(__func::__block_type); 965fe6060f1SDimitry Andric } 9661ac55f4cSDimitry Andric #endif // _LIBCPP_HAS_NO_RTTI 967fe6060f1SDimitry Andric }; 968fe6060f1SDimitry Andric 969f3fd488fSDimitry Andric #endif // _LIBCPP_HAS_EXTENSION_BLOCKS 970fe6060f1SDimitry Andric 9710eae32dcSDimitry Andric } // namespace __function 972fe6060f1SDimitry Andric 973fe6060f1SDimitry Andric template<class _Rp, class ..._ArgTypes> 974fe6060f1SDimitry Andric class _LIBCPP_TEMPLATE_VIS function<_Rp(_ArgTypes...)> 975fe6060f1SDimitry Andric : public __function::__maybe_derive_from_unary_function<_Rp(_ArgTypes...)>, 976fe6060f1SDimitry Andric public __function::__maybe_derive_from_binary_function<_Rp(_ArgTypes...)> 977fe6060f1SDimitry Andric { 978fe6060f1SDimitry Andric #ifndef _LIBCPP_ABI_OPTIMIZED_FUNCTION 979fe6060f1SDimitry Andric typedef __function::__value_func<_Rp(_ArgTypes...)> __func; 980fe6060f1SDimitry Andric #else 981fe6060f1SDimitry Andric typedef __function::__policy_func<_Rp(_ArgTypes...)> __func; 982fe6060f1SDimitry Andric #endif 983fe6060f1SDimitry Andric 984fe6060f1SDimitry Andric __func __f_; 985fe6060f1SDimitry Andric 986fe6060f1SDimitry Andric template <class _Fp, bool = _And< 987bdd1243dSDimitry Andric _IsNotSame<__remove_cvref_t<_Fp>, function>, 988fe6060f1SDimitry Andric __invokable<_Fp, _ArgTypes...> 989fe6060f1SDimitry Andric >::value> 990fe6060f1SDimitry Andric struct __callable; 991fe6060f1SDimitry Andric template <class _Fp> 992fe6060f1SDimitry Andric struct __callable<_Fp, true> 993fe6060f1SDimitry Andric { 994fe6060f1SDimitry Andric static const bool value = is_void<_Rp>::value || 995fe6060f1SDimitry Andric __is_core_convertible<typename __invoke_of<_Fp, _ArgTypes...>::type, 996fe6060f1SDimitry Andric _Rp>::value; 997fe6060f1SDimitry Andric }; 998fe6060f1SDimitry Andric template <class _Fp> 999fe6060f1SDimitry Andric struct __callable<_Fp, false> 1000fe6060f1SDimitry Andric { 1001fe6060f1SDimitry Andric static const bool value = false; 1002fe6060f1SDimitry Andric }; 1003fe6060f1SDimitry Andric 1004fe6060f1SDimitry Andric template <class _Fp> 1005fe6060f1SDimitry Andric using _EnableIfLValueCallable = typename enable_if<__callable<_Fp&>::value>::type; 1006fe6060f1SDimitry Andric public: 1007fe6060f1SDimitry Andric typedef _Rp result_type; 1008fe6060f1SDimitry Andric 1009fe6060f1SDimitry Andric // construct/copy/destroy: 1010fe6060f1SDimitry Andric _LIBCPP_INLINE_VISIBILITY 1011fe6060f1SDimitry Andric function() _NOEXCEPT { } 1012fe6060f1SDimitry Andric _LIBCPP_INLINE_VISIBILITY 1013*06c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI function(nullptr_t) _NOEXCEPT {} 1014*06c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI function(const function&); 1015*06c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI function(function&&) _NOEXCEPT; 1016fe6060f1SDimitry Andric template<class _Fp, class = _EnableIfLValueCallable<_Fp>> 1017*06c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI function(_Fp); 1018fe6060f1SDimitry Andric 1019fe6060f1SDimitry Andric #if _LIBCPP_STD_VER <= 14 1020fe6060f1SDimitry Andric template<class _Alloc> 1021fe6060f1SDimitry Andric _LIBCPP_INLINE_VISIBILITY 1022fe6060f1SDimitry Andric function(allocator_arg_t, const _Alloc&) _NOEXCEPT {} 1023fe6060f1SDimitry Andric template<class _Alloc> 1024fe6060f1SDimitry Andric _LIBCPP_INLINE_VISIBILITY 1025fe6060f1SDimitry Andric function(allocator_arg_t, const _Alloc&, nullptr_t) _NOEXCEPT {} 1026fe6060f1SDimitry Andric template<class _Alloc> 1027*06c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI function(allocator_arg_t, const _Alloc&, const function&); 1028fe6060f1SDimitry Andric template<class _Alloc> 1029*06c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI function(allocator_arg_t, const _Alloc&, function&&); 1030fe6060f1SDimitry Andric template<class _Fp, class _Alloc, class = _EnableIfLValueCallable<_Fp>> 1031*06c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI function(allocator_arg_t, const _Alloc& __a, _Fp __f); 1032fe6060f1SDimitry Andric #endif 1033fe6060f1SDimitry Andric 1034*06c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI function& operator=(const function&); 1035*06c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI function& operator=(function&&) _NOEXCEPT; 1036*06c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI function& operator=(nullptr_t) _NOEXCEPT; 1037*06c3fb27SDimitry Andric template<class _Fp, class = _EnableIfLValueCallable<__decay_t<_Fp>>> 1038*06c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI function& operator=(_Fp&&); 1039fe6060f1SDimitry Andric 1040*06c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI ~function(); 1041fe6060f1SDimitry Andric 1042fe6060f1SDimitry Andric // function modifiers: 1043*06c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI void swap(function&) _NOEXCEPT; 1044fe6060f1SDimitry Andric 1045fe6060f1SDimitry Andric #if _LIBCPP_STD_VER <= 14 1046fe6060f1SDimitry Andric template<class _Fp, class _Alloc> 1047fe6060f1SDimitry Andric _LIBCPP_INLINE_VISIBILITY 1048fe6060f1SDimitry Andric void assign(_Fp&& __f, const _Alloc& __a) 1049fe6060f1SDimitry Andric {function(allocator_arg, __a, _VSTD::forward<_Fp>(__f)).swap(*this);} 1050fe6060f1SDimitry Andric #endif 1051fe6060f1SDimitry Andric 1052fe6060f1SDimitry Andric // function capacity: 1053fe6060f1SDimitry Andric _LIBCPP_INLINE_VISIBILITY 1054fe6060f1SDimitry Andric explicit operator bool() const _NOEXCEPT { 1055fe6060f1SDimitry Andric return static_cast<bool>(__f_); 1056fe6060f1SDimitry Andric } 1057fe6060f1SDimitry Andric 1058fe6060f1SDimitry Andric // deleted overloads close possible hole in the type system 1059fe6060f1SDimitry Andric template<class _R2, class... _ArgTypes2> 1060fe6060f1SDimitry Andric bool operator==(const function<_R2(_ArgTypes2...)>&) const = delete; 1061*06c3fb27SDimitry Andric #if _LIBCPP_STD_VER <= 17 1062fe6060f1SDimitry Andric template<class _R2, class... _ArgTypes2> 1063fe6060f1SDimitry Andric bool operator!=(const function<_R2(_ArgTypes2...)>&) const = delete; 1064*06c3fb27SDimitry Andric #endif 1065fe6060f1SDimitry Andric public: 1066fe6060f1SDimitry Andric // function invocation: 1067*06c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI _Rp operator()(_ArgTypes...) const; 1068fe6060f1SDimitry Andric 10691ac55f4cSDimitry Andric #ifndef _LIBCPP_HAS_NO_RTTI 1070fe6060f1SDimitry Andric // function target access: 1071*06c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI const std::type_info& target_type() const _NOEXCEPT; 1072*06c3fb27SDimitry Andric template <typename _Tp> 1073*06c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI _Tp* target() _NOEXCEPT; 1074*06c3fb27SDimitry Andric template <typename _Tp> 1075*06c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI const _Tp* target() const _NOEXCEPT; 10761ac55f4cSDimitry Andric #endif // _LIBCPP_HAS_NO_RTTI 1077fe6060f1SDimitry Andric }; 1078fe6060f1SDimitry Andric 1079349cc55cSDimitry Andric #if _LIBCPP_STD_VER >= 17 1080fe6060f1SDimitry Andric template<class _Rp, class ..._Ap> 1081fe6060f1SDimitry Andric function(_Rp(*)(_Ap...)) -> function<_Rp(_Ap...)>; 1082fe6060f1SDimitry Andric 1083fe6060f1SDimitry Andric template<class _Fp, class _Stripped = typename __strip_signature<decltype(&_Fp::operator())>::type> 1084fe6060f1SDimitry Andric function(_Fp) -> function<_Stripped>; 1085349cc55cSDimitry Andric #endif // _LIBCPP_STD_VER >= 17 1086fe6060f1SDimitry Andric 1087fe6060f1SDimitry Andric template<class _Rp, class ..._ArgTypes> 1088fe6060f1SDimitry Andric function<_Rp(_ArgTypes...)>::function(const function& __f) : __f_(__f.__f_) {} 1089fe6060f1SDimitry Andric 1090fe6060f1SDimitry Andric #if _LIBCPP_STD_VER <= 14 1091fe6060f1SDimitry Andric template<class _Rp, class ..._ArgTypes> 1092fe6060f1SDimitry Andric template <class _Alloc> 1093fe6060f1SDimitry Andric function<_Rp(_ArgTypes...)>::function(allocator_arg_t, const _Alloc&, 1094fe6060f1SDimitry Andric const function& __f) : __f_(__f.__f_) {} 1095fe6060f1SDimitry Andric #endif 1096fe6060f1SDimitry Andric 1097fe6060f1SDimitry Andric template <class _Rp, class... _ArgTypes> 1098fe6060f1SDimitry Andric function<_Rp(_ArgTypes...)>::function(function&& __f) _NOEXCEPT 1099fe6060f1SDimitry Andric : __f_(_VSTD::move(__f.__f_)) {} 1100fe6060f1SDimitry Andric 1101fe6060f1SDimitry Andric #if _LIBCPP_STD_VER <= 14 1102fe6060f1SDimitry Andric template<class _Rp, class ..._ArgTypes> 1103fe6060f1SDimitry Andric template <class _Alloc> 1104fe6060f1SDimitry Andric function<_Rp(_ArgTypes...)>::function(allocator_arg_t, const _Alloc&, 1105fe6060f1SDimitry Andric function&& __f) 1106fe6060f1SDimitry Andric : __f_(_VSTD::move(__f.__f_)) {} 1107fe6060f1SDimitry Andric #endif 1108fe6060f1SDimitry Andric 1109fe6060f1SDimitry Andric template <class _Rp, class... _ArgTypes> 1110fe6060f1SDimitry Andric template <class _Fp, class> 1111fe6060f1SDimitry Andric function<_Rp(_ArgTypes...)>::function(_Fp __f) : __f_(_VSTD::move(__f)) {} 1112fe6060f1SDimitry Andric 1113fe6060f1SDimitry Andric #if _LIBCPP_STD_VER <= 14 1114fe6060f1SDimitry Andric template <class _Rp, class... _ArgTypes> 1115fe6060f1SDimitry Andric template <class _Fp, class _Alloc, class> 1116fe6060f1SDimitry Andric function<_Rp(_ArgTypes...)>::function(allocator_arg_t, const _Alloc& __a, 1117fe6060f1SDimitry Andric _Fp __f) 1118fe6060f1SDimitry Andric : __f_(_VSTD::move(__f), __a) {} 1119fe6060f1SDimitry Andric #endif 1120fe6060f1SDimitry Andric 1121fe6060f1SDimitry Andric template<class _Rp, class ..._ArgTypes> 1122fe6060f1SDimitry Andric function<_Rp(_ArgTypes...)>& 1123fe6060f1SDimitry Andric function<_Rp(_ArgTypes...)>::operator=(const function& __f) 1124fe6060f1SDimitry Andric { 1125fe6060f1SDimitry Andric function(__f).swap(*this); 1126fe6060f1SDimitry Andric return *this; 1127fe6060f1SDimitry Andric } 1128fe6060f1SDimitry Andric 1129fe6060f1SDimitry Andric template<class _Rp, class ..._ArgTypes> 1130fe6060f1SDimitry Andric function<_Rp(_ArgTypes...)>& 1131fe6060f1SDimitry Andric function<_Rp(_ArgTypes...)>::operator=(function&& __f) _NOEXCEPT 1132fe6060f1SDimitry Andric { 1133fe6060f1SDimitry Andric __f_ = _VSTD::move(__f.__f_); 1134fe6060f1SDimitry Andric return *this; 1135fe6060f1SDimitry Andric } 1136fe6060f1SDimitry Andric 1137fe6060f1SDimitry Andric template<class _Rp, class ..._ArgTypes> 1138fe6060f1SDimitry Andric function<_Rp(_ArgTypes...)>& 1139fe6060f1SDimitry Andric function<_Rp(_ArgTypes...)>::operator=(nullptr_t) _NOEXCEPT 1140fe6060f1SDimitry Andric { 1141fe6060f1SDimitry Andric __f_ = nullptr; 1142fe6060f1SDimitry Andric return *this; 1143fe6060f1SDimitry Andric } 1144fe6060f1SDimitry Andric 1145fe6060f1SDimitry Andric template<class _Rp, class ..._ArgTypes> 1146fe6060f1SDimitry Andric template <class _Fp, class> 1147fe6060f1SDimitry Andric function<_Rp(_ArgTypes...)>& 1148fe6060f1SDimitry Andric function<_Rp(_ArgTypes...)>::operator=(_Fp&& __f) 1149fe6060f1SDimitry Andric { 1150fe6060f1SDimitry Andric function(_VSTD::forward<_Fp>(__f)).swap(*this); 1151fe6060f1SDimitry Andric return *this; 1152fe6060f1SDimitry Andric } 1153fe6060f1SDimitry Andric 1154fe6060f1SDimitry Andric template<class _Rp, class ..._ArgTypes> 1155fe6060f1SDimitry Andric function<_Rp(_ArgTypes...)>::~function() {} 1156fe6060f1SDimitry Andric 1157fe6060f1SDimitry Andric template<class _Rp, class ..._ArgTypes> 1158fe6060f1SDimitry Andric void 1159fe6060f1SDimitry Andric function<_Rp(_ArgTypes...)>::swap(function& __f) _NOEXCEPT 1160fe6060f1SDimitry Andric { 1161fe6060f1SDimitry Andric __f_.swap(__f.__f_); 1162fe6060f1SDimitry Andric } 1163fe6060f1SDimitry Andric 1164fe6060f1SDimitry Andric template<class _Rp, class ..._ArgTypes> 1165fe6060f1SDimitry Andric _Rp 1166fe6060f1SDimitry Andric function<_Rp(_ArgTypes...)>::operator()(_ArgTypes... __arg) const 1167fe6060f1SDimitry Andric { 1168fe6060f1SDimitry Andric return __f_(_VSTD::forward<_ArgTypes>(__arg)...); 1169fe6060f1SDimitry Andric } 1170fe6060f1SDimitry Andric 11711ac55f4cSDimitry Andric #ifndef _LIBCPP_HAS_NO_RTTI 1172fe6060f1SDimitry Andric 1173fe6060f1SDimitry Andric template<class _Rp, class ..._ArgTypes> 1174fe6060f1SDimitry Andric const std::type_info& 1175fe6060f1SDimitry Andric function<_Rp(_ArgTypes...)>::target_type() const _NOEXCEPT 1176fe6060f1SDimitry Andric { 1177fe6060f1SDimitry Andric return __f_.target_type(); 1178fe6060f1SDimitry Andric } 1179fe6060f1SDimitry Andric 1180fe6060f1SDimitry Andric template<class _Rp, class ..._ArgTypes> 1181fe6060f1SDimitry Andric template <typename _Tp> 1182fe6060f1SDimitry Andric _Tp* 1183fe6060f1SDimitry Andric function<_Rp(_ArgTypes...)>::target() _NOEXCEPT 1184fe6060f1SDimitry Andric { 1185fe6060f1SDimitry Andric return (_Tp*)(__f_.template target<_Tp>()); 1186fe6060f1SDimitry Andric } 1187fe6060f1SDimitry Andric 1188fe6060f1SDimitry Andric template<class _Rp, class ..._ArgTypes> 1189fe6060f1SDimitry Andric template <typename _Tp> 1190fe6060f1SDimitry Andric const _Tp* 1191fe6060f1SDimitry Andric function<_Rp(_ArgTypes...)>::target() const _NOEXCEPT 1192fe6060f1SDimitry Andric { 1193fe6060f1SDimitry Andric return __f_.template target<_Tp>(); 1194fe6060f1SDimitry Andric } 1195fe6060f1SDimitry Andric 11961ac55f4cSDimitry Andric #endif // _LIBCPP_HAS_NO_RTTI 1197fe6060f1SDimitry Andric 1198fe6060f1SDimitry Andric template <class _Rp, class... _ArgTypes> 1199fe6060f1SDimitry Andric inline _LIBCPP_INLINE_VISIBILITY 1200fe6060f1SDimitry Andric bool 1201fe6060f1SDimitry Andric operator==(const function<_Rp(_ArgTypes...)>& __f, nullptr_t) _NOEXCEPT {return !__f;} 1202fe6060f1SDimitry Andric 1203*06c3fb27SDimitry Andric #if _LIBCPP_STD_VER <= 17 1204*06c3fb27SDimitry Andric 1205fe6060f1SDimitry Andric template <class _Rp, class... _ArgTypes> 1206fe6060f1SDimitry Andric inline _LIBCPP_INLINE_VISIBILITY 1207fe6060f1SDimitry Andric bool 1208fe6060f1SDimitry Andric operator==(nullptr_t, const function<_Rp(_ArgTypes...)>& __f) _NOEXCEPT {return !__f;} 1209fe6060f1SDimitry Andric 1210fe6060f1SDimitry Andric template <class _Rp, class... _ArgTypes> 1211fe6060f1SDimitry Andric inline _LIBCPP_INLINE_VISIBILITY 1212fe6060f1SDimitry Andric bool 1213fe6060f1SDimitry Andric operator!=(const function<_Rp(_ArgTypes...)>& __f, nullptr_t) _NOEXCEPT {return (bool)__f;} 1214fe6060f1SDimitry Andric 1215fe6060f1SDimitry Andric template <class _Rp, class... _ArgTypes> 1216fe6060f1SDimitry Andric inline _LIBCPP_INLINE_VISIBILITY 1217fe6060f1SDimitry Andric bool 1218fe6060f1SDimitry Andric operator!=(nullptr_t, const function<_Rp(_ArgTypes...)>& __f) _NOEXCEPT {return (bool)__f;} 1219fe6060f1SDimitry Andric 1220*06c3fb27SDimitry Andric #endif // _LIBCPP_STD_VER <= 17 1221*06c3fb27SDimitry Andric 1222fe6060f1SDimitry Andric template <class _Rp, class... _ArgTypes> 1223fe6060f1SDimitry Andric inline _LIBCPP_INLINE_VISIBILITY 1224fe6060f1SDimitry Andric void 1225fe6060f1SDimitry Andric swap(function<_Rp(_ArgTypes...)>& __x, function<_Rp(_ArgTypes...)>& __y) _NOEXCEPT 1226fe6060f1SDimitry Andric {return __x.swap(__y);} 1227fe6060f1SDimitry Andric 1228bdd1243dSDimitry Andric _LIBCPP_END_NAMESPACE_STD 1229fe6060f1SDimitry Andric 123081ad6265SDimitry Andric #endif // _LIBCPP_CXX03_LANG 1231fe6060f1SDimitry Andric 1232fe6060f1SDimitry Andric #endif // _LIBCPP___FUNCTIONAL_FUNCTION_H 1233