1*fe6060f1SDimitry Andric // -*- C++ -*- 2*fe6060f1SDimitry Andric //===----------------------------------------------------------------------===// 3*fe6060f1SDimitry Andric // 4*fe6060f1SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 5*fe6060f1SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 6*fe6060f1SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 7*fe6060f1SDimitry Andric // 8*fe6060f1SDimitry Andric //===----------------------------------------------------------------------===// 9*fe6060f1SDimitry Andric 10*fe6060f1SDimitry Andric #ifndef _LIBCPP___FUNCTIONAL_FUNCTION_H 11*fe6060f1SDimitry Andric #define _LIBCPP___FUNCTIONAL_FUNCTION_H 12*fe6060f1SDimitry Andric 13*fe6060f1SDimitry Andric #include <__config> 14*fe6060f1SDimitry Andric #include <__functional/binary_function.h> 15*fe6060f1SDimitry Andric #include <__functional/invoke.h> 16*fe6060f1SDimitry Andric #include <__functional/unary_function.h> 17*fe6060f1SDimitry Andric #include <__iterator/iterator_traits.h> 18*fe6060f1SDimitry Andric #include <__memory/allocator_traits.h> 19*fe6060f1SDimitry Andric #include <__memory/compressed_pair.h> 20*fe6060f1SDimitry Andric #include <__memory/shared_ptr.h> 21*fe6060f1SDimitry Andric #include <exception> 22*fe6060f1SDimitry Andric #include <memory> // TODO: replace with <__memory/__builtin_new_allocator.h> 23*fe6060f1SDimitry Andric #include <type_traits> 24*fe6060f1SDimitry Andric #include <utility> 25*fe6060f1SDimitry Andric 26*fe6060f1SDimitry Andric #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 27*fe6060f1SDimitry Andric #pragma GCC system_header 28*fe6060f1SDimitry Andric #endif 29*fe6060f1SDimitry Andric 30*fe6060f1SDimitry Andric _LIBCPP_BEGIN_NAMESPACE_STD 31*fe6060f1SDimitry Andric 32*fe6060f1SDimitry Andric // bad_function_call 33*fe6060f1SDimitry Andric 34*fe6060f1SDimitry Andric class _LIBCPP_EXCEPTION_ABI bad_function_call 35*fe6060f1SDimitry Andric : public exception 36*fe6060f1SDimitry Andric { 37*fe6060f1SDimitry Andric #ifdef _LIBCPP_ABI_BAD_FUNCTION_CALL_KEY_FUNCTION 38*fe6060f1SDimitry Andric public: 39*fe6060f1SDimitry Andric virtual ~bad_function_call() _NOEXCEPT; 40*fe6060f1SDimitry Andric 41*fe6060f1SDimitry Andric virtual const char* what() const _NOEXCEPT; 42*fe6060f1SDimitry Andric #endif 43*fe6060f1SDimitry Andric }; 44*fe6060f1SDimitry Andric 45*fe6060f1SDimitry Andric _LIBCPP_NORETURN inline _LIBCPP_INLINE_VISIBILITY 46*fe6060f1SDimitry Andric void __throw_bad_function_call() 47*fe6060f1SDimitry Andric { 48*fe6060f1SDimitry Andric #ifndef _LIBCPP_NO_EXCEPTIONS 49*fe6060f1SDimitry Andric throw bad_function_call(); 50*fe6060f1SDimitry Andric #else 51*fe6060f1SDimitry Andric _VSTD::abort(); 52*fe6060f1SDimitry Andric #endif 53*fe6060f1SDimitry Andric } 54*fe6060f1SDimitry Andric 55*fe6060f1SDimitry Andric #if defined(_LIBCPP_CXX03_LANG) && !defined(_LIBCPP_DISABLE_DEPRECATION_WARNINGS) && __has_attribute(deprecated) 56*fe6060f1SDimitry Andric # define _LIBCPP_DEPRECATED_CXX03_FUNCTION \ 57*fe6060f1SDimitry Andric __attribute__((deprecated("Using std::function in C++03 is not supported anymore. Please upgrade to C++11 or later, or use a different type"))) 58*fe6060f1SDimitry Andric #else 59*fe6060f1SDimitry Andric # define _LIBCPP_DEPRECATED_CXX03_FUNCTION /* nothing */ 60*fe6060f1SDimitry Andric #endif 61*fe6060f1SDimitry Andric 62*fe6060f1SDimitry Andric template<class _Fp> class _LIBCPP_DEPRECATED_CXX03_FUNCTION _LIBCPP_TEMPLATE_VIS function; // undefined 63*fe6060f1SDimitry Andric 64*fe6060f1SDimitry Andric namespace __function 65*fe6060f1SDimitry Andric { 66*fe6060f1SDimitry Andric 67*fe6060f1SDimitry Andric template<class _Rp> 68*fe6060f1SDimitry Andric struct __maybe_derive_from_unary_function 69*fe6060f1SDimitry Andric { 70*fe6060f1SDimitry Andric }; 71*fe6060f1SDimitry Andric 72*fe6060f1SDimitry Andric template<class _Rp, class _A1> 73*fe6060f1SDimitry Andric struct __maybe_derive_from_unary_function<_Rp(_A1)> 74*fe6060f1SDimitry Andric : public unary_function<_A1, _Rp> 75*fe6060f1SDimitry Andric { 76*fe6060f1SDimitry Andric }; 77*fe6060f1SDimitry Andric 78*fe6060f1SDimitry Andric template<class _Rp> 79*fe6060f1SDimitry Andric struct __maybe_derive_from_binary_function 80*fe6060f1SDimitry Andric { 81*fe6060f1SDimitry Andric }; 82*fe6060f1SDimitry Andric 83*fe6060f1SDimitry Andric template<class _Rp, class _A1, class _A2> 84*fe6060f1SDimitry Andric struct __maybe_derive_from_binary_function<_Rp(_A1, _A2)> 85*fe6060f1SDimitry Andric : public binary_function<_A1, _A2, _Rp> 86*fe6060f1SDimitry Andric { 87*fe6060f1SDimitry Andric }; 88*fe6060f1SDimitry Andric 89*fe6060f1SDimitry Andric template <class _Fp> 90*fe6060f1SDimitry Andric _LIBCPP_INLINE_VISIBILITY 91*fe6060f1SDimitry Andric bool __not_null(_Fp const&) { return true; } 92*fe6060f1SDimitry Andric 93*fe6060f1SDimitry Andric template <class _Fp> 94*fe6060f1SDimitry Andric _LIBCPP_INLINE_VISIBILITY 95*fe6060f1SDimitry Andric bool __not_null(_Fp* __ptr) { return __ptr; } 96*fe6060f1SDimitry Andric 97*fe6060f1SDimitry Andric template <class _Ret, class _Class> 98*fe6060f1SDimitry Andric _LIBCPP_INLINE_VISIBILITY 99*fe6060f1SDimitry Andric bool __not_null(_Ret _Class::*__ptr) { return __ptr; } 100*fe6060f1SDimitry Andric 101*fe6060f1SDimitry Andric template <class _Fp> 102*fe6060f1SDimitry Andric _LIBCPP_INLINE_VISIBILITY 103*fe6060f1SDimitry Andric bool __not_null(function<_Fp> const& __f) { return !!__f; } 104*fe6060f1SDimitry Andric 105*fe6060f1SDimitry Andric #ifdef _LIBCPP_HAS_EXTENSION_BLOCKS 106*fe6060f1SDimitry Andric template <class _Rp, class ..._Args> 107*fe6060f1SDimitry Andric _LIBCPP_INLINE_VISIBILITY 108*fe6060f1SDimitry Andric bool __not_null(_Rp (^__p)(_Args...)) { return __p; } 109*fe6060f1SDimitry Andric #endif 110*fe6060f1SDimitry Andric 111*fe6060f1SDimitry Andric } // namespace __function 112*fe6060f1SDimitry Andric 113*fe6060f1SDimitry Andric #ifndef _LIBCPP_CXX03_LANG 114*fe6060f1SDimitry Andric 115*fe6060f1SDimitry Andric namespace __function { 116*fe6060f1SDimitry Andric 117*fe6060f1SDimitry Andric // __alloc_func holds a functor and an allocator. 118*fe6060f1SDimitry Andric 119*fe6060f1SDimitry Andric template <class _Fp, class _Ap, class _FB> class __alloc_func; 120*fe6060f1SDimitry Andric template <class _Fp, class _FB> 121*fe6060f1SDimitry Andric class __default_alloc_func; 122*fe6060f1SDimitry Andric 123*fe6060f1SDimitry Andric template <class _Fp, class _Ap, class _Rp, class... _ArgTypes> 124*fe6060f1SDimitry Andric class __alloc_func<_Fp, _Ap, _Rp(_ArgTypes...)> 125*fe6060f1SDimitry Andric { 126*fe6060f1SDimitry Andric __compressed_pair<_Fp, _Ap> __f_; 127*fe6060f1SDimitry Andric 128*fe6060f1SDimitry Andric public: 129*fe6060f1SDimitry Andric typedef _LIBCPP_NODEBUG_TYPE _Fp _Target; 130*fe6060f1SDimitry Andric typedef _LIBCPP_NODEBUG_TYPE _Ap _Alloc; 131*fe6060f1SDimitry Andric 132*fe6060f1SDimitry Andric _LIBCPP_INLINE_VISIBILITY 133*fe6060f1SDimitry Andric const _Target& __target() const { return __f_.first(); } 134*fe6060f1SDimitry Andric 135*fe6060f1SDimitry Andric // WIN32 APIs may define __allocator, so use __get_allocator instead. 136*fe6060f1SDimitry Andric _LIBCPP_INLINE_VISIBILITY 137*fe6060f1SDimitry Andric const _Alloc& __get_allocator() const { return __f_.second(); } 138*fe6060f1SDimitry Andric 139*fe6060f1SDimitry Andric _LIBCPP_INLINE_VISIBILITY 140*fe6060f1SDimitry Andric explicit __alloc_func(_Target&& __f) 141*fe6060f1SDimitry Andric : __f_(piecewise_construct, _VSTD::forward_as_tuple(_VSTD::move(__f)), 142*fe6060f1SDimitry Andric _VSTD::forward_as_tuple()) 143*fe6060f1SDimitry Andric { 144*fe6060f1SDimitry Andric } 145*fe6060f1SDimitry Andric 146*fe6060f1SDimitry Andric _LIBCPP_INLINE_VISIBILITY 147*fe6060f1SDimitry Andric explicit __alloc_func(const _Target& __f, const _Alloc& __a) 148*fe6060f1SDimitry Andric : __f_(piecewise_construct, _VSTD::forward_as_tuple(__f), 149*fe6060f1SDimitry Andric _VSTD::forward_as_tuple(__a)) 150*fe6060f1SDimitry Andric { 151*fe6060f1SDimitry Andric } 152*fe6060f1SDimitry Andric 153*fe6060f1SDimitry Andric _LIBCPP_INLINE_VISIBILITY 154*fe6060f1SDimitry Andric explicit __alloc_func(const _Target& __f, _Alloc&& __a) 155*fe6060f1SDimitry Andric : __f_(piecewise_construct, _VSTD::forward_as_tuple(__f), 156*fe6060f1SDimitry Andric _VSTD::forward_as_tuple(_VSTD::move(__a))) 157*fe6060f1SDimitry Andric { 158*fe6060f1SDimitry Andric } 159*fe6060f1SDimitry Andric 160*fe6060f1SDimitry Andric _LIBCPP_INLINE_VISIBILITY 161*fe6060f1SDimitry Andric explicit __alloc_func(_Target&& __f, _Alloc&& __a) 162*fe6060f1SDimitry Andric : __f_(piecewise_construct, _VSTD::forward_as_tuple(_VSTD::move(__f)), 163*fe6060f1SDimitry Andric _VSTD::forward_as_tuple(_VSTD::move(__a))) 164*fe6060f1SDimitry Andric { 165*fe6060f1SDimitry Andric } 166*fe6060f1SDimitry Andric 167*fe6060f1SDimitry Andric _LIBCPP_INLINE_VISIBILITY 168*fe6060f1SDimitry Andric _Rp operator()(_ArgTypes&&... __arg) 169*fe6060f1SDimitry Andric { 170*fe6060f1SDimitry Andric typedef __invoke_void_return_wrapper<_Rp> _Invoker; 171*fe6060f1SDimitry Andric return _Invoker::__call(__f_.first(), 172*fe6060f1SDimitry Andric _VSTD::forward<_ArgTypes>(__arg)...); 173*fe6060f1SDimitry Andric } 174*fe6060f1SDimitry Andric 175*fe6060f1SDimitry Andric _LIBCPP_INLINE_VISIBILITY 176*fe6060f1SDimitry Andric __alloc_func* __clone() const 177*fe6060f1SDimitry Andric { 178*fe6060f1SDimitry Andric typedef allocator_traits<_Alloc> __alloc_traits; 179*fe6060f1SDimitry Andric typedef 180*fe6060f1SDimitry Andric typename __rebind_alloc_helper<__alloc_traits, __alloc_func>::type 181*fe6060f1SDimitry Andric _AA; 182*fe6060f1SDimitry Andric _AA __a(__f_.second()); 183*fe6060f1SDimitry Andric typedef __allocator_destructor<_AA> _Dp; 184*fe6060f1SDimitry Andric unique_ptr<__alloc_func, _Dp> __hold(__a.allocate(1), _Dp(__a, 1)); 185*fe6060f1SDimitry Andric ::new ((void*)__hold.get()) __alloc_func(__f_.first(), _Alloc(__a)); 186*fe6060f1SDimitry Andric return __hold.release(); 187*fe6060f1SDimitry Andric } 188*fe6060f1SDimitry Andric 189*fe6060f1SDimitry Andric _LIBCPP_INLINE_VISIBILITY 190*fe6060f1SDimitry Andric void destroy() _NOEXCEPT { __f_.~__compressed_pair<_Target, _Alloc>(); } 191*fe6060f1SDimitry Andric 192*fe6060f1SDimitry Andric static void __destroy_and_delete(__alloc_func* __f) { 193*fe6060f1SDimitry Andric typedef allocator_traits<_Alloc> __alloc_traits; 194*fe6060f1SDimitry Andric typedef typename __rebind_alloc_helper<__alloc_traits, __alloc_func>::type 195*fe6060f1SDimitry Andric _FunAlloc; 196*fe6060f1SDimitry Andric _FunAlloc __a(__f->__get_allocator()); 197*fe6060f1SDimitry Andric __f->destroy(); 198*fe6060f1SDimitry Andric __a.deallocate(__f, 1); 199*fe6060f1SDimitry Andric } 200*fe6060f1SDimitry Andric }; 201*fe6060f1SDimitry Andric 202*fe6060f1SDimitry Andric template <class _Fp, class _Rp, class... _ArgTypes> 203*fe6060f1SDimitry Andric class __default_alloc_func<_Fp, _Rp(_ArgTypes...)> { 204*fe6060f1SDimitry Andric _Fp __f_; 205*fe6060f1SDimitry Andric 206*fe6060f1SDimitry Andric public: 207*fe6060f1SDimitry Andric typedef _LIBCPP_NODEBUG_TYPE _Fp _Target; 208*fe6060f1SDimitry Andric 209*fe6060f1SDimitry Andric _LIBCPP_INLINE_VISIBILITY 210*fe6060f1SDimitry Andric const _Target& __target() const { return __f_; } 211*fe6060f1SDimitry Andric 212*fe6060f1SDimitry Andric _LIBCPP_INLINE_VISIBILITY 213*fe6060f1SDimitry Andric explicit __default_alloc_func(_Target&& __f) : __f_(_VSTD::move(__f)) {} 214*fe6060f1SDimitry Andric 215*fe6060f1SDimitry Andric _LIBCPP_INLINE_VISIBILITY 216*fe6060f1SDimitry Andric explicit __default_alloc_func(const _Target& __f) : __f_(__f) {} 217*fe6060f1SDimitry Andric 218*fe6060f1SDimitry Andric _LIBCPP_INLINE_VISIBILITY 219*fe6060f1SDimitry Andric _Rp operator()(_ArgTypes&&... __arg) { 220*fe6060f1SDimitry Andric typedef __invoke_void_return_wrapper<_Rp> _Invoker; 221*fe6060f1SDimitry Andric return _Invoker::__call(__f_, _VSTD::forward<_ArgTypes>(__arg)...); 222*fe6060f1SDimitry Andric } 223*fe6060f1SDimitry Andric 224*fe6060f1SDimitry Andric _LIBCPP_INLINE_VISIBILITY 225*fe6060f1SDimitry Andric __default_alloc_func* __clone() const { 226*fe6060f1SDimitry Andric __builtin_new_allocator::__holder_t __hold = 227*fe6060f1SDimitry Andric __builtin_new_allocator::__allocate_type<__default_alloc_func>(1); 228*fe6060f1SDimitry Andric __default_alloc_func* __res = 229*fe6060f1SDimitry Andric ::new ((void*)__hold.get()) __default_alloc_func(__f_); 230*fe6060f1SDimitry Andric (void)__hold.release(); 231*fe6060f1SDimitry Andric return __res; 232*fe6060f1SDimitry Andric } 233*fe6060f1SDimitry Andric 234*fe6060f1SDimitry Andric _LIBCPP_INLINE_VISIBILITY 235*fe6060f1SDimitry Andric void destroy() _NOEXCEPT { __f_.~_Target(); } 236*fe6060f1SDimitry Andric 237*fe6060f1SDimitry Andric static void __destroy_and_delete(__default_alloc_func* __f) { 238*fe6060f1SDimitry Andric __f->destroy(); 239*fe6060f1SDimitry Andric __builtin_new_allocator::__deallocate_type<__default_alloc_func>(__f, 1); 240*fe6060f1SDimitry Andric } 241*fe6060f1SDimitry Andric }; 242*fe6060f1SDimitry Andric 243*fe6060f1SDimitry Andric // __base provides an abstract interface for copyable functors. 244*fe6060f1SDimitry Andric 245*fe6060f1SDimitry Andric template<class _Fp> class _LIBCPP_TEMPLATE_VIS __base; 246*fe6060f1SDimitry Andric 247*fe6060f1SDimitry Andric template<class _Rp, class ..._ArgTypes> 248*fe6060f1SDimitry Andric class __base<_Rp(_ArgTypes...)> 249*fe6060f1SDimitry Andric { 250*fe6060f1SDimitry Andric __base(const __base&); 251*fe6060f1SDimitry Andric __base& operator=(const __base&); 252*fe6060f1SDimitry Andric public: 253*fe6060f1SDimitry Andric _LIBCPP_INLINE_VISIBILITY __base() {} 254*fe6060f1SDimitry Andric _LIBCPP_INLINE_VISIBILITY virtual ~__base() {} 255*fe6060f1SDimitry Andric virtual __base* __clone() const = 0; 256*fe6060f1SDimitry Andric virtual void __clone(__base*) const = 0; 257*fe6060f1SDimitry Andric virtual void destroy() _NOEXCEPT = 0; 258*fe6060f1SDimitry Andric virtual void destroy_deallocate() _NOEXCEPT = 0; 259*fe6060f1SDimitry Andric virtual _Rp operator()(_ArgTypes&& ...) = 0; 260*fe6060f1SDimitry Andric #ifndef _LIBCPP_NO_RTTI 261*fe6060f1SDimitry Andric virtual const void* target(const type_info&) const _NOEXCEPT = 0; 262*fe6060f1SDimitry Andric virtual const std::type_info& target_type() const _NOEXCEPT = 0; 263*fe6060f1SDimitry Andric #endif // _LIBCPP_NO_RTTI 264*fe6060f1SDimitry Andric }; 265*fe6060f1SDimitry Andric 266*fe6060f1SDimitry Andric // __func implements __base for a given functor type. 267*fe6060f1SDimitry Andric 268*fe6060f1SDimitry Andric template<class _FD, class _Alloc, class _FB> class __func; 269*fe6060f1SDimitry Andric 270*fe6060f1SDimitry Andric template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes> 271*fe6060f1SDimitry Andric class __func<_Fp, _Alloc, _Rp(_ArgTypes...)> 272*fe6060f1SDimitry Andric : public __base<_Rp(_ArgTypes...)> 273*fe6060f1SDimitry Andric { 274*fe6060f1SDimitry Andric __alloc_func<_Fp, _Alloc, _Rp(_ArgTypes...)> __f_; 275*fe6060f1SDimitry Andric public: 276*fe6060f1SDimitry Andric _LIBCPP_INLINE_VISIBILITY 277*fe6060f1SDimitry Andric explicit __func(_Fp&& __f) 278*fe6060f1SDimitry Andric : __f_(_VSTD::move(__f)) {} 279*fe6060f1SDimitry Andric 280*fe6060f1SDimitry Andric _LIBCPP_INLINE_VISIBILITY 281*fe6060f1SDimitry Andric explicit __func(const _Fp& __f, const _Alloc& __a) 282*fe6060f1SDimitry Andric : __f_(__f, __a) {} 283*fe6060f1SDimitry Andric 284*fe6060f1SDimitry Andric _LIBCPP_INLINE_VISIBILITY 285*fe6060f1SDimitry Andric explicit __func(const _Fp& __f, _Alloc&& __a) 286*fe6060f1SDimitry Andric : __f_(__f, _VSTD::move(__a)) {} 287*fe6060f1SDimitry Andric 288*fe6060f1SDimitry Andric _LIBCPP_INLINE_VISIBILITY 289*fe6060f1SDimitry Andric explicit __func(_Fp&& __f, _Alloc&& __a) 290*fe6060f1SDimitry Andric : __f_(_VSTD::move(__f), _VSTD::move(__a)) {} 291*fe6060f1SDimitry Andric 292*fe6060f1SDimitry Andric virtual __base<_Rp(_ArgTypes...)>* __clone() const; 293*fe6060f1SDimitry Andric virtual void __clone(__base<_Rp(_ArgTypes...)>*) const; 294*fe6060f1SDimitry Andric virtual void destroy() _NOEXCEPT; 295*fe6060f1SDimitry Andric virtual void destroy_deallocate() _NOEXCEPT; 296*fe6060f1SDimitry Andric virtual _Rp operator()(_ArgTypes&&... __arg); 297*fe6060f1SDimitry Andric #ifndef _LIBCPP_NO_RTTI 298*fe6060f1SDimitry Andric virtual const void* target(const type_info&) const _NOEXCEPT; 299*fe6060f1SDimitry Andric virtual const std::type_info& target_type() const _NOEXCEPT; 300*fe6060f1SDimitry Andric #endif // _LIBCPP_NO_RTTI 301*fe6060f1SDimitry Andric }; 302*fe6060f1SDimitry Andric 303*fe6060f1SDimitry Andric template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes> 304*fe6060f1SDimitry Andric __base<_Rp(_ArgTypes...)>* 305*fe6060f1SDimitry Andric __func<_Fp, _Alloc, _Rp(_ArgTypes...)>::__clone() const 306*fe6060f1SDimitry Andric { 307*fe6060f1SDimitry Andric typedef allocator_traits<_Alloc> __alloc_traits; 308*fe6060f1SDimitry Andric typedef typename __rebind_alloc_helper<__alloc_traits, __func>::type _Ap; 309*fe6060f1SDimitry Andric _Ap __a(__f_.__get_allocator()); 310*fe6060f1SDimitry Andric typedef __allocator_destructor<_Ap> _Dp; 311*fe6060f1SDimitry Andric unique_ptr<__func, _Dp> __hold(__a.allocate(1), _Dp(__a, 1)); 312*fe6060f1SDimitry Andric ::new ((void*)__hold.get()) __func(__f_.__target(), _Alloc(__a)); 313*fe6060f1SDimitry Andric return __hold.release(); 314*fe6060f1SDimitry Andric } 315*fe6060f1SDimitry Andric 316*fe6060f1SDimitry Andric template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes> 317*fe6060f1SDimitry Andric void 318*fe6060f1SDimitry Andric __func<_Fp, _Alloc, _Rp(_ArgTypes...)>::__clone(__base<_Rp(_ArgTypes...)>* __p) const 319*fe6060f1SDimitry Andric { 320*fe6060f1SDimitry Andric ::new ((void*)__p) __func(__f_.__target(), __f_.__get_allocator()); 321*fe6060f1SDimitry Andric } 322*fe6060f1SDimitry Andric 323*fe6060f1SDimitry Andric template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes> 324*fe6060f1SDimitry Andric void 325*fe6060f1SDimitry Andric __func<_Fp, _Alloc, _Rp(_ArgTypes...)>::destroy() _NOEXCEPT 326*fe6060f1SDimitry Andric { 327*fe6060f1SDimitry Andric __f_.destroy(); 328*fe6060f1SDimitry Andric } 329*fe6060f1SDimitry Andric 330*fe6060f1SDimitry Andric template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes> 331*fe6060f1SDimitry Andric void 332*fe6060f1SDimitry Andric __func<_Fp, _Alloc, _Rp(_ArgTypes...)>::destroy_deallocate() _NOEXCEPT 333*fe6060f1SDimitry Andric { 334*fe6060f1SDimitry Andric typedef allocator_traits<_Alloc> __alloc_traits; 335*fe6060f1SDimitry Andric typedef typename __rebind_alloc_helper<__alloc_traits, __func>::type _Ap; 336*fe6060f1SDimitry Andric _Ap __a(__f_.__get_allocator()); 337*fe6060f1SDimitry Andric __f_.destroy(); 338*fe6060f1SDimitry Andric __a.deallocate(this, 1); 339*fe6060f1SDimitry Andric } 340*fe6060f1SDimitry Andric 341*fe6060f1SDimitry Andric template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes> 342*fe6060f1SDimitry Andric _Rp 343*fe6060f1SDimitry Andric __func<_Fp, _Alloc, _Rp(_ArgTypes...)>::operator()(_ArgTypes&& ... __arg) 344*fe6060f1SDimitry Andric { 345*fe6060f1SDimitry Andric return __f_(_VSTD::forward<_ArgTypes>(__arg)...); 346*fe6060f1SDimitry Andric } 347*fe6060f1SDimitry Andric 348*fe6060f1SDimitry Andric #ifndef _LIBCPP_NO_RTTI 349*fe6060f1SDimitry Andric 350*fe6060f1SDimitry Andric template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes> 351*fe6060f1SDimitry Andric const void* 352*fe6060f1SDimitry Andric __func<_Fp, _Alloc, _Rp(_ArgTypes...)>::target(const type_info& __ti) const _NOEXCEPT 353*fe6060f1SDimitry Andric { 354*fe6060f1SDimitry Andric if (__ti == typeid(_Fp)) 355*fe6060f1SDimitry Andric return &__f_.__target(); 356*fe6060f1SDimitry Andric return nullptr; 357*fe6060f1SDimitry Andric } 358*fe6060f1SDimitry Andric 359*fe6060f1SDimitry Andric template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes> 360*fe6060f1SDimitry Andric const std::type_info& 361*fe6060f1SDimitry Andric __func<_Fp, _Alloc, _Rp(_ArgTypes...)>::target_type() const _NOEXCEPT 362*fe6060f1SDimitry Andric { 363*fe6060f1SDimitry Andric return typeid(_Fp); 364*fe6060f1SDimitry Andric } 365*fe6060f1SDimitry Andric 366*fe6060f1SDimitry Andric #endif // _LIBCPP_NO_RTTI 367*fe6060f1SDimitry Andric 368*fe6060f1SDimitry Andric // __value_func creates a value-type from a __func. 369*fe6060f1SDimitry Andric 370*fe6060f1SDimitry Andric template <class _Fp> class __value_func; 371*fe6060f1SDimitry Andric 372*fe6060f1SDimitry Andric template <class _Rp, class... _ArgTypes> class __value_func<_Rp(_ArgTypes...)> 373*fe6060f1SDimitry Andric { 374*fe6060f1SDimitry Andric typename aligned_storage<3 * sizeof(void*)>::type __buf_; 375*fe6060f1SDimitry Andric 376*fe6060f1SDimitry Andric typedef __base<_Rp(_ArgTypes...)> __func; 377*fe6060f1SDimitry Andric __func* __f_; 378*fe6060f1SDimitry Andric 379*fe6060f1SDimitry Andric _LIBCPP_NO_CFI static __func* __as_base(void* p) 380*fe6060f1SDimitry Andric { 381*fe6060f1SDimitry Andric return reinterpret_cast<__func*>(p); 382*fe6060f1SDimitry Andric } 383*fe6060f1SDimitry Andric 384*fe6060f1SDimitry Andric public: 385*fe6060f1SDimitry Andric _LIBCPP_INLINE_VISIBILITY 386*fe6060f1SDimitry Andric __value_func() _NOEXCEPT : __f_(nullptr) {} 387*fe6060f1SDimitry Andric 388*fe6060f1SDimitry Andric template <class _Fp, class _Alloc> 389*fe6060f1SDimitry Andric _LIBCPP_INLINE_VISIBILITY __value_func(_Fp&& __f, const _Alloc& __a) 390*fe6060f1SDimitry Andric : __f_(nullptr) 391*fe6060f1SDimitry Andric { 392*fe6060f1SDimitry Andric typedef allocator_traits<_Alloc> __alloc_traits; 393*fe6060f1SDimitry Andric typedef __function::__func<_Fp, _Alloc, _Rp(_ArgTypes...)> _Fun; 394*fe6060f1SDimitry Andric typedef typename __rebind_alloc_helper<__alloc_traits, _Fun>::type 395*fe6060f1SDimitry Andric _FunAlloc; 396*fe6060f1SDimitry Andric 397*fe6060f1SDimitry Andric if (__function::__not_null(__f)) 398*fe6060f1SDimitry Andric { 399*fe6060f1SDimitry Andric _FunAlloc __af(__a); 400*fe6060f1SDimitry Andric if (sizeof(_Fun) <= sizeof(__buf_) && 401*fe6060f1SDimitry Andric is_nothrow_copy_constructible<_Fp>::value && 402*fe6060f1SDimitry Andric is_nothrow_copy_constructible<_FunAlloc>::value) 403*fe6060f1SDimitry Andric { 404*fe6060f1SDimitry Andric __f_ = 405*fe6060f1SDimitry Andric ::new ((void*)&__buf_) _Fun(_VSTD::move(__f), _Alloc(__af)); 406*fe6060f1SDimitry Andric } 407*fe6060f1SDimitry Andric else 408*fe6060f1SDimitry Andric { 409*fe6060f1SDimitry Andric typedef __allocator_destructor<_FunAlloc> _Dp; 410*fe6060f1SDimitry Andric unique_ptr<__func, _Dp> __hold(__af.allocate(1), _Dp(__af, 1)); 411*fe6060f1SDimitry Andric ::new ((void*)__hold.get()) _Fun(_VSTD::move(__f), _Alloc(__a)); 412*fe6060f1SDimitry Andric __f_ = __hold.release(); 413*fe6060f1SDimitry Andric } 414*fe6060f1SDimitry Andric } 415*fe6060f1SDimitry Andric } 416*fe6060f1SDimitry Andric 417*fe6060f1SDimitry Andric template <class _Fp, 418*fe6060f1SDimitry Andric class = typename enable_if<!is_same<typename decay<_Fp>::type, __value_func>::value>::type> 419*fe6060f1SDimitry Andric _LIBCPP_INLINE_VISIBILITY explicit __value_func(_Fp&& __f) 420*fe6060f1SDimitry Andric : __value_func(_VSTD::forward<_Fp>(__f), allocator<_Fp>()) {} 421*fe6060f1SDimitry Andric 422*fe6060f1SDimitry Andric _LIBCPP_INLINE_VISIBILITY 423*fe6060f1SDimitry Andric __value_func(const __value_func& __f) 424*fe6060f1SDimitry Andric { 425*fe6060f1SDimitry Andric if (__f.__f_ == nullptr) 426*fe6060f1SDimitry Andric __f_ = nullptr; 427*fe6060f1SDimitry Andric else if ((void*)__f.__f_ == &__f.__buf_) 428*fe6060f1SDimitry Andric { 429*fe6060f1SDimitry Andric __f_ = __as_base(&__buf_); 430*fe6060f1SDimitry Andric __f.__f_->__clone(__f_); 431*fe6060f1SDimitry Andric } 432*fe6060f1SDimitry Andric else 433*fe6060f1SDimitry Andric __f_ = __f.__f_->__clone(); 434*fe6060f1SDimitry Andric } 435*fe6060f1SDimitry Andric 436*fe6060f1SDimitry Andric _LIBCPP_INLINE_VISIBILITY 437*fe6060f1SDimitry Andric __value_func(__value_func&& __f) _NOEXCEPT 438*fe6060f1SDimitry Andric { 439*fe6060f1SDimitry Andric if (__f.__f_ == nullptr) 440*fe6060f1SDimitry Andric __f_ = nullptr; 441*fe6060f1SDimitry Andric else if ((void*)__f.__f_ == &__f.__buf_) 442*fe6060f1SDimitry Andric { 443*fe6060f1SDimitry Andric __f_ = __as_base(&__buf_); 444*fe6060f1SDimitry Andric __f.__f_->__clone(__f_); 445*fe6060f1SDimitry Andric } 446*fe6060f1SDimitry Andric else 447*fe6060f1SDimitry Andric { 448*fe6060f1SDimitry Andric __f_ = __f.__f_; 449*fe6060f1SDimitry Andric __f.__f_ = nullptr; 450*fe6060f1SDimitry Andric } 451*fe6060f1SDimitry Andric } 452*fe6060f1SDimitry Andric 453*fe6060f1SDimitry Andric _LIBCPP_INLINE_VISIBILITY 454*fe6060f1SDimitry Andric ~__value_func() 455*fe6060f1SDimitry Andric { 456*fe6060f1SDimitry Andric if ((void*)__f_ == &__buf_) 457*fe6060f1SDimitry Andric __f_->destroy(); 458*fe6060f1SDimitry Andric else if (__f_) 459*fe6060f1SDimitry Andric __f_->destroy_deallocate(); 460*fe6060f1SDimitry Andric } 461*fe6060f1SDimitry Andric 462*fe6060f1SDimitry Andric _LIBCPP_INLINE_VISIBILITY 463*fe6060f1SDimitry Andric __value_func& operator=(__value_func&& __f) 464*fe6060f1SDimitry Andric { 465*fe6060f1SDimitry Andric *this = nullptr; 466*fe6060f1SDimitry Andric if (__f.__f_ == nullptr) 467*fe6060f1SDimitry Andric __f_ = nullptr; 468*fe6060f1SDimitry Andric else if ((void*)__f.__f_ == &__f.__buf_) 469*fe6060f1SDimitry Andric { 470*fe6060f1SDimitry Andric __f_ = __as_base(&__buf_); 471*fe6060f1SDimitry Andric __f.__f_->__clone(__f_); 472*fe6060f1SDimitry Andric } 473*fe6060f1SDimitry Andric else 474*fe6060f1SDimitry Andric { 475*fe6060f1SDimitry Andric __f_ = __f.__f_; 476*fe6060f1SDimitry Andric __f.__f_ = nullptr; 477*fe6060f1SDimitry Andric } 478*fe6060f1SDimitry Andric return *this; 479*fe6060f1SDimitry Andric } 480*fe6060f1SDimitry Andric 481*fe6060f1SDimitry Andric _LIBCPP_INLINE_VISIBILITY 482*fe6060f1SDimitry Andric __value_func& operator=(nullptr_t) 483*fe6060f1SDimitry Andric { 484*fe6060f1SDimitry Andric __func* __f = __f_; 485*fe6060f1SDimitry Andric __f_ = nullptr; 486*fe6060f1SDimitry Andric if ((void*)__f == &__buf_) 487*fe6060f1SDimitry Andric __f->destroy(); 488*fe6060f1SDimitry Andric else if (__f) 489*fe6060f1SDimitry Andric __f->destroy_deallocate(); 490*fe6060f1SDimitry Andric return *this; 491*fe6060f1SDimitry Andric } 492*fe6060f1SDimitry Andric 493*fe6060f1SDimitry Andric _LIBCPP_INLINE_VISIBILITY 494*fe6060f1SDimitry Andric _Rp operator()(_ArgTypes&&... __args) const 495*fe6060f1SDimitry Andric { 496*fe6060f1SDimitry Andric if (__f_ == nullptr) 497*fe6060f1SDimitry Andric __throw_bad_function_call(); 498*fe6060f1SDimitry Andric return (*__f_)(_VSTD::forward<_ArgTypes>(__args)...); 499*fe6060f1SDimitry Andric } 500*fe6060f1SDimitry Andric 501*fe6060f1SDimitry Andric _LIBCPP_INLINE_VISIBILITY 502*fe6060f1SDimitry Andric void swap(__value_func& __f) _NOEXCEPT 503*fe6060f1SDimitry Andric { 504*fe6060f1SDimitry Andric if (&__f == this) 505*fe6060f1SDimitry Andric return; 506*fe6060f1SDimitry Andric if ((void*)__f_ == &__buf_ && (void*)__f.__f_ == &__f.__buf_) 507*fe6060f1SDimitry Andric { 508*fe6060f1SDimitry Andric typename aligned_storage<sizeof(__buf_)>::type __tempbuf; 509*fe6060f1SDimitry Andric __func* __t = __as_base(&__tempbuf); 510*fe6060f1SDimitry Andric __f_->__clone(__t); 511*fe6060f1SDimitry Andric __f_->destroy(); 512*fe6060f1SDimitry Andric __f_ = nullptr; 513*fe6060f1SDimitry Andric __f.__f_->__clone(__as_base(&__buf_)); 514*fe6060f1SDimitry Andric __f.__f_->destroy(); 515*fe6060f1SDimitry Andric __f.__f_ = nullptr; 516*fe6060f1SDimitry Andric __f_ = __as_base(&__buf_); 517*fe6060f1SDimitry Andric __t->__clone(__as_base(&__f.__buf_)); 518*fe6060f1SDimitry Andric __t->destroy(); 519*fe6060f1SDimitry Andric __f.__f_ = __as_base(&__f.__buf_); 520*fe6060f1SDimitry Andric } 521*fe6060f1SDimitry Andric else if ((void*)__f_ == &__buf_) 522*fe6060f1SDimitry Andric { 523*fe6060f1SDimitry Andric __f_->__clone(__as_base(&__f.__buf_)); 524*fe6060f1SDimitry Andric __f_->destroy(); 525*fe6060f1SDimitry Andric __f_ = __f.__f_; 526*fe6060f1SDimitry Andric __f.__f_ = __as_base(&__f.__buf_); 527*fe6060f1SDimitry Andric } 528*fe6060f1SDimitry Andric else if ((void*)__f.__f_ == &__f.__buf_) 529*fe6060f1SDimitry Andric { 530*fe6060f1SDimitry Andric __f.__f_->__clone(__as_base(&__buf_)); 531*fe6060f1SDimitry Andric __f.__f_->destroy(); 532*fe6060f1SDimitry Andric __f.__f_ = __f_; 533*fe6060f1SDimitry Andric __f_ = __as_base(&__buf_); 534*fe6060f1SDimitry Andric } 535*fe6060f1SDimitry Andric else 536*fe6060f1SDimitry Andric _VSTD::swap(__f_, __f.__f_); 537*fe6060f1SDimitry Andric } 538*fe6060f1SDimitry Andric 539*fe6060f1SDimitry Andric _LIBCPP_INLINE_VISIBILITY 540*fe6060f1SDimitry Andric explicit operator bool() const _NOEXCEPT { return __f_ != nullptr; } 541*fe6060f1SDimitry Andric 542*fe6060f1SDimitry Andric #ifndef _LIBCPP_NO_RTTI 543*fe6060f1SDimitry Andric _LIBCPP_INLINE_VISIBILITY 544*fe6060f1SDimitry Andric const std::type_info& target_type() const _NOEXCEPT 545*fe6060f1SDimitry Andric { 546*fe6060f1SDimitry Andric if (__f_ == nullptr) 547*fe6060f1SDimitry Andric return typeid(void); 548*fe6060f1SDimitry Andric return __f_->target_type(); 549*fe6060f1SDimitry Andric } 550*fe6060f1SDimitry Andric 551*fe6060f1SDimitry Andric template <typename _Tp> 552*fe6060f1SDimitry Andric _LIBCPP_INLINE_VISIBILITY const _Tp* target() const _NOEXCEPT 553*fe6060f1SDimitry Andric { 554*fe6060f1SDimitry Andric if (__f_ == nullptr) 555*fe6060f1SDimitry Andric return nullptr; 556*fe6060f1SDimitry Andric return (const _Tp*)__f_->target(typeid(_Tp)); 557*fe6060f1SDimitry Andric } 558*fe6060f1SDimitry Andric #endif // _LIBCPP_NO_RTTI 559*fe6060f1SDimitry Andric }; 560*fe6060f1SDimitry Andric 561*fe6060f1SDimitry Andric // Storage for a functor object, to be used with __policy to manage copy and 562*fe6060f1SDimitry Andric // destruction. 563*fe6060f1SDimitry Andric union __policy_storage 564*fe6060f1SDimitry Andric { 565*fe6060f1SDimitry Andric mutable char __small[sizeof(void*) * 2]; 566*fe6060f1SDimitry Andric void* __large; 567*fe6060f1SDimitry Andric }; 568*fe6060f1SDimitry Andric 569*fe6060f1SDimitry Andric // True if _Fun can safely be held in __policy_storage.__small. 570*fe6060f1SDimitry Andric template <typename _Fun> 571*fe6060f1SDimitry Andric struct __use_small_storage 572*fe6060f1SDimitry Andric : public integral_constant< 573*fe6060f1SDimitry Andric bool, sizeof(_Fun) <= sizeof(__policy_storage) && 574*fe6060f1SDimitry Andric _LIBCPP_ALIGNOF(_Fun) <= _LIBCPP_ALIGNOF(__policy_storage) && 575*fe6060f1SDimitry Andric is_trivially_copy_constructible<_Fun>::value && 576*fe6060f1SDimitry Andric is_trivially_destructible<_Fun>::value> {}; 577*fe6060f1SDimitry Andric 578*fe6060f1SDimitry Andric // Policy contains information about how to copy, destroy, and move the 579*fe6060f1SDimitry Andric // underlying functor. You can think of it as a vtable of sorts. 580*fe6060f1SDimitry Andric struct __policy 581*fe6060f1SDimitry Andric { 582*fe6060f1SDimitry Andric // Used to copy or destroy __large values. null for trivial objects. 583*fe6060f1SDimitry Andric void* (*const __clone)(const void*); 584*fe6060f1SDimitry Andric void (*const __destroy)(void*); 585*fe6060f1SDimitry Andric 586*fe6060f1SDimitry Andric // True if this is the null policy (no value). 587*fe6060f1SDimitry Andric const bool __is_null; 588*fe6060f1SDimitry Andric 589*fe6060f1SDimitry Andric // The target type. May be null if RTTI is disabled. 590*fe6060f1SDimitry Andric const std::type_info* const __type_info; 591*fe6060f1SDimitry Andric 592*fe6060f1SDimitry Andric // Returns a pointer to a static policy object suitable for the functor 593*fe6060f1SDimitry Andric // type. 594*fe6060f1SDimitry Andric template <typename _Fun> 595*fe6060f1SDimitry Andric _LIBCPP_INLINE_VISIBILITY static const __policy* __create() 596*fe6060f1SDimitry Andric { 597*fe6060f1SDimitry Andric return __choose_policy<_Fun>(__use_small_storage<_Fun>()); 598*fe6060f1SDimitry Andric } 599*fe6060f1SDimitry Andric 600*fe6060f1SDimitry Andric _LIBCPP_INLINE_VISIBILITY 601*fe6060f1SDimitry Andric static const __policy* __create_empty() 602*fe6060f1SDimitry Andric { 603*fe6060f1SDimitry Andric static const _LIBCPP_CONSTEXPR __policy __policy_ = {nullptr, nullptr, 604*fe6060f1SDimitry Andric true, 605*fe6060f1SDimitry Andric #ifndef _LIBCPP_NO_RTTI 606*fe6060f1SDimitry Andric &typeid(void) 607*fe6060f1SDimitry Andric #else 608*fe6060f1SDimitry Andric nullptr 609*fe6060f1SDimitry Andric #endif 610*fe6060f1SDimitry Andric }; 611*fe6060f1SDimitry Andric return &__policy_; 612*fe6060f1SDimitry Andric } 613*fe6060f1SDimitry Andric 614*fe6060f1SDimitry Andric private: 615*fe6060f1SDimitry Andric template <typename _Fun> static void* __large_clone(const void* __s) 616*fe6060f1SDimitry Andric { 617*fe6060f1SDimitry Andric const _Fun* __f = static_cast<const _Fun*>(__s); 618*fe6060f1SDimitry Andric return __f->__clone(); 619*fe6060f1SDimitry Andric } 620*fe6060f1SDimitry Andric 621*fe6060f1SDimitry Andric template <typename _Fun> 622*fe6060f1SDimitry Andric static void __large_destroy(void* __s) { 623*fe6060f1SDimitry Andric _Fun::__destroy_and_delete(static_cast<_Fun*>(__s)); 624*fe6060f1SDimitry Andric } 625*fe6060f1SDimitry Andric 626*fe6060f1SDimitry Andric template <typename _Fun> 627*fe6060f1SDimitry Andric _LIBCPP_INLINE_VISIBILITY static const __policy* 628*fe6060f1SDimitry Andric __choose_policy(/* is_small = */ false_type) { 629*fe6060f1SDimitry Andric static const _LIBCPP_CONSTEXPR __policy __policy_ = { 630*fe6060f1SDimitry Andric &__large_clone<_Fun>, &__large_destroy<_Fun>, false, 631*fe6060f1SDimitry Andric #ifndef _LIBCPP_NO_RTTI 632*fe6060f1SDimitry Andric &typeid(typename _Fun::_Target) 633*fe6060f1SDimitry Andric #else 634*fe6060f1SDimitry Andric nullptr 635*fe6060f1SDimitry Andric #endif 636*fe6060f1SDimitry Andric }; 637*fe6060f1SDimitry Andric return &__policy_; 638*fe6060f1SDimitry Andric } 639*fe6060f1SDimitry Andric 640*fe6060f1SDimitry Andric template <typename _Fun> 641*fe6060f1SDimitry Andric _LIBCPP_INLINE_VISIBILITY static const __policy* 642*fe6060f1SDimitry Andric __choose_policy(/* is_small = */ true_type) 643*fe6060f1SDimitry Andric { 644*fe6060f1SDimitry Andric static const _LIBCPP_CONSTEXPR __policy __policy_ = { 645*fe6060f1SDimitry Andric nullptr, nullptr, false, 646*fe6060f1SDimitry Andric #ifndef _LIBCPP_NO_RTTI 647*fe6060f1SDimitry Andric &typeid(typename _Fun::_Target) 648*fe6060f1SDimitry Andric #else 649*fe6060f1SDimitry Andric nullptr 650*fe6060f1SDimitry Andric #endif 651*fe6060f1SDimitry Andric }; 652*fe6060f1SDimitry Andric return &__policy_; 653*fe6060f1SDimitry Andric } 654*fe6060f1SDimitry Andric }; 655*fe6060f1SDimitry Andric 656*fe6060f1SDimitry Andric // Used to choose between perfect forwarding or pass-by-value. Pass-by-value is 657*fe6060f1SDimitry Andric // faster for types that can be passed in registers. 658*fe6060f1SDimitry Andric template <typename _Tp> 659*fe6060f1SDimitry Andric using __fast_forward = 660*fe6060f1SDimitry Andric typename conditional<is_scalar<_Tp>::value, _Tp, _Tp&&>::type; 661*fe6060f1SDimitry Andric 662*fe6060f1SDimitry Andric // __policy_invoker calls an instance of __alloc_func held in __policy_storage. 663*fe6060f1SDimitry Andric 664*fe6060f1SDimitry Andric template <class _Fp> struct __policy_invoker; 665*fe6060f1SDimitry Andric 666*fe6060f1SDimitry Andric template <class _Rp, class... _ArgTypes> 667*fe6060f1SDimitry Andric struct __policy_invoker<_Rp(_ArgTypes...)> 668*fe6060f1SDimitry Andric { 669*fe6060f1SDimitry Andric typedef _Rp (*__Call)(const __policy_storage*, 670*fe6060f1SDimitry Andric __fast_forward<_ArgTypes>...); 671*fe6060f1SDimitry Andric 672*fe6060f1SDimitry Andric __Call __call_; 673*fe6060f1SDimitry Andric 674*fe6060f1SDimitry Andric // Creates an invoker that throws bad_function_call. 675*fe6060f1SDimitry Andric _LIBCPP_INLINE_VISIBILITY 676*fe6060f1SDimitry Andric __policy_invoker() : __call_(&__call_empty) {} 677*fe6060f1SDimitry Andric 678*fe6060f1SDimitry Andric // Creates an invoker that calls the given instance of __func. 679*fe6060f1SDimitry Andric template <typename _Fun> 680*fe6060f1SDimitry Andric _LIBCPP_INLINE_VISIBILITY static __policy_invoker __create() 681*fe6060f1SDimitry Andric { 682*fe6060f1SDimitry Andric return __policy_invoker(&__call_impl<_Fun>); 683*fe6060f1SDimitry Andric } 684*fe6060f1SDimitry Andric 685*fe6060f1SDimitry Andric private: 686*fe6060f1SDimitry Andric _LIBCPP_INLINE_VISIBILITY 687*fe6060f1SDimitry Andric explicit __policy_invoker(__Call __c) : __call_(__c) {} 688*fe6060f1SDimitry Andric 689*fe6060f1SDimitry Andric static _Rp __call_empty(const __policy_storage*, 690*fe6060f1SDimitry Andric __fast_forward<_ArgTypes>...) 691*fe6060f1SDimitry Andric { 692*fe6060f1SDimitry Andric __throw_bad_function_call(); 693*fe6060f1SDimitry Andric } 694*fe6060f1SDimitry Andric 695*fe6060f1SDimitry Andric template <typename _Fun> 696*fe6060f1SDimitry Andric static _Rp __call_impl(const __policy_storage* __buf, 697*fe6060f1SDimitry Andric __fast_forward<_ArgTypes>... __args) 698*fe6060f1SDimitry Andric { 699*fe6060f1SDimitry Andric _Fun* __f = reinterpret_cast<_Fun*>(__use_small_storage<_Fun>::value 700*fe6060f1SDimitry Andric ? &__buf->__small 701*fe6060f1SDimitry Andric : __buf->__large); 702*fe6060f1SDimitry Andric return (*__f)(_VSTD::forward<_ArgTypes>(__args)...); 703*fe6060f1SDimitry Andric } 704*fe6060f1SDimitry Andric }; 705*fe6060f1SDimitry Andric 706*fe6060f1SDimitry Andric // __policy_func uses a __policy and __policy_invoker to create a type-erased, 707*fe6060f1SDimitry Andric // copyable functor. 708*fe6060f1SDimitry Andric 709*fe6060f1SDimitry Andric template <class _Fp> class __policy_func; 710*fe6060f1SDimitry Andric 711*fe6060f1SDimitry Andric template <class _Rp, class... _ArgTypes> class __policy_func<_Rp(_ArgTypes...)> 712*fe6060f1SDimitry Andric { 713*fe6060f1SDimitry Andric // Inline storage for small objects. 714*fe6060f1SDimitry Andric __policy_storage __buf_; 715*fe6060f1SDimitry Andric 716*fe6060f1SDimitry Andric // Calls the value stored in __buf_. This could technically be part of 717*fe6060f1SDimitry Andric // policy, but storing it here eliminates a level of indirection inside 718*fe6060f1SDimitry Andric // operator(). 719*fe6060f1SDimitry Andric typedef __function::__policy_invoker<_Rp(_ArgTypes...)> __invoker; 720*fe6060f1SDimitry Andric __invoker __invoker_; 721*fe6060f1SDimitry Andric 722*fe6060f1SDimitry Andric // The policy that describes how to move / copy / destroy __buf_. Never 723*fe6060f1SDimitry Andric // null, even if the function is empty. 724*fe6060f1SDimitry Andric const __policy* __policy_; 725*fe6060f1SDimitry Andric 726*fe6060f1SDimitry Andric public: 727*fe6060f1SDimitry Andric _LIBCPP_INLINE_VISIBILITY 728*fe6060f1SDimitry Andric __policy_func() : __policy_(__policy::__create_empty()) {} 729*fe6060f1SDimitry Andric 730*fe6060f1SDimitry Andric template <class _Fp, class _Alloc> 731*fe6060f1SDimitry Andric _LIBCPP_INLINE_VISIBILITY __policy_func(_Fp&& __f, const _Alloc& __a) 732*fe6060f1SDimitry Andric : __policy_(__policy::__create_empty()) 733*fe6060f1SDimitry Andric { 734*fe6060f1SDimitry Andric typedef __alloc_func<_Fp, _Alloc, _Rp(_ArgTypes...)> _Fun; 735*fe6060f1SDimitry Andric typedef allocator_traits<_Alloc> __alloc_traits; 736*fe6060f1SDimitry Andric typedef typename __rebind_alloc_helper<__alloc_traits, _Fun>::type 737*fe6060f1SDimitry Andric _FunAlloc; 738*fe6060f1SDimitry Andric 739*fe6060f1SDimitry Andric if (__function::__not_null(__f)) 740*fe6060f1SDimitry Andric { 741*fe6060f1SDimitry Andric __invoker_ = __invoker::template __create<_Fun>(); 742*fe6060f1SDimitry Andric __policy_ = __policy::__create<_Fun>(); 743*fe6060f1SDimitry Andric 744*fe6060f1SDimitry Andric _FunAlloc __af(__a); 745*fe6060f1SDimitry Andric if (__use_small_storage<_Fun>()) 746*fe6060f1SDimitry Andric { 747*fe6060f1SDimitry Andric ::new ((void*)&__buf_.__small) 748*fe6060f1SDimitry Andric _Fun(_VSTD::move(__f), _Alloc(__af)); 749*fe6060f1SDimitry Andric } 750*fe6060f1SDimitry Andric else 751*fe6060f1SDimitry Andric { 752*fe6060f1SDimitry Andric typedef __allocator_destructor<_FunAlloc> _Dp; 753*fe6060f1SDimitry Andric unique_ptr<_Fun, _Dp> __hold(__af.allocate(1), _Dp(__af, 1)); 754*fe6060f1SDimitry Andric ::new ((void*)__hold.get()) 755*fe6060f1SDimitry Andric _Fun(_VSTD::move(__f), _Alloc(__af)); 756*fe6060f1SDimitry Andric __buf_.__large = __hold.release(); 757*fe6060f1SDimitry Andric } 758*fe6060f1SDimitry Andric } 759*fe6060f1SDimitry Andric } 760*fe6060f1SDimitry Andric 761*fe6060f1SDimitry Andric template <class _Fp, class = typename enable_if<!is_same<typename decay<_Fp>::type, __policy_func>::value>::type> 762*fe6060f1SDimitry Andric _LIBCPP_INLINE_VISIBILITY explicit __policy_func(_Fp&& __f) 763*fe6060f1SDimitry Andric : __policy_(__policy::__create_empty()) { 764*fe6060f1SDimitry Andric typedef __default_alloc_func<_Fp, _Rp(_ArgTypes...)> _Fun; 765*fe6060f1SDimitry Andric 766*fe6060f1SDimitry Andric if (__function::__not_null(__f)) { 767*fe6060f1SDimitry Andric __invoker_ = __invoker::template __create<_Fun>(); 768*fe6060f1SDimitry Andric __policy_ = __policy::__create<_Fun>(); 769*fe6060f1SDimitry Andric if (__use_small_storage<_Fun>()) { 770*fe6060f1SDimitry Andric ::new ((void*)&__buf_.__small) _Fun(_VSTD::move(__f)); 771*fe6060f1SDimitry Andric } else { 772*fe6060f1SDimitry Andric __builtin_new_allocator::__holder_t __hold = 773*fe6060f1SDimitry Andric __builtin_new_allocator::__allocate_type<_Fun>(1); 774*fe6060f1SDimitry Andric __buf_.__large = ::new ((void*)__hold.get()) _Fun(_VSTD::move(__f)); 775*fe6060f1SDimitry Andric (void)__hold.release(); 776*fe6060f1SDimitry Andric } 777*fe6060f1SDimitry Andric } 778*fe6060f1SDimitry Andric } 779*fe6060f1SDimitry Andric 780*fe6060f1SDimitry Andric _LIBCPP_INLINE_VISIBILITY 781*fe6060f1SDimitry Andric __policy_func(const __policy_func& __f) 782*fe6060f1SDimitry Andric : __buf_(__f.__buf_), __invoker_(__f.__invoker_), 783*fe6060f1SDimitry Andric __policy_(__f.__policy_) 784*fe6060f1SDimitry Andric { 785*fe6060f1SDimitry Andric if (__policy_->__clone) 786*fe6060f1SDimitry Andric __buf_.__large = __policy_->__clone(__f.__buf_.__large); 787*fe6060f1SDimitry Andric } 788*fe6060f1SDimitry Andric 789*fe6060f1SDimitry Andric _LIBCPP_INLINE_VISIBILITY 790*fe6060f1SDimitry Andric __policy_func(__policy_func&& __f) 791*fe6060f1SDimitry Andric : __buf_(__f.__buf_), __invoker_(__f.__invoker_), 792*fe6060f1SDimitry Andric __policy_(__f.__policy_) 793*fe6060f1SDimitry Andric { 794*fe6060f1SDimitry Andric if (__policy_->__destroy) 795*fe6060f1SDimitry Andric { 796*fe6060f1SDimitry Andric __f.__policy_ = __policy::__create_empty(); 797*fe6060f1SDimitry Andric __f.__invoker_ = __invoker(); 798*fe6060f1SDimitry Andric } 799*fe6060f1SDimitry Andric } 800*fe6060f1SDimitry Andric 801*fe6060f1SDimitry Andric _LIBCPP_INLINE_VISIBILITY 802*fe6060f1SDimitry Andric ~__policy_func() 803*fe6060f1SDimitry Andric { 804*fe6060f1SDimitry Andric if (__policy_->__destroy) 805*fe6060f1SDimitry Andric __policy_->__destroy(__buf_.__large); 806*fe6060f1SDimitry Andric } 807*fe6060f1SDimitry Andric 808*fe6060f1SDimitry Andric _LIBCPP_INLINE_VISIBILITY 809*fe6060f1SDimitry Andric __policy_func& operator=(__policy_func&& __f) 810*fe6060f1SDimitry Andric { 811*fe6060f1SDimitry Andric *this = nullptr; 812*fe6060f1SDimitry Andric __buf_ = __f.__buf_; 813*fe6060f1SDimitry Andric __invoker_ = __f.__invoker_; 814*fe6060f1SDimitry Andric __policy_ = __f.__policy_; 815*fe6060f1SDimitry Andric __f.__policy_ = __policy::__create_empty(); 816*fe6060f1SDimitry Andric __f.__invoker_ = __invoker(); 817*fe6060f1SDimitry Andric return *this; 818*fe6060f1SDimitry Andric } 819*fe6060f1SDimitry Andric 820*fe6060f1SDimitry Andric _LIBCPP_INLINE_VISIBILITY 821*fe6060f1SDimitry Andric __policy_func& operator=(nullptr_t) 822*fe6060f1SDimitry Andric { 823*fe6060f1SDimitry Andric const __policy* __p = __policy_; 824*fe6060f1SDimitry Andric __policy_ = __policy::__create_empty(); 825*fe6060f1SDimitry Andric __invoker_ = __invoker(); 826*fe6060f1SDimitry Andric if (__p->__destroy) 827*fe6060f1SDimitry Andric __p->__destroy(__buf_.__large); 828*fe6060f1SDimitry Andric return *this; 829*fe6060f1SDimitry Andric } 830*fe6060f1SDimitry Andric 831*fe6060f1SDimitry Andric _LIBCPP_INLINE_VISIBILITY 832*fe6060f1SDimitry Andric _Rp operator()(_ArgTypes&&... __args) const 833*fe6060f1SDimitry Andric { 834*fe6060f1SDimitry Andric return __invoker_.__call_(_VSTD::addressof(__buf_), 835*fe6060f1SDimitry Andric _VSTD::forward<_ArgTypes>(__args)...); 836*fe6060f1SDimitry Andric } 837*fe6060f1SDimitry Andric 838*fe6060f1SDimitry Andric _LIBCPP_INLINE_VISIBILITY 839*fe6060f1SDimitry Andric void swap(__policy_func& __f) 840*fe6060f1SDimitry Andric { 841*fe6060f1SDimitry Andric _VSTD::swap(__invoker_, __f.__invoker_); 842*fe6060f1SDimitry Andric _VSTD::swap(__policy_, __f.__policy_); 843*fe6060f1SDimitry Andric _VSTD::swap(__buf_, __f.__buf_); 844*fe6060f1SDimitry Andric } 845*fe6060f1SDimitry Andric 846*fe6060f1SDimitry Andric _LIBCPP_INLINE_VISIBILITY 847*fe6060f1SDimitry Andric explicit operator bool() const _NOEXCEPT 848*fe6060f1SDimitry Andric { 849*fe6060f1SDimitry Andric return !__policy_->__is_null; 850*fe6060f1SDimitry Andric } 851*fe6060f1SDimitry Andric 852*fe6060f1SDimitry Andric #ifndef _LIBCPP_NO_RTTI 853*fe6060f1SDimitry Andric _LIBCPP_INLINE_VISIBILITY 854*fe6060f1SDimitry Andric const std::type_info& target_type() const _NOEXCEPT 855*fe6060f1SDimitry Andric { 856*fe6060f1SDimitry Andric return *__policy_->__type_info; 857*fe6060f1SDimitry Andric } 858*fe6060f1SDimitry Andric 859*fe6060f1SDimitry Andric template <typename _Tp> 860*fe6060f1SDimitry Andric _LIBCPP_INLINE_VISIBILITY const _Tp* target() const _NOEXCEPT 861*fe6060f1SDimitry Andric { 862*fe6060f1SDimitry Andric if (__policy_->__is_null || typeid(_Tp) != *__policy_->__type_info) 863*fe6060f1SDimitry Andric return nullptr; 864*fe6060f1SDimitry Andric if (__policy_->__clone) // Out of line storage. 865*fe6060f1SDimitry Andric return reinterpret_cast<const _Tp*>(__buf_.__large); 866*fe6060f1SDimitry Andric else 867*fe6060f1SDimitry Andric return reinterpret_cast<const _Tp*>(&__buf_.__small); 868*fe6060f1SDimitry Andric } 869*fe6060f1SDimitry Andric #endif // _LIBCPP_NO_RTTI 870*fe6060f1SDimitry Andric }; 871*fe6060f1SDimitry Andric 872*fe6060f1SDimitry Andric #if defined(_LIBCPP_HAS_BLOCKS_RUNTIME) && !defined(_LIBCPP_HAS_OBJC_ARC) 873*fe6060f1SDimitry Andric 874*fe6060f1SDimitry Andric extern "C" void *_Block_copy(const void *); 875*fe6060f1SDimitry Andric extern "C" void _Block_release(const void *); 876*fe6060f1SDimitry Andric 877*fe6060f1SDimitry Andric template<class _Rp1, class ..._ArgTypes1, class _Alloc, class _Rp, class ..._ArgTypes> 878*fe6060f1SDimitry Andric class __func<_Rp1(^)(_ArgTypes1...), _Alloc, _Rp(_ArgTypes...)> 879*fe6060f1SDimitry Andric : public __base<_Rp(_ArgTypes...)> 880*fe6060f1SDimitry Andric { 881*fe6060f1SDimitry Andric typedef _Rp1(^__block_type)(_ArgTypes1...); 882*fe6060f1SDimitry Andric __block_type __f_; 883*fe6060f1SDimitry Andric 884*fe6060f1SDimitry Andric public: 885*fe6060f1SDimitry Andric _LIBCPP_INLINE_VISIBILITY 886*fe6060f1SDimitry Andric explicit __func(__block_type const& __f) 887*fe6060f1SDimitry Andric : __f_(reinterpret_cast<__block_type>(__f ? _Block_copy(__f) : nullptr)) 888*fe6060f1SDimitry Andric { } 889*fe6060f1SDimitry Andric 890*fe6060f1SDimitry Andric // [TODO] add && to save on a retain 891*fe6060f1SDimitry Andric 892*fe6060f1SDimitry Andric _LIBCPP_INLINE_VISIBILITY 893*fe6060f1SDimitry Andric explicit __func(__block_type __f, const _Alloc& /* unused */) 894*fe6060f1SDimitry Andric : __f_(reinterpret_cast<__block_type>(__f ? _Block_copy(__f) : nullptr)) 895*fe6060f1SDimitry Andric { } 896*fe6060f1SDimitry Andric 897*fe6060f1SDimitry Andric virtual __base<_Rp(_ArgTypes...)>* __clone() const { 898*fe6060f1SDimitry Andric _LIBCPP_ASSERT(false, 899*fe6060f1SDimitry Andric "Block pointers are just pointers, so they should always fit into " 900*fe6060f1SDimitry Andric "std::function's small buffer optimization. This function should " 901*fe6060f1SDimitry Andric "never be invoked."); 902*fe6060f1SDimitry Andric return nullptr; 903*fe6060f1SDimitry Andric } 904*fe6060f1SDimitry Andric 905*fe6060f1SDimitry Andric virtual void __clone(__base<_Rp(_ArgTypes...)>* __p) const { 906*fe6060f1SDimitry Andric ::new ((void*)__p) __func(__f_); 907*fe6060f1SDimitry Andric } 908*fe6060f1SDimitry Andric 909*fe6060f1SDimitry Andric virtual void destroy() _NOEXCEPT { 910*fe6060f1SDimitry Andric if (__f_) 911*fe6060f1SDimitry Andric _Block_release(__f_); 912*fe6060f1SDimitry Andric __f_ = 0; 913*fe6060f1SDimitry Andric } 914*fe6060f1SDimitry Andric 915*fe6060f1SDimitry Andric virtual void destroy_deallocate() _NOEXCEPT { 916*fe6060f1SDimitry Andric _LIBCPP_ASSERT(false, 917*fe6060f1SDimitry Andric "Block pointers are just pointers, so they should always fit into " 918*fe6060f1SDimitry Andric "std::function's small buffer optimization. This function should " 919*fe6060f1SDimitry Andric "never be invoked."); 920*fe6060f1SDimitry Andric } 921*fe6060f1SDimitry Andric 922*fe6060f1SDimitry Andric virtual _Rp operator()(_ArgTypes&& ... __arg) { 923*fe6060f1SDimitry Andric return _VSTD::__invoke(__f_, _VSTD::forward<_ArgTypes>(__arg)...); 924*fe6060f1SDimitry Andric } 925*fe6060f1SDimitry Andric 926*fe6060f1SDimitry Andric #ifndef _LIBCPP_NO_RTTI 927*fe6060f1SDimitry Andric virtual const void* target(type_info const& __ti) const _NOEXCEPT { 928*fe6060f1SDimitry Andric if (__ti == typeid(__func::__block_type)) 929*fe6060f1SDimitry Andric return &__f_; 930*fe6060f1SDimitry Andric return (const void*)nullptr; 931*fe6060f1SDimitry Andric } 932*fe6060f1SDimitry Andric 933*fe6060f1SDimitry Andric virtual const std::type_info& target_type() const _NOEXCEPT { 934*fe6060f1SDimitry Andric return typeid(__func::__block_type); 935*fe6060f1SDimitry Andric } 936*fe6060f1SDimitry Andric #endif // _LIBCPP_NO_RTTI 937*fe6060f1SDimitry Andric }; 938*fe6060f1SDimitry Andric 939*fe6060f1SDimitry Andric #endif // _LIBCPP_HAS_EXTENSION_BLOCKS && !_LIBCPP_HAS_OBJC_ARC 940*fe6060f1SDimitry Andric 941*fe6060f1SDimitry Andric } // __function 942*fe6060f1SDimitry Andric 943*fe6060f1SDimitry Andric template<class _Rp, class ..._ArgTypes> 944*fe6060f1SDimitry Andric class _LIBCPP_TEMPLATE_VIS function<_Rp(_ArgTypes...)> 945*fe6060f1SDimitry Andric #if _LIBCPP_STD_VER <= 17 || !defined(_LIBCPP_ABI_NO_BINDER_BASES) 946*fe6060f1SDimitry Andric : public __function::__maybe_derive_from_unary_function<_Rp(_ArgTypes...)>, 947*fe6060f1SDimitry Andric public __function::__maybe_derive_from_binary_function<_Rp(_ArgTypes...)> 948*fe6060f1SDimitry Andric #endif 949*fe6060f1SDimitry Andric { 950*fe6060f1SDimitry Andric #ifndef _LIBCPP_ABI_OPTIMIZED_FUNCTION 951*fe6060f1SDimitry Andric typedef __function::__value_func<_Rp(_ArgTypes...)> __func; 952*fe6060f1SDimitry Andric #else 953*fe6060f1SDimitry Andric typedef __function::__policy_func<_Rp(_ArgTypes...)> __func; 954*fe6060f1SDimitry Andric #endif 955*fe6060f1SDimitry Andric 956*fe6060f1SDimitry Andric __func __f_; 957*fe6060f1SDimitry Andric 958*fe6060f1SDimitry Andric template <class _Fp, bool = _And< 959*fe6060f1SDimitry Andric _IsNotSame<__uncvref_t<_Fp>, function>, 960*fe6060f1SDimitry Andric __invokable<_Fp, _ArgTypes...> 961*fe6060f1SDimitry Andric >::value> 962*fe6060f1SDimitry Andric struct __callable; 963*fe6060f1SDimitry Andric template <class _Fp> 964*fe6060f1SDimitry Andric struct __callable<_Fp, true> 965*fe6060f1SDimitry Andric { 966*fe6060f1SDimitry Andric static const bool value = is_void<_Rp>::value || 967*fe6060f1SDimitry Andric __is_core_convertible<typename __invoke_of<_Fp, _ArgTypes...>::type, 968*fe6060f1SDimitry Andric _Rp>::value; 969*fe6060f1SDimitry Andric }; 970*fe6060f1SDimitry Andric template <class _Fp> 971*fe6060f1SDimitry Andric struct __callable<_Fp, false> 972*fe6060f1SDimitry Andric { 973*fe6060f1SDimitry Andric static const bool value = false; 974*fe6060f1SDimitry Andric }; 975*fe6060f1SDimitry Andric 976*fe6060f1SDimitry Andric template <class _Fp> 977*fe6060f1SDimitry Andric using _EnableIfLValueCallable = typename enable_if<__callable<_Fp&>::value>::type; 978*fe6060f1SDimitry Andric public: 979*fe6060f1SDimitry Andric typedef _Rp result_type; 980*fe6060f1SDimitry Andric 981*fe6060f1SDimitry Andric // construct/copy/destroy: 982*fe6060f1SDimitry Andric _LIBCPP_INLINE_VISIBILITY 983*fe6060f1SDimitry Andric function() _NOEXCEPT { } 984*fe6060f1SDimitry Andric _LIBCPP_INLINE_VISIBILITY 985*fe6060f1SDimitry Andric function(nullptr_t) _NOEXCEPT {} 986*fe6060f1SDimitry Andric function(const function&); 987*fe6060f1SDimitry Andric function(function&&) _NOEXCEPT; 988*fe6060f1SDimitry Andric template<class _Fp, class = _EnableIfLValueCallable<_Fp>> 989*fe6060f1SDimitry Andric function(_Fp); 990*fe6060f1SDimitry Andric 991*fe6060f1SDimitry Andric #if _LIBCPP_STD_VER <= 14 992*fe6060f1SDimitry Andric template<class _Alloc> 993*fe6060f1SDimitry Andric _LIBCPP_INLINE_VISIBILITY 994*fe6060f1SDimitry Andric function(allocator_arg_t, const _Alloc&) _NOEXCEPT {} 995*fe6060f1SDimitry Andric template<class _Alloc> 996*fe6060f1SDimitry Andric _LIBCPP_INLINE_VISIBILITY 997*fe6060f1SDimitry Andric function(allocator_arg_t, const _Alloc&, nullptr_t) _NOEXCEPT {} 998*fe6060f1SDimitry Andric template<class _Alloc> 999*fe6060f1SDimitry Andric function(allocator_arg_t, const _Alloc&, const function&); 1000*fe6060f1SDimitry Andric template<class _Alloc> 1001*fe6060f1SDimitry Andric function(allocator_arg_t, const _Alloc&, function&&); 1002*fe6060f1SDimitry Andric template<class _Fp, class _Alloc, class = _EnableIfLValueCallable<_Fp>> 1003*fe6060f1SDimitry Andric function(allocator_arg_t, const _Alloc& __a, _Fp __f); 1004*fe6060f1SDimitry Andric #endif 1005*fe6060f1SDimitry Andric 1006*fe6060f1SDimitry Andric function& operator=(const function&); 1007*fe6060f1SDimitry Andric function& operator=(function&&) _NOEXCEPT; 1008*fe6060f1SDimitry Andric function& operator=(nullptr_t) _NOEXCEPT; 1009*fe6060f1SDimitry Andric template<class _Fp, class = _EnableIfLValueCallable<typename decay<_Fp>::type>> 1010*fe6060f1SDimitry Andric function& operator=(_Fp&&); 1011*fe6060f1SDimitry Andric 1012*fe6060f1SDimitry Andric ~function(); 1013*fe6060f1SDimitry Andric 1014*fe6060f1SDimitry Andric // function modifiers: 1015*fe6060f1SDimitry Andric void swap(function&) _NOEXCEPT; 1016*fe6060f1SDimitry Andric 1017*fe6060f1SDimitry Andric #if _LIBCPP_STD_VER <= 14 1018*fe6060f1SDimitry Andric template<class _Fp, class _Alloc> 1019*fe6060f1SDimitry Andric _LIBCPP_INLINE_VISIBILITY 1020*fe6060f1SDimitry Andric void assign(_Fp&& __f, const _Alloc& __a) 1021*fe6060f1SDimitry Andric {function(allocator_arg, __a, _VSTD::forward<_Fp>(__f)).swap(*this);} 1022*fe6060f1SDimitry Andric #endif 1023*fe6060f1SDimitry Andric 1024*fe6060f1SDimitry Andric // function capacity: 1025*fe6060f1SDimitry Andric _LIBCPP_INLINE_VISIBILITY 1026*fe6060f1SDimitry Andric explicit operator bool() const _NOEXCEPT { 1027*fe6060f1SDimitry Andric return static_cast<bool>(__f_); 1028*fe6060f1SDimitry Andric } 1029*fe6060f1SDimitry Andric 1030*fe6060f1SDimitry Andric // deleted overloads close possible hole in the type system 1031*fe6060f1SDimitry Andric template<class _R2, class... _ArgTypes2> 1032*fe6060f1SDimitry Andric bool operator==(const function<_R2(_ArgTypes2...)>&) const = delete; 1033*fe6060f1SDimitry Andric template<class _R2, class... _ArgTypes2> 1034*fe6060f1SDimitry Andric bool operator!=(const function<_R2(_ArgTypes2...)>&) const = delete; 1035*fe6060f1SDimitry Andric public: 1036*fe6060f1SDimitry Andric // function invocation: 1037*fe6060f1SDimitry Andric _Rp operator()(_ArgTypes...) const; 1038*fe6060f1SDimitry Andric 1039*fe6060f1SDimitry Andric #ifndef _LIBCPP_NO_RTTI 1040*fe6060f1SDimitry Andric // function target access: 1041*fe6060f1SDimitry Andric const std::type_info& target_type() const _NOEXCEPT; 1042*fe6060f1SDimitry Andric template <typename _Tp> _Tp* target() _NOEXCEPT; 1043*fe6060f1SDimitry Andric template <typename _Tp> const _Tp* target() const _NOEXCEPT; 1044*fe6060f1SDimitry Andric #endif // _LIBCPP_NO_RTTI 1045*fe6060f1SDimitry Andric }; 1046*fe6060f1SDimitry Andric 1047*fe6060f1SDimitry Andric #ifndef _LIBCPP_HAS_NO_DEDUCTION_GUIDES 1048*fe6060f1SDimitry Andric template<class _Rp, class ..._Ap> 1049*fe6060f1SDimitry Andric function(_Rp(*)(_Ap...)) -> function<_Rp(_Ap...)>; 1050*fe6060f1SDimitry Andric 1051*fe6060f1SDimitry Andric template<class _Fp> 1052*fe6060f1SDimitry Andric struct __strip_signature; 1053*fe6060f1SDimitry Andric 1054*fe6060f1SDimitry Andric template<class _Rp, class _Gp, class ..._Ap> 1055*fe6060f1SDimitry Andric struct __strip_signature<_Rp (_Gp::*) (_Ap...)> { using type = _Rp(_Ap...); }; 1056*fe6060f1SDimitry Andric template<class _Rp, class _Gp, class ..._Ap> 1057*fe6060f1SDimitry Andric struct __strip_signature<_Rp (_Gp::*) (_Ap...) const> { using type = _Rp(_Ap...); }; 1058*fe6060f1SDimitry Andric template<class _Rp, class _Gp, class ..._Ap> 1059*fe6060f1SDimitry Andric struct __strip_signature<_Rp (_Gp::*) (_Ap...) volatile> { using type = _Rp(_Ap...); }; 1060*fe6060f1SDimitry Andric template<class _Rp, class _Gp, class ..._Ap> 1061*fe6060f1SDimitry Andric struct __strip_signature<_Rp (_Gp::*) (_Ap...) const volatile> { using type = _Rp(_Ap...); }; 1062*fe6060f1SDimitry Andric 1063*fe6060f1SDimitry Andric template<class _Rp, class _Gp, class ..._Ap> 1064*fe6060f1SDimitry Andric struct __strip_signature<_Rp (_Gp::*) (_Ap...) &> { using type = _Rp(_Ap...); }; 1065*fe6060f1SDimitry Andric template<class _Rp, class _Gp, class ..._Ap> 1066*fe6060f1SDimitry Andric struct __strip_signature<_Rp (_Gp::*) (_Ap...) const &> { using type = _Rp(_Ap...); }; 1067*fe6060f1SDimitry Andric template<class _Rp, class _Gp, class ..._Ap> 1068*fe6060f1SDimitry Andric struct __strip_signature<_Rp (_Gp::*) (_Ap...) volatile &> { using type = _Rp(_Ap...); }; 1069*fe6060f1SDimitry Andric template<class _Rp, class _Gp, class ..._Ap> 1070*fe6060f1SDimitry Andric struct __strip_signature<_Rp (_Gp::*) (_Ap...) const volatile &> { using type = _Rp(_Ap...); }; 1071*fe6060f1SDimitry Andric 1072*fe6060f1SDimitry Andric template<class _Rp, class _Gp, class ..._Ap> 1073*fe6060f1SDimitry Andric struct __strip_signature<_Rp (_Gp::*) (_Ap...) noexcept> { using type = _Rp(_Ap...); }; 1074*fe6060f1SDimitry Andric template<class _Rp, class _Gp, class ..._Ap> 1075*fe6060f1SDimitry Andric struct __strip_signature<_Rp (_Gp::*) (_Ap...) const noexcept> { using type = _Rp(_Ap...); }; 1076*fe6060f1SDimitry Andric template<class _Rp, class _Gp, class ..._Ap> 1077*fe6060f1SDimitry Andric struct __strip_signature<_Rp (_Gp::*) (_Ap...) volatile noexcept> { using type = _Rp(_Ap...); }; 1078*fe6060f1SDimitry Andric template<class _Rp, class _Gp, class ..._Ap> 1079*fe6060f1SDimitry Andric struct __strip_signature<_Rp (_Gp::*) (_Ap...) const volatile noexcept> { using type = _Rp(_Ap...); }; 1080*fe6060f1SDimitry Andric 1081*fe6060f1SDimitry Andric template<class _Rp, class _Gp, class ..._Ap> 1082*fe6060f1SDimitry Andric struct __strip_signature<_Rp (_Gp::*) (_Ap...) & noexcept> { using type = _Rp(_Ap...); }; 1083*fe6060f1SDimitry Andric template<class _Rp, class _Gp, class ..._Ap> 1084*fe6060f1SDimitry Andric struct __strip_signature<_Rp (_Gp::*) (_Ap...) const & noexcept> { using type = _Rp(_Ap...); }; 1085*fe6060f1SDimitry Andric template<class _Rp, class _Gp, class ..._Ap> 1086*fe6060f1SDimitry Andric struct __strip_signature<_Rp (_Gp::*) (_Ap...) volatile & noexcept> { using type = _Rp(_Ap...); }; 1087*fe6060f1SDimitry Andric template<class _Rp, class _Gp, class ..._Ap> 1088*fe6060f1SDimitry Andric struct __strip_signature<_Rp (_Gp::*) (_Ap...) const volatile & noexcept> { using type = _Rp(_Ap...); }; 1089*fe6060f1SDimitry Andric 1090*fe6060f1SDimitry Andric template<class _Fp, class _Stripped = typename __strip_signature<decltype(&_Fp::operator())>::type> 1091*fe6060f1SDimitry Andric function(_Fp) -> function<_Stripped>; 1092*fe6060f1SDimitry Andric #endif // !_LIBCPP_HAS_NO_DEDUCTION_GUIDES 1093*fe6060f1SDimitry Andric 1094*fe6060f1SDimitry Andric template<class _Rp, class ..._ArgTypes> 1095*fe6060f1SDimitry Andric function<_Rp(_ArgTypes...)>::function(const function& __f) : __f_(__f.__f_) {} 1096*fe6060f1SDimitry Andric 1097*fe6060f1SDimitry Andric #if _LIBCPP_STD_VER <= 14 1098*fe6060f1SDimitry Andric template<class _Rp, class ..._ArgTypes> 1099*fe6060f1SDimitry Andric template <class _Alloc> 1100*fe6060f1SDimitry Andric function<_Rp(_ArgTypes...)>::function(allocator_arg_t, const _Alloc&, 1101*fe6060f1SDimitry Andric const function& __f) : __f_(__f.__f_) {} 1102*fe6060f1SDimitry Andric #endif 1103*fe6060f1SDimitry Andric 1104*fe6060f1SDimitry Andric template <class _Rp, class... _ArgTypes> 1105*fe6060f1SDimitry Andric function<_Rp(_ArgTypes...)>::function(function&& __f) _NOEXCEPT 1106*fe6060f1SDimitry Andric : __f_(_VSTD::move(__f.__f_)) {} 1107*fe6060f1SDimitry Andric 1108*fe6060f1SDimitry Andric #if _LIBCPP_STD_VER <= 14 1109*fe6060f1SDimitry Andric template<class _Rp, class ..._ArgTypes> 1110*fe6060f1SDimitry Andric template <class _Alloc> 1111*fe6060f1SDimitry Andric function<_Rp(_ArgTypes...)>::function(allocator_arg_t, const _Alloc&, 1112*fe6060f1SDimitry Andric function&& __f) 1113*fe6060f1SDimitry Andric : __f_(_VSTD::move(__f.__f_)) {} 1114*fe6060f1SDimitry Andric #endif 1115*fe6060f1SDimitry Andric 1116*fe6060f1SDimitry Andric template <class _Rp, class... _ArgTypes> 1117*fe6060f1SDimitry Andric template <class _Fp, class> 1118*fe6060f1SDimitry Andric function<_Rp(_ArgTypes...)>::function(_Fp __f) : __f_(_VSTD::move(__f)) {} 1119*fe6060f1SDimitry Andric 1120*fe6060f1SDimitry Andric #if _LIBCPP_STD_VER <= 14 1121*fe6060f1SDimitry Andric template <class _Rp, class... _ArgTypes> 1122*fe6060f1SDimitry Andric template <class _Fp, class _Alloc, class> 1123*fe6060f1SDimitry Andric function<_Rp(_ArgTypes...)>::function(allocator_arg_t, const _Alloc& __a, 1124*fe6060f1SDimitry Andric _Fp __f) 1125*fe6060f1SDimitry Andric : __f_(_VSTD::move(__f), __a) {} 1126*fe6060f1SDimitry Andric #endif 1127*fe6060f1SDimitry Andric 1128*fe6060f1SDimitry Andric template<class _Rp, class ..._ArgTypes> 1129*fe6060f1SDimitry Andric function<_Rp(_ArgTypes...)>& 1130*fe6060f1SDimitry Andric function<_Rp(_ArgTypes...)>::operator=(const function& __f) 1131*fe6060f1SDimitry Andric { 1132*fe6060f1SDimitry Andric function(__f).swap(*this); 1133*fe6060f1SDimitry Andric return *this; 1134*fe6060f1SDimitry Andric } 1135*fe6060f1SDimitry Andric 1136*fe6060f1SDimitry Andric template<class _Rp, class ..._ArgTypes> 1137*fe6060f1SDimitry Andric function<_Rp(_ArgTypes...)>& 1138*fe6060f1SDimitry Andric function<_Rp(_ArgTypes...)>::operator=(function&& __f) _NOEXCEPT 1139*fe6060f1SDimitry Andric { 1140*fe6060f1SDimitry Andric __f_ = _VSTD::move(__f.__f_); 1141*fe6060f1SDimitry Andric return *this; 1142*fe6060f1SDimitry Andric } 1143*fe6060f1SDimitry Andric 1144*fe6060f1SDimitry Andric template<class _Rp, class ..._ArgTypes> 1145*fe6060f1SDimitry Andric function<_Rp(_ArgTypes...)>& 1146*fe6060f1SDimitry Andric function<_Rp(_ArgTypes...)>::operator=(nullptr_t) _NOEXCEPT 1147*fe6060f1SDimitry Andric { 1148*fe6060f1SDimitry Andric __f_ = nullptr; 1149*fe6060f1SDimitry Andric return *this; 1150*fe6060f1SDimitry Andric } 1151*fe6060f1SDimitry Andric 1152*fe6060f1SDimitry Andric template<class _Rp, class ..._ArgTypes> 1153*fe6060f1SDimitry Andric template <class _Fp, class> 1154*fe6060f1SDimitry Andric function<_Rp(_ArgTypes...)>& 1155*fe6060f1SDimitry Andric function<_Rp(_ArgTypes...)>::operator=(_Fp&& __f) 1156*fe6060f1SDimitry Andric { 1157*fe6060f1SDimitry Andric function(_VSTD::forward<_Fp>(__f)).swap(*this); 1158*fe6060f1SDimitry Andric return *this; 1159*fe6060f1SDimitry Andric } 1160*fe6060f1SDimitry Andric 1161*fe6060f1SDimitry Andric template<class _Rp, class ..._ArgTypes> 1162*fe6060f1SDimitry Andric function<_Rp(_ArgTypes...)>::~function() {} 1163*fe6060f1SDimitry Andric 1164*fe6060f1SDimitry Andric template<class _Rp, class ..._ArgTypes> 1165*fe6060f1SDimitry Andric void 1166*fe6060f1SDimitry Andric function<_Rp(_ArgTypes...)>::swap(function& __f) _NOEXCEPT 1167*fe6060f1SDimitry Andric { 1168*fe6060f1SDimitry Andric __f_.swap(__f.__f_); 1169*fe6060f1SDimitry Andric } 1170*fe6060f1SDimitry Andric 1171*fe6060f1SDimitry Andric template<class _Rp, class ..._ArgTypes> 1172*fe6060f1SDimitry Andric _Rp 1173*fe6060f1SDimitry Andric function<_Rp(_ArgTypes...)>::operator()(_ArgTypes... __arg) const 1174*fe6060f1SDimitry Andric { 1175*fe6060f1SDimitry Andric return __f_(_VSTD::forward<_ArgTypes>(__arg)...); 1176*fe6060f1SDimitry Andric } 1177*fe6060f1SDimitry Andric 1178*fe6060f1SDimitry Andric #ifndef _LIBCPP_NO_RTTI 1179*fe6060f1SDimitry Andric 1180*fe6060f1SDimitry Andric template<class _Rp, class ..._ArgTypes> 1181*fe6060f1SDimitry Andric const std::type_info& 1182*fe6060f1SDimitry Andric function<_Rp(_ArgTypes...)>::target_type() const _NOEXCEPT 1183*fe6060f1SDimitry Andric { 1184*fe6060f1SDimitry Andric return __f_.target_type(); 1185*fe6060f1SDimitry Andric } 1186*fe6060f1SDimitry Andric 1187*fe6060f1SDimitry Andric template<class _Rp, class ..._ArgTypes> 1188*fe6060f1SDimitry Andric template <typename _Tp> 1189*fe6060f1SDimitry Andric _Tp* 1190*fe6060f1SDimitry Andric function<_Rp(_ArgTypes...)>::target() _NOEXCEPT 1191*fe6060f1SDimitry Andric { 1192*fe6060f1SDimitry Andric return (_Tp*)(__f_.template target<_Tp>()); 1193*fe6060f1SDimitry Andric } 1194*fe6060f1SDimitry Andric 1195*fe6060f1SDimitry Andric template<class _Rp, class ..._ArgTypes> 1196*fe6060f1SDimitry Andric template <typename _Tp> 1197*fe6060f1SDimitry Andric const _Tp* 1198*fe6060f1SDimitry Andric function<_Rp(_ArgTypes...)>::target() const _NOEXCEPT 1199*fe6060f1SDimitry Andric { 1200*fe6060f1SDimitry Andric return __f_.template target<_Tp>(); 1201*fe6060f1SDimitry Andric } 1202*fe6060f1SDimitry Andric 1203*fe6060f1SDimitry Andric #endif // _LIBCPP_NO_RTTI 1204*fe6060f1SDimitry Andric 1205*fe6060f1SDimitry Andric template <class _Rp, class... _ArgTypes> 1206*fe6060f1SDimitry Andric inline _LIBCPP_INLINE_VISIBILITY 1207*fe6060f1SDimitry Andric bool 1208*fe6060f1SDimitry Andric operator==(const function<_Rp(_ArgTypes...)>& __f, nullptr_t) _NOEXCEPT {return !__f;} 1209*fe6060f1SDimitry Andric 1210*fe6060f1SDimitry Andric template <class _Rp, class... _ArgTypes> 1211*fe6060f1SDimitry Andric inline _LIBCPP_INLINE_VISIBILITY 1212*fe6060f1SDimitry Andric bool 1213*fe6060f1SDimitry Andric operator==(nullptr_t, const function<_Rp(_ArgTypes...)>& __f) _NOEXCEPT {return !__f;} 1214*fe6060f1SDimitry Andric 1215*fe6060f1SDimitry Andric template <class _Rp, class... _ArgTypes> 1216*fe6060f1SDimitry Andric inline _LIBCPP_INLINE_VISIBILITY 1217*fe6060f1SDimitry Andric bool 1218*fe6060f1SDimitry Andric operator!=(const function<_Rp(_ArgTypes...)>& __f, nullptr_t) _NOEXCEPT {return (bool)__f;} 1219*fe6060f1SDimitry Andric 1220*fe6060f1SDimitry Andric template <class _Rp, class... _ArgTypes> 1221*fe6060f1SDimitry Andric inline _LIBCPP_INLINE_VISIBILITY 1222*fe6060f1SDimitry Andric bool 1223*fe6060f1SDimitry Andric operator!=(nullptr_t, const function<_Rp(_ArgTypes...)>& __f) _NOEXCEPT {return (bool)__f;} 1224*fe6060f1SDimitry Andric 1225*fe6060f1SDimitry Andric template <class _Rp, class... _ArgTypes> 1226*fe6060f1SDimitry Andric inline _LIBCPP_INLINE_VISIBILITY 1227*fe6060f1SDimitry Andric void 1228*fe6060f1SDimitry Andric swap(function<_Rp(_ArgTypes...)>& __x, function<_Rp(_ArgTypes...)>& __y) _NOEXCEPT 1229*fe6060f1SDimitry Andric {return __x.swap(__y);} 1230*fe6060f1SDimitry Andric 1231*fe6060f1SDimitry Andric #else // _LIBCPP_CXX03_LANG 1232*fe6060f1SDimitry Andric 1233*fe6060f1SDimitry Andric namespace __function { 1234*fe6060f1SDimitry Andric 1235*fe6060f1SDimitry Andric template<class _Fp> class __base; 1236*fe6060f1SDimitry Andric 1237*fe6060f1SDimitry Andric template<class _Rp> 1238*fe6060f1SDimitry Andric class __base<_Rp()> 1239*fe6060f1SDimitry Andric { 1240*fe6060f1SDimitry Andric __base(const __base&); 1241*fe6060f1SDimitry Andric __base& operator=(const __base&); 1242*fe6060f1SDimitry Andric public: 1243*fe6060f1SDimitry Andric __base() {} 1244*fe6060f1SDimitry Andric virtual ~__base() {} 1245*fe6060f1SDimitry Andric virtual __base* __clone() const = 0; 1246*fe6060f1SDimitry Andric virtual void __clone(__base*) const = 0; 1247*fe6060f1SDimitry Andric virtual void destroy() = 0; 1248*fe6060f1SDimitry Andric virtual void destroy_deallocate() = 0; 1249*fe6060f1SDimitry Andric virtual _Rp operator()() = 0; 1250*fe6060f1SDimitry Andric #ifndef _LIBCPP_NO_RTTI 1251*fe6060f1SDimitry Andric virtual const void* target(const type_info&) const = 0; 1252*fe6060f1SDimitry Andric virtual const std::type_info& target_type() const = 0; 1253*fe6060f1SDimitry Andric #endif // _LIBCPP_NO_RTTI 1254*fe6060f1SDimitry Andric }; 1255*fe6060f1SDimitry Andric 1256*fe6060f1SDimitry Andric template<class _Rp, class _A0> 1257*fe6060f1SDimitry Andric class __base<_Rp(_A0)> 1258*fe6060f1SDimitry Andric { 1259*fe6060f1SDimitry Andric __base(const __base&); 1260*fe6060f1SDimitry Andric __base& operator=(const __base&); 1261*fe6060f1SDimitry Andric public: 1262*fe6060f1SDimitry Andric __base() {} 1263*fe6060f1SDimitry Andric virtual ~__base() {} 1264*fe6060f1SDimitry Andric virtual __base* __clone() const = 0; 1265*fe6060f1SDimitry Andric virtual void __clone(__base*) const = 0; 1266*fe6060f1SDimitry Andric virtual void destroy() = 0; 1267*fe6060f1SDimitry Andric virtual void destroy_deallocate() = 0; 1268*fe6060f1SDimitry Andric virtual _Rp operator()(_A0) = 0; 1269*fe6060f1SDimitry Andric #ifndef _LIBCPP_NO_RTTI 1270*fe6060f1SDimitry Andric virtual const void* target(const type_info&) const = 0; 1271*fe6060f1SDimitry Andric virtual const std::type_info& target_type() const = 0; 1272*fe6060f1SDimitry Andric #endif // _LIBCPP_NO_RTTI 1273*fe6060f1SDimitry Andric }; 1274*fe6060f1SDimitry Andric 1275*fe6060f1SDimitry Andric template<class _Rp, class _A0, class _A1> 1276*fe6060f1SDimitry Andric class __base<_Rp(_A0, _A1)> 1277*fe6060f1SDimitry Andric { 1278*fe6060f1SDimitry Andric __base(const __base&); 1279*fe6060f1SDimitry Andric __base& operator=(const __base&); 1280*fe6060f1SDimitry Andric public: 1281*fe6060f1SDimitry Andric __base() {} 1282*fe6060f1SDimitry Andric virtual ~__base() {} 1283*fe6060f1SDimitry Andric virtual __base* __clone() const = 0; 1284*fe6060f1SDimitry Andric virtual void __clone(__base*) const = 0; 1285*fe6060f1SDimitry Andric virtual void destroy() = 0; 1286*fe6060f1SDimitry Andric virtual void destroy_deallocate() = 0; 1287*fe6060f1SDimitry Andric virtual _Rp operator()(_A0, _A1) = 0; 1288*fe6060f1SDimitry Andric #ifndef _LIBCPP_NO_RTTI 1289*fe6060f1SDimitry Andric virtual const void* target(const type_info&) const = 0; 1290*fe6060f1SDimitry Andric virtual const std::type_info& target_type() const = 0; 1291*fe6060f1SDimitry Andric #endif // _LIBCPP_NO_RTTI 1292*fe6060f1SDimitry Andric }; 1293*fe6060f1SDimitry Andric 1294*fe6060f1SDimitry Andric template<class _Rp, class _A0, class _A1, class _A2> 1295*fe6060f1SDimitry Andric class __base<_Rp(_A0, _A1, _A2)> 1296*fe6060f1SDimitry Andric { 1297*fe6060f1SDimitry Andric __base(const __base&); 1298*fe6060f1SDimitry Andric __base& operator=(const __base&); 1299*fe6060f1SDimitry Andric public: 1300*fe6060f1SDimitry Andric __base() {} 1301*fe6060f1SDimitry Andric virtual ~__base() {} 1302*fe6060f1SDimitry Andric virtual __base* __clone() const = 0; 1303*fe6060f1SDimitry Andric virtual void __clone(__base*) const = 0; 1304*fe6060f1SDimitry Andric virtual void destroy() = 0; 1305*fe6060f1SDimitry Andric virtual void destroy_deallocate() = 0; 1306*fe6060f1SDimitry Andric virtual _Rp operator()(_A0, _A1, _A2) = 0; 1307*fe6060f1SDimitry Andric #ifndef _LIBCPP_NO_RTTI 1308*fe6060f1SDimitry Andric virtual const void* target(const type_info&) const = 0; 1309*fe6060f1SDimitry Andric virtual const std::type_info& target_type() const = 0; 1310*fe6060f1SDimitry Andric #endif // _LIBCPP_NO_RTTI 1311*fe6060f1SDimitry Andric }; 1312*fe6060f1SDimitry Andric 1313*fe6060f1SDimitry Andric template<class _FD, class _Alloc, class _FB> class __func; 1314*fe6060f1SDimitry Andric 1315*fe6060f1SDimitry Andric template<class _Fp, class _Alloc, class _Rp> 1316*fe6060f1SDimitry Andric class __func<_Fp, _Alloc, _Rp()> 1317*fe6060f1SDimitry Andric : public __base<_Rp()> 1318*fe6060f1SDimitry Andric { 1319*fe6060f1SDimitry Andric __compressed_pair<_Fp, _Alloc> __f_; 1320*fe6060f1SDimitry Andric public: 1321*fe6060f1SDimitry Andric explicit __func(_Fp __f) : __f_(_VSTD::move(__f), __default_init_tag()) {} 1322*fe6060f1SDimitry Andric explicit __func(_Fp __f, _Alloc __a) : __f_(_VSTD::move(__f), _VSTD::move(__a)) {} 1323*fe6060f1SDimitry Andric virtual __base<_Rp()>* __clone() const; 1324*fe6060f1SDimitry Andric virtual void __clone(__base<_Rp()>*) const; 1325*fe6060f1SDimitry Andric virtual void destroy(); 1326*fe6060f1SDimitry Andric virtual void destroy_deallocate(); 1327*fe6060f1SDimitry Andric virtual _Rp operator()(); 1328*fe6060f1SDimitry Andric #ifndef _LIBCPP_NO_RTTI 1329*fe6060f1SDimitry Andric virtual const void* target(const type_info&) const; 1330*fe6060f1SDimitry Andric virtual const std::type_info& target_type() const; 1331*fe6060f1SDimitry Andric #endif // _LIBCPP_NO_RTTI 1332*fe6060f1SDimitry Andric }; 1333*fe6060f1SDimitry Andric 1334*fe6060f1SDimitry Andric template<class _Fp, class _Alloc, class _Rp> 1335*fe6060f1SDimitry Andric __base<_Rp()>* 1336*fe6060f1SDimitry Andric __func<_Fp, _Alloc, _Rp()>::__clone() const 1337*fe6060f1SDimitry Andric { 1338*fe6060f1SDimitry Andric typedef allocator_traits<_Alloc> __alloc_traits; 1339*fe6060f1SDimitry Andric typedef typename __rebind_alloc_helper<__alloc_traits, __func>::type _Ap; 1340*fe6060f1SDimitry Andric _Ap __a(__f_.second()); 1341*fe6060f1SDimitry Andric typedef __allocator_destructor<_Ap> _Dp; 1342*fe6060f1SDimitry Andric unique_ptr<__func, _Dp> __hold(__a.allocate(1), _Dp(__a, 1)); 1343*fe6060f1SDimitry Andric ::new ((void*)__hold.get()) __func(__f_.first(), _Alloc(__a)); 1344*fe6060f1SDimitry Andric return __hold.release(); 1345*fe6060f1SDimitry Andric } 1346*fe6060f1SDimitry Andric 1347*fe6060f1SDimitry Andric template<class _Fp, class _Alloc, class _Rp> 1348*fe6060f1SDimitry Andric void 1349*fe6060f1SDimitry Andric __func<_Fp, _Alloc, _Rp()>::__clone(__base<_Rp()>* __p) const 1350*fe6060f1SDimitry Andric { 1351*fe6060f1SDimitry Andric ::new ((void*)__p) __func(__f_.first(), __f_.second()); 1352*fe6060f1SDimitry Andric } 1353*fe6060f1SDimitry Andric 1354*fe6060f1SDimitry Andric template<class _Fp, class _Alloc, class _Rp> 1355*fe6060f1SDimitry Andric void 1356*fe6060f1SDimitry Andric __func<_Fp, _Alloc, _Rp()>::destroy() 1357*fe6060f1SDimitry Andric { 1358*fe6060f1SDimitry Andric __f_.~__compressed_pair<_Fp, _Alloc>(); 1359*fe6060f1SDimitry Andric } 1360*fe6060f1SDimitry Andric 1361*fe6060f1SDimitry Andric template<class _Fp, class _Alloc, class _Rp> 1362*fe6060f1SDimitry Andric void 1363*fe6060f1SDimitry Andric __func<_Fp, _Alloc, _Rp()>::destroy_deallocate() 1364*fe6060f1SDimitry Andric { 1365*fe6060f1SDimitry Andric typedef allocator_traits<_Alloc> __alloc_traits; 1366*fe6060f1SDimitry Andric typedef typename __rebind_alloc_helper<__alloc_traits, __func>::type _Ap; 1367*fe6060f1SDimitry Andric _Ap __a(__f_.second()); 1368*fe6060f1SDimitry Andric __f_.~__compressed_pair<_Fp, _Alloc>(); 1369*fe6060f1SDimitry Andric __a.deallocate(this, 1); 1370*fe6060f1SDimitry Andric } 1371*fe6060f1SDimitry Andric 1372*fe6060f1SDimitry Andric template<class _Fp, class _Alloc, class _Rp> 1373*fe6060f1SDimitry Andric _Rp 1374*fe6060f1SDimitry Andric __func<_Fp, _Alloc, _Rp()>::operator()() 1375*fe6060f1SDimitry Andric { 1376*fe6060f1SDimitry Andric typedef __invoke_void_return_wrapper<_Rp> _Invoker; 1377*fe6060f1SDimitry Andric return _Invoker::__call(__f_.first()); 1378*fe6060f1SDimitry Andric } 1379*fe6060f1SDimitry Andric 1380*fe6060f1SDimitry Andric #ifndef _LIBCPP_NO_RTTI 1381*fe6060f1SDimitry Andric 1382*fe6060f1SDimitry Andric template<class _Fp, class _Alloc, class _Rp> 1383*fe6060f1SDimitry Andric const void* 1384*fe6060f1SDimitry Andric __func<_Fp, _Alloc, _Rp()>::target(const type_info& __ti) const 1385*fe6060f1SDimitry Andric { 1386*fe6060f1SDimitry Andric if (__ti == typeid(_Fp)) 1387*fe6060f1SDimitry Andric return &__f_.first(); 1388*fe6060f1SDimitry Andric return (const void*)0; 1389*fe6060f1SDimitry Andric } 1390*fe6060f1SDimitry Andric 1391*fe6060f1SDimitry Andric template<class _Fp, class _Alloc, class _Rp> 1392*fe6060f1SDimitry Andric const std::type_info& 1393*fe6060f1SDimitry Andric __func<_Fp, _Alloc, _Rp()>::target_type() const 1394*fe6060f1SDimitry Andric { 1395*fe6060f1SDimitry Andric return typeid(_Fp); 1396*fe6060f1SDimitry Andric } 1397*fe6060f1SDimitry Andric 1398*fe6060f1SDimitry Andric #endif // _LIBCPP_NO_RTTI 1399*fe6060f1SDimitry Andric 1400*fe6060f1SDimitry Andric template<class _Fp, class _Alloc, class _Rp, class _A0> 1401*fe6060f1SDimitry Andric class __func<_Fp, _Alloc, _Rp(_A0)> 1402*fe6060f1SDimitry Andric : public __base<_Rp(_A0)> 1403*fe6060f1SDimitry Andric { 1404*fe6060f1SDimitry Andric __compressed_pair<_Fp, _Alloc> __f_; 1405*fe6060f1SDimitry Andric public: 1406*fe6060f1SDimitry Andric _LIBCPP_INLINE_VISIBILITY explicit __func(_Fp __f) : __f_(_VSTD::move(__f), __default_init_tag()) {} 1407*fe6060f1SDimitry Andric _LIBCPP_INLINE_VISIBILITY explicit __func(_Fp __f, _Alloc __a) 1408*fe6060f1SDimitry Andric : __f_(_VSTD::move(__f), _VSTD::move(__a)) {} 1409*fe6060f1SDimitry Andric virtual __base<_Rp(_A0)>* __clone() const; 1410*fe6060f1SDimitry Andric virtual void __clone(__base<_Rp(_A0)>*) const; 1411*fe6060f1SDimitry Andric virtual void destroy(); 1412*fe6060f1SDimitry Andric virtual void destroy_deallocate(); 1413*fe6060f1SDimitry Andric virtual _Rp operator()(_A0); 1414*fe6060f1SDimitry Andric #ifndef _LIBCPP_NO_RTTI 1415*fe6060f1SDimitry Andric virtual const void* target(const type_info&) const; 1416*fe6060f1SDimitry Andric virtual const std::type_info& target_type() const; 1417*fe6060f1SDimitry Andric #endif // _LIBCPP_NO_RTTI 1418*fe6060f1SDimitry Andric }; 1419*fe6060f1SDimitry Andric 1420*fe6060f1SDimitry Andric template<class _Fp, class _Alloc, class _Rp, class _A0> 1421*fe6060f1SDimitry Andric __base<_Rp(_A0)>* 1422*fe6060f1SDimitry Andric __func<_Fp, _Alloc, _Rp(_A0)>::__clone() const 1423*fe6060f1SDimitry Andric { 1424*fe6060f1SDimitry Andric typedef allocator_traits<_Alloc> __alloc_traits; 1425*fe6060f1SDimitry Andric typedef typename __rebind_alloc_helper<__alloc_traits, __func>::type _Ap; 1426*fe6060f1SDimitry Andric _Ap __a(__f_.second()); 1427*fe6060f1SDimitry Andric typedef __allocator_destructor<_Ap> _Dp; 1428*fe6060f1SDimitry Andric unique_ptr<__func, _Dp> __hold(__a.allocate(1), _Dp(__a, 1)); 1429*fe6060f1SDimitry Andric ::new ((void*)__hold.get()) __func(__f_.first(), _Alloc(__a)); 1430*fe6060f1SDimitry Andric return __hold.release(); 1431*fe6060f1SDimitry Andric } 1432*fe6060f1SDimitry Andric 1433*fe6060f1SDimitry Andric template<class _Fp, class _Alloc, class _Rp, class _A0> 1434*fe6060f1SDimitry Andric void 1435*fe6060f1SDimitry Andric __func<_Fp, _Alloc, _Rp(_A0)>::__clone(__base<_Rp(_A0)>* __p) const 1436*fe6060f1SDimitry Andric { 1437*fe6060f1SDimitry Andric ::new ((void*)__p) __func(__f_.first(), __f_.second()); 1438*fe6060f1SDimitry Andric } 1439*fe6060f1SDimitry Andric 1440*fe6060f1SDimitry Andric template<class _Fp, class _Alloc, class _Rp, class _A0> 1441*fe6060f1SDimitry Andric void 1442*fe6060f1SDimitry Andric __func<_Fp, _Alloc, _Rp(_A0)>::destroy() 1443*fe6060f1SDimitry Andric { 1444*fe6060f1SDimitry Andric __f_.~__compressed_pair<_Fp, _Alloc>(); 1445*fe6060f1SDimitry Andric } 1446*fe6060f1SDimitry Andric 1447*fe6060f1SDimitry Andric template<class _Fp, class _Alloc, class _Rp, class _A0> 1448*fe6060f1SDimitry Andric void 1449*fe6060f1SDimitry Andric __func<_Fp, _Alloc, _Rp(_A0)>::destroy_deallocate() 1450*fe6060f1SDimitry Andric { 1451*fe6060f1SDimitry Andric typedef allocator_traits<_Alloc> __alloc_traits; 1452*fe6060f1SDimitry Andric typedef typename __rebind_alloc_helper<__alloc_traits, __func>::type _Ap; 1453*fe6060f1SDimitry Andric _Ap __a(__f_.second()); 1454*fe6060f1SDimitry Andric __f_.~__compressed_pair<_Fp, _Alloc>(); 1455*fe6060f1SDimitry Andric __a.deallocate(this, 1); 1456*fe6060f1SDimitry Andric } 1457*fe6060f1SDimitry Andric 1458*fe6060f1SDimitry Andric template<class _Fp, class _Alloc, class _Rp, class _A0> 1459*fe6060f1SDimitry Andric _Rp 1460*fe6060f1SDimitry Andric __func<_Fp, _Alloc, _Rp(_A0)>::operator()(_A0 __a0) 1461*fe6060f1SDimitry Andric { 1462*fe6060f1SDimitry Andric typedef __invoke_void_return_wrapper<_Rp> _Invoker; 1463*fe6060f1SDimitry Andric return _Invoker::__call(__f_.first(), __a0); 1464*fe6060f1SDimitry Andric } 1465*fe6060f1SDimitry Andric 1466*fe6060f1SDimitry Andric #ifndef _LIBCPP_NO_RTTI 1467*fe6060f1SDimitry Andric 1468*fe6060f1SDimitry Andric template<class _Fp, class _Alloc, class _Rp, class _A0> 1469*fe6060f1SDimitry Andric const void* 1470*fe6060f1SDimitry Andric __func<_Fp, _Alloc, _Rp(_A0)>::target(const type_info& __ti) const 1471*fe6060f1SDimitry Andric { 1472*fe6060f1SDimitry Andric if (__ti == typeid(_Fp)) 1473*fe6060f1SDimitry Andric return &__f_.first(); 1474*fe6060f1SDimitry Andric return (const void*)0; 1475*fe6060f1SDimitry Andric } 1476*fe6060f1SDimitry Andric 1477*fe6060f1SDimitry Andric template<class _Fp, class _Alloc, class _Rp, class _A0> 1478*fe6060f1SDimitry Andric const std::type_info& 1479*fe6060f1SDimitry Andric __func<_Fp, _Alloc, _Rp(_A0)>::target_type() const 1480*fe6060f1SDimitry Andric { 1481*fe6060f1SDimitry Andric return typeid(_Fp); 1482*fe6060f1SDimitry Andric } 1483*fe6060f1SDimitry Andric 1484*fe6060f1SDimitry Andric #endif // _LIBCPP_NO_RTTI 1485*fe6060f1SDimitry Andric 1486*fe6060f1SDimitry Andric template<class _Fp, class _Alloc, class _Rp, class _A0, class _A1> 1487*fe6060f1SDimitry Andric class __func<_Fp, _Alloc, _Rp(_A0, _A1)> 1488*fe6060f1SDimitry Andric : public __base<_Rp(_A0, _A1)> 1489*fe6060f1SDimitry Andric { 1490*fe6060f1SDimitry Andric __compressed_pair<_Fp, _Alloc> __f_; 1491*fe6060f1SDimitry Andric public: 1492*fe6060f1SDimitry Andric _LIBCPP_INLINE_VISIBILITY explicit __func(_Fp __f) : __f_(_VSTD::move(__f), __default_init_tag()) {} 1493*fe6060f1SDimitry Andric _LIBCPP_INLINE_VISIBILITY explicit __func(_Fp __f, _Alloc __a) 1494*fe6060f1SDimitry Andric : __f_(_VSTD::move(__f), _VSTD::move(__a)) {} 1495*fe6060f1SDimitry Andric virtual __base<_Rp(_A0, _A1)>* __clone() const; 1496*fe6060f1SDimitry Andric virtual void __clone(__base<_Rp(_A0, _A1)>*) const; 1497*fe6060f1SDimitry Andric virtual void destroy(); 1498*fe6060f1SDimitry Andric virtual void destroy_deallocate(); 1499*fe6060f1SDimitry Andric virtual _Rp operator()(_A0, _A1); 1500*fe6060f1SDimitry Andric #ifndef _LIBCPP_NO_RTTI 1501*fe6060f1SDimitry Andric virtual const void* target(const type_info&) const; 1502*fe6060f1SDimitry Andric virtual const std::type_info& target_type() const; 1503*fe6060f1SDimitry Andric #endif // _LIBCPP_NO_RTTI 1504*fe6060f1SDimitry Andric }; 1505*fe6060f1SDimitry Andric 1506*fe6060f1SDimitry Andric template<class _Fp, class _Alloc, class _Rp, class _A0, class _A1> 1507*fe6060f1SDimitry Andric __base<_Rp(_A0, _A1)>* 1508*fe6060f1SDimitry Andric __func<_Fp, _Alloc, _Rp(_A0, _A1)>::__clone() const 1509*fe6060f1SDimitry Andric { 1510*fe6060f1SDimitry Andric typedef allocator_traits<_Alloc> __alloc_traits; 1511*fe6060f1SDimitry Andric typedef typename __rebind_alloc_helper<__alloc_traits, __func>::type _Ap; 1512*fe6060f1SDimitry Andric _Ap __a(__f_.second()); 1513*fe6060f1SDimitry Andric typedef __allocator_destructor<_Ap> _Dp; 1514*fe6060f1SDimitry Andric unique_ptr<__func, _Dp> __hold(__a.allocate(1), _Dp(__a, 1)); 1515*fe6060f1SDimitry Andric ::new ((void*)__hold.get()) __func(__f_.first(), _Alloc(__a)); 1516*fe6060f1SDimitry Andric return __hold.release(); 1517*fe6060f1SDimitry Andric } 1518*fe6060f1SDimitry Andric 1519*fe6060f1SDimitry Andric template<class _Fp, class _Alloc, class _Rp, class _A0, class _A1> 1520*fe6060f1SDimitry Andric void 1521*fe6060f1SDimitry Andric __func<_Fp, _Alloc, _Rp(_A0, _A1)>::__clone(__base<_Rp(_A0, _A1)>* __p) const 1522*fe6060f1SDimitry Andric { 1523*fe6060f1SDimitry Andric ::new ((void*)__p) __func(__f_.first(), __f_.second()); 1524*fe6060f1SDimitry Andric } 1525*fe6060f1SDimitry Andric 1526*fe6060f1SDimitry Andric template<class _Fp, class _Alloc, class _Rp, class _A0, class _A1> 1527*fe6060f1SDimitry Andric void 1528*fe6060f1SDimitry Andric __func<_Fp, _Alloc, _Rp(_A0, _A1)>::destroy() 1529*fe6060f1SDimitry Andric { 1530*fe6060f1SDimitry Andric __f_.~__compressed_pair<_Fp, _Alloc>(); 1531*fe6060f1SDimitry Andric } 1532*fe6060f1SDimitry Andric 1533*fe6060f1SDimitry Andric template<class _Fp, class _Alloc, class _Rp, class _A0, class _A1> 1534*fe6060f1SDimitry Andric void 1535*fe6060f1SDimitry Andric __func<_Fp, _Alloc, _Rp(_A0, _A1)>::destroy_deallocate() 1536*fe6060f1SDimitry Andric { 1537*fe6060f1SDimitry Andric typedef allocator_traits<_Alloc> __alloc_traits; 1538*fe6060f1SDimitry Andric typedef typename __rebind_alloc_helper<__alloc_traits, __func>::type _Ap; 1539*fe6060f1SDimitry Andric _Ap __a(__f_.second()); 1540*fe6060f1SDimitry Andric __f_.~__compressed_pair<_Fp, _Alloc>(); 1541*fe6060f1SDimitry Andric __a.deallocate(this, 1); 1542*fe6060f1SDimitry Andric } 1543*fe6060f1SDimitry Andric 1544*fe6060f1SDimitry Andric template<class _Fp, class _Alloc, class _Rp, class _A0, class _A1> 1545*fe6060f1SDimitry Andric _Rp 1546*fe6060f1SDimitry Andric __func<_Fp, _Alloc, _Rp(_A0, _A1)>::operator()(_A0 __a0, _A1 __a1) 1547*fe6060f1SDimitry Andric { 1548*fe6060f1SDimitry Andric typedef __invoke_void_return_wrapper<_Rp> _Invoker; 1549*fe6060f1SDimitry Andric return _Invoker::__call(__f_.first(), __a0, __a1); 1550*fe6060f1SDimitry Andric } 1551*fe6060f1SDimitry Andric 1552*fe6060f1SDimitry Andric #ifndef _LIBCPP_NO_RTTI 1553*fe6060f1SDimitry Andric 1554*fe6060f1SDimitry Andric template<class _Fp, class _Alloc, class _Rp, class _A0, class _A1> 1555*fe6060f1SDimitry Andric const void* 1556*fe6060f1SDimitry Andric __func<_Fp, _Alloc, _Rp(_A0, _A1)>::target(const type_info& __ti) const 1557*fe6060f1SDimitry Andric { 1558*fe6060f1SDimitry Andric if (__ti == typeid(_Fp)) 1559*fe6060f1SDimitry Andric return &__f_.first(); 1560*fe6060f1SDimitry Andric return (const void*)0; 1561*fe6060f1SDimitry Andric } 1562*fe6060f1SDimitry Andric 1563*fe6060f1SDimitry Andric template<class _Fp, class _Alloc, class _Rp, class _A0, class _A1> 1564*fe6060f1SDimitry Andric const std::type_info& 1565*fe6060f1SDimitry Andric __func<_Fp, _Alloc, _Rp(_A0, _A1)>::target_type() const 1566*fe6060f1SDimitry Andric { 1567*fe6060f1SDimitry Andric return typeid(_Fp); 1568*fe6060f1SDimitry Andric } 1569*fe6060f1SDimitry Andric 1570*fe6060f1SDimitry Andric #endif // _LIBCPP_NO_RTTI 1571*fe6060f1SDimitry Andric 1572*fe6060f1SDimitry Andric template<class _Fp, class _Alloc, class _Rp, class _A0, class _A1, class _A2> 1573*fe6060f1SDimitry Andric class __func<_Fp, _Alloc, _Rp(_A0, _A1, _A2)> 1574*fe6060f1SDimitry Andric : public __base<_Rp(_A0, _A1, _A2)> 1575*fe6060f1SDimitry Andric { 1576*fe6060f1SDimitry Andric __compressed_pair<_Fp, _Alloc> __f_; 1577*fe6060f1SDimitry Andric public: 1578*fe6060f1SDimitry Andric _LIBCPP_INLINE_VISIBILITY explicit __func(_Fp __f) : __f_(_VSTD::move(__f), __default_init_tag()) {} 1579*fe6060f1SDimitry Andric _LIBCPP_INLINE_VISIBILITY explicit __func(_Fp __f, _Alloc __a) 1580*fe6060f1SDimitry Andric : __f_(_VSTD::move(__f), _VSTD::move(__a)) {} 1581*fe6060f1SDimitry Andric virtual __base<_Rp(_A0, _A1, _A2)>* __clone() const; 1582*fe6060f1SDimitry Andric virtual void __clone(__base<_Rp(_A0, _A1, _A2)>*) const; 1583*fe6060f1SDimitry Andric virtual void destroy(); 1584*fe6060f1SDimitry Andric virtual void destroy_deallocate(); 1585*fe6060f1SDimitry Andric virtual _Rp operator()(_A0, _A1, _A2); 1586*fe6060f1SDimitry Andric #ifndef _LIBCPP_NO_RTTI 1587*fe6060f1SDimitry Andric virtual const void* target(const type_info&) const; 1588*fe6060f1SDimitry Andric virtual const std::type_info& target_type() const; 1589*fe6060f1SDimitry Andric #endif // _LIBCPP_NO_RTTI 1590*fe6060f1SDimitry Andric }; 1591*fe6060f1SDimitry Andric 1592*fe6060f1SDimitry Andric template<class _Fp, class _Alloc, class _Rp, class _A0, class _A1, class _A2> 1593*fe6060f1SDimitry Andric __base<_Rp(_A0, _A1, _A2)>* 1594*fe6060f1SDimitry Andric __func<_Fp, _Alloc, _Rp(_A0, _A1, _A2)>::__clone() const 1595*fe6060f1SDimitry Andric { 1596*fe6060f1SDimitry Andric typedef allocator_traits<_Alloc> __alloc_traits; 1597*fe6060f1SDimitry Andric typedef typename __rebind_alloc_helper<__alloc_traits, __func>::type _Ap; 1598*fe6060f1SDimitry Andric _Ap __a(__f_.second()); 1599*fe6060f1SDimitry Andric typedef __allocator_destructor<_Ap> _Dp; 1600*fe6060f1SDimitry Andric unique_ptr<__func, _Dp> __hold(__a.allocate(1), _Dp(__a, 1)); 1601*fe6060f1SDimitry Andric ::new ((void*)__hold.get()) __func(__f_.first(), _Alloc(__a)); 1602*fe6060f1SDimitry Andric return __hold.release(); 1603*fe6060f1SDimitry Andric } 1604*fe6060f1SDimitry Andric 1605*fe6060f1SDimitry Andric template<class _Fp, class _Alloc, class _Rp, class _A0, class _A1, class _A2> 1606*fe6060f1SDimitry Andric void 1607*fe6060f1SDimitry Andric __func<_Fp, _Alloc, _Rp(_A0, _A1, _A2)>::__clone(__base<_Rp(_A0, _A1, _A2)>* __p) const 1608*fe6060f1SDimitry Andric { 1609*fe6060f1SDimitry Andric ::new ((void*)__p) __func(__f_.first(), __f_.second()); 1610*fe6060f1SDimitry Andric } 1611*fe6060f1SDimitry Andric 1612*fe6060f1SDimitry Andric template<class _Fp, class _Alloc, class _Rp, class _A0, class _A1, class _A2> 1613*fe6060f1SDimitry Andric void 1614*fe6060f1SDimitry Andric __func<_Fp, _Alloc, _Rp(_A0, _A1, _A2)>::destroy() 1615*fe6060f1SDimitry Andric { 1616*fe6060f1SDimitry Andric __f_.~__compressed_pair<_Fp, _Alloc>(); 1617*fe6060f1SDimitry Andric } 1618*fe6060f1SDimitry Andric 1619*fe6060f1SDimitry Andric template<class _Fp, class _Alloc, class _Rp, class _A0, class _A1, class _A2> 1620*fe6060f1SDimitry Andric void 1621*fe6060f1SDimitry Andric __func<_Fp, _Alloc, _Rp(_A0, _A1, _A2)>::destroy_deallocate() 1622*fe6060f1SDimitry Andric { 1623*fe6060f1SDimitry Andric typedef allocator_traits<_Alloc> __alloc_traits; 1624*fe6060f1SDimitry Andric typedef typename __rebind_alloc_helper<__alloc_traits, __func>::type _Ap; 1625*fe6060f1SDimitry Andric _Ap __a(__f_.second()); 1626*fe6060f1SDimitry Andric __f_.~__compressed_pair<_Fp, _Alloc>(); 1627*fe6060f1SDimitry Andric __a.deallocate(this, 1); 1628*fe6060f1SDimitry Andric } 1629*fe6060f1SDimitry Andric 1630*fe6060f1SDimitry Andric template<class _Fp, class _Alloc, class _Rp, class _A0, class _A1, class _A2> 1631*fe6060f1SDimitry Andric _Rp 1632*fe6060f1SDimitry Andric __func<_Fp, _Alloc, _Rp(_A0, _A1, _A2)>::operator()(_A0 __a0, _A1 __a1, _A2 __a2) 1633*fe6060f1SDimitry Andric { 1634*fe6060f1SDimitry Andric typedef __invoke_void_return_wrapper<_Rp> _Invoker; 1635*fe6060f1SDimitry Andric return _Invoker::__call(__f_.first(), __a0, __a1, __a2); 1636*fe6060f1SDimitry Andric } 1637*fe6060f1SDimitry Andric 1638*fe6060f1SDimitry Andric #ifndef _LIBCPP_NO_RTTI 1639*fe6060f1SDimitry Andric 1640*fe6060f1SDimitry Andric template<class _Fp, class _Alloc, class _Rp, class _A0, class _A1, class _A2> 1641*fe6060f1SDimitry Andric const void* 1642*fe6060f1SDimitry Andric __func<_Fp, _Alloc, _Rp(_A0, _A1, _A2)>::target(const type_info& __ti) const 1643*fe6060f1SDimitry Andric { 1644*fe6060f1SDimitry Andric if (__ti == typeid(_Fp)) 1645*fe6060f1SDimitry Andric return &__f_.first(); 1646*fe6060f1SDimitry Andric return (const void*)0; 1647*fe6060f1SDimitry Andric } 1648*fe6060f1SDimitry Andric 1649*fe6060f1SDimitry Andric template<class _Fp, class _Alloc, class _Rp, class _A0, class _A1, class _A2> 1650*fe6060f1SDimitry Andric const std::type_info& 1651*fe6060f1SDimitry Andric __func<_Fp, _Alloc, _Rp(_A0, _A1, _A2)>::target_type() const 1652*fe6060f1SDimitry Andric { 1653*fe6060f1SDimitry Andric return typeid(_Fp); 1654*fe6060f1SDimitry Andric } 1655*fe6060f1SDimitry Andric 1656*fe6060f1SDimitry Andric #endif // _LIBCPP_NO_RTTI 1657*fe6060f1SDimitry Andric 1658*fe6060f1SDimitry Andric } // __function 1659*fe6060f1SDimitry Andric 1660*fe6060f1SDimitry Andric template<class _Rp> 1661*fe6060f1SDimitry Andric class _LIBCPP_TEMPLATE_VIS function<_Rp()> 1662*fe6060f1SDimitry Andric { 1663*fe6060f1SDimitry Andric typedef __function::__base<_Rp()> __base; 1664*fe6060f1SDimitry Andric aligned_storage<3*sizeof(void*)>::type __buf_; 1665*fe6060f1SDimitry Andric __base* __f_; 1666*fe6060f1SDimitry Andric 1667*fe6060f1SDimitry Andric public: 1668*fe6060f1SDimitry Andric typedef _Rp result_type; 1669*fe6060f1SDimitry Andric 1670*fe6060f1SDimitry Andric // 20.7.16.2.1, construct/copy/destroy: 1671*fe6060f1SDimitry Andric _LIBCPP_INLINE_VISIBILITY explicit function() : __f_(0) {} 1672*fe6060f1SDimitry Andric _LIBCPP_INLINE_VISIBILITY function(nullptr_t) : __f_(0) {} 1673*fe6060f1SDimitry Andric function(const function&); 1674*fe6060f1SDimitry Andric template<class _Fp> 1675*fe6060f1SDimitry Andric function(_Fp, 1676*fe6060f1SDimitry Andric typename enable_if<!is_integral<_Fp>::value>::type* = 0); 1677*fe6060f1SDimitry Andric 1678*fe6060f1SDimitry Andric template<class _Alloc> 1679*fe6060f1SDimitry Andric _LIBCPP_INLINE_VISIBILITY 1680*fe6060f1SDimitry Andric function(allocator_arg_t, const _Alloc&) : __f_(0) {} 1681*fe6060f1SDimitry Andric template<class _Alloc> 1682*fe6060f1SDimitry Andric _LIBCPP_INLINE_VISIBILITY 1683*fe6060f1SDimitry Andric function(allocator_arg_t, const _Alloc&, nullptr_t) : __f_(0) {} 1684*fe6060f1SDimitry Andric template<class _Alloc> 1685*fe6060f1SDimitry Andric function(allocator_arg_t, const _Alloc&, const function&); 1686*fe6060f1SDimitry Andric template<class _Fp, class _Alloc> 1687*fe6060f1SDimitry Andric function(allocator_arg_t, const _Alloc& __a, _Fp __f, 1688*fe6060f1SDimitry Andric typename enable_if<!is_integral<_Fp>::value>::type* = 0); 1689*fe6060f1SDimitry Andric 1690*fe6060f1SDimitry Andric function& operator=(const function&); 1691*fe6060f1SDimitry Andric function& operator=(nullptr_t); 1692*fe6060f1SDimitry Andric template<class _Fp> 1693*fe6060f1SDimitry Andric typename enable_if 1694*fe6060f1SDimitry Andric < 1695*fe6060f1SDimitry Andric !is_integral<_Fp>::value, 1696*fe6060f1SDimitry Andric function& 1697*fe6060f1SDimitry Andric >::type 1698*fe6060f1SDimitry Andric operator=(_Fp); 1699*fe6060f1SDimitry Andric 1700*fe6060f1SDimitry Andric ~function(); 1701*fe6060f1SDimitry Andric 1702*fe6060f1SDimitry Andric // 20.7.16.2.2, function modifiers: 1703*fe6060f1SDimitry Andric void swap(function&); 1704*fe6060f1SDimitry Andric template<class _Fp, class _Alloc> 1705*fe6060f1SDimitry Andric _LIBCPP_INLINE_VISIBILITY 1706*fe6060f1SDimitry Andric void assign(_Fp __f, const _Alloc& __a) 1707*fe6060f1SDimitry Andric {function(allocator_arg, __a, __f).swap(*this);} 1708*fe6060f1SDimitry Andric 1709*fe6060f1SDimitry Andric // 20.7.16.2.3, function capacity: 1710*fe6060f1SDimitry Andric _LIBCPP_INLINE_VISIBILITY explicit operator bool() const {return __f_;} 1711*fe6060f1SDimitry Andric 1712*fe6060f1SDimitry Andric private: 1713*fe6060f1SDimitry Andric // deleted overloads close possible hole in the type system 1714*fe6060f1SDimitry Andric template<class _R2> 1715*fe6060f1SDimitry Andric bool operator==(const function<_R2()>&) const;// = delete; 1716*fe6060f1SDimitry Andric template<class _R2> 1717*fe6060f1SDimitry Andric bool operator!=(const function<_R2()>&) const;// = delete; 1718*fe6060f1SDimitry Andric public: 1719*fe6060f1SDimitry Andric // 20.7.16.2.4, function invocation: 1720*fe6060f1SDimitry Andric _Rp operator()() const; 1721*fe6060f1SDimitry Andric 1722*fe6060f1SDimitry Andric #ifndef _LIBCPP_NO_RTTI 1723*fe6060f1SDimitry Andric // 20.7.16.2.5, function target access: 1724*fe6060f1SDimitry Andric const std::type_info& target_type() const; 1725*fe6060f1SDimitry Andric template <typename _Tp> _Tp* target(); 1726*fe6060f1SDimitry Andric template <typename _Tp> const _Tp* target() const; 1727*fe6060f1SDimitry Andric #endif // _LIBCPP_NO_RTTI 1728*fe6060f1SDimitry Andric }; 1729*fe6060f1SDimitry Andric 1730*fe6060f1SDimitry Andric template<class _Rp> 1731*fe6060f1SDimitry Andric function<_Rp()>::function(const function& __f) 1732*fe6060f1SDimitry Andric { 1733*fe6060f1SDimitry Andric if (__f.__f_ == 0) 1734*fe6060f1SDimitry Andric __f_ = 0; 1735*fe6060f1SDimitry Andric else if (__f.__f_ == (const __base*)&__f.__buf_) 1736*fe6060f1SDimitry Andric { 1737*fe6060f1SDimitry Andric __f_ = (__base*)&__buf_; 1738*fe6060f1SDimitry Andric __f.__f_->__clone(__f_); 1739*fe6060f1SDimitry Andric } 1740*fe6060f1SDimitry Andric else 1741*fe6060f1SDimitry Andric __f_ = __f.__f_->__clone(); 1742*fe6060f1SDimitry Andric } 1743*fe6060f1SDimitry Andric 1744*fe6060f1SDimitry Andric template<class _Rp> 1745*fe6060f1SDimitry Andric template<class _Alloc> 1746*fe6060f1SDimitry Andric function<_Rp()>::function(allocator_arg_t, const _Alloc&, const function& __f) 1747*fe6060f1SDimitry Andric { 1748*fe6060f1SDimitry Andric if (__f.__f_ == 0) 1749*fe6060f1SDimitry Andric __f_ = 0; 1750*fe6060f1SDimitry Andric else if (__f.__f_ == (const __base*)&__f.__buf_) 1751*fe6060f1SDimitry Andric { 1752*fe6060f1SDimitry Andric __f_ = (__base*)&__buf_; 1753*fe6060f1SDimitry Andric __f.__f_->__clone(__f_); 1754*fe6060f1SDimitry Andric } 1755*fe6060f1SDimitry Andric else 1756*fe6060f1SDimitry Andric __f_ = __f.__f_->__clone(); 1757*fe6060f1SDimitry Andric } 1758*fe6060f1SDimitry Andric 1759*fe6060f1SDimitry Andric template<class _Rp> 1760*fe6060f1SDimitry Andric template <class _Fp> 1761*fe6060f1SDimitry Andric function<_Rp()>::function(_Fp __f, 1762*fe6060f1SDimitry Andric typename enable_if<!is_integral<_Fp>::value>::type*) 1763*fe6060f1SDimitry Andric : __f_(0) 1764*fe6060f1SDimitry Andric { 1765*fe6060f1SDimitry Andric if (__function::__not_null(__f)) 1766*fe6060f1SDimitry Andric { 1767*fe6060f1SDimitry Andric typedef __function::__func<_Fp, allocator<_Fp>, _Rp()> _FF; 1768*fe6060f1SDimitry Andric if (sizeof(_FF) <= sizeof(__buf_)) 1769*fe6060f1SDimitry Andric { 1770*fe6060f1SDimitry Andric __f_ = (__base*)&__buf_; 1771*fe6060f1SDimitry Andric ::new ((void*)__f_) _FF(__f); 1772*fe6060f1SDimitry Andric } 1773*fe6060f1SDimitry Andric else 1774*fe6060f1SDimitry Andric { 1775*fe6060f1SDimitry Andric typedef allocator<_FF> _Ap; 1776*fe6060f1SDimitry Andric _Ap __a; 1777*fe6060f1SDimitry Andric typedef __allocator_destructor<_Ap> _Dp; 1778*fe6060f1SDimitry Andric unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1)); 1779*fe6060f1SDimitry Andric ::new ((void*)__hold.get()) _FF(__f, allocator<_Fp>(__a)); 1780*fe6060f1SDimitry Andric __f_ = __hold.release(); 1781*fe6060f1SDimitry Andric } 1782*fe6060f1SDimitry Andric } 1783*fe6060f1SDimitry Andric } 1784*fe6060f1SDimitry Andric 1785*fe6060f1SDimitry Andric template<class _Rp> 1786*fe6060f1SDimitry Andric template <class _Fp, class _Alloc> 1787*fe6060f1SDimitry Andric function<_Rp()>::function(allocator_arg_t, const _Alloc& __a0, _Fp __f, 1788*fe6060f1SDimitry Andric typename enable_if<!is_integral<_Fp>::value>::type*) 1789*fe6060f1SDimitry Andric : __f_(0) 1790*fe6060f1SDimitry Andric { 1791*fe6060f1SDimitry Andric typedef allocator_traits<_Alloc> __alloc_traits; 1792*fe6060f1SDimitry Andric if (__function::__not_null(__f)) 1793*fe6060f1SDimitry Andric { 1794*fe6060f1SDimitry Andric typedef __function::__func<_Fp, _Alloc, _Rp()> _FF; 1795*fe6060f1SDimitry Andric if (sizeof(_FF) <= sizeof(__buf_)) 1796*fe6060f1SDimitry Andric { 1797*fe6060f1SDimitry Andric __f_ = (__base*)&__buf_; 1798*fe6060f1SDimitry Andric ::new ((void*)__f_) _FF(__f, __a0); 1799*fe6060f1SDimitry Andric } 1800*fe6060f1SDimitry Andric else 1801*fe6060f1SDimitry Andric { 1802*fe6060f1SDimitry Andric typedef typename __rebind_alloc_helper<__alloc_traits, _FF>::type _Ap; 1803*fe6060f1SDimitry Andric _Ap __a(__a0); 1804*fe6060f1SDimitry Andric typedef __allocator_destructor<_Ap> _Dp; 1805*fe6060f1SDimitry Andric unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1)); 1806*fe6060f1SDimitry Andric ::new ((void*)__hold.get()) _FF(__f, _Alloc(__a)); 1807*fe6060f1SDimitry Andric __f_ = __hold.release(); 1808*fe6060f1SDimitry Andric } 1809*fe6060f1SDimitry Andric } 1810*fe6060f1SDimitry Andric } 1811*fe6060f1SDimitry Andric 1812*fe6060f1SDimitry Andric template<class _Rp> 1813*fe6060f1SDimitry Andric function<_Rp()>& 1814*fe6060f1SDimitry Andric function<_Rp()>::operator=(const function& __f) 1815*fe6060f1SDimitry Andric { 1816*fe6060f1SDimitry Andric if (__f) 1817*fe6060f1SDimitry Andric function(__f).swap(*this); 1818*fe6060f1SDimitry Andric else 1819*fe6060f1SDimitry Andric *this = nullptr; 1820*fe6060f1SDimitry Andric return *this; 1821*fe6060f1SDimitry Andric } 1822*fe6060f1SDimitry Andric 1823*fe6060f1SDimitry Andric template<class _Rp> 1824*fe6060f1SDimitry Andric function<_Rp()>& 1825*fe6060f1SDimitry Andric function<_Rp()>::operator=(nullptr_t) 1826*fe6060f1SDimitry Andric { 1827*fe6060f1SDimitry Andric __base* __t = __f_; 1828*fe6060f1SDimitry Andric __f_ = 0; 1829*fe6060f1SDimitry Andric if (__t == (__base*)&__buf_) 1830*fe6060f1SDimitry Andric __t->destroy(); 1831*fe6060f1SDimitry Andric else if (__t) 1832*fe6060f1SDimitry Andric __t->destroy_deallocate(); 1833*fe6060f1SDimitry Andric return *this; 1834*fe6060f1SDimitry Andric } 1835*fe6060f1SDimitry Andric 1836*fe6060f1SDimitry Andric template<class _Rp> 1837*fe6060f1SDimitry Andric template <class _Fp> 1838*fe6060f1SDimitry Andric typename enable_if 1839*fe6060f1SDimitry Andric < 1840*fe6060f1SDimitry Andric !is_integral<_Fp>::value, 1841*fe6060f1SDimitry Andric function<_Rp()>& 1842*fe6060f1SDimitry Andric >::type 1843*fe6060f1SDimitry Andric function<_Rp()>::operator=(_Fp __f) 1844*fe6060f1SDimitry Andric { 1845*fe6060f1SDimitry Andric function(_VSTD::move(__f)).swap(*this); 1846*fe6060f1SDimitry Andric return *this; 1847*fe6060f1SDimitry Andric } 1848*fe6060f1SDimitry Andric 1849*fe6060f1SDimitry Andric template<class _Rp> 1850*fe6060f1SDimitry Andric function<_Rp()>::~function() 1851*fe6060f1SDimitry Andric { 1852*fe6060f1SDimitry Andric if (__f_ == (__base*)&__buf_) 1853*fe6060f1SDimitry Andric __f_->destroy(); 1854*fe6060f1SDimitry Andric else if (__f_) 1855*fe6060f1SDimitry Andric __f_->destroy_deallocate(); 1856*fe6060f1SDimitry Andric } 1857*fe6060f1SDimitry Andric 1858*fe6060f1SDimitry Andric template<class _Rp> 1859*fe6060f1SDimitry Andric void 1860*fe6060f1SDimitry Andric function<_Rp()>::swap(function& __f) 1861*fe6060f1SDimitry Andric { 1862*fe6060f1SDimitry Andric if (_VSTD::addressof(__f) == this) 1863*fe6060f1SDimitry Andric return; 1864*fe6060f1SDimitry Andric if (__f_ == (__base*)&__buf_ && __f.__f_ == (__base*)&__f.__buf_) 1865*fe6060f1SDimitry Andric { 1866*fe6060f1SDimitry Andric typename aligned_storage<sizeof(__buf_)>::type __tempbuf; 1867*fe6060f1SDimitry Andric __base* __t = (__base*)&__tempbuf; 1868*fe6060f1SDimitry Andric __f_->__clone(__t); 1869*fe6060f1SDimitry Andric __f_->destroy(); 1870*fe6060f1SDimitry Andric __f_ = 0; 1871*fe6060f1SDimitry Andric __f.__f_->__clone((__base*)&__buf_); 1872*fe6060f1SDimitry Andric __f.__f_->destroy(); 1873*fe6060f1SDimitry Andric __f.__f_ = 0; 1874*fe6060f1SDimitry Andric __f_ = (__base*)&__buf_; 1875*fe6060f1SDimitry Andric __t->__clone((__base*)&__f.__buf_); 1876*fe6060f1SDimitry Andric __t->destroy(); 1877*fe6060f1SDimitry Andric __f.__f_ = (__base*)&__f.__buf_; 1878*fe6060f1SDimitry Andric } 1879*fe6060f1SDimitry Andric else if (__f_ == (__base*)&__buf_) 1880*fe6060f1SDimitry Andric { 1881*fe6060f1SDimitry Andric __f_->__clone((__base*)&__f.__buf_); 1882*fe6060f1SDimitry Andric __f_->destroy(); 1883*fe6060f1SDimitry Andric __f_ = __f.__f_; 1884*fe6060f1SDimitry Andric __f.__f_ = (__base*)&__f.__buf_; 1885*fe6060f1SDimitry Andric } 1886*fe6060f1SDimitry Andric else if (__f.__f_ == (__base*)&__f.__buf_) 1887*fe6060f1SDimitry Andric { 1888*fe6060f1SDimitry Andric __f.__f_->__clone((__base*)&__buf_); 1889*fe6060f1SDimitry Andric __f.__f_->destroy(); 1890*fe6060f1SDimitry Andric __f.__f_ = __f_; 1891*fe6060f1SDimitry Andric __f_ = (__base*)&__buf_; 1892*fe6060f1SDimitry Andric } 1893*fe6060f1SDimitry Andric else 1894*fe6060f1SDimitry Andric _VSTD::swap(__f_, __f.__f_); 1895*fe6060f1SDimitry Andric } 1896*fe6060f1SDimitry Andric 1897*fe6060f1SDimitry Andric template<class _Rp> 1898*fe6060f1SDimitry Andric _Rp 1899*fe6060f1SDimitry Andric function<_Rp()>::operator()() const 1900*fe6060f1SDimitry Andric { 1901*fe6060f1SDimitry Andric if (__f_ == 0) 1902*fe6060f1SDimitry Andric __throw_bad_function_call(); 1903*fe6060f1SDimitry Andric return (*__f_)(); 1904*fe6060f1SDimitry Andric } 1905*fe6060f1SDimitry Andric 1906*fe6060f1SDimitry Andric #ifndef _LIBCPP_NO_RTTI 1907*fe6060f1SDimitry Andric 1908*fe6060f1SDimitry Andric template<class _Rp> 1909*fe6060f1SDimitry Andric const std::type_info& 1910*fe6060f1SDimitry Andric function<_Rp()>::target_type() const 1911*fe6060f1SDimitry Andric { 1912*fe6060f1SDimitry Andric if (__f_ == 0) 1913*fe6060f1SDimitry Andric return typeid(void); 1914*fe6060f1SDimitry Andric return __f_->target_type(); 1915*fe6060f1SDimitry Andric } 1916*fe6060f1SDimitry Andric 1917*fe6060f1SDimitry Andric template<class _Rp> 1918*fe6060f1SDimitry Andric template <typename _Tp> 1919*fe6060f1SDimitry Andric _Tp* 1920*fe6060f1SDimitry Andric function<_Rp()>::target() 1921*fe6060f1SDimitry Andric { 1922*fe6060f1SDimitry Andric if (__f_ == 0) 1923*fe6060f1SDimitry Andric return (_Tp*)0; 1924*fe6060f1SDimitry Andric return (_Tp*) const_cast<void *>(__f_->target(typeid(_Tp))); 1925*fe6060f1SDimitry Andric } 1926*fe6060f1SDimitry Andric 1927*fe6060f1SDimitry Andric template<class _Rp> 1928*fe6060f1SDimitry Andric template <typename _Tp> 1929*fe6060f1SDimitry Andric const _Tp* 1930*fe6060f1SDimitry Andric function<_Rp()>::target() const 1931*fe6060f1SDimitry Andric { 1932*fe6060f1SDimitry Andric if (__f_ == 0) 1933*fe6060f1SDimitry Andric return (const _Tp*)0; 1934*fe6060f1SDimitry Andric return (const _Tp*)__f_->target(typeid(_Tp)); 1935*fe6060f1SDimitry Andric } 1936*fe6060f1SDimitry Andric 1937*fe6060f1SDimitry Andric #endif // _LIBCPP_NO_RTTI 1938*fe6060f1SDimitry Andric 1939*fe6060f1SDimitry Andric template<class _Rp, class _A0> 1940*fe6060f1SDimitry Andric class _LIBCPP_TEMPLATE_VIS function<_Rp(_A0)> 1941*fe6060f1SDimitry Andric : public unary_function<_A0, _Rp> 1942*fe6060f1SDimitry Andric { 1943*fe6060f1SDimitry Andric typedef __function::__base<_Rp(_A0)> __base; 1944*fe6060f1SDimitry Andric aligned_storage<3*sizeof(void*)>::type __buf_; 1945*fe6060f1SDimitry Andric __base* __f_; 1946*fe6060f1SDimitry Andric 1947*fe6060f1SDimitry Andric public: 1948*fe6060f1SDimitry Andric typedef _Rp result_type; 1949*fe6060f1SDimitry Andric 1950*fe6060f1SDimitry Andric // 20.7.16.2.1, construct/copy/destroy: 1951*fe6060f1SDimitry Andric _LIBCPP_INLINE_VISIBILITY explicit function() : __f_(0) {} 1952*fe6060f1SDimitry Andric _LIBCPP_INLINE_VISIBILITY function(nullptr_t) : __f_(0) {} 1953*fe6060f1SDimitry Andric function(const function&); 1954*fe6060f1SDimitry Andric template<class _Fp> 1955*fe6060f1SDimitry Andric function(_Fp, 1956*fe6060f1SDimitry Andric typename enable_if<!is_integral<_Fp>::value>::type* = 0); 1957*fe6060f1SDimitry Andric 1958*fe6060f1SDimitry Andric template<class _Alloc> 1959*fe6060f1SDimitry Andric _LIBCPP_INLINE_VISIBILITY 1960*fe6060f1SDimitry Andric function(allocator_arg_t, const _Alloc&) : __f_(0) {} 1961*fe6060f1SDimitry Andric template<class _Alloc> 1962*fe6060f1SDimitry Andric _LIBCPP_INLINE_VISIBILITY 1963*fe6060f1SDimitry Andric function(allocator_arg_t, const _Alloc&, nullptr_t) : __f_(0) {} 1964*fe6060f1SDimitry Andric template<class _Alloc> 1965*fe6060f1SDimitry Andric function(allocator_arg_t, const _Alloc&, const function&); 1966*fe6060f1SDimitry Andric template<class _Fp, class _Alloc> 1967*fe6060f1SDimitry Andric function(allocator_arg_t, const _Alloc& __a, _Fp __f, 1968*fe6060f1SDimitry Andric typename enable_if<!is_integral<_Fp>::value>::type* = 0); 1969*fe6060f1SDimitry Andric 1970*fe6060f1SDimitry Andric function& operator=(const function&); 1971*fe6060f1SDimitry Andric function& operator=(nullptr_t); 1972*fe6060f1SDimitry Andric template<class _Fp> 1973*fe6060f1SDimitry Andric typename enable_if 1974*fe6060f1SDimitry Andric < 1975*fe6060f1SDimitry Andric !is_integral<_Fp>::value, 1976*fe6060f1SDimitry Andric function& 1977*fe6060f1SDimitry Andric >::type 1978*fe6060f1SDimitry Andric operator=(_Fp); 1979*fe6060f1SDimitry Andric 1980*fe6060f1SDimitry Andric ~function(); 1981*fe6060f1SDimitry Andric 1982*fe6060f1SDimitry Andric // 20.7.16.2.2, function modifiers: 1983*fe6060f1SDimitry Andric void swap(function&); 1984*fe6060f1SDimitry Andric template<class _Fp, class _Alloc> 1985*fe6060f1SDimitry Andric _LIBCPP_INLINE_VISIBILITY 1986*fe6060f1SDimitry Andric void assign(_Fp __f, const _Alloc& __a) 1987*fe6060f1SDimitry Andric {function(allocator_arg, __a, __f).swap(*this);} 1988*fe6060f1SDimitry Andric 1989*fe6060f1SDimitry Andric // 20.7.16.2.3, function capacity: 1990*fe6060f1SDimitry Andric _LIBCPP_INLINE_VISIBILITY explicit operator bool() const {return __f_;} 1991*fe6060f1SDimitry Andric 1992*fe6060f1SDimitry Andric private: 1993*fe6060f1SDimitry Andric // deleted overloads close possible hole in the type system 1994*fe6060f1SDimitry Andric template<class _R2, class _B0> 1995*fe6060f1SDimitry Andric bool operator==(const function<_R2(_B0)>&) const;// = delete; 1996*fe6060f1SDimitry Andric template<class _R2, class _B0> 1997*fe6060f1SDimitry Andric bool operator!=(const function<_R2(_B0)>&) const;// = delete; 1998*fe6060f1SDimitry Andric public: 1999*fe6060f1SDimitry Andric // 20.7.16.2.4, function invocation: 2000*fe6060f1SDimitry Andric _Rp operator()(_A0) const; 2001*fe6060f1SDimitry Andric 2002*fe6060f1SDimitry Andric #ifndef _LIBCPP_NO_RTTI 2003*fe6060f1SDimitry Andric // 20.7.16.2.5, function target access: 2004*fe6060f1SDimitry Andric const std::type_info& target_type() const; 2005*fe6060f1SDimitry Andric template <typename _Tp> _Tp* target(); 2006*fe6060f1SDimitry Andric template <typename _Tp> const _Tp* target() const; 2007*fe6060f1SDimitry Andric #endif // _LIBCPP_NO_RTTI 2008*fe6060f1SDimitry Andric }; 2009*fe6060f1SDimitry Andric 2010*fe6060f1SDimitry Andric template<class _Rp, class _A0> 2011*fe6060f1SDimitry Andric function<_Rp(_A0)>::function(const function& __f) 2012*fe6060f1SDimitry Andric { 2013*fe6060f1SDimitry Andric if (__f.__f_ == 0) 2014*fe6060f1SDimitry Andric __f_ = 0; 2015*fe6060f1SDimitry Andric else if (__f.__f_ == (const __base*)&__f.__buf_) 2016*fe6060f1SDimitry Andric { 2017*fe6060f1SDimitry Andric __f_ = (__base*)&__buf_; 2018*fe6060f1SDimitry Andric __f.__f_->__clone(__f_); 2019*fe6060f1SDimitry Andric } 2020*fe6060f1SDimitry Andric else 2021*fe6060f1SDimitry Andric __f_ = __f.__f_->__clone(); 2022*fe6060f1SDimitry Andric } 2023*fe6060f1SDimitry Andric 2024*fe6060f1SDimitry Andric template<class _Rp, class _A0> 2025*fe6060f1SDimitry Andric template<class _Alloc> 2026*fe6060f1SDimitry Andric function<_Rp(_A0)>::function(allocator_arg_t, const _Alloc&, const function& __f) 2027*fe6060f1SDimitry Andric { 2028*fe6060f1SDimitry Andric if (__f.__f_ == 0) 2029*fe6060f1SDimitry Andric __f_ = 0; 2030*fe6060f1SDimitry Andric else if (__f.__f_ == (const __base*)&__f.__buf_) 2031*fe6060f1SDimitry Andric { 2032*fe6060f1SDimitry Andric __f_ = (__base*)&__buf_; 2033*fe6060f1SDimitry Andric __f.__f_->__clone(__f_); 2034*fe6060f1SDimitry Andric } 2035*fe6060f1SDimitry Andric else 2036*fe6060f1SDimitry Andric __f_ = __f.__f_->__clone(); 2037*fe6060f1SDimitry Andric } 2038*fe6060f1SDimitry Andric 2039*fe6060f1SDimitry Andric template<class _Rp, class _A0> 2040*fe6060f1SDimitry Andric template <class _Fp> 2041*fe6060f1SDimitry Andric function<_Rp(_A0)>::function(_Fp __f, 2042*fe6060f1SDimitry Andric typename enable_if<!is_integral<_Fp>::value>::type*) 2043*fe6060f1SDimitry Andric : __f_(0) 2044*fe6060f1SDimitry Andric { 2045*fe6060f1SDimitry Andric if (__function::__not_null(__f)) 2046*fe6060f1SDimitry Andric { 2047*fe6060f1SDimitry Andric typedef __function::__func<_Fp, allocator<_Fp>, _Rp(_A0)> _FF; 2048*fe6060f1SDimitry Andric if (sizeof(_FF) <= sizeof(__buf_)) 2049*fe6060f1SDimitry Andric { 2050*fe6060f1SDimitry Andric __f_ = (__base*)&__buf_; 2051*fe6060f1SDimitry Andric ::new ((void*)__f_) _FF(__f); 2052*fe6060f1SDimitry Andric } 2053*fe6060f1SDimitry Andric else 2054*fe6060f1SDimitry Andric { 2055*fe6060f1SDimitry Andric typedef allocator<_FF> _Ap; 2056*fe6060f1SDimitry Andric _Ap __a; 2057*fe6060f1SDimitry Andric typedef __allocator_destructor<_Ap> _Dp; 2058*fe6060f1SDimitry Andric unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1)); 2059*fe6060f1SDimitry Andric ::new ((void*)__hold.get()) _FF(__f, allocator<_Fp>(__a)); 2060*fe6060f1SDimitry Andric __f_ = __hold.release(); 2061*fe6060f1SDimitry Andric } 2062*fe6060f1SDimitry Andric } 2063*fe6060f1SDimitry Andric } 2064*fe6060f1SDimitry Andric 2065*fe6060f1SDimitry Andric template<class _Rp, class _A0> 2066*fe6060f1SDimitry Andric template <class _Fp, class _Alloc> 2067*fe6060f1SDimitry Andric function<_Rp(_A0)>::function(allocator_arg_t, const _Alloc& __a0, _Fp __f, 2068*fe6060f1SDimitry Andric typename enable_if<!is_integral<_Fp>::value>::type*) 2069*fe6060f1SDimitry Andric : __f_(0) 2070*fe6060f1SDimitry Andric { 2071*fe6060f1SDimitry Andric typedef allocator_traits<_Alloc> __alloc_traits; 2072*fe6060f1SDimitry Andric if (__function::__not_null(__f)) 2073*fe6060f1SDimitry Andric { 2074*fe6060f1SDimitry Andric typedef __function::__func<_Fp, _Alloc, _Rp(_A0)> _FF; 2075*fe6060f1SDimitry Andric if (sizeof(_FF) <= sizeof(__buf_)) 2076*fe6060f1SDimitry Andric { 2077*fe6060f1SDimitry Andric __f_ = (__base*)&__buf_; 2078*fe6060f1SDimitry Andric ::new ((void*)__f_) _FF(__f, __a0); 2079*fe6060f1SDimitry Andric } 2080*fe6060f1SDimitry Andric else 2081*fe6060f1SDimitry Andric { 2082*fe6060f1SDimitry Andric typedef typename __rebind_alloc_helper<__alloc_traits, _FF>::type _Ap; 2083*fe6060f1SDimitry Andric _Ap __a(__a0); 2084*fe6060f1SDimitry Andric typedef __allocator_destructor<_Ap> _Dp; 2085*fe6060f1SDimitry Andric unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1)); 2086*fe6060f1SDimitry Andric ::new ((void*)__hold.get()) _FF(__f, _Alloc(__a)); 2087*fe6060f1SDimitry Andric __f_ = __hold.release(); 2088*fe6060f1SDimitry Andric } 2089*fe6060f1SDimitry Andric } 2090*fe6060f1SDimitry Andric } 2091*fe6060f1SDimitry Andric 2092*fe6060f1SDimitry Andric template<class _Rp, class _A0> 2093*fe6060f1SDimitry Andric function<_Rp(_A0)>& 2094*fe6060f1SDimitry Andric function<_Rp(_A0)>::operator=(const function& __f) 2095*fe6060f1SDimitry Andric { 2096*fe6060f1SDimitry Andric if (__f) 2097*fe6060f1SDimitry Andric function(__f).swap(*this); 2098*fe6060f1SDimitry Andric else 2099*fe6060f1SDimitry Andric *this = nullptr; 2100*fe6060f1SDimitry Andric return *this; 2101*fe6060f1SDimitry Andric } 2102*fe6060f1SDimitry Andric 2103*fe6060f1SDimitry Andric template<class _Rp, class _A0> 2104*fe6060f1SDimitry Andric function<_Rp(_A0)>& 2105*fe6060f1SDimitry Andric function<_Rp(_A0)>::operator=(nullptr_t) 2106*fe6060f1SDimitry Andric { 2107*fe6060f1SDimitry Andric __base* __t = __f_; 2108*fe6060f1SDimitry Andric __f_ = 0; 2109*fe6060f1SDimitry Andric if (__t == (__base*)&__buf_) 2110*fe6060f1SDimitry Andric __t->destroy(); 2111*fe6060f1SDimitry Andric else if (__t) 2112*fe6060f1SDimitry Andric __t->destroy_deallocate(); 2113*fe6060f1SDimitry Andric return *this; 2114*fe6060f1SDimitry Andric } 2115*fe6060f1SDimitry Andric 2116*fe6060f1SDimitry Andric template<class _Rp, class _A0> 2117*fe6060f1SDimitry Andric template <class _Fp> 2118*fe6060f1SDimitry Andric typename enable_if 2119*fe6060f1SDimitry Andric < 2120*fe6060f1SDimitry Andric !is_integral<_Fp>::value, 2121*fe6060f1SDimitry Andric function<_Rp(_A0)>& 2122*fe6060f1SDimitry Andric >::type 2123*fe6060f1SDimitry Andric function<_Rp(_A0)>::operator=(_Fp __f) 2124*fe6060f1SDimitry Andric { 2125*fe6060f1SDimitry Andric function(_VSTD::move(__f)).swap(*this); 2126*fe6060f1SDimitry Andric return *this; 2127*fe6060f1SDimitry Andric } 2128*fe6060f1SDimitry Andric 2129*fe6060f1SDimitry Andric template<class _Rp, class _A0> 2130*fe6060f1SDimitry Andric function<_Rp(_A0)>::~function() 2131*fe6060f1SDimitry Andric { 2132*fe6060f1SDimitry Andric if (__f_ == (__base*)&__buf_) 2133*fe6060f1SDimitry Andric __f_->destroy(); 2134*fe6060f1SDimitry Andric else if (__f_) 2135*fe6060f1SDimitry Andric __f_->destroy_deallocate(); 2136*fe6060f1SDimitry Andric } 2137*fe6060f1SDimitry Andric 2138*fe6060f1SDimitry Andric template<class _Rp, class _A0> 2139*fe6060f1SDimitry Andric void 2140*fe6060f1SDimitry Andric function<_Rp(_A0)>::swap(function& __f) 2141*fe6060f1SDimitry Andric { 2142*fe6060f1SDimitry Andric if (_VSTD::addressof(__f) == this) 2143*fe6060f1SDimitry Andric return; 2144*fe6060f1SDimitry Andric if (__f_ == (__base*)&__buf_ && __f.__f_ == (__base*)&__f.__buf_) 2145*fe6060f1SDimitry Andric { 2146*fe6060f1SDimitry Andric typename aligned_storage<sizeof(__buf_)>::type __tempbuf; 2147*fe6060f1SDimitry Andric __base* __t = (__base*)&__tempbuf; 2148*fe6060f1SDimitry Andric __f_->__clone(__t); 2149*fe6060f1SDimitry Andric __f_->destroy(); 2150*fe6060f1SDimitry Andric __f_ = 0; 2151*fe6060f1SDimitry Andric __f.__f_->__clone((__base*)&__buf_); 2152*fe6060f1SDimitry Andric __f.__f_->destroy(); 2153*fe6060f1SDimitry Andric __f.__f_ = 0; 2154*fe6060f1SDimitry Andric __f_ = (__base*)&__buf_; 2155*fe6060f1SDimitry Andric __t->__clone((__base*)&__f.__buf_); 2156*fe6060f1SDimitry Andric __t->destroy(); 2157*fe6060f1SDimitry Andric __f.__f_ = (__base*)&__f.__buf_; 2158*fe6060f1SDimitry Andric } 2159*fe6060f1SDimitry Andric else if (__f_ == (__base*)&__buf_) 2160*fe6060f1SDimitry Andric { 2161*fe6060f1SDimitry Andric __f_->__clone((__base*)&__f.__buf_); 2162*fe6060f1SDimitry Andric __f_->destroy(); 2163*fe6060f1SDimitry Andric __f_ = __f.__f_; 2164*fe6060f1SDimitry Andric __f.__f_ = (__base*)&__f.__buf_; 2165*fe6060f1SDimitry Andric } 2166*fe6060f1SDimitry Andric else if (__f.__f_ == (__base*)&__f.__buf_) 2167*fe6060f1SDimitry Andric { 2168*fe6060f1SDimitry Andric __f.__f_->__clone((__base*)&__buf_); 2169*fe6060f1SDimitry Andric __f.__f_->destroy(); 2170*fe6060f1SDimitry Andric __f.__f_ = __f_; 2171*fe6060f1SDimitry Andric __f_ = (__base*)&__buf_; 2172*fe6060f1SDimitry Andric } 2173*fe6060f1SDimitry Andric else 2174*fe6060f1SDimitry Andric _VSTD::swap(__f_, __f.__f_); 2175*fe6060f1SDimitry Andric } 2176*fe6060f1SDimitry Andric 2177*fe6060f1SDimitry Andric template<class _Rp, class _A0> 2178*fe6060f1SDimitry Andric _Rp 2179*fe6060f1SDimitry Andric function<_Rp(_A0)>::operator()(_A0 __a0) const 2180*fe6060f1SDimitry Andric { 2181*fe6060f1SDimitry Andric if (__f_ == 0) 2182*fe6060f1SDimitry Andric __throw_bad_function_call(); 2183*fe6060f1SDimitry Andric return (*__f_)(__a0); 2184*fe6060f1SDimitry Andric } 2185*fe6060f1SDimitry Andric 2186*fe6060f1SDimitry Andric #ifndef _LIBCPP_NO_RTTI 2187*fe6060f1SDimitry Andric 2188*fe6060f1SDimitry Andric template<class _Rp, class _A0> 2189*fe6060f1SDimitry Andric const std::type_info& 2190*fe6060f1SDimitry Andric function<_Rp(_A0)>::target_type() const 2191*fe6060f1SDimitry Andric { 2192*fe6060f1SDimitry Andric if (__f_ == 0) 2193*fe6060f1SDimitry Andric return typeid(void); 2194*fe6060f1SDimitry Andric return __f_->target_type(); 2195*fe6060f1SDimitry Andric } 2196*fe6060f1SDimitry Andric 2197*fe6060f1SDimitry Andric template<class _Rp, class _A0> 2198*fe6060f1SDimitry Andric template <typename _Tp> 2199*fe6060f1SDimitry Andric _Tp* 2200*fe6060f1SDimitry Andric function<_Rp(_A0)>::target() 2201*fe6060f1SDimitry Andric { 2202*fe6060f1SDimitry Andric if (__f_ == 0) 2203*fe6060f1SDimitry Andric return (_Tp*)0; 2204*fe6060f1SDimitry Andric return (_Tp*) const_cast<void *>(__f_->target(typeid(_Tp))); 2205*fe6060f1SDimitry Andric } 2206*fe6060f1SDimitry Andric 2207*fe6060f1SDimitry Andric template<class _Rp, class _A0> 2208*fe6060f1SDimitry Andric template <typename _Tp> 2209*fe6060f1SDimitry Andric const _Tp* 2210*fe6060f1SDimitry Andric function<_Rp(_A0)>::target() const 2211*fe6060f1SDimitry Andric { 2212*fe6060f1SDimitry Andric if (__f_ == 0) 2213*fe6060f1SDimitry Andric return (const _Tp*)0; 2214*fe6060f1SDimitry Andric return (const _Tp*)__f_->target(typeid(_Tp)); 2215*fe6060f1SDimitry Andric } 2216*fe6060f1SDimitry Andric 2217*fe6060f1SDimitry Andric #endif // _LIBCPP_NO_RTTI 2218*fe6060f1SDimitry Andric 2219*fe6060f1SDimitry Andric template<class _Rp, class _A0, class _A1> 2220*fe6060f1SDimitry Andric class _LIBCPP_TEMPLATE_VIS function<_Rp(_A0, _A1)> 2221*fe6060f1SDimitry Andric : public binary_function<_A0, _A1, _Rp> 2222*fe6060f1SDimitry Andric { 2223*fe6060f1SDimitry Andric typedef __function::__base<_Rp(_A0, _A1)> __base; 2224*fe6060f1SDimitry Andric aligned_storage<3*sizeof(void*)>::type __buf_; 2225*fe6060f1SDimitry Andric __base* __f_; 2226*fe6060f1SDimitry Andric 2227*fe6060f1SDimitry Andric public: 2228*fe6060f1SDimitry Andric typedef _Rp result_type; 2229*fe6060f1SDimitry Andric 2230*fe6060f1SDimitry Andric // 20.7.16.2.1, construct/copy/destroy: 2231*fe6060f1SDimitry Andric _LIBCPP_INLINE_VISIBILITY explicit function() : __f_(0) {} 2232*fe6060f1SDimitry Andric _LIBCPP_INLINE_VISIBILITY function(nullptr_t) : __f_(0) {} 2233*fe6060f1SDimitry Andric function(const function&); 2234*fe6060f1SDimitry Andric template<class _Fp> 2235*fe6060f1SDimitry Andric function(_Fp, 2236*fe6060f1SDimitry Andric typename enable_if<!is_integral<_Fp>::value>::type* = 0); 2237*fe6060f1SDimitry Andric 2238*fe6060f1SDimitry Andric template<class _Alloc> 2239*fe6060f1SDimitry Andric _LIBCPP_INLINE_VISIBILITY 2240*fe6060f1SDimitry Andric function(allocator_arg_t, const _Alloc&) : __f_(0) {} 2241*fe6060f1SDimitry Andric template<class _Alloc> 2242*fe6060f1SDimitry Andric _LIBCPP_INLINE_VISIBILITY 2243*fe6060f1SDimitry Andric function(allocator_arg_t, const _Alloc&, nullptr_t) : __f_(0) {} 2244*fe6060f1SDimitry Andric template<class _Alloc> 2245*fe6060f1SDimitry Andric function(allocator_arg_t, const _Alloc&, const function&); 2246*fe6060f1SDimitry Andric template<class _Fp, class _Alloc> 2247*fe6060f1SDimitry Andric function(allocator_arg_t, const _Alloc& __a, _Fp __f, 2248*fe6060f1SDimitry Andric typename enable_if<!is_integral<_Fp>::value>::type* = 0); 2249*fe6060f1SDimitry Andric 2250*fe6060f1SDimitry Andric function& operator=(const function&); 2251*fe6060f1SDimitry Andric function& operator=(nullptr_t); 2252*fe6060f1SDimitry Andric template<class _Fp> 2253*fe6060f1SDimitry Andric typename enable_if 2254*fe6060f1SDimitry Andric < 2255*fe6060f1SDimitry Andric !is_integral<_Fp>::value, 2256*fe6060f1SDimitry Andric function& 2257*fe6060f1SDimitry Andric >::type 2258*fe6060f1SDimitry Andric operator=(_Fp); 2259*fe6060f1SDimitry Andric 2260*fe6060f1SDimitry Andric ~function(); 2261*fe6060f1SDimitry Andric 2262*fe6060f1SDimitry Andric // 20.7.16.2.2, function modifiers: 2263*fe6060f1SDimitry Andric void swap(function&); 2264*fe6060f1SDimitry Andric template<class _Fp, class _Alloc> 2265*fe6060f1SDimitry Andric _LIBCPP_INLINE_VISIBILITY 2266*fe6060f1SDimitry Andric void assign(_Fp __f, const _Alloc& __a) 2267*fe6060f1SDimitry Andric {function(allocator_arg, __a, __f).swap(*this);} 2268*fe6060f1SDimitry Andric 2269*fe6060f1SDimitry Andric // 20.7.16.2.3, function capacity: 2270*fe6060f1SDimitry Andric _LIBCPP_INLINE_VISIBILITY explicit operator bool() const {return __f_;} 2271*fe6060f1SDimitry Andric 2272*fe6060f1SDimitry Andric private: 2273*fe6060f1SDimitry Andric // deleted overloads close possible hole in the type system 2274*fe6060f1SDimitry Andric template<class _R2, class _B0, class _B1> 2275*fe6060f1SDimitry Andric bool operator==(const function<_R2(_B0, _B1)>&) const;// = delete; 2276*fe6060f1SDimitry Andric template<class _R2, class _B0, class _B1> 2277*fe6060f1SDimitry Andric bool operator!=(const function<_R2(_B0, _B1)>&) const;// = delete; 2278*fe6060f1SDimitry Andric public: 2279*fe6060f1SDimitry Andric // 20.7.16.2.4, function invocation: 2280*fe6060f1SDimitry Andric _Rp operator()(_A0, _A1) const; 2281*fe6060f1SDimitry Andric 2282*fe6060f1SDimitry Andric #ifndef _LIBCPP_NO_RTTI 2283*fe6060f1SDimitry Andric // 20.7.16.2.5, function target access: 2284*fe6060f1SDimitry Andric const std::type_info& target_type() const; 2285*fe6060f1SDimitry Andric template <typename _Tp> _Tp* target(); 2286*fe6060f1SDimitry Andric template <typename _Tp> const _Tp* target() const; 2287*fe6060f1SDimitry Andric #endif // _LIBCPP_NO_RTTI 2288*fe6060f1SDimitry Andric }; 2289*fe6060f1SDimitry Andric 2290*fe6060f1SDimitry Andric template<class _Rp, class _A0, class _A1> 2291*fe6060f1SDimitry Andric function<_Rp(_A0, _A1)>::function(const function& __f) 2292*fe6060f1SDimitry Andric { 2293*fe6060f1SDimitry Andric if (__f.__f_ == 0) 2294*fe6060f1SDimitry Andric __f_ = 0; 2295*fe6060f1SDimitry Andric else if (__f.__f_ == (const __base*)&__f.__buf_) 2296*fe6060f1SDimitry Andric { 2297*fe6060f1SDimitry Andric __f_ = (__base*)&__buf_; 2298*fe6060f1SDimitry Andric __f.__f_->__clone(__f_); 2299*fe6060f1SDimitry Andric } 2300*fe6060f1SDimitry Andric else 2301*fe6060f1SDimitry Andric __f_ = __f.__f_->__clone(); 2302*fe6060f1SDimitry Andric } 2303*fe6060f1SDimitry Andric 2304*fe6060f1SDimitry Andric template<class _Rp, class _A0, class _A1> 2305*fe6060f1SDimitry Andric template<class _Alloc> 2306*fe6060f1SDimitry Andric function<_Rp(_A0, _A1)>::function(allocator_arg_t, const _Alloc&, const function& __f) 2307*fe6060f1SDimitry Andric { 2308*fe6060f1SDimitry Andric if (__f.__f_ == 0) 2309*fe6060f1SDimitry Andric __f_ = 0; 2310*fe6060f1SDimitry Andric else if (__f.__f_ == (const __base*)&__f.__buf_) 2311*fe6060f1SDimitry Andric { 2312*fe6060f1SDimitry Andric __f_ = (__base*)&__buf_; 2313*fe6060f1SDimitry Andric __f.__f_->__clone(__f_); 2314*fe6060f1SDimitry Andric } 2315*fe6060f1SDimitry Andric else 2316*fe6060f1SDimitry Andric __f_ = __f.__f_->__clone(); 2317*fe6060f1SDimitry Andric } 2318*fe6060f1SDimitry Andric 2319*fe6060f1SDimitry Andric template<class _Rp, class _A0, class _A1> 2320*fe6060f1SDimitry Andric template <class _Fp> 2321*fe6060f1SDimitry Andric function<_Rp(_A0, _A1)>::function(_Fp __f, 2322*fe6060f1SDimitry Andric typename enable_if<!is_integral<_Fp>::value>::type*) 2323*fe6060f1SDimitry Andric : __f_(0) 2324*fe6060f1SDimitry Andric { 2325*fe6060f1SDimitry Andric if (__function::__not_null(__f)) 2326*fe6060f1SDimitry Andric { 2327*fe6060f1SDimitry Andric typedef __function::__func<_Fp, allocator<_Fp>, _Rp(_A0, _A1)> _FF; 2328*fe6060f1SDimitry Andric if (sizeof(_FF) <= sizeof(__buf_)) 2329*fe6060f1SDimitry Andric { 2330*fe6060f1SDimitry Andric __f_ = (__base*)&__buf_; 2331*fe6060f1SDimitry Andric ::new ((void*)__f_) _FF(__f); 2332*fe6060f1SDimitry Andric } 2333*fe6060f1SDimitry Andric else 2334*fe6060f1SDimitry Andric { 2335*fe6060f1SDimitry Andric typedef allocator<_FF> _Ap; 2336*fe6060f1SDimitry Andric _Ap __a; 2337*fe6060f1SDimitry Andric typedef __allocator_destructor<_Ap> _Dp; 2338*fe6060f1SDimitry Andric unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1)); 2339*fe6060f1SDimitry Andric ::new ((void*)__hold.get()) _FF(__f, allocator<_Fp>(__a)); 2340*fe6060f1SDimitry Andric __f_ = __hold.release(); 2341*fe6060f1SDimitry Andric } 2342*fe6060f1SDimitry Andric } 2343*fe6060f1SDimitry Andric } 2344*fe6060f1SDimitry Andric 2345*fe6060f1SDimitry Andric template<class _Rp, class _A0, class _A1> 2346*fe6060f1SDimitry Andric template <class _Fp, class _Alloc> 2347*fe6060f1SDimitry Andric function<_Rp(_A0, _A1)>::function(allocator_arg_t, const _Alloc& __a0, _Fp __f, 2348*fe6060f1SDimitry Andric typename enable_if<!is_integral<_Fp>::value>::type*) 2349*fe6060f1SDimitry Andric : __f_(0) 2350*fe6060f1SDimitry Andric { 2351*fe6060f1SDimitry Andric typedef allocator_traits<_Alloc> __alloc_traits; 2352*fe6060f1SDimitry Andric if (__function::__not_null(__f)) 2353*fe6060f1SDimitry Andric { 2354*fe6060f1SDimitry Andric typedef __function::__func<_Fp, _Alloc, _Rp(_A0, _A1)> _FF; 2355*fe6060f1SDimitry Andric if (sizeof(_FF) <= sizeof(__buf_)) 2356*fe6060f1SDimitry Andric { 2357*fe6060f1SDimitry Andric __f_ = (__base*)&__buf_; 2358*fe6060f1SDimitry Andric ::new ((void*)__f_) _FF(__f, __a0); 2359*fe6060f1SDimitry Andric } 2360*fe6060f1SDimitry Andric else 2361*fe6060f1SDimitry Andric { 2362*fe6060f1SDimitry Andric typedef typename __rebind_alloc_helper<__alloc_traits, _FF>::type _Ap; 2363*fe6060f1SDimitry Andric _Ap __a(__a0); 2364*fe6060f1SDimitry Andric typedef __allocator_destructor<_Ap> _Dp; 2365*fe6060f1SDimitry Andric unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1)); 2366*fe6060f1SDimitry Andric ::new ((void*)__hold.get()) _FF(__f, _Alloc(__a)); 2367*fe6060f1SDimitry Andric __f_ = __hold.release(); 2368*fe6060f1SDimitry Andric } 2369*fe6060f1SDimitry Andric } 2370*fe6060f1SDimitry Andric } 2371*fe6060f1SDimitry Andric 2372*fe6060f1SDimitry Andric template<class _Rp, class _A0, class _A1> 2373*fe6060f1SDimitry Andric function<_Rp(_A0, _A1)>& 2374*fe6060f1SDimitry Andric function<_Rp(_A0, _A1)>::operator=(const function& __f) 2375*fe6060f1SDimitry Andric { 2376*fe6060f1SDimitry Andric if (__f) 2377*fe6060f1SDimitry Andric function(__f).swap(*this); 2378*fe6060f1SDimitry Andric else 2379*fe6060f1SDimitry Andric *this = nullptr; 2380*fe6060f1SDimitry Andric return *this; 2381*fe6060f1SDimitry Andric } 2382*fe6060f1SDimitry Andric 2383*fe6060f1SDimitry Andric template<class _Rp, class _A0, class _A1> 2384*fe6060f1SDimitry Andric function<_Rp(_A0, _A1)>& 2385*fe6060f1SDimitry Andric function<_Rp(_A0, _A1)>::operator=(nullptr_t) 2386*fe6060f1SDimitry Andric { 2387*fe6060f1SDimitry Andric __base* __t = __f_; 2388*fe6060f1SDimitry Andric __f_ = 0; 2389*fe6060f1SDimitry Andric if (__t == (__base*)&__buf_) 2390*fe6060f1SDimitry Andric __t->destroy(); 2391*fe6060f1SDimitry Andric else if (__t) 2392*fe6060f1SDimitry Andric __t->destroy_deallocate(); 2393*fe6060f1SDimitry Andric return *this; 2394*fe6060f1SDimitry Andric } 2395*fe6060f1SDimitry Andric 2396*fe6060f1SDimitry Andric template<class _Rp, class _A0, class _A1> 2397*fe6060f1SDimitry Andric template <class _Fp> 2398*fe6060f1SDimitry Andric typename enable_if 2399*fe6060f1SDimitry Andric < 2400*fe6060f1SDimitry Andric !is_integral<_Fp>::value, 2401*fe6060f1SDimitry Andric function<_Rp(_A0, _A1)>& 2402*fe6060f1SDimitry Andric >::type 2403*fe6060f1SDimitry Andric function<_Rp(_A0, _A1)>::operator=(_Fp __f) 2404*fe6060f1SDimitry Andric { 2405*fe6060f1SDimitry Andric function(_VSTD::move(__f)).swap(*this); 2406*fe6060f1SDimitry Andric return *this; 2407*fe6060f1SDimitry Andric } 2408*fe6060f1SDimitry Andric 2409*fe6060f1SDimitry Andric template<class _Rp, class _A0, class _A1> 2410*fe6060f1SDimitry Andric function<_Rp(_A0, _A1)>::~function() 2411*fe6060f1SDimitry Andric { 2412*fe6060f1SDimitry Andric if (__f_ == (__base*)&__buf_) 2413*fe6060f1SDimitry Andric __f_->destroy(); 2414*fe6060f1SDimitry Andric else if (__f_) 2415*fe6060f1SDimitry Andric __f_->destroy_deallocate(); 2416*fe6060f1SDimitry Andric } 2417*fe6060f1SDimitry Andric 2418*fe6060f1SDimitry Andric template<class _Rp, class _A0, class _A1> 2419*fe6060f1SDimitry Andric void 2420*fe6060f1SDimitry Andric function<_Rp(_A0, _A1)>::swap(function& __f) 2421*fe6060f1SDimitry Andric { 2422*fe6060f1SDimitry Andric if (_VSTD::addressof(__f) == this) 2423*fe6060f1SDimitry Andric return; 2424*fe6060f1SDimitry Andric if (__f_ == (__base*)&__buf_ && __f.__f_ == (__base*)&__f.__buf_) 2425*fe6060f1SDimitry Andric { 2426*fe6060f1SDimitry Andric typename aligned_storage<sizeof(__buf_)>::type __tempbuf; 2427*fe6060f1SDimitry Andric __base* __t = (__base*)&__tempbuf; 2428*fe6060f1SDimitry Andric __f_->__clone(__t); 2429*fe6060f1SDimitry Andric __f_->destroy(); 2430*fe6060f1SDimitry Andric __f_ = 0; 2431*fe6060f1SDimitry Andric __f.__f_->__clone((__base*)&__buf_); 2432*fe6060f1SDimitry Andric __f.__f_->destroy(); 2433*fe6060f1SDimitry Andric __f.__f_ = 0; 2434*fe6060f1SDimitry Andric __f_ = (__base*)&__buf_; 2435*fe6060f1SDimitry Andric __t->__clone((__base*)&__f.__buf_); 2436*fe6060f1SDimitry Andric __t->destroy(); 2437*fe6060f1SDimitry Andric __f.__f_ = (__base*)&__f.__buf_; 2438*fe6060f1SDimitry Andric } 2439*fe6060f1SDimitry Andric else if (__f_ == (__base*)&__buf_) 2440*fe6060f1SDimitry Andric { 2441*fe6060f1SDimitry Andric __f_->__clone((__base*)&__f.__buf_); 2442*fe6060f1SDimitry Andric __f_->destroy(); 2443*fe6060f1SDimitry Andric __f_ = __f.__f_; 2444*fe6060f1SDimitry Andric __f.__f_ = (__base*)&__f.__buf_; 2445*fe6060f1SDimitry Andric } 2446*fe6060f1SDimitry Andric else if (__f.__f_ == (__base*)&__f.__buf_) 2447*fe6060f1SDimitry Andric { 2448*fe6060f1SDimitry Andric __f.__f_->__clone((__base*)&__buf_); 2449*fe6060f1SDimitry Andric __f.__f_->destroy(); 2450*fe6060f1SDimitry Andric __f.__f_ = __f_; 2451*fe6060f1SDimitry Andric __f_ = (__base*)&__buf_; 2452*fe6060f1SDimitry Andric } 2453*fe6060f1SDimitry Andric else 2454*fe6060f1SDimitry Andric _VSTD::swap(__f_, __f.__f_); 2455*fe6060f1SDimitry Andric } 2456*fe6060f1SDimitry Andric 2457*fe6060f1SDimitry Andric template<class _Rp, class _A0, class _A1> 2458*fe6060f1SDimitry Andric _Rp 2459*fe6060f1SDimitry Andric function<_Rp(_A0, _A1)>::operator()(_A0 __a0, _A1 __a1) const 2460*fe6060f1SDimitry Andric { 2461*fe6060f1SDimitry Andric if (__f_ == 0) 2462*fe6060f1SDimitry Andric __throw_bad_function_call(); 2463*fe6060f1SDimitry Andric return (*__f_)(__a0, __a1); 2464*fe6060f1SDimitry Andric } 2465*fe6060f1SDimitry Andric 2466*fe6060f1SDimitry Andric #ifndef _LIBCPP_NO_RTTI 2467*fe6060f1SDimitry Andric 2468*fe6060f1SDimitry Andric template<class _Rp, class _A0, class _A1> 2469*fe6060f1SDimitry Andric const std::type_info& 2470*fe6060f1SDimitry Andric function<_Rp(_A0, _A1)>::target_type() const 2471*fe6060f1SDimitry Andric { 2472*fe6060f1SDimitry Andric if (__f_ == 0) 2473*fe6060f1SDimitry Andric return typeid(void); 2474*fe6060f1SDimitry Andric return __f_->target_type(); 2475*fe6060f1SDimitry Andric } 2476*fe6060f1SDimitry Andric 2477*fe6060f1SDimitry Andric template<class _Rp, class _A0, class _A1> 2478*fe6060f1SDimitry Andric template <typename _Tp> 2479*fe6060f1SDimitry Andric _Tp* 2480*fe6060f1SDimitry Andric function<_Rp(_A0, _A1)>::target() 2481*fe6060f1SDimitry Andric { 2482*fe6060f1SDimitry Andric if (__f_ == 0) 2483*fe6060f1SDimitry Andric return (_Tp*)0; 2484*fe6060f1SDimitry Andric return (_Tp*) const_cast<void *>(__f_->target(typeid(_Tp))); 2485*fe6060f1SDimitry Andric } 2486*fe6060f1SDimitry Andric 2487*fe6060f1SDimitry Andric template<class _Rp, class _A0, class _A1> 2488*fe6060f1SDimitry Andric template <typename _Tp> 2489*fe6060f1SDimitry Andric const _Tp* 2490*fe6060f1SDimitry Andric function<_Rp(_A0, _A1)>::target() const 2491*fe6060f1SDimitry Andric { 2492*fe6060f1SDimitry Andric if (__f_ == 0) 2493*fe6060f1SDimitry Andric return (const _Tp*)0; 2494*fe6060f1SDimitry Andric return (const _Tp*)__f_->target(typeid(_Tp)); 2495*fe6060f1SDimitry Andric } 2496*fe6060f1SDimitry Andric 2497*fe6060f1SDimitry Andric #endif // _LIBCPP_NO_RTTI 2498*fe6060f1SDimitry Andric 2499*fe6060f1SDimitry Andric template<class _Rp, class _A0, class _A1, class _A2> 2500*fe6060f1SDimitry Andric class _LIBCPP_TEMPLATE_VIS function<_Rp(_A0, _A1, _A2)> 2501*fe6060f1SDimitry Andric { 2502*fe6060f1SDimitry Andric typedef __function::__base<_Rp(_A0, _A1, _A2)> __base; 2503*fe6060f1SDimitry Andric aligned_storage<3*sizeof(void*)>::type __buf_; 2504*fe6060f1SDimitry Andric __base* __f_; 2505*fe6060f1SDimitry Andric 2506*fe6060f1SDimitry Andric public: 2507*fe6060f1SDimitry Andric typedef _Rp result_type; 2508*fe6060f1SDimitry Andric 2509*fe6060f1SDimitry Andric // 20.7.16.2.1, construct/copy/destroy: 2510*fe6060f1SDimitry Andric _LIBCPP_INLINE_VISIBILITY explicit function() : __f_(0) {} 2511*fe6060f1SDimitry Andric _LIBCPP_INLINE_VISIBILITY function(nullptr_t) : __f_(0) {} 2512*fe6060f1SDimitry Andric function(const function&); 2513*fe6060f1SDimitry Andric template<class _Fp> 2514*fe6060f1SDimitry Andric function(_Fp, 2515*fe6060f1SDimitry Andric typename enable_if<!is_integral<_Fp>::value>::type* = 0); 2516*fe6060f1SDimitry Andric 2517*fe6060f1SDimitry Andric template<class _Alloc> 2518*fe6060f1SDimitry Andric _LIBCPP_INLINE_VISIBILITY 2519*fe6060f1SDimitry Andric function(allocator_arg_t, const _Alloc&) : __f_(0) {} 2520*fe6060f1SDimitry Andric template<class _Alloc> 2521*fe6060f1SDimitry Andric _LIBCPP_INLINE_VISIBILITY 2522*fe6060f1SDimitry Andric function(allocator_arg_t, const _Alloc&, nullptr_t) : __f_(0) {} 2523*fe6060f1SDimitry Andric template<class _Alloc> 2524*fe6060f1SDimitry Andric function(allocator_arg_t, const _Alloc&, const function&); 2525*fe6060f1SDimitry Andric template<class _Fp, class _Alloc> 2526*fe6060f1SDimitry Andric function(allocator_arg_t, const _Alloc& __a, _Fp __f, 2527*fe6060f1SDimitry Andric typename enable_if<!is_integral<_Fp>::value>::type* = 0); 2528*fe6060f1SDimitry Andric 2529*fe6060f1SDimitry Andric function& operator=(const function&); 2530*fe6060f1SDimitry Andric function& operator=(nullptr_t); 2531*fe6060f1SDimitry Andric template<class _Fp> 2532*fe6060f1SDimitry Andric typename enable_if 2533*fe6060f1SDimitry Andric < 2534*fe6060f1SDimitry Andric !is_integral<_Fp>::value, 2535*fe6060f1SDimitry Andric function& 2536*fe6060f1SDimitry Andric >::type 2537*fe6060f1SDimitry Andric operator=(_Fp); 2538*fe6060f1SDimitry Andric 2539*fe6060f1SDimitry Andric ~function(); 2540*fe6060f1SDimitry Andric 2541*fe6060f1SDimitry Andric // 20.7.16.2.2, function modifiers: 2542*fe6060f1SDimitry Andric void swap(function&); 2543*fe6060f1SDimitry Andric template<class _Fp, class _Alloc> 2544*fe6060f1SDimitry Andric _LIBCPP_INLINE_VISIBILITY 2545*fe6060f1SDimitry Andric void assign(_Fp __f, const _Alloc& __a) 2546*fe6060f1SDimitry Andric {function(allocator_arg, __a, __f).swap(*this);} 2547*fe6060f1SDimitry Andric 2548*fe6060f1SDimitry Andric // 20.7.16.2.3, function capacity: 2549*fe6060f1SDimitry Andric _LIBCPP_INLINE_VISIBILITY explicit operator bool() const {return __f_;} 2550*fe6060f1SDimitry Andric 2551*fe6060f1SDimitry Andric private: 2552*fe6060f1SDimitry Andric // deleted overloads close possible hole in the type system 2553*fe6060f1SDimitry Andric template<class _R2, class _B0, class _B1, class _B2> 2554*fe6060f1SDimitry Andric bool operator==(const function<_R2(_B0, _B1, _B2)>&) const;// = delete; 2555*fe6060f1SDimitry Andric template<class _R2, class _B0, class _B1, class _B2> 2556*fe6060f1SDimitry Andric bool operator!=(const function<_R2(_B0, _B1, _B2)>&) const;// = delete; 2557*fe6060f1SDimitry Andric public: 2558*fe6060f1SDimitry Andric // 20.7.16.2.4, function invocation: 2559*fe6060f1SDimitry Andric _Rp operator()(_A0, _A1, _A2) const; 2560*fe6060f1SDimitry Andric 2561*fe6060f1SDimitry Andric #ifndef _LIBCPP_NO_RTTI 2562*fe6060f1SDimitry Andric // 20.7.16.2.5, function target access: 2563*fe6060f1SDimitry Andric const std::type_info& target_type() const; 2564*fe6060f1SDimitry Andric template <typename _Tp> _Tp* target(); 2565*fe6060f1SDimitry Andric template <typename _Tp> const _Tp* target() const; 2566*fe6060f1SDimitry Andric #endif // _LIBCPP_NO_RTTI 2567*fe6060f1SDimitry Andric }; 2568*fe6060f1SDimitry Andric 2569*fe6060f1SDimitry Andric template<class _Rp, class _A0, class _A1, class _A2> 2570*fe6060f1SDimitry Andric function<_Rp(_A0, _A1, _A2)>::function(const function& __f) 2571*fe6060f1SDimitry Andric { 2572*fe6060f1SDimitry Andric if (__f.__f_ == 0) 2573*fe6060f1SDimitry Andric __f_ = 0; 2574*fe6060f1SDimitry Andric else if (__f.__f_ == (const __base*)&__f.__buf_) 2575*fe6060f1SDimitry Andric { 2576*fe6060f1SDimitry Andric __f_ = (__base*)&__buf_; 2577*fe6060f1SDimitry Andric __f.__f_->__clone(__f_); 2578*fe6060f1SDimitry Andric } 2579*fe6060f1SDimitry Andric else 2580*fe6060f1SDimitry Andric __f_ = __f.__f_->__clone(); 2581*fe6060f1SDimitry Andric } 2582*fe6060f1SDimitry Andric 2583*fe6060f1SDimitry Andric template<class _Rp, class _A0, class _A1, class _A2> 2584*fe6060f1SDimitry Andric template<class _Alloc> 2585*fe6060f1SDimitry Andric function<_Rp(_A0, _A1, _A2)>::function(allocator_arg_t, const _Alloc&, 2586*fe6060f1SDimitry Andric const function& __f) 2587*fe6060f1SDimitry Andric { 2588*fe6060f1SDimitry Andric if (__f.__f_ == 0) 2589*fe6060f1SDimitry Andric __f_ = 0; 2590*fe6060f1SDimitry Andric else if (__f.__f_ == (const __base*)&__f.__buf_) 2591*fe6060f1SDimitry Andric { 2592*fe6060f1SDimitry Andric __f_ = (__base*)&__buf_; 2593*fe6060f1SDimitry Andric __f.__f_->__clone(__f_); 2594*fe6060f1SDimitry Andric } 2595*fe6060f1SDimitry Andric else 2596*fe6060f1SDimitry Andric __f_ = __f.__f_->__clone(); 2597*fe6060f1SDimitry Andric } 2598*fe6060f1SDimitry Andric 2599*fe6060f1SDimitry Andric template<class _Rp, class _A0, class _A1, class _A2> 2600*fe6060f1SDimitry Andric template <class _Fp> 2601*fe6060f1SDimitry Andric function<_Rp(_A0, _A1, _A2)>::function(_Fp __f, 2602*fe6060f1SDimitry Andric typename enable_if<!is_integral<_Fp>::value>::type*) 2603*fe6060f1SDimitry Andric : __f_(0) 2604*fe6060f1SDimitry Andric { 2605*fe6060f1SDimitry Andric if (__function::__not_null(__f)) 2606*fe6060f1SDimitry Andric { 2607*fe6060f1SDimitry Andric typedef __function::__func<_Fp, allocator<_Fp>, _Rp(_A0, _A1, _A2)> _FF; 2608*fe6060f1SDimitry Andric if (sizeof(_FF) <= sizeof(__buf_)) 2609*fe6060f1SDimitry Andric { 2610*fe6060f1SDimitry Andric __f_ = (__base*)&__buf_; 2611*fe6060f1SDimitry Andric ::new ((void*)__f_) _FF(__f); 2612*fe6060f1SDimitry Andric } 2613*fe6060f1SDimitry Andric else 2614*fe6060f1SDimitry Andric { 2615*fe6060f1SDimitry Andric typedef allocator<_FF> _Ap; 2616*fe6060f1SDimitry Andric _Ap __a; 2617*fe6060f1SDimitry Andric typedef __allocator_destructor<_Ap> _Dp; 2618*fe6060f1SDimitry Andric unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1)); 2619*fe6060f1SDimitry Andric ::new ((void*)__hold.get()) _FF(__f, allocator<_Fp>(__a)); 2620*fe6060f1SDimitry Andric __f_ = __hold.release(); 2621*fe6060f1SDimitry Andric } 2622*fe6060f1SDimitry Andric } 2623*fe6060f1SDimitry Andric } 2624*fe6060f1SDimitry Andric 2625*fe6060f1SDimitry Andric template<class _Rp, class _A0, class _A1, class _A2> 2626*fe6060f1SDimitry Andric template <class _Fp, class _Alloc> 2627*fe6060f1SDimitry Andric function<_Rp(_A0, _A1, _A2)>::function(allocator_arg_t, const _Alloc& __a0, _Fp __f, 2628*fe6060f1SDimitry Andric typename enable_if<!is_integral<_Fp>::value>::type*) 2629*fe6060f1SDimitry Andric : __f_(0) 2630*fe6060f1SDimitry Andric { 2631*fe6060f1SDimitry Andric typedef allocator_traits<_Alloc> __alloc_traits; 2632*fe6060f1SDimitry Andric if (__function::__not_null(__f)) 2633*fe6060f1SDimitry Andric { 2634*fe6060f1SDimitry Andric typedef __function::__func<_Fp, _Alloc, _Rp(_A0, _A1, _A2)> _FF; 2635*fe6060f1SDimitry Andric if (sizeof(_FF) <= sizeof(__buf_)) 2636*fe6060f1SDimitry Andric { 2637*fe6060f1SDimitry Andric __f_ = (__base*)&__buf_; 2638*fe6060f1SDimitry Andric ::new ((void*)__f_) _FF(__f, __a0); 2639*fe6060f1SDimitry Andric } 2640*fe6060f1SDimitry Andric else 2641*fe6060f1SDimitry Andric { 2642*fe6060f1SDimitry Andric typedef typename __rebind_alloc_helper<__alloc_traits, _FF>::type _Ap; 2643*fe6060f1SDimitry Andric _Ap __a(__a0); 2644*fe6060f1SDimitry Andric typedef __allocator_destructor<_Ap> _Dp; 2645*fe6060f1SDimitry Andric unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1)); 2646*fe6060f1SDimitry Andric ::new ((void*)__hold.get()) _FF(__f, _Alloc(__a)); 2647*fe6060f1SDimitry Andric __f_ = __hold.release(); 2648*fe6060f1SDimitry Andric } 2649*fe6060f1SDimitry Andric } 2650*fe6060f1SDimitry Andric } 2651*fe6060f1SDimitry Andric 2652*fe6060f1SDimitry Andric template<class _Rp, class _A0, class _A1, class _A2> 2653*fe6060f1SDimitry Andric function<_Rp(_A0, _A1, _A2)>& 2654*fe6060f1SDimitry Andric function<_Rp(_A0, _A1, _A2)>::operator=(const function& __f) 2655*fe6060f1SDimitry Andric { 2656*fe6060f1SDimitry Andric if (__f) 2657*fe6060f1SDimitry Andric function(__f).swap(*this); 2658*fe6060f1SDimitry Andric else 2659*fe6060f1SDimitry Andric *this = nullptr; 2660*fe6060f1SDimitry Andric return *this; 2661*fe6060f1SDimitry Andric } 2662*fe6060f1SDimitry Andric 2663*fe6060f1SDimitry Andric template<class _Rp, class _A0, class _A1, class _A2> 2664*fe6060f1SDimitry Andric function<_Rp(_A0, _A1, _A2)>& 2665*fe6060f1SDimitry Andric function<_Rp(_A0, _A1, _A2)>::operator=(nullptr_t) 2666*fe6060f1SDimitry Andric { 2667*fe6060f1SDimitry Andric __base* __t = __f_; 2668*fe6060f1SDimitry Andric __f_ = 0; 2669*fe6060f1SDimitry Andric if (__t == (__base*)&__buf_) 2670*fe6060f1SDimitry Andric __t->destroy(); 2671*fe6060f1SDimitry Andric else if (__t) 2672*fe6060f1SDimitry Andric __t->destroy_deallocate(); 2673*fe6060f1SDimitry Andric return *this; 2674*fe6060f1SDimitry Andric } 2675*fe6060f1SDimitry Andric 2676*fe6060f1SDimitry Andric template<class _Rp, class _A0, class _A1, class _A2> 2677*fe6060f1SDimitry Andric template <class _Fp> 2678*fe6060f1SDimitry Andric typename enable_if 2679*fe6060f1SDimitry Andric < 2680*fe6060f1SDimitry Andric !is_integral<_Fp>::value, 2681*fe6060f1SDimitry Andric function<_Rp(_A0, _A1, _A2)>& 2682*fe6060f1SDimitry Andric >::type 2683*fe6060f1SDimitry Andric function<_Rp(_A0, _A1, _A2)>::operator=(_Fp __f) 2684*fe6060f1SDimitry Andric { 2685*fe6060f1SDimitry Andric function(_VSTD::move(__f)).swap(*this); 2686*fe6060f1SDimitry Andric return *this; 2687*fe6060f1SDimitry Andric } 2688*fe6060f1SDimitry Andric 2689*fe6060f1SDimitry Andric template<class _Rp, class _A0, class _A1, class _A2> 2690*fe6060f1SDimitry Andric function<_Rp(_A0, _A1, _A2)>::~function() 2691*fe6060f1SDimitry Andric { 2692*fe6060f1SDimitry Andric if (__f_ == (__base*)&__buf_) 2693*fe6060f1SDimitry Andric __f_->destroy(); 2694*fe6060f1SDimitry Andric else if (__f_) 2695*fe6060f1SDimitry Andric __f_->destroy_deallocate(); 2696*fe6060f1SDimitry Andric } 2697*fe6060f1SDimitry Andric 2698*fe6060f1SDimitry Andric template<class _Rp, class _A0, class _A1, class _A2> 2699*fe6060f1SDimitry Andric void 2700*fe6060f1SDimitry Andric function<_Rp(_A0, _A1, _A2)>::swap(function& __f) 2701*fe6060f1SDimitry Andric { 2702*fe6060f1SDimitry Andric if (_VSTD::addressof(__f) == this) 2703*fe6060f1SDimitry Andric return; 2704*fe6060f1SDimitry Andric if (__f_ == (__base*)&__buf_ && __f.__f_ == (__base*)&__f.__buf_) 2705*fe6060f1SDimitry Andric { 2706*fe6060f1SDimitry Andric typename aligned_storage<sizeof(__buf_)>::type __tempbuf; 2707*fe6060f1SDimitry Andric __base* __t = (__base*)&__tempbuf; 2708*fe6060f1SDimitry Andric __f_->__clone(__t); 2709*fe6060f1SDimitry Andric __f_->destroy(); 2710*fe6060f1SDimitry Andric __f_ = 0; 2711*fe6060f1SDimitry Andric __f.__f_->__clone((__base*)&__buf_); 2712*fe6060f1SDimitry Andric __f.__f_->destroy(); 2713*fe6060f1SDimitry Andric __f.__f_ = 0; 2714*fe6060f1SDimitry Andric __f_ = (__base*)&__buf_; 2715*fe6060f1SDimitry Andric __t->__clone((__base*)&__f.__buf_); 2716*fe6060f1SDimitry Andric __t->destroy(); 2717*fe6060f1SDimitry Andric __f.__f_ = (__base*)&__f.__buf_; 2718*fe6060f1SDimitry Andric } 2719*fe6060f1SDimitry Andric else if (__f_ == (__base*)&__buf_) 2720*fe6060f1SDimitry Andric { 2721*fe6060f1SDimitry Andric __f_->__clone((__base*)&__f.__buf_); 2722*fe6060f1SDimitry Andric __f_->destroy(); 2723*fe6060f1SDimitry Andric __f_ = __f.__f_; 2724*fe6060f1SDimitry Andric __f.__f_ = (__base*)&__f.__buf_; 2725*fe6060f1SDimitry Andric } 2726*fe6060f1SDimitry Andric else if (__f.__f_ == (__base*)&__f.__buf_) 2727*fe6060f1SDimitry Andric { 2728*fe6060f1SDimitry Andric __f.__f_->__clone((__base*)&__buf_); 2729*fe6060f1SDimitry Andric __f.__f_->destroy(); 2730*fe6060f1SDimitry Andric __f.__f_ = __f_; 2731*fe6060f1SDimitry Andric __f_ = (__base*)&__buf_; 2732*fe6060f1SDimitry Andric } 2733*fe6060f1SDimitry Andric else 2734*fe6060f1SDimitry Andric _VSTD::swap(__f_, __f.__f_); 2735*fe6060f1SDimitry Andric } 2736*fe6060f1SDimitry Andric 2737*fe6060f1SDimitry Andric template<class _Rp, class _A0, class _A1, class _A2> 2738*fe6060f1SDimitry Andric _Rp 2739*fe6060f1SDimitry Andric function<_Rp(_A0, _A1, _A2)>::operator()(_A0 __a0, _A1 __a1, _A2 __a2) const 2740*fe6060f1SDimitry Andric { 2741*fe6060f1SDimitry Andric if (__f_ == 0) 2742*fe6060f1SDimitry Andric __throw_bad_function_call(); 2743*fe6060f1SDimitry Andric return (*__f_)(__a0, __a1, __a2); 2744*fe6060f1SDimitry Andric } 2745*fe6060f1SDimitry Andric 2746*fe6060f1SDimitry Andric #ifndef _LIBCPP_NO_RTTI 2747*fe6060f1SDimitry Andric 2748*fe6060f1SDimitry Andric template<class _Rp, class _A0, class _A1, class _A2> 2749*fe6060f1SDimitry Andric const std::type_info& 2750*fe6060f1SDimitry Andric function<_Rp(_A0, _A1, _A2)>::target_type() const 2751*fe6060f1SDimitry Andric { 2752*fe6060f1SDimitry Andric if (__f_ == 0) 2753*fe6060f1SDimitry Andric return typeid(void); 2754*fe6060f1SDimitry Andric return __f_->target_type(); 2755*fe6060f1SDimitry Andric } 2756*fe6060f1SDimitry Andric 2757*fe6060f1SDimitry Andric template<class _Rp, class _A0, class _A1, class _A2> 2758*fe6060f1SDimitry Andric template <typename _Tp> 2759*fe6060f1SDimitry Andric _Tp* 2760*fe6060f1SDimitry Andric function<_Rp(_A0, _A1, _A2)>::target() 2761*fe6060f1SDimitry Andric { 2762*fe6060f1SDimitry Andric if (__f_ == 0) 2763*fe6060f1SDimitry Andric return (_Tp*)0; 2764*fe6060f1SDimitry Andric return (_Tp*) const_cast<void *>(__f_->target(typeid(_Tp))); 2765*fe6060f1SDimitry Andric } 2766*fe6060f1SDimitry Andric 2767*fe6060f1SDimitry Andric template<class _Rp, class _A0, class _A1, class _A2> 2768*fe6060f1SDimitry Andric template <typename _Tp> 2769*fe6060f1SDimitry Andric const _Tp* 2770*fe6060f1SDimitry Andric function<_Rp(_A0, _A1, _A2)>::target() const 2771*fe6060f1SDimitry Andric { 2772*fe6060f1SDimitry Andric if (__f_ == 0) 2773*fe6060f1SDimitry Andric return (const _Tp*)0; 2774*fe6060f1SDimitry Andric return (const _Tp*)__f_->target(typeid(_Tp)); 2775*fe6060f1SDimitry Andric } 2776*fe6060f1SDimitry Andric 2777*fe6060f1SDimitry Andric #endif // _LIBCPP_NO_RTTI 2778*fe6060f1SDimitry Andric 2779*fe6060f1SDimitry Andric template <class _Fp> 2780*fe6060f1SDimitry Andric inline _LIBCPP_INLINE_VISIBILITY 2781*fe6060f1SDimitry Andric bool 2782*fe6060f1SDimitry Andric operator==(const function<_Fp>& __f, nullptr_t) {return !__f;} 2783*fe6060f1SDimitry Andric 2784*fe6060f1SDimitry Andric template <class _Fp> 2785*fe6060f1SDimitry Andric inline _LIBCPP_INLINE_VISIBILITY 2786*fe6060f1SDimitry Andric bool 2787*fe6060f1SDimitry Andric operator==(nullptr_t, const function<_Fp>& __f) {return !__f;} 2788*fe6060f1SDimitry Andric 2789*fe6060f1SDimitry Andric template <class _Fp> 2790*fe6060f1SDimitry Andric inline _LIBCPP_INLINE_VISIBILITY 2791*fe6060f1SDimitry Andric bool 2792*fe6060f1SDimitry Andric operator!=(const function<_Fp>& __f, nullptr_t) {return (bool)__f;} 2793*fe6060f1SDimitry Andric 2794*fe6060f1SDimitry Andric template <class _Fp> 2795*fe6060f1SDimitry Andric inline _LIBCPP_INLINE_VISIBILITY 2796*fe6060f1SDimitry Andric bool 2797*fe6060f1SDimitry Andric operator!=(nullptr_t, const function<_Fp>& __f) {return (bool)__f;} 2798*fe6060f1SDimitry Andric 2799*fe6060f1SDimitry Andric template <class _Fp> 2800*fe6060f1SDimitry Andric inline _LIBCPP_INLINE_VISIBILITY 2801*fe6060f1SDimitry Andric void 2802*fe6060f1SDimitry Andric swap(function<_Fp>& __x, function<_Fp>& __y) 2803*fe6060f1SDimitry Andric {return __x.swap(__y);} 2804*fe6060f1SDimitry Andric 2805*fe6060f1SDimitry Andric #endif 2806*fe6060f1SDimitry Andric 2807*fe6060f1SDimitry Andric _LIBCPP_END_NAMESPACE_STD 2808*fe6060f1SDimitry Andric 2809*fe6060f1SDimitry Andric #endif // _LIBCPP___FUNCTIONAL_FUNCTION_H 2810