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