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