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