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