// -*- C++ -*- //===----------------------------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// #ifndef _LIBCPP___FUNCTIONAL_FUNCTION_H #define _LIBCPP___FUNCTIONAL_FUNCTION_H #include <__assert> #include <__config> #include <__functional/binary_function.h> #include <__functional/invoke.h> #include <__functional/unary_function.h> #include <__iterator/iterator_traits.h> #include <__memory/addressof.h> #include <__memory/allocator_traits.h> #include <__memory/compressed_pair.h> #include <__memory/shared_ptr.h> #include <__utility/forward.h> #include <__utility/move.h> #include <__utility/swap.h> #include #include // TODO: replace with <__memory/__builtin_new_allocator.h> #include #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) # pragma GCC system_header #endif _LIBCPP_BEGIN_NAMESPACE_STD // bad_function_call _LIBCPP_DIAGNOSTIC_PUSH _LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wweak-vtables") class _LIBCPP_EXCEPTION_ABI bad_function_call : public exception { public: // Note that when a key function is not used, every translation unit that uses // bad_function_call will end up containing a weak definition of the vtable and // typeinfo. #ifdef _LIBCPP_ABI_BAD_FUNCTION_CALL_KEY_FUNCTION virtual ~bad_function_call() _NOEXCEPT; #else virtual ~bad_function_call() _NOEXCEPT {} #endif #ifdef _LIBCPP_ABI_BAD_FUNCTION_CALL_GOOD_WHAT_MESSAGE virtual const char* what() const _NOEXCEPT; #endif }; _LIBCPP_DIAGNOSTIC_POP _LIBCPP_NORETURN inline _LIBCPP_INLINE_VISIBILITY void __throw_bad_function_call() { #ifndef _LIBCPP_NO_EXCEPTIONS throw bad_function_call(); #else _VSTD::abort(); #endif } #if defined(_LIBCPP_CXX03_LANG) && !defined(_LIBCPP_DISABLE_DEPRECATION_WARNINGS) && __has_attribute(deprecated) # define _LIBCPP_DEPRECATED_CXX03_FUNCTION \ __attribute__((deprecated("Using std::function in C++03 is not supported anymore. Please upgrade to C++11 or later, or use a different type"))) #else # define _LIBCPP_DEPRECATED_CXX03_FUNCTION /* nothing */ #endif template class _LIBCPP_DEPRECATED_CXX03_FUNCTION _LIBCPP_TEMPLATE_VIS function; // undefined namespace __function { template struct __maybe_derive_from_unary_function { }; template struct __maybe_derive_from_unary_function<_Rp(_A1)> : public __unary_function<_A1, _Rp> { }; template struct __maybe_derive_from_binary_function { }; template struct __maybe_derive_from_binary_function<_Rp(_A1, _A2)> : public __binary_function<_A1, _A2, _Rp> { }; template _LIBCPP_INLINE_VISIBILITY bool __not_null(_Fp const&) { return true; } template _LIBCPP_INLINE_VISIBILITY bool __not_null(_Fp* __ptr) { return __ptr; } template _LIBCPP_INLINE_VISIBILITY bool __not_null(_Ret _Class::*__ptr) { return __ptr; } template _LIBCPP_INLINE_VISIBILITY bool __not_null(function<_Fp> const& __f) { return !!__f; } #ifdef _LIBCPP_HAS_EXTENSION_BLOCKS template _LIBCPP_INLINE_VISIBILITY bool __not_null(_Rp (^__p)(_Args...)) { return __p; } #endif } // namespace __function #ifndef _LIBCPP_CXX03_LANG namespace __function { // __alloc_func holds a functor and an allocator. template class __alloc_func; template class __default_alloc_func; template class __alloc_func<_Fp, _Ap, _Rp(_ArgTypes...)> { __compressed_pair<_Fp, _Ap> __f_; public: typedef _LIBCPP_NODEBUG _Fp _Target; typedef _LIBCPP_NODEBUG _Ap _Alloc; _LIBCPP_INLINE_VISIBILITY const _Target& __target() const { return __f_.first(); } // WIN32 APIs may define __allocator, so use __get_allocator instead. _LIBCPP_INLINE_VISIBILITY const _Alloc& __get_allocator() const { return __f_.second(); } _LIBCPP_INLINE_VISIBILITY explicit __alloc_func(_Target&& __f) : __f_(piecewise_construct, _VSTD::forward_as_tuple(_VSTD::move(__f)), _VSTD::forward_as_tuple()) { } _LIBCPP_INLINE_VISIBILITY explicit __alloc_func(const _Target& __f, const _Alloc& __a) : __f_(piecewise_construct, _VSTD::forward_as_tuple(__f), _VSTD::forward_as_tuple(__a)) { } _LIBCPP_INLINE_VISIBILITY explicit __alloc_func(const _Target& __f, _Alloc&& __a) : __f_(piecewise_construct, _VSTD::forward_as_tuple(__f), _VSTD::forward_as_tuple(_VSTD::move(__a))) { } _LIBCPP_INLINE_VISIBILITY explicit __alloc_func(_Target&& __f, _Alloc&& __a) : __f_(piecewise_construct, _VSTD::forward_as_tuple(_VSTD::move(__f)), _VSTD::forward_as_tuple(_VSTD::move(__a))) { } _LIBCPP_INLINE_VISIBILITY _Rp operator()(_ArgTypes&&... __arg) { typedef __invoke_void_return_wrapper<_Rp> _Invoker; return _Invoker::__call(__f_.first(), _VSTD::forward<_ArgTypes>(__arg)...); } _LIBCPP_INLINE_VISIBILITY __alloc_func* __clone() const { typedef allocator_traits<_Alloc> __alloc_traits; typedef typename __rebind_alloc_helper<__alloc_traits, __alloc_func>::type _AA; _AA __a(__f_.second()); typedef __allocator_destructor<_AA> _Dp; unique_ptr<__alloc_func, _Dp> __hold(__a.allocate(1), _Dp(__a, 1)); ::new ((void*)__hold.get()) __alloc_func(__f_.first(), _Alloc(__a)); return __hold.release(); } _LIBCPP_INLINE_VISIBILITY void destroy() _NOEXCEPT { __f_.~__compressed_pair<_Target, _Alloc>(); } static void __destroy_and_delete(__alloc_func* __f) { typedef allocator_traits<_Alloc> __alloc_traits; typedef typename __rebind_alloc_helper<__alloc_traits, __alloc_func>::type _FunAlloc; _FunAlloc __a(__f->__get_allocator()); __f->destroy(); __a.deallocate(__f, 1); } }; template class __default_alloc_func<_Fp, _Rp(_ArgTypes...)> { _Fp __f_; public: typedef _LIBCPP_NODEBUG _Fp _Target; _LIBCPP_INLINE_VISIBILITY const _Target& __target() const { return __f_; } _LIBCPP_INLINE_VISIBILITY explicit __default_alloc_func(_Target&& __f) : __f_(_VSTD::move(__f)) {} _LIBCPP_INLINE_VISIBILITY explicit __default_alloc_func(const _Target& __f) : __f_(__f) {} _LIBCPP_INLINE_VISIBILITY _Rp operator()(_ArgTypes&&... __arg) { typedef __invoke_void_return_wrapper<_Rp> _Invoker; return _Invoker::__call(__f_, _VSTD::forward<_ArgTypes>(__arg)...); } _LIBCPP_INLINE_VISIBILITY __default_alloc_func* __clone() const { __builtin_new_allocator::__holder_t __hold = __builtin_new_allocator::__allocate_type<__default_alloc_func>(1); __default_alloc_func* __res = ::new ((void*)__hold.get()) __default_alloc_func(__f_); (void)__hold.release(); return __res; } _LIBCPP_INLINE_VISIBILITY void destroy() _NOEXCEPT { __f_.~_Target(); } static void __destroy_and_delete(__default_alloc_func* __f) { __f->destroy(); __builtin_new_allocator::__deallocate_type<__default_alloc_func>(__f, 1); } }; // __base provides an abstract interface for copyable functors. template class _LIBCPP_TEMPLATE_VIS __base; template class __base<_Rp(_ArgTypes...)> { __base(const __base&); __base& operator=(const __base&); public: _LIBCPP_INLINE_VISIBILITY __base() {} _LIBCPP_INLINE_VISIBILITY virtual ~__base() {} virtual __base* __clone() const = 0; virtual void __clone(__base*) const = 0; virtual void destroy() _NOEXCEPT = 0; virtual void destroy_deallocate() _NOEXCEPT = 0; virtual _Rp operator()(_ArgTypes&& ...) = 0; #ifndef _LIBCPP_NO_RTTI virtual const void* target(const type_info&) const _NOEXCEPT = 0; virtual const std::type_info& target_type() const _NOEXCEPT = 0; #endif // _LIBCPP_NO_RTTI }; // __func implements __base for a given functor type. template class __func; template class __func<_Fp, _Alloc, _Rp(_ArgTypes...)> : public __base<_Rp(_ArgTypes...)> { __alloc_func<_Fp, _Alloc, _Rp(_ArgTypes...)> __f_; public: _LIBCPP_INLINE_VISIBILITY explicit __func(_Fp&& __f) : __f_(_VSTD::move(__f)) {} _LIBCPP_INLINE_VISIBILITY explicit __func(const _Fp& __f, const _Alloc& __a) : __f_(__f, __a) {} _LIBCPP_INLINE_VISIBILITY explicit __func(const _Fp& __f, _Alloc&& __a) : __f_(__f, _VSTD::move(__a)) {} _LIBCPP_INLINE_VISIBILITY explicit __func(_Fp&& __f, _Alloc&& __a) : __f_(_VSTD::move(__f), _VSTD::move(__a)) {} virtual __base<_Rp(_ArgTypes...)>* __clone() const; virtual void __clone(__base<_Rp(_ArgTypes...)>*) const; virtual void destroy() _NOEXCEPT; virtual void destroy_deallocate() _NOEXCEPT; virtual _Rp operator()(_ArgTypes&&... __arg); #ifndef _LIBCPP_NO_RTTI virtual const void* target(const type_info&) const _NOEXCEPT; virtual const std::type_info& target_type() const _NOEXCEPT; #endif // _LIBCPP_NO_RTTI }; template __base<_Rp(_ArgTypes...)>* __func<_Fp, _Alloc, _Rp(_ArgTypes...)>::__clone() const { typedef allocator_traits<_Alloc> __alloc_traits; typedef typename __rebind_alloc_helper<__alloc_traits, __func>::type _Ap; _Ap __a(__f_.__get_allocator()); typedef __allocator_destructor<_Ap> _Dp; unique_ptr<__func, _Dp> __hold(__a.allocate(1), _Dp(__a, 1)); ::new ((void*)__hold.get()) __func(__f_.__target(), _Alloc(__a)); return __hold.release(); } template void __func<_Fp, _Alloc, _Rp(_ArgTypes...)>::__clone(__base<_Rp(_ArgTypes...)>* __p) const { ::new ((void*)__p) __func(__f_.__target(), __f_.__get_allocator()); } template void __func<_Fp, _Alloc, _Rp(_ArgTypes...)>::destroy() _NOEXCEPT { __f_.destroy(); } template void __func<_Fp, _Alloc, _Rp(_ArgTypes...)>::destroy_deallocate() _NOEXCEPT { typedef allocator_traits<_Alloc> __alloc_traits; typedef typename __rebind_alloc_helper<__alloc_traits, __func>::type _Ap; _Ap __a(__f_.__get_allocator()); __f_.destroy(); __a.deallocate(this, 1); } template _Rp __func<_Fp, _Alloc, _Rp(_ArgTypes...)>::operator()(_ArgTypes&& ... __arg) { return __f_(_VSTD::forward<_ArgTypes>(__arg)...); } #ifndef _LIBCPP_NO_RTTI template const void* __func<_Fp, _Alloc, _Rp(_ArgTypes...)>::target(const type_info& __ti) const _NOEXCEPT { if (__ti == typeid(_Fp)) return _VSTD::addressof(__f_.__target()); return nullptr; } template const std::type_info& __func<_Fp, _Alloc, _Rp(_ArgTypes...)>::target_type() const _NOEXCEPT { return typeid(_Fp); } #endif // _LIBCPP_NO_RTTI // __value_func creates a value-type from a __func. template class __value_func; template class __value_func<_Rp(_ArgTypes...)> { typename aligned_storage<3 * sizeof(void*)>::type __buf_; typedef __base<_Rp(_ArgTypes...)> __func; __func* __f_; _LIBCPP_NO_CFI static __func* __as_base(void* __p) { return reinterpret_cast<__func*>(__p); } public: _LIBCPP_INLINE_VISIBILITY __value_func() _NOEXCEPT : __f_(nullptr) {} template _LIBCPP_INLINE_VISIBILITY __value_func(_Fp&& __f, const _Alloc& __a) : __f_(nullptr) { typedef allocator_traits<_Alloc> __alloc_traits; typedef __function::__func<_Fp, _Alloc, _Rp(_ArgTypes...)> _Fun; typedef typename __rebind_alloc_helper<__alloc_traits, _Fun>::type _FunAlloc; if (__function::__not_null(__f)) { _FunAlloc __af(__a); if (sizeof(_Fun) <= sizeof(__buf_) && is_nothrow_copy_constructible<_Fp>::value && is_nothrow_copy_constructible<_FunAlloc>::value) { __f_ = ::new ((void*)&__buf_) _Fun(_VSTD::move(__f), _Alloc(__af)); } else { typedef __allocator_destructor<_FunAlloc> _Dp; unique_ptr<__func, _Dp> __hold(__af.allocate(1), _Dp(__af, 1)); ::new ((void*)__hold.get()) _Fun(_VSTD::move(__f), _Alloc(__a)); __f_ = __hold.release(); } } } template ::type, __value_func>::value>::type> _LIBCPP_INLINE_VISIBILITY explicit __value_func(_Fp&& __f) : __value_func(_VSTD::forward<_Fp>(__f), allocator<_Fp>()) {} _LIBCPP_INLINE_VISIBILITY __value_func(const __value_func& __f) { if (__f.__f_ == nullptr) __f_ = nullptr; else if ((void*)__f.__f_ == &__f.__buf_) { __f_ = __as_base(&__buf_); __f.__f_->__clone(__f_); } else __f_ = __f.__f_->__clone(); } _LIBCPP_INLINE_VISIBILITY __value_func(__value_func&& __f) _NOEXCEPT { if (__f.__f_ == nullptr) __f_ = nullptr; else if ((void*)__f.__f_ == &__f.__buf_) { __f_ = __as_base(&__buf_); __f.__f_->__clone(__f_); } else { __f_ = __f.__f_; __f.__f_ = nullptr; } } _LIBCPP_INLINE_VISIBILITY ~__value_func() { if ((void*)__f_ == &__buf_) __f_->destroy(); else if (__f_) __f_->destroy_deallocate(); } _LIBCPP_INLINE_VISIBILITY __value_func& operator=(__value_func&& __f) { *this = nullptr; if (__f.__f_ == nullptr) __f_ = nullptr; else if ((void*)__f.__f_ == &__f.__buf_) { __f_ = __as_base(&__buf_); __f.__f_->__clone(__f_); } else { __f_ = __f.__f_; __f.__f_ = nullptr; } return *this; } _LIBCPP_INLINE_VISIBILITY __value_func& operator=(nullptr_t) { __func* __f = __f_; __f_ = nullptr; if ((void*)__f == &__buf_) __f->destroy(); else if (__f) __f->destroy_deallocate(); return *this; } _LIBCPP_INLINE_VISIBILITY _Rp operator()(_ArgTypes&&... __args) const { if (__f_ == nullptr) __throw_bad_function_call(); return (*__f_)(_VSTD::forward<_ArgTypes>(__args)...); } _LIBCPP_INLINE_VISIBILITY void swap(__value_func& __f) _NOEXCEPT { if (&__f == this) return; if ((void*)__f_ == &__buf_ && (void*)__f.__f_ == &__f.__buf_) { typename aligned_storage::type __tempbuf; __func* __t = __as_base(&__tempbuf); __f_->__clone(__t); __f_->destroy(); __f_ = nullptr; __f.__f_->__clone(__as_base(&__buf_)); __f.__f_->destroy(); __f.__f_ = nullptr; __f_ = __as_base(&__buf_); __t->__clone(__as_base(&__f.__buf_)); __t->destroy(); __f.__f_ = __as_base(&__f.__buf_); } else if ((void*)__f_ == &__buf_) { __f_->__clone(__as_base(&__f.__buf_)); __f_->destroy(); __f_ = __f.__f_; __f.__f_ = __as_base(&__f.__buf_); } else if ((void*)__f.__f_ == &__f.__buf_) { __f.__f_->__clone(__as_base(&__buf_)); __f.__f_->destroy(); __f.__f_ = __f_; __f_ = __as_base(&__buf_); } else _VSTD::swap(__f_, __f.__f_); } _LIBCPP_INLINE_VISIBILITY explicit operator bool() const _NOEXCEPT { return __f_ != nullptr; } #ifndef _LIBCPP_NO_RTTI _LIBCPP_INLINE_VISIBILITY const std::type_info& target_type() const _NOEXCEPT { if (__f_ == nullptr) return typeid(void); return __f_->target_type(); } template _LIBCPP_INLINE_VISIBILITY const _Tp* target() const _NOEXCEPT { if (__f_ == nullptr) return nullptr; return (const _Tp*)__f_->target(typeid(_Tp)); } #endif // _LIBCPP_NO_RTTI }; // Storage for a functor object, to be used with __policy to manage copy and // destruction. union __policy_storage { mutable char __small[sizeof(void*) * 2]; void* __large; }; // True if _Fun can safely be held in __policy_storage.__small. template struct __use_small_storage : public integral_constant< bool, sizeof(_Fun) <= sizeof(__policy_storage) && _LIBCPP_ALIGNOF(_Fun) <= _LIBCPP_ALIGNOF(__policy_storage) && is_trivially_copy_constructible<_Fun>::value && is_trivially_destructible<_Fun>::value> {}; // Policy contains information about how to copy, destroy, and move the // underlying functor. You can think of it as a vtable of sorts. struct __policy { // Used to copy or destroy __large values. null for trivial objects. void* (*const __clone)(const void*); void (*const __destroy)(void*); // True if this is the null policy (no value). const bool __is_null; // The target type. May be null if RTTI is disabled. const std::type_info* const __type_info; // Returns a pointer to a static policy object suitable for the functor // type. template _LIBCPP_INLINE_VISIBILITY static const __policy* __create() { return __choose_policy<_Fun>(__use_small_storage<_Fun>()); } _LIBCPP_INLINE_VISIBILITY static const __policy* __create_empty() { static const _LIBCPP_CONSTEXPR __policy __policy_ = {nullptr, nullptr, true, #ifndef _LIBCPP_NO_RTTI &typeid(void) #else nullptr #endif }; return &__policy_; } private: template static void* __large_clone(const void* __s) { const _Fun* __f = static_cast(__s); return __f->__clone(); } template static void __large_destroy(void* __s) { _Fun::__destroy_and_delete(static_cast<_Fun*>(__s)); } template _LIBCPP_INLINE_VISIBILITY static const __policy* __choose_policy(/* is_small = */ false_type) { static const _LIBCPP_CONSTEXPR __policy __policy_ = { &__large_clone<_Fun>, &__large_destroy<_Fun>, false, #ifndef _LIBCPP_NO_RTTI &typeid(typename _Fun::_Target) #else nullptr #endif }; return &__policy_; } template _LIBCPP_INLINE_VISIBILITY static const __policy* __choose_policy(/* is_small = */ true_type) { static const _LIBCPP_CONSTEXPR __policy __policy_ = { nullptr, nullptr, false, #ifndef _LIBCPP_NO_RTTI &typeid(typename _Fun::_Target) #else nullptr #endif }; return &__policy_; } }; // Used to choose between perfect forwarding or pass-by-value. Pass-by-value is // faster for types that can be passed in registers. template using __fast_forward = typename conditional::value, _Tp, _Tp&&>::type; // __policy_invoker calls an instance of __alloc_func held in __policy_storage. template struct __policy_invoker; template struct __policy_invoker<_Rp(_ArgTypes...)> { typedef _Rp (*__Call)(const __policy_storage*, __fast_forward<_ArgTypes>...); __Call __call_; // Creates an invoker that throws bad_function_call. _LIBCPP_INLINE_VISIBILITY __policy_invoker() : __call_(&__call_empty) {} // Creates an invoker that calls the given instance of __func. template _LIBCPP_INLINE_VISIBILITY static __policy_invoker __create() { return __policy_invoker(&__call_impl<_Fun>); } private: _LIBCPP_INLINE_VISIBILITY explicit __policy_invoker(__Call __c) : __call_(__c) {} static _Rp __call_empty(const __policy_storage*, __fast_forward<_ArgTypes>...) { __throw_bad_function_call(); } template static _Rp __call_impl(const __policy_storage* __buf, __fast_forward<_ArgTypes>... __args) { _Fun* __f = reinterpret_cast<_Fun*>(__use_small_storage<_Fun>::value ? &__buf->__small : __buf->__large); return (*__f)(_VSTD::forward<_ArgTypes>(__args)...); } }; // __policy_func uses a __policy and __policy_invoker to create a type-erased, // copyable functor. template class __policy_func; template class __policy_func<_Rp(_ArgTypes...)> { // Inline storage for small objects. __policy_storage __buf_; // Calls the value stored in __buf_. This could technically be part of // policy, but storing it here eliminates a level of indirection inside // operator(). typedef __function::__policy_invoker<_Rp(_ArgTypes...)> __invoker; __invoker __invoker_; // The policy that describes how to move / copy / destroy __buf_. Never // null, even if the function is empty. const __policy* __policy_; public: _LIBCPP_INLINE_VISIBILITY __policy_func() : __policy_(__policy::__create_empty()) {} template _LIBCPP_INLINE_VISIBILITY __policy_func(_Fp&& __f, const _Alloc& __a) : __policy_(__policy::__create_empty()) { typedef __alloc_func<_Fp, _Alloc, _Rp(_ArgTypes...)> _Fun; typedef allocator_traits<_Alloc> __alloc_traits; typedef typename __rebind_alloc_helper<__alloc_traits, _Fun>::type _FunAlloc; if (__function::__not_null(__f)) { __invoker_ = __invoker::template __create<_Fun>(); __policy_ = __policy::__create<_Fun>(); _FunAlloc __af(__a); if (__use_small_storage<_Fun>()) { ::new ((void*)&__buf_.__small) _Fun(_VSTD::move(__f), _Alloc(__af)); } else { typedef __allocator_destructor<_FunAlloc> _Dp; unique_ptr<_Fun, _Dp> __hold(__af.allocate(1), _Dp(__af, 1)); ::new ((void*)__hold.get()) _Fun(_VSTD::move(__f), _Alloc(__af)); __buf_.__large = __hold.release(); } } } template ::type, __policy_func>::value>::type> _LIBCPP_INLINE_VISIBILITY explicit __policy_func(_Fp&& __f) : __policy_(__policy::__create_empty()) { typedef __default_alloc_func<_Fp, _Rp(_ArgTypes...)> _Fun; if (__function::__not_null(__f)) { __invoker_ = __invoker::template __create<_Fun>(); __policy_ = __policy::__create<_Fun>(); if (__use_small_storage<_Fun>()) { ::new ((void*)&__buf_.__small) _Fun(_VSTD::move(__f)); } else { __builtin_new_allocator::__holder_t __hold = __builtin_new_allocator::__allocate_type<_Fun>(1); __buf_.__large = ::new ((void*)__hold.get()) _Fun(_VSTD::move(__f)); (void)__hold.release(); } } } _LIBCPP_INLINE_VISIBILITY __policy_func(const __policy_func& __f) : __buf_(__f.__buf_), __invoker_(__f.__invoker_), __policy_(__f.__policy_) { if (__policy_->__clone) __buf_.__large = __policy_->__clone(__f.__buf_.__large); } _LIBCPP_INLINE_VISIBILITY __policy_func(__policy_func&& __f) : __buf_(__f.__buf_), __invoker_(__f.__invoker_), __policy_(__f.__policy_) { if (__policy_->__destroy) { __f.__policy_ = __policy::__create_empty(); __f.__invoker_ = __invoker(); } } _LIBCPP_INLINE_VISIBILITY ~__policy_func() { if (__policy_->__destroy) __policy_->__destroy(__buf_.__large); } _LIBCPP_INLINE_VISIBILITY __policy_func& operator=(__policy_func&& __f) { *this = nullptr; __buf_ = __f.__buf_; __invoker_ = __f.__invoker_; __policy_ = __f.__policy_; __f.__policy_ = __policy::__create_empty(); __f.__invoker_ = __invoker(); return *this; } _LIBCPP_INLINE_VISIBILITY __policy_func& operator=(nullptr_t) { const __policy* __p = __policy_; __policy_ = __policy::__create_empty(); __invoker_ = __invoker(); if (__p->__destroy) __p->__destroy(__buf_.__large); return *this; } _LIBCPP_INLINE_VISIBILITY _Rp operator()(_ArgTypes&&... __args) const { return __invoker_.__call_(_VSTD::addressof(__buf_), _VSTD::forward<_ArgTypes>(__args)...); } _LIBCPP_INLINE_VISIBILITY void swap(__policy_func& __f) { _VSTD::swap(__invoker_, __f.__invoker_); _VSTD::swap(__policy_, __f.__policy_); _VSTD::swap(__buf_, __f.__buf_); } _LIBCPP_INLINE_VISIBILITY explicit operator bool() const _NOEXCEPT { return !__policy_->__is_null; } #ifndef _LIBCPP_NO_RTTI _LIBCPP_INLINE_VISIBILITY const std::type_info& target_type() const _NOEXCEPT { return *__policy_->__type_info; } template _LIBCPP_INLINE_VISIBILITY const _Tp* target() const _NOEXCEPT { if (__policy_->__is_null || typeid(_Tp) != *__policy_->__type_info) return nullptr; if (__policy_->__clone) // Out of line storage. return reinterpret_cast(__buf_.__large); else return reinterpret_cast(&__buf_.__small); } #endif // _LIBCPP_NO_RTTI }; #if defined(_LIBCPP_HAS_BLOCKS_RUNTIME) && !defined(_LIBCPP_HAS_OBJC_ARC) extern "C" void *_Block_copy(const void *); extern "C" void _Block_release(const void *); template class __func<_Rp1(^)(_ArgTypes1...), _Alloc, _Rp(_ArgTypes...)> : public __base<_Rp(_ArgTypes...)> { typedef _Rp1(^__block_type)(_ArgTypes1...); __block_type __f_; public: _LIBCPP_INLINE_VISIBILITY explicit __func(__block_type const& __f) : __f_(reinterpret_cast<__block_type>(__f ? _Block_copy(__f) : nullptr)) { } // [TODO] add && to save on a retain _LIBCPP_INLINE_VISIBILITY explicit __func(__block_type __f, const _Alloc& /* unused */) : __f_(reinterpret_cast<__block_type>(__f ? _Block_copy(__f) : nullptr)) { } virtual __base<_Rp(_ArgTypes...)>* __clone() const { _LIBCPP_ASSERT(false, "Block pointers are just pointers, so they should always fit into " "std::function's small buffer optimization. This function should " "never be invoked."); return nullptr; } virtual void __clone(__base<_Rp(_ArgTypes...)>* __p) const { ::new ((void*)__p) __func(__f_); } virtual void destroy() _NOEXCEPT { if (__f_) _Block_release(__f_); __f_ = 0; } virtual void destroy_deallocate() _NOEXCEPT { _LIBCPP_ASSERT(false, "Block pointers are just pointers, so they should always fit into " "std::function's small buffer optimization. This function should " "never be invoked."); } virtual _Rp operator()(_ArgTypes&& ... __arg) { return _VSTD::__invoke(__f_, _VSTD::forward<_ArgTypes>(__arg)...); } #ifndef _LIBCPP_NO_RTTI virtual const void* target(type_info const& __ti) const _NOEXCEPT { if (__ti == typeid(__func::__block_type)) return &__f_; return (const void*)nullptr; } virtual const std::type_info& target_type() const _NOEXCEPT { return typeid(__func::__block_type); } #endif // _LIBCPP_NO_RTTI }; #endif // _LIBCPP_HAS_EXTENSION_BLOCKS && !_LIBCPP_HAS_OBJC_ARC } // namespace __function template class _LIBCPP_TEMPLATE_VIS function<_Rp(_ArgTypes...)> : public __function::__maybe_derive_from_unary_function<_Rp(_ArgTypes...)>, public __function::__maybe_derive_from_binary_function<_Rp(_ArgTypes...)> { #ifndef _LIBCPP_ABI_OPTIMIZED_FUNCTION typedef __function::__value_func<_Rp(_ArgTypes...)> __func; #else typedef __function::__policy_func<_Rp(_ArgTypes...)> __func; #endif __func __f_; template , function>, __invokable<_Fp, _ArgTypes...> >::value> struct __callable; template struct __callable<_Fp, true> { static const bool value = is_void<_Rp>::value || __is_core_convertible::type, _Rp>::value; }; template struct __callable<_Fp, false> { static const bool value = false; }; template using _EnableIfLValueCallable = typename enable_if<__callable<_Fp&>::value>::type; public: typedef _Rp result_type; // construct/copy/destroy: _LIBCPP_INLINE_VISIBILITY function() _NOEXCEPT { } _LIBCPP_INLINE_VISIBILITY function(nullptr_t) _NOEXCEPT {} function(const function&); function(function&&) _NOEXCEPT; template> function(_Fp); #if _LIBCPP_STD_VER <= 14 template _LIBCPP_INLINE_VISIBILITY function(allocator_arg_t, const _Alloc&) _NOEXCEPT {} template _LIBCPP_INLINE_VISIBILITY function(allocator_arg_t, const _Alloc&, nullptr_t) _NOEXCEPT {} template function(allocator_arg_t, const _Alloc&, const function&); template function(allocator_arg_t, const _Alloc&, function&&); template> function(allocator_arg_t, const _Alloc& __a, _Fp __f); #endif function& operator=(const function&); function& operator=(function&&) _NOEXCEPT; function& operator=(nullptr_t) _NOEXCEPT; template::type>> function& operator=(_Fp&&); ~function(); // function modifiers: void swap(function&) _NOEXCEPT; #if _LIBCPP_STD_VER <= 14 template _LIBCPP_INLINE_VISIBILITY void assign(_Fp&& __f, const _Alloc& __a) {function(allocator_arg, __a, _VSTD::forward<_Fp>(__f)).swap(*this);} #endif // function capacity: _LIBCPP_INLINE_VISIBILITY explicit operator bool() const _NOEXCEPT { return static_cast(__f_); } // deleted overloads close possible hole in the type system template bool operator==(const function<_R2(_ArgTypes2...)>&) const = delete; template bool operator!=(const function<_R2(_ArgTypes2...)>&) const = delete; public: // function invocation: _Rp operator()(_ArgTypes...) const; #ifndef _LIBCPP_NO_RTTI // function target access: const std::type_info& target_type() const _NOEXCEPT; template _Tp* target() _NOEXCEPT; template const _Tp* target() const _NOEXCEPT; #endif // _LIBCPP_NO_RTTI }; #if _LIBCPP_STD_VER >= 17 template function(_Rp(*)(_Ap...)) -> function<_Rp(_Ap...)>; template struct __strip_signature; template struct __strip_signature<_Rp (_Gp::*) (_Ap...)> { using type = _Rp(_Ap...); }; template struct __strip_signature<_Rp (_Gp::*) (_Ap...) const> { using type = _Rp(_Ap...); }; template struct __strip_signature<_Rp (_Gp::*) (_Ap...) volatile> { using type = _Rp(_Ap...); }; template struct __strip_signature<_Rp (_Gp::*) (_Ap...) const volatile> { using type = _Rp(_Ap...); }; template struct __strip_signature<_Rp (_Gp::*) (_Ap...) &> { using type = _Rp(_Ap...); }; template struct __strip_signature<_Rp (_Gp::*) (_Ap...) const &> { using type = _Rp(_Ap...); }; template struct __strip_signature<_Rp (_Gp::*) (_Ap...) volatile &> { using type = _Rp(_Ap...); }; template struct __strip_signature<_Rp (_Gp::*) (_Ap...) const volatile &> { using type = _Rp(_Ap...); }; template struct __strip_signature<_Rp (_Gp::*) (_Ap...) noexcept> { using type = _Rp(_Ap...); }; template struct __strip_signature<_Rp (_Gp::*) (_Ap...) const noexcept> { using type = _Rp(_Ap...); }; template struct __strip_signature<_Rp (_Gp::*) (_Ap...) volatile noexcept> { using type = _Rp(_Ap...); }; template struct __strip_signature<_Rp (_Gp::*) (_Ap...) const volatile noexcept> { using type = _Rp(_Ap...); }; template struct __strip_signature<_Rp (_Gp::*) (_Ap...) & noexcept> { using type = _Rp(_Ap...); }; template struct __strip_signature<_Rp (_Gp::*) (_Ap...) const & noexcept> { using type = _Rp(_Ap...); }; template struct __strip_signature<_Rp (_Gp::*) (_Ap...) volatile & noexcept> { using type = _Rp(_Ap...); }; template struct __strip_signature<_Rp (_Gp::*) (_Ap...) const volatile & noexcept> { using type = _Rp(_Ap...); }; template::type> function(_Fp) -> function<_Stripped>; #endif // _LIBCPP_STD_VER >= 17 template function<_Rp(_ArgTypes...)>::function(const function& __f) : __f_(__f.__f_) {} #if _LIBCPP_STD_VER <= 14 template template function<_Rp(_ArgTypes...)>::function(allocator_arg_t, const _Alloc&, const function& __f) : __f_(__f.__f_) {} #endif template function<_Rp(_ArgTypes...)>::function(function&& __f) _NOEXCEPT : __f_(_VSTD::move(__f.__f_)) {} #if _LIBCPP_STD_VER <= 14 template template function<_Rp(_ArgTypes...)>::function(allocator_arg_t, const _Alloc&, function&& __f) : __f_(_VSTD::move(__f.__f_)) {} #endif template template function<_Rp(_ArgTypes...)>::function(_Fp __f) : __f_(_VSTD::move(__f)) {} #if _LIBCPP_STD_VER <= 14 template template function<_Rp(_ArgTypes...)>::function(allocator_arg_t, const _Alloc& __a, _Fp __f) : __f_(_VSTD::move(__f), __a) {} #endif template function<_Rp(_ArgTypes...)>& function<_Rp(_ArgTypes...)>::operator=(const function& __f) { function(__f).swap(*this); return *this; } template function<_Rp(_ArgTypes...)>& function<_Rp(_ArgTypes...)>::operator=(function&& __f) _NOEXCEPT { __f_ = _VSTD::move(__f.__f_); return *this; } template function<_Rp(_ArgTypes...)>& function<_Rp(_ArgTypes...)>::operator=(nullptr_t) _NOEXCEPT { __f_ = nullptr; return *this; } template template function<_Rp(_ArgTypes...)>& function<_Rp(_ArgTypes...)>::operator=(_Fp&& __f) { function(_VSTD::forward<_Fp>(__f)).swap(*this); return *this; } template function<_Rp(_ArgTypes...)>::~function() {} template void function<_Rp(_ArgTypes...)>::swap(function& __f) _NOEXCEPT { __f_.swap(__f.__f_); } template _Rp function<_Rp(_ArgTypes...)>::operator()(_ArgTypes... __arg) const { return __f_(_VSTD::forward<_ArgTypes>(__arg)...); } #ifndef _LIBCPP_NO_RTTI template const std::type_info& function<_Rp(_ArgTypes...)>::target_type() const _NOEXCEPT { return __f_.target_type(); } template template _Tp* function<_Rp(_ArgTypes...)>::target() _NOEXCEPT { return (_Tp*)(__f_.template target<_Tp>()); } template template const _Tp* function<_Rp(_ArgTypes...)>::target() const _NOEXCEPT { return __f_.template target<_Tp>(); } #endif // _LIBCPP_NO_RTTI template inline _LIBCPP_INLINE_VISIBILITY bool operator==(const function<_Rp(_ArgTypes...)>& __f, nullptr_t) _NOEXCEPT {return !__f;} template inline _LIBCPP_INLINE_VISIBILITY bool operator==(nullptr_t, const function<_Rp(_ArgTypes...)>& __f) _NOEXCEPT {return !__f;} template inline _LIBCPP_INLINE_VISIBILITY bool operator!=(const function<_Rp(_ArgTypes...)>& __f, nullptr_t) _NOEXCEPT {return (bool)__f;} template inline _LIBCPP_INLINE_VISIBILITY bool operator!=(nullptr_t, const function<_Rp(_ArgTypes...)>& __f) _NOEXCEPT {return (bool)__f;} template inline _LIBCPP_INLINE_VISIBILITY void swap(function<_Rp(_ArgTypes...)>& __x, function<_Rp(_ArgTypes...)>& __y) _NOEXCEPT {return __x.swap(__y);} #elif defined(_LIBCPP_ENABLE_CXX03_FUNCTION) namespace __function { template class __base; template class __base<_Rp()> { __base(const __base&); __base& operator=(const __base&); public: __base() {} virtual ~__base() {} virtual __base* __clone() const = 0; virtual void __clone(__base*) const = 0; virtual void destroy() = 0; virtual void destroy_deallocate() = 0; virtual _Rp operator()() = 0; #ifndef _LIBCPP_NO_RTTI virtual const void* target(const type_info&) const = 0; virtual const std::type_info& target_type() const = 0; #endif // _LIBCPP_NO_RTTI }; template class __base<_Rp(_A0)> { __base(const __base&); __base& operator=(const __base&); public: __base() {} virtual ~__base() {} virtual __base* __clone() const = 0; virtual void __clone(__base*) const = 0; virtual void destroy() = 0; virtual void destroy_deallocate() = 0; virtual _Rp operator()(_A0) = 0; #ifndef _LIBCPP_NO_RTTI virtual const void* target(const type_info&) const = 0; virtual const std::type_info& target_type() const = 0; #endif // _LIBCPP_NO_RTTI }; template class __base<_Rp(_A0, _A1)> { __base(const __base&); __base& operator=(const __base&); public: __base() {} virtual ~__base() {} virtual __base* __clone() const = 0; virtual void __clone(__base*) const = 0; virtual void destroy() = 0; virtual void destroy_deallocate() = 0; virtual _Rp operator()(_A0, _A1) = 0; #ifndef _LIBCPP_NO_RTTI virtual const void* target(const type_info&) const = 0; virtual const std::type_info& target_type() const = 0; #endif // _LIBCPP_NO_RTTI }; template class __base<_Rp(_A0, _A1, _A2)> { __base(const __base&); __base& operator=(const __base&); public: __base() {} virtual ~__base() {} virtual __base* __clone() const = 0; virtual void __clone(__base*) const = 0; virtual void destroy() = 0; virtual void destroy_deallocate() = 0; virtual _Rp operator()(_A0, _A1, _A2) = 0; #ifndef _LIBCPP_NO_RTTI virtual const void* target(const type_info&) const = 0; virtual const std::type_info& target_type() const = 0; #endif // _LIBCPP_NO_RTTI }; template class __func; template class __func<_Fp, _Alloc, _Rp()> : public __base<_Rp()> { __compressed_pair<_Fp, _Alloc> __f_; public: explicit __func(_Fp __f) : __f_(_VSTD::move(__f), __default_init_tag()) {} explicit __func(_Fp __f, _Alloc __a) : __f_(_VSTD::move(__f), _VSTD::move(__a)) {} virtual __base<_Rp()>* __clone() const; virtual void __clone(__base<_Rp()>*) const; virtual void destroy(); virtual void destroy_deallocate(); virtual _Rp operator()(); #ifndef _LIBCPP_NO_RTTI virtual const void* target(const type_info&) const; virtual const std::type_info& target_type() const; #endif // _LIBCPP_NO_RTTI }; template __base<_Rp()>* __func<_Fp, _Alloc, _Rp()>::__clone() const { typedef allocator_traits<_Alloc> __alloc_traits; typedef typename __rebind_alloc_helper<__alloc_traits, __func>::type _Ap; _Ap __a(__f_.second()); typedef __allocator_destructor<_Ap> _Dp; unique_ptr<__func, _Dp> __hold(__a.allocate(1), _Dp(__a, 1)); ::new ((void*)__hold.get()) __func(__f_.first(), _Alloc(__a)); return __hold.release(); } template void __func<_Fp, _Alloc, _Rp()>::__clone(__base<_Rp()>* __p) const { ::new ((void*)__p) __func(__f_.first(), __f_.second()); } template void __func<_Fp, _Alloc, _Rp()>::destroy() { __f_.~__compressed_pair<_Fp, _Alloc>(); } template void __func<_Fp, _Alloc, _Rp()>::destroy_deallocate() { typedef allocator_traits<_Alloc> __alloc_traits; typedef typename __rebind_alloc_helper<__alloc_traits, __func>::type _Ap; _Ap __a(__f_.second()); __f_.~__compressed_pair<_Fp, _Alloc>(); __a.deallocate(this, 1); } template _Rp __func<_Fp, _Alloc, _Rp()>::operator()() { typedef __invoke_void_return_wrapper<_Rp> _Invoker; return _Invoker::__call(__f_.first()); } #ifndef _LIBCPP_NO_RTTI template const void* __func<_Fp, _Alloc, _Rp()>::target(const type_info& __ti) const { if (__ti == typeid(_Fp)) return _VSTD::addressof(__f_.first()); return (const void*)0; } template const std::type_info& __func<_Fp, _Alloc, _Rp()>::target_type() const { return typeid(_Fp); } #endif // _LIBCPP_NO_RTTI template class __func<_Fp, _Alloc, _Rp(_A0)> : public __base<_Rp(_A0)> { __compressed_pair<_Fp, _Alloc> __f_; public: _LIBCPP_INLINE_VISIBILITY explicit __func(_Fp __f) : __f_(_VSTD::move(__f), __default_init_tag()) {} _LIBCPP_INLINE_VISIBILITY explicit __func(_Fp __f, _Alloc __a) : __f_(_VSTD::move(__f), _VSTD::move(__a)) {} virtual __base<_Rp(_A0)>* __clone() const; virtual void __clone(__base<_Rp(_A0)>*) const; virtual void destroy(); virtual void destroy_deallocate(); virtual _Rp operator()(_A0); #ifndef _LIBCPP_NO_RTTI virtual const void* target(const type_info&) const; virtual const std::type_info& target_type() const; #endif // _LIBCPP_NO_RTTI }; template __base<_Rp(_A0)>* __func<_Fp, _Alloc, _Rp(_A0)>::__clone() const { typedef allocator_traits<_Alloc> __alloc_traits; typedef typename __rebind_alloc_helper<__alloc_traits, __func>::type _Ap; _Ap __a(__f_.second()); typedef __allocator_destructor<_Ap> _Dp; unique_ptr<__func, _Dp> __hold(__a.allocate(1), _Dp(__a, 1)); ::new ((void*)__hold.get()) __func(__f_.first(), _Alloc(__a)); return __hold.release(); } template void __func<_Fp, _Alloc, _Rp(_A0)>::__clone(__base<_Rp(_A0)>* __p) const { ::new ((void*)__p) __func(__f_.first(), __f_.second()); } template void __func<_Fp, _Alloc, _Rp(_A0)>::destroy() { __f_.~__compressed_pair<_Fp, _Alloc>(); } template void __func<_Fp, _Alloc, _Rp(_A0)>::destroy_deallocate() { typedef allocator_traits<_Alloc> __alloc_traits; typedef typename __rebind_alloc_helper<__alloc_traits, __func>::type _Ap; _Ap __a(__f_.second()); __f_.~__compressed_pair<_Fp, _Alloc>(); __a.deallocate(this, 1); } template _Rp __func<_Fp, _Alloc, _Rp(_A0)>::operator()(_A0 __a0) { typedef __invoke_void_return_wrapper<_Rp> _Invoker; return _Invoker::__call(__f_.first(), __a0); } #ifndef _LIBCPP_NO_RTTI template const void* __func<_Fp, _Alloc, _Rp(_A0)>::target(const type_info& __ti) const { if (__ti == typeid(_Fp)) return &__f_.first(); return (const void*)0; } template const std::type_info& __func<_Fp, _Alloc, _Rp(_A0)>::target_type() const { return typeid(_Fp); } #endif // _LIBCPP_NO_RTTI template class __func<_Fp, _Alloc, _Rp(_A0, _A1)> : public __base<_Rp(_A0, _A1)> { __compressed_pair<_Fp, _Alloc> __f_; public: _LIBCPP_INLINE_VISIBILITY explicit __func(_Fp __f) : __f_(_VSTD::move(__f), __default_init_tag()) {} _LIBCPP_INLINE_VISIBILITY explicit __func(_Fp __f, _Alloc __a) : __f_(_VSTD::move(__f), _VSTD::move(__a)) {} virtual __base<_Rp(_A0, _A1)>* __clone() const; virtual void __clone(__base<_Rp(_A0, _A1)>*) const; virtual void destroy(); virtual void destroy_deallocate(); virtual _Rp operator()(_A0, _A1); #ifndef _LIBCPP_NO_RTTI virtual const void* target(const type_info&) const; virtual const std::type_info& target_type() const; #endif // _LIBCPP_NO_RTTI }; template __base<_Rp(_A0, _A1)>* __func<_Fp, _Alloc, _Rp(_A0, _A1)>::__clone() const { typedef allocator_traits<_Alloc> __alloc_traits; typedef typename __rebind_alloc_helper<__alloc_traits, __func>::type _Ap; _Ap __a(__f_.second()); typedef __allocator_destructor<_Ap> _Dp; unique_ptr<__func, _Dp> __hold(__a.allocate(1), _Dp(__a, 1)); ::new ((void*)__hold.get()) __func(__f_.first(), _Alloc(__a)); return __hold.release(); } template void __func<_Fp, _Alloc, _Rp(_A0, _A1)>::__clone(__base<_Rp(_A0, _A1)>* __p) const { ::new ((void*)__p) __func(__f_.first(), __f_.second()); } template void __func<_Fp, _Alloc, _Rp(_A0, _A1)>::destroy() { __f_.~__compressed_pair<_Fp, _Alloc>(); } template void __func<_Fp, _Alloc, _Rp(_A0, _A1)>::destroy_deallocate() { typedef allocator_traits<_Alloc> __alloc_traits; typedef typename __rebind_alloc_helper<__alloc_traits, __func>::type _Ap; _Ap __a(__f_.second()); __f_.~__compressed_pair<_Fp, _Alloc>(); __a.deallocate(this, 1); } template _Rp __func<_Fp, _Alloc, _Rp(_A0, _A1)>::operator()(_A0 __a0, _A1 __a1) { typedef __invoke_void_return_wrapper<_Rp> _Invoker; return _Invoker::__call(__f_.first(), __a0, __a1); } #ifndef _LIBCPP_NO_RTTI template const void* __func<_Fp, _Alloc, _Rp(_A0, _A1)>::target(const type_info& __ti) const { if (__ti == typeid(_Fp)) return &__f_.first(); return (const void*)0; } template const std::type_info& __func<_Fp, _Alloc, _Rp(_A0, _A1)>::target_type() const { return typeid(_Fp); } #endif // _LIBCPP_NO_RTTI template class __func<_Fp, _Alloc, _Rp(_A0, _A1, _A2)> : public __base<_Rp(_A0, _A1, _A2)> { __compressed_pair<_Fp, _Alloc> __f_; public: _LIBCPP_INLINE_VISIBILITY explicit __func(_Fp __f) : __f_(_VSTD::move(__f), __default_init_tag()) {} _LIBCPP_INLINE_VISIBILITY explicit __func(_Fp __f, _Alloc __a) : __f_(_VSTD::move(__f), _VSTD::move(__a)) {} virtual __base<_Rp(_A0, _A1, _A2)>* __clone() const; virtual void __clone(__base<_Rp(_A0, _A1, _A2)>*) const; virtual void destroy(); virtual void destroy_deallocate(); virtual _Rp operator()(_A0, _A1, _A2); #ifndef _LIBCPP_NO_RTTI virtual const void* target(const type_info&) const; virtual const std::type_info& target_type() const; #endif // _LIBCPP_NO_RTTI }; template __base<_Rp(_A0, _A1, _A2)>* __func<_Fp, _Alloc, _Rp(_A0, _A1, _A2)>::__clone() const { typedef allocator_traits<_Alloc> __alloc_traits; typedef typename __rebind_alloc_helper<__alloc_traits, __func>::type _Ap; _Ap __a(__f_.second()); typedef __allocator_destructor<_Ap> _Dp; unique_ptr<__func, _Dp> __hold(__a.allocate(1), _Dp(__a, 1)); ::new ((void*)__hold.get()) __func(__f_.first(), _Alloc(__a)); return __hold.release(); } template void __func<_Fp, _Alloc, _Rp(_A0, _A1, _A2)>::__clone(__base<_Rp(_A0, _A1, _A2)>* __p) const { ::new ((void*)__p) __func(__f_.first(), __f_.second()); } template void __func<_Fp, _Alloc, _Rp(_A0, _A1, _A2)>::destroy() { __f_.~__compressed_pair<_Fp, _Alloc>(); } template void __func<_Fp, _Alloc, _Rp(_A0, _A1, _A2)>::destroy_deallocate() { typedef allocator_traits<_Alloc> __alloc_traits; typedef typename __rebind_alloc_helper<__alloc_traits, __func>::type _Ap; _Ap __a(__f_.second()); __f_.~__compressed_pair<_Fp, _Alloc>(); __a.deallocate(this, 1); } template _Rp __func<_Fp, _Alloc, _Rp(_A0, _A1, _A2)>::operator()(_A0 __a0, _A1 __a1, _A2 __a2) { typedef __invoke_void_return_wrapper<_Rp> _Invoker; return _Invoker::__call(__f_.first(), __a0, __a1, __a2); } #ifndef _LIBCPP_NO_RTTI template const void* __func<_Fp, _Alloc, _Rp(_A0, _A1, _A2)>::target(const type_info& __ti) const { if (__ti == typeid(_Fp)) return &__f_.first(); return (const void*)0; } template const std::type_info& __func<_Fp, _Alloc, _Rp(_A0, _A1, _A2)>::target_type() const { return typeid(_Fp); } #endif // _LIBCPP_NO_RTTI } // namespace __function template class _LIBCPP_TEMPLATE_VIS function<_Rp()> { typedef __function::__base<_Rp()> __base; aligned_storage<3*sizeof(void*)>::type __buf_; __base* __f_; public: typedef _Rp result_type; // 20.7.16.2.1, construct/copy/destroy: _LIBCPP_INLINE_VISIBILITY explicit function() : __f_(0) {} _LIBCPP_INLINE_VISIBILITY function(nullptr_t) : __f_(0) {} function(const function&); template function(_Fp, typename enable_if::value>::type* = 0); template _LIBCPP_INLINE_VISIBILITY function(allocator_arg_t, const _Alloc&) : __f_(0) {} template _LIBCPP_INLINE_VISIBILITY function(allocator_arg_t, const _Alloc&, nullptr_t) : __f_(0) {} template function(allocator_arg_t, const _Alloc&, const function&); template function(allocator_arg_t, const _Alloc& __a, _Fp __f, typename enable_if::value>::type* = 0); function& operator=(const function&); function& operator=(nullptr_t); template typename enable_if < !is_integral<_Fp>::value, function& >::type operator=(_Fp); ~function(); // 20.7.16.2.2, function modifiers: void swap(function&); template _LIBCPP_INLINE_VISIBILITY void assign(_Fp __f, const _Alloc& __a) {function(allocator_arg, __a, __f).swap(*this);} // 20.7.16.2.3, function capacity: _LIBCPP_INLINE_VISIBILITY explicit operator bool() const {return __f_;} template bool operator==(const function<_R2()>&) const = delete; template bool operator!=(const function<_R2()>&) const = delete; // 20.7.16.2.4, function invocation: _Rp operator()() const; #ifndef _LIBCPP_NO_RTTI // 20.7.16.2.5, function target access: const std::type_info& target_type() const; template _Tp* target(); template const _Tp* target() const; #endif // _LIBCPP_NO_RTTI }; template function<_Rp()>::function(const function& __f) { if (__f.__f_ == 0) __f_ = 0; else if (__f.__f_ == (const __base*)&__f.__buf_) { __f_ = (__base*)&__buf_; __f.__f_->__clone(__f_); } else __f_ = __f.__f_->__clone(); } template template function<_Rp()>::function(allocator_arg_t, const _Alloc&, const function& __f) { if (__f.__f_ == 0) __f_ = 0; else if (__f.__f_ == (const __base*)&__f.__buf_) { __f_ = (__base*)&__buf_; __f.__f_->__clone(__f_); } else __f_ = __f.__f_->__clone(); } template template function<_Rp()>::function(_Fp __f, typename enable_if::value>::type*) : __f_(0) { if (__function::__not_null(__f)) { typedef __function::__func<_Fp, allocator<_Fp>, _Rp()> _FF; if (sizeof(_FF) <= sizeof(__buf_)) { __f_ = (__base*)&__buf_; ::new ((void*)__f_) _FF(__f); } else { typedef allocator<_FF> _Ap; _Ap __a; typedef __allocator_destructor<_Ap> _Dp; unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1)); ::new ((void*)__hold.get()) _FF(__f, allocator<_Fp>(__a)); __f_ = __hold.release(); } } } template template function<_Rp()>::function(allocator_arg_t, const _Alloc& __a0, _Fp __f, typename enable_if::value>::type*) : __f_(0) { typedef allocator_traits<_Alloc> __alloc_traits; if (__function::__not_null(__f)) { typedef __function::__func<_Fp, _Alloc, _Rp()> _FF; if (sizeof(_FF) <= sizeof(__buf_)) { __f_ = (__base*)&__buf_; ::new ((void*)__f_) _FF(__f, __a0); } else { typedef typename __rebind_alloc_helper<__alloc_traits, _FF>::type _Ap; _Ap __a(__a0); typedef __allocator_destructor<_Ap> _Dp; unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1)); ::new ((void*)__hold.get()) _FF(__f, _Alloc(__a)); __f_ = __hold.release(); } } } template function<_Rp()>& function<_Rp()>::operator=(const function& __f) { if (__f) function(__f).swap(*this); else *this = nullptr; return *this; } template function<_Rp()>& function<_Rp()>::operator=(nullptr_t) { __base* __t = __f_; __f_ = 0; if (__t == (__base*)&__buf_) __t->destroy(); else if (__t) __t->destroy_deallocate(); return *this; } template template typename enable_if < !is_integral<_Fp>::value, function<_Rp()>& >::type function<_Rp()>::operator=(_Fp __f) { function(_VSTD::move(__f)).swap(*this); return *this; } template function<_Rp()>::~function() { if (__f_ == (__base*)&__buf_) __f_->destroy(); else if (__f_) __f_->destroy_deallocate(); } template void function<_Rp()>::swap(function& __f) { if (_VSTD::addressof(__f) == this) return; if (__f_ == (__base*)&__buf_ && __f.__f_ == (__base*)&__f.__buf_) { typename aligned_storage::type __tempbuf; __base* __t = (__base*)&__tempbuf; __f_->__clone(__t); __f_->destroy(); __f_ = 0; __f.__f_->__clone((__base*)&__buf_); __f.__f_->destroy(); __f.__f_ = 0; __f_ = (__base*)&__buf_; __t->__clone((__base*)&__f.__buf_); __t->destroy(); __f.__f_ = (__base*)&__f.__buf_; } else if (__f_ == (__base*)&__buf_) { __f_->__clone((__base*)&__f.__buf_); __f_->destroy(); __f_ = __f.__f_; __f.__f_ = (__base*)&__f.__buf_; } else if (__f.__f_ == (__base*)&__f.__buf_) { __f.__f_->__clone((__base*)&__buf_); __f.__f_->destroy(); __f.__f_ = __f_; __f_ = (__base*)&__buf_; } else _VSTD::swap(__f_, __f.__f_); } template _Rp function<_Rp()>::operator()() const { if (__f_ == 0) __throw_bad_function_call(); return (*__f_)(); } #ifndef _LIBCPP_NO_RTTI template const std::type_info& function<_Rp()>::target_type() const { if (__f_ == 0) return typeid(void); return __f_->target_type(); } template template _Tp* function<_Rp()>::target() { if (__f_ == 0) return (_Tp*)0; return (_Tp*) const_cast(__f_->target(typeid(_Tp))); } template template const _Tp* function<_Rp()>::target() const { if (__f_ == 0) return (const _Tp*)0; return (const _Tp*)__f_->target(typeid(_Tp)); } #endif // _LIBCPP_NO_RTTI template class _LIBCPP_TEMPLATE_VIS function<_Rp(_A0)> : public unary_function<_A0, _Rp> { typedef __function::__base<_Rp(_A0)> __base; aligned_storage<3*sizeof(void*)>::type __buf_; __base* __f_; public: typedef _Rp result_type; // 20.7.16.2.1, construct/copy/destroy: _LIBCPP_INLINE_VISIBILITY explicit function() : __f_(0) {} _LIBCPP_INLINE_VISIBILITY function(nullptr_t) : __f_(0) {} function(const function&); template function(_Fp, typename enable_if::value>::type* = 0); template _LIBCPP_INLINE_VISIBILITY function(allocator_arg_t, const _Alloc&) : __f_(0) {} template _LIBCPP_INLINE_VISIBILITY function(allocator_arg_t, const _Alloc&, nullptr_t) : __f_(0) {} template function(allocator_arg_t, const _Alloc&, const function&); template function(allocator_arg_t, const _Alloc& __a, _Fp __f, typename enable_if::value>::type* = 0); function& operator=(const function&); function& operator=(nullptr_t); template typename enable_if < !is_integral<_Fp>::value, function& >::type operator=(_Fp); ~function(); // 20.7.16.2.2, function modifiers: void swap(function&); template _LIBCPP_INLINE_VISIBILITY void assign(_Fp __f, const _Alloc& __a) {function(allocator_arg, __a, __f).swap(*this);} // 20.7.16.2.3, function capacity: _LIBCPP_INLINE_VISIBILITY explicit operator bool() const {return __f_;} template bool operator==(const function<_R2(_B0)>&) const = delete; template bool operator!=(const function<_R2(_B0)>&) const = delete; // 20.7.16.2.4, function invocation: _Rp operator()(_A0) const; #ifndef _LIBCPP_NO_RTTI // 20.7.16.2.5, function target access: const std::type_info& target_type() const; template _Tp* target(); template const _Tp* target() const; #endif // _LIBCPP_NO_RTTI }; template function<_Rp(_A0)>::function(const function& __f) { if (__f.__f_ == 0) __f_ = 0; else if (__f.__f_ == (const __base*)&__f.__buf_) { __f_ = (__base*)&__buf_; __f.__f_->__clone(__f_); } else __f_ = __f.__f_->__clone(); } template template function<_Rp(_A0)>::function(allocator_arg_t, const _Alloc&, const function& __f) { if (__f.__f_ == 0) __f_ = 0; else if (__f.__f_ == (const __base*)&__f.__buf_) { __f_ = (__base*)&__buf_; __f.__f_->__clone(__f_); } else __f_ = __f.__f_->__clone(); } template template function<_Rp(_A0)>::function(_Fp __f, typename enable_if::value>::type*) : __f_(0) { if (__function::__not_null(__f)) { typedef __function::__func<_Fp, allocator<_Fp>, _Rp(_A0)> _FF; if (sizeof(_FF) <= sizeof(__buf_)) { __f_ = (__base*)&__buf_; ::new ((void*)__f_) _FF(__f); } else { typedef allocator<_FF> _Ap; _Ap __a; typedef __allocator_destructor<_Ap> _Dp; unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1)); ::new ((void*)__hold.get()) _FF(__f, allocator<_Fp>(__a)); __f_ = __hold.release(); } } } template template function<_Rp(_A0)>::function(allocator_arg_t, const _Alloc& __a0, _Fp __f, typename enable_if::value>::type*) : __f_(0) { typedef allocator_traits<_Alloc> __alloc_traits; if (__function::__not_null(__f)) { typedef __function::__func<_Fp, _Alloc, _Rp(_A0)> _FF; if (sizeof(_FF) <= sizeof(__buf_)) { __f_ = (__base*)&__buf_; ::new ((void*)__f_) _FF(__f, __a0); } else { typedef typename __rebind_alloc_helper<__alloc_traits, _FF>::type _Ap; _Ap __a(__a0); typedef __allocator_destructor<_Ap> _Dp; unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1)); ::new ((void*)__hold.get()) _FF(__f, _Alloc(__a)); __f_ = __hold.release(); } } } template function<_Rp(_A0)>& function<_Rp(_A0)>::operator=(const function& __f) { if (__f) function(__f).swap(*this); else *this = nullptr; return *this; } template function<_Rp(_A0)>& function<_Rp(_A0)>::operator=(nullptr_t) { __base* __t = __f_; __f_ = 0; if (__t == (__base*)&__buf_) __t->destroy(); else if (__t) __t->destroy_deallocate(); return *this; } template template typename enable_if < !is_integral<_Fp>::value, function<_Rp(_A0)>& >::type function<_Rp(_A0)>::operator=(_Fp __f) { function(_VSTD::move(__f)).swap(*this); return *this; } template function<_Rp(_A0)>::~function() { if (__f_ == (__base*)&__buf_) __f_->destroy(); else if (__f_) __f_->destroy_deallocate(); } template void function<_Rp(_A0)>::swap(function& __f) { if (_VSTD::addressof(__f) == this) return; if (__f_ == (__base*)&__buf_ && __f.__f_ == (__base*)&__f.__buf_) { typename aligned_storage::type __tempbuf; __base* __t = (__base*)&__tempbuf; __f_->__clone(__t); __f_->destroy(); __f_ = 0; __f.__f_->__clone((__base*)&__buf_); __f.__f_->destroy(); __f.__f_ = 0; __f_ = (__base*)&__buf_; __t->__clone((__base*)&__f.__buf_); __t->destroy(); __f.__f_ = (__base*)&__f.__buf_; } else if (__f_ == (__base*)&__buf_) { __f_->__clone((__base*)&__f.__buf_); __f_->destroy(); __f_ = __f.__f_; __f.__f_ = (__base*)&__f.__buf_; } else if (__f.__f_ == (__base*)&__f.__buf_) { __f.__f_->__clone((__base*)&__buf_); __f.__f_->destroy(); __f.__f_ = __f_; __f_ = (__base*)&__buf_; } else _VSTD::swap(__f_, __f.__f_); } template _Rp function<_Rp(_A0)>::operator()(_A0 __a0) const { if (__f_ == 0) __throw_bad_function_call(); return (*__f_)(__a0); } #ifndef _LIBCPP_NO_RTTI template const std::type_info& function<_Rp(_A0)>::target_type() const { if (__f_ == 0) return typeid(void); return __f_->target_type(); } template template _Tp* function<_Rp(_A0)>::target() { if (__f_ == 0) return (_Tp*)0; return (_Tp*) const_cast(__f_->target(typeid(_Tp))); } template template const _Tp* function<_Rp(_A0)>::target() const { if (__f_ == 0) return (const _Tp*)0; return (const _Tp*)__f_->target(typeid(_Tp)); } #endif // _LIBCPP_NO_RTTI template class _LIBCPP_TEMPLATE_VIS function<_Rp(_A0, _A1)> : public binary_function<_A0, _A1, _Rp> { typedef __function::__base<_Rp(_A0, _A1)> __base; aligned_storage<3*sizeof(void*)>::type __buf_; __base* __f_; public: typedef _Rp result_type; // 20.7.16.2.1, construct/copy/destroy: _LIBCPP_INLINE_VISIBILITY explicit function() : __f_(0) {} _LIBCPP_INLINE_VISIBILITY function(nullptr_t) : __f_(0) {} function(const function&); template function(_Fp, typename enable_if::value>::type* = 0); template _LIBCPP_INLINE_VISIBILITY function(allocator_arg_t, const _Alloc&) : __f_(0) {} template _LIBCPP_INLINE_VISIBILITY function(allocator_arg_t, const _Alloc&, nullptr_t) : __f_(0) {} template function(allocator_arg_t, const _Alloc&, const function&); template function(allocator_arg_t, const _Alloc& __a, _Fp __f, typename enable_if::value>::type* = 0); function& operator=(const function&); function& operator=(nullptr_t); template typename enable_if < !is_integral<_Fp>::value, function& >::type operator=(_Fp); ~function(); // 20.7.16.2.2, function modifiers: void swap(function&); template _LIBCPP_INLINE_VISIBILITY void assign(_Fp __f, const _Alloc& __a) {function(allocator_arg, __a, __f).swap(*this);} // 20.7.16.2.3, function capacity: _LIBCPP_INLINE_VISIBILITY explicit operator bool() const {return __f_;} template bool operator==(const function<_R2(_B0, _B1)>&) const = delete; template bool operator!=(const function<_R2(_B0, _B1)>&) const = delete; // 20.7.16.2.4, function invocation: _Rp operator()(_A0, _A1) const; #ifndef _LIBCPP_NO_RTTI // 20.7.16.2.5, function target access: const std::type_info& target_type() const; template _Tp* target(); template const _Tp* target() const; #endif // _LIBCPP_NO_RTTI }; template function<_Rp(_A0, _A1)>::function(const function& __f) { if (__f.__f_ == 0) __f_ = 0; else if (__f.__f_ == (const __base*)&__f.__buf_) { __f_ = (__base*)&__buf_; __f.__f_->__clone(__f_); } else __f_ = __f.__f_->__clone(); } template template function<_Rp(_A0, _A1)>::function(allocator_arg_t, const _Alloc&, const function& __f) { if (__f.__f_ == 0) __f_ = 0; else if (__f.__f_ == (const __base*)&__f.__buf_) { __f_ = (__base*)&__buf_; __f.__f_->__clone(__f_); } else __f_ = __f.__f_->__clone(); } template template function<_Rp(_A0, _A1)>::function(_Fp __f, typename enable_if::value>::type*) : __f_(0) { if (__function::__not_null(__f)) { typedef __function::__func<_Fp, allocator<_Fp>, _Rp(_A0, _A1)> _FF; if (sizeof(_FF) <= sizeof(__buf_)) { __f_ = (__base*)&__buf_; ::new ((void*)__f_) _FF(__f); } else { typedef allocator<_FF> _Ap; _Ap __a; typedef __allocator_destructor<_Ap> _Dp; unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1)); ::new ((void*)__hold.get()) _FF(__f, allocator<_Fp>(__a)); __f_ = __hold.release(); } } } template template function<_Rp(_A0, _A1)>::function(allocator_arg_t, const _Alloc& __a0, _Fp __f, typename enable_if::value>::type*) : __f_(0) { typedef allocator_traits<_Alloc> __alloc_traits; if (__function::__not_null(__f)) { typedef __function::__func<_Fp, _Alloc, _Rp(_A0, _A1)> _FF; if (sizeof(_FF) <= sizeof(__buf_)) { __f_ = (__base*)&__buf_; ::new ((void*)__f_) _FF(__f, __a0); } else { typedef typename __rebind_alloc_helper<__alloc_traits, _FF>::type _Ap; _Ap __a(__a0); typedef __allocator_destructor<_Ap> _Dp; unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1)); ::new ((void*)__hold.get()) _FF(__f, _Alloc(__a)); __f_ = __hold.release(); } } } template function<_Rp(_A0, _A1)>& function<_Rp(_A0, _A1)>::operator=(const function& __f) { if (__f) function(__f).swap(*this); else *this = nullptr; return *this; } template function<_Rp(_A0, _A1)>& function<_Rp(_A0, _A1)>::operator=(nullptr_t) { __base* __t = __f_; __f_ = 0; if (__t == (__base*)&__buf_) __t->destroy(); else if (__t) __t->destroy_deallocate(); return *this; } template template typename enable_if < !is_integral<_Fp>::value, function<_Rp(_A0, _A1)>& >::type function<_Rp(_A0, _A1)>::operator=(_Fp __f) { function(_VSTD::move(__f)).swap(*this); return *this; } template function<_Rp(_A0, _A1)>::~function() { if (__f_ == (__base*)&__buf_) __f_->destroy(); else if (__f_) __f_->destroy_deallocate(); } template void function<_Rp(_A0, _A1)>::swap(function& __f) { if (_VSTD::addressof(__f) == this) return; if (__f_ == (__base*)&__buf_ && __f.__f_ == (__base*)&__f.__buf_) { typename aligned_storage::type __tempbuf; __base* __t = (__base*)&__tempbuf; __f_->__clone(__t); __f_->destroy(); __f_ = 0; __f.__f_->__clone((__base*)&__buf_); __f.__f_->destroy(); __f.__f_ = 0; __f_ = (__base*)&__buf_; __t->__clone((__base*)&__f.__buf_); __t->destroy(); __f.__f_ = (__base*)&__f.__buf_; } else if (__f_ == (__base*)&__buf_) { __f_->__clone((__base*)&__f.__buf_); __f_->destroy(); __f_ = __f.__f_; __f.__f_ = (__base*)&__f.__buf_; } else if (__f.__f_ == (__base*)&__f.__buf_) { __f.__f_->__clone((__base*)&__buf_); __f.__f_->destroy(); __f.__f_ = __f_; __f_ = (__base*)&__buf_; } else _VSTD::swap(__f_, __f.__f_); } template _Rp function<_Rp(_A0, _A1)>::operator()(_A0 __a0, _A1 __a1) const { if (__f_ == 0) __throw_bad_function_call(); return (*__f_)(__a0, __a1); } #ifndef _LIBCPP_NO_RTTI template const std::type_info& function<_Rp(_A0, _A1)>::target_type() const { if (__f_ == 0) return typeid(void); return __f_->target_type(); } template template _Tp* function<_Rp(_A0, _A1)>::target() { if (__f_ == 0) return (_Tp*)0; return (_Tp*) const_cast(__f_->target(typeid(_Tp))); } template template const _Tp* function<_Rp(_A0, _A1)>::target() const { if (__f_ == 0) return (const _Tp*)0; return (const _Tp*)__f_->target(typeid(_Tp)); } #endif // _LIBCPP_NO_RTTI template class _LIBCPP_TEMPLATE_VIS function<_Rp(_A0, _A1, _A2)> { typedef __function::__base<_Rp(_A0, _A1, _A2)> __base; aligned_storage<3*sizeof(void*)>::type __buf_; __base* __f_; public: typedef _Rp result_type; // 20.7.16.2.1, construct/copy/destroy: _LIBCPP_INLINE_VISIBILITY explicit function() : __f_(0) {} _LIBCPP_INLINE_VISIBILITY function(nullptr_t) : __f_(0) {} function(const function&); template function(_Fp, typename enable_if::value>::type* = 0); template _LIBCPP_INLINE_VISIBILITY function(allocator_arg_t, const _Alloc&) : __f_(0) {} template _LIBCPP_INLINE_VISIBILITY function(allocator_arg_t, const _Alloc&, nullptr_t) : __f_(0) {} template function(allocator_arg_t, const _Alloc&, const function&); template function(allocator_arg_t, const _Alloc& __a, _Fp __f, typename enable_if::value>::type* = 0); function& operator=(const function&); function& operator=(nullptr_t); template typename enable_if < !is_integral<_Fp>::value, function& >::type operator=(_Fp); ~function(); // 20.7.16.2.2, function modifiers: void swap(function&); template _LIBCPP_INLINE_VISIBILITY void assign(_Fp __f, const _Alloc& __a) {function(allocator_arg, __a, __f).swap(*this);} // 20.7.16.2.3, function capacity: _LIBCPP_INLINE_VISIBILITY explicit operator bool() const {return __f_;} template bool operator==(const function<_R2(_B0, _B1, _B2)>&) const = delete; template bool operator!=(const function<_R2(_B0, _B1, _B2)>&) const = delete; // 20.7.16.2.4, function invocation: _Rp operator()(_A0, _A1, _A2) const; #ifndef _LIBCPP_NO_RTTI // 20.7.16.2.5, function target access: const std::type_info& target_type() const; template _Tp* target(); template const _Tp* target() const; #endif // _LIBCPP_NO_RTTI }; template function<_Rp(_A0, _A1, _A2)>::function(const function& __f) { if (__f.__f_ == 0) __f_ = 0; else if (__f.__f_ == (const __base*)&__f.__buf_) { __f_ = (__base*)&__buf_; __f.__f_->__clone(__f_); } else __f_ = __f.__f_->__clone(); } template template function<_Rp(_A0, _A1, _A2)>::function(allocator_arg_t, const _Alloc&, const function& __f) { if (__f.__f_ == 0) __f_ = 0; else if (__f.__f_ == (const __base*)&__f.__buf_) { __f_ = (__base*)&__buf_; __f.__f_->__clone(__f_); } else __f_ = __f.__f_->__clone(); } template template function<_Rp(_A0, _A1, _A2)>::function(_Fp __f, typename enable_if::value>::type*) : __f_(0) { if (__function::__not_null(__f)) { typedef __function::__func<_Fp, allocator<_Fp>, _Rp(_A0, _A1, _A2)> _FF; if (sizeof(_FF) <= sizeof(__buf_)) { __f_ = (__base*)&__buf_; ::new ((void*)__f_) _FF(__f); } else { typedef allocator<_FF> _Ap; _Ap __a; typedef __allocator_destructor<_Ap> _Dp; unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1)); ::new ((void*)__hold.get()) _FF(__f, allocator<_Fp>(__a)); __f_ = __hold.release(); } } } template template function<_Rp(_A0, _A1, _A2)>::function(allocator_arg_t, const _Alloc& __a0, _Fp __f, typename enable_if::value>::type*) : __f_(0) { typedef allocator_traits<_Alloc> __alloc_traits; if (__function::__not_null(__f)) { typedef __function::__func<_Fp, _Alloc, _Rp(_A0, _A1, _A2)> _FF; if (sizeof(_FF) <= sizeof(__buf_)) { __f_ = (__base*)&__buf_; ::new ((void*)__f_) _FF(__f, __a0); } else { typedef typename __rebind_alloc_helper<__alloc_traits, _FF>::type _Ap; _Ap __a(__a0); typedef __allocator_destructor<_Ap> _Dp; unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1)); ::new ((void*)__hold.get()) _FF(__f, _Alloc(__a)); __f_ = __hold.release(); } } } template function<_Rp(_A0, _A1, _A2)>& function<_Rp(_A0, _A1, _A2)>::operator=(const function& __f) { if (__f) function(__f).swap(*this); else *this = nullptr; return *this; } template function<_Rp(_A0, _A1, _A2)>& function<_Rp(_A0, _A1, _A2)>::operator=(nullptr_t) { __base* __t = __f_; __f_ = 0; if (__t == (__base*)&__buf_) __t->destroy(); else if (__t) __t->destroy_deallocate(); return *this; } template template typename enable_if < !is_integral<_Fp>::value, function<_Rp(_A0, _A1, _A2)>& >::type function<_Rp(_A0, _A1, _A2)>::operator=(_Fp __f) { function(_VSTD::move(__f)).swap(*this); return *this; } template function<_Rp(_A0, _A1, _A2)>::~function() { if (__f_ == (__base*)&__buf_) __f_->destroy(); else if (__f_) __f_->destroy_deallocate(); } template void function<_Rp(_A0, _A1, _A2)>::swap(function& __f) { if (_VSTD::addressof(__f) == this) return; if (__f_ == (__base*)&__buf_ && __f.__f_ == (__base*)&__f.__buf_) { typename aligned_storage::type __tempbuf; __base* __t = (__base*)&__tempbuf; __f_->__clone(__t); __f_->destroy(); __f_ = 0; __f.__f_->__clone((__base*)&__buf_); __f.__f_->destroy(); __f.__f_ = 0; __f_ = (__base*)&__buf_; __t->__clone((__base*)&__f.__buf_); __t->destroy(); __f.__f_ = (__base*)&__f.__buf_; } else if (__f_ == (__base*)&__buf_) { __f_->__clone((__base*)&__f.__buf_); __f_->destroy(); __f_ = __f.__f_; __f.__f_ = (__base*)&__f.__buf_; } else if (__f.__f_ == (__base*)&__f.__buf_) { __f.__f_->__clone((__base*)&__buf_); __f.__f_->destroy(); __f.__f_ = __f_; __f_ = (__base*)&__buf_; } else _VSTD::swap(__f_, __f.__f_); } template _Rp function<_Rp(_A0, _A1, _A2)>::operator()(_A0 __a0, _A1 __a1, _A2 __a2) const { if (__f_ == 0) __throw_bad_function_call(); return (*__f_)(__a0, __a1, __a2); } #ifndef _LIBCPP_NO_RTTI template const std::type_info& function<_Rp(_A0, _A1, _A2)>::target_type() const { if (__f_ == 0) return typeid(void); return __f_->target_type(); } template template _Tp* function<_Rp(_A0, _A1, _A2)>::target() { if (__f_ == 0) return (_Tp*)0; return (_Tp*) const_cast(__f_->target(typeid(_Tp))); } template template const _Tp* function<_Rp(_A0, _A1, _A2)>::target() const { if (__f_ == 0) return (const _Tp*)0; return (const _Tp*)__f_->target(typeid(_Tp)); } #endif // _LIBCPP_NO_RTTI template inline _LIBCPP_INLINE_VISIBILITY bool operator==(const function<_Fp>& __f, nullptr_t) {return !__f;} template inline _LIBCPP_INLINE_VISIBILITY bool operator==(nullptr_t, const function<_Fp>& __f) {return !__f;} template inline _LIBCPP_INLINE_VISIBILITY bool operator!=(const function<_Fp>& __f, nullptr_t) {return (bool)__f;} template inline _LIBCPP_INLINE_VISIBILITY bool operator!=(nullptr_t, const function<_Fp>& __f) {return (bool)__f;} template inline _LIBCPP_INLINE_VISIBILITY void swap(function<_Fp>& __x, function<_Fp>& __y) {return __x.swap(__y);} #endif // _LIBCPP_CXX03_LANG _LIBCPP_END_NAMESPACE_STD #endif // _LIBCPP___FUNCTIONAL_FUNCTION_H