17a984708SDavid Chisnall// -*- C++ -*- 27a984708SDavid Chisnall//===----------------------------------------------------------------------===// 37a984708SDavid Chisnall// 47a984708SDavid Chisnall// The LLVM Compiler Infrastructure 57a984708SDavid Chisnall// 67a984708SDavid Chisnall// This file is dual licensed under the MIT and the University of Illinois Open 77a984708SDavid Chisnall// Source Licenses. See LICENSE.TXT for details. 87a984708SDavid Chisnall// 97a984708SDavid Chisnall//===----------------------------------------------------------------------===// 107a984708SDavid Chisnall 117a984708SDavid Chisnall#ifndef _LIBCPP_FUNCTIONAL_03 127a984708SDavid Chisnall#define _LIBCPP_FUNCTIONAL_03 137a984708SDavid Chisnall 147a984708SDavid Chisnall// manual variadic expansion for <functional> 157a984708SDavid Chisnall 167a984708SDavid Chisnall#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 177a984708SDavid Chisnall#pragma GCC system_header 187a984708SDavid Chisnall#endif 197a984708SDavid Chisnall 209729cf09SDimitry Andricnamespace __function { 217a984708SDavid Chisnall 227a984708SDavid Chisnalltemplate<class _Fp> class __base; 237a984708SDavid Chisnall 2494e3ee44SDavid Chisnalltemplate<class _Rp> 2594e3ee44SDavid Chisnallclass __base<_Rp()> 267a984708SDavid Chisnall{ 277a984708SDavid Chisnall __base(const __base&); 287a984708SDavid Chisnall __base& operator=(const __base&); 297a984708SDavid Chisnallpublic: 307a984708SDavid Chisnall __base() {} 317a984708SDavid Chisnall virtual ~__base() {} 327a984708SDavid Chisnall virtual __base* __clone() const = 0; 337a984708SDavid Chisnall virtual void __clone(__base*) const = 0; 347a984708SDavid Chisnall virtual void destroy() = 0; 357a984708SDavid Chisnall virtual void destroy_deallocate() = 0; 3694e3ee44SDavid Chisnall virtual _Rp operator()() = 0; 377a984708SDavid Chisnall#ifndef _LIBCPP_NO_RTTI 387a984708SDavid Chisnall virtual const void* target(const type_info&) const = 0; 397a984708SDavid Chisnall virtual const std::type_info& target_type() const = 0; 407a984708SDavid Chisnall#endif // _LIBCPP_NO_RTTI 417a984708SDavid Chisnall}; 427a984708SDavid Chisnall 4394e3ee44SDavid Chisnalltemplate<class _Rp, class _A0> 4494e3ee44SDavid Chisnallclass __base<_Rp(_A0)> 457a984708SDavid Chisnall{ 467a984708SDavid Chisnall __base(const __base&); 477a984708SDavid Chisnall __base& operator=(const __base&); 487a984708SDavid Chisnallpublic: 497a984708SDavid Chisnall __base() {} 507a984708SDavid Chisnall virtual ~__base() {} 517a984708SDavid Chisnall virtual __base* __clone() const = 0; 527a984708SDavid Chisnall virtual void __clone(__base*) const = 0; 537a984708SDavid Chisnall virtual void destroy() = 0; 547a984708SDavid Chisnall virtual void destroy_deallocate() = 0; 5594e3ee44SDavid Chisnall virtual _Rp operator()(_A0) = 0; 567a984708SDavid Chisnall#ifndef _LIBCPP_NO_RTTI 577a984708SDavid Chisnall virtual const void* target(const type_info&) const = 0; 587a984708SDavid Chisnall virtual const std::type_info& target_type() const = 0; 597a984708SDavid Chisnall#endif // _LIBCPP_NO_RTTI 607a984708SDavid Chisnall}; 617a984708SDavid Chisnall 6294e3ee44SDavid Chisnalltemplate<class _Rp, class _A0, class _A1> 6394e3ee44SDavid Chisnallclass __base<_Rp(_A0, _A1)> 647a984708SDavid Chisnall{ 657a984708SDavid Chisnall __base(const __base&); 667a984708SDavid Chisnall __base& operator=(const __base&); 677a984708SDavid Chisnallpublic: 687a984708SDavid Chisnall __base() {} 697a984708SDavid Chisnall virtual ~__base() {} 707a984708SDavid Chisnall virtual __base* __clone() const = 0; 717a984708SDavid Chisnall virtual void __clone(__base*) const = 0; 727a984708SDavid Chisnall virtual void destroy() = 0; 737a984708SDavid Chisnall virtual void destroy_deallocate() = 0; 7494e3ee44SDavid Chisnall virtual _Rp operator()(_A0, _A1) = 0; 757a984708SDavid Chisnall#ifndef _LIBCPP_NO_RTTI 767a984708SDavid Chisnall virtual const void* target(const type_info&) const = 0; 777a984708SDavid Chisnall virtual const std::type_info& target_type() const = 0; 787a984708SDavid Chisnall#endif // _LIBCPP_NO_RTTI 797a984708SDavid Chisnall}; 807a984708SDavid Chisnall 8194e3ee44SDavid Chisnalltemplate<class _Rp, class _A0, class _A1, class _A2> 8294e3ee44SDavid Chisnallclass __base<_Rp(_A0, _A1, _A2)> 837a984708SDavid Chisnall{ 847a984708SDavid Chisnall __base(const __base&); 857a984708SDavid Chisnall __base& operator=(const __base&); 867a984708SDavid Chisnallpublic: 877a984708SDavid Chisnall __base() {} 887a984708SDavid Chisnall virtual ~__base() {} 897a984708SDavid Chisnall virtual __base* __clone() const = 0; 907a984708SDavid Chisnall virtual void __clone(__base*) const = 0; 917a984708SDavid Chisnall virtual void destroy() = 0; 927a984708SDavid Chisnall virtual void destroy_deallocate() = 0; 9394e3ee44SDavid Chisnall virtual _Rp operator()(_A0, _A1, _A2) = 0; 947a984708SDavid Chisnall#ifndef _LIBCPP_NO_RTTI 957a984708SDavid Chisnall virtual const void* target(const type_info&) const = 0; 967a984708SDavid Chisnall virtual const std::type_info& target_type() const = 0; 977a984708SDavid Chisnall#endif // _LIBCPP_NO_RTTI 987a984708SDavid Chisnall}; 997a984708SDavid Chisnall 1007a984708SDavid Chisnalltemplate<class _FD, class _Alloc, class _FB> class __func; 1017a984708SDavid Chisnall 10294e3ee44SDavid Chisnalltemplate<class _Fp, class _Alloc, class _Rp> 10394e3ee44SDavid Chisnallclass __func<_Fp, _Alloc, _Rp()> 10494e3ee44SDavid Chisnall : public __base<_Rp()> 1057a984708SDavid Chisnall{ 10694e3ee44SDavid Chisnall __compressed_pair<_Fp, _Alloc> __f_; 1077a984708SDavid Chisnallpublic: 10894e3ee44SDavid Chisnall explicit __func(_Fp __f) : __f_(_VSTD::move(__f)) {} 10994e3ee44SDavid Chisnall explicit __func(_Fp __f, _Alloc __a) : __f_(_VSTD::move(__f), _VSTD::move(__a)) {} 11094e3ee44SDavid Chisnall virtual __base<_Rp()>* __clone() const; 11194e3ee44SDavid Chisnall virtual void __clone(__base<_Rp()>*) const; 1127a984708SDavid Chisnall virtual void destroy(); 1137a984708SDavid Chisnall virtual void destroy_deallocate(); 11494e3ee44SDavid Chisnall virtual _Rp operator()(); 1157a984708SDavid Chisnall#ifndef _LIBCPP_NO_RTTI 1167a984708SDavid Chisnall virtual const void* target(const type_info&) const; 1177a984708SDavid Chisnall virtual const std::type_info& target_type() const; 1187a984708SDavid Chisnall#endif // _LIBCPP_NO_RTTI 1197a984708SDavid Chisnall}; 1207a984708SDavid Chisnall 12194e3ee44SDavid Chisnalltemplate<class _Fp, class _Alloc, class _Rp> 12294e3ee44SDavid Chisnall__base<_Rp()>* 12394e3ee44SDavid Chisnall__func<_Fp, _Alloc, _Rp()>::__clone() const 1247a984708SDavid Chisnall{ 125854fa44bSDimitry Andric typedef allocator_traits<_Alloc> __alloc_traits; 126854fa44bSDimitry Andric typedef typename __rebind_alloc_helper<__alloc_traits, __func>::type _Ap; 12794e3ee44SDavid Chisnall _Ap __a(__f_.second()); 12894e3ee44SDavid Chisnall typedef __allocator_destructor<_Ap> _Dp; 12994e3ee44SDavid Chisnall unique_ptr<__func, _Dp> __hold(__a.allocate(1), _Dp(__a, 1)); 1307a984708SDavid Chisnall ::new (__hold.get()) __func(__f_.first(), _Alloc(__a)); 1317a984708SDavid Chisnall return __hold.release(); 1327a984708SDavid Chisnall} 1337a984708SDavid Chisnall 13494e3ee44SDavid Chisnalltemplate<class _Fp, class _Alloc, class _Rp> 1357a984708SDavid Chisnallvoid 13694e3ee44SDavid Chisnall__func<_Fp, _Alloc, _Rp()>::__clone(__base<_Rp()>* __p) const 1377a984708SDavid Chisnall{ 1387a984708SDavid Chisnall ::new (__p) __func(__f_.first(), __f_.second()); 1397a984708SDavid Chisnall} 1407a984708SDavid Chisnall 14194e3ee44SDavid Chisnalltemplate<class _Fp, class _Alloc, class _Rp> 1427a984708SDavid Chisnallvoid 14394e3ee44SDavid Chisnall__func<_Fp, _Alloc, _Rp()>::destroy() 1447a984708SDavid Chisnall{ 14594e3ee44SDavid Chisnall __f_.~__compressed_pair<_Fp, _Alloc>(); 1467a984708SDavid Chisnall} 1477a984708SDavid Chisnall 14894e3ee44SDavid Chisnalltemplate<class _Fp, class _Alloc, class _Rp> 1497a984708SDavid Chisnallvoid 15094e3ee44SDavid Chisnall__func<_Fp, _Alloc, _Rp()>::destroy_deallocate() 1517a984708SDavid Chisnall{ 152854fa44bSDimitry Andric typedef allocator_traits<_Alloc> __alloc_traits; 153854fa44bSDimitry Andric typedef typename __rebind_alloc_helper<__alloc_traits, __func>::type _Ap; 15494e3ee44SDavid Chisnall _Ap __a(__f_.second()); 15594e3ee44SDavid Chisnall __f_.~__compressed_pair<_Fp, _Alloc>(); 1567a984708SDavid Chisnall __a.deallocate(this, 1); 1577a984708SDavid Chisnall} 1587a984708SDavid Chisnall 15994e3ee44SDavid Chisnalltemplate<class _Fp, class _Alloc, class _Rp> 16094e3ee44SDavid Chisnall_Rp 16194e3ee44SDavid Chisnall__func<_Fp, _Alloc, _Rp()>::operator()() 1627a984708SDavid Chisnall{ 163854fa44bSDimitry Andric typedef __invoke_void_return_wrapper<_Rp> _Invoker; 164854fa44bSDimitry Andric return _Invoker::__call(__f_.first()); 1657a984708SDavid Chisnall} 1667a984708SDavid Chisnall 1677a984708SDavid Chisnall#ifndef _LIBCPP_NO_RTTI 1687a984708SDavid Chisnall 16994e3ee44SDavid Chisnalltemplate<class _Fp, class _Alloc, class _Rp> 1707a984708SDavid Chisnallconst void* 17194e3ee44SDavid Chisnall__func<_Fp, _Alloc, _Rp()>::target(const type_info& __ti) const 1727a984708SDavid Chisnall{ 17394e3ee44SDavid Chisnall if (__ti == typeid(_Fp)) 1747a984708SDavid Chisnall return &__f_.first(); 1757a984708SDavid Chisnall return (const void*)0; 1767a984708SDavid Chisnall} 1777a984708SDavid Chisnall 17894e3ee44SDavid Chisnalltemplate<class _Fp, class _Alloc, class _Rp> 1797a984708SDavid Chisnallconst std::type_info& 18094e3ee44SDavid Chisnall__func<_Fp, _Alloc, _Rp()>::target_type() const 1817a984708SDavid Chisnall{ 18294e3ee44SDavid Chisnall return typeid(_Fp); 1837a984708SDavid Chisnall} 1847a984708SDavid Chisnall 1857a984708SDavid Chisnall#endif // _LIBCPP_NO_RTTI 1867a984708SDavid Chisnall 18794e3ee44SDavid Chisnalltemplate<class _Fp, class _Alloc, class _Rp, class _A0> 18894e3ee44SDavid Chisnallclass __func<_Fp, _Alloc, _Rp(_A0)> 18994e3ee44SDavid Chisnall : public __base<_Rp(_A0)> 1907a984708SDavid Chisnall{ 19194e3ee44SDavid Chisnall __compressed_pair<_Fp, _Alloc> __f_; 1927a984708SDavid Chisnallpublic: 19394e3ee44SDavid Chisnall _LIBCPP_INLINE_VISIBILITY explicit __func(_Fp __f) : __f_(_VSTD::move(__f)) {} 19494e3ee44SDavid Chisnall _LIBCPP_INLINE_VISIBILITY explicit __func(_Fp __f, _Alloc __a) 1957a984708SDavid Chisnall : __f_(_VSTD::move(__f), _VSTD::move(__a)) {} 19694e3ee44SDavid Chisnall virtual __base<_Rp(_A0)>* __clone() const; 19794e3ee44SDavid Chisnall virtual void __clone(__base<_Rp(_A0)>*) const; 1987a984708SDavid Chisnall virtual void destroy(); 1997a984708SDavid Chisnall virtual void destroy_deallocate(); 20094e3ee44SDavid Chisnall virtual _Rp operator()(_A0); 2017a984708SDavid Chisnall#ifndef _LIBCPP_NO_RTTI 2027a984708SDavid Chisnall virtual const void* target(const type_info&) const; 2037a984708SDavid Chisnall virtual const std::type_info& target_type() const; 2047a984708SDavid Chisnall#endif // _LIBCPP_NO_RTTI 2057a984708SDavid Chisnall}; 2067a984708SDavid Chisnall 20794e3ee44SDavid Chisnalltemplate<class _Fp, class _Alloc, class _Rp, class _A0> 20894e3ee44SDavid Chisnall__base<_Rp(_A0)>* 20994e3ee44SDavid Chisnall__func<_Fp, _Alloc, _Rp(_A0)>::__clone() const 2107a984708SDavid Chisnall{ 211854fa44bSDimitry Andric typedef allocator_traits<_Alloc> __alloc_traits; 212854fa44bSDimitry Andric typedef typename __rebind_alloc_helper<__alloc_traits, __func>::type _Ap; 21394e3ee44SDavid Chisnall _Ap __a(__f_.second()); 21494e3ee44SDavid Chisnall typedef __allocator_destructor<_Ap> _Dp; 21594e3ee44SDavid Chisnall unique_ptr<__func, _Dp> __hold(__a.allocate(1), _Dp(__a, 1)); 2167a984708SDavid Chisnall ::new (__hold.get()) __func(__f_.first(), _Alloc(__a)); 2177a984708SDavid Chisnall return __hold.release(); 2187a984708SDavid Chisnall} 2197a984708SDavid Chisnall 22094e3ee44SDavid Chisnalltemplate<class _Fp, class _Alloc, class _Rp, class _A0> 2217a984708SDavid Chisnallvoid 22294e3ee44SDavid Chisnall__func<_Fp, _Alloc, _Rp(_A0)>::__clone(__base<_Rp(_A0)>* __p) const 2237a984708SDavid Chisnall{ 2247a984708SDavid Chisnall ::new (__p) __func(__f_.first(), __f_.second()); 2257a984708SDavid Chisnall} 2267a984708SDavid Chisnall 22794e3ee44SDavid Chisnalltemplate<class _Fp, class _Alloc, class _Rp, class _A0> 2287a984708SDavid Chisnallvoid 22994e3ee44SDavid Chisnall__func<_Fp, _Alloc, _Rp(_A0)>::destroy() 2307a984708SDavid Chisnall{ 23194e3ee44SDavid Chisnall __f_.~__compressed_pair<_Fp, _Alloc>(); 2327a984708SDavid Chisnall} 2337a984708SDavid Chisnall 23494e3ee44SDavid Chisnalltemplate<class _Fp, class _Alloc, class _Rp, class _A0> 2357a984708SDavid Chisnallvoid 23694e3ee44SDavid Chisnall__func<_Fp, _Alloc, _Rp(_A0)>::destroy_deallocate() 2377a984708SDavid Chisnall{ 238854fa44bSDimitry Andric typedef allocator_traits<_Alloc> __alloc_traits; 239854fa44bSDimitry Andric typedef typename __rebind_alloc_helper<__alloc_traits, __func>::type _Ap; 24094e3ee44SDavid Chisnall _Ap __a(__f_.second()); 24194e3ee44SDavid Chisnall __f_.~__compressed_pair<_Fp, _Alloc>(); 2427a984708SDavid Chisnall __a.deallocate(this, 1); 2437a984708SDavid Chisnall} 2447a984708SDavid Chisnall 24594e3ee44SDavid Chisnalltemplate<class _Fp, class _Alloc, class _Rp, class _A0> 24694e3ee44SDavid Chisnall_Rp 24794e3ee44SDavid Chisnall__func<_Fp, _Alloc, _Rp(_A0)>::operator()(_A0 __a0) 2487a984708SDavid Chisnall{ 249854fa44bSDimitry Andric typedef __invoke_void_return_wrapper<_Rp> _Invoker; 250854fa44bSDimitry Andric return _Invoker::__call(__f_.first(), __a0); 2517a984708SDavid Chisnall} 2527a984708SDavid Chisnall 2537a984708SDavid Chisnall#ifndef _LIBCPP_NO_RTTI 2547a984708SDavid Chisnall 25594e3ee44SDavid Chisnalltemplate<class _Fp, class _Alloc, class _Rp, class _A0> 2567a984708SDavid Chisnallconst void* 25794e3ee44SDavid Chisnall__func<_Fp, _Alloc, _Rp(_A0)>::target(const type_info& __ti) const 2587a984708SDavid Chisnall{ 25994e3ee44SDavid Chisnall if (__ti == typeid(_Fp)) 2607a984708SDavid Chisnall return &__f_.first(); 2617a984708SDavid Chisnall return (const void*)0; 2627a984708SDavid Chisnall} 2637a984708SDavid Chisnall 26494e3ee44SDavid Chisnalltemplate<class _Fp, class _Alloc, class _Rp, class _A0> 2657a984708SDavid Chisnallconst std::type_info& 26694e3ee44SDavid Chisnall__func<_Fp, _Alloc, _Rp(_A0)>::target_type() const 2677a984708SDavid Chisnall{ 26894e3ee44SDavid Chisnall return typeid(_Fp); 2697a984708SDavid Chisnall} 2707a984708SDavid Chisnall 2717a984708SDavid Chisnall#endif // _LIBCPP_NO_RTTI 2727a984708SDavid Chisnall 27394e3ee44SDavid Chisnalltemplate<class _Fp, class _Alloc, class _Rp, class _A0, class _A1> 27494e3ee44SDavid Chisnallclass __func<_Fp, _Alloc, _Rp(_A0, _A1)> 27594e3ee44SDavid Chisnall : public __base<_Rp(_A0, _A1)> 2767a984708SDavid Chisnall{ 27794e3ee44SDavid Chisnall __compressed_pair<_Fp, _Alloc> __f_; 2787a984708SDavid Chisnallpublic: 27994e3ee44SDavid Chisnall _LIBCPP_INLINE_VISIBILITY explicit __func(_Fp __f) : __f_(_VSTD::move(__f)) {} 28094e3ee44SDavid Chisnall _LIBCPP_INLINE_VISIBILITY explicit __func(_Fp __f, _Alloc __a) 2817a984708SDavid Chisnall : __f_(_VSTD::move(__f), _VSTD::move(__a)) {} 28294e3ee44SDavid Chisnall virtual __base<_Rp(_A0, _A1)>* __clone() const; 28394e3ee44SDavid Chisnall virtual void __clone(__base<_Rp(_A0, _A1)>*) const; 2847a984708SDavid Chisnall virtual void destroy(); 2857a984708SDavid Chisnall virtual void destroy_deallocate(); 28694e3ee44SDavid Chisnall virtual _Rp operator()(_A0, _A1); 2877a984708SDavid Chisnall#ifndef _LIBCPP_NO_RTTI 2887a984708SDavid Chisnall virtual const void* target(const type_info&) const; 2897a984708SDavid Chisnall virtual const std::type_info& target_type() const; 2907a984708SDavid Chisnall#endif // _LIBCPP_NO_RTTI 2917a984708SDavid Chisnall}; 2927a984708SDavid Chisnall 29394e3ee44SDavid Chisnalltemplate<class _Fp, class _Alloc, class _Rp, class _A0, class _A1> 29494e3ee44SDavid Chisnall__base<_Rp(_A0, _A1)>* 29594e3ee44SDavid Chisnall__func<_Fp, _Alloc, _Rp(_A0, _A1)>::__clone() const 2967a984708SDavid Chisnall{ 297854fa44bSDimitry Andric typedef allocator_traits<_Alloc> __alloc_traits; 298854fa44bSDimitry Andric typedef typename __rebind_alloc_helper<__alloc_traits, __func>::type _Ap; 29994e3ee44SDavid Chisnall _Ap __a(__f_.second()); 30094e3ee44SDavid Chisnall typedef __allocator_destructor<_Ap> _Dp; 30194e3ee44SDavid Chisnall unique_ptr<__func, _Dp> __hold(__a.allocate(1), _Dp(__a, 1)); 3027a984708SDavid Chisnall ::new (__hold.get()) __func(__f_.first(), _Alloc(__a)); 3037a984708SDavid Chisnall return __hold.release(); 3047a984708SDavid Chisnall} 3057a984708SDavid Chisnall 30694e3ee44SDavid Chisnalltemplate<class _Fp, class _Alloc, class _Rp, class _A0, class _A1> 3077a984708SDavid Chisnallvoid 30894e3ee44SDavid Chisnall__func<_Fp, _Alloc, _Rp(_A0, _A1)>::__clone(__base<_Rp(_A0, _A1)>* __p) const 3097a984708SDavid Chisnall{ 3107a984708SDavid Chisnall ::new (__p) __func(__f_.first(), __f_.second()); 3117a984708SDavid Chisnall} 3127a984708SDavid Chisnall 31394e3ee44SDavid Chisnalltemplate<class _Fp, class _Alloc, class _Rp, class _A0, class _A1> 3147a984708SDavid Chisnallvoid 31594e3ee44SDavid Chisnall__func<_Fp, _Alloc, _Rp(_A0, _A1)>::destroy() 3167a984708SDavid Chisnall{ 31794e3ee44SDavid Chisnall __f_.~__compressed_pair<_Fp, _Alloc>(); 3187a984708SDavid Chisnall} 3197a984708SDavid Chisnall 32094e3ee44SDavid Chisnalltemplate<class _Fp, class _Alloc, class _Rp, class _A0, class _A1> 3217a984708SDavid Chisnallvoid 32294e3ee44SDavid Chisnall__func<_Fp, _Alloc, _Rp(_A0, _A1)>::destroy_deallocate() 3237a984708SDavid Chisnall{ 324854fa44bSDimitry Andric typedef allocator_traits<_Alloc> __alloc_traits; 325854fa44bSDimitry Andric typedef typename __rebind_alloc_helper<__alloc_traits, __func>::type _Ap; 32694e3ee44SDavid Chisnall _Ap __a(__f_.second()); 32794e3ee44SDavid Chisnall __f_.~__compressed_pair<_Fp, _Alloc>(); 3287a984708SDavid Chisnall __a.deallocate(this, 1); 3297a984708SDavid Chisnall} 3307a984708SDavid Chisnall 33194e3ee44SDavid Chisnalltemplate<class _Fp, class _Alloc, class _Rp, class _A0, class _A1> 33294e3ee44SDavid Chisnall_Rp 33394e3ee44SDavid Chisnall__func<_Fp, _Alloc, _Rp(_A0, _A1)>::operator()(_A0 __a0, _A1 __a1) 3347a984708SDavid Chisnall{ 335854fa44bSDimitry Andric typedef __invoke_void_return_wrapper<_Rp> _Invoker; 336854fa44bSDimitry Andric return _Invoker::__call(__f_.first(), __a0, __a1); 3377a984708SDavid Chisnall} 3387a984708SDavid Chisnall 3397a984708SDavid Chisnall#ifndef _LIBCPP_NO_RTTI 3407a984708SDavid Chisnall 34194e3ee44SDavid Chisnalltemplate<class _Fp, class _Alloc, class _Rp, class _A0, class _A1> 3427a984708SDavid Chisnallconst void* 34394e3ee44SDavid Chisnall__func<_Fp, _Alloc, _Rp(_A0, _A1)>::target(const type_info& __ti) const 3447a984708SDavid Chisnall{ 34594e3ee44SDavid Chisnall if (__ti == typeid(_Fp)) 3467a984708SDavid Chisnall return &__f_.first(); 3477a984708SDavid Chisnall return (const void*)0; 3487a984708SDavid Chisnall} 3497a984708SDavid Chisnall 35094e3ee44SDavid Chisnalltemplate<class _Fp, class _Alloc, class _Rp, class _A0, class _A1> 3517a984708SDavid Chisnallconst std::type_info& 35294e3ee44SDavid Chisnall__func<_Fp, _Alloc, _Rp(_A0, _A1)>::target_type() const 3537a984708SDavid Chisnall{ 35494e3ee44SDavid Chisnall return typeid(_Fp); 3557a984708SDavid Chisnall} 3567a984708SDavid Chisnall 3577a984708SDavid Chisnall#endif // _LIBCPP_NO_RTTI 3587a984708SDavid Chisnall 35994e3ee44SDavid Chisnalltemplate<class _Fp, class _Alloc, class _Rp, class _A0, class _A1, class _A2> 36094e3ee44SDavid Chisnallclass __func<_Fp, _Alloc, _Rp(_A0, _A1, _A2)> 36194e3ee44SDavid Chisnall : public __base<_Rp(_A0, _A1, _A2)> 3627a984708SDavid Chisnall{ 36394e3ee44SDavid Chisnall __compressed_pair<_Fp, _Alloc> __f_; 3647a984708SDavid Chisnallpublic: 36594e3ee44SDavid Chisnall _LIBCPP_INLINE_VISIBILITY explicit __func(_Fp __f) : __f_(_VSTD::move(__f)) {} 36694e3ee44SDavid Chisnall _LIBCPP_INLINE_VISIBILITY explicit __func(_Fp __f, _Alloc __a) 3677a984708SDavid Chisnall : __f_(_VSTD::move(__f), _VSTD::move(__a)) {} 36894e3ee44SDavid Chisnall virtual __base<_Rp(_A0, _A1, _A2)>* __clone() const; 36994e3ee44SDavid Chisnall virtual void __clone(__base<_Rp(_A0, _A1, _A2)>*) const; 3707a984708SDavid Chisnall virtual void destroy(); 3717a984708SDavid Chisnall virtual void destroy_deallocate(); 37294e3ee44SDavid Chisnall virtual _Rp operator()(_A0, _A1, _A2); 3737a984708SDavid Chisnall#ifndef _LIBCPP_NO_RTTI 3747a984708SDavid Chisnall virtual const void* target(const type_info&) const; 3757a984708SDavid Chisnall virtual const std::type_info& target_type() const; 3767a984708SDavid Chisnall#endif // _LIBCPP_NO_RTTI 3777a984708SDavid Chisnall}; 3787a984708SDavid Chisnall 37994e3ee44SDavid Chisnalltemplate<class _Fp, class _Alloc, class _Rp, class _A0, class _A1, class _A2> 38094e3ee44SDavid Chisnall__base<_Rp(_A0, _A1, _A2)>* 38194e3ee44SDavid Chisnall__func<_Fp, _Alloc, _Rp(_A0, _A1, _A2)>::__clone() const 3827a984708SDavid Chisnall{ 383854fa44bSDimitry Andric typedef allocator_traits<_Alloc> __alloc_traits; 384854fa44bSDimitry Andric typedef typename __rebind_alloc_helper<__alloc_traits, __func>::type _Ap; 38594e3ee44SDavid Chisnall _Ap __a(__f_.second()); 38694e3ee44SDavid Chisnall typedef __allocator_destructor<_Ap> _Dp; 38794e3ee44SDavid Chisnall unique_ptr<__func, _Dp> __hold(__a.allocate(1), _Dp(__a, 1)); 3887a984708SDavid Chisnall ::new (__hold.get()) __func(__f_.first(), _Alloc(__a)); 3897a984708SDavid Chisnall return __hold.release(); 3907a984708SDavid Chisnall} 3917a984708SDavid Chisnall 39294e3ee44SDavid Chisnalltemplate<class _Fp, class _Alloc, class _Rp, class _A0, class _A1, class _A2> 3937a984708SDavid Chisnallvoid 39494e3ee44SDavid Chisnall__func<_Fp, _Alloc, _Rp(_A0, _A1, _A2)>::__clone(__base<_Rp(_A0, _A1, _A2)>* __p) const 3957a984708SDavid Chisnall{ 3967a984708SDavid Chisnall ::new (__p) __func(__f_.first(), __f_.second()); 3977a984708SDavid Chisnall} 3987a984708SDavid Chisnall 39994e3ee44SDavid Chisnalltemplate<class _Fp, class _Alloc, class _Rp, class _A0, class _A1, class _A2> 4007a984708SDavid Chisnallvoid 40194e3ee44SDavid Chisnall__func<_Fp, _Alloc, _Rp(_A0, _A1, _A2)>::destroy() 4027a984708SDavid Chisnall{ 40394e3ee44SDavid Chisnall __f_.~__compressed_pair<_Fp, _Alloc>(); 4047a984708SDavid Chisnall} 4057a984708SDavid Chisnall 40694e3ee44SDavid Chisnalltemplate<class _Fp, class _Alloc, class _Rp, class _A0, class _A1, class _A2> 4077a984708SDavid Chisnallvoid 40894e3ee44SDavid Chisnall__func<_Fp, _Alloc, _Rp(_A0, _A1, _A2)>::destroy_deallocate() 4097a984708SDavid Chisnall{ 410854fa44bSDimitry Andric typedef allocator_traits<_Alloc> __alloc_traits; 411854fa44bSDimitry Andric typedef typename __rebind_alloc_helper<__alloc_traits, __func>::type _Ap; 41294e3ee44SDavid Chisnall _Ap __a(__f_.second()); 41394e3ee44SDavid Chisnall __f_.~__compressed_pair<_Fp, _Alloc>(); 4147a984708SDavid Chisnall __a.deallocate(this, 1); 4157a984708SDavid Chisnall} 4167a984708SDavid Chisnall 41794e3ee44SDavid Chisnalltemplate<class _Fp, class _Alloc, class _Rp, class _A0, class _A1, class _A2> 41894e3ee44SDavid Chisnall_Rp 41994e3ee44SDavid Chisnall__func<_Fp, _Alloc, _Rp(_A0, _A1, _A2)>::operator()(_A0 __a0, _A1 __a1, _A2 __a2) 4207a984708SDavid Chisnall{ 421854fa44bSDimitry Andric typedef __invoke_void_return_wrapper<_Rp> _Invoker; 422854fa44bSDimitry Andric return _Invoker::__call(__f_.first(), __a0, __a1, __a2); 4237a984708SDavid Chisnall} 4247a984708SDavid Chisnall 4257a984708SDavid Chisnall#ifndef _LIBCPP_NO_RTTI 4267a984708SDavid Chisnall 42794e3ee44SDavid Chisnalltemplate<class _Fp, class _Alloc, class _Rp, class _A0, class _A1, class _A2> 4287a984708SDavid Chisnallconst void* 42994e3ee44SDavid Chisnall__func<_Fp, _Alloc, _Rp(_A0, _A1, _A2)>::target(const type_info& __ti) const 4307a984708SDavid Chisnall{ 43194e3ee44SDavid Chisnall if (__ti == typeid(_Fp)) 4327a984708SDavid Chisnall return &__f_.first(); 4337a984708SDavid Chisnall return (const void*)0; 4347a984708SDavid Chisnall} 4357a984708SDavid Chisnall 43694e3ee44SDavid Chisnalltemplate<class _Fp, class _Alloc, class _Rp, class _A0, class _A1, class _A2> 4377a984708SDavid Chisnallconst std::type_info& 43894e3ee44SDavid Chisnall__func<_Fp, _Alloc, _Rp(_A0, _A1, _A2)>::target_type() const 4397a984708SDavid Chisnall{ 44094e3ee44SDavid Chisnall return typeid(_Fp); 4417a984708SDavid Chisnall} 4427a984708SDavid Chisnall 4437a984708SDavid Chisnall#endif // _LIBCPP_NO_RTTI 4447a984708SDavid Chisnall 4457a984708SDavid Chisnall} // __function 4467a984708SDavid Chisnall 44794e3ee44SDavid Chisnalltemplate<class _Rp> 448aed8d94eSDimitry Andricclass _LIBCPP_TEMPLATE_VIS function<_Rp()> 4497a984708SDavid Chisnall{ 45094e3ee44SDavid Chisnall typedef __function::__base<_Rp()> __base; 4517a984708SDavid Chisnall aligned_storage<3*sizeof(void*)>::type __buf_; 4527a984708SDavid Chisnall __base* __f_; 4537a984708SDavid Chisnall 4547a984708SDavid Chisnallpublic: 45594e3ee44SDavid Chisnall typedef _Rp result_type; 4567a984708SDavid Chisnall 4577a984708SDavid Chisnall // 20.7.16.2.1, construct/copy/destroy: 4587a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY explicit function() : __f_(0) {} 4597a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY function(nullptr_t) : __f_(0) {} 4607a984708SDavid Chisnall function(const function&); 46194e3ee44SDavid Chisnall template<class _Fp> 46294e3ee44SDavid Chisnall function(_Fp, 46394e3ee44SDavid Chisnall typename enable_if<!is_integral<_Fp>::value>::type* = 0); 4647a984708SDavid Chisnall 4657a984708SDavid Chisnall template<class _Alloc> 4667a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY 4677a984708SDavid Chisnall function(allocator_arg_t, const _Alloc&) : __f_(0) {} 4687a984708SDavid Chisnall template<class _Alloc> 4697a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY 4707a984708SDavid Chisnall function(allocator_arg_t, const _Alloc&, nullptr_t) : __f_(0) {} 4717a984708SDavid Chisnall template<class _Alloc> 4727a984708SDavid Chisnall function(allocator_arg_t, const _Alloc&, const function&); 47394e3ee44SDavid Chisnall template<class _Fp, class _Alloc> 47494e3ee44SDavid Chisnall function(allocator_arg_t, const _Alloc& __a, _Fp __f, 47594e3ee44SDavid Chisnall typename enable_if<!is_integral<_Fp>::value>::type* = 0); 4767a984708SDavid Chisnall 4777a984708SDavid Chisnall function& operator=(const function&); 4787a984708SDavid Chisnall function& operator=(nullptr_t); 47994e3ee44SDavid Chisnall template<class _Fp> 4807a984708SDavid Chisnall typename enable_if 4817a984708SDavid Chisnall < 48294e3ee44SDavid Chisnall !is_integral<_Fp>::value, 4837a984708SDavid Chisnall function& 4847a984708SDavid Chisnall >::type 48594e3ee44SDavid Chisnall operator=(_Fp); 4867a984708SDavid Chisnall 4877a984708SDavid Chisnall ~function(); 4887a984708SDavid Chisnall 4897a984708SDavid Chisnall // 20.7.16.2.2, function modifiers: 4907a984708SDavid Chisnall void swap(function&); 49194e3ee44SDavid Chisnall template<class _Fp, class _Alloc> 4927a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY 49394e3ee44SDavid Chisnall void assign(_Fp __f, const _Alloc& __a) 4947a984708SDavid Chisnall {function(allocator_arg, __a, __f).swap(*this);} 4957a984708SDavid Chisnall 4967a984708SDavid Chisnall // 20.7.16.2.3, function capacity: 4977a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY operator bool() const {return __f_;} 4987a984708SDavid Chisnall 4997a984708SDavid Chisnallprivate: 5007a984708SDavid Chisnall // deleted overloads close possible hole in the type system 5017a984708SDavid Chisnall template<class _R2> 5027a984708SDavid Chisnall bool operator==(const function<_R2()>&) const;// = delete; 5037a984708SDavid Chisnall template<class _R2> 5047a984708SDavid Chisnall bool operator!=(const function<_R2()>&) const;// = delete; 5057a984708SDavid Chisnallpublic: 5067a984708SDavid Chisnall // 20.7.16.2.4, function invocation: 50794e3ee44SDavid Chisnall _Rp operator()() const; 5087a984708SDavid Chisnall 5097a984708SDavid Chisnall#ifndef _LIBCPP_NO_RTTI 5107a984708SDavid Chisnall // 20.7.16.2.5, function target access: 5117a984708SDavid Chisnall const std::type_info& target_type() const; 51294e3ee44SDavid Chisnall template <typename _Tp> _Tp* target(); 51394e3ee44SDavid Chisnall template <typename _Tp> const _Tp* target() const; 5147a984708SDavid Chisnall#endif // _LIBCPP_NO_RTTI 5157a984708SDavid Chisnall}; 5167a984708SDavid Chisnall 51794e3ee44SDavid Chisnalltemplate<class _Rp> 51894e3ee44SDavid Chisnallfunction<_Rp()>::function(const function& __f) 5197a984708SDavid Chisnall{ 5207a984708SDavid Chisnall if (__f.__f_ == 0) 5217a984708SDavid Chisnall __f_ = 0; 5227a984708SDavid Chisnall else if (__f.__f_ == (const __base*)&__f.__buf_) 5237a984708SDavid Chisnall { 5247a984708SDavid Chisnall __f_ = (__base*)&__buf_; 5257a984708SDavid Chisnall __f.__f_->__clone(__f_); 5267a984708SDavid Chisnall } 5277a984708SDavid Chisnall else 5287a984708SDavid Chisnall __f_ = __f.__f_->__clone(); 5297a984708SDavid Chisnall} 5307a984708SDavid Chisnall 53194e3ee44SDavid Chisnalltemplate<class _Rp> 5327a984708SDavid Chisnalltemplate<class _Alloc> 53394e3ee44SDavid Chisnallfunction<_Rp()>::function(allocator_arg_t, const _Alloc&, const function& __f) 5347a984708SDavid Chisnall{ 5357a984708SDavid Chisnall if (__f.__f_ == 0) 5367a984708SDavid Chisnall __f_ = 0; 5377a984708SDavid Chisnall else if (__f.__f_ == (const __base*)&__f.__buf_) 5387a984708SDavid Chisnall { 5397a984708SDavid Chisnall __f_ = (__base*)&__buf_; 5407a984708SDavid Chisnall __f.__f_->__clone(__f_); 5417a984708SDavid Chisnall } 5427a984708SDavid Chisnall else 5437a984708SDavid Chisnall __f_ = __f.__f_->__clone(); 5447a984708SDavid Chisnall} 5457a984708SDavid Chisnall 54694e3ee44SDavid Chisnalltemplate<class _Rp> 54794e3ee44SDavid Chisnalltemplate <class _Fp> 54894e3ee44SDavid Chisnallfunction<_Rp()>::function(_Fp __f, 54994e3ee44SDavid Chisnall typename enable_if<!is_integral<_Fp>::value>::type*) 5507a984708SDavid Chisnall : __f_(0) 5517a984708SDavid Chisnall{ 5529729cf09SDimitry Andric if (__function::__not_null(__f)) 5537a984708SDavid Chisnall { 55494e3ee44SDavid Chisnall typedef __function::__func<_Fp, allocator<_Fp>, _Rp()> _FF; 5557a984708SDavid Chisnall if (sizeof(_FF) <= sizeof(__buf_)) 5567a984708SDavid Chisnall { 5577a984708SDavid Chisnall __f_ = (__base*)&__buf_; 5587a984708SDavid Chisnall ::new (__f_) _FF(__f); 5597a984708SDavid Chisnall } 5607a984708SDavid Chisnall else 5617a984708SDavid Chisnall { 56294e3ee44SDavid Chisnall typedef allocator<_FF> _Ap; 56394e3ee44SDavid Chisnall _Ap __a; 56494e3ee44SDavid Chisnall typedef __allocator_destructor<_Ap> _Dp; 56594e3ee44SDavid Chisnall unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1)); 56694e3ee44SDavid Chisnall ::new (__hold.get()) _FF(__f, allocator<_Fp>(__a)); 5677a984708SDavid Chisnall __f_ = __hold.release(); 5687a984708SDavid Chisnall } 5697a984708SDavid Chisnall } 5707a984708SDavid Chisnall} 5717a984708SDavid Chisnall 57294e3ee44SDavid Chisnalltemplate<class _Rp> 57394e3ee44SDavid Chisnalltemplate <class _Fp, class _Alloc> 57494e3ee44SDavid Chisnallfunction<_Rp()>::function(allocator_arg_t, const _Alloc& __a0, _Fp __f, 57594e3ee44SDavid Chisnall typename enable_if<!is_integral<_Fp>::value>::type*) 5767a984708SDavid Chisnall : __f_(0) 5777a984708SDavid Chisnall{ 5787a984708SDavid Chisnall typedef allocator_traits<_Alloc> __alloc_traits; 5799729cf09SDimitry Andric if (__function::__not_null(__f)) 5807a984708SDavid Chisnall { 58194e3ee44SDavid Chisnall typedef __function::__func<_Fp, _Alloc, _Rp()> _FF; 5827a984708SDavid Chisnall if (sizeof(_FF) <= sizeof(__buf_)) 5837a984708SDavid Chisnall { 5847a984708SDavid Chisnall __f_ = (__base*)&__buf_; 585854fa44bSDimitry Andric ::new (__f_) _FF(__f, __a0); 5867a984708SDavid Chisnall } 5877a984708SDavid Chisnall else 5887a984708SDavid Chisnall { 589854fa44bSDimitry Andric typedef typename __rebind_alloc_helper<__alloc_traits, _FF>::type _Ap; 59094e3ee44SDavid Chisnall _Ap __a(__a0); 59194e3ee44SDavid Chisnall typedef __allocator_destructor<_Ap> _Dp; 59294e3ee44SDavid Chisnall unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1)); 5937a984708SDavid Chisnall ::new (__hold.get()) _FF(__f, _Alloc(__a)); 5947a984708SDavid Chisnall __f_ = __hold.release(); 5957a984708SDavid Chisnall } 5967a984708SDavid Chisnall } 5977a984708SDavid Chisnall} 5987a984708SDavid Chisnall 59994e3ee44SDavid Chisnalltemplate<class _Rp> 60094e3ee44SDavid Chisnallfunction<_Rp()>& 60194e3ee44SDavid Chisnallfunction<_Rp()>::operator=(const function& __f) 6027a984708SDavid Chisnall{ 603*4ba319b5SDimitry Andric if (__f) 6047a984708SDavid Chisnall function(__f).swap(*this); 605*4ba319b5SDimitry Andric else 606*4ba319b5SDimitry Andric *this = nullptr; 6077a984708SDavid Chisnall return *this; 6087a984708SDavid Chisnall} 6097a984708SDavid Chisnall 61094e3ee44SDavid Chisnalltemplate<class _Rp> 61194e3ee44SDavid Chisnallfunction<_Rp()>& 61294e3ee44SDavid Chisnallfunction<_Rp()>::operator=(nullptr_t) 6137a984708SDavid Chisnall{ 614*4ba319b5SDimitry Andric __base* __t = __f_; 6157a984708SDavid Chisnall __f_ = 0; 616*4ba319b5SDimitry Andric if (__t == (__base*)&__buf_) 617*4ba319b5SDimitry Andric __t->destroy(); 618*4ba319b5SDimitry Andric else if (__t) 619*4ba319b5SDimitry Andric __t->destroy_deallocate(); 620854fa44bSDimitry Andric return *this; 6217a984708SDavid Chisnall} 6227a984708SDavid Chisnall 62394e3ee44SDavid Chisnalltemplate<class _Rp> 62494e3ee44SDavid Chisnalltemplate <class _Fp> 6257a984708SDavid Chisnalltypename enable_if 6267a984708SDavid Chisnall< 62794e3ee44SDavid Chisnall !is_integral<_Fp>::value, 62894e3ee44SDavid Chisnall function<_Rp()>& 6297a984708SDavid Chisnall>::type 63094e3ee44SDavid Chisnallfunction<_Rp()>::operator=(_Fp __f) 6317a984708SDavid Chisnall{ 6327a984708SDavid Chisnall function(_VSTD::move(__f)).swap(*this); 6337a984708SDavid Chisnall return *this; 6347a984708SDavid Chisnall} 6357a984708SDavid Chisnall 63694e3ee44SDavid Chisnalltemplate<class _Rp> 63794e3ee44SDavid Chisnallfunction<_Rp()>::~function() 6387a984708SDavid Chisnall{ 6397a984708SDavid Chisnall if (__f_ == (__base*)&__buf_) 6407a984708SDavid Chisnall __f_->destroy(); 6417a984708SDavid Chisnall else if (__f_) 6427a984708SDavid Chisnall __f_->destroy_deallocate(); 6437a984708SDavid Chisnall} 6447a984708SDavid Chisnall 64594e3ee44SDavid Chisnalltemplate<class _Rp> 6467a984708SDavid Chisnallvoid 64794e3ee44SDavid Chisnallfunction<_Rp()>::swap(function& __f) 6487a984708SDavid Chisnall{ 649aed8d94eSDimitry Andric if (_VSTD::addressof(__f) == this) 650aed8d94eSDimitry Andric return; 6517a984708SDavid Chisnall if (__f_ == (__base*)&__buf_ && __f.__f_ == (__base*)&__f.__buf_) 6527a984708SDavid Chisnall { 6537a984708SDavid Chisnall typename aligned_storage<sizeof(__buf_)>::type __tempbuf; 6547a984708SDavid Chisnall __base* __t = (__base*)&__tempbuf; 6557a984708SDavid Chisnall __f_->__clone(__t); 6567a984708SDavid Chisnall __f_->destroy(); 6577a984708SDavid Chisnall __f_ = 0; 6587a984708SDavid Chisnall __f.__f_->__clone((__base*)&__buf_); 6597a984708SDavid Chisnall __f.__f_->destroy(); 6607a984708SDavid Chisnall __f.__f_ = 0; 6617a984708SDavid Chisnall __f_ = (__base*)&__buf_; 6627a984708SDavid Chisnall __t->__clone((__base*)&__f.__buf_); 6637a984708SDavid Chisnall __t->destroy(); 6647a984708SDavid Chisnall __f.__f_ = (__base*)&__f.__buf_; 6657a984708SDavid Chisnall } 6667a984708SDavid Chisnall else if (__f_ == (__base*)&__buf_) 6677a984708SDavid Chisnall { 6687a984708SDavid Chisnall __f_->__clone((__base*)&__f.__buf_); 6697a984708SDavid Chisnall __f_->destroy(); 6707a984708SDavid Chisnall __f_ = __f.__f_; 6717a984708SDavid Chisnall __f.__f_ = (__base*)&__f.__buf_; 6727a984708SDavid Chisnall } 6737a984708SDavid Chisnall else if (__f.__f_ == (__base*)&__f.__buf_) 6747a984708SDavid Chisnall { 6757a984708SDavid Chisnall __f.__f_->__clone((__base*)&__buf_); 6767a984708SDavid Chisnall __f.__f_->destroy(); 6777a984708SDavid Chisnall __f.__f_ = __f_; 6787a984708SDavid Chisnall __f_ = (__base*)&__buf_; 6797a984708SDavid Chisnall } 6807a984708SDavid Chisnall else 6817a984708SDavid Chisnall _VSTD::swap(__f_, __f.__f_); 6827a984708SDavid Chisnall} 6837a984708SDavid Chisnall 68494e3ee44SDavid Chisnalltemplate<class _Rp> 68594e3ee44SDavid Chisnall_Rp 68694e3ee44SDavid Chisnallfunction<_Rp()>::operator()() const 6877a984708SDavid Chisnall{ 6887a984708SDavid Chisnall if (__f_ == 0) 689aed8d94eSDimitry Andric __throw_bad_function_call(); 6907a984708SDavid Chisnall return (*__f_)(); 6917a984708SDavid Chisnall} 6927a984708SDavid Chisnall 6937a984708SDavid Chisnall#ifndef _LIBCPP_NO_RTTI 6947a984708SDavid Chisnall 69594e3ee44SDavid Chisnalltemplate<class _Rp> 6967a984708SDavid Chisnallconst std::type_info& 69794e3ee44SDavid Chisnallfunction<_Rp()>::target_type() const 6987a984708SDavid Chisnall{ 6997a984708SDavid Chisnall if (__f_ == 0) 7007a984708SDavid Chisnall return typeid(void); 7017a984708SDavid Chisnall return __f_->target_type(); 7027a984708SDavid Chisnall} 7037a984708SDavid Chisnall 70494e3ee44SDavid Chisnalltemplate<class _Rp> 70594e3ee44SDavid Chisnalltemplate <typename _Tp> 70694e3ee44SDavid Chisnall_Tp* 70794e3ee44SDavid Chisnallfunction<_Rp()>::target() 7087a984708SDavid Chisnall{ 7097a984708SDavid Chisnall if (__f_ == 0) 71094e3ee44SDavid Chisnall return (_Tp*)0; 71124d58133SDimitry Andric return (_Tp*) const_cast<void *>(__f_->target(typeid(_Tp))); 7127a984708SDavid Chisnall} 7137a984708SDavid Chisnall 71494e3ee44SDavid Chisnalltemplate<class _Rp> 71594e3ee44SDavid Chisnalltemplate <typename _Tp> 71694e3ee44SDavid Chisnallconst _Tp* 71794e3ee44SDavid Chisnallfunction<_Rp()>::target() const 7187a984708SDavid Chisnall{ 7197a984708SDavid Chisnall if (__f_ == 0) 72094e3ee44SDavid Chisnall return (const _Tp*)0; 72194e3ee44SDavid Chisnall return (const _Tp*)__f_->target(typeid(_Tp)); 7227a984708SDavid Chisnall} 7237a984708SDavid Chisnall 7247a984708SDavid Chisnall#endif // _LIBCPP_NO_RTTI 7257a984708SDavid Chisnall 72694e3ee44SDavid Chisnalltemplate<class _Rp, class _A0> 727aed8d94eSDimitry Andricclass _LIBCPP_TEMPLATE_VIS function<_Rp(_A0)> 72894e3ee44SDavid Chisnall : public unary_function<_A0, _Rp> 7297a984708SDavid Chisnall{ 73094e3ee44SDavid Chisnall typedef __function::__base<_Rp(_A0)> __base; 7317a984708SDavid Chisnall aligned_storage<3*sizeof(void*)>::type __buf_; 7327a984708SDavid Chisnall __base* __f_; 7337a984708SDavid Chisnall 7347a984708SDavid Chisnallpublic: 73594e3ee44SDavid Chisnall typedef _Rp result_type; 7367a984708SDavid Chisnall 7377a984708SDavid Chisnall // 20.7.16.2.1, construct/copy/destroy: 7387a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY explicit function() : __f_(0) {} 7397a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY function(nullptr_t) : __f_(0) {} 7407a984708SDavid Chisnall function(const function&); 74194e3ee44SDavid Chisnall template<class _Fp> 74294e3ee44SDavid Chisnall function(_Fp, 74394e3ee44SDavid Chisnall typename enable_if<!is_integral<_Fp>::value>::type* = 0); 7447a984708SDavid Chisnall 7457a984708SDavid Chisnall template<class _Alloc> 7467a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY 7477a984708SDavid Chisnall function(allocator_arg_t, const _Alloc&) : __f_(0) {} 7487a984708SDavid Chisnall template<class _Alloc> 7497a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY 7507a984708SDavid Chisnall function(allocator_arg_t, const _Alloc&, nullptr_t) : __f_(0) {} 7517a984708SDavid Chisnall template<class _Alloc> 7527a984708SDavid Chisnall function(allocator_arg_t, const _Alloc&, const function&); 75394e3ee44SDavid Chisnall template<class _Fp, class _Alloc> 75494e3ee44SDavid Chisnall function(allocator_arg_t, const _Alloc& __a, _Fp __f, 75594e3ee44SDavid Chisnall typename enable_if<!is_integral<_Fp>::value>::type* = 0); 7567a984708SDavid Chisnall 7577a984708SDavid Chisnall function& operator=(const function&); 7587a984708SDavid Chisnall function& operator=(nullptr_t); 75994e3ee44SDavid Chisnall template<class _Fp> 7607a984708SDavid Chisnall typename enable_if 7617a984708SDavid Chisnall < 76294e3ee44SDavid Chisnall !is_integral<_Fp>::value, 7637a984708SDavid Chisnall function& 7647a984708SDavid Chisnall >::type 76594e3ee44SDavid Chisnall operator=(_Fp); 7667a984708SDavid Chisnall 7677a984708SDavid Chisnall ~function(); 7687a984708SDavid Chisnall 7697a984708SDavid Chisnall // 20.7.16.2.2, function modifiers: 7707a984708SDavid Chisnall void swap(function&); 77194e3ee44SDavid Chisnall template<class _Fp, class _Alloc> 7727a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY 77394e3ee44SDavid Chisnall void assign(_Fp __f, const _Alloc& __a) 7747a984708SDavid Chisnall {function(allocator_arg, __a, __f).swap(*this);} 7757a984708SDavid Chisnall 7767a984708SDavid Chisnall // 20.7.16.2.3, function capacity: 7777a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY operator bool() const {return __f_;} 7787a984708SDavid Chisnall 7797a984708SDavid Chisnallprivate: 7807a984708SDavid Chisnall // deleted overloads close possible hole in the type system 7817a984708SDavid Chisnall template<class _R2, class _B0> 7827a984708SDavid Chisnall bool operator==(const function<_R2(_B0)>&) const;// = delete; 7837a984708SDavid Chisnall template<class _R2, class _B0> 7847a984708SDavid Chisnall bool operator!=(const function<_R2(_B0)>&) const;// = delete; 7857a984708SDavid Chisnallpublic: 7867a984708SDavid Chisnall // 20.7.16.2.4, function invocation: 78794e3ee44SDavid Chisnall _Rp operator()(_A0) const; 7887a984708SDavid Chisnall 7897a984708SDavid Chisnall#ifndef _LIBCPP_NO_RTTI 7907a984708SDavid Chisnall // 20.7.16.2.5, function target access: 7917a984708SDavid Chisnall const std::type_info& target_type() const; 79294e3ee44SDavid Chisnall template <typename _Tp> _Tp* target(); 79394e3ee44SDavid Chisnall template <typename _Tp> const _Tp* target() const; 7947a984708SDavid Chisnall#endif // _LIBCPP_NO_RTTI 7957a984708SDavid Chisnall}; 7967a984708SDavid Chisnall 79794e3ee44SDavid Chisnalltemplate<class _Rp, class _A0> 79894e3ee44SDavid Chisnallfunction<_Rp(_A0)>::function(const function& __f) 7997a984708SDavid Chisnall{ 8007a984708SDavid Chisnall if (__f.__f_ == 0) 8017a984708SDavid Chisnall __f_ = 0; 8027a984708SDavid Chisnall else if (__f.__f_ == (const __base*)&__f.__buf_) 8037a984708SDavid Chisnall { 8047a984708SDavid Chisnall __f_ = (__base*)&__buf_; 8057a984708SDavid Chisnall __f.__f_->__clone(__f_); 8067a984708SDavid Chisnall } 8077a984708SDavid Chisnall else 8087a984708SDavid Chisnall __f_ = __f.__f_->__clone(); 8097a984708SDavid Chisnall} 8107a984708SDavid Chisnall 81194e3ee44SDavid Chisnalltemplate<class _Rp, class _A0> 8127a984708SDavid Chisnalltemplate<class _Alloc> 81394e3ee44SDavid Chisnallfunction<_Rp(_A0)>::function(allocator_arg_t, const _Alloc&, const function& __f) 8147a984708SDavid Chisnall{ 8157a984708SDavid Chisnall if (__f.__f_ == 0) 8167a984708SDavid Chisnall __f_ = 0; 8177a984708SDavid Chisnall else if (__f.__f_ == (const __base*)&__f.__buf_) 8187a984708SDavid Chisnall { 8197a984708SDavid Chisnall __f_ = (__base*)&__buf_; 8207a984708SDavid Chisnall __f.__f_->__clone(__f_); 8217a984708SDavid Chisnall } 8227a984708SDavid Chisnall else 8237a984708SDavid Chisnall __f_ = __f.__f_->__clone(); 8247a984708SDavid Chisnall} 8257a984708SDavid Chisnall 82694e3ee44SDavid Chisnalltemplate<class _Rp, class _A0> 82794e3ee44SDavid Chisnalltemplate <class _Fp> 82894e3ee44SDavid Chisnallfunction<_Rp(_A0)>::function(_Fp __f, 82994e3ee44SDavid Chisnall typename enable_if<!is_integral<_Fp>::value>::type*) 8307a984708SDavid Chisnall : __f_(0) 8317a984708SDavid Chisnall{ 8329729cf09SDimitry Andric if (__function::__not_null(__f)) 8337a984708SDavid Chisnall { 83494e3ee44SDavid Chisnall typedef __function::__func<_Fp, allocator<_Fp>, _Rp(_A0)> _FF; 8357a984708SDavid Chisnall if (sizeof(_FF) <= sizeof(__buf_)) 8367a984708SDavid Chisnall { 8377a984708SDavid Chisnall __f_ = (__base*)&__buf_; 8387a984708SDavid Chisnall ::new (__f_) _FF(__f); 8397a984708SDavid Chisnall } 8407a984708SDavid Chisnall else 8417a984708SDavid Chisnall { 84294e3ee44SDavid Chisnall typedef allocator<_FF> _Ap; 84394e3ee44SDavid Chisnall _Ap __a; 84494e3ee44SDavid Chisnall typedef __allocator_destructor<_Ap> _Dp; 84594e3ee44SDavid Chisnall unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1)); 84694e3ee44SDavid Chisnall ::new (__hold.get()) _FF(__f, allocator<_Fp>(__a)); 8477a984708SDavid Chisnall __f_ = __hold.release(); 8487a984708SDavid Chisnall } 8497a984708SDavid Chisnall } 8507a984708SDavid Chisnall} 8517a984708SDavid Chisnall 85294e3ee44SDavid Chisnalltemplate<class _Rp, class _A0> 85394e3ee44SDavid Chisnalltemplate <class _Fp, class _Alloc> 85494e3ee44SDavid Chisnallfunction<_Rp(_A0)>::function(allocator_arg_t, const _Alloc& __a0, _Fp __f, 85594e3ee44SDavid Chisnall typename enable_if<!is_integral<_Fp>::value>::type*) 8567a984708SDavid Chisnall : __f_(0) 8577a984708SDavid Chisnall{ 8587a984708SDavid Chisnall typedef allocator_traits<_Alloc> __alloc_traits; 8599729cf09SDimitry Andric if (__function::__not_null(__f)) 8607a984708SDavid Chisnall { 86194e3ee44SDavid Chisnall typedef __function::__func<_Fp, _Alloc, _Rp(_A0)> _FF; 8627a984708SDavid Chisnall if (sizeof(_FF) <= sizeof(__buf_)) 8637a984708SDavid Chisnall { 8647a984708SDavid Chisnall __f_ = (__base*)&__buf_; 865854fa44bSDimitry Andric ::new (__f_) _FF(__f, __a0); 8667a984708SDavid Chisnall } 8677a984708SDavid Chisnall else 8687a984708SDavid Chisnall { 869854fa44bSDimitry Andric typedef typename __rebind_alloc_helper<__alloc_traits, _FF>::type _Ap; 87094e3ee44SDavid Chisnall _Ap __a(__a0); 87194e3ee44SDavid Chisnall typedef __allocator_destructor<_Ap> _Dp; 87294e3ee44SDavid Chisnall unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1)); 8737a984708SDavid Chisnall ::new (__hold.get()) _FF(__f, _Alloc(__a)); 8747a984708SDavid Chisnall __f_ = __hold.release(); 8757a984708SDavid Chisnall } 8767a984708SDavid Chisnall } 8777a984708SDavid Chisnall} 8787a984708SDavid Chisnall 87994e3ee44SDavid Chisnalltemplate<class _Rp, class _A0> 88094e3ee44SDavid Chisnallfunction<_Rp(_A0)>& 88194e3ee44SDavid Chisnallfunction<_Rp(_A0)>::operator=(const function& __f) 8827a984708SDavid Chisnall{ 883*4ba319b5SDimitry Andric if (__f) 8847a984708SDavid Chisnall function(__f).swap(*this); 885*4ba319b5SDimitry Andric else 886*4ba319b5SDimitry Andric *this = nullptr; 8877a984708SDavid Chisnall return *this; 8887a984708SDavid Chisnall} 8897a984708SDavid Chisnall 89094e3ee44SDavid Chisnalltemplate<class _Rp, class _A0> 89194e3ee44SDavid Chisnallfunction<_Rp(_A0)>& 89294e3ee44SDavid Chisnallfunction<_Rp(_A0)>::operator=(nullptr_t) 8937a984708SDavid Chisnall{ 894*4ba319b5SDimitry Andric __base* __t = __f_; 8957a984708SDavid Chisnall __f_ = 0; 896*4ba319b5SDimitry Andric if (__t == (__base*)&__buf_) 897*4ba319b5SDimitry Andric __t->destroy(); 898*4ba319b5SDimitry Andric else if (__t) 899*4ba319b5SDimitry Andric __t->destroy_deallocate(); 900854fa44bSDimitry Andric return *this; 9017a984708SDavid Chisnall} 9027a984708SDavid Chisnall 90394e3ee44SDavid Chisnalltemplate<class _Rp, class _A0> 90494e3ee44SDavid Chisnalltemplate <class _Fp> 9057a984708SDavid Chisnalltypename enable_if 9067a984708SDavid Chisnall< 90794e3ee44SDavid Chisnall !is_integral<_Fp>::value, 90894e3ee44SDavid Chisnall function<_Rp(_A0)>& 9097a984708SDavid Chisnall>::type 91094e3ee44SDavid Chisnallfunction<_Rp(_A0)>::operator=(_Fp __f) 9117a984708SDavid Chisnall{ 9127a984708SDavid Chisnall function(_VSTD::move(__f)).swap(*this); 9137a984708SDavid Chisnall return *this; 9147a984708SDavid Chisnall} 9157a984708SDavid Chisnall 91694e3ee44SDavid Chisnalltemplate<class _Rp, class _A0> 91794e3ee44SDavid Chisnallfunction<_Rp(_A0)>::~function() 9187a984708SDavid Chisnall{ 9197a984708SDavid Chisnall if (__f_ == (__base*)&__buf_) 9207a984708SDavid Chisnall __f_->destroy(); 9217a984708SDavid Chisnall else if (__f_) 9227a984708SDavid Chisnall __f_->destroy_deallocate(); 9237a984708SDavid Chisnall} 9247a984708SDavid Chisnall 92594e3ee44SDavid Chisnalltemplate<class _Rp, class _A0> 9267a984708SDavid Chisnallvoid 92794e3ee44SDavid Chisnallfunction<_Rp(_A0)>::swap(function& __f) 9287a984708SDavid Chisnall{ 929aed8d94eSDimitry Andric if (_VSTD::addressof(__f) == this) 930aed8d94eSDimitry Andric return; 9317a984708SDavid Chisnall if (__f_ == (__base*)&__buf_ && __f.__f_ == (__base*)&__f.__buf_) 9327a984708SDavid Chisnall { 9337a984708SDavid Chisnall typename aligned_storage<sizeof(__buf_)>::type __tempbuf; 9347a984708SDavid Chisnall __base* __t = (__base*)&__tempbuf; 9357a984708SDavid Chisnall __f_->__clone(__t); 9367a984708SDavid Chisnall __f_->destroy(); 9377a984708SDavid Chisnall __f_ = 0; 9387a984708SDavid Chisnall __f.__f_->__clone((__base*)&__buf_); 9397a984708SDavid Chisnall __f.__f_->destroy(); 9407a984708SDavid Chisnall __f.__f_ = 0; 9417a984708SDavid Chisnall __f_ = (__base*)&__buf_; 9427a984708SDavid Chisnall __t->__clone((__base*)&__f.__buf_); 9437a984708SDavid Chisnall __t->destroy(); 9447a984708SDavid Chisnall __f.__f_ = (__base*)&__f.__buf_; 9457a984708SDavid Chisnall } 9467a984708SDavid Chisnall else if (__f_ == (__base*)&__buf_) 9477a984708SDavid Chisnall { 9487a984708SDavid Chisnall __f_->__clone((__base*)&__f.__buf_); 9497a984708SDavid Chisnall __f_->destroy(); 9507a984708SDavid Chisnall __f_ = __f.__f_; 9517a984708SDavid Chisnall __f.__f_ = (__base*)&__f.__buf_; 9527a984708SDavid Chisnall } 9537a984708SDavid Chisnall else if (__f.__f_ == (__base*)&__f.__buf_) 9547a984708SDavid Chisnall { 9557a984708SDavid Chisnall __f.__f_->__clone((__base*)&__buf_); 9567a984708SDavid Chisnall __f.__f_->destroy(); 9577a984708SDavid Chisnall __f.__f_ = __f_; 9587a984708SDavid Chisnall __f_ = (__base*)&__buf_; 9597a984708SDavid Chisnall } 9607a984708SDavid Chisnall else 9617a984708SDavid Chisnall _VSTD::swap(__f_, __f.__f_); 9627a984708SDavid Chisnall} 9637a984708SDavid Chisnall 96494e3ee44SDavid Chisnalltemplate<class _Rp, class _A0> 96594e3ee44SDavid Chisnall_Rp 96694e3ee44SDavid Chisnallfunction<_Rp(_A0)>::operator()(_A0 __a0) const 9677a984708SDavid Chisnall{ 9687a984708SDavid Chisnall if (__f_ == 0) 969aed8d94eSDimitry Andric __throw_bad_function_call(); 9707a984708SDavid Chisnall return (*__f_)(__a0); 9717a984708SDavid Chisnall} 9727a984708SDavid Chisnall 9737a984708SDavid Chisnall#ifndef _LIBCPP_NO_RTTI 9747a984708SDavid Chisnall 97594e3ee44SDavid Chisnalltemplate<class _Rp, class _A0> 9767a984708SDavid Chisnallconst std::type_info& 97794e3ee44SDavid Chisnallfunction<_Rp(_A0)>::target_type() const 9787a984708SDavid Chisnall{ 9797a984708SDavid Chisnall if (__f_ == 0) 9807a984708SDavid Chisnall return typeid(void); 9817a984708SDavid Chisnall return __f_->target_type(); 9827a984708SDavid Chisnall} 9837a984708SDavid Chisnall 98494e3ee44SDavid Chisnalltemplate<class _Rp, class _A0> 98594e3ee44SDavid Chisnalltemplate <typename _Tp> 98694e3ee44SDavid Chisnall_Tp* 98794e3ee44SDavid Chisnallfunction<_Rp(_A0)>::target() 9887a984708SDavid Chisnall{ 9897a984708SDavid Chisnall if (__f_ == 0) 99094e3ee44SDavid Chisnall return (_Tp*)0; 99124d58133SDimitry Andric return (_Tp*) const_cast<void *>(__f_->target(typeid(_Tp))); 9927a984708SDavid Chisnall} 9937a984708SDavid Chisnall 99494e3ee44SDavid Chisnalltemplate<class _Rp, class _A0> 99594e3ee44SDavid Chisnalltemplate <typename _Tp> 99694e3ee44SDavid Chisnallconst _Tp* 99794e3ee44SDavid Chisnallfunction<_Rp(_A0)>::target() const 9987a984708SDavid Chisnall{ 9997a984708SDavid Chisnall if (__f_ == 0) 100094e3ee44SDavid Chisnall return (const _Tp*)0; 100194e3ee44SDavid Chisnall return (const _Tp*)__f_->target(typeid(_Tp)); 10027a984708SDavid Chisnall} 10037a984708SDavid Chisnall 10047a984708SDavid Chisnall#endif // _LIBCPP_NO_RTTI 10057a984708SDavid Chisnall 100694e3ee44SDavid Chisnalltemplate<class _Rp, class _A0, class _A1> 1007aed8d94eSDimitry Andricclass _LIBCPP_TEMPLATE_VIS function<_Rp(_A0, _A1)> 100894e3ee44SDavid Chisnall : public binary_function<_A0, _A1, _Rp> 10097a984708SDavid Chisnall{ 101094e3ee44SDavid Chisnall typedef __function::__base<_Rp(_A0, _A1)> __base; 10117a984708SDavid Chisnall aligned_storage<3*sizeof(void*)>::type __buf_; 10127a984708SDavid Chisnall __base* __f_; 10137a984708SDavid Chisnall 10147a984708SDavid Chisnallpublic: 101594e3ee44SDavid Chisnall typedef _Rp result_type; 10167a984708SDavid Chisnall 10177a984708SDavid Chisnall // 20.7.16.2.1, construct/copy/destroy: 10187a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY explicit function() : __f_(0) {} 10197a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY function(nullptr_t) : __f_(0) {} 10207a984708SDavid Chisnall function(const function&); 102194e3ee44SDavid Chisnall template<class _Fp> 102294e3ee44SDavid Chisnall function(_Fp, 102394e3ee44SDavid Chisnall typename enable_if<!is_integral<_Fp>::value>::type* = 0); 10247a984708SDavid Chisnall 10257a984708SDavid Chisnall template<class _Alloc> 10267a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY 10277a984708SDavid Chisnall function(allocator_arg_t, const _Alloc&) : __f_(0) {} 10287a984708SDavid Chisnall template<class _Alloc> 10297a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY 10307a984708SDavid Chisnall function(allocator_arg_t, const _Alloc&, nullptr_t) : __f_(0) {} 10317a984708SDavid Chisnall template<class _Alloc> 10327a984708SDavid Chisnall function(allocator_arg_t, const _Alloc&, const function&); 103394e3ee44SDavid Chisnall template<class _Fp, class _Alloc> 103494e3ee44SDavid Chisnall function(allocator_arg_t, const _Alloc& __a, _Fp __f, 103594e3ee44SDavid Chisnall typename enable_if<!is_integral<_Fp>::value>::type* = 0); 10367a984708SDavid Chisnall 10377a984708SDavid Chisnall function& operator=(const function&); 10387a984708SDavid Chisnall function& operator=(nullptr_t); 103994e3ee44SDavid Chisnall template<class _Fp> 10407a984708SDavid Chisnall typename enable_if 10417a984708SDavid Chisnall < 104294e3ee44SDavid Chisnall !is_integral<_Fp>::value, 10437a984708SDavid Chisnall function& 10447a984708SDavid Chisnall >::type 104594e3ee44SDavid Chisnall operator=(_Fp); 10467a984708SDavid Chisnall 10477a984708SDavid Chisnall ~function(); 10487a984708SDavid Chisnall 10497a984708SDavid Chisnall // 20.7.16.2.2, function modifiers: 10507a984708SDavid Chisnall void swap(function&); 105194e3ee44SDavid Chisnall template<class _Fp, class _Alloc> 10527a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY 105394e3ee44SDavid Chisnall void assign(_Fp __f, const _Alloc& __a) 10547a984708SDavid Chisnall {function(allocator_arg, __a, __f).swap(*this);} 10557a984708SDavid Chisnall 10567a984708SDavid Chisnall // 20.7.16.2.3, function capacity: 10577a984708SDavid Chisnall operator bool() const {return __f_;} 10587a984708SDavid Chisnall 10597a984708SDavid Chisnallprivate: 10607a984708SDavid Chisnall // deleted overloads close possible hole in the type system 10617a984708SDavid Chisnall template<class _R2, class _B0, class _B1> 10627a984708SDavid Chisnall bool operator==(const function<_R2(_B0, _B1)>&) const;// = delete; 10637a984708SDavid Chisnall template<class _R2, class _B0, class _B1> 10647a984708SDavid Chisnall bool operator!=(const function<_R2(_B0, _B1)>&) const;// = delete; 10657a984708SDavid Chisnallpublic: 10667a984708SDavid Chisnall // 20.7.16.2.4, function invocation: 106794e3ee44SDavid Chisnall _Rp operator()(_A0, _A1) const; 10687a984708SDavid Chisnall 10697a984708SDavid Chisnall#ifndef _LIBCPP_NO_RTTI 10707a984708SDavid Chisnall // 20.7.16.2.5, function target access: 10717a984708SDavid Chisnall const std::type_info& target_type() const; 107294e3ee44SDavid Chisnall template <typename _Tp> _Tp* target(); 107394e3ee44SDavid Chisnall template <typename _Tp> const _Tp* target() const; 10747a984708SDavid Chisnall#endif // _LIBCPP_NO_RTTI 10757a984708SDavid Chisnall}; 10767a984708SDavid Chisnall 107794e3ee44SDavid Chisnalltemplate<class _Rp, class _A0, class _A1> 107894e3ee44SDavid Chisnallfunction<_Rp(_A0, _A1)>::function(const function& __f) 10797a984708SDavid Chisnall{ 10807a984708SDavid Chisnall if (__f.__f_ == 0) 10817a984708SDavid Chisnall __f_ = 0; 10827a984708SDavid Chisnall else if (__f.__f_ == (const __base*)&__f.__buf_) 10837a984708SDavid Chisnall { 10847a984708SDavid Chisnall __f_ = (__base*)&__buf_; 10857a984708SDavid Chisnall __f.__f_->__clone(__f_); 10867a984708SDavid Chisnall } 10877a984708SDavid Chisnall else 10887a984708SDavid Chisnall __f_ = __f.__f_->__clone(); 10897a984708SDavid Chisnall} 10907a984708SDavid Chisnall 109194e3ee44SDavid Chisnalltemplate<class _Rp, class _A0, class _A1> 10927a984708SDavid Chisnalltemplate<class _Alloc> 109394e3ee44SDavid Chisnallfunction<_Rp(_A0, _A1)>::function(allocator_arg_t, const _Alloc&, const function& __f) 10947a984708SDavid Chisnall{ 10957a984708SDavid Chisnall if (__f.__f_ == 0) 10967a984708SDavid Chisnall __f_ = 0; 10977a984708SDavid Chisnall else if (__f.__f_ == (const __base*)&__f.__buf_) 10987a984708SDavid Chisnall { 10997a984708SDavid Chisnall __f_ = (__base*)&__buf_; 11007a984708SDavid Chisnall __f.__f_->__clone(__f_); 11017a984708SDavid Chisnall } 11027a984708SDavid Chisnall else 11037a984708SDavid Chisnall __f_ = __f.__f_->__clone(); 11047a984708SDavid Chisnall} 11057a984708SDavid Chisnall 110694e3ee44SDavid Chisnalltemplate<class _Rp, class _A0, class _A1> 110794e3ee44SDavid Chisnalltemplate <class _Fp> 110894e3ee44SDavid Chisnallfunction<_Rp(_A0, _A1)>::function(_Fp __f, 110994e3ee44SDavid Chisnall typename enable_if<!is_integral<_Fp>::value>::type*) 11107a984708SDavid Chisnall : __f_(0) 11117a984708SDavid Chisnall{ 11129729cf09SDimitry Andric if (__function::__not_null(__f)) 11137a984708SDavid Chisnall { 111494e3ee44SDavid Chisnall typedef __function::__func<_Fp, allocator<_Fp>, _Rp(_A0, _A1)> _FF; 11157a984708SDavid Chisnall if (sizeof(_FF) <= sizeof(__buf_)) 11167a984708SDavid Chisnall { 11177a984708SDavid Chisnall __f_ = (__base*)&__buf_; 11187a984708SDavid Chisnall ::new (__f_) _FF(__f); 11197a984708SDavid Chisnall } 11207a984708SDavid Chisnall else 11217a984708SDavid Chisnall { 112294e3ee44SDavid Chisnall typedef allocator<_FF> _Ap; 112394e3ee44SDavid Chisnall _Ap __a; 112494e3ee44SDavid Chisnall typedef __allocator_destructor<_Ap> _Dp; 112594e3ee44SDavid Chisnall unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1)); 112694e3ee44SDavid Chisnall ::new (__hold.get()) _FF(__f, allocator<_Fp>(__a)); 11277a984708SDavid Chisnall __f_ = __hold.release(); 11287a984708SDavid Chisnall } 11297a984708SDavid Chisnall } 11307a984708SDavid Chisnall} 11317a984708SDavid Chisnall 113294e3ee44SDavid Chisnalltemplate<class _Rp, class _A0, class _A1> 113394e3ee44SDavid Chisnalltemplate <class _Fp, class _Alloc> 113494e3ee44SDavid Chisnallfunction<_Rp(_A0, _A1)>::function(allocator_arg_t, const _Alloc& __a0, _Fp __f, 113594e3ee44SDavid Chisnall typename enable_if<!is_integral<_Fp>::value>::type*) 11367a984708SDavid Chisnall : __f_(0) 11377a984708SDavid Chisnall{ 11387a984708SDavid Chisnall typedef allocator_traits<_Alloc> __alloc_traits; 11399729cf09SDimitry Andric if (__function::__not_null(__f)) 11407a984708SDavid Chisnall { 114194e3ee44SDavid Chisnall typedef __function::__func<_Fp, _Alloc, _Rp(_A0, _A1)> _FF; 11427a984708SDavid Chisnall if (sizeof(_FF) <= sizeof(__buf_)) 11437a984708SDavid Chisnall { 11447a984708SDavid Chisnall __f_ = (__base*)&__buf_; 1145854fa44bSDimitry Andric ::new (__f_) _FF(__f, __a0); 11467a984708SDavid Chisnall } 11477a984708SDavid Chisnall else 11487a984708SDavid Chisnall { 1149854fa44bSDimitry Andric typedef typename __rebind_alloc_helper<__alloc_traits, _FF>::type _Ap; 115094e3ee44SDavid Chisnall _Ap __a(__a0); 115194e3ee44SDavid Chisnall typedef __allocator_destructor<_Ap> _Dp; 115294e3ee44SDavid Chisnall unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1)); 11537a984708SDavid Chisnall ::new (__hold.get()) _FF(__f, _Alloc(__a)); 11547a984708SDavid Chisnall __f_ = __hold.release(); 11557a984708SDavid Chisnall } 11567a984708SDavid Chisnall } 11577a984708SDavid Chisnall} 11587a984708SDavid Chisnall 115994e3ee44SDavid Chisnalltemplate<class _Rp, class _A0, class _A1> 116094e3ee44SDavid Chisnallfunction<_Rp(_A0, _A1)>& 116194e3ee44SDavid Chisnallfunction<_Rp(_A0, _A1)>::operator=(const function& __f) 11627a984708SDavid Chisnall{ 1163*4ba319b5SDimitry Andric if (__f) 11647a984708SDavid Chisnall function(__f).swap(*this); 1165*4ba319b5SDimitry Andric else 1166*4ba319b5SDimitry Andric *this = nullptr; 11677a984708SDavid Chisnall return *this; 11687a984708SDavid Chisnall} 11697a984708SDavid Chisnall 117094e3ee44SDavid Chisnalltemplate<class _Rp, class _A0, class _A1> 117194e3ee44SDavid Chisnallfunction<_Rp(_A0, _A1)>& 117294e3ee44SDavid Chisnallfunction<_Rp(_A0, _A1)>::operator=(nullptr_t) 11737a984708SDavid Chisnall{ 1174*4ba319b5SDimitry Andric __base* __t = __f_; 11757a984708SDavid Chisnall __f_ = 0; 1176*4ba319b5SDimitry Andric if (__t == (__base*)&__buf_) 1177*4ba319b5SDimitry Andric __t->destroy(); 1178*4ba319b5SDimitry Andric else if (__t) 1179*4ba319b5SDimitry Andric __t->destroy_deallocate(); 1180854fa44bSDimitry Andric return *this; 11817a984708SDavid Chisnall} 11827a984708SDavid Chisnall 118394e3ee44SDavid Chisnalltemplate<class _Rp, class _A0, class _A1> 118494e3ee44SDavid Chisnalltemplate <class _Fp> 11857a984708SDavid Chisnalltypename enable_if 11867a984708SDavid Chisnall< 118794e3ee44SDavid Chisnall !is_integral<_Fp>::value, 118894e3ee44SDavid Chisnall function<_Rp(_A0, _A1)>& 11897a984708SDavid Chisnall>::type 119094e3ee44SDavid Chisnallfunction<_Rp(_A0, _A1)>::operator=(_Fp __f) 11917a984708SDavid Chisnall{ 11927a984708SDavid Chisnall function(_VSTD::move(__f)).swap(*this); 11937a984708SDavid Chisnall return *this; 11947a984708SDavid Chisnall} 11957a984708SDavid Chisnall 119694e3ee44SDavid Chisnalltemplate<class _Rp, class _A0, class _A1> 119794e3ee44SDavid Chisnallfunction<_Rp(_A0, _A1)>::~function() 11987a984708SDavid Chisnall{ 11997a984708SDavid Chisnall if (__f_ == (__base*)&__buf_) 12007a984708SDavid Chisnall __f_->destroy(); 12017a984708SDavid Chisnall else if (__f_) 12027a984708SDavid Chisnall __f_->destroy_deallocate(); 12037a984708SDavid Chisnall} 12047a984708SDavid Chisnall 120594e3ee44SDavid Chisnalltemplate<class _Rp, class _A0, class _A1> 12067a984708SDavid Chisnallvoid 120794e3ee44SDavid Chisnallfunction<_Rp(_A0, _A1)>::swap(function& __f) 12087a984708SDavid Chisnall{ 1209aed8d94eSDimitry Andric if (_VSTD::addressof(__f) == this) 1210aed8d94eSDimitry Andric return; 12117a984708SDavid Chisnall if (__f_ == (__base*)&__buf_ && __f.__f_ == (__base*)&__f.__buf_) 12127a984708SDavid Chisnall { 12137a984708SDavid Chisnall typename aligned_storage<sizeof(__buf_)>::type __tempbuf; 12147a984708SDavid Chisnall __base* __t = (__base*)&__tempbuf; 12157a984708SDavid Chisnall __f_->__clone(__t); 12167a984708SDavid Chisnall __f_->destroy(); 12177a984708SDavid Chisnall __f_ = 0; 12187a984708SDavid Chisnall __f.__f_->__clone((__base*)&__buf_); 12197a984708SDavid Chisnall __f.__f_->destroy(); 12207a984708SDavid Chisnall __f.__f_ = 0; 12217a984708SDavid Chisnall __f_ = (__base*)&__buf_; 12227a984708SDavid Chisnall __t->__clone((__base*)&__f.__buf_); 12237a984708SDavid Chisnall __t->destroy(); 12247a984708SDavid Chisnall __f.__f_ = (__base*)&__f.__buf_; 12257a984708SDavid Chisnall } 12267a984708SDavid Chisnall else if (__f_ == (__base*)&__buf_) 12277a984708SDavid Chisnall { 12287a984708SDavid Chisnall __f_->__clone((__base*)&__f.__buf_); 12297a984708SDavid Chisnall __f_->destroy(); 12307a984708SDavid Chisnall __f_ = __f.__f_; 12317a984708SDavid Chisnall __f.__f_ = (__base*)&__f.__buf_; 12327a984708SDavid Chisnall } 12337a984708SDavid Chisnall else if (__f.__f_ == (__base*)&__f.__buf_) 12347a984708SDavid Chisnall { 12357a984708SDavid Chisnall __f.__f_->__clone((__base*)&__buf_); 12367a984708SDavid Chisnall __f.__f_->destroy(); 12377a984708SDavid Chisnall __f.__f_ = __f_; 12387a984708SDavid Chisnall __f_ = (__base*)&__buf_; 12397a984708SDavid Chisnall } 12407a984708SDavid Chisnall else 12417a984708SDavid Chisnall _VSTD::swap(__f_, __f.__f_); 12427a984708SDavid Chisnall} 12437a984708SDavid Chisnall 124494e3ee44SDavid Chisnalltemplate<class _Rp, class _A0, class _A1> 124594e3ee44SDavid Chisnall_Rp 124694e3ee44SDavid Chisnallfunction<_Rp(_A0, _A1)>::operator()(_A0 __a0, _A1 __a1) const 12477a984708SDavid Chisnall{ 12487a984708SDavid Chisnall if (__f_ == 0) 1249aed8d94eSDimitry Andric __throw_bad_function_call(); 12507a984708SDavid Chisnall return (*__f_)(__a0, __a1); 12517a984708SDavid Chisnall} 12527a984708SDavid Chisnall 12537a984708SDavid Chisnall#ifndef _LIBCPP_NO_RTTI 12547a984708SDavid Chisnall 125594e3ee44SDavid Chisnalltemplate<class _Rp, class _A0, class _A1> 12567a984708SDavid Chisnallconst std::type_info& 125794e3ee44SDavid Chisnallfunction<_Rp(_A0, _A1)>::target_type() const 12587a984708SDavid Chisnall{ 12597a984708SDavid Chisnall if (__f_ == 0) 12607a984708SDavid Chisnall return typeid(void); 12617a984708SDavid Chisnall return __f_->target_type(); 12627a984708SDavid Chisnall} 12637a984708SDavid Chisnall 126494e3ee44SDavid Chisnalltemplate<class _Rp, class _A0, class _A1> 126594e3ee44SDavid Chisnalltemplate <typename _Tp> 126694e3ee44SDavid Chisnall_Tp* 126794e3ee44SDavid Chisnallfunction<_Rp(_A0, _A1)>::target() 12687a984708SDavid Chisnall{ 12697a984708SDavid Chisnall if (__f_ == 0) 127094e3ee44SDavid Chisnall return (_Tp*)0; 127124d58133SDimitry Andric return (_Tp*) const_cast<void *>(__f_->target(typeid(_Tp))); 12727a984708SDavid Chisnall} 12737a984708SDavid Chisnall 127494e3ee44SDavid Chisnalltemplate<class _Rp, class _A0, class _A1> 127594e3ee44SDavid Chisnalltemplate <typename _Tp> 127694e3ee44SDavid Chisnallconst _Tp* 127794e3ee44SDavid Chisnallfunction<_Rp(_A0, _A1)>::target() const 12787a984708SDavid Chisnall{ 12797a984708SDavid Chisnall if (__f_ == 0) 128094e3ee44SDavid Chisnall return (const _Tp*)0; 128194e3ee44SDavid Chisnall return (const _Tp*)__f_->target(typeid(_Tp)); 12827a984708SDavid Chisnall} 12837a984708SDavid Chisnall 12847a984708SDavid Chisnall#endif // _LIBCPP_NO_RTTI 12857a984708SDavid Chisnall 128694e3ee44SDavid Chisnalltemplate<class _Rp, class _A0, class _A1, class _A2> 1287aed8d94eSDimitry Andricclass _LIBCPP_TEMPLATE_VIS function<_Rp(_A0, _A1, _A2)> 12887a984708SDavid Chisnall{ 128994e3ee44SDavid Chisnall typedef __function::__base<_Rp(_A0, _A1, _A2)> __base; 12907a984708SDavid Chisnall aligned_storage<3*sizeof(void*)>::type __buf_; 12917a984708SDavid Chisnall __base* __f_; 12927a984708SDavid Chisnall 12937a984708SDavid Chisnallpublic: 129494e3ee44SDavid Chisnall typedef _Rp result_type; 12957a984708SDavid Chisnall 12967a984708SDavid Chisnall // 20.7.16.2.1, construct/copy/destroy: 12977a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY explicit function() : __f_(0) {} 12987a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY function(nullptr_t) : __f_(0) {} 12997a984708SDavid Chisnall function(const function&); 130094e3ee44SDavid Chisnall template<class _Fp> 130194e3ee44SDavid Chisnall function(_Fp, 130294e3ee44SDavid Chisnall typename enable_if<!is_integral<_Fp>::value>::type* = 0); 13037a984708SDavid Chisnall 13047a984708SDavid Chisnall template<class _Alloc> 13057a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY 13067a984708SDavid Chisnall function(allocator_arg_t, const _Alloc&) : __f_(0) {} 13077a984708SDavid Chisnall template<class _Alloc> 13087a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY 13097a984708SDavid Chisnall function(allocator_arg_t, const _Alloc&, nullptr_t) : __f_(0) {} 13107a984708SDavid Chisnall template<class _Alloc> 13117a984708SDavid Chisnall function(allocator_arg_t, const _Alloc&, const function&); 131294e3ee44SDavid Chisnall template<class _Fp, class _Alloc> 131394e3ee44SDavid Chisnall function(allocator_arg_t, const _Alloc& __a, _Fp __f, 131494e3ee44SDavid Chisnall typename enable_if<!is_integral<_Fp>::value>::type* = 0); 13157a984708SDavid Chisnall 13167a984708SDavid Chisnall function& operator=(const function&); 13177a984708SDavid Chisnall function& operator=(nullptr_t); 131894e3ee44SDavid Chisnall template<class _Fp> 13197a984708SDavid Chisnall typename enable_if 13207a984708SDavid Chisnall < 132194e3ee44SDavid Chisnall !is_integral<_Fp>::value, 13227a984708SDavid Chisnall function& 13237a984708SDavid Chisnall >::type 132494e3ee44SDavid Chisnall operator=(_Fp); 13257a984708SDavid Chisnall 13267a984708SDavid Chisnall ~function(); 13277a984708SDavid Chisnall 13287a984708SDavid Chisnall // 20.7.16.2.2, function modifiers: 13297a984708SDavid Chisnall void swap(function&); 133094e3ee44SDavid Chisnall template<class _Fp, class _Alloc> 13317a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY 133294e3ee44SDavid Chisnall void assign(_Fp __f, const _Alloc& __a) 13337a984708SDavid Chisnall {function(allocator_arg, __a, __f).swap(*this);} 13347a984708SDavid Chisnall 13357a984708SDavid Chisnall // 20.7.16.2.3, function capacity: 13367a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY operator bool() const {return __f_;} 13377a984708SDavid Chisnall 13387a984708SDavid Chisnallprivate: 13397a984708SDavid Chisnall // deleted overloads close possible hole in the type system 13407a984708SDavid Chisnall template<class _R2, class _B0, class _B1, class _B2> 13417a984708SDavid Chisnall bool operator==(const function<_R2(_B0, _B1, _B2)>&) const;// = delete; 13427a984708SDavid Chisnall template<class _R2, class _B0, class _B1, class _B2> 13437a984708SDavid Chisnall bool operator!=(const function<_R2(_B0, _B1, _B2)>&) const;// = delete; 13447a984708SDavid Chisnallpublic: 13457a984708SDavid Chisnall // 20.7.16.2.4, function invocation: 134694e3ee44SDavid Chisnall _Rp operator()(_A0, _A1, _A2) const; 13477a984708SDavid Chisnall 13487a984708SDavid Chisnall#ifndef _LIBCPP_NO_RTTI 13497a984708SDavid Chisnall // 20.7.16.2.5, function target access: 13507a984708SDavid Chisnall const std::type_info& target_type() const; 135194e3ee44SDavid Chisnall template <typename _Tp> _Tp* target(); 135294e3ee44SDavid Chisnall template <typename _Tp> const _Tp* target() const; 13537a984708SDavid Chisnall#endif // _LIBCPP_NO_RTTI 13547a984708SDavid Chisnall}; 13557a984708SDavid Chisnall 135694e3ee44SDavid Chisnalltemplate<class _Rp, class _A0, class _A1, class _A2> 135794e3ee44SDavid Chisnallfunction<_Rp(_A0, _A1, _A2)>::function(const function& __f) 13587a984708SDavid Chisnall{ 13597a984708SDavid Chisnall if (__f.__f_ == 0) 13607a984708SDavid Chisnall __f_ = 0; 13617a984708SDavid Chisnall else if (__f.__f_ == (const __base*)&__f.__buf_) 13627a984708SDavid Chisnall { 13637a984708SDavid Chisnall __f_ = (__base*)&__buf_; 13647a984708SDavid Chisnall __f.__f_->__clone(__f_); 13657a984708SDavid Chisnall } 13667a984708SDavid Chisnall else 13677a984708SDavid Chisnall __f_ = __f.__f_->__clone(); 13687a984708SDavid Chisnall} 13697a984708SDavid Chisnall 137094e3ee44SDavid Chisnalltemplate<class _Rp, class _A0, class _A1, class _A2> 13717a984708SDavid Chisnalltemplate<class _Alloc> 137294e3ee44SDavid Chisnallfunction<_Rp(_A0, _A1, _A2)>::function(allocator_arg_t, const _Alloc&, 13737a984708SDavid Chisnall const function& __f) 13747a984708SDavid Chisnall{ 13757a984708SDavid Chisnall if (__f.__f_ == 0) 13767a984708SDavid Chisnall __f_ = 0; 13777a984708SDavid Chisnall else if (__f.__f_ == (const __base*)&__f.__buf_) 13787a984708SDavid Chisnall { 13797a984708SDavid Chisnall __f_ = (__base*)&__buf_; 13807a984708SDavid Chisnall __f.__f_->__clone(__f_); 13817a984708SDavid Chisnall } 13827a984708SDavid Chisnall else 13837a984708SDavid Chisnall __f_ = __f.__f_->__clone(); 13847a984708SDavid Chisnall} 13857a984708SDavid Chisnall 138694e3ee44SDavid Chisnalltemplate<class _Rp, class _A0, class _A1, class _A2> 138794e3ee44SDavid Chisnalltemplate <class _Fp> 138894e3ee44SDavid Chisnallfunction<_Rp(_A0, _A1, _A2)>::function(_Fp __f, 138994e3ee44SDavid Chisnall typename enable_if<!is_integral<_Fp>::value>::type*) 13907a984708SDavid Chisnall : __f_(0) 13917a984708SDavid Chisnall{ 13929729cf09SDimitry Andric if (__function::__not_null(__f)) 13937a984708SDavid Chisnall { 139494e3ee44SDavid Chisnall typedef __function::__func<_Fp, allocator<_Fp>, _Rp(_A0, _A1, _A2)> _FF; 13957a984708SDavid Chisnall if (sizeof(_FF) <= sizeof(__buf_)) 13967a984708SDavid Chisnall { 13977a984708SDavid Chisnall __f_ = (__base*)&__buf_; 13987a984708SDavid Chisnall ::new (__f_) _FF(__f); 13997a984708SDavid Chisnall } 14007a984708SDavid Chisnall else 14017a984708SDavid Chisnall { 140294e3ee44SDavid Chisnall typedef allocator<_FF> _Ap; 140394e3ee44SDavid Chisnall _Ap __a; 140494e3ee44SDavid Chisnall typedef __allocator_destructor<_Ap> _Dp; 140594e3ee44SDavid Chisnall unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1)); 140694e3ee44SDavid Chisnall ::new (__hold.get()) _FF(__f, allocator<_Fp>(__a)); 14077a984708SDavid Chisnall __f_ = __hold.release(); 14087a984708SDavid Chisnall } 14097a984708SDavid Chisnall } 14107a984708SDavid Chisnall} 14117a984708SDavid Chisnall 141294e3ee44SDavid Chisnalltemplate<class _Rp, class _A0, class _A1, class _A2> 141394e3ee44SDavid Chisnalltemplate <class _Fp, class _Alloc> 141494e3ee44SDavid Chisnallfunction<_Rp(_A0, _A1, _A2)>::function(allocator_arg_t, const _Alloc& __a0, _Fp __f, 141594e3ee44SDavid Chisnall typename enable_if<!is_integral<_Fp>::value>::type*) 14167a984708SDavid Chisnall : __f_(0) 14177a984708SDavid Chisnall{ 14187a984708SDavid Chisnall typedef allocator_traits<_Alloc> __alloc_traits; 14199729cf09SDimitry Andric if (__function::__not_null(__f)) 14207a984708SDavid Chisnall { 142194e3ee44SDavid Chisnall typedef __function::__func<_Fp, _Alloc, _Rp(_A0, _A1, _A2)> _FF; 14227a984708SDavid Chisnall if (sizeof(_FF) <= sizeof(__buf_)) 14237a984708SDavid Chisnall { 14247a984708SDavid Chisnall __f_ = (__base*)&__buf_; 1425854fa44bSDimitry Andric ::new (__f_) _FF(__f, __a0); 14267a984708SDavid Chisnall } 14277a984708SDavid Chisnall else 14287a984708SDavid Chisnall { 1429854fa44bSDimitry Andric typedef typename __rebind_alloc_helper<__alloc_traits, _FF>::type _Ap; 143094e3ee44SDavid Chisnall _Ap __a(__a0); 143194e3ee44SDavid Chisnall typedef __allocator_destructor<_Ap> _Dp; 143294e3ee44SDavid Chisnall unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1)); 14337a984708SDavid Chisnall ::new (__hold.get()) _FF(__f, _Alloc(__a)); 14347a984708SDavid Chisnall __f_ = __hold.release(); 14357a984708SDavid Chisnall } 14367a984708SDavid Chisnall } 14377a984708SDavid Chisnall} 14387a984708SDavid Chisnall 143994e3ee44SDavid Chisnalltemplate<class _Rp, class _A0, class _A1, class _A2> 144094e3ee44SDavid Chisnallfunction<_Rp(_A0, _A1, _A2)>& 144194e3ee44SDavid Chisnallfunction<_Rp(_A0, _A1, _A2)>::operator=(const function& __f) 14427a984708SDavid Chisnall{ 1443*4ba319b5SDimitry Andric if (__f) 14447a984708SDavid Chisnall function(__f).swap(*this); 1445*4ba319b5SDimitry Andric else 1446*4ba319b5SDimitry Andric *this = nullptr; 14477a984708SDavid Chisnall return *this; 14487a984708SDavid Chisnall} 14497a984708SDavid Chisnall 145094e3ee44SDavid Chisnalltemplate<class _Rp, class _A0, class _A1, class _A2> 145194e3ee44SDavid Chisnallfunction<_Rp(_A0, _A1, _A2)>& 145294e3ee44SDavid Chisnallfunction<_Rp(_A0, _A1, _A2)>::operator=(nullptr_t) 14537a984708SDavid Chisnall{ 1454*4ba319b5SDimitry Andric __base* __t = __f_; 14557a984708SDavid Chisnall __f_ = 0; 1456*4ba319b5SDimitry Andric if (__t == (__base*)&__buf_) 1457*4ba319b5SDimitry Andric __t->destroy(); 1458*4ba319b5SDimitry Andric else if (__t) 1459*4ba319b5SDimitry Andric __t->destroy_deallocate(); 1460854fa44bSDimitry Andric return *this; 14617a984708SDavid Chisnall} 14627a984708SDavid Chisnall 146394e3ee44SDavid Chisnalltemplate<class _Rp, class _A0, class _A1, class _A2> 146494e3ee44SDavid Chisnalltemplate <class _Fp> 14657a984708SDavid Chisnalltypename enable_if 14667a984708SDavid Chisnall< 146794e3ee44SDavid Chisnall !is_integral<_Fp>::value, 146894e3ee44SDavid Chisnall function<_Rp(_A0, _A1, _A2)>& 14697a984708SDavid Chisnall>::type 147094e3ee44SDavid Chisnallfunction<_Rp(_A0, _A1, _A2)>::operator=(_Fp __f) 14717a984708SDavid Chisnall{ 14727a984708SDavid Chisnall function(_VSTD::move(__f)).swap(*this); 14737a984708SDavid Chisnall return *this; 14747a984708SDavid Chisnall} 14757a984708SDavid Chisnall 147694e3ee44SDavid Chisnalltemplate<class _Rp, class _A0, class _A1, class _A2> 147794e3ee44SDavid Chisnallfunction<_Rp(_A0, _A1, _A2)>::~function() 14787a984708SDavid Chisnall{ 14797a984708SDavid Chisnall if (__f_ == (__base*)&__buf_) 14807a984708SDavid Chisnall __f_->destroy(); 14817a984708SDavid Chisnall else if (__f_) 14827a984708SDavid Chisnall __f_->destroy_deallocate(); 14837a984708SDavid Chisnall} 14847a984708SDavid Chisnall 148594e3ee44SDavid Chisnalltemplate<class _Rp, class _A0, class _A1, class _A2> 14867a984708SDavid Chisnallvoid 148794e3ee44SDavid Chisnallfunction<_Rp(_A0, _A1, _A2)>::swap(function& __f) 14887a984708SDavid Chisnall{ 1489aed8d94eSDimitry Andric if (_VSTD::addressof(__f) == this) 1490aed8d94eSDimitry Andric return; 14917a984708SDavid Chisnall if (__f_ == (__base*)&__buf_ && __f.__f_ == (__base*)&__f.__buf_) 14927a984708SDavid Chisnall { 14937a984708SDavid Chisnall typename aligned_storage<sizeof(__buf_)>::type __tempbuf; 14947a984708SDavid Chisnall __base* __t = (__base*)&__tempbuf; 14957a984708SDavid Chisnall __f_->__clone(__t); 14967a984708SDavid Chisnall __f_->destroy(); 14977a984708SDavid Chisnall __f_ = 0; 14987a984708SDavid Chisnall __f.__f_->__clone((__base*)&__buf_); 14997a984708SDavid Chisnall __f.__f_->destroy(); 15007a984708SDavid Chisnall __f.__f_ = 0; 15017a984708SDavid Chisnall __f_ = (__base*)&__buf_; 15027a984708SDavid Chisnall __t->__clone((__base*)&__f.__buf_); 15037a984708SDavid Chisnall __t->destroy(); 15047a984708SDavid Chisnall __f.__f_ = (__base*)&__f.__buf_; 15057a984708SDavid Chisnall } 15067a984708SDavid Chisnall else if (__f_ == (__base*)&__buf_) 15077a984708SDavid Chisnall { 15087a984708SDavid Chisnall __f_->__clone((__base*)&__f.__buf_); 15097a984708SDavid Chisnall __f_->destroy(); 15107a984708SDavid Chisnall __f_ = __f.__f_; 15117a984708SDavid Chisnall __f.__f_ = (__base*)&__f.__buf_; 15127a984708SDavid Chisnall } 15137a984708SDavid Chisnall else if (__f.__f_ == (__base*)&__f.__buf_) 15147a984708SDavid Chisnall { 15157a984708SDavid Chisnall __f.__f_->__clone((__base*)&__buf_); 15167a984708SDavid Chisnall __f.__f_->destroy(); 15177a984708SDavid Chisnall __f.__f_ = __f_; 15187a984708SDavid Chisnall __f_ = (__base*)&__buf_; 15197a984708SDavid Chisnall } 15207a984708SDavid Chisnall else 15217a984708SDavid Chisnall _VSTD::swap(__f_, __f.__f_); 15227a984708SDavid Chisnall} 15237a984708SDavid Chisnall 152494e3ee44SDavid Chisnalltemplate<class _Rp, class _A0, class _A1, class _A2> 152594e3ee44SDavid Chisnall_Rp 152694e3ee44SDavid Chisnallfunction<_Rp(_A0, _A1, _A2)>::operator()(_A0 __a0, _A1 __a1, _A2 __a2) const 15277a984708SDavid Chisnall{ 15287a984708SDavid Chisnall if (__f_ == 0) 1529aed8d94eSDimitry Andric __throw_bad_function_call(); 15307a984708SDavid Chisnall return (*__f_)(__a0, __a1, __a2); 15317a984708SDavid Chisnall} 15327a984708SDavid Chisnall 15337a984708SDavid Chisnall#ifndef _LIBCPP_NO_RTTI 15347a984708SDavid Chisnall 153594e3ee44SDavid Chisnalltemplate<class _Rp, class _A0, class _A1, class _A2> 15367a984708SDavid Chisnallconst std::type_info& 153794e3ee44SDavid Chisnallfunction<_Rp(_A0, _A1, _A2)>::target_type() const 15387a984708SDavid Chisnall{ 15397a984708SDavid Chisnall if (__f_ == 0) 15407a984708SDavid Chisnall return typeid(void); 15417a984708SDavid Chisnall return __f_->target_type(); 15427a984708SDavid Chisnall} 15437a984708SDavid Chisnall 154494e3ee44SDavid Chisnalltemplate<class _Rp, class _A0, class _A1, class _A2> 154594e3ee44SDavid Chisnalltemplate <typename _Tp> 154694e3ee44SDavid Chisnall_Tp* 154794e3ee44SDavid Chisnallfunction<_Rp(_A0, _A1, _A2)>::target() 15487a984708SDavid Chisnall{ 15497a984708SDavid Chisnall if (__f_ == 0) 155094e3ee44SDavid Chisnall return (_Tp*)0; 155124d58133SDimitry Andric return (_Tp*) const_cast<void *>(__f_->target(typeid(_Tp))); 15527a984708SDavid Chisnall} 15537a984708SDavid Chisnall 155494e3ee44SDavid Chisnalltemplate<class _Rp, class _A0, class _A1, class _A2> 155594e3ee44SDavid Chisnalltemplate <typename _Tp> 155694e3ee44SDavid Chisnallconst _Tp* 155794e3ee44SDavid Chisnallfunction<_Rp(_A0, _A1, _A2)>::target() const 15587a984708SDavid Chisnall{ 15597a984708SDavid Chisnall if (__f_ == 0) 156094e3ee44SDavid Chisnall return (const _Tp*)0; 156194e3ee44SDavid Chisnall return (const _Tp*)__f_->target(typeid(_Tp)); 15627a984708SDavid Chisnall} 15637a984708SDavid Chisnall 15647a984708SDavid Chisnall#endif // _LIBCPP_NO_RTTI 15657a984708SDavid Chisnall 156694e3ee44SDavid Chisnalltemplate <class _Fp> 15677a984708SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY 15687a984708SDavid Chisnallbool 156994e3ee44SDavid Chisnalloperator==(const function<_Fp>& __f, nullptr_t) {return !__f;} 15707a984708SDavid Chisnall 157194e3ee44SDavid Chisnalltemplate <class _Fp> 15727a984708SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY 15737a984708SDavid Chisnallbool 157494e3ee44SDavid Chisnalloperator==(nullptr_t, const function<_Fp>& __f) {return !__f;} 15757a984708SDavid Chisnall 157694e3ee44SDavid Chisnalltemplate <class _Fp> 15777a984708SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY 15787a984708SDavid Chisnallbool 157994e3ee44SDavid Chisnalloperator!=(const function<_Fp>& __f, nullptr_t) {return (bool)__f;} 15807a984708SDavid Chisnall 158194e3ee44SDavid Chisnalltemplate <class _Fp> 15827a984708SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY 15837a984708SDavid Chisnallbool 158494e3ee44SDavid Chisnalloperator!=(nullptr_t, const function<_Fp>& __f) {return (bool)__f;} 15857a984708SDavid Chisnall 158694e3ee44SDavid Chisnalltemplate <class _Fp> 15877a984708SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY 15887a984708SDavid Chisnallvoid 158994e3ee44SDavid Chisnallswap(function<_Fp>& __x, function<_Fp>& __y) 15907a984708SDavid Chisnall{return __x.swap(__y);} 15917a984708SDavid Chisnall 15927a984708SDavid Chisnall#endif // _LIBCPP_FUNCTIONAL_03 1593