176d0caaeSpatrick // -*- C++ -*-
276d0caaeSpatrick //===----------------------------------------------------------------------===//
376d0caaeSpatrick //
476d0caaeSpatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
576d0caaeSpatrick // See https://llvm.org/LICENSE.txt for license information.
676d0caaeSpatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
776d0caaeSpatrick //
876d0caaeSpatrick //===----------------------------------------------------------------------===//
976d0caaeSpatrick
1076d0caaeSpatrick #ifndef _LIBCPP___FUNCTIONAL_FUNCTION_H
1176d0caaeSpatrick #define _LIBCPP___FUNCTIONAL_FUNCTION_H
1276d0caaeSpatrick
13*4bdff4beSrobert #include <__assert>
1476d0caaeSpatrick #include <__config>
1576d0caaeSpatrick #include <__functional/binary_function.h>
1676d0caaeSpatrick #include <__functional/invoke.h>
1776d0caaeSpatrick #include <__functional/unary_function.h>
1876d0caaeSpatrick #include <__iterator/iterator_traits.h>
19*4bdff4beSrobert #include <__memory/addressof.h>
20*4bdff4beSrobert #include <__memory/allocator.h>
21*4bdff4beSrobert #include <__memory/allocator_destructor.h>
2276d0caaeSpatrick #include <__memory/allocator_traits.h>
23*4bdff4beSrobert #include <__memory/builtin_new_allocator.h>
2476d0caaeSpatrick #include <__memory/compressed_pair.h>
25*4bdff4beSrobert #include <__memory/unique_ptr.h>
26*4bdff4beSrobert #include <__type_traits/strip_signature.h>
27*4bdff4beSrobert #include <__utility/forward.h>
28*4bdff4beSrobert #include <__utility/move.h>
29*4bdff4beSrobert #include <__utility/piecewise_construct.h>
30*4bdff4beSrobert #include <__utility/swap.h>
3176d0caaeSpatrick #include <exception>
32*4bdff4beSrobert #include <new>
33*4bdff4beSrobert #include <tuple>
3476d0caaeSpatrick #include <type_traits>
35*4bdff4beSrobert #include <typeinfo>
3676d0caaeSpatrick
3776d0caaeSpatrick #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
3876d0caaeSpatrick # pragma GCC system_header
3976d0caaeSpatrick #endif
4076d0caaeSpatrick
41*4bdff4beSrobert #ifndef _LIBCPP_CXX03_LANG
42*4bdff4beSrobert
4376d0caaeSpatrick _LIBCPP_BEGIN_NAMESPACE_STD
4476d0caaeSpatrick
4576d0caaeSpatrick // bad_function_call
4676d0caaeSpatrick
47*4bdff4beSrobert _LIBCPP_DIAGNOSTIC_PUSH
48*4bdff4beSrobert _LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wweak-vtables")
4976d0caaeSpatrick class _LIBCPP_EXCEPTION_ABI bad_function_call
5076d0caaeSpatrick : public exception
5176d0caaeSpatrick {
5276d0caaeSpatrick public:
53*4bdff4beSrobert // Note that when a key function is not used, every translation unit that uses
54*4bdff4beSrobert // bad_function_call will end up containing a weak definition of the vtable and
55*4bdff4beSrobert // typeinfo.
56*4bdff4beSrobert #ifdef _LIBCPP_ABI_BAD_FUNCTION_CALL_KEY_FUNCTION
57*4bdff4beSrobert ~bad_function_call() _NOEXCEPT override;
58*4bdff4beSrobert #else
59*4bdff4beSrobert ~bad_function_call() _NOEXCEPT override {}
60*4bdff4beSrobert #endif
6176d0caaeSpatrick
62*4bdff4beSrobert #ifdef _LIBCPP_ABI_BAD_FUNCTION_CALL_GOOD_WHAT_MESSAGE
63*4bdff4beSrobert const char* what() const _NOEXCEPT override;
6476d0caaeSpatrick #endif
6576d0caaeSpatrick };
66*4bdff4beSrobert _LIBCPP_DIAGNOSTIC_POP
6776d0caaeSpatrick
6876d0caaeSpatrick _LIBCPP_NORETURN inline _LIBCPP_INLINE_VISIBILITY
__throw_bad_function_call()6976d0caaeSpatrick void __throw_bad_function_call()
7076d0caaeSpatrick {
7176d0caaeSpatrick #ifndef _LIBCPP_NO_EXCEPTIONS
7276d0caaeSpatrick throw bad_function_call();
7376d0caaeSpatrick #else
7476d0caaeSpatrick _VSTD::abort();
7576d0caaeSpatrick #endif
7676d0caaeSpatrick }
7776d0caaeSpatrick
78*4bdff4beSrobert template<class _Fp> class _LIBCPP_TEMPLATE_VIS function; // undefined
7976d0caaeSpatrick
8076d0caaeSpatrick namespace __function
8176d0caaeSpatrick {
8276d0caaeSpatrick
8376d0caaeSpatrick template<class _Rp>
8476d0caaeSpatrick struct __maybe_derive_from_unary_function
8576d0caaeSpatrick {
8676d0caaeSpatrick };
8776d0caaeSpatrick
8876d0caaeSpatrick template<class _Rp, class _A1>
8976d0caaeSpatrick struct __maybe_derive_from_unary_function<_Rp(_A1)>
90*4bdff4beSrobert : public __unary_function<_A1, _Rp>
9176d0caaeSpatrick {
9276d0caaeSpatrick };
9376d0caaeSpatrick
9476d0caaeSpatrick template<class _Rp>
9576d0caaeSpatrick struct __maybe_derive_from_binary_function
9676d0caaeSpatrick {
9776d0caaeSpatrick };
9876d0caaeSpatrick
9976d0caaeSpatrick template<class _Rp, class _A1, class _A2>
10076d0caaeSpatrick struct __maybe_derive_from_binary_function<_Rp(_A1, _A2)>
101*4bdff4beSrobert : public __binary_function<_A1, _A2, _Rp>
10276d0caaeSpatrick {
10376d0caaeSpatrick };
10476d0caaeSpatrick
10576d0caaeSpatrick template <class _Fp>
10676d0caaeSpatrick _LIBCPP_INLINE_VISIBILITY
10776d0caaeSpatrick bool __not_null(_Fp const&) { return true; }
10876d0caaeSpatrick
10976d0caaeSpatrick template <class _Fp>
11076d0caaeSpatrick _LIBCPP_INLINE_VISIBILITY
11176d0caaeSpatrick bool __not_null(_Fp* __ptr) { return __ptr; }
11276d0caaeSpatrick
11376d0caaeSpatrick template <class _Ret, class _Class>
11476d0caaeSpatrick _LIBCPP_INLINE_VISIBILITY
11576d0caaeSpatrick bool __not_null(_Ret _Class::*__ptr) { return __ptr; }
11676d0caaeSpatrick
11776d0caaeSpatrick template <class _Fp>
11876d0caaeSpatrick _LIBCPP_INLINE_VISIBILITY
11976d0caaeSpatrick bool __not_null(function<_Fp> const& __f) { return !!__f; }
12076d0caaeSpatrick
12176d0caaeSpatrick #ifdef _LIBCPP_HAS_EXTENSION_BLOCKS
12276d0caaeSpatrick template <class _Rp, class ..._Args>
12376d0caaeSpatrick _LIBCPP_INLINE_VISIBILITY
12476d0caaeSpatrick bool __not_null(_Rp (^__p)(_Args...)) { return __p; }
12576d0caaeSpatrick #endif
12676d0caaeSpatrick
12776d0caaeSpatrick } // namespace __function
12876d0caaeSpatrick
12976d0caaeSpatrick namespace __function {
13076d0caaeSpatrick
13176d0caaeSpatrick // __alloc_func holds a functor and an allocator.
13276d0caaeSpatrick
13376d0caaeSpatrick template <class _Fp, class _Ap, class _FB> class __alloc_func;
13476d0caaeSpatrick template <class _Fp, class _FB>
13576d0caaeSpatrick class __default_alloc_func;
13676d0caaeSpatrick
13776d0caaeSpatrick template <class _Fp, class _Ap, class _Rp, class... _ArgTypes>
13876d0caaeSpatrick class __alloc_func<_Fp, _Ap, _Rp(_ArgTypes...)>
13976d0caaeSpatrick {
14076d0caaeSpatrick __compressed_pair<_Fp, _Ap> __f_;
14176d0caaeSpatrick
14276d0caaeSpatrick public:
143*4bdff4beSrobert typedef _LIBCPP_NODEBUG _Fp _Target;
144*4bdff4beSrobert typedef _LIBCPP_NODEBUG _Ap _Alloc;
14576d0caaeSpatrick
14676d0caaeSpatrick _LIBCPP_INLINE_VISIBILITY
14776d0caaeSpatrick const _Target& __target() const { return __f_.first(); }
14876d0caaeSpatrick
14976d0caaeSpatrick // WIN32 APIs may define __allocator, so use __get_allocator instead.
15076d0caaeSpatrick _LIBCPP_INLINE_VISIBILITY
15176d0caaeSpatrick const _Alloc& __get_allocator() const { return __f_.second(); }
15276d0caaeSpatrick
15376d0caaeSpatrick _LIBCPP_INLINE_VISIBILITY
15476d0caaeSpatrick explicit __alloc_func(_Target&& __f)
15576d0caaeSpatrick : __f_(piecewise_construct, _VSTD::forward_as_tuple(_VSTD::move(__f)),
15676d0caaeSpatrick _VSTD::forward_as_tuple())
15776d0caaeSpatrick {
15876d0caaeSpatrick }
15976d0caaeSpatrick
16076d0caaeSpatrick _LIBCPP_INLINE_VISIBILITY
16176d0caaeSpatrick explicit __alloc_func(const _Target& __f, const _Alloc& __a)
16276d0caaeSpatrick : __f_(piecewise_construct, _VSTD::forward_as_tuple(__f),
16376d0caaeSpatrick _VSTD::forward_as_tuple(__a))
16476d0caaeSpatrick {
16576d0caaeSpatrick }
16676d0caaeSpatrick
16776d0caaeSpatrick _LIBCPP_INLINE_VISIBILITY
16876d0caaeSpatrick explicit __alloc_func(const _Target& __f, _Alloc&& __a)
16976d0caaeSpatrick : __f_(piecewise_construct, _VSTD::forward_as_tuple(__f),
17076d0caaeSpatrick _VSTD::forward_as_tuple(_VSTD::move(__a)))
17176d0caaeSpatrick {
17276d0caaeSpatrick }
17376d0caaeSpatrick
17476d0caaeSpatrick _LIBCPP_INLINE_VISIBILITY
17576d0caaeSpatrick explicit __alloc_func(_Target&& __f, _Alloc&& __a)
17676d0caaeSpatrick : __f_(piecewise_construct, _VSTD::forward_as_tuple(_VSTD::move(__f)),
17776d0caaeSpatrick _VSTD::forward_as_tuple(_VSTD::move(__a)))
17876d0caaeSpatrick {
17976d0caaeSpatrick }
18076d0caaeSpatrick
18176d0caaeSpatrick _LIBCPP_INLINE_VISIBILITY
18276d0caaeSpatrick _Rp operator()(_ArgTypes&&... __arg)
18376d0caaeSpatrick {
18476d0caaeSpatrick typedef __invoke_void_return_wrapper<_Rp> _Invoker;
18576d0caaeSpatrick return _Invoker::__call(__f_.first(),
18676d0caaeSpatrick _VSTD::forward<_ArgTypes>(__arg)...);
18776d0caaeSpatrick }
18876d0caaeSpatrick
18976d0caaeSpatrick _LIBCPP_INLINE_VISIBILITY
19076d0caaeSpatrick __alloc_func* __clone() const
19176d0caaeSpatrick {
19276d0caaeSpatrick typedef allocator_traits<_Alloc> __alloc_traits;
193*4bdff4beSrobert typedef __rebind_alloc<__alloc_traits, __alloc_func> _AA;
19476d0caaeSpatrick _AA __a(__f_.second());
19576d0caaeSpatrick typedef __allocator_destructor<_AA> _Dp;
19676d0caaeSpatrick unique_ptr<__alloc_func, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
19776d0caaeSpatrick ::new ((void*)__hold.get()) __alloc_func(__f_.first(), _Alloc(__a));
19876d0caaeSpatrick return __hold.release();
19976d0caaeSpatrick }
20076d0caaeSpatrick
20176d0caaeSpatrick _LIBCPP_INLINE_VISIBILITY
20276d0caaeSpatrick void destroy() _NOEXCEPT { __f_.~__compressed_pair<_Target, _Alloc>(); }
20376d0caaeSpatrick
20476d0caaeSpatrick static void __destroy_and_delete(__alloc_func* __f) {
20576d0caaeSpatrick typedef allocator_traits<_Alloc> __alloc_traits;
206*4bdff4beSrobert typedef __rebind_alloc<__alloc_traits, __alloc_func> _FunAlloc;
20776d0caaeSpatrick _FunAlloc __a(__f->__get_allocator());
20876d0caaeSpatrick __f->destroy();
20976d0caaeSpatrick __a.deallocate(__f, 1);
21076d0caaeSpatrick }
21176d0caaeSpatrick };
21276d0caaeSpatrick
21376d0caaeSpatrick template <class _Fp, class _Rp, class... _ArgTypes>
21476d0caaeSpatrick class __default_alloc_func<_Fp, _Rp(_ArgTypes...)> {
21576d0caaeSpatrick _Fp __f_;
21676d0caaeSpatrick
21776d0caaeSpatrick public:
218*4bdff4beSrobert typedef _LIBCPP_NODEBUG _Fp _Target;
21976d0caaeSpatrick
22076d0caaeSpatrick _LIBCPP_INLINE_VISIBILITY
22176d0caaeSpatrick const _Target& __target() const { return __f_; }
22276d0caaeSpatrick
22376d0caaeSpatrick _LIBCPP_INLINE_VISIBILITY
22476d0caaeSpatrick explicit __default_alloc_func(_Target&& __f) : __f_(_VSTD::move(__f)) {}
22576d0caaeSpatrick
22676d0caaeSpatrick _LIBCPP_INLINE_VISIBILITY
22776d0caaeSpatrick explicit __default_alloc_func(const _Target& __f) : __f_(__f) {}
22876d0caaeSpatrick
22976d0caaeSpatrick _LIBCPP_INLINE_VISIBILITY
23076d0caaeSpatrick _Rp operator()(_ArgTypes&&... __arg) {
23176d0caaeSpatrick typedef __invoke_void_return_wrapper<_Rp> _Invoker;
23276d0caaeSpatrick return _Invoker::__call(__f_, _VSTD::forward<_ArgTypes>(__arg)...);
23376d0caaeSpatrick }
23476d0caaeSpatrick
23576d0caaeSpatrick _LIBCPP_INLINE_VISIBILITY
23676d0caaeSpatrick __default_alloc_func* __clone() const {
23776d0caaeSpatrick __builtin_new_allocator::__holder_t __hold =
23876d0caaeSpatrick __builtin_new_allocator::__allocate_type<__default_alloc_func>(1);
23976d0caaeSpatrick __default_alloc_func* __res =
24076d0caaeSpatrick ::new ((void*)__hold.get()) __default_alloc_func(__f_);
24176d0caaeSpatrick (void)__hold.release();
24276d0caaeSpatrick return __res;
24376d0caaeSpatrick }
24476d0caaeSpatrick
24576d0caaeSpatrick _LIBCPP_INLINE_VISIBILITY
24676d0caaeSpatrick void destroy() _NOEXCEPT { __f_.~_Target(); }
24776d0caaeSpatrick
24876d0caaeSpatrick static void __destroy_and_delete(__default_alloc_func* __f) {
24976d0caaeSpatrick __f->destroy();
25076d0caaeSpatrick __builtin_new_allocator::__deallocate_type<__default_alloc_func>(__f, 1);
25176d0caaeSpatrick }
25276d0caaeSpatrick };
25376d0caaeSpatrick
25476d0caaeSpatrick // __base provides an abstract interface for copyable functors.
25576d0caaeSpatrick
25676d0caaeSpatrick template<class _Fp> class _LIBCPP_TEMPLATE_VIS __base;
25776d0caaeSpatrick
25876d0caaeSpatrick template<class _Rp, class ..._ArgTypes>
25976d0caaeSpatrick class __base<_Rp(_ArgTypes...)>
26076d0caaeSpatrick {
26176d0caaeSpatrick __base(const __base&);
26276d0caaeSpatrick __base& operator=(const __base&);
26376d0caaeSpatrick public:
26476d0caaeSpatrick _LIBCPP_INLINE_VISIBILITY __base() {}
265*4bdff4beSrobert _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual ~__base() {}
26676d0caaeSpatrick virtual __base* __clone() const = 0;
26776d0caaeSpatrick virtual void __clone(__base*) const = 0;
26876d0caaeSpatrick virtual void destroy() _NOEXCEPT = 0;
26976d0caaeSpatrick virtual void destroy_deallocate() _NOEXCEPT = 0;
27076d0caaeSpatrick virtual _Rp operator()(_ArgTypes&& ...) = 0;
271*4bdff4beSrobert #ifndef _LIBCPP_HAS_NO_RTTI
27276d0caaeSpatrick virtual const void* target(const type_info&) const _NOEXCEPT = 0;
27376d0caaeSpatrick virtual const std::type_info& target_type() const _NOEXCEPT = 0;
274*4bdff4beSrobert #endif // _LIBCPP_HAS_NO_RTTI
27576d0caaeSpatrick };
27676d0caaeSpatrick
27776d0caaeSpatrick // __func implements __base for a given functor type.
27876d0caaeSpatrick
27976d0caaeSpatrick template<class _FD, class _Alloc, class _FB> class __func;
28076d0caaeSpatrick
28176d0caaeSpatrick template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
28276d0caaeSpatrick class __func<_Fp, _Alloc, _Rp(_ArgTypes...)>
28376d0caaeSpatrick : public __base<_Rp(_ArgTypes...)>
28476d0caaeSpatrick {
28576d0caaeSpatrick __alloc_func<_Fp, _Alloc, _Rp(_ArgTypes...)> __f_;
28676d0caaeSpatrick public:
28776d0caaeSpatrick _LIBCPP_INLINE_VISIBILITY
28876d0caaeSpatrick explicit __func(_Fp&& __f)
28976d0caaeSpatrick : __f_(_VSTD::move(__f)) {}
29076d0caaeSpatrick
29176d0caaeSpatrick _LIBCPP_INLINE_VISIBILITY
29276d0caaeSpatrick explicit __func(const _Fp& __f, const _Alloc& __a)
29376d0caaeSpatrick : __f_(__f, __a) {}
29476d0caaeSpatrick
29576d0caaeSpatrick _LIBCPP_INLINE_VISIBILITY
29676d0caaeSpatrick explicit __func(const _Fp& __f, _Alloc&& __a)
29776d0caaeSpatrick : __f_(__f, _VSTD::move(__a)) {}
29876d0caaeSpatrick
29976d0caaeSpatrick _LIBCPP_INLINE_VISIBILITY
30076d0caaeSpatrick explicit __func(_Fp&& __f, _Alloc&& __a)
30176d0caaeSpatrick : __f_(_VSTD::move(__f), _VSTD::move(__a)) {}
30276d0caaeSpatrick
30376d0caaeSpatrick virtual __base<_Rp(_ArgTypes...)>* __clone() const;
30476d0caaeSpatrick virtual void __clone(__base<_Rp(_ArgTypes...)>*) const;
30576d0caaeSpatrick virtual void destroy() _NOEXCEPT;
30676d0caaeSpatrick virtual void destroy_deallocate() _NOEXCEPT;
30776d0caaeSpatrick virtual _Rp operator()(_ArgTypes&&... __arg);
308*4bdff4beSrobert #ifndef _LIBCPP_HAS_NO_RTTI
30976d0caaeSpatrick virtual const void* target(const type_info&) const _NOEXCEPT;
31076d0caaeSpatrick virtual const std::type_info& target_type() const _NOEXCEPT;
311*4bdff4beSrobert #endif // _LIBCPP_HAS_NO_RTTI
31276d0caaeSpatrick };
31376d0caaeSpatrick
31476d0caaeSpatrick template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
31576d0caaeSpatrick __base<_Rp(_ArgTypes...)>*
31676d0caaeSpatrick __func<_Fp, _Alloc, _Rp(_ArgTypes...)>::__clone() const
31776d0caaeSpatrick {
31876d0caaeSpatrick typedef allocator_traits<_Alloc> __alloc_traits;
319*4bdff4beSrobert typedef __rebind_alloc<__alloc_traits, __func> _Ap;
32076d0caaeSpatrick _Ap __a(__f_.__get_allocator());
32176d0caaeSpatrick typedef __allocator_destructor<_Ap> _Dp;
32276d0caaeSpatrick unique_ptr<__func, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
32376d0caaeSpatrick ::new ((void*)__hold.get()) __func(__f_.__target(), _Alloc(__a));
32476d0caaeSpatrick return __hold.release();
32576d0caaeSpatrick }
32676d0caaeSpatrick
32776d0caaeSpatrick template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
32876d0caaeSpatrick void
32976d0caaeSpatrick __func<_Fp, _Alloc, _Rp(_ArgTypes...)>::__clone(__base<_Rp(_ArgTypes...)>* __p) const
33076d0caaeSpatrick {
33176d0caaeSpatrick ::new ((void*)__p) __func(__f_.__target(), __f_.__get_allocator());
33276d0caaeSpatrick }
33376d0caaeSpatrick
33476d0caaeSpatrick template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
33576d0caaeSpatrick void
33676d0caaeSpatrick __func<_Fp, _Alloc, _Rp(_ArgTypes...)>::destroy() _NOEXCEPT
33776d0caaeSpatrick {
33876d0caaeSpatrick __f_.destroy();
33976d0caaeSpatrick }
34076d0caaeSpatrick
34176d0caaeSpatrick template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
34276d0caaeSpatrick void
34376d0caaeSpatrick __func<_Fp, _Alloc, _Rp(_ArgTypes...)>::destroy_deallocate() _NOEXCEPT
34476d0caaeSpatrick {
34576d0caaeSpatrick typedef allocator_traits<_Alloc> __alloc_traits;
346*4bdff4beSrobert typedef __rebind_alloc<__alloc_traits, __func> _Ap;
34776d0caaeSpatrick _Ap __a(__f_.__get_allocator());
34876d0caaeSpatrick __f_.destroy();
34976d0caaeSpatrick __a.deallocate(this, 1);
35076d0caaeSpatrick }
35176d0caaeSpatrick
35276d0caaeSpatrick template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
35376d0caaeSpatrick _Rp
35476d0caaeSpatrick __func<_Fp, _Alloc, _Rp(_ArgTypes...)>::operator()(_ArgTypes&& ... __arg)
35576d0caaeSpatrick {
35676d0caaeSpatrick return __f_(_VSTD::forward<_ArgTypes>(__arg)...);
35776d0caaeSpatrick }
35876d0caaeSpatrick
359*4bdff4beSrobert #ifndef _LIBCPP_HAS_NO_RTTI
36076d0caaeSpatrick
36176d0caaeSpatrick template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
36276d0caaeSpatrick const void*
36376d0caaeSpatrick __func<_Fp, _Alloc, _Rp(_ArgTypes...)>::target(const type_info& __ti) const _NOEXCEPT
36476d0caaeSpatrick {
36576d0caaeSpatrick if (__ti == typeid(_Fp))
366*4bdff4beSrobert return _VSTD::addressof(__f_.__target());
36776d0caaeSpatrick return nullptr;
36876d0caaeSpatrick }
36976d0caaeSpatrick
37076d0caaeSpatrick template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
37176d0caaeSpatrick const std::type_info&
37276d0caaeSpatrick __func<_Fp, _Alloc, _Rp(_ArgTypes...)>::target_type() const _NOEXCEPT
37376d0caaeSpatrick {
37476d0caaeSpatrick return typeid(_Fp);
37576d0caaeSpatrick }
37676d0caaeSpatrick
377*4bdff4beSrobert #endif // _LIBCPP_HAS_NO_RTTI
37876d0caaeSpatrick
37976d0caaeSpatrick // __value_func creates a value-type from a __func.
38076d0caaeSpatrick
38176d0caaeSpatrick template <class _Fp> class __value_func;
38276d0caaeSpatrick
38376d0caaeSpatrick template <class _Rp, class... _ArgTypes> class __value_func<_Rp(_ArgTypes...)>
38476d0caaeSpatrick {
385*4bdff4beSrobert _LIBCPP_SUPPRESS_DEPRECATED_PUSH
38676d0caaeSpatrick typename aligned_storage<3 * sizeof(void*)>::type __buf_;
387*4bdff4beSrobert _LIBCPP_SUPPRESS_DEPRECATED_POP
38876d0caaeSpatrick
38976d0caaeSpatrick typedef __base<_Rp(_ArgTypes...)> __func;
39076d0caaeSpatrick __func* __f_;
39176d0caaeSpatrick
392*4bdff4beSrobert _LIBCPP_NO_CFI static __func* __as_base(void* __p)
39376d0caaeSpatrick {
394*4bdff4beSrobert return reinterpret_cast<__func*>(__p);
39576d0caaeSpatrick }
39676d0caaeSpatrick
39776d0caaeSpatrick public:
39876d0caaeSpatrick _LIBCPP_INLINE_VISIBILITY
39976d0caaeSpatrick __value_func() _NOEXCEPT : __f_(nullptr) {}
40076d0caaeSpatrick
40176d0caaeSpatrick template <class _Fp, class _Alloc>
40276d0caaeSpatrick _LIBCPP_INLINE_VISIBILITY __value_func(_Fp&& __f, const _Alloc& __a)
40376d0caaeSpatrick : __f_(nullptr)
40476d0caaeSpatrick {
40576d0caaeSpatrick typedef allocator_traits<_Alloc> __alloc_traits;
40676d0caaeSpatrick typedef __function::__func<_Fp, _Alloc, _Rp(_ArgTypes...)> _Fun;
407*4bdff4beSrobert typedef __rebind_alloc<__alloc_traits, _Fun> _FunAlloc;
40876d0caaeSpatrick
40976d0caaeSpatrick if (__function::__not_null(__f))
41076d0caaeSpatrick {
41176d0caaeSpatrick _FunAlloc __af(__a);
41276d0caaeSpatrick if (sizeof(_Fun) <= sizeof(__buf_) &&
41376d0caaeSpatrick is_nothrow_copy_constructible<_Fp>::value &&
41476d0caaeSpatrick is_nothrow_copy_constructible<_FunAlloc>::value)
41576d0caaeSpatrick {
41676d0caaeSpatrick __f_ =
41776d0caaeSpatrick ::new ((void*)&__buf_) _Fun(_VSTD::move(__f), _Alloc(__af));
41876d0caaeSpatrick }
41976d0caaeSpatrick else
42076d0caaeSpatrick {
42176d0caaeSpatrick typedef __allocator_destructor<_FunAlloc> _Dp;
42276d0caaeSpatrick unique_ptr<__func, _Dp> __hold(__af.allocate(1), _Dp(__af, 1));
42376d0caaeSpatrick ::new ((void*)__hold.get()) _Fun(_VSTD::move(__f), _Alloc(__a));
42476d0caaeSpatrick __f_ = __hold.release();
42576d0caaeSpatrick }
42676d0caaeSpatrick }
42776d0caaeSpatrick }
42876d0caaeSpatrick
42976d0caaeSpatrick template <class _Fp,
43076d0caaeSpatrick class = typename enable_if<!is_same<typename decay<_Fp>::type, __value_func>::value>::type>
43176d0caaeSpatrick _LIBCPP_INLINE_VISIBILITY explicit __value_func(_Fp&& __f)
43276d0caaeSpatrick : __value_func(_VSTD::forward<_Fp>(__f), allocator<_Fp>()) {}
43376d0caaeSpatrick
43476d0caaeSpatrick _LIBCPP_INLINE_VISIBILITY
43576d0caaeSpatrick __value_func(const __value_func& __f)
43676d0caaeSpatrick {
43776d0caaeSpatrick if (__f.__f_ == nullptr)
43876d0caaeSpatrick __f_ = nullptr;
43976d0caaeSpatrick else if ((void*)__f.__f_ == &__f.__buf_)
44076d0caaeSpatrick {
44176d0caaeSpatrick __f_ = __as_base(&__buf_);
44276d0caaeSpatrick __f.__f_->__clone(__f_);
44376d0caaeSpatrick }
44476d0caaeSpatrick else
44576d0caaeSpatrick __f_ = __f.__f_->__clone();
44676d0caaeSpatrick }
44776d0caaeSpatrick
44876d0caaeSpatrick _LIBCPP_INLINE_VISIBILITY
44976d0caaeSpatrick __value_func(__value_func&& __f) _NOEXCEPT
45076d0caaeSpatrick {
45176d0caaeSpatrick if (__f.__f_ == nullptr)
45276d0caaeSpatrick __f_ = nullptr;
45376d0caaeSpatrick else if ((void*)__f.__f_ == &__f.__buf_)
45476d0caaeSpatrick {
45576d0caaeSpatrick __f_ = __as_base(&__buf_);
45676d0caaeSpatrick __f.__f_->__clone(__f_);
45776d0caaeSpatrick }
45876d0caaeSpatrick else
45976d0caaeSpatrick {
46076d0caaeSpatrick __f_ = __f.__f_;
46176d0caaeSpatrick __f.__f_ = nullptr;
46276d0caaeSpatrick }
46376d0caaeSpatrick }
46476d0caaeSpatrick
46576d0caaeSpatrick _LIBCPP_INLINE_VISIBILITY
46676d0caaeSpatrick ~__value_func()
46776d0caaeSpatrick {
46876d0caaeSpatrick if ((void*)__f_ == &__buf_)
46976d0caaeSpatrick __f_->destroy();
47076d0caaeSpatrick else if (__f_)
47176d0caaeSpatrick __f_->destroy_deallocate();
47276d0caaeSpatrick }
47376d0caaeSpatrick
47476d0caaeSpatrick _LIBCPP_INLINE_VISIBILITY
47576d0caaeSpatrick __value_func& operator=(__value_func&& __f)
47676d0caaeSpatrick {
47776d0caaeSpatrick *this = nullptr;
47876d0caaeSpatrick if (__f.__f_ == nullptr)
47976d0caaeSpatrick __f_ = nullptr;
48076d0caaeSpatrick else if ((void*)__f.__f_ == &__f.__buf_)
48176d0caaeSpatrick {
48276d0caaeSpatrick __f_ = __as_base(&__buf_);
48376d0caaeSpatrick __f.__f_->__clone(__f_);
48476d0caaeSpatrick }
48576d0caaeSpatrick else
48676d0caaeSpatrick {
48776d0caaeSpatrick __f_ = __f.__f_;
48876d0caaeSpatrick __f.__f_ = nullptr;
48976d0caaeSpatrick }
49076d0caaeSpatrick return *this;
49176d0caaeSpatrick }
49276d0caaeSpatrick
49376d0caaeSpatrick _LIBCPP_INLINE_VISIBILITY
49476d0caaeSpatrick __value_func& operator=(nullptr_t)
49576d0caaeSpatrick {
49676d0caaeSpatrick __func* __f = __f_;
49776d0caaeSpatrick __f_ = nullptr;
49876d0caaeSpatrick if ((void*)__f == &__buf_)
49976d0caaeSpatrick __f->destroy();
50076d0caaeSpatrick else if (__f)
50176d0caaeSpatrick __f->destroy_deallocate();
50276d0caaeSpatrick return *this;
50376d0caaeSpatrick }
50476d0caaeSpatrick
50576d0caaeSpatrick _LIBCPP_INLINE_VISIBILITY
50676d0caaeSpatrick _Rp operator()(_ArgTypes&&... __args) const
50776d0caaeSpatrick {
50876d0caaeSpatrick if (__f_ == nullptr)
50976d0caaeSpatrick __throw_bad_function_call();
51076d0caaeSpatrick return (*__f_)(_VSTD::forward<_ArgTypes>(__args)...);
51176d0caaeSpatrick }
51276d0caaeSpatrick
51376d0caaeSpatrick _LIBCPP_INLINE_VISIBILITY
51476d0caaeSpatrick void swap(__value_func& __f) _NOEXCEPT
51576d0caaeSpatrick {
51676d0caaeSpatrick if (&__f == this)
51776d0caaeSpatrick return;
51876d0caaeSpatrick if ((void*)__f_ == &__buf_ && (void*)__f.__f_ == &__f.__buf_)
51976d0caaeSpatrick {
520*4bdff4beSrobert _LIBCPP_SUPPRESS_DEPRECATED_PUSH
52176d0caaeSpatrick typename aligned_storage<sizeof(__buf_)>::type __tempbuf;
522*4bdff4beSrobert _LIBCPP_SUPPRESS_DEPRECATED_POP
52376d0caaeSpatrick __func* __t = __as_base(&__tempbuf);
52476d0caaeSpatrick __f_->__clone(__t);
52576d0caaeSpatrick __f_->destroy();
52676d0caaeSpatrick __f_ = nullptr;
52776d0caaeSpatrick __f.__f_->__clone(__as_base(&__buf_));
52876d0caaeSpatrick __f.__f_->destroy();
52976d0caaeSpatrick __f.__f_ = nullptr;
53076d0caaeSpatrick __f_ = __as_base(&__buf_);
53176d0caaeSpatrick __t->__clone(__as_base(&__f.__buf_));
53276d0caaeSpatrick __t->destroy();
53376d0caaeSpatrick __f.__f_ = __as_base(&__f.__buf_);
53476d0caaeSpatrick }
53576d0caaeSpatrick else if ((void*)__f_ == &__buf_)
53676d0caaeSpatrick {
53776d0caaeSpatrick __f_->__clone(__as_base(&__f.__buf_));
53876d0caaeSpatrick __f_->destroy();
53976d0caaeSpatrick __f_ = __f.__f_;
54076d0caaeSpatrick __f.__f_ = __as_base(&__f.__buf_);
54176d0caaeSpatrick }
54276d0caaeSpatrick else if ((void*)__f.__f_ == &__f.__buf_)
54376d0caaeSpatrick {
54476d0caaeSpatrick __f.__f_->__clone(__as_base(&__buf_));
54576d0caaeSpatrick __f.__f_->destroy();
54676d0caaeSpatrick __f.__f_ = __f_;
54776d0caaeSpatrick __f_ = __as_base(&__buf_);
54876d0caaeSpatrick }
54976d0caaeSpatrick else
55076d0caaeSpatrick _VSTD::swap(__f_, __f.__f_);
55176d0caaeSpatrick }
55276d0caaeSpatrick
55376d0caaeSpatrick _LIBCPP_INLINE_VISIBILITY
55476d0caaeSpatrick explicit operator bool() const _NOEXCEPT { return __f_ != nullptr; }
55576d0caaeSpatrick
556*4bdff4beSrobert #ifndef _LIBCPP_HAS_NO_RTTI
55776d0caaeSpatrick _LIBCPP_INLINE_VISIBILITY
55876d0caaeSpatrick const std::type_info& target_type() const _NOEXCEPT
55976d0caaeSpatrick {
56076d0caaeSpatrick if (__f_ == nullptr)
56176d0caaeSpatrick return typeid(void);
56276d0caaeSpatrick return __f_->target_type();
56376d0caaeSpatrick }
56476d0caaeSpatrick
56576d0caaeSpatrick template <typename _Tp>
56676d0caaeSpatrick _LIBCPP_INLINE_VISIBILITY const _Tp* target() const _NOEXCEPT
56776d0caaeSpatrick {
56876d0caaeSpatrick if (__f_ == nullptr)
56976d0caaeSpatrick return nullptr;
57076d0caaeSpatrick return (const _Tp*)__f_->target(typeid(_Tp));
57176d0caaeSpatrick }
572*4bdff4beSrobert #endif // _LIBCPP_HAS_NO_RTTI
57376d0caaeSpatrick };
57476d0caaeSpatrick
57576d0caaeSpatrick // Storage for a functor object, to be used with __policy to manage copy and
57676d0caaeSpatrick // destruction.
57776d0caaeSpatrick union __policy_storage
57876d0caaeSpatrick {
57976d0caaeSpatrick mutable char __small[sizeof(void*) * 2];
58076d0caaeSpatrick void* __large;
58176d0caaeSpatrick };
58276d0caaeSpatrick
58376d0caaeSpatrick // True if _Fun can safely be held in __policy_storage.__small.
58476d0caaeSpatrick template <typename _Fun>
58576d0caaeSpatrick struct __use_small_storage
58676d0caaeSpatrick : public integral_constant<
58776d0caaeSpatrick bool, sizeof(_Fun) <= sizeof(__policy_storage) &&
58876d0caaeSpatrick _LIBCPP_ALIGNOF(_Fun) <= _LIBCPP_ALIGNOF(__policy_storage) &&
58976d0caaeSpatrick is_trivially_copy_constructible<_Fun>::value &&
59076d0caaeSpatrick is_trivially_destructible<_Fun>::value> {};
59176d0caaeSpatrick
59276d0caaeSpatrick // Policy contains information about how to copy, destroy, and move the
59376d0caaeSpatrick // underlying functor. You can think of it as a vtable of sorts.
59476d0caaeSpatrick struct __policy
59576d0caaeSpatrick {
59676d0caaeSpatrick // Used to copy or destroy __large values. null for trivial objects.
59776d0caaeSpatrick void* (*const __clone)(const void*);
59876d0caaeSpatrick void (*const __destroy)(void*);
59976d0caaeSpatrick
60076d0caaeSpatrick // True if this is the null policy (no value).
60176d0caaeSpatrick const bool __is_null;
60276d0caaeSpatrick
60376d0caaeSpatrick // The target type. May be null if RTTI is disabled.
60476d0caaeSpatrick const std::type_info* const __type_info;
60576d0caaeSpatrick
60676d0caaeSpatrick // Returns a pointer to a static policy object suitable for the functor
60776d0caaeSpatrick // type.
60876d0caaeSpatrick template <typename _Fun>
60976d0caaeSpatrick _LIBCPP_INLINE_VISIBILITY static const __policy* __create()
61076d0caaeSpatrick {
61176d0caaeSpatrick return __choose_policy<_Fun>(__use_small_storage<_Fun>());
61276d0caaeSpatrick }
61376d0caaeSpatrick
61476d0caaeSpatrick _LIBCPP_INLINE_VISIBILITY
61576d0caaeSpatrick static const __policy* __create_empty()
61676d0caaeSpatrick {
61776d0caaeSpatrick static const _LIBCPP_CONSTEXPR __policy __policy_ = {nullptr, nullptr,
61876d0caaeSpatrick true,
619*4bdff4beSrobert #ifndef _LIBCPP_HAS_NO_RTTI
62076d0caaeSpatrick &typeid(void)
62176d0caaeSpatrick #else
62276d0caaeSpatrick nullptr
62376d0caaeSpatrick #endif
62476d0caaeSpatrick };
62576d0caaeSpatrick return &__policy_;
62676d0caaeSpatrick }
62776d0caaeSpatrick
62876d0caaeSpatrick private:
62976d0caaeSpatrick template <typename _Fun> static void* __large_clone(const void* __s)
63076d0caaeSpatrick {
63176d0caaeSpatrick const _Fun* __f = static_cast<const _Fun*>(__s);
63276d0caaeSpatrick return __f->__clone();
63376d0caaeSpatrick }
63476d0caaeSpatrick
63576d0caaeSpatrick template <typename _Fun>
63676d0caaeSpatrick static void __large_destroy(void* __s) {
63776d0caaeSpatrick _Fun::__destroy_and_delete(static_cast<_Fun*>(__s));
63876d0caaeSpatrick }
63976d0caaeSpatrick
64076d0caaeSpatrick template <typename _Fun>
64176d0caaeSpatrick _LIBCPP_INLINE_VISIBILITY static const __policy*
64276d0caaeSpatrick __choose_policy(/* is_small = */ false_type) {
64376d0caaeSpatrick static const _LIBCPP_CONSTEXPR __policy __policy_ = {
64476d0caaeSpatrick &__large_clone<_Fun>, &__large_destroy<_Fun>, false,
645*4bdff4beSrobert #ifndef _LIBCPP_HAS_NO_RTTI
64676d0caaeSpatrick &typeid(typename _Fun::_Target)
64776d0caaeSpatrick #else
64876d0caaeSpatrick nullptr
64976d0caaeSpatrick #endif
65076d0caaeSpatrick };
65176d0caaeSpatrick return &__policy_;
65276d0caaeSpatrick }
65376d0caaeSpatrick
65476d0caaeSpatrick template <typename _Fun>
65576d0caaeSpatrick _LIBCPP_INLINE_VISIBILITY static const __policy*
65676d0caaeSpatrick __choose_policy(/* is_small = */ true_type)
65776d0caaeSpatrick {
65876d0caaeSpatrick static const _LIBCPP_CONSTEXPR __policy __policy_ = {
65976d0caaeSpatrick nullptr, nullptr, false,
660*4bdff4beSrobert #ifndef _LIBCPP_HAS_NO_RTTI
66176d0caaeSpatrick &typeid(typename _Fun::_Target)
66276d0caaeSpatrick #else
66376d0caaeSpatrick nullptr
66476d0caaeSpatrick #endif
66576d0caaeSpatrick };
66676d0caaeSpatrick return &__policy_;
66776d0caaeSpatrick }
66876d0caaeSpatrick };
66976d0caaeSpatrick
67076d0caaeSpatrick // Used to choose between perfect forwarding or pass-by-value. Pass-by-value is
67176d0caaeSpatrick // faster for types that can be passed in registers.
67276d0caaeSpatrick template <typename _Tp>
673*4bdff4beSrobert using __fast_forward = __conditional_t<is_scalar<_Tp>::value, _Tp, _Tp&&>;
67476d0caaeSpatrick
67576d0caaeSpatrick // __policy_invoker calls an instance of __alloc_func held in __policy_storage.
67676d0caaeSpatrick
67776d0caaeSpatrick template <class _Fp> struct __policy_invoker;
67876d0caaeSpatrick
67976d0caaeSpatrick template <class _Rp, class... _ArgTypes>
68076d0caaeSpatrick struct __policy_invoker<_Rp(_ArgTypes...)>
68176d0caaeSpatrick {
68276d0caaeSpatrick typedef _Rp (*__Call)(const __policy_storage*,
68376d0caaeSpatrick __fast_forward<_ArgTypes>...);
68476d0caaeSpatrick
68576d0caaeSpatrick __Call __call_;
68676d0caaeSpatrick
68776d0caaeSpatrick // Creates an invoker that throws bad_function_call.
68876d0caaeSpatrick _LIBCPP_INLINE_VISIBILITY
68976d0caaeSpatrick __policy_invoker() : __call_(&__call_empty) {}
69076d0caaeSpatrick
69176d0caaeSpatrick // Creates an invoker that calls the given instance of __func.
69276d0caaeSpatrick template <typename _Fun>
69376d0caaeSpatrick _LIBCPP_INLINE_VISIBILITY static __policy_invoker __create()
69476d0caaeSpatrick {
69576d0caaeSpatrick return __policy_invoker(&__call_impl<_Fun>);
69676d0caaeSpatrick }
69776d0caaeSpatrick
69876d0caaeSpatrick private:
69976d0caaeSpatrick _LIBCPP_INLINE_VISIBILITY
70076d0caaeSpatrick explicit __policy_invoker(__Call __c) : __call_(__c) {}
70176d0caaeSpatrick
70276d0caaeSpatrick static _Rp __call_empty(const __policy_storage*,
70376d0caaeSpatrick __fast_forward<_ArgTypes>...)
70476d0caaeSpatrick {
70576d0caaeSpatrick __throw_bad_function_call();
70676d0caaeSpatrick }
70776d0caaeSpatrick
70876d0caaeSpatrick template <typename _Fun>
70976d0caaeSpatrick static _Rp __call_impl(const __policy_storage* __buf,
71076d0caaeSpatrick __fast_forward<_ArgTypes>... __args)
71176d0caaeSpatrick {
71276d0caaeSpatrick _Fun* __f = reinterpret_cast<_Fun*>(__use_small_storage<_Fun>::value
71376d0caaeSpatrick ? &__buf->__small
71476d0caaeSpatrick : __buf->__large);
71576d0caaeSpatrick return (*__f)(_VSTD::forward<_ArgTypes>(__args)...);
71676d0caaeSpatrick }
71776d0caaeSpatrick };
71876d0caaeSpatrick
71976d0caaeSpatrick // __policy_func uses a __policy and __policy_invoker to create a type-erased,
72076d0caaeSpatrick // copyable functor.
72176d0caaeSpatrick
72276d0caaeSpatrick template <class _Fp> class __policy_func;
72376d0caaeSpatrick
72476d0caaeSpatrick template <class _Rp, class... _ArgTypes> class __policy_func<_Rp(_ArgTypes...)>
72576d0caaeSpatrick {
72676d0caaeSpatrick // Inline storage for small objects.
72776d0caaeSpatrick __policy_storage __buf_;
72876d0caaeSpatrick
72976d0caaeSpatrick // Calls the value stored in __buf_. This could technically be part of
73076d0caaeSpatrick // policy, but storing it here eliminates a level of indirection inside
73176d0caaeSpatrick // operator().
73276d0caaeSpatrick typedef __function::__policy_invoker<_Rp(_ArgTypes...)> __invoker;
73376d0caaeSpatrick __invoker __invoker_;
73476d0caaeSpatrick
73576d0caaeSpatrick // The policy that describes how to move / copy / destroy __buf_. Never
73676d0caaeSpatrick // null, even if the function is empty.
73776d0caaeSpatrick const __policy* __policy_;
73876d0caaeSpatrick
73976d0caaeSpatrick public:
74076d0caaeSpatrick _LIBCPP_INLINE_VISIBILITY
74176d0caaeSpatrick __policy_func() : __policy_(__policy::__create_empty()) {}
74276d0caaeSpatrick
74376d0caaeSpatrick template <class _Fp, class _Alloc>
74476d0caaeSpatrick _LIBCPP_INLINE_VISIBILITY __policy_func(_Fp&& __f, const _Alloc& __a)
74576d0caaeSpatrick : __policy_(__policy::__create_empty())
74676d0caaeSpatrick {
74776d0caaeSpatrick typedef __alloc_func<_Fp, _Alloc, _Rp(_ArgTypes...)> _Fun;
74876d0caaeSpatrick typedef allocator_traits<_Alloc> __alloc_traits;
749*4bdff4beSrobert typedef __rebind_alloc<__alloc_traits, _Fun> _FunAlloc;
75076d0caaeSpatrick
75176d0caaeSpatrick if (__function::__not_null(__f))
75276d0caaeSpatrick {
75376d0caaeSpatrick __invoker_ = __invoker::template __create<_Fun>();
75476d0caaeSpatrick __policy_ = __policy::__create<_Fun>();
75576d0caaeSpatrick
75676d0caaeSpatrick _FunAlloc __af(__a);
75776d0caaeSpatrick if (__use_small_storage<_Fun>())
75876d0caaeSpatrick {
75976d0caaeSpatrick ::new ((void*)&__buf_.__small)
76076d0caaeSpatrick _Fun(_VSTD::move(__f), _Alloc(__af));
76176d0caaeSpatrick }
76276d0caaeSpatrick else
76376d0caaeSpatrick {
76476d0caaeSpatrick typedef __allocator_destructor<_FunAlloc> _Dp;
76576d0caaeSpatrick unique_ptr<_Fun, _Dp> __hold(__af.allocate(1), _Dp(__af, 1));
76676d0caaeSpatrick ::new ((void*)__hold.get())
76776d0caaeSpatrick _Fun(_VSTD::move(__f), _Alloc(__af));
76876d0caaeSpatrick __buf_.__large = __hold.release();
76976d0caaeSpatrick }
77076d0caaeSpatrick }
77176d0caaeSpatrick }
77276d0caaeSpatrick
77376d0caaeSpatrick template <class _Fp, class = typename enable_if<!is_same<typename decay<_Fp>::type, __policy_func>::value>::type>
77476d0caaeSpatrick _LIBCPP_INLINE_VISIBILITY explicit __policy_func(_Fp&& __f)
77576d0caaeSpatrick : __policy_(__policy::__create_empty()) {
77676d0caaeSpatrick typedef __default_alloc_func<_Fp, _Rp(_ArgTypes...)> _Fun;
77776d0caaeSpatrick
77876d0caaeSpatrick if (__function::__not_null(__f)) {
77976d0caaeSpatrick __invoker_ = __invoker::template __create<_Fun>();
78076d0caaeSpatrick __policy_ = __policy::__create<_Fun>();
78176d0caaeSpatrick if (__use_small_storage<_Fun>()) {
78276d0caaeSpatrick ::new ((void*)&__buf_.__small) _Fun(_VSTD::move(__f));
78376d0caaeSpatrick } else {
78476d0caaeSpatrick __builtin_new_allocator::__holder_t __hold =
78576d0caaeSpatrick __builtin_new_allocator::__allocate_type<_Fun>(1);
78676d0caaeSpatrick __buf_.__large = ::new ((void*)__hold.get()) _Fun(_VSTD::move(__f));
78776d0caaeSpatrick (void)__hold.release();
78876d0caaeSpatrick }
78976d0caaeSpatrick }
79076d0caaeSpatrick }
79176d0caaeSpatrick
79276d0caaeSpatrick _LIBCPP_INLINE_VISIBILITY
79376d0caaeSpatrick __policy_func(const __policy_func& __f)
79476d0caaeSpatrick : __buf_(__f.__buf_), __invoker_(__f.__invoker_),
79576d0caaeSpatrick __policy_(__f.__policy_)
79676d0caaeSpatrick {
79776d0caaeSpatrick if (__policy_->__clone)
79876d0caaeSpatrick __buf_.__large = __policy_->__clone(__f.__buf_.__large);
79976d0caaeSpatrick }
80076d0caaeSpatrick
80176d0caaeSpatrick _LIBCPP_INLINE_VISIBILITY
80276d0caaeSpatrick __policy_func(__policy_func&& __f)
80376d0caaeSpatrick : __buf_(__f.__buf_), __invoker_(__f.__invoker_),
80476d0caaeSpatrick __policy_(__f.__policy_)
80576d0caaeSpatrick {
80676d0caaeSpatrick if (__policy_->__destroy)
80776d0caaeSpatrick {
80876d0caaeSpatrick __f.__policy_ = __policy::__create_empty();
80976d0caaeSpatrick __f.__invoker_ = __invoker();
81076d0caaeSpatrick }
81176d0caaeSpatrick }
81276d0caaeSpatrick
81376d0caaeSpatrick _LIBCPP_INLINE_VISIBILITY
81476d0caaeSpatrick ~__policy_func()
81576d0caaeSpatrick {
81676d0caaeSpatrick if (__policy_->__destroy)
81776d0caaeSpatrick __policy_->__destroy(__buf_.__large);
81876d0caaeSpatrick }
81976d0caaeSpatrick
82076d0caaeSpatrick _LIBCPP_INLINE_VISIBILITY
82176d0caaeSpatrick __policy_func& operator=(__policy_func&& __f)
82276d0caaeSpatrick {
82376d0caaeSpatrick *this = nullptr;
82476d0caaeSpatrick __buf_ = __f.__buf_;
82576d0caaeSpatrick __invoker_ = __f.__invoker_;
82676d0caaeSpatrick __policy_ = __f.__policy_;
82776d0caaeSpatrick __f.__policy_ = __policy::__create_empty();
82876d0caaeSpatrick __f.__invoker_ = __invoker();
82976d0caaeSpatrick return *this;
83076d0caaeSpatrick }
83176d0caaeSpatrick
83276d0caaeSpatrick _LIBCPP_INLINE_VISIBILITY
83376d0caaeSpatrick __policy_func& operator=(nullptr_t)
83476d0caaeSpatrick {
83576d0caaeSpatrick const __policy* __p = __policy_;
83676d0caaeSpatrick __policy_ = __policy::__create_empty();
83776d0caaeSpatrick __invoker_ = __invoker();
83876d0caaeSpatrick if (__p->__destroy)
83976d0caaeSpatrick __p->__destroy(__buf_.__large);
84076d0caaeSpatrick return *this;
84176d0caaeSpatrick }
84276d0caaeSpatrick
84376d0caaeSpatrick _LIBCPP_INLINE_VISIBILITY
84476d0caaeSpatrick _Rp operator()(_ArgTypes&&... __args) const
84576d0caaeSpatrick {
84676d0caaeSpatrick return __invoker_.__call_(_VSTD::addressof(__buf_),
84776d0caaeSpatrick _VSTD::forward<_ArgTypes>(__args)...);
84876d0caaeSpatrick }
84976d0caaeSpatrick
85076d0caaeSpatrick _LIBCPP_INLINE_VISIBILITY
85176d0caaeSpatrick void swap(__policy_func& __f)
85276d0caaeSpatrick {
85376d0caaeSpatrick _VSTD::swap(__invoker_, __f.__invoker_);
85476d0caaeSpatrick _VSTD::swap(__policy_, __f.__policy_);
85576d0caaeSpatrick _VSTD::swap(__buf_, __f.__buf_);
85676d0caaeSpatrick }
85776d0caaeSpatrick
85876d0caaeSpatrick _LIBCPP_INLINE_VISIBILITY
85976d0caaeSpatrick explicit operator bool() const _NOEXCEPT
86076d0caaeSpatrick {
86176d0caaeSpatrick return !__policy_->__is_null;
86276d0caaeSpatrick }
86376d0caaeSpatrick
864*4bdff4beSrobert #ifndef _LIBCPP_HAS_NO_RTTI
86576d0caaeSpatrick _LIBCPP_INLINE_VISIBILITY
86676d0caaeSpatrick const std::type_info& target_type() const _NOEXCEPT
86776d0caaeSpatrick {
86876d0caaeSpatrick return *__policy_->__type_info;
86976d0caaeSpatrick }
87076d0caaeSpatrick
87176d0caaeSpatrick template <typename _Tp>
87276d0caaeSpatrick _LIBCPP_INLINE_VISIBILITY const _Tp* target() const _NOEXCEPT
87376d0caaeSpatrick {
87476d0caaeSpatrick if (__policy_->__is_null || typeid(_Tp) != *__policy_->__type_info)
87576d0caaeSpatrick return nullptr;
87676d0caaeSpatrick if (__policy_->__clone) // Out of line storage.
87776d0caaeSpatrick return reinterpret_cast<const _Tp*>(__buf_.__large);
87876d0caaeSpatrick else
87976d0caaeSpatrick return reinterpret_cast<const _Tp*>(&__buf_.__small);
88076d0caaeSpatrick }
881*4bdff4beSrobert #endif // _LIBCPP_HAS_NO_RTTI
88276d0caaeSpatrick };
88376d0caaeSpatrick
884*4bdff4beSrobert #if defined(_LIBCPP_HAS_BLOCKS_RUNTIME)
88576d0caaeSpatrick
88676d0caaeSpatrick extern "C" void *_Block_copy(const void *);
88776d0caaeSpatrick extern "C" void _Block_release(const void *);
88876d0caaeSpatrick
88976d0caaeSpatrick template<class _Rp1, class ..._ArgTypes1, class _Alloc, class _Rp, class ..._ArgTypes>
89076d0caaeSpatrick class __func<_Rp1(^)(_ArgTypes1...), _Alloc, _Rp(_ArgTypes...)>
89176d0caaeSpatrick : public __base<_Rp(_ArgTypes...)>
89276d0caaeSpatrick {
89376d0caaeSpatrick typedef _Rp1(^__block_type)(_ArgTypes1...);
89476d0caaeSpatrick __block_type __f_;
89576d0caaeSpatrick
89676d0caaeSpatrick public:
89776d0caaeSpatrick _LIBCPP_INLINE_VISIBILITY
89876d0caaeSpatrick explicit __func(__block_type const& __f)
899*4bdff4beSrobert #ifdef _LIBCPP_HAS_OBJC_ARC
900*4bdff4beSrobert : __f_(__f)
901*4bdff4beSrobert #else
90276d0caaeSpatrick : __f_(reinterpret_cast<__block_type>(__f ? _Block_copy(__f) : nullptr))
903*4bdff4beSrobert #endif
90476d0caaeSpatrick { }
90576d0caaeSpatrick
90676d0caaeSpatrick // [TODO] add && to save on a retain
90776d0caaeSpatrick
90876d0caaeSpatrick _LIBCPP_INLINE_VISIBILITY
90976d0caaeSpatrick explicit __func(__block_type __f, const _Alloc& /* unused */)
910*4bdff4beSrobert #ifdef _LIBCPP_HAS_OBJC_ARC
911*4bdff4beSrobert : __f_(__f)
912*4bdff4beSrobert #else
91376d0caaeSpatrick : __f_(reinterpret_cast<__block_type>(__f ? _Block_copy(__f) : nullptr))
914*4bdff4beSrobert #endif
91576d0caaeSpatrick { }
91676d0caaeSpatrick
91776d0caaeSpatrick virtual __base<_Rp(_ArgTypes...)>* __clone() const {
91876d0caaeSpatrick _LIBCPP_ASSERT(false,
91976d0caaeSpatrick "Block pointers are just pointers, so they should always fit into "
92076d0caaeSpatrick "std::function's small buffer optimization. This function should "
92176d0caaeSpatrick "never be invoked.");
92276d0caaeSpatrick return nullptr;
92376d0caaeSpatrick }
92476d0caaeSpatrick
92576d0caaeSpatrick virtual void __clone(__base<_Rp(_ArgTypes...)>* __p) const {
92676d0caaeSpatrick ::new ((void*)__p) __func(__f_);
92776d0caaeSpatrick }
92876d0caaeSpatrick
92976d0caaeSpatrick virtual void destroy() _NOEXCEPT {
930*4bdff4beSrobert #ifndef _LIBCPP_HAS_OBJC_ARC
93176d0caaeSpatrick if (__f_)
93276d0caaeSpatrick _Block_release(__f_);
933*4bdff4beSrobert #endif
93476d0caaeSpatrick __f_ = 0;
93576d0caaeSpatrick }
93676d0caaeSpatrick
93776d0caaeSpatrick virtual void destroy_deallocate() _NOEXCEPT {
93876d0caaeSpatrick _LIBCPP_ASSERT(false,
93976d0caaeSpatrick "Block pointers are just pointers, so they should always fit into "
94076d0caaeSpatrick "std::function's small buffer optimization. This function should "
94176d0caaeSpatrick "never be invoked.");
94276d0caaeSpatrick }
94376d0caaeSpatrick
94476d0caaeSpatrick virtual _Rp operator()(_ArgTypes&& ... __arg) {
94576d0caaeSpatrick return _VSTD::__invoke(__f_, _VSTD::forward<_ArgTypes>(__arg)...);
94676d0caaeSpatrick }
94776d0caaeSpatrick
948*4bdff4beSrobert #ifndef _LIBCPP_HAS_NO_RTTI
94976d0caaeSpatrick virtual const void* target(type_info const& __ti) const _NOEXCEPT {
95076d0caaeSpatrick if (__ti == typeid(__func::__block_type))
95176d0caaeSpatrick return &__f_;
95276d0caaeSpatrick return (const void*)nullptr;
95376d0caaeSpatrick }
95476d0caaeSpatrick
95576d0caaeSpatrick virtual const std::type_info& target_type() const _NOEXCEPT {
95676d0caaeSpatrick return typeid(__func::__block_type);
95776d0caaeSpatrick }
958*4bdff4beSrobert #endif // _LIBCPP_HAS_NO_RTTI
95976d0caaeSpatrick };
96076d0caaeSpatrick
961*4bdff4beSrobert #endif // _LIBCPP_HAS_EXTENSION_BLOCKS
96276d0caaeSpatrick
963*4bdff4beSrobert } // namespace __function
96476d0caaeSpatrick
96576d0caaeSpatrick template<class _Rp, class ..._ArgTypes>
96676d0caaeSpatrick class _LIBCPP_TEMPLATE_VIS function<_Rp(_ArgTypes...)>
96776d0caaeSpatrick : public __function::__maybe_derive_from_unary_function<_Rp(_ArgTypes...)>,
96876d0caaeSpatrick public __function::__maybe_derive_from_binary_function<_Rp(_ArgTypes...)>
96976d0caaeSpatrick {
97076d0caaeSpatrick #ifndef _LIBCPP_ABI_OPTIMIZED_FUNCTION
97176d0caaeSpatrick typedef __function::__value_func<_Rp(_ArgTypes...)> __func;
97276d0caaeSpatrick #else
97376d0caaeSpatrick typedef __function::__policy_func<_Rp(_ArgTypes...)> __func;
97476d0caaeSpatrick #endif
97576d0caaeSpatrick
97676d0caaeSpatrick __func __f_;
97776d0caaeSpatrick
97876d0caaeSpatrick template <class _Fp, bool = _And<
979*4bdff4beSrobert _IsNotSame<__remove_cvref_t<_Fp>, function>,
98076d0caaeSpatrick __invokable<_Fp, _ArgTypes...>
98176d0caaeSpatrick >::value>
98276d0caaeSpatrick struct __callable;
98376d0caaeSpatrick template <class _Fp>
98476d0caaeSpatrick struct __callable<_Fp, true>
98576d0caaeSpatrick {
98676d0caaeSpatrick static const bool value = is_void<_Rp>::value ||
98776d0caaeSpatrick __is_core_convertible<typename __invoke_of<_Fp, _ArgTypes...>::type,
98876d0caaeSpatrick _Rp>::value;
98976d0caaeSpatrick };
99076d0caaeSpatrick template <class _Fp>
99176d0caaeSpatrick struct __callable<_Fp, false>
99276d0caaeSpatrick {
99376d0caaeSpatrick static const bool value = false;
99476d0caaeSpatrick };
99576d0caaeSpatrick
99676d0caaeSpatrick template <class _Fp>
99776d0caaeSpatrick using _EnableIfLValueCallable = typename enable_if<__callable<_Fp&>::value>::type;
99876d0caaeSpatrick public:
99976d0caaeSpatrick typedef _Rp result_type;
100076d0caaeSpatrick
100176d0caaeSpatrick // construct/copy/destroy:
100276d0caaeSpatrick _LIBCPP_INLINE_VISIBILITY
100376d0caaeSpatrick function() _NOEXCEPT { }
100476d0caaeSpatrick _LIBCPP_INLINE_VISIBILITY
100576d0caaeSpatrick function(nullptr_t) _NOEXCEPT {}
100676d0caaeSpatrick function(const function&);
100776d0caaeSpatrick function(function&&) _NOEXCEPT;
100876d0caaeSpatrick template<class _Fp, class = _EnableIfLValueCallable<_Fp>>
100976d0caaeSpatrick function(_Fp);
101076d0caaeSpatrick
101176d0caaeSpatrick #if _LIBCPP_STD_VER <= 14
101276d0caaeSpatrick template<class _Alloc>
101376d0caaeSpatrick _LIBCPP_INLINE_VISIBILITY
101476d0caaeSpatrick function(allocator_arg_t, const _Alloc&) _NOEXCEPT {}
101576d0caaeSpatrick template<class _Alloc>
101676d0caaeSpatrick _LIBCPP_INLINE_VISIBILITY
101776d0caaeSpatrick function(allocator_arg_t, const _Alloc&, nullptr_t) _NOEXCEPT {}
101876d0caaeSpatrick template<class _Alloc>
101976d0caaeSpatrick function(allocator_arg_t, const _Alloc&, const function&);
102076d0caaeSpatrick template<class _Alloc>
102176d0caaeSpatrick function(allocator_arg_t, const _Alloc&, function&&);
102276d0caaeSpatrick template<class _Fp, class _Alloc, class = _EnableIfLValueCallable<_Fp>>
102376d0caaeSpatrick function(allocator_arg_t, const _Alloc& __a, _Fp __f);
102476d0caaeSpatrick #endif
102576d0caaeSpatrick
102676d0caaeSpatrick function& operator=(const function&);
102776d0caaeSpatrick function& operator=(function&&) _NOEXCEPT;
102876d0caaeSpatrick function& operator=(nullptr_t) _NOEXCEPT;
102976d0caaeSpatrick template<class _Fp, class = _EnableIfLValueCallable<typename decay<_Fp>::type>>
103076d0caaeSpatrick function& operator=(_Fp&&);
103176d0caaeSpatrick
103276d0caaeSpatrick ~function();
103376d0caaeSpatrick
103476d0caaeSpatrick // function modifiers:
103576d0caaeSpatrick void swap(function&) _NOEXCEPT;
103676d0caaeSpatrick
103776d0caaeSpatrick #if _LIBCPP_STD_VER <= 14
103876d0caaeSpatrick template<class _Fp, class _Alloc>
103976d0caaeSpatrick _LIBCPP_INLINE_VISIBILITY
104076d0caaeSpatrick void assign(_Fp&& __f, const _Alloc& __a)
104176d0caaeSpatrick {function(allocator_arg, __a, _VSTD::forward<_Fp>(__f)).swap(*this);}
104276d0caaeSpatrick #endif
104376d0caaeSpatrick
104476d0caaeSpatrick // function capacity:
104576d0caaeSpatrick _LIBCPP_INLINE_VISIBILITY
104676d0caaeSpatrick explicit operator bool() const _NOEXCEPT {
104776d0caaeSpatrick return static_cast<bool>(__f_);
104876d0caaeSpatrick }
104976d0caaeSpatrick
105076d0caaeSpatrick // deleted overloads close possible hole in the type system
105176d0caaeSpatrick template<class _R2, class... _ArgTypes2>
105276d0caaeSpatrick bool operator==(const function<_R2(_ArgTypes2...)>&) const = delete;
105376d0caaeSpatrick template<class _R2, class... _ArgTypes2>
105476d0caaeSpatrick bool operator!=(const function<_R2(_ArgTypes2...)>&) const = delete;
105576d0caaeSpatrick public:
105676d0caaeSpatrick // function invocation:
105776d0caaeSpatrick _Rp operator()(_ArgTypes...) const;
105876d0caaeSpatrick
1059*4bdff4beSrobert #ifndef _LIBCPP_HAS_NO_RTTI
106076d0caaeSpatrick // function target access:
106176d0caaeSpatrick const std::type_info& target_type() const _NOEXCEPT;
106276d0caaeSpatrick template <typename _Tp> _Tp* target() _NOEXCEPT;
106376d0caaeSpatrick template <typename _Tp> const _Tp* target() const _NOEXCEPT;
1064*4bdff4beSrobert #endif // _LIBCPP_HAS_NO_RTTI
106576d0caaeSpatrick };
106676d0caaeSpatrick
1067*4bdff4beSrobert #if _LIBCPP_STD_VER >= 17
106876d0caaeSpatrick template<class _Rp, class ..._Ap>
106976d0caaeSpatrick function(_Rp(*)(_Ap...)) -> function<_Rp(_Ap...)>;
107076d0caaeSpatrick
107176d0caaeSpatrick template<class _Fp, class _Stripped = typename __strip_signature<decltype(&_Fp::operator())>::type>
107276d0caaeSpatrick function(_Fp) -> function<_Stripped>;
1073*4bdff4beSrobert #endif // _LIBCPP_STD_VER >= 17
107476d0caaeSpatrick
107576d0caaeSpatrick template<class _Rp, class ..._ArgTypes>
107676d0caaeSpatrick function<_Rp(_ArgTypes...)>::function(const function& __f) : __f_(__f.__f_) {}
107776d0caaeSpatrick
107876d0caaeSpatrick #if _LIBCPP_STD_VER <= 14
107976d0caaeSpatrick template<class _Rp, class ..._ArgTypes>
108076d0caaeSpatrick template <class _Alloc>
108176d0caaeSpatrick function<_Rp(_ArgTypes...)>::function(allocator_arg_t, const _Alloc&,
108276d0caaeSpatrick const function& __f) : __f_(__f.__f_) {}
108376d0caaeSpatrick #endif
108476d0caaeSpatrick
108576d0caaeSpatrick template <class _Rp, class... _ArgTypes>
108676d0caaeSpatrick function<_Rp(_ArgTypes...)>::function(function&& __f) _NOEXCEPT
108776d0caaeSpatrick : __f_(_VSTD::move(__f.__f_)) {}
108876d0caaeSpatrick
108976d0caaeSpatrick #if _LIBCPP_STD_VER <= 14
109076d0caaeSpatrick template<class _Rp, class ..._ArgTypes>
109176d0caaeSpatrick template <class _Alloc>
109276d0caaeSpatrick function<_Rp(_ArgTypes...)>::function(allocator_arg_t, const _Alloc&,
109376d0caaeSpatrick function&& __f)
109476d0caaeSpatrick : __f_(_VSTD::move(__f.__f_)) {}
109576d0caaeSpatrick #endif
109676d0caaeSpatrick
109776d0caaeSpatrick template <class _Rp, class... _ArgTypes>
109876d0caaeSpatrick template <class _Fp, class>
109976d0caaeSpatrick function<_Rp(_ArgTypes...)>::function(_Fp __f) : __f_(_VSTD::move(__f)) {}
110076d0caaeSpatrick
110176d0caaeSpatrick #if _LIBCPP_STD_VER <= 14
110276d0caaeSpatrick template <class _Rp, class... _ArgTypes>
110376d0caaeSpatrick template <class _Fp, class _Alloc, class>
110476d0caaeSpatrick function<_Rp(_ArgTypes...)>::function(allocator_arg_t, const _Alloc& __a,
110576d0caaeSpatrick _Fp __f)
110676d0caaeSpatrick : __f_(_VSTD::move(__f), __a) {}
110776d0caaeSpatrick #endif
110876d0caaeSpatrick
110976d0caaeSpatrick template<class _Rp, class ..._ArgTypes>
111076d0caaeSpatrick function<_Rp(_ArgTypes...)>&
111176d0caaeSpatrick function<_Rp(_ArgTypes...)>::operator=(const function& __f)
111276d0caaeSpatrick {
111376d0caaeSpatrick function(__f).swap(*this);
111476d0caaeSpatrick return *this;
111576d0caaeSpatrick }
111676d0caaeSpatrick
111776d0caaeSpatrick template<class _Rp, class ..._ArgTypes>
111876d0caaeSpatrick function<_Rp(_ArgTypes...)>&
111976d0caaeSpatrick function<_Rp(_ArgTypes...)>::operator=(function&& __f) _NOEXCEPT
112076d0caaeSpatrick {
112176d0caaeSpatrick __f_ = _VSTD::move(__f.__f_);
112276d0caaeSpatrick return *this;
112376d0caaeSpatrick }
112476d0caaeSpatrick
112576d0caaeSpatrick template<class _Rp, class ..._ArgTypes>
112676d0caaeSpatrick function<_Rp(_ArgTypes...)>&
112776d0caaeSpatrick function<_Rp(_ArgTypes...)>::operator=(nullptr_t) _NOEXCEPT
112876d0caaeSpatrick {
112976d0caaeSpatrick __f_ = nullptr;
113076d0caaeSpatrick return *this;
113176d0caaeSpatrick }
113276d0caaeSpatrick
113376d0caaeSpatrick template<class _Rp, class ..._ArgTypes>
113476d0caaeSpatrick template <class _Fp, class>
113576d0caaeSpatrick function<_Rp(_ArgTypes...)>&
113676d0caaeSpatrick function<_Rp(_ArgTypes...)>::operator=(_Fp&& __f)
113776d0caaeSpatrick {
113876d0caaeSpatrick function(_VSTD::forward<_Fp>(__f)).swap(*this);
113976d0caaeSpatrick return *this;
114076d0caaeSpatrick }
114176d0caaeSpatrick
114276d0caaeSpatrick template<class _Rp, class ..._ArgTypes>
114376d0caaeSpatrick function<_Rp(_ArgTypes...)>::~function() {}
114476d0caaeSpatrick
114576d0caaeSpatrick template<class _Rp, class ..._ArgTypes>
114676d0caaeSpatrick void
114776d0caaeSpatrick function<_Rp(_ArgTypes...)>::swap(function& __f) _NOEXCEPT
114876d0caaeSpatrick {
114976d0caaeSpatrick __f_.swap(__f.__f_);
115076d0caaeSpatrick }
115176d0caaeSpatrick
115276d0caaeSpatrick template<class _Rp, class ..._ArgTypes>
115376d0caaeSpatrick _Rp
115476d0caaeSpatrick function<_Rp(_ArgTypes...)>::operator()(_ArgTypes... __arg) const
115576d0caaeSpatrick {
115676d0caaeSpatrick return __f_(_VSTD::forward<_ArgTypes>(__arg)...);
115776d0caaeSpatrick }
115876d0caaeSpatrick
1159*4bdff4beSrobert #ifndef _LIBCPP_HAS_NO_RTTI
116076d0caaeSpatrick
116176d0caaeSpatrick template<class _Rp, class ..._ArgTypes>
116276d0caaeSpatrick const std::type_info&
116376d0caaeSpatrick function<_Rp(_ArgTypes...)>::target_type() const _NOEXCEPT
116476d0caaeSpatrick {
116576d0caaeSpatrick return __f_.target_type();
116676d0caaeSpatrick }
116776d0caaeSpatrick
116876d0caaeSpatrick template<class _Rp, class ..._ArgTypes>
116976d0caaeSpatrick template <typename _Tp>
117076d0caaeSpatrick _Tp*
117176d0caaeSpatrick function<_Rp(_ArgTypes...)>::target() _NOEXCEPT
117276d0caaeSpatrick {
117376d0caaeSpatrick return (_Tp*)(__f_.template target<_Tp>());
117476d0caaeSpatrick }
117576d0caaeSpatrick
117676d0caaeSpatrick template<class _Rp, class ..._ArgTypes>
117776d0caaeSpatrick template <typename _Tp>
117876d0caaeSpatrick const _Tp*
117976d0caaeSpatrick function<_Rp(_ArgTypes...)>::target() const _NOEXCEPT
118076d0caaeSpatrick {
118176d0caaeSpatrick return __f_.template target<_Tp>();
118276d0caaeSpatrick }
118376d0caaeSpatrick
1184*4bdff4beSrobert #endif // _LIBCPP_HAS_NO_RTTI
118576d0caaeSpatrick
118676d0caaeSpatrick template <class _Rp, class... _ArgTypes>
118776d0caaeSpatrick inline _LIBCPP_INLINE_VISIBILITY
118876d0caaeSpatrick bool
118976d0caaeSpatrick operator==(const function<_Rp(_ArgTypes...)>& __f, nullptr_t) _NOEXCEPT {return !__f;}
119076d0caaeSpatrick
119176d0caaeSpatrick template <class _Rp, class... _ArgTypes>
119276d0caaeSpatrick inline _LIBCPP_INLINE_VISIBILITY
119376d0caaeSpatrick bool
119476d0caaeSpatrick operator==(nullptr_t, const function<_Rp(_ArgTypes...)>& __f) _NOEXCEPT {return !__f;}
119576d0caaeSpatrick
119676d0caaeSpatrick template <class _Rp, class... _ArgTypes>
119776d0caaeSpatrick inline _LIBCPP_INLINE_VISIBILITY
119876d0caaeSpatrick bool
119976d0caaeSpatrick operator!=(const function<_Rp(_ArgTypes...)>& __f, nullptr_t) _NOEXCEPT {return (bool)__f;}
120076d0caaeSpatrick
120176d0caaeSpatrick template <class _Rp, class... _ArgTypes>
120276d0caaeSpatrick inline _LIBCPP_INLINE_VISIBILITY
120376d0caaeSpatrick bool
120476d0caaeSpatrick operator!=(nullptr_t, const function<_Rp(_ArgTypes...)>& __f) _NOEXCEPT {return (bool)__f;}
120576d0caaeSpatrick
120676d0caaeSpatrick template <class _Rp, class... _ArgTypes>
120776d0caaeSpatrick inline _LIBCPP_INLINE_VISIBILITY
120876d0caaeSpatrick void
120976d0caaeSpatrick swap(function<_Rp(_ArgTypes...)>& __x, function<_Rp(_ArgTypes...)>& __y) _NOEXCEPT
121076d0caaeSpatrick {return __x.swap(__y);}
121176d0caaeSpatrick
121276d0caaeSpatrick _LIBCPP_END_NAMESPACE_STD
121376d0caaeSpatrick
1214*4bdff4beSrobert #endif // _LIBCPP_CXX03_LANG
1215*4bdff4beSrobert
121676d0caaeSpatrick #endif // _LIBCPP___FUNCTIONAL_FUNCTION_H
1217