xref: /freebsd-src/contrib/llvm-project/libcxx/include/__functional/function.h (revision 5f757f3ff9144b609b3c433dfd370cc6bdc191ad)
1fe6060f1SDimitry Andric // -*- C++ -*-
2fe6060f1SDimitry Andric //===----------------------------------------------------------------------===//
3fe6060f1SDimitry Andric //
4fe6060f1SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5fe6060f1SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
6fe6060f1SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7fe6060f1SDimitry Andric //
8fe6060f1SDimitry Andric //===----------------------------------------------------------------------===//
9fe6060f1SDimitry Andric 
10fe6060f1SDimitry Andric #ifndef _LIBCPP___FUNCTIONAL_FUNCTION_H
11fe6060f1SDimitry Andric #define _LIBCPP___FUNCTIONAL_FUNCTION_H
12fe6060f1SDimitry Andric 
1381ad6265SDimitry Andric #include <__assert>
14fe6060f1SDimitry Andric #include <__config>
1506c3fb27SDimitry Andric #include <__exception/exception.h>
16fe6060f1SDimitry Andric #include <__functional/binary_function.h>
17fe6060f1SDimitry Andric #include <__functional/invoke.h>
18fe6060f1SDimitry Andric #include <__functional/unary_function.h>
19fe6060f1SDimitry Andric #include <__iterator/iterator_traits.h>
2004eeddc0SDimitry Andric #include <__memory/addressof.h>
21bdd1243dSDimitry Andric #include <__memory/allocator.h>
22bdd1243dSDimitry Andric #include <__memory/allocator_destructor.h>
23fe6060f1SDimitry Andric #include <__memory/allocator_traits.h>
24bdd1243dSDimitry Andric #include <__memory/builtin_new_allocator.h>
25fe6060f1SDimitry Andric #include <__memory/compressed_pair.h>
26bdd1243dSDimitry Andric #include <__memory/unique_ptr.h>
2706c3fb27SDimitry Andric #include <__type_traits/aligned_storage.h>
2806c3fb27SDimitry Andric #include <__type_traits/decay.h>
2906c3fb27SDimitry Andric #include <__type_traits/is_core_convertible.h>
3006c3fb27SDimitry Andric #include <__type_traits/is_scalar.h>
3106c3fb27SDimitry Andric #include <__type_traits/is_trivially_copy_constructible.h>
3206c3fb27SDimitry Andric #include <__type_traits/is_trivially_destructible.h>
3306c3fb27SDimitry Andric #include <__type_traits/is_void.h>
34bdd1243dSDimitry Andric #include <__type_traits/strip_signature.h>
3581ad6265SDimitry Andric #include <__utility/forward.h>
3681ad6265SDimitry Andric #include <__utility/move.h>
37bdd1243dSDimitry Andric #include <__utility/piecewise_construct.h>
3881ad6265SDimitry Andric #include <__utility/swap.h>
3906c3fb27SDimitry Andric #include <__verbose_abort>
40bdd1243dSDimitry Andric #include <new>
41bdd1243dSDimitry Andric #include <tuple>
42bdd1243dSDimitry Andric #include <typeinfo>
43fe6060f1SDimitry Andric 
44fe6060f1SDimitry Andric #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
45fe6060f1SDimitry Andric #  pragma GCC system_header
46fe6060f1SDimitry Andric #endif
47fe6060f1SDimitry Andric 
48bdd1243dSDimitry Andric #ifndef _LIBCPP_CXX03_LANG
49bdd1243dSDimitry Andric 
50fe6060f1SDimitry Andric _LIBCPP_BEGIN_NAMESPACE_STD
51fe6060f1SDimitry Andric 
52fe6060f1SDimitry Andric // bad_function_call
53fe6060f1SDimitry Andric 
5481ad6265SDimitry Andric _LIBCPP_DIAGNOSTIC_PUSH
5581ad6265SDimitry Andric _LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wweak-vtables")
5606c3fb27SDimitry Andric class _LIBCPP_EXPORTED_FROM_ABI bad_function_call
57fe6060f1SDimitry Andric     : public exception
58fe6060f1SDimitry Andric {
59fe6060f1SDimitry Andric public:
60*5f757f3fSDimitry Andric     _LIBCPP_HIDE_FROM_ABI bad_function_call() _NOEXCEPT = default;
61*5f757f3fSDimitry Andric     _LIBCPP_HIDE_FROM_ABI bad_function_call(const bad_function_call&) _NOEXCEPT = default;
62*5f757f3fSDimitry Andric     _LIBCPP_HIDE_FROM_ABI bad_function_call& operator=(const bad_function_call&) _NOEXCEPT = default;
63349cc55cSDimitry Andric // Note that when a key function is not used, every translation unit that uses
64349cc55cSDimitry Andric // bad_function_call will end up containing a weak definition of the vtable and
65349cc55cSDimitry Andric // typeinfo.
66349cc55cSDimitry Andric #ifdef _LIBCPP_ABI_BAD_FUNCTION_CALL_KEY_FUNCTION
67bdd1243dSDimitry Andric     ~bad_function_call() _NOEXCEPT override;
68349cc55cSDimitry Andric #else
6906c3fb27SDimitry Andric     _LIBCPP_HIDE_FROM_ABI_VIRTUAL ~bad_function_call() _NOEXCEPT override {}
70349cc55cSDimitry Andric #endif
71fe6060f1SDimitry Andric 
72349cc55cSDimitry Andric #ifdef _LIBCPP_ABI_BAD_FUNCTION_CALL_GOOD_WHAT_MESSAGE
73bdd1243dSDimitry Andric     const char* what() const _NOEXCEPT override;
74fe6060f1SDimitry Andric #endif
75fe6060f1SDimitry Andric };
7681ad6265SDimitry Andric _LIBCPP_DIAGNOSTIC_POP
77fe6060f1SDimitry Andric 
78*5f757f3fSDimitry Andric _LIBCPP_NORETURN inline _LIBCPP_HIDE_FROM_ABI
79fe6060f1SDimitry Andric void __throw_bad_function_call()
80fe6060f1SDimitry Andric {
8106c3fb27SDimitry Andric #ifndef _LIBCPP_HAS_NO_EXCEPTIONS
82fe6060f1SDimitry Andric     throw bad_function_call();
83fe6060f1SDimitry Andric #else
8406c3fb27SDimitry Andric     _LIBCPP_VERBOSE_ABORT("bad_function_call was thrown in -fno-exceptions mode");
85fe6060f1SDimitry Andric #endif
86fe6060f1SDimitry Andric }
87fe6060f1SDimitry Andric 
88bdd1243dSDimitry Andric template<class _Fp> class _LIBCPP_TEMPLATE_VIS function; // undefined
89fe6060f1SDimitry Andric 
90fe6060f1SDimitry Andric namespace __function
91fe6060f1SDimitry Andric {
92fe6060f1SDimitry Andric 
93fe6060f1SDimitry Andric template<class _Rp>
94fe6060f1SDimitry Andric struct __maybe_derive_from_unary_function
95fe6060f1SDimitry Andric {
96fe6060f1SDimitry Andric };
97fe6060f1SDimitry Andric 
98fe6060f1SDimitry Andric template<class _Rp, class _A1>
99fe6060f1SDimitry Andric struct __maybe_derive_from_unary_function<_Rp(_A1)>
10081ad6265SDimitry Andric     : public __unary_function<_A1, _Rp>
101fe6060f1SDimitry Andric {
102fe6060f1SDimitry Andric };
103fe6060f1SDimitry Andric 
104fe6060f1SDimitry Andric template<class _Rp>
105fe6060f1SDimitry Andric struct __maybe_derive_from_binary_function
106fe6060f1SDimitry Andric {
107fe6060f1SDimitry Andric };
108fe6060f1SDimitry Andric 
109fe6060f1SDimitry Andric template<class _Rp, class _A1, class _A2>
110fe6060f1SDimitry Andric struct __maybe_derive_from_binary_function<_Rp(_A1, _A2)>
11181ad6265SDimitry Andric     : public __binary_function<_A1, _A2, _Rp>
112fe6060f1SDimitry Andric {
113fe6060f1SDimitry Andric };
114fe6060f1SDimitry Andric 
115fe6060f1SDimitry Andric template <class _Fp>
116*5f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI
117fe6060f1SDimitry Andric bool __not_null(_Fp const&) { return true; }
118fe6060f1SDimitry Andric 
119fe6060f1SDimitry Andric template <class _Fp>
120*5f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI
121fe6060f1SDimitry Andric bool __not_null(_Fp* __ptr) { return __ptr; }
122fe6060f1SDimitry Andric 
123fe6060f1SDimitry Andric template <class _Ret, class _Class>
124*5f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI
125fe6060f1SDimitry Andric bool __not_null(_Ret _Class::*__ptr) { return __ptr; }
126fe6060f1SDimitry Andric 
127fe6060f1SDimitry Andric template <class _Fp>
128*5f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI
129fe6060f1SDimitry Andric bool __not_null(function<_Fp> const& __f) { return !!__f; }
130fe6060f1SDimitry Andric 
131fe6060f1SDimitry Andric #ifdef _LIBCPP_HAS_EXTENSION_BLOCKS
132fe6060f1SDimitry Andric template <class _Rp, class ..._Args>
133*5f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI
134fe6060f1SDimitry Andric bool __not_null(_Rp (^__p)(_Args...)) { return __p; }
135fe6060f1SDimitry Andric #endif
136fe6060f1SDimitry Andric 
137fe6060f1SDimitry Andric } // namespace __function
138fe6060f1SDimitry Andric 
139fe6060f1SDimitry Andric namespace __function {
140fe6060f1SDimitry Andric 
141fe6060f1SDimitry Andric // __alloc_func holds a functor and an allocator.
142fe6060f1SDimitry Andric 
143fe6060f1SDimitry Andric template <class _Fp, class _Ap, class _FB> class __alloc_func;
144fe6060f1SDimitry Andric template <class _Fp, class _FB>
145fe6060f1SDimitry Andric class __default_alloc_func;
146fe6060f1SDimitry Andric 
147fe6060f1SDimitry Andric template <class _Fp, class _Ap, class _Rp, class... _ArgTypes>
148fe6060f1SDimitry Andric class __alloc_func<_Fp, _Ap, _Rp(_ArgTypes...)>
149fe6060f1SDimitry Andric {
150fe6060f1SDimitry Andric     __compressed_pair<_Fp, _Ap> __f_;
151fe6060f1SDimitry Andric 
152fe6060f1SDimitry Andric   public:
153349cc55cSDimitry Andric     typedef _LIBCPP_NODEBUG _Fp _Target;
154349cc55cSDimitry Andric     typedef _LIBCPP_NODEBUG _Ap _Alloc;
155fe6060f1SDimitry Andric 
156*5f757f3fSDimitry Andric     _LIBCPP_HIDE_FROM_ABI
157fe6060f1SDimitry Andric     const _Target& __target() const { return __f_.first(); }
158fe6060f1SDimitry Andric 
159fe6060f1SDimitry Andric     // WIN32 APIs may define __allocator, so use __get_allocator instead.
160*5f757f3fSDimitry Andric     _LIBCPP_HIDE_FROM_ABI
161fe6060f1SDimitry Andric     const _Alloc& __get_allocator() const { return __f_.second(); }
162fe6060f1SDimitry Andric 
163*5f757f3fSDimitry Andric     _LIBCPP_HIDE_FROM_ABI
164fe6060f1SDimitry Andric     explicit __alloc_func(_Target&& __f)
165*5f757f3fSDimitry Andric         : __f_(piecewise_construct, std::forward_as_tuple(std::move(__f)),
166*5f757f3fSDimitry Andric                std::forward_as_tuple())
167fe6060f1SDimitry Andric     {
168fe6060f1SDimitry Andric     }
169fe6060f1SDimitry Andric 
170*5f757f3fSDimitry Andric     _LIBCPP_HIDE_FROM_ABI
171fe6060f1SDimitry Andric     explicit __alloc_func(const _Target& __f, const _Alloc& __a)
172*5f757f3fSDimitry Andric         : __f_(piecewise_construct, std::forward_as_tuple(__f),
173*5f757f3fSDimitry Andric                std::forward_as_tuple(__a))
174fe6060f1SDimitry Andric     {
175fe6060f1SDimitry Andric     }
176fe6060f1SDimitry Andric 
177*5f757f3fSDimitry Andric     _LIBCPP_HIDE_FROM_ABI
178fe6060f1SDimitry Andric     explicit __alloc_func(const _Target& __f, _Alloc&& __a)
179*5f757f3fSDimitry Andric         : __f_(piecewise_construct, std::forward_as_tuple(__f),
180*5f757f3fSDimitry Andric                std::forward_as_tuple(std::move(__a)))
181fe6060f1SDimitry Andric     {
182fe6060f1SDimitry Andric     }
183fe6060f1SDimitry Andric 
184*5f757f3fSDimitry Andric     _LIBCPP_HIDE_FROM_ABI
185fe6060f1SDimitry Andric     explicit __alloc_func(_Target&& __f, _Alloc&& __a)
186*5f757f3fSDimitry Andric         : __f_(piecewise_construct, std::forward_as_tuple(std::move(__f)),
187*5f757f3fSDimitry Andric                std::forward_as_tuple(std::move(__a)))
188fe6060f1SDimitry Andric     {
189fe6060f1SDimitry Andric     }
190fe6060f1SDimitry Andric 
191*5f757f3fSDimitry Andric     _LIBCPP_HIDE_FROM_ABI
192fe6060f1SDimitry Andric     _Rp operator()(_ArgTypes&&... __arg)
193fe6060f1SDimitry Andric     {
194fe6060f1SDimitry Andric         typedef __invoke_void_return_wrapper<_Rp> _Invoker;
195fe6060f1SDimitry Andric         return _Invoker::__call(__f_.first(),
196*5f757f3fSDimitry Andric                                 std::forward<_ArgTypes>(__arg)...);
197fe6060f1SDimitry Andric     }
198fe6060f1SDimitry Andric 
199*5f757f3fSDimitry Andric     _LIBCPP_HIDE_FROM_ABI
200fe6060f1SDimitry Andric     __alloc_func* __clone() const
201fe6060f1SDimitry Andric     {
202fe6060f1SDimitry Andric         typedef allocator_traits<_Alloc> __alloc_traits;
203bdd1243dSDimitry Andric         typedef __rebind_alloc<__alloc_traits, __alloc_func> _AA;
204fe6060f1SDimitry Andric         _AA __a(__f_.second());
205fe6060f1SDimitry Andric         typedef __allocator_destructor<_AA> _Dp;
206fe6060f1SDimitry Andric         unique_ptr<__alloc_func, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
207fe6060f1SDimitry Andric         ::new ((void*)__hold.get()) __alloc_func(__f_.first(), _Alloc(__a));
208fe6060f1SDimitry Andric         return __hold.release();
209fe6060f1SDimitry Andric     }
210fe6060f1SDimitry Andric 
211*5f757f3fSDimitry Andric     _LIBCPP_HIDE_FROM_ABI
212fe6060f1SDimitry Andric     void destroy() _NOEXCEPT { __f_.~__compressed_pair<_Target, _Alloc>(); }
213fe6060f1SDimitry Andric 
21406c3fb27SDimitry Andric     _LIBCPP_HIDE_FROM_ABI static void __destroy_and_delete(__alloc_func* __f) {
215fe6060f1SDimitry Andric       typedef allocator_traits<_Alloc> __alloc_traits;
216bdd1243dSDimitry Andric       typedef __rebind_alloc<__alloc_traits, __alloc_func> _FunAlloc;
217fe6060f1SDimitry Andric       _FunAlloc __a(__f->__get_allocator());
218fe6060f1SDimitry Andric       __f->destroy();
219fe6060f1SDimitry Andric       __a.deallocate(__f, 1);
220fe6060f1SDimitry Andric     }
221fe6060f1SDimitry Andric };
222fe6060f1SDimitry Andric 
223fe6060f1SDimitry Andric template <class _Fp, class _Rp, class... _ArgTypes>
224fe6060f1SDimitry Andric class __default_alloc_func<_Fp, _Rp(_ArgTypes...)> {
225fe6060f1SDimitry Andric   _Fp __f_;
226fe6060f1SDimitry Andric 
227fe6060f1SDimitry Andric public:
228349cc55cSDimitry Andric   typedef _LIBCPP_NODEBUG _Fp _Target;
229fe6060f1SDimitry Andric 
230*5f757f3fSDimitry Andric   _LIBCPP_HIDE_FROM_ABI
231fe6060f1SDimitry Andric   const _Target& __target() const { return __f_; }
232fe6060f1SDimitry Andric 
233*5f757f3fSDimitry Andric   _LIBCPP_HIDE_FROM_ABI
234*5f757f3fSDimitry Andric   explicit __default_alloc_func(_Target&& __f) : __f_(std::move(__f)) {}
235fe6060f1SDimitry Andric 
236*5f757f3fSDimitry Andric   _LIBCPP_HIDE_FROM_ABI
237fe6060f1SDimitry Andric   explicit __default_alloc_func(const _Target& __f) : __f_(__f) {}
238fe6060f1SDimitry Andric 
239*5f757f3fSDimitry Andric   _LIBCPP_HIDE_FROM_ABI
240fe6060f1SDimitry Andric   _Rp operator()(_ArgTypes&&... __arg) {
241fe6060f1SDimitry Andric     typedef __invoke_void_return_wrapper<_Rp> _Invoker;
242*5f757f3fSDimitry Andric     return _Invoker::__call(__f_, std::forward<_ArgTypes>(__arg)...);
243fe6060f1SDimitry Andric   }
244fe6060f1SDimitry Andric 
245*5f757f3fSDimitry Andric   _LIBCPP_HIDE_FROM_ABI
246fe6060f1SDimitry Andric   __default_alloc_func* __clone() const {
247fe6060f1SDimitry Andric       __builtin_new_allocator::__holder_t __hold =
248fe6060f1SDimitry Andric         __builtin_new_allocator::__allocate_type<__default_alloc_func>(1);
249fe6060f1SDimitry Andric     __default_alloc_func* __res =
250fe6060f1SDimitry Andric         ::new ((void*)__hold.get()) __default_alloc_func(__f_);
251fe6060f1SDimitry Andric     (void)__hold.release();
252fe6060f1SDimitry Andric     return __res;
253fe6060f1SDimitry Andric   }
254fe6060f1SDimitry Andric 
255*5f757f3fSDimitry Andric   _LIBCPP_HIDE_FROM_ABI
256fe6060f1SDimitry Andric   void destroy() _NOEXCEPT { __f_.~_Target(); }
257fe6060f1SDimitry Andric 
25806c3fb27SDimitry Andric   _LIBCPP_HIDE_FROM_ABI static void __destroy_and_delete(__default_alloc_func* __f) {
259fe6060f1SDimitry Andric     __f->destroy();
260fe6060f1SDimitry Andric       __builtin_new_allocator::__deallocate_type<__default_alloc_func>(__f, 1);
261fe6060f1SDimitry Andric   }
262fe6060f1SDimitry Andric };
263fe6060f1SDimitry Andric 
264fe6060f1SDimitry Andric // __base provides an abstract interface for copyable functors.
265fe6060f1SDimitry Andric 
266fe6060f1SDimitry Andric template<class _Fp> class _LIBCPP_TEMPLATE_VIS __base;
267fe6060f1SDimitry Andric 
268fe6060f1SDimitry Andric template<class _Rp, class ..._ArgTypes>
269fe6060f1SDimitry Andric class __base<_Rp(_ArgTypes...)>
270fe6060f1SDimitry Andric {
271fe6060f1SDimitry Andric     __base(const __base&);
272fe6060f1SDimitry Andric     __base& operator=(const __base&);
273fe6060f1SDimitry Andric public:
274*5f757f3fSDimitry Andric     _LIBCPP_HIDE_FROM_ABI __base() {}
275bdd1243dSDimitry Andric     _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual ~__base() {}
276fe6060f1SDimitry Andric     virtual __base* __clone() const = 0;
277fe6060f1SDimitry Andric     virtual void __clone(__base*) const = 0;
278fe6060f1SDimitry Andric     virtual void destroy() _NOEXCEPT = 0;
279fe6060f1SDimitry Andric     virtual void destroy_deallocate() _NOEXCEPT = 0;
280fe6060f1SDimitry Andric     virtual _Rp operator()(_ArgTypes&& ...) = 0;
2811ac55f4cSDimitry Andric #ifndef _LIBCPP_HAS_NO_RTTI
282fe6060f1SDimitry Andric     virtual const void* target(const type_info&) const _NOEXCEPT = 0;
283fe6060f1SDimitry Andric     virtual const std::type_info& target_type() const _NOEXCEPT = 0;
2841ac55f4cSDimitry Andric #endif // _LIBCPP_HAS_NO_RTTI
285fe6060f1SDimitry Andric };
286fe6060f1SDimitry Andric 
287fe6060f1SDimitry Andric // __func implements __base for a given functor type.
288fe6060f1SDimitry Andric 
289fe6060f1SDimitry Andric template<class _FD, class _Alloc, class _FB> class __func;
290fe6060f1SDimitry Andric 
291fe6060f1SDimitry Andric template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
292fe6060f1SDimitry Andric class __func<_Fp, _Alloc, _Rp(_ArgTypes...)>
293fe6060f1SDimitry Andric     : public  __base<_Rp(_ArgTypes...)>
294fe6060f1SDimitry Andric {
295fe6060f1SDimitry Andric     __alloc_func<_Fp, _Alloc, _Rp(_ArgTypes...)> __f_;
296fe6060f1SDimitry Andric public:
297*5f757f3fSDimitry Andric     _LIBCPP_HIDE_FROM_ABI
298fe6060f1SDimitry Andric     explicit __func(_Fp&& __f)
299*5f757f3fSDimitry Andric         : __f_(std::move(__f)) {}
300fe6060f1SDimitry Andric 
301*5f757f3fSDimitry Andric     _LIBCPP_HIDE_FROM_ABI
302fe6060f1SDimitry Andric     explicit __func(const _Fp& __f, const _Alloc& __a)
303fe6060f1SDimitry Andric         : __f_(__f, __a) {}
304fe6060f1SDimitry Andric 
305*5f757f3fSDimitry Andric     _LIBCPP_HIDE_FROM_ABI
306fe6060f1SDimitry Andric     explicit __func(const _Fp& __f, _Alloc&& __a)
307*5f757f3fSDimitry Andric         : __f_(__f, std::move(__a)) {}
308fe6060f1SDimitry Andric 
309*5f757f3fSDimitry Andric     _LIBCPP_HIDE_FROM_ABI
310fe6060f1SDimitry Andric     explicit __func(_Fp&& __f, _Alloc&& __a)
311*5f757f3fSDimitry Andric         : __f_(std::move(__f), std::move(__a)) {}
312fe6060f1SDimitry Andric 
31306c3fb27SDimitry Andric     _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual __base<_Rp(_ArgTypes...)>* __clone() const;
31406c3fb27SDimitry Andric     _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void __clone(__base<_Rp(_ArgTypes...)>*) const;
31506c3fb27SDimitry Andric     _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void destroy() _NOEXCEPT;
31606c3fb27SDimitry Andric     _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void destroy_deallocate() _NOEXCEPT;
31706c3fb27SDimitry Andric     _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual _Rp operator()(_ArgTypes&&... __arg);
3181ac55f4cSDimitry Andric #ifndef _LIBCPP_HAS_NO_RTTI
31906c3fb27SDimitry Andric     _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual const void* target(const type_info&) const _NOEXCEPT;
32006c3fb27SDimitry Andric     _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual const std::type_info& target_type() const _NOEXCEPT;
3211ac55f4cSDimitry Andric #endif // _LIBCPP_HAS_NO_RTTI
322fe6060f1SDimitry Andric };
323fe6060f1SDimitry Andric 
324fe6060f1SDimitry Andric template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
325fe6060f1SDimitry Andric __base<_Rp(_ArgTypes...)>*
326fe6060f1SDimitry Andric __func<_Fp, _Alloc, _Rp(_ArgTypes...)>::__clone() const
327fe6060f1SDimitry Andric {
328fe6060f1SDimitry Andric     typedef allocator_traits<_Alloc> __alloc_traits;
329bdd1243dSDimitry Andric     typedef __rebind_alloc<__alloc_traits, __func> _Ap;
330fe6060f1SDimitry Andric     _Ap __a(__f_.__get_allocator());
331fe6060f1SDimitry Andric     typedef __allocator_destructor<_Ap> _Dp;
332fe6060f1SDimitry Andric     unique_ptr<__func, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
333fe6060f1SDimitry Andric     ::new ((void*)__hold.get()) __func(__f_.__target(), _Alloc(__a));
334fe6060f1SDimitry Andric     return __hold.release();
335fe6060f1SDimitry Andric }
336fe6060f1SDimitry Andric 
337fe6060f1SDimitry Andric template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
338fe6060f1SDimitry Andric void
339fe6060f1SDimitry Andric __func<_Fp, _Alloc, _Rp(_ArgTypes...)>::__clone(__base<_Rp(_ArgTypes...)>* __p) const
340fe6060f1SDimitry Andric {
341fe6060f1SDimitry Andric     ::new ((void*)__p) __func(__f_.__target(), __f_.__get_allocator());
342fe6060f1SDimitry Andric }
343fe6060f1SDimitry Andric 
344fe6060f1SDimitry Andric template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
345fe6060f1SDimitry Andric void
346fe6060f1SDimitry Andric __func<_Fp, _Alloc, _Rp(_ArgTypes...)>::destroy() _NOEXCEPT
347fe6060f1SDimitry Andric {
348fe6060f1SDimitry Andric     __f_.destroy();
349fe6060f1SDimitry Andric }
350fe6060f1SDimitry Andric 
351fe6060f1SDimitry Andric template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
352fe6060f1SDimitry Andric void
353fe6060f1SDimitry Andric __func<_Fp, _Alloc, _Rp(_ArgTypes...)>::destroy_deallocate() _NOEXCEPT
354fe6060f1SDimitry Andric {
355fe6060f1SDimitry Andric     typedef allocator_traits<_Alloc> __alloc_traits;
356bdd1243dSDimitry Andric     typedef __rebind_alloc<__alloc_traits, __func> _Ap;
357fe6060f1SDimitry Andric     _Ap __a(__f_.__get_allocator());
358fe6060f1SDimitry Andric     __f_.destroy();
359fe6060f1SDimitry Andric     __a.deallocate(this, 1);
360fe6060f1SDimitry Andric }
361fe6060f1SDimitry Andric 
362fe6060f1SDimitry Andric template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
363fe6060f1SDimitry Andric _Rp
364fe6060f1SDimitry Andric __func<_Fp, _Alloc, _Rp(_ArgTypes...)>::operator()(_ArgTypes&& ... __arg)
365fe6060f1SDimitry Andric {
366*5f757f3fSDimitry Andric     return __f_(std::forward<_ArgTypes>(__arg)...);
367fe6060f1SDimitry Andric }
368fe6060f1SDimitry Andric 
3691ac55f4cSDimitry Andric #ifndef _LIBCPP_HAS_NO_RTTI
370fe6060f1SDimitry Andric 
371fe6060f1SDimitry Andric template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
372fe6060f1SDimitry Andric const void*
373fe6060f1SDimitry Andric __func<_Fp, _Alloc, _Rp(_ArgTypes...)>::target(const type_info& __ti) const _NOEXCEPT
374fe6060f1SDimitry Andric {
375fe6060f1SDimitry Andric     if (__ti == typeid(_Fp))
376*5f757f3fSDimitry Andric         return std::addressof(__f_.__target());
377fe6060f1SDimitry Andric     return nullptr;
378fe6060f1SDimitry Andric }
379fe6060f1SDimitry Andric 
380fe6060f1SDimitry Andric template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
381fe6060f1SDimitry Andric const std::type_info&
382fe6060f1SDimitry Andric __func<_Fp, _Alloc, _Rp(_ArgTypes...)>::target_type() const _NOEXCEPT
383fe6060f1SDimitry Andric {
384fe6060f1SDimitry Andric     return typeid(_Fp);
385fe6060f1SDimitry Andric }
386fe6060f1SDimitry Andric 
3871ac55f4cSDimitry Andric #endif // _LIBCPP_HAS_NO_RTTI
388fe6060f1SDimitry Andric 
389fe6060f1SDimitry Andric // __value_func creates a value-type from a __func.
390fe6060f1SDimitry Andric 
391fe6060f1SDimitry Andric template <class _Fp> class __value_func;
392fe6060f1SDimitry Andric 
393fe6060f1SDimitry Andric template <class _Rp, class... _ArgTypes> class __value_func<_Rp(_ArgTypes...)>
394fe6060f1SDimitry Andric {
395bdd1243dSDimitry Andric     _LIBCPP_SUPPRESS_DEPRECATED_PUSH
396fe6060f1SDimitry Andric     typename aligned_storage<3 * sizeof(void*)>::type __buf_;
397bdd1243dSDimitry Andric     _LIBCPP_SUPPRESS_DEPRECATED_POP
398fe6060f1SDimitry Andric 
399fe6060f1SDimitry Andric     typedef __base<_Rp(_ArgTypes...)> __func;
400fe6060f1SDimitry Andric     __func* __f_;
401fe6060f1SDimitry Andric 
40206c3fb27SDimitry Andric     _LIBCPP_HIDE_FROM_ABI _LIBCPP_NO_CFI static __func* __as_base(void* __p)
403fe6060f1SDimitry Andric     {
404753f127fSDimitry Andric         return reinterpret_cast<__func*>(__p);
405fe6060f1SDimitry Andric     }
406fe6060f1SDimitry Andric 
407fe6060f1SDimitry Andric   public:
408*5f757f3fSDimitry Andric     _LIBCPP_HIDE_FROM_ABI
409fe6060f1SDimitry Andric     __value_func() _NOEXCEPT : __f_(nullptr) {}
410fe6060f1SDimitry Andric 
411fe6060f1SDimitry Andric     template <class _Fp, class _Alloc>
412*5f757f3fSDimitry Andric     _LIBCPP_HIDE_FROM_ABI __value_func(_Fp&& __f, const _Alloc& __a)
413fe6060f1SDimitry Andric         : __f_(nullptr)
414fe6060f1SDimitry Andric     {
415fe6060f1SDimitry Andric         typedef allocator_traits<_Alloc> __alloc_traits;
416fe6060f1SDimitry Andric         typedef __function::__func<_Fp, _Alloc, _Rp(_ArgTypes...)> _Fun;
417bdd1243dSDimitry Andric         typedef __rebind_alloc<__alloc_traits, _Fun> _FunAlloc;
418fe6060f1SDimitry Andric 
419fe6060f1SDimitry Andric         if (__function::__not_null(__f))
420fe6060f1SDimitry Andric         {
421fe6060f1SDimitry Andric             _FunAlloc __af(__a);
422fe6060f1SDimitry Andric             if (sizeof(_Fun) <= sizeof(__buf_) &&
423fe6060f1SDimitry Andric                 is_nothrow_copy_constructible<_Fp>::value &&
424fe6060f1SDimitry Andric                 is_nothrow_copy_constructible<_FunAlloc>::value)
425fe6060f1SDimitry Andric             {
426fe6060f1SDimitry Andric                 __f_ =
427*5f757f3fSDimitry Andric                     ::new ((void*)&__buf_) _Fun(std::move(__f), _Alloc(__af));
428fe6060f1SDimitry Andric             }
429fe6060f1SDimitry Andric             else
430fe6060f1SDimitry Andric             {
431fe6060f1SDimitry Andric                 typedef __allocator_destructor<_FunAlloc> _Dp;
432fe6060f1SDimitry Andric                 unique_ptr<__func, _Dp> __hold(__af.allocate(1), _Dp(__af, 1));
433*5f757f3fSDimitry Andric                 ::new ((void*)__hold.get()) _Fun(std::move(__f), _Alloc(__a));
434fe6060f1SDimitry Andric                 __f_ = __hold.release();
435fe6060f1SDimitry Andric             }
436fe6060f1SDimitry Andric         }
437fe6060f1SDimitry Andric     }
438fe6060f1SDimitry Andric 
439*5f757f3fSDimitry Andric     template <class _Fp, __enable_if_t<!is_same<__decay_t<_Fp>, __value_func>::value, int> = 0>
440*5f757f3fSDimitry Andric     _LIBCPP_HIDE_FROM_ABI explicit __value_func(_Fp&& __f)
441*5f757f3fSDimitry Andric         : __value_func(std::forward<_Fp>(__f), allocator<_Fp>()) {}
442fe6060f1SDimitry Andric 
443*5f757f3fSDimitry Andric     _LIBCPP_HIDE_FROM_ABI
444fe6060f1SDimitry Andric     __value_func(const __value_func& __f)
445fe6060f1SDimitry Andric     {
446fe6060f1SDimitry Andric         if (__f.__f_ == nullptr)
447fe6060f1SDimitry Andric             __f_ = nullptr;
448fe6060f1SDimitry Andric         else if ((void*)__f.__f_ == &__f.__buf_)
449fe6060f1SDimitry Andric         {
450fe6060f1SDimitry Andric             __f_ = __as_base(&__buf_);
451fe6060f1SDimitry Andric             __f.__f_->__clone(__f_);
452fe6060f1SDimitry Andric         }
453fe6060f1SDimitry Andric         else
454fe6060f1SDimitry Andric             __f_ = __f.__f_->__clone();
455fe6060f1SDimitry Andric     }
456fe6060f1SDimitry Andric 
457*5f757f3fSDimitry Andric     _LIBCPP_HIDE_FROM_ABI
458fe6060f1SDimitry Andric     __value_func(__value_func&& __f) _NOEXCEPT
459fe6060f1SDimitry Andric     {
460fe6060f1SDimitry Andric         if (__f.__f_ == nullptr)
461fe6060f1SDimitry Andric             __f_ = nullptr;
462fe6060f1SDimitry Andric         else if ((void*)__f.__f_ == &__f.__buf_)
463fe6060f1SDimitry Andric         {
464fe6060f1SDimitry Andric             __f_ = __as_base(&__buf_);
465fe6060f1SDimitry Andric             __f.__f_->__clone(__f_);
466fe6060f1SDimitry Andric         }
467fe6060f1SDimitry Andric         else
468fe6060f1SDimitry Andric         {
469fe6060f1SDimitry Andric             __f_ = __f.__f_;
470fe6060f1SDimitry Andric             __f.__f_ = nullptr;
471fe6060f1SDimitry Andric         }
472fe6060f1SDimitry Andric     }
473fe6060f1SDimitry Andric 
474*5f757f3fSDimitry Andric     _LIBCPP_HIDE_FROM_ABI
475fe6060f1SDimitry Andric     ~__value_func()
476fe6060f1SDimitry Andric     {
477fe6060f1SDimitry Andric         if ((void*)__f_ == &__buf_)
478fe6060f1SDimitry Andric             __f_->destroy();
479fe6060f1SDimitry Andric         else if (__f_)
480fe6060f1SDimitry Andric             __f_->destroy_deallocate();
481fe6060f1SDimitry Andric     }
482fe6060f1SDimitry Andric 
483*5f757f3fSDimitry Andric     _LIBCPP_HIDE_FROM_ABI
484fe6060f1SDimitry Andric     __value_func& operator=(__value_func&& __f)
485fe6060f1SDimitry Andric     {
486fe6060f1SDimitry Andric         *this = nullptr;
487fe6060f1SDimitry Andric         if (__f.__f_ == nullptr)
488fe6060f1SDimitry Andric             __f_ = nullptr;
489fe6060f1SDimitry Andric         else if ((void*)__f.__f_ == &__f.__buf_)
490fe6060f1SDimitry Andric         {
491fe6060f1SDimitry Andric             __f_ = __as_base(&__buf_);
492fe6060f1SDimitry Andric             __f.__f_->__clone(__f_);
493fe6060f1SDimitry Andric         }
494fe6060f1SDimitry Andric         else
495fe6060f1SDimitry Andric         {
496fe6060f1SDimitry Andric             __f_ = __f.__f_;
497fe6060f1SDimitry Andric             __f.__f_ = nullptr;
498fe6060f1SDimitry Andric         }
499fe6060f1SDimitry Andric         return *this;
500fe6060f1SDimitry Andric     }
501fe6060f1SDimitry Andric 
502*5f757f3fSDimitry Andric     _LIBCPP_HIDE_FROM_ABI
503fe6060f1SDimitry Andric     __value_func& operator=(nullptr_t)
504fe6060f1SDimitry Andric     {
505fe6060f1SDimitry Andric         __func* __f = __f_;
506fe6060f1SDimitry Andric         __f_ = nullptr;
507fe6060f1SDimitry Andric         if ((void*)__f == &__buf_)
508fe6060f1SDimitry Andric             __f->destroy();
509fe6060f1SDimitry Andric         else if (__f)
510fe6060f1SDimitry Andric             __f->destroy_deallocate();
511fe6060f1SDimitry Andric         return *this;
512fe6060f1SDimitry Andric     }
513fe6060f1SDimitry Andric 
514*5f757f3fSDimitry Andric     _LIBCPP_HIDE_FROM_ABI
515fe6060f1SDimitry Andric     _Rp operator()(_ArgTypes&&... __args) const
516fe6060f1SDimitry Andric     {
517fe6060f1SDimitry Andric         if (__f_ == nullptr)
518fe6060f1SDimitry Andric             __throw_bad_function_call();
519*5f757f3fSDimitry Andric         return (*__f_)(std::forward<_ArgTypes>(__args)...);
520fe6060f1SDimitry Andric     }
521fe6060f1SDimitry Andric 
522*5f757f3fSDimitry Andric     _LIBCPP_HIDE_FROM_ABI
523fe6060f1SDimitry Andric     void swap(__value_func& __f) _NOEXCEPT
524fe6060f1SDimitry Andric     {
525fe6060f1SDimitry Andric         if (&__f == this)
526fe6060f1SDimitry Andric             return;
527fe6060f1SDimitry Andric         if ((void*)__f_ == &__buf_ && (void*)__f.__f_ == &__f.__buf_)
528fe6060f1SDimitry Andric         {
529bdd1243dSDimitry Andric             _LIBCPP_SUPPRESS_DEPRECATED_PUSH
530fe6060f1SDimitry Andric             typename aligned_storage<sizeof(__buf_)>::type __tempbuf;
531bdd1243dSDimitry Andric             _LIBCPP_SUPPRESS_DEPRECATED_POP
532fe6060f1SDimitry Andric             __func* __t = __as_base(&__tempbuf);
533fe6060f1SDimitry Andric             __f_->__clone(__t);
534fe6060f1SDimitry Andric             __f_->destroy();
535fe6060f1SDimitry Andric             __f_ = nullptr;
536fe6060f1SDimitry Andric             __f.__f_->__clone(__as_base(&__buf_));
537fe6060f1SDimitry Andric             __f.__f_->destroy();
538fe6060f1SDimitry Andric             __f.__f_ = nullptr;
539fe6060f1SDimitry Andric             __f_ = __as_base(&__buf_);
540fe6060f1SDimitry Andric             __t->__clone(__as_base(&__f.__buf_));
541fe6060f1SDimitry Andric             __t->destroy();
542fe6060f1SDimitry Andric             __f.__f_ = __as_base(&__f.__buf_);
543fe6060f1SDimitry Andric         }
544fe6060f1SDimitry Andric         else if ((void*)__f_ == &__buf_)
545fe6060f1SDimitry Andric         {
546fe6060f1SDimitry Andric             __f_->__clone(__as_base(&__f.__buf_));
547fe6060f1SDimitry Andric             __f_->destroy();
548fe6060f1SDimitry Andric             __f_ = __f.__f_;
549fe6060f1SDimitry Andric             __f.__f_ = __as_base(&__f.__buf_);
550fe6060f1SDimitry Andric         }
551fe6060f1SDimitry Andric         else if ((void*)__f.__f_ == &__f.__buf_)
552fe6060f1SDimitry Andric         {
553fe6060f1SDimitry Andric             __f.__f_->__clone(__as_base(&__buf_));
554fe6060f1SDimitry Andric             __f.__f_->destroy();
555fe6060f1SDimitry Andric             __f.__f_ = __f_;
556fe6060f1SDimitry Andric             __f_ = __as_base(&__buf_);
557fe6060f1SDimitry Andric         }
558fe6060f1SDimitry Andric         else
559*5f757f3fSDimitry Andric             std::swap(__f_, __f.__f_);
560fe6060f1SDimitry Andric     }
561fe6060f1SDimitry Andric 
562*5f757f3fSDimitry Andric     _LIBCPP_HIDE_FROM_ABI
563fe6060f1SDimitry Andric     explicit operator bool() const _NOEXCEPT { return __f_ != nullptr; }
564fe6060f1SDimitry Andric 
5651ac55f4cSDimitry Andric #ifndef _LIBCPP_HAS_NO_RTTI
566*5f757f3fSDimitry Andric     _LIBCPP_HIDE_FROM_ABI
567fe6060f1SDimitry Andric     const std::type_info& target_type() const _NOEXCEPT
568fe6060f1SDimitry Andric     {
569fe6060f1SDimitry Andric         if (__f_ == nullptr)
570fe6060f1SDimitry Andric             return typeid(void);
571fe6060f1SDimitry Andric         return __f_->target_type();
572fe6060f1SDimitry Andric     }
573fe6060f1SDimitry Andric 
574fe6060f1SDimitry Andric     template <typename _Tp>
575*5f757f3fSDimitry Andric     _LIBCPP_HIDE_FROM_ABI const _Tp* target() const _NOEXCEPT
576fe6060f1SDimitry Andric     {
577fe6060f1SDimitry Andric         if (__f_ == nullptr)
578fe6060f1SDimitry Andric             return nullptr;
579fe6060f1SDimitry Andric         return (const _Tp*)__f_->target(typeid(_Tp));
580fe6060f1SDimitry Andric     }
5811ac55f4cSDimitry Andric #endif // _LIBCPP_HAS_NO_RTTI
582fe6060f1SDimitry Andric };
583fe6060f1SDimitry Andric 
584fe6060f1SDimitry Andric // Storage for a functor object, to be used with __policy to manage copy and
585fe6060f1SDimitry Andric // destruction.
586fe6060f1SDimitry Andric union __policy_storage
587fe6060f1SDimitry Andric {
588fe6060f1SDimitry Andric     mutable char __small[sizeof(void*) * 2];
589fe6060f1SDimitry Andric     void* __large;
590fe6060f1SDimitry Andric };
591fe6060f1SDimitry Andric 
592fe6060f1SDimitry Andric // True if _Fun can safely be held in __policy_storage.__small.
593fe6060f1SDimitry Andric template <typename _Fun>
594fe6060f1SDimitry Andric struct __use_small_storage
595fe6060f1SDimitry Andric     : public integral_constant<
596fe6060f1SDimitry Andric           bool, sizeof(_Fun) <= sizeof(__policy_storage) &&
597fe6060f1SDimitry Andric                     _LIBCPP_ALIGNOF(_Fun) <= _LIBCPP_ALIGNOF(__policy_storage) &&
598fe6060f1SDimitry Andric                     is_trivially_copy_constructible<_Fun>::value &&
599fe6060f1SDimitry Andric                     is_trivially_destructible<_Fun>::value> {};
600fe6060f1SDimitry Andric 
601fe6060f1SDimitry Andric // Policy contains information about how to copy, destroy, and move the
602fe6060f1SDimitry Andric // underlying functor. You can think of it as a vtable of sorts.
603fe6060f1SDimitry Andric struct __policy
604fe6060f1SDimitry Andric {
605fe6060f1SDimitry Andric     // Used to copy or destroy __large values. null for trivial objects.
606fe6060f1SDimitry Andric     void* (*const __clone)(const void*);
607fe6060f1SDimitry Andric     void (*const __destroy)(void*);
608fe6060f1SDimitry Andric 
609fe6060f1SDimitry Andric     // True if this is the null policy (no value).
610fe6060f1SDimitry Andric     const bool __is_null;
611fe6060f1SDimitry Andric 
612fe6060f1SDimitry Andric     // The target type. May be null if RTTI is disabled.
613fe6060f1SDimitry Andric     const std::type_info* const __type_info;
614fe6060f1SDimitry Andric 
615fe6060f1SDimitry Andric     // Returns a pointer to a static policy object suitable for the functor
616fe6060f1SDimitry Andric     // type.
617fe6060f1SDimitry Andric     template <typename _Fun>
618*5f757f3fSDimitry Andric     _LIBCPP_HIDE_FROM_ABI static const __policy* __create()
619fe6060f1SDimitry Andric     {
620fe6060f1SDimitry Andric         return __choose_policy<_Fun>(__use_small_storage<_Fun>());
621fe6060f1SDimitry Andric     }
622fe6060f1SDimitry Andric 
623*5f757f3fSDimitry Andric     _LIBCPP_HIDE_FROM_ABI
624fe6060f1SDimitry Andric     static const __policy* __create_empty()
625fe6060f1SDimitry Andric     {
62606c3fb27SDimitry Andric         static const _LIBCPP_CONSTEXPR __policy __policy = {nullptr, nullptr,
627fe6060f1SDimitry Andric                                                             true,
6281ac55f4cSDimitry Andric #ifndef _LIBCPP_HAS_NO_RTTI
629fe6060f1SDimitry Andric                                                             &typeid(void)
630fe6060f1SDimitry Andric #else
631fe6060f1SDimitry Andric                                                             nullptr
632fe6060f1SDimitry Andric #endif
633fe6060f1SDimitry Andric         };
63406c3fb27SDimitry Andric         return &__policy;
635fe6060f1SDimitry Andric     }
636fe6060f1SDimitry Andric 
637fe6060f1SDimitry Andric   private:
63806c3fb27SDimitry Andric     template <typename _Fun>
63906c3fb27SDimitry Andric     _LIBCPP_HIDE_FROM_ABI static void* __large_clone(const void* __s)
640fe6060f1SDimitry Andric     {
641fe6060f1SDimitry Andric         const _Fun* __f = static_cast<const _Fun*>(__s);
642fe6060f1SDimitry Andric         return __f->__clone();
643fe6060f1SDimitry Andric     }
644fe6060f1SDimitry Andric 
645fe6060f1SDimitry Andric     template <typename _Fun>
64606c3fb27SDimitry Andric     _LIBCPP_HIDE_FROM_ABI static void __large_destroy(void* __s) {
647fe6060f1SDimitry Andric       _Fun::__destroy_and_delete(static_cast<_Fun*>(__s));
648fe6060f1SDimitry Andric     }
649fe6060f1SDimitry Andric 
650fe6060f1SDimitry Andric     template <typename _Fun>
651*5f757f3fSDimitry Andric     _LIBCPP_HIDE_FROM_ABI static const __policy*
652fe6060f1SDimitry Andric     __choose_policy(/* is_small = */ false_type) {
65306c3fb27SDimitry Andric       static const _LIBCPP_CONSTEXPR __policy __policy = {
654fe6060f1SDimitry Andric           &__large_clone<_Fun>, &__large_destroy<_Fun>, false,
6551ac55f4cSDimitry Andric #ifndef _LIBCPP_HAS_NO_RTTI
656fe6060f1SDimitry Andric           &typeid(typename _Fun::_Target)
657fe6060f1SDimitry Andric #else
658fe6060f1SDimitry Andric           nullptr
659fe6060f1SDimitry Andric #endif
660fe6060f1SDimitry Andric       };
66106c3fb27SDimitry Andric         return &__policy;
662fe6060f1SDimitry Andric     }
663fe6060f1SDimitry Andric 
664fe6060f1SDimitry Andric     template <typename _Fun>
665*5f757f3fSDimitry Andric     _LIBCPP_HIDE_FROM_ABI static const __policy*
666fe6060f1SDimitry Andric         __choose_policy(/* is_small = */ true_type)
667fe6060f1SDimitry Andric     {
66806c3fb27SDimitry Andric         static const _LIBCPP_CONSTEXPR __policy __policy = {
669fe6060f1SDimitry Andric             nullptr, nullptr, false,
6701ac55f4cSDimitry Andric #ifndef _LIBCPP_HAS_NO_RTTI
671fe6060f1SDimitry Andric             &typeid(typename _Fun::_Target)
672fe6060f1SDimitry Andric #else
673fe6060f1SDimitry Andric             nullptr
674fe6060f1SDimitry Andric #endif
675fe6060f1SDimitry Andric         };
67606c3fb27SDimitry Andric         return &__policy;
677fe6060f1SDimitry Andric     }
678fe6060f1SDimitry Andric };
679fe6060f1SDimitry Andric 
680fe6060f1SDimitry Andric // Used to choose between perfect forwarding or pass-by-value. Pass-by-value is
681fe6060f1SDimitry Andric // faster for types that can be passed in registers.
682fe6060f1SDimitry Andric template <typename _Tp>
683bdd1243dSDimitry Andric using __fast_forward = __conditional_t<is_scalar<_Tp>::value, _Tp, _Tp&&>;
684fe6060f1SDimitry Andric 
685fe6060f1SDimitry Andric // __policy_invoker calls an instance of __alloc_func held in __policy_storage.
686fe6060f1SDimitry Andric 
687fe6060f1SDimitry Andric template <class _Fp> struct __policy_invoker;
688fe6060f1SDimitry Andric 
689fe6060f1SDimitry Andric template <class _Rp, class... _ArgTypes>
690fe6060f1SDimitry Andric struct __policy_invoker<_Rp(_ArgTypes...)>
691fe6060f1SDimitry Andric {
692fe6060f1SDimitry Andric     typedef _Rp (*__Call)(const __policy_storage*,
693fe6060f1SDimitry Andric                           __fast_forward<_ArgTypes>...);
694fe6060f1SDimitry Andric 
695fe6060f1SDimitry Andric     __Call __call_;
696fe6060f1SDimitry Andric 
697fe6060f1SDimitry Andric     // Creates an invoker that throws bad_function_call.
698*5f757f3fSDimitry Andric     _LIBCPP_HIDE_FROM_ABI
699fe6060f1SDimitry Andric     __policy_invoker() : __call_(&__call_empty) {}
700fe6060f1SDimitry Andric 
701fe6060f1SDimitry Andric     // Creates an invoker that calls the given instance of __func.
702fe6060f1SDimitry Andric     template <typename _Fun>
703*5f757f3fSDimitry Andric     _LIBCPP_HIDE_FROM_ABI static __policy_invoker __create()
704fe6060f1SDimitry Andric     {
705fe6060f1SDimitry Andric         return __policy_invoker(&__call_impl<_Fun>);
706fe6060f1SDimitry Andric     }
707fe6060f1SDimitry Andric 
708fe6060f1SDimitry Andric   private:
709*5f757f3fSDimitry Andric     _LIBCPP_HIDE_FROM_ABI
710fe6060f1SDimitry Andric     explicit __policy_invoker(__Call __c) : __call_(__c) {}
711fe6060f1SDimitry Andric 
71206c3fb27SDimitry Andric     _LIBCPP_HIDE_FROM_ABI static _Rp __call_empty(const __policy_storage*,
713fe6060f1SDimitry Andric                             __fast_forward<_ArgTypes>...)
714fe6060f1SDimitry Andric     {
715fe6060f1SDimitry Andric         __throw_bad_function_call();
716fe6060f1SDimitry Andric     }
717fe6060f1SDimitry Andric 
718fe6060f1SDimitry Andric     template <typename _Fun>
71906c3fb27SDimitry Andric     _LIBCPP_HIDE_FROM_ABI static _Rp __call_impl(const __policy_storage* __buf,
720fe6060f1SDimitry Andric                            __fast_forward<_ArgTypes>... __args)
721fe6060f1SDimitry Andric     {
722fe6060f1SDimitry Andric         _Fun* __f = reinterpret_cast<_Fun*>(__use_small_storage<_Fun>::value
723fe6060f1SDimitry Andric                                                 ? &__buf->__small
724fe6060f1SDimitry Andric                                                 : __buf->__large);
725*5f757f3fSDimitry Andric         return (*__f)(std::forward<_ArgTypes>(__args)...);
726fe6060f1SDimitry Andric     }
727fe6060f1SDimitry Andric };
728fe6060f1SDimitry Andric 
729fe6060f1SDimitry Andric // __policy_func uses a __policy and __policy_invoker to create a type-erased,
730fe6060f1SDimitry Andric // copyable functor.
731fe6060f1SDimitry Andric 
732fe6060f1SDimitry Andric template <class _Fp> class __policy_func;
733fe6060f1SDimitry Andric 
734fe6060f1SDimitry Andric template <class _Rp, class... _ArgTypes> class __policy_func<_Rp(_ArgTypes...)>
735fe6060f1SDimitry Andric {
736fe6060f1SDimitry Andric     // Inline storage for small objects.
737fe6060f1SDimitry Andric     __policy_storage __buf_;
738fe6060f1SDimitry Andric 
739fe6060f1SDimitry Andric     // Calls the value stored in __buf_. This could technically be part of
740fe6060f1SDimitry Andric     // policy, but storing it here eliminates a level of indirection inside
741fe6060f1SDimitry Andric     // operator().
742fe6060f1SDimitry Andric     typedef __function::__policy_invoker<_Rp(_ArgTypes...)> __invoker;
743fe6060f1SDimitry Andric     __invoker __invoker_;
744fe6060f1SDimitry Andric 
745fe6060f1SDimitry Andric     // The policy that describes how to move / copy / destroy __buf_. Never
746fe6060f1SDimitry Andric     // null, even if the function is empty.
747fe6060f1SDimitry Andric     const __policy* __policy_;
748fe6060f1SDimitry Andric 
749fe6060f1SDimitry Andric   public:
750*5f757f3fSDimitry Andric     _LIBCPP_HIDE_FROM_ABI
751fe6060f1SDimitry Andric     __policy_func() : __policy_(__policy::__create_empty()) {}
752fe6060f1SDimitry Andric 
753fe6060f1SDimitry Andric     template <class _Fp, class _Alloc>
754*5f757f3fSDimitry Andric     _LIBCPP_HIDE_FROM_ABI __policy_func(_Fp&& __f, const _Alloc& __a)
755fe6060f1SDimitry Andric         : __policy_(__policy::__create_empty())
756fe6060f1SDimitry Andric     {
757fe6060f1SDimitry Andric         typedef __alloc_func<_Fp, _Alloc, _Rp(_ArgTypes...)> _Fun;
758fe6060f1SDimitry Andric         typedef allocator_traits<_Alloc> __alloc_traits;
759bdd1243dSDimitry Andric         typedef __rebind_alloc<__alloc_traits, _Fun> _FunAlloc;
760fe6060f1SDimitry Andric 
761fe6060f1SDimitry Andric         if (__function::__not_null(__f))
762fe6060f1SDimitry Andric         {
763fe6060f1SDimitry Andric             __invoker_ = __invoker::template __create<_Fun>();
764fe6060f1SDimitry Andric             __policy_ = __policy::__create<_Fun>();
765fe6060f1SDimitry Andric 
766fe6060f1SDimitry Andric             _FunAlloc __af(__a);
767fe6060f1SDimitry Andric             if (__use_small_storage<_Fun>())
768fe6060f1SDimitry Andric             {
769fe6060f1SDimitry Andric                 ::new ((void*)&__buf_.__small)
770*5f757f3fSDimitry Andric                     _Fun(std::move(__f), _Alloc(__af));
771fe6060f1SDimitry Andric             }
772fe6060f1SDimitry Andric             else
773fe6060f1SDimitry Andric             {
774fe6060f1SDimitry Andric                 typedef __allocator_destructor<_FunAlloc> _Dp;
775fe6060f1SDimitry Andric                 unique_ptr<_Fun, _Dp> __hold(__af.allocate(1), _Dp(__af, 1));
776fe6060f1SDimitry Andric                 ::new ((void*)__hold.get())
777*5f757f3fSDimitry Andric                     _Fun(std::move(__f), _Alloc(__af));
778fe6060f1SDimitry Andric                 __buf_.__large = __hold.release();
779fe6060f1SDimitry Andric             }
780fe6060f1SDimitry Andric         }
781fe6060f1SDimitry Andric     }
782fe6060f1SDimitry Andric 
783*5f757f3fSDimitry Andric     template <class _Fp, __enable_if_t<!is_same<__decay_t<_Fp>, __policy_func>::value, int> = 0>
784*5f757f3fSDimitry Andric     _LIBCPP_HIDE_FROM_ABI explicit __policy_func(_Fp&& __f)
785fe6060f1SDimitry Andric         : __policy_(__policy::__create_empty()) {
786fe6060f1SDimitry Andric       typedef __default_alloc_func<_Fp, _Rp(_ArgTypes...)> _Fun;
787fe6060f1SDimitry Andric 
788fe6060f1SDimitry Andric       if (__function::__not_null(__f)) {
789fe6060f1SDimitry Andric         __invoker_ = __invoker::template __create<_Fun>();
790fe6060f1SDimitry Andric         __policy_ = __policy::__create<_Fun>();
791fe6060f1SDimitry Andric         if (__use_small_storage<_Fun>()) {
792*5f757f3fSDimitry Andric           ::new ((void*)&__buf_.__small) _Fun(std::move(__f));
793fe6060f1SDimitry Andric         } else {
794fe6060f1SDimitry Andric           __builtin_new_allocator::__holder_t __hold =
795fe6060f1SDimitry Andric               __builtin_new_allocator::__allocate_type<_Fun>(1);
796*5f757f3fSDimitry Andric           __buf_.__large = ::new ((void*)__hold.get()) _Fun(std::move(__f));
797fe6060f1SDimitry Andric           (void)__hold.release();
798fe6060f1SDimitry Andric         }
799fe6060f1SDimitry Andric       }
800fe6060f1SDimitry Andric     }
801fe6060f1SDimitry Andric 
802*5f757f3fSDimitry Andric     _LIBCPP_HIDE_FROM_ABI
803fe6060f1SDimitry Andric     __policy_func(const __policy_func& __f)
804fe6060f1SDimitry Andric         : __buf_(__f.__buf_), __invoker_(__f.__invoker_),
805fe6060f1SDimitry Andric           __policy_(__f.__policy_)
806fe6060f1SDimitry Andric     {
807fe6060f1SDimitry Andric         if (__policy_->__clone)
808fe6060f1SDimitry Andric             __buf_.__large = __policy_->__clone(__f.__buf_.__large);
809fe6060f1SDimitry Andric     }
810fe6060f1SDimitry Andric 
811*5f757f3fSDimitry Andric     _LIBCPP_HIDE_FROM_ABI
812fe6060f1SDimitry Andric     __policy_func(__policy_func&& __f)
813fe6060f1SDimitry Andric         : __buf_(__f.__buf_), __invoker_(__f.__invoker_),
814fe6060f1SDimitry Andric           __policy_(__f.__policy_)
815fe6060f1SDimitry Andric     {
816fe6060f1SDimitry Andric         if (__policy_->__destroy)
817fe6060f1SDimitry Andric         {
818fe6060f1SDimitry Andric             __f.__policy_ = __policy::__create_empty();
819fe6060f1SDimitry Andric             __f.__invoker_ = __invoker();
820fe6060f1SDimitry Andric         }
821fe6060f1SDimitry Andric     }
822fe6060f1SDimitry Andric 
823*5f757f3fSDimitry Andric     _LIBCPP_HIDE_FROM_ABI
824fe6060f1SDimitry Andric     ~__policy_func()
825fe6060f1SDimitry Andric     {
826fe6060f1SDimitry Andric         if (__policy_->__destroy)
827fe6060f1SDimitry Andric             __policy_->__destroy(__buf_.__large);
828fe6060f1SDimitry Andric     }
829fe6060f1SDimitry Andric 
830*5f757f3fSDimitry Andric     _LIBCPP_HIDE_FROM_ABI
831fe6060f1SDimitry Andric     __policy_func& operator=(__policy_func&& __f)
832fe6060f1SDimitry Andric     {
833fe6060f1SDimitry Andric         *this = nullptr;
834fe6060f1SDimitry Andric         __buf_ = __f.__buf_;
835fe6060f1SDimitry Andric         __invoker_ = __f.__invoker_;
836fe6060f1SDimitry Andric         __policy_ = __f.__policy_;
837fe6060f1SDimitry Andric         __f.__policy_ = __policy::__create_empty();
838fe6060f1SDimitry Andric         __f.__invoker_ = __invoker();
839fe6060f1SDimitry Andric         return *this;
840fe6060f1SDimitry Andric     }
841fe6060f1SDimitry Andric 
842*5f757f3fSDimitry Andric     _LIBCPP_HIDE_FROM_ABI
843fe6060f1SDimitry Andric     __policy_func& operator=(nullptr_t)
844fe6060f1SDimitry Andric     {
845fe6060f1SDimitry Andric         const __policy* __p = __policy_;
846fe6060f1SDimitry Andric         __policy_ = __policy::__create_empty();
847fe6060f1SDimitry Andric         __invoker_ = __invoker();
848fe6060f1SDimitry Andric         if (__p->__destroy)
849fe6060f1SDimitry Andric             __p->__destroy(__buf_.__large);
850fe6060f1SDimitry Andric         return *this;
851fe6060f1SDimitry Andric     }
852fe6060f1SDimitry Andric 
853*5f757f3fSDimitry Andric     _LIBCPP_HIDE_FROM_ABI
854fe6060f1SDimitry Andric     _Rp operator()(_ArgTypes&&... __args) const
855fe6060f1SDimitry Andric     {
856*5f757f3fSDimitry Andric         return __invoker_.__call_(std::addressof(__buf_),
857*5f757f3fSDimitry Andric                                   std::forward<_ArgTypes>(__args)...);
858fe6060f1SDimitry Andric     }
859fe6060f1SDimitry Andric 
860*5f757f3fSDimitry Andric     _LIBCPP_HIDE_FROM_ABI
861fe6060f1SDimitry Andric     void swap(__policy_func& __f)
862fe6060f1SDimitry Andric     {
863*5f757f3fSDimitry Andric         std::swap(__invoker_, __f.__invoker_);
864*5f757f3fSDimitry Andric         std::swap(__policy_, __f.__policy_);
865*5f757f3fSDimitry Andric         std::swap(__buf_, __f.__buf_);
866fe6060f1SDimitry Andric     }
867fe6060f1SDimitry Andric 
868*5f757f3fSDimitry Andric     _LIBCPP_HIDE_FROM_ABI
869fe6060f1SDimitry Andric     explicit operator bool() const _NOEXCEPT
870fe6060f1SDimitry Andric     {
871fe6060f1SDimitry Andric         return !__policy_->__is_null;
872fe6060f1SDimitry Andric     }
873fe6060f1SDimitry Andric 
8741ac55f4cSDimitry Andric #ifndef _LIBCPP_HAS_NO_RTTI
875*5f757f3fSDimitry Andric     _LIBCPP_HIDE_FROM_ABI
876fe6060f1SDimitry Andric     const std::type_info& target_type() const _NOEXCEPT
877fe6060f1SDimitry Andric     {
878fe6060f1SDimitry Andric         return *__policy_->__type_info;
879fe6060f1SDimitry Andric     }
880fe6060f1SDimitry Andric 
881fe6060f1SDimitry Andric     template <typename _Tp>
882*5f757f3fSDimitry Andric     _LIBCPP_HIDE_FROM_ABI const _Tp* target() const _NOEXCEPT
883fe6060f1SDimitry Andric     {
884fe6060f1SDimitry Andric         if (__policy_->__is_null || typeid(_Tp) != *__policy_->__type_info)
885fe6060f1SDimitry Andric             return nullptr;
886fe6060f1SDimitry Andric         if (__policy_->__clone) // Out of line storage.
887fe6060f1SDimitry Andric             return reinterpret_cast<const _Tp*>(__buf_.__large);
888fe6060f1SDimitry Andric         else
889fe6060f1SDimitry Andric             return reinterpret_cast<const _Tp*>(&__buf_.__small);
890fe6060f1SDimitry Andric     }
8911ac55f4cSDimitry Andric #endif // _LIBCPP_HAS_NO_RTTI
892fe6060f1SDimitry Andric };
893fe6060f1SDimitry Andric 
894f3fd488fSDimitry Andric #if defined(_LIBCPP_HAS_BLOCKS_RUNTIME)
895fe6060f1SDimitry Andric 
896fe6060f1SDimitry Andric extern "C" void *_Block_copy(const void *);
897fe6060f1SDimitry Andric extern "C" void _Block_release(const void *);
898fe6060f1SDimitry Andric 
899fe6060f1SDimitry Andric template<class _Rp1, class ..._ArgTypes1, class _Alloc, class _Rp, class ..._ArgTypes>
900fe6060f1SDimitry Andric class __func<_Rp1(^)(_ArgTypes1...), _Alloc, _Rp(_ArgTypes...)>
901fe6060f1SDimitry Andric     : public  __base<_Rp(_ArgTypes...)>
902fe6060f1SDimitry Andric {
903fe6060f1SDimitry Andric     typedef _Rp1(^__block_type)(_ArgTypes1...);
904fe6060f1SDimitry Andric     __block_type __f_;
905fe6060f1SDimitry Andric 
906fe6060f1SDimitry Andric public:
907*5f757f3fSDimitry Andric     _LIBCPP_HIDE_FROM_ABI
908fe6060f1SDimitry Andric     explicit __func(__block_type const& __f)
909f3fd488fSDimitry Andric #ifdef _LIBCPP_HAS_OBJC_ARC
910f3fd488fSDimitry Andric         : __f_(__f)
911f3fd488fSDimitry Andric #else
912fe6060f1SDimitry Andric         : __f_(reinterpret_cast<__block_type>(__f ? _Block_copy(__f) : nullptr))
913f3fd488fSDimitry Andric #endif
914fe6060f1SDimitry Andric     { }
915fe6060f1SDimitry Andric 
916fe6060f1SDimitry Andric     // [TODO] add && to save on a retain
917fe6060f1SDimitry Andric 
918*5f757f3fSDimitry Andric     _LIBCPP_HIDE_FROM_ABI
919fe6060f1SDimitry Andric     explicit __func(__block_type __f, const _Alloc& /* unused */)
920f3fd488fSDimitry Andric #ifdef _LIBCPP_HAS_OBJC_ARC
921f3fd488fSDimitry Andric         : __f_(__f)
922f3fd488fSDimitry Andric #else
923fe6060f1SDimitry Andric         : __f_(reinterpret_cast<__block_type>(__f ? _Block_copy(__f) : nullptr))
924f3fd488fSDimitry Andric #endif
925fe6060f1SDimitry Andric     { }
926fe6060f1SDimitry Andric 
927fe6060f1SDimitry Andric     virtual __base<_Rp(_ArgTypes...)>* __clone() const {
92806c3fb27SDimitry Andric         _LIBCPP_ASSERT_INTERNAL(false,
929fe6060f1SDimitry Andric             "Block pointers are just pointers, so they should always fit into "
930fe6060f1SDimitry Andric             "std::function's small buffer optimization. This function should "
931fe6060f1SDimitry Andric             "never be invoked.");
932fe6060f1SDimitry Andric         return nullptr;
933fe6060f1SDimitry Andric     }
934fe6060f1SDimitry Andric 
935fe6060f1SDimitry Andric     virtual void __clone(__base<_Rp(_ArgTypes...)>* __p) const {
936fe6060f1SDimitry Andric         ::new ((void*)__p) __func(__f_);
937fe6060f1SDimitry Andric     }
938fe6060f1SDimitry Andric 
939fe6060f1SDimitry Andric     virtual void destroy() _NOEXCEPT {
940f3fd488fSDimitry Andric #ifndef _LIBCPP_HAS_OBJC_ARC
941fe6060f1SDimitry Andric         if (__f_)
942fe6060f1SDimitry Andric             _Block_release(__f_);
943f3fd488fSDimitry Andric #endif
944fe6060f1SDimitry Andric         __f_ = 0;
945fe6060f1SDimitry Andric     }
946fe6060f1SDimitry Andric 
947fe6060f1SDimitry Andric     virtual void destroy_deallocate() _NOEXCEPT {
94806c3fb27SDimitry Andric         _LIBCPP_ASSERT_INTERNAL(false,
949fe6060f1SDimitry Andric             "Block pointers are just pointers, so they should always fit into "
950fe6060f1SDimitry Andric             "std::function's small buffer optimization. This function should "
951fe6060f1SDimitry Andric             "never be invoked.");
952fe6060f1SDimitry Andric     }
953fe6060f1SDimitry Andric 
954fe6060f1SDimitry Andric     virtual _Rp operator()(_ArgTypes&& ... __arg) {
955*5f757f3fSDimitry Andric         return std::__invoke(__f_, std::forward<_ArgTypes>(__arg)...);
956fe6060f1SDimitry Andric     }
957fe6060f1SDimitry Andric 
9581ac55f4cSDimitry Andric #ifndef _LIBCPP_HAS_NO_RTTI
959fe6060f1SDimitry Andric     virtual const void* target(type_info const& __ti) const _NOEXCEPT {
960fe6060f1SDimitry Andric         if (__ti == typeid(__func::__block_type))
961fe6060f1SDimitry Andric             return &__f_;
962fe6060f1SDimitry Andric         return (const void*)nullptr;
963fe6060f1SDimitry Andric     }
964fe6060f1SDimitry Andric 
965fe6060f1SDimitry Andric     virtual const std::type_info& target_type() const _NOEXCEPT {
966fe6060f1SDimitry Andric         return typeid(__func::__block_type);
967fe6060f1SDimitry Andric     }
9681ac55f4cSDimitry Andric #endif // _LIBCPP_HAS_NO_RTTI
969fe6060f1SDimitry Andric };
970fe6060f1SDimitry Andric 
971f3fd488fSDimitry Andric #endif // _LIBCPP_HAS_EXTENSION_BLOCKS
972fe6060f1SDimitry Andric 
9730eae32dcSDimitry Andric } // namespace __function
974fe6060f1SDimitry Andric 
975fe6060f1SDimitry Andric template<class _Rp, class ..._ArgTypes>
976fe6060f1SDimitry Andric class _LIBCPP_TEMPLATE_VIS function<_Rp(_ArgTypes...)>
977fe6060f1SDimitry Andric     : public __function::__maybe_derive_from_unary_function<_Rp(_ArgTypes...)>,
978fe6060f1SDimitry Andric       public __function::__maybe_derive_from_binary_function<_Rp(_ArgTypes...)>
979fe6060f1SDimitry Andric {
980fe6060f1SDimitry Andric #ifndef _LIBCPP_ABI_OPTIMIZED_FUNCTION
981fe6060f1SDimitry Andric     typedef __function::__value_func<_Rp(_ArgTypes...)> __func;
982fe6060f1SDimitry Andric #else
983fe6060f1SDimitry Andric     typedef __function::__policy_func<_Rp(_ArgTypes...)> __func;
984fe6060f1SDimitry Andric #endif
985fe6060f1SDimitry Andric 
986fe6060f1SDimitry Andric     __func __f_;
987fe6060f1SDimitry Andric 
988fe6060f1SDimitry Andric     template <class _Fp, bool = _And<
989bdd1243dSDimitry Andric         _IsNotSame<__remove_cvref_t<_Fp>, function>,
990fe6060f1SDimitry Andric         __invokable<_Fp, _ArgTypes...>
991fe6060f1SDimitry Andric     >::value>
992fe6060f1SDimitry Andric     struct __callable;
993fe6060f1SDimitry Andric     template <class _Fp>
994fe6060f1SDimitry Andric         struct __callable<_Fp, true>
995fe6060f1SDimitry Andric         {
996fe6060f1SDimitry Andric             static const bool value = is_void<_Rp>::value ||
997fe6060f1SDimitry Andric                 __is_core_convertible<typename __invoke_of<_Fp, _ArgTypes...>::type,
998fe6060f1SDimitry Andric                                       _Rp>::value;
999fe6060f1SDimitry Andric         };
1000fe6060f1SDimitry Andric     template <class _Fp>
1001fe6060f1SDimitry Andric         struct __callable<_Fp, false>
1002fe6060f1SDimitry Andric         {
1003fe6060f1SDimitry Andric             static const bool value = false;
1004fe6060f1SDimitry Andric         };
1005fe6060f1SDimitry Andric 
1006fe6060f1SDimitry Andric   template <class _Fp>
1007*5f757f3fSDimitry Andric   using _EnableIfLValueCallable = __enable_if_t<__callable<_Fp&>::value>;
1008fe6060f1SDimitry Andric public:
1009fe6060f1SDimitry Andric     typedef _Rp result_type;
1010fe6060f1SDimitry Andric 
1011fe6060f1SDimitry Andric     // construct/copy/destroy:
1012*5f757f3fSDimitry Andric     _LIBCPP_HIDE_FROM_ABI
1013fe6060f1SDimitry Andric     function() _NOEXCEPT { }
1014*5f757f3fSDimitry Andric     _LIBCPP_HIDE_FROM_ABI
101506c3fb27SDimitry Andric     _LIBCPP_HIDE_FROM_ABI function(nullptr_t) _NOEXCEPT {}
101606c3fb27SDimitry Andric     _LIBCPP_HIDE_FROM_ABI function(const function&);
101706c3fb27SDimitry Andric     _LIBCPP_HIDE_FROM_ABI function(function&&) _NOEXCEPT;
1018fe6060f1SDimitry Andric     template<class _Fp, class = _EnableIfLValueCallable<_Fp>>
101906c3fb27SDimitry Andric     _LIBCPP_HIDE_FROM_ABI function(_Fp);
1020fe6060f1SDimitry Andric 
1021fe6060f1SDimitry Andric #if _LIBCPP_STD_VER <= 14
1022fe6060f1SDimitry Andric     template<class _Alloc>
1023*5f757f3fSDimitry Andric       _LIBCPP_HIDE_FROM_ABI
1024fe6060f1SDimitry Andric       function(allocator_arg_t, const _Alloc&) _NOEXCEPT {}
1025fe6060f1SDimitry Andric     template<class _Alloc>
1026*5f757f3fSDimitry Andric       _LIBCPP_HIDE_FROM_ABI
1027fe6060f1SDimitry Andric       function(allocator_arg_t, const _Alloc&, nullptr_t) _NOEXCEPT {}
1028fe6060f1SDimitry Andric     template<class _Alloc>
102906c3fb27SDimitry Andric     _LIBCPP_HIDE_FROM_ABI function(allocator_arg_t, const _Alloc&, const function&);
1030fe6060f1SDimitry Andric     template<class _Alloc>
103106c3fb27SDimitry Andric     _LIBCPP_HIDE_FROM_ABI function(allocator_arg_t, const _Alloc&, function&&);
1032fe6060f1SDimitry Andric     template<class _Fp, class _Alloc, class = _EnableIfLValueCallable<_Fp>>
103306c3fb27SDimitry Andric     _LIBCPP_HIDE_FROM_ABI function(allocator_arg_t, const _Alloc& __a, _Fp __f);
1034fe6060f1SDimitry Andric #endif
1035fe6060f1SDimitry Andric 
103606c3fb27SDimitry Andric     _LIBCPP_HIDE_FROM_ABI function& operator=(const function&);
103706c3fb27SDimitry Andric     _LIBCPP_HIDE_FROM_ABI function& operator=(function&&) _NOEXCEPT;
103806c3fb27SDimitry Andric     _LIBCPP_HIDE_FROM_ABI function& operator=(nullptr_t) _NOEXCEPT;
103906c3fb27SDimitry Andric     template<class _Fp, class = _EnableIfLValueCallable<__decay_t<_Fp>>>
104006c3fb27SDimitry Andric     _LIBCPP_HIDE_FROM_ABI function& operator=(_Fp&&);
1041fe6060f1SDimitry Andric 
104206c3fb27SDimitry Andric     _LIBCPP_HIDE_FROM_ABI ~function();
1043fe6060f1SDimitry Andric 
1044fe6060f1SDimitry Andric     // function modifiers:
104506c3fb27SDimitry Andric     _LIBCPP_HIDE_FROM_ABI void swap(function&) _NOEXCEPT;
1046fe6060f1SDimitry Andric 
1047fe6060f1SDimitry Andric #if _LIBCPP_STD_VER <= 14
1048fe6060f1SDimitry Andric     template<class _Fp, class _Alloc>
1049*5f757f3fSDimitry Andric       _LIBCPP_HIDE_FROM_ABI
1050fe6060f1SDimitry Andric       void assign(_Fp&& __f, const _Alloc& __a)
1051*5f757f3fSDimitry Andric         {function(allocator_arg, __a, std::forward<_Fp>(__f)).swap(*this);}
1052fe6060f1SDimitry Andric #endif
1053fe6060f1SDimitry Andric 
1054fe6060f1SDimitry Andric     // function capacity:
1055*5f757f3fSDimitry Andric     _LIBCPP_HIDE_FROM_ABI
1056fe6060f1SDimitry Andric     explicit operator bool() const _NOEXCEPT {
1057fe6060f1SDimitry Andric       return static_cast<bool>(__f_);
1058fe6060f1SDimitry Andric     }
1059fe6060f1SDimitry Andric 
1060fe6060f1SDimitry Andric     // deleted overloads close possible hole in the type system
1061fe6060f1SDimitry Andric     template<class _R2, class... _ArgTypes2>
1062fe6060f1SDimitry Andric       bool operator==(const function<_R2(_ArgTypes2...)>&) const = delete;
106306c3fb27SDimitry Andric #if _LIBCPP_STD_VER <= 17
1064fe6060f1SDimitry Andric     template<class _R2, class... _ArgTypes2>
1065fe6060f1SDimitry Andric       bool operator!=(const function<_R2(_ArgTypes2...)>&) const = delete;
106606c3fb27SDimitry Andric #endif
1067fe6060f1SDimitry Andric public:
1068fe6060f1SDimitry Andric     // function invocation:
106906c3fb27SDimitry Andric     _LIBCPP_HIDE_FROM_ABI _Rp operator()(_ArgTypes...) const;
1070fe6060f1SDimitry Andric 
10711ac55f4cSDimitry Andric #ifndef _LIBCPP_HAS_NO_RTTI
1072fe6060f1SDimitry Andric     // function target access:
107306c3fb27SDimitry Andric     _LIBCPP_HIDE_FROM_ABI const std::type_info& target_type() const _NOEXCEPT;
107406c3fb27SDimitry Andric     template <typename _Tp>
107506c3fb27SDimitry Andric     _LIBCPP_HIDE_FROM_ABI _Tp* target() _NOEXCEPT;
107606c3fb27SDimitry Andric     template <typename _Tp>
107706c3fb27SDimitry Andric     _LIBCPP_HIDE_FROM_ABI const _Tp* target() const _NOEXCEPT;
10781ac55f4cSDimitry Andric #endif // _LIBCPP_HAS_NO_RTTI
1079fe6060f1SDimitry Andric };
1080fe6060f1SDimitry Andric 
1081349cc55cSDimitry Andric #if _LIBCPP_STD_VER >= 17
1082fe6060f1SDimitry Andric template<class _Rp, class ..._Ap>
1083fe6060f1SDimitry Andric function(_Rp(*)(_Ap...)) -> function<_Rp(_Ap...)>;
1084fe6060f1SDimitry Andric 
1085fe6060f1SDimitry Andric template<class _Fp, class _Stripped = typename __strip_signature<decltype(&_Fp::operator())>::type>
1086fe6060f1SDimitry Andric function(_Fp) -> function<_Stripped>;
1087349cc55cSDimitry Andric #endif // _LIBCPP_STD_VER >= 17
1088fe6060f1SDimitry Andric 
1089fe6060f1SDimitry Andric template<class _Rp, class ..._ArgTypes>
1090fe6060f1SDimitry Andric function<_Rp(_ArgTypes...)>::function(const function& __f) : __f_(__f.__f_) {}
1091fe6060f1SDimitry Andric 
1092fe6060f1SDimitry Andric #if _LIBCPP_STD_VER <= 14
1093fe6060f1SDimitry Andric template<class _Rp, class ..._ArgTypes>
1094fe6060f1SDimitry Andric template <class _Alloc>
1095fe6060f1SDimitry Andric function<_Rp(_ArgTypes...)>::function(allocator_arg_t, const _Alloc&,
1096fe6060f1SDimitry Andric                                      const function& __f) : __f_(__f.__f_) {}
1097fe6060f1SDimitry Andric #endif
1098fe6060f1SDimitry Andric 
1099fe6060f1SDimitry Andric template <class _Rp, class... _ArgTypes>
1100fe6060f1SDimitry Andric function<_Rp(_ArgTypes...)>::function(function&& __f) _NOEXCEPT
1101*5f757f3fSDimitry Andric     : __f_(std::move(__f.__f_)) {}
1102fe6060f1SDimitry Andric 
1103fe6060f1SDimitry Andric #if _LIBCPP_STD_VER <= 14
1104fe6060f1SDimitry Andric template<class _Rp, class ..._ArgTypes>
1105fe6060f1SDimitry Andric template <class _Alloc>
1106fe6060f1SDimitry Andric function<_Rp(_ArgTypes...)>::function(allocator_arg_t, const _Alloc&,
1107fe6060f1SDimitry Andric                                       function&& __f)
1108*5f757f3fSDimitry Andric     : __f_(std::move(__f.__f_)) {}
1109fe6060f1SDimitry Andric #endif
1110fe6060f1SDimitry Andric 
1111fe6060f1SDimitry Andric template <class _Rp, class... _ArgTypes>
1112fe6060f1SDimitry Andric template <class _Fp, class>
1113*5f757f3fSDimitry Andric function<_Rp(_ArgTypes...)>::function(_Fp __f) : __f_(std::move(__f)) {}
1114fe6060f1SDimitry Andric 
1115fe6060f1SDimitry Andric #if _LIBCPP_STD_VER <= 14
1116fe6060f1SDimitry Andric template <class _Rp, class... _ArgTypes>
1117fe6060f1SDimitry Andric template <class _Fp, class _Alloc, class>
1118fe6060f1SDimitry Andric function<_Rp(_ArgTypes...)>::function(allocator_arg_t, const _Alloc& __a,
1119fe6060f1SDimitry Andric                                       _Fp __f)
1120*5f757f3fSDimitry Andric     : __f_(std::move(__f), __a) {}
1121fe6060f1SDimitry Andric #endif
1122fe6060f1SDimitry Andric 
1123fe6060f1SDimitry Andric template<class _Rp, class ..._ArgTypes>
1124fe6060f1SDimitry Andric function<_Rp(_ArgTypes...)>&
1125fe6060f1SDimitry Andric function<_Rp(_ArgTypes...)>::operator=(const function& __f)
1126fe6060f1SDimitry Andric {
1127fe6060f1SDimitry Andric     function(__f).swap(*this);
1128fe6060f1SDimitry Andric     return *this;
1129fe6060f1SDimitry Andric }
1130fe6060f1SDimitry Andric 
1131fe6060f1SDimitry Andric template<class _Rp, class ..._ArgTypes>
1132fe6060f1SDimitry Andric function<_Rp(_ArgTypes...)>&
1133fe6060f1SDimitry Andric function<_Rp(_ArgTypes...)>::operator=(function&& __f) _NOEXCEPT
1134fe6060f1SDimitry Andric {
1135*5f757f3fSDimitry Andric     __f_ = std::move(__f.__f_);
1136fe6060f1SDimitry Andric     return *this;
1137fe6060f1SDimitry Andric }
1138fe6060f1SDimitry Andric 
1139fe6060f1SDimitry Andric template<class _Rp, class ..._ArgTypes>
1140fe6060f1SDimitry Andric function<_Rp(_ArgTypes...)>&
1141fe6060f1SDimitry Andric function<_Rp(_ArgTypes...)>::operator=(nullptr_t) _NOEXCEPT
1142fe6060f1SDimitry Andric {
1143fe6060f1SDimitry Andric     __f_ = nullptr;
1144fe6060f1SDimitry Andric     return *this;
1145fe6060f1SDimitry Andric }
1146fe6060f1SDimitry Andric 
1147fe6060f1SDimitry Andric template<class _Rp, class ..._ArgTypes>
1148fe6060f1SDimitry Andric template <class _Fp, class>
1149fe6060f1SDimitry Andric function<_Rp(_ArgTypes...)>&
1150fe6060f1SDimitry Andric function<_Rp(_ArgTypes...)>::operator=(_Fp&& __f)
1151fe6060f1SDimitry Andric {
1152*5f757f3fSDimitry Andric     function(std::forward<_Fp>(__f)).swap(*this);
1153fe6060f1SDimitry Andric     return *this;
1154fe6060f1SDimitry Andric }
1155fe6060f1SDimitry Andric 
1156fe6060f1SDimitry Andric template<class _Rp, class ..._ArgTypes>
1157fe6060f1SDimitry Andric function<_Rp(_ArgTypes...)>::~function() {}
1158fe6060f1SDimitry Andric 
1159fe6060f1SDimitry Andric template<class _Rp, class ..._ArgTypes>
1160fe6060f1SDimitry Andric void
1161fe6060f1SDimitry Andric function<_Rp(_ArgTypes...)>::swap(function& __f) _NOEXCEPT
1162fe6060f1SDimitry Andric {
1163fe6060f1SDimitry Andric     __f_.swap(__f.__f_);
1164fe6060f1SDimitry Andric }
1165fe6060f1SDimitry Andric 
1166fe6060f1SDimitry Andric template<class _Rp, class ..._ArgTypes>
1167fe6060f1SDimitry Andric _Rp
1168fe6060f1SDimitry Andric function<_Rp(_ArgTypes...)>::operator()(_ArgTypes... __arg) const
1169fe6060f1SDimitry Andric {
1170*5f757f3fSDimitry Andric     return __f_(std::forward<_ArgTypes>(__arg)...);
1171fe6060f1SDimitry Andric }
1172fe6060f1SDimitry Andric 
11731ac55f4cSDimitry Andric #ifndef _LIBCPP_HAS_NO_RTTI
1174fe6060f1SDimitry Andric 
1175fe6060f1SDimitry Andric template<class _Rp, class ..._ArgTypes>
1176fe6060f1SDimitry Andric const std::type_info&
1177fe6060f1SDimitry Andric function<_Rp(_ArgTypes...)>::target_type() const _NOEXCEPT
1178fe6060f1SDimitry Andric {
1179fe6060f1SDimitry Andric     return __f_.target_type();
1180fe6060f1SDimitry Andric }
1181fe6060f1SDimitry Andric 
1182fe6060f1SDimitry Andric template<class _Rp, class ..._ArgTypes>
1183fe6060f1SDimitry Andric template <typename _Tp>
1184fe6060f1SDimitry Andric _Tp*
1185fe6060f1SDimitry Andric function<_Rp(_ArgTypes...)>::target() _NOEXCEPT
1186fe6060f1SDimitry Andric {
1187fe6060f1SDimitry Andric     return (_Tp*)(__f_.template target<_Tp>());
1188fe6060f1SDimitry Andric }
1189fe6060f1SDimitry Andric 
1190fe6060f1SDimitry Andric template<class _Rp, class ..._ArgTypes>
1191fe6060f1SDimitry Andric template <typename _Tp>
1192fe6060f1SDimitry Andric const _Tp*
1193fe6060f1SDimitry Andric function<_Rp(_ArgTypes...)>::target() const _NOEXCEPT
1194fe6060f1SDimitry Andric {
1195fe6060f1SDimitry Andric     return __f_.template target<_Tp>();
1196fe6060f1SDimitry Andric }
1197fe6060f1SDimitry Andric 
11981ac55f4cSDimitry Andric #endif // _LIBCPP_HAS_NO_RTTI
1199fe6060f1SDimitry Andric 
1200fe6060f1SDimitry Andric template <class _Rp, class... _ArgTypes>
1201*5f757f3fSDimitry Andric inline _LIBCPP_HIDE_FROM_ABI
1202fe6060f1SDimitry Andric bool
1203fe6060f1SDimitry Andric operator==(const function<_Rp(_ArgTypes...)>& __f, nullptr_t) _NOEXCEPT {return !__f;}
1204fe6060f1SDimitry Andric 
120506c3fb27SDimitry Andric #if _LIBCPP_STD_VER <= 17
120606c3fb27SDimitry Andric 
1207fe6060f1SDimitry Andric template <class _Rp, class... _ArgTypes>
1208*5f757f3fSDimitry Andric inline _LIBCPP_HIDE_FROM_ABI
1209fe6060f1SDimitry Andric bool
1210fe6060f1SDimitry Andric operator==(nullptr_t, const function<_Rp(_ArgTypes...)>& __f) _NOEXCEPT {return !__f;}
1211fe6060f1SDimitry Andric 
1212fe6060f1SDimitry Andric template <class _Rp, class... _ArgTypes>
1213*5f757f3fSDimitry Andric inline _LIBCPP_HIDE_FROM_ABI
1214fe6060f1SDimitry Andric bool
1215fe6060f1SDimitry Andric operator!=(const function<_Rp(_ArgTypes...)>& __f, nullptr_t) _NOEXCEPT {return (bool)__f;}
1216fe6060f1SDimitry Andric 
1217fe6060f1SDimitry Andric template <class _Rp, class... _ArgTypes>
1218*5f757f3fSDimitry Andric inline _LIBCPP_HIDE_FROM_ABI
1219fe6060f1SDimitry Andric bool
1220fe6060f1SDimitry Andric operator!=(nullptr_t, const function<_Rp(_ArgTypes...)>& __f) _NOEXCEPT {return (bool)__f;}
1221fe6060f1SDimitry Andric 
122206c3fb27SDimitry Andric #endif // _LIBCPP_STD_VER <= 17
122306c3fb27SDimitry Andric 
1224fe6060f1SDimitry Andric template <class _Rp, class... _ArgTypes>
1225*5f757f3fSDimitry Andric inline _LIBCPP_HIDE_FROM_ABI
1226fe6060f1SDimitry Andric void
1227fe6060f1SDimitry Andric swap(function<_Rp(_ArgTypes...)>& __x, function<_Rp(_ArgTypes...)>& __y) _NOEXCEPT
1228fe6060f1SDimitry Andric {return __x.swap(__y);}
1229fe6060f1SDimitry Andric 
1230bdd1243dSDimitry Andric _LIBCPP_END_NAMESPACE_STD
1231fe6060f1SDimitry Andric 
123281ad6265SDimitry Andric #endif // _LIBCPP_CXX03_LANG
1233fe6060f1SDimitry Andric 
1234fe6060f1SDimitry Andric #endif // _LIBCPP___FUNCTIONAL_FUNCTION_H
1235