blob: 13d8a3d96009165635552ba3ca08d3d9adf8243a [file] [log] [blame]
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
Howard Hinnantf5256e12010-05-11 21:36:01 +00004// The LLVM Compiler Infrastructure
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00005//
Howard Hinnantb64f8b02010-11-16 22:09:02 +00006// This file is dual licensed under the MIT and the University of Illinois Open
7// Source Licenses. See LICENSE.TXT for details.
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00008//
9//===----------------------------------------------------------------------===//
10
11#ifndef _LIBCPP_FUNCTIONAL_03
12#define _LIBCPP_FUNCTIONAL_03
13
14// manual variadic expansion for <functional>
15
Howard Hinnant08e17472011-10-17 20:05:10 +000016#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +000017#pragma GCC system_header
Howard Hinnant08e17472011-10-17 20:05:10 +000018#endif
Howard Hinnantbc8d3f92010-05-11 19:42:16 +000019
Eric Fiselier45f63bc2015-07-22 04:14:38 +000020namespace __function {
Howard Hinnantbc8d3f92010-05-11 19:42:16 +000021
22template<class _Fp> class __base;
23
Howard Hinnant99968442011-11-29 18:15:50 +000024template<class _Rp>
25class __base<_Rp()>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +000026{
27 __base(const __base&);
28 __base& operator=(const __base&);
29public:
30 __base() {}
31 virtual ~__base() {}
32 virtual __base* __clone() const = 0;
33 virtual void __clone(__base*) const = 0;
34 virtual void destroy() = 0;
35 virtual void destroy_deallocate() = 0;
Howard Hinnant99968442011-11-29 18:15:50 +000036 virtual _Rp operator()() = 0;
Howard Hinnantd4444702010-08-11 17:04:31 +000037#ifndef _LIBCPP_NO_RTTI
Howard Hinnantbc8d3f92010-05-11 19:42:16 +000038 virtual const void* target(const type_info&) const = 0;
39 virtual const std::type_info& target_type() const = 0;
Howard Hinnant324bb032010-08-22 00:02:43 +000040#endif // _LIBCPP_NO_RTTI
Howard Hinnantbc8d3f92010-05-11 19:42:16 +000041};
42
Howard Hinnant99968442011-11-29 18:15:50 +000043template<class _Rp, class _A0>
44class __base<_Rp(_A0)>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +000045{
46 __base(const __base&);
47 __base& operator=(const __base&);
48public:
49 __base() {}
50 virtual ~__base() {}
51 virtual __base* __clone() const = 0;
52 virtual void __clone(__base*) const = 0;
53 virtual void destroy() = 0;
54 virtual void destroy_deallocate() = 0;
Howard Hinnant99968442011-11-29 18:15:50 +000055 virtual _Rp operator()(_A0) = 0;
Howard Hinnantd4444702010-08-11 17:04:31 +000056#ifndef _LIBCPP_NO_RTTI
Howard Hinnantbc8d3f92010-05-11 19:42:16 +000057 virtual const void* target(const type_info&) const = 0;
58 virtual const std::type_info& target_type() const = 0;
Howard Hinnant324bb032010-08-22 00:02:43 +000059#endif // _LIBCPP_NO_RTTI
Howard Hinnantbc8d3f92010-05-11 19:42:16 +000060};
61
Howard Hinnant99968442011-11-29 18:15:50 +000062template<class _Rp, class _A0, class _A1>
63class __base<_Rp(_A0, _A1)>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +000064{
65 __base(const __base&);
66 __base& operator=(const __base&);
67public:
68 __base() {}
69 virtual ~__base() {}
70 virtual __base* __clone() const = 0;
71 virtual void __clone(__base*) const = 0;
72 virtual void destroy() = 0;
73 virtual void destroy_deallocate() = 0;
Howard Hinnant99968442011-11-29 18:15:50 +000074 virtual _Rp operator()(_A0, _A1) = 0;
Howard Hinnantd4444702010-08-11 17:04:31 +000075#ifndef _LIBCPP_NO_RTTI
Howard Hinnantbc8d3f92010-05-11 19:42:16 +000076 virtual const void* target(const type_info&) const = 0;
77 virtual const std::type_info& target_type() const = 0;
Howard Hinnant324bb032010-08-22 00:02:43 +000078#endif // _LIBCPP_NO_RTTI
Howard Hinnantbc8d3f92010-05-11 19:42:16 +000079};
80
Howard Hinnant99968442011-11-29 18:15:50 +000081template<class _Rp, class _A0, class _A1, class _A2>
82class __base<_Rp(_A0, _A1, _A2)>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +000083{
84 __base(const __base&);
85 __base& operator=(const __base&);
86public:
87 __base() {}
88 virtual ~__base() {}
89 virtual __base* __clone() const = 0;
90 virtual void __clone(__base*) const = 0;
91 virtual void destroy() = 0;
92 virtual void destroy_deallocate() = 0;
Howard Hinnant99968442011-11-29 18:15:50 +000093 virtual _Rp operator()(_A0, _A1, _A2) = 0;
Howard Hinnantd4444702010-08-11 17:04:31 +000094#ifndef _LIBCPP_NO_RTTI
Howard Hinnantbc8d3f92010-05-11 19:42:16 +000095 virtual const void* target(const type_info&) const = 0;
96 virtual const std::type_info& target_type() const = 0;
Howard Hinnant324bb032010-08-22 00:02:43 +000097#endif // _LIBCPP_NO_RTTI
Howard Hinnantbc8d3f92010-05-11 19:42:16 +000098};
99
100template<class _FD, class _Alloc, class _FB> class __func;
101
Howard Hinnant99968442011-11-29 18:15:50 +0000102template<class _Fp, class _Alloc, class _Rp>
103class __func<_Fp, _Alloc, _Rp()>
104 : public __base<_Rp()>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000105{
Howard Hinnant99968442011-11-29 18:15:50 +0000106 __compressed_pair<_Fp, _Alloc> __f_;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000107public:
Howard Hinnant99968442011-11-29 18:15:50 +0000108 explicit __func(_Fp __f) : __f_(_VSTD::move(__f)) {}
109 explicit __func(_Fp __f, _Alloc __a) : __f_(_VSTD::move(__f), _VSTD::move(__a)) {}
110 virtual __base<_Rp()>* __clone() const;
111 virtual void __clone(__base<_Rp()>*) const;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000112 virtual void destroy();
113 virtual void destroy_deallocate();
Howard Hinnant99968442011-11-29 18:15:50 +0000114 virtual _Rp operator()();
Howard Hinnantd4444702010-08-11 17:04:31 +0000115#ifndef _LIBCPP_NO_RTTI
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000116 virtual const void* target(const type_info&) const;
117 virtual const std::type_info& target_type() const;
Howard Hinnant324bb032010-08-22 00:02:43 +0000118#endif // _LIBCPP_NO_RTTI
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000119};
120
Howard Hinnant99968442011-11-29 18:15:50 +0000121template<class _Fp, class _Alloc, class _Rp>
122__base<_Rp()>*
123__func<_Fp, _Alloc, _Rp()>::__clone() const
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000124{
Eric Fiselierb05f0592015-06-14 23:30:09 +0000125 typedef allocator_traits<_Alloc> __alloc_traits;
126 typedef typename __rebind_alloc_helper<__alloc_traits, __func>::type _Ap;
Howard Hinnant99968442011-11-29 18:15:50 +0000127 _Ap __a(__f_.second());
128 typedef __allocator_destructor<_Ap> _Dp;
129 unique_ptr<__func, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000130 ::new (__hold.get()) __func(__f_.first(), _Alloc(__a));
131 return __hold.release();
132}
133
Howard Hinnant99968442011-11-29 18:15:50 +0000134template<class _Fp, class _Alloc, class _Rp>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000135void
Howard Hinnant99968442011-11-29 18:15:50 +0000136__func<_Fp, _Alloc, _Rp()>::__clone(__base<_Rp()>* __p) const
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000137{
138 ::new (__p) __func(__f_.first(), __f_.second());
139}
140
Howard Hinnant99968442011-11-29 18:15:50 +0000141template<class _Fp, class _Alloc, class _Rp>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000142void
Howard Hinnant99968442011-11-29 18:15:50 +0000143__func<_Fp, _Alloc, _Rp()>::destroy()
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000144{
Howard Hinnant99968442011-11-29 18:15:50 +0000145 __f_.~__compressed_pair<_Fp, _Alloc>();
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000146}
147
Howard Hinnant99968442011-11-29 18:15:50 +0000148template<class _Fp, class _Alloc, class _Rp>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000149void
Howard Hinnant99968442011-11-29 18:15:50 +0000150__func<_Fp, _Alloc, _Rp()>::destroy_deallocate()
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000151{
Eric Fiselierb05f0592015-06-14 23:30:09 +0000152 typedef allocator_traits<_Alloc> __alloc_traits;
153 typedef typename __rebind_alloc_helper<__alloc_traits, __func>::type _Ap;
Howard Hinnant99968442011-11-29 18:15:50 +0000154 _Ap __a(__f_.second());
155 __f_.~__compressed_pair<_Fp, _Alloc>();
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000156 __a.deallocate(this, 1);
157}
158
Howard Hinnant99968442011-11-29 18:15:50 +0000159template<class _Fp, class _Alloc, class _Rp>
160_Rp
161__func<_Fp, _Alloc, _Rp()>::operator()()
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000162{
Eric Fiselierc3231d22015-02-10 16:48:45 +0000163 typedef __invoke_void_return_wrapper<_Rp> _Invoker;
164 return _Invoker::__call(__f_.first());
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000165}
166
Howard Hinnantd4444702010-08-11 17:04:31 +0000167#ifndef _LIBCPP_NO_RTTI
168
Howard Hinnant99968442011-11-29 18:15:50 +0000169template<class _Fp, class _Alloc, class _Rp>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000170const void*
Howard Hinnant99968442011-11-29 18:15:50 +0000171__func<_Fp, _Alloc, _Rp()>::target(const type_info& __ti) const
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000172{
Howard Hinnant99968442011-11-29 18:15:50 +0000173 if (__ti == typeid(_Fp))
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000174 return &__f_.first();
175 return (const void*)0;
176}
177
Howard Hinnant99968442011-11-29 18:15:50 +0000178template<class _Fp, class _Alloc, class _Rp>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000179const std::type_info&
Howard Hinnant99968442011-11-29 18:15:50 +0000180__func<_Fp, _Alloc, _Rp()>::target_type() const
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000181{
Howard Hinnant99968442011-11-29 18:15:50 +0000182 return typeid(_Fp);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000183}
184
Howard Hinnant324bb032010-08-22 00:02:43 +0000185#endif // _LIBCPP_NO_RTTI
Howard Hinnantd4444702010-08-11 17:04:31 +0000186
Howard Hinnant99968442011-11-29 18:15:50 +0000187template<class _Fp, class _Alloc, class _Rp, class _A0>
188class __func<_Fp, _Alloc, _Rp(_A0)>
189 : public __base<_Rp(_A0)>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000190{
Howard Hinnant99968442011-11-29 18:15:50 +0000191 __compressed_pair<_Fp, _Alloc> __f_;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000192public:
Howard Hinnant99968442011-11-29 18:15:50 +0000193 _LIBCPP_INLINE_VISIBILITY explicit __func(_Fp __f) : __f_(_VSTD::move(__f)) {}
194 _LIBCPP_INLINE_VISIBILITY explicit __func(_Fp __f, _Alloc __a)
Howard Hinnant0949eed2011-06-30 21:18:19 +0000195 : __f_(_VSTD::move(__f), _VSTD::move(__a)) {}
Howard Hinnant99968442011-11-29 18:15:50 +0000196 virtual __base<_Rp(_A0)>* __clone() const;
197 virtual void __clone(__base<_Rp(_A0)>*) const;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000198 virtual void destroy();
199 virtual void destroy_deallocate();
Howard Hinnant99968442011-11-29 18:15:50 +0000200 virtual _Rp operator()(_A0);
Howard Hinnantd4444702010-08-11 17:04:31 +0000201#ifndef _LIBCPP_NO_RTTI
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000202 virtual const void* target(const type_info&) const;
203 virtual const std::type_info& target_type() const;
Howard Hinnant324bb032010-08-22 00:02:43 +0000204#endif // _LIBCPP_NO_RTTI
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000205};
206
Howard Hinnant99968442011-11-29 18:15:50 +0000207template<class _Fp, class _Alloc, class _Rp, class _A0>
208__base<_Rp(_A0)>*
209__func<_Fp, _Alloc, _Rp(_A0)>::__clone() const
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000210{
Eric Fiselierb05f0592015-06-14 23:30:09 +0000211 typedef allocator_traits<_Alloc> __alloc_traits;
212 typedef typename __rebind_alloc_helper<__alloc_traits, __func>::type _Ap;
Howard Hinnant99968442011-11-29 18:15:50 +0000213 _Ap __a(__f_.second());
214 typedef __allocator_destructor<_Ap> _Dp;
215 unique_ptr<__func, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000216 ::new (__hold.get()) __func(__f_.first(), _Alloc(__a));
217 return __hold.release();
218}
219
Howard Hinnant99968442011-11-29 18:15:50 +0000220template<class _Fp, class _Alloc, class _Rp, class _A0>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000221void
Howard Hinnant99968442011-11-29 18:15:50 +0000222__func<_Fp, _Alloc, _Rp(_A0)>::__clone(__base<_Rp(_A0)>* __p) const
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000223{
224 ::new (__p) __func(__f_.first(), __f_.second());
225}
226
Howard Hinnant99968442011-11-29 18:15:50 +0000227template<class _Fp, class _Alloc, class _Rp, class _A0>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000228void
Howard Hinnant99968442011-11-29 18:15:50 +0000229__func<_Fp, _Alloc, _Rp(_A0)>::destroy()
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000230{
Howard Hinnant99968442011-11-29 18:15:50 +0000231 __f_.~__compressed_pair<_Fp, _Alloc>();
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000232}
233
Howard Hinnant99968442011-11-29 18:15:50 +0000234template<class _Fp, class _Alloc, class _Rp, class _A0>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000235void
Howard Hinnant99968442011-11-29 18:15:50 +0000236__func<_Fp, _Alloc, _Rp(_A0)>::destroy_deallocate()
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000237{
Eric Fiselierb05f0592015-06-14 23:30:09 +0000238 typedef allocator_traits<_Alloc> __alloc_traits;
239 typedef typename __rebind_alloc_helper<__alloc_traits, __func>::type _Ap;
Howard Hinnant99968442011-11-29 18:15:50 +0000240 _Ap __a(__f_.second());
241 __f_.~__compressed_pair<_Fp, _Alloc>();
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000242 __a.deallocate(this, 1);
243}
244
Howard Hinnant99968442011-11-29 18:15:50 +0000245template<class _Fp, class _Alloc, class _Rp, class _A0>
246_Rp
247__func<_Fp, _Alloc, _Rp(_A0)>::operator()(_A0 __a0)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000248{
Eric Fiselierc3231d22015-02-10 16:48:45 +0000249 typedef __invoke_void_return_wrapper<_Rp> _Invoker;
250 return _Invoker::__call(__f_.first(), __a0);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000251}
252
Howard Hinnantd4444702010-08-11 17:04:31 +0000253#ifndef _LIBCPP_NO_RTTI
254
Howard Hinnant99968442011-11-29 18:15:50 +0000255template<class _Fp, class _Alloc, class _Rp, class _A0>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000256const void*
Howard Hinnant99968442011-11-29 18:15:50 +0000257__func<_Fp, _Alloc, _Rp(_A0)>::target(const type_info& __ti) const
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000258{
Howard Hinnant99968442011-11-29 18:15:50 +0000259 if (__ti == typeid(_Fp))
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000260 return &__f_.first();
261 return (const void*)0;
262}
263
Howard Hinnant99968442011-11-29 18:15:50 +0000264template<class _Fp, class _Alloc, class _Rp, class _A0>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000265const std::type_info&
Howard Hinnant99968442011-11-29 18:15:50 +0000266__func<_Fp, _Alloc, _Rp(_A0)>::target_type() const
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000267{
Howard Hinnant99968442011-11-29 18:15:50 +0000268 return typeid(_Fp);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000269}
270
Howard Hinnant324bb032010-08-22 00:02:43 +0000271#endif // _LIBCPP_NO_RTTI
Howard Hinnantd4444702010-08-11 17:04:31 +0000272
Howard Hinnant99968442011-11-29 18:15:50 +0000273template<class _Fp, class _Alloc, class _Rp, class _A0, class _A1>
274class __func<_Fp, _Alloc, _Rp(_A0, _A1)>
275 : public __base<_Rp(_A0, _A1)>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000276{
Howard Hinnant99968442011-11-29 18:15:50 +0000277 __compressed_pair<_Fp, _Alloc> __f_;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000278public:
Howard Hinnant99968442011-11-29 18:15:50 +0000279 _LIBCPP_INLINE_VISIBILITY explicit __func(_Fp __f) : __f_(_VSTD::move(__f)) {}
280 _LIBCPP_INLINE_VISIBILITY explicit __func(_Fp __f, _Alloc __a)
Howard Hinnant0949eed2011-06-30 21:18:19 +0000281 : __f_(_VSTD::move(__f), _VSTD::move(__a)) {}
Howard Hinnant99968442011-11-29 18:15:50 +0000282 virtual __base<_Rp(_A0, _A1)>* __clone() const;
283 virtual void __clone(__base<_Rp(_A0, _A1)>*) const;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000284 virtual void destroy();
285 virtual void destroy_deallocate();
Howard Hinnant99968442011-11-29 18:15:50 +0000286 virtual _Rp operator()(_A0, _A1);
Howard Hinnantd4444702010-08-11 17:04:31 +0000287#ifndef _LIBCPP_NO_RTTI
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000288 virtual const void* target(const type_info&) const;
289 virtual const std::type_info& target_type() const;
Howard Hinnant324bb032010-08-22 00:02:43 +0000290#endif // _LIBCPP_NO_RTTI
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000291};
292
Howard Hinnant99968442011-11-29 18:15:50 +0000293template<class _Fp, class _Alloc, class _Rp, class _A0, class _A1>
294__base<_Rp(_A0, _A1)>*
295__func<_Fp, _Alloc, _Rp(_A0, _A1)>::__clone() const
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000296{
Eric Fiselierb05f0592015-06-14 23:30:09 +0000297 typedef allocator_traits<_Alloc> __alloc_traits;
298 typedef typename __rebind_alloc_helper<__alloc_traits, __func>::type _Ap;
Howard Hinnant99968442011-11-29 18:15:50 +0000299 _Ap __a(__f_.second());
300 typedef __allocator_destructor<_Ap> _Dp;
301 unique_ptr<__func, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000302 ::new (__hold.get()) __func(__f_.first(), _Alloc(__a));
303 return __hold.release();
304}
305
Howard Hinnant99968442011-11-29 18:15:50 +0000306template<class _Fp, class _Alloc, class _Rp, class _A0, class _A1>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000307void
Howard Hinnant99968442011-11-29 18:15:50 +0000308__func<_Fp, _Alloc, _Rp(_A0, _A1)>::__clone(__base<_Rp(_A0, _A1)>* __p) const
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000309{
310 ::new (__p) __func(__f_.first(), __f_.second());
311}
312
Howard Hinnant99968442011-11-29 18:15:50 +0000313template<class _Fp, class _Alloc, class _Rp, class _A0, class _A1>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000314void
Howard Hinnant99968442011-11-29 18:15:50 +0000315__func<_Fp, _Alloc, _Rp(_A0, _A1)>::destroy()
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000316{
Howard Hinnant99968442011-11-29 18:15:50 +0000317 __f_.~__compressed_pair<_Fp, _Alloc>();
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000318}
319
Howard Hinnant99968442011-11-29 18:15:50 +0000320template<class _Fp, class _Alloc, class _Rp, class _A0, class _A1>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000321void
Howard Hinnant99968442011-11-29 18:15:50 +0000322__func<_Fp, _Alloc, _Rp(_A0, _A1)>::destroy_deallocate()
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000323{
Eric Fiselierb05f0592015-06-14 23:30:09 +0000324 typedef allocator_traits<_Alloc> __alloc_traits;
325 typedef typename __rebind_alloc_helper<__alloc_traits, __func>::type _Ap;
Howard Hinnant99968442011-11-29 18:15:50 +0000326 _Ap __a(__f_.second());
327 __f_.~__compressed_pair<_Fp, _Alloc>();
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000328 __a.deallocate(this, 1);
329}
330
Howard Hinnant99968442011-11-29 18:15:50 +0000331template<class _Fp, class _Alloc, class _Rp, class _A0, class _A1>
332_Rp
333__func<_Fp, _Alloc, _Rp(_A0, _A1)>::operator()(_A0 __a0, _A1 __a1)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000334{
Eric Fiselierc3231d22015-02-10 16:48:45 +0000335 typedef __invoke_void_return_wrapper<_Rp> _Invoker;
336 return _Invoker::__call(__f_.first(), __a0, __a1);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000337}
338
Howard Hinnantd4444702010-08-11 17:04:31 +0000339#ifndef _LIBCPP_NO_RTTI
340
Howard Hinnant99968442011-11-29 18:15:50 +0000341template<class _Fp, class _Alloc, class _Rp, class _A0, class _A1>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000342const void*
Howard Hinnant99968442011-11-29 18:15:50 +0000343__func<_Fp, _Alloc, _Rp(_A0, _A1)>::target(const type_info& __ti) const
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000344{
Howard Hinnant99968442011-11-29 18:15:50 +0000345 if (__ti == typeid(_Fp))
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000346 return &__f_.first();
347 return (const void*)0;
348}
349
Howard Hinnant99968442011-11-29 18:15:50 +0000350template<class _Fp, class _Alloc, class _Rp, class _A0, class _A1>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000351const std::type_info&
Howard Hinnant99968442011-11-29 18:15:50 +0000352__func<_Fp, _Alloc, _Rp(_A0, _A1)>::target_type() const
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000353{
Howard Hinnant99968442011-11-29 18:15:50 +0000354 return typeid(_Fp);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000355}
356
Howard Hinnant324bb032010-08-22 00:02:43 +0000357#endif // _LIBCPP_NO_RTTI
Howard Hinnantd4444702010-08-11 17:04:31 +0000358
Howard Hinnant99968442011-11-29 18:15:50 +0000359template<class _Fp, class _Alloc, class _Rp, class _A0, class _A1, class _A2>
360class __func<_Fp, _Alloc, _Rp(_A0, _A1, _A2)>
361 : public __base<_Rp(_A0, _A1, _A2)>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000362{
Howard Hinnant99968442011-11-29 18:15:50 +0000363 __compressed_pair<_Fp, _Alloc> __f_;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000364public:
Howard Hinnant99968442011-11-29 18:15:50 +0000365 _LIBCPP_INLINE_VISIBILITY explicit __func(_Fp __f) : __f_(_VSTD::move(__f)) {}
366 _LIBCPP_INLINE_VISIBILITY explicit __func(_Fp __f, _Alloc __a)
Howard Hinnant0949eed2011-06-30 21:18:19 +0000367 : __f_(_VSTD::move(__f), _VSTD::move(__a)) {}
Howard Hinnant99968442011-11-29 18:15:50 +0000368 virtual __base<_Rp(_A0, _A1, _A2)>* __clone() const;
369 virtual void __clone(__base<_Rp(_A0, _A1, _A2)>*) const;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000370 virtual void destroy();
371 virtual void destroy_deallocate();
Howard Hinnant99968442011-11-29 18:15:50 +0000372 virtual _Rp operator()(_A0, _A1, _A2);
Howard Hinnantd4444702010-08-11 17:04:31 +0000373#ifndef _LIBCPP_NO_RTTI
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000374 virtual const void* target(const type_info&) const;
375 virtual const std::type_info& target_type() const;
Howard Hinnant324bb032010-08-22 00:02:43 +0000376#endif // _LIBCPP_NO_RTTI
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000377};
378
Howard Hinnant99968442011-11-29 18:15:50 +0000379template<class _Fp, class _Alloc, class _Rp, class _A0, class _A1, class _A2>
380__base<_Rp(_A0, _A1, _A2)>*
381__func<_Fp, _Alloc, _Rp(_A0, _A1, _A2)>::__clone() const
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000382{
Eric Fiselierb05f0592015-06-14 23:30:09 +0000383 typedef allocator_traits<_Alloc> __alloc_traits;
384 typedef typename __rebind_alloc_helper<__alloc_traits, __func>::type _Ap;
Howard Hinnant99968442011-11-29 18:15:50 +0000385 _Ap __a(__f_.second());
386 typedef __allocator_destructor<_Ap> _Dp;
387 unique_ptr<__func, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000388 ::new (__hold.get()) __func(__f_.first(), _Alloc(__a));
389 return __hold.release();
390}
391
Howard Hinnant99968442011-11-29 18:15:50 +0000392template<class _Fp, class _Alloc, class _Rp, class _A0, class _A1, class _A2>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000393void
Howard Hinnant99968442011-11-29 18:15:50 +0000394__func<_Fp, _Alloc, _Rp(_A0, _A1, _A2)>::__clone(__base<_Rp(_A0, _A1, _A2)>* __p) const
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000395{
396 ::new (__p) __func(__f_.first(), __f_.second());
397}
398
Howard Hinnant99968442011-11-29 18:15:50 +0000399template<class _Fp, class _Alloc, class _Rp, class _A0, class _A1, class _A2>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000400void
Howard Hinnant99968442011-11-29 18:15:50 +0000401__func<_Fp, _Alloc, _Rp(_A0, _A1, _A2)>::destroy()
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000402{
Howard Hinnant99968442011-11-29 18:15:50 +0000403 __f_.~__compressed_pair<_Fp, _Alloc>();
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000404}
405
Howard Hinnant99968442011-11-29 18:15:50 +0000406template<class _Fp, class _Alloc, class _Rp, class _A0, class _A1, class _A2>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000407void
Howard Hinnant99968442011-11-29 18:15:50 +0000408__func<_Fp, _Alloc, _Rp(_A0, _A1, _A2)>::destroy_deallocate()
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000409{
Eric Fiselierb05f0592015-06-14 23:30:09 +0000410 typedef allocator_traits<_Alloc> __alloc_traits;
411 typedef typename __rebind_alloc_helper<__alloc_traits, __func>::type _Ap;
Howard Hinnant99968442011-11-29 18:15:50 +0000412 _Ap __a(__f_.second());
413 __f_.~__compressed_pair<_Fp, _Alloc>();
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000414 __a.deallocate(this, 1);
415}
416
Howard Hinnant99968442011-11-29 18:15:50 +0000417template<class _Fp, class _Alloc, class _Rp, class _A0, class _A1, class _A2>
418_Rp
419__func<_Fp, _Alloc, _Rp(_A0, _A1, _A2)>::operator()(_A0 __a0, _A1 __a1, _A2 __a2)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000420{
Eric Fiselierc3231d22015-02-10 16:48:45 +0000421 typedef __invoke_void_return_wrapper<_Rp> _Invoker;
422 return _Invoker::__call(__f_.first(), __a0, __a1, __a2);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000423}
424
Howard Hinnantd4444702010-08-11 17:04:31 +0000425#ifndef _LIBCPP_NO_RTTI
426
Howard Hinnant99968442011-11-29 18:15:50 +0000427template<class _Fp, class _Alloc, class _Rp, class _A0, class _A1, class _A2>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000428const void*
Howard Hinnant99968442011-11-29 18:15:50 +0000429__func<_Fp, _Alloc, _Rp(_A0, _A1, _A2)>::target(const type_info& __ti) const
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000430{
Howard Hinnant99968442011-11-29 18:15:50 +0000431 if (__ti == typeid(_Fp))
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000432 return &__f_.first();
433 return (const void*)0;
434}
435
Howard Hinnant99968442011-11-29 18:15:50 +0000436template<class _Fp, class _Alloc, class _Rp, class _A0, class _A1, class _A2>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000437const std::type_info&
Howard Hinnant99968442011-11-29 18:15:50 +0000438__func<_Fp, _Alloc, _Rp(_A0, _A1, _A2)>::target_type() const
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000439{
Howard Hinnant99968442011-11-29 18:15:50 +0000440 return typeid(_Fp);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000441}
442
Howard Hinnant324bb032010-08-22 00:02:43 +0000443#endif // _LIBCPP_NO_RTTI
Howard Hinnantd4444702010-08-11 17:04:31 +0000444
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000445} // __function
446
Howard Hinnant99968442011-11-29 18:15:50 +0000447template<class _Rp>
Eric Fiselierc3589a82017-01-04 23:56:00 +0000448class _LIBCPP_TEMPLATE_VIS function<_Rp()>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000449{
Howard Hinnant99968442011-11-29 18:15:50 +0000450 typedef __function::__base<_Rp()> __base;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000451 aligned_storage<3*sizeof(void*)>::type __buf_;
452 __base* __f_;
453
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000454public:
Howard Hinnant99968442011-11-29 18:15:50 +0000455 typedef _Rp result_type;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000456
457 // 20.7.16.2.1, construct/copy/destroy:
Howard Hinnant99acc502010-09-21 17:32:39 +0000458 _LIBCPP_INLINE_VISIBILITY explicit function() : __f_(0) {}
459 _LIBCPP_INLINE_VISIBILITY function(nullptr_t) : __f_(0) {}
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000460 function(const function&);
Howard Hinnant99968442011-11-29 18:15:50 +0000461 template<class _Fp>
462 function(_Fp,
463 typename enable_if<!is_integral<_Fp>::value>::type* = 0);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000464
Howard Hinnant72552802010-08-20 19:36:46 +0000465 template<class _Alloc>
Howard Hinnant99acc502010-09-21 17:32:39 +0000466 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant72552802010-08-20 19:36:46 +0000467 function(allocator_arg_t, const _Alloc&) : __f_(0) {}
468 template<class _Alloc>
Howard Hinnant99acc502010-09-21 17:32:39 +0000469 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant72552802010-08-20 19:36:46 +0000470 function(allocator_arg_t, const _Alloc&, nullptr_t) : __f_(0) {}
471 template<class _Alloc>
472 function(allocator_arg_t, const _Alloc&, const function&);
Howard Hinnant99968442011-11-29 18:15:50 +0000473 template<class _Fp, class _Alloc>
474 function(allocator_arg_t, const _Alloc& __a, _Fp __f,
475 typename enable_if<!is_integral<_Fp>::value>::type* = 0);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000476
477 function& operator=(const function&);
478 function& operator=(nullptr_t);
Howard Hinnant99968442011-11-29 18:15:50 +0000479 template<class _Fp>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000480 typename enable_if
481 <
Howard Hinnant99968442011-11-29 18:15:50 +0000482 !is_integral<_Fp>::value,
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000483 function&
484 >::type
Howard Hinnant99968442011-11-29 18:15:50 +0000485 operator=(_Fp);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000486
487 ~function();
488
489 // 20.7.16.2.2, function modifiers:
490 void swap(function&);
Howard Hinnant99968442011-11-29 18:15:50 +0000491 template<class _Fp, class _Alloc>
Howard Hinnant99acc502010-09-21 17:32:39 +0000492 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99968442011-11-29 18:15:50 +0000493 void assign(_Fp __f, const _Alloc& __a)
Howard Hinnant72552802010-08-20 19:36:46 +0000494 {function(allocator_arg, __a, __f).swap(*this);}
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000495
496 // 20.7.16.2.3, function capacity:
Howard Hinnant99acc502010-09-21 17:32:39 +0000497 _LIBCPP_INLINE_VISIBILITY operator bool() const {return __f_;}
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000498
499private:
500 // deleted overloads close possible hole in the type system
501 template<class _R2>
Howard Hinnant99acc502010-09-21 17:32:39 +0000502 bool operator==(const function<_R2()>&) const;// = delete;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000503 template<class _R2>
Howard Hinnant99acc502010-09-21 17:32:39 +0000504 bool operator!=(const function<_R2()>&) const;// = delete;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000505public:
506 // 20.7.16.2.4, function invocation:
Howard Hinnant99968442011-11-29 18:15:50 +0000507 _Rp operator()() const;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000508
Howard Hinnantd4444702010-08-11 17:04:31 +0000509#ifndef _LIBCPP_NO_RTTI
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000510 // 20.7.16.2.5, function target access:
511 const std::type_info& target_type() const;
Howard Hinnant99968442011-11-29 18:15:50 +0000512 template <typename _Tp> _Tp* target();
513 template <typename _Tp> const _Tp* target() const;
Howard Hinnant324bb032010-08-22 00:02:43 +0000514#endif // _LIBCPP_NO_RTTI
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000515};
516
Howard Hinnant99968442011-11-29 18:15:50 +0000517template<class _Rp>
518function<_Rp()>::function(const function& __f)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000519{
520 if (__f.__f_ == 0)
521 __f_ = 0;
522 else if (__f.__f_ == (const __base*)&__f.__buf_)
523 {
524 __f_ = (__base*)&__buf_;
525 __f.__f_->__clone(__f_);
526 }
527 else
528 __f_ = __f.__f_->__clone();
529}
530
Howard Hinnant99968442011-11-29 18:15:50 +0000531template<class _Rp>
Howard Hinnant72552802010-08-20 19:36:46 +0000532template<class _Alloc>
Howard Hinnant99968442011-11-29 18:15:50 +0000533function<_Rp()>::function(allocator_arg_t, const _Alloc&, const function& __f)
Howard Hinnant72552802010-08-20 19:36:46 +0000534{
535 if (__f.__f_ == 0)
536 __f_ = 0;
537 else if (__f.__f_ == (const __base*)&__f.__buf_)
538 {
539 __f_ = (__base*)&__buf_;
540 __f.__f_->__clone(__f_);
541 }
542 else
543 __f_ = __f.__f_->__clone();
544}
545
Howard Hinnant99968442011-11-29 18:15:50 +0000546template<class _Rp>
547template <class _Fp>
548function<_Rp()>::function(_Fp __f,
549 typename enable_if<!is_integral<_Fp>::value>::type*)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000550 : __f_(0)
551{
Eric Fiselier8e030712015-08-18 19:41:51 +0000552 if (__function::__not_null(__f))
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000553 {
Howard Hinnant99968442011-11-29 18:15:50 +0000554 typedef __function::__func<_Fp, allocator<_Fp>, _Rp()> _FF;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000555 if (sizeof(_FF) <= sizeof(__buf_))
556 {
557 __f_ = (__base*)&__buf_;
558 ::new (__f_) _FF(__f);
559 }
560 else
561 {
Howard Hinnant99968442011-11-29 18:15:50 +0000562 typedef allocator<_FF> _Ap;
563 _Ap __a;
564 typedef __allocator_destructor<_Ap> _Dp;
565 unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
566 ::new (__hold.get()) _FF(__f, allocator<_Fp>(__a));
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000567 __f_ = __hold.release();
568 }
569 }
570}
571
Howard Hinnant99968442011-11-29 18:15:50 +0000572template<class _Rp>
573template <class _Fp, class _Alloc>
574function<_Rp()>::function(allocator_arg_t, const _Alloc& __a0, _Fp __f,
575 typename enable_if<!is_integral<_Fp>::value>::type*)
Howard Hinnant72552802010-08-20 19:36:46 +0000576 : __f_(0)
577{
578 typedef allocator_traits<_Alloc> __alloc_traits;
Eric Fiselier8e030712015-08-18 19:41:51 +0000579 if (__function::__not_null(__f))
Howard Hinnant72552802010-08-20 19:36:46 +0000580 {
Howard Hinnant99968442011-11-29 18:15:50 +0000581 typedef __function::__func<_Fp, _Alloc, _Rp()> _FF;
Howard Hinnant72552802010-08-20 19:36:46 +0000582 if (sizeof(_FF) <= sizeof(__buf_))
583 {
584 __f_ = (__base*)&__buf_;
Eric Fiselierb05f0592015-06-14 23:30:09 +0000585 ::new (__f_) _FF(__f, __a0);
Howard Hinnant72552802010-08-20 19:36:46 +0000586 }
587 else
588 {
Marshall Clow66302c62015-04-07 05:21:38 +0000589 typedef typename __rebind_alloc_helper<__alloc_traits, _FF>::type _Ap;
Howard Hinnant99968442011-11-29 18:15:50 +0000590 _Ap __a(__a0);
591 typedef __allocator_destructor<_Ap> _Dp;
592 unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
Howard Hinnant72552802010-08-20 19:36:46 +0000593 ::new (__hold.get()) _FF(__f, _Alloc(__a));
594 __f_ = __hold.release();
595 }
596 }
597}
598
Howard Hinnant99968442011-11-29 18:15:50 +0000599template<class _Rp>
600function<_Rp()>&
601function<_Rp()>::operator=(const function& __f)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000602{
603 function(__f).swap(*this);
604 return *this;
605}
606
Howard Hinnant99968442011-11-29 18:15:50 +0000607template<class _Rp>
608function<_Rp()>&
609function<_Rp()>::operator=(nullptr_t)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000610{
611 if (__f_ == (__base*)&__buf_)
612 __f_->destroy();
613 else if (__f_)
614 __f_->destroy_deallocate();
615 __f_ = 0;
Eric Fiselierfa97c2e2015-06-02 01:31:33 +0000616 return *this;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000617}
618
Howard Hinnant99968442011-11-29 18:15:50 +0000619template<class _Rp>
620template <class _Fp>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000621typename enable_if
622<
Howard Hinnant99968442011-11-29 18:15:50 +0000623 !is_integral<_Fp>::value,
624 function<_Rp()>&
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000625>::type
Howard Hinnant99968442011-11-29 18:15:50 +0000626function<_Rp()>::operator=(_Fp __f)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000627{
Howard Hinnant0949eed2011-06-30 21:18:19 +0000628 function(_VSTD::move(__f)).swap(*this);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000629 return *this;
630}
631
Howard Hinnant99968442011-11-29 18:15:50 +0000632template<class _Rp>
633function<_Rp()>::~function()
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000634{
635 if (__f_ == (__base*)&__buf_)
636 __f_->destroy();
637 else if (__f_)
638 __f_->destroy_deallocate();
639}
640
Howard Hinnant99968442011-11-29 18:15:50 +0000641template<class _Rp>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000642void
Howard Hinnant99968442011-11-29 18:15:50 +0000643function<_Rp()>::swap(function& __f)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000644{
Eric Fiselier152e5e62016-12-29 20:03:55 +0000645 if (_VSTD::addressof(__f) == this)
646 return;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000647 if (__f_ == (__base*)&__buf_ && __f.__f_ == (__base*)&__f.__buf_)
648 {
649 typename aligned_storage<sizeof(__buf_)>::type __tempbuf;
650 __base* __t = (__base*)&__tempbuf;
651 __f_->__clone(__t);
652 __f_->destroy();
653 __f_ = 0;
654 __f.__f_->__clone((__base*)&__buf_);
655 __f.__f_->destroy();
656 __f.__f_ = 0;
657 __f_ = (__base*)&__buf_;
658 __t->__clone((__base*)&__f.__buf_);
659 __t->destroy();
660 __f.__f_ = (__base*)&__f.__buf_;
661 }
662 else if (__f_ == (__base*)&__buf_)
663 {
664 __f_->__clone((__base*)&__f.__buf_);
665 __f_->destroy();
666 __f_ = __f.__f_;
667 __f.__f_ = (__base*)&__f.__buf_;
668 }
669 else if (__f.__f_ == (__base*)&__f.__buf_)
670 {
671 __f.__f_->__clone((__base*)&__buf_);
672 __f.__f_->destroy();
673 __f.__f_ = __f_;
674 __f_ = (__base*)&__buf_;
675 }
676 else
Howard Hinnant0949eed2011-06-30 21:18:19 +0000677 _VSTD::swap(__f_, __f.__f_);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000678}
679
Howard Hinnant99968442011-11-29 18:15:50 +0000680template<class _Rp>
681_Rp
682function<_Rp()>::operator()() const
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000683{
684 if (__f_ == 0)
Marshall Clow14c09a22016-08-25 15:09:01 +0000685 __throw_bad_function_call();
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000686 return (*__f_)();
687}
688
Howard Hinnantd4444702010-08-11 17:04:31 +0000689#ifndef _LIBCPP_NO_RTTI
690
Howard Hinnant99968442011-11-29 18:15:50 +0000691template<class _Rp>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000692const std::type_info&
Howard Hinnant99968442011-11-29 18:15:50 +0000693function<_Rp()>::target_type() const
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000694{
695 if (__f_ == 0)
696 return typeid(void);
697 return __f_->target_type();
698}
699
Howard Hinnant99968442011-11-29 18:15:50 +0000700template<class _Rp>
701template <typename _Tp>
702_Tp*
703function<_Rp()>::target()
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000704{
705 if (__f_ == 0)
Howard Hinnant99968442011-11-29 18:15:50 +0000706 return (_Tp*)0;
Marshall Clowff5f9b22017-06-14 20:00:36 +0000707 return (_Tp*) const_cast<void *>(__f_->target(typeid(_Tp)));
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000708}
709
Howard Hinnant99968442011-11-29 18:15:50 +0000710template<class _Rp>
711template <typename _Tp>
712const _Tp*
713function<_Rp()>::target() const
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000714{
715 if (__f_ == 0)
Howard Hinnant99968442011-11-29 18:15:50 +0000716 return (const _Tp*)0;
717 return (const _Tp*)__f_->target(typeid(_Tp));
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000718}
719
Howard Hinnant324bb032010-08-22 00:02:43 +0000720#endif // _LIBCPP_NO_RTTI
Howard Hinnantd4444702010-08-11 17:04:31 +0000721
Howard Hinnant99968442011-11-29 18:15:50 +0000722template<class _Rp, class _A0>
Eric Fiselierc3589a82017-01-04 23:56:00 +0000723class _LIBCPP_TEMPLATE_VIS function<_Rp(_A0)>
Howard Hinnant99968442011-11-29 18:15:50 +0000724 : public unary_function<_A0, _Rp>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000725{
Howard Hinnant99968442011-11-29 18:15:50 +0000726 typedef __function::__base<_Rp(_A0)> __base;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000727 aligned_storage<3*sizeof(void*)>::type __buf_;
728 __base* __f_;
729
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000730public:
Howard Hinnant99968442011-11-29 18:15:50 +0000731 typedef _Rp result_type;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000732
733 // 20.7.16.2.1, construct/copy/destroy:
Howard Hinnant99acc502010-09-21 17:32:39 +0000734 _LIBCPP_INLINE_VISIBILITY explicit function() : __f_(0) {}
735 _LIBCPP_INLINE_VISIBILITY function(nullptr_t) : __f_(0) {}
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000736 function(const function&);
Howard Hinnant99968442011-11-29 18:15:50 +0000737 template<class _Fp>
738 function(_Fp,
739 typename enable_if<!is_integral<_Fp>::value>::type* = 0);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000740
Howard Hinnant72552802010-08-20 19:36:46 +0000741 template<class _Alloc>
Howard Hinnant99acc502010-09-21 17:32:39 +0000742 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant72552802010-08-20 19:36:46 +0000743 function(allocator_arg_t, const _Alloc&) : __f_(0) {}
744 template<class _Alloc>
Howard Hinnant99acc502010-09-21 17:32:39 +0000745 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant72552802010-08-20 19:36:46 +0000746 function(allocator_arg_t, const _Alloc&, nullptr_t) : __f_(0) {}
747 template<class _Alloc>
748 function(allocator_arg_t, const _Alloc&, const function&);
Howard Hinnant99968442011-11-29 18:15:50 +0000749 template<class _Fp, class _Alloc>
750 function(allocator_arg_t, const _Alloc& __a, _Fp __f,
751 typename enable_if<!is_integral<_Fp>::value>::type* = 0);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000752
753 function& operator=(const function&);
754 function& operator=(nullptr_t);
Howard Hinnant99968442011-11-29 18:15:50 +0000755 template<class _Fp>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000756 typename enable_if
757 <
Howard Hinnant99968442011-11-29 18:15:50 +0000758 !is_integral<_Fp>::value,
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000759 function&
760 >::type
Howard Hinnant99968442011-11-29 18:15:50 +0000761 operator=(_Fp);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000762
763 ~function();
764
765 // 20.7.16.2.2, function modifiers:
766 void swap(function&);
Howard Hinnant99968442011-11-29 18:15:50 +0000767 template<class _Fp, class _Alloc>
Howard Hinnant99acc502010-09-21 17:32:39 +0000768 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99968442011-11-29 18:15:50 +0000769 void assign(_Fp __f, const _Alloc& __a)
Howard Hinnant72552802010-08-20 19:36:46 +0000770 {function(allocator_arg, __a, __f).swap(*this);}
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000771
772 // 20.7.16.2.3, function capacity:
Howard Hinnant99acc502010-09-21 17:32:39 +0000773 _LIBCPP_INLINE_VISIBILITY operator bool() const {return __f_;}
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000774
775private:
776 // deleted overloads close possible hole in the type system
777 template<class _R2, class _B0>
Howard Hinnant99acc502010-09-21 17:32:39 +0000778 bool operator==(const function<_R2(_B0)>&) const;// = delete;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000779 template<class _R2, class _B0>
Howard Hinnant99acc502010-09-21 17:32:39 +0000780 bool operator!=(const function<_R2(_B0)>&) const;// = delete;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000781public:
782 // 20.7.16.2.4, function invocation:
Howard Hinnant99968442011-11-29 18:15:50 +0000783 _Rp operator()(_A0) const;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000784
Howard Hinnantd4444702010-08-11 17:04:31 +0000785#ifndef _LIBCPP_NO_RTTI
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000786 // 20.7.16.2.5, function target access:
787 const std::type_info& target_type() const;
Howard Hinnant99968442011-11-29 18:15:50 +0000788 template <typename _Tp> _Tp* target();
789 template <typename _Tp> const _Tp* target() const;
Howard Hinnant324bb032010-08-22 00:02:43 +0000790#endif // _LIBCPP_NO_RTTI
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000791};
792
Howard Hinnant99968442011-11-29 18:15:50 +0000793template<class _Rp, class _A0>
794function<_Rp(_A0)>::function(const function& __f)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000795{
796 if (__f.__f_ == 0)
797 __f_ = 0;
798 else if (__f.__f_ == (const __base*)&__f.__buf_)
799 {
800 __f_ = (__base*)&__buf_;
801 __f.__f_->__clone(__f_);
802 }
803 else
804 __f_ = __f.__f_->__clone();
805}
806
Howard Hinnant99968442011-11-29 18:15:50 +0000807template<class _Rp, class _A0>
Howard Hinnant72552802010-08-20 19:36:46 +0000808template<class _Alloc>
Howard Hinnant99968442011-11-29 18:15:50 +0000809function<_Rp(_A0)>::function(allocator_arg_t, const _Alloc&, const function& __f)
Howard Hinnant72552802010-08-20 19:36:46 +0000810{
811 if (__f.__f_ == 0)
812 __f_ = 0;
813 else if (__f.__f_ == (const __base*)&__f.__buf_)
814 {
815 __f_ = (__base*)&__buf_;
816 __f.__f_->__clone(__f_);
817 }
818 else
819 __f_ = __f.__f_->__clone();
820}
821
Howard Hinnant99968442011-11-29 18:15:50 +0000822template<class _Rp, class _A0>
823template <class _Fp>
824function<_Rp(_A0)>::function(_Fp __f,
825 typename enable_if<!is_integral<_Fp>::value>::type*)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000826 : __f_(0)
827{
Eric Fiselier8e030712015-08-18 19:41:51 +0000828 if (__function::__not_null(__f))
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000829 {
Howard Hinnant99968442011-11-29 18:15:50 +0000830 typedef __function::__func<_Fp, allocator<_Fp>, _Rp(_A0)> _FF;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000831 if (sizeof(_FF) <= sizeof(__buf_))
832 {
833 __f_ = (__base*)&__buf_;
834 ::new (__f_) _FF(__f);
835 }
836 else
837 {
Howard Hinnant99968442011-11-29 18:15:50 +0000838 typedef allocator<_FF> _Ap;
839 _Ap __a;
840 typedef __allocator_destructor<_Ap> _Dp;
841 unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
842 ::new (__hold.get()) _FF(__f, allocator<_Fp>(__a));
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000843 __f_ = __hold.release();
844 }
845 }
846}
847
Howard Hinnant99968442011-11-29 18:15:50 +0000848template<class _Rp, class _A0>
849template <class _Fp, class _Alloc>
850function<_Rp(_A0)>::function(allocator_arg_t, const _Alloc& __a0, _Fp __f,
851 typename enable_if<!is_integral<_Fp>::value>::type*)
Howard Hinnant72552802010-08-20 19:36:46 +0000852 : __f_(0)
853{
854 typedef allocator_traits<_Alloc> __alloc_traits;
Eric Fiselier8e030712015-08-18 19:41:51 +0000855 if (__function::__not_null(__f))
Howard Hinnant72552802010-08-20 19:36:46 +0000856 {
Howard Hinnant99968442011-11-29 18:15:50 +0000857 typedef __function::__func<_Fp, _Alloc, _Rp(_A0)> _FF;
Howard Hinnant72552802010-08-20 19:36:46 +0000858 if (sizeof(_FF) <= sizeof(__buf_))
859 {
860 __f_ = (__base*)&__buf_;
Eric Fiselierb05f0592015-06-14 23:30:09 +0000861 ::new (__f_) _FF(__f, __a0);
Howard Hinnant72552802010-08-20 19:36:46 +0000862 }
863 else
864 {
Marshall Clow66302c62015-04-07 05:21:38 +0000865 typedef typename __rebind_alloc_helper<__alloc_traits, _FF>::type _Ap;
Howard Hinnant99968442011-11-29 18:15:50 +0000866 _Ap __a(__a0);
867 typedef __allocator_destructor<_Ap> _Dp;
868 unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
Howard Hinnant72552802010-08-20 19:36:46 +0000869 ::new (__hold.get()) _FF(__f, _Alloc(__a));
870 __f_ = __hold.release();
871 }
872 }
873}
874
Howard Hinnant99968442011-11-29 18:15:50 +0000875template<class _Rp, class _A0>
876function<_Rp(_A0)>&
877function<_Rp(_A0)>::operator=(const function& __f)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000878{
879 function(__f).swap(*this);
880 return *this;
881}
882
Howard Hinnant99968442011-11-29 18:15:50 +0000883template<class _Rp, class _A0>
884function<_Rp(_A0)>&
885function<_Rp(_A0)>::operator=(nullptr_t)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000886{
887 if (__f_ == (__base*)&__buf_)
888 __f_->destroy();
889 else if (__f_)
890 __f_->destroy_deallocate();
891 __f_ = 0;
Eric Fiselierfa97c2e2015-06-02 01:31:33 +0000892 return *this;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000893}
894
Howard Hinnant99968442011-11-29 18:15:50 +0000895template<class _Rp, class _A0>
896template <class _Fp>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000897typename enable_if
898<
Howard Hinnant99968442011-11-29 18:15:50 +0000899 !is_integral<_Fp>::value,
900 function<_Rp(_A0)>&
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000901>::type
Howard Hinnant99968442011-11-29 18:15:50 +0000902function<_Rp(_A0)>::operator=(_Fp __f)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000903{
Howard Hinnant0949eed2011-06-30 21:18:19 +0000904 function(_VSTD::move(__f)).swap(*this);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000905 return *this;
906}
907
Howard Hinnant99968442011-11-29 18:15:50 +0000908template<class _Rp, class _A0>
909function<_Rp(_A0)>::~function()
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000910{
911 if (__f_ == (__base*)&__buf_)
912 __f_->destroy();
913 else if (__f_)
914 __f_->destroy_deallocate();
915}
916
Howard Hinnant99968442011-11-29 18:15:50 +0000917template<class _Rp, class _A0>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000918void
Howard Hinnant99968442011-11-29 18:15:50 +0000919function<_Rp(_A0)>::swap(function& __f)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000920{
Eric Fiselier152e5e62016-12-29 20:03:55 +0000921 if (_VSTD::addressof(__f) == this)
922 return;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000923 if (__f_ == (__base*)&__buf_ && __f.__f_ == (__base*)&__f.__buf_)
924 {
925 typename aligned_storage<sizeof(__buf_)>::type __tempbuf;
926 __base* __t = (__base*)&__tempbuf;
927 __f_->__clone(__t);
928 __f_->destroy();
929 __f_ = 0;
930 __f.__f_->__clone((__base*)&__buf_);
931 __f.__f_->destroy();
932 __f.__f_ = 0;
933 __f_ = (__base*)&__buf_;
934 __t->__clone((__base*)&__f.__buf_);
935 __t->destroy();
936 __f.__f_ = (__base*)&__f.__buf_;
937 }
938 else if (__f_ == (__base*)&__buf_)
939 {
940 __f_->__clone((__base*)&__f.__buf_);
941 __f_->destroy();
942 __f_ = __f.__f_;
943 __f.__f_ = (__base*)&__f.__buf_;
944 }
945 else if (__f.__f_ == (__base*)&__f.__buf_)
946 {
947 __f.__f_->__clone((__base*)&__buf_);
948 __f.__f_->destroy();
949 __f.__f_ = __f_;
950 __f_ = (__base*)&__buf_;
951 }
952 else
Howard Hinnant0949eed2011-06-30 21:18:19 +0000953 _VSTD::swap(__f_, __f.__f_);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000954}
955
Howard Hinnant99968442011-11-29 18:15:50 +0000956template<class _Rp, class _A0>
957_Rp
958function<_Rp(_A0)>::operator()(_A0 __a0) const
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000959{
960 if (__f_ == 0)
Marshall Clow14c09a22016-08-25 15:09:01 +0000961 __throw_bad_function_call();
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000962 return (*__f_)(__a0);
963}
964
Howard Hinnantd4444702010-08-11 17:04:31 +0000965#ifndef _LIBCPP_NO_RTTI
966
Howard Hinnant99968442011-11-29 18:15:50 +0000967template<class _Rp, class _A0>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000968const std::type_info&
Howard Hinnant99968442011-11-29 18:15:50 +0000969function<_Rp(_A0)>::target_type() const
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000970{
971 if (__f_ == 0)
972 return typeid(void);
973 return __f_->target_type();
974}
975
Howard Hinnant99968442011-11-29 18:15:50 +0000976template<class _Rp, class _A0>
977template <typename _Tp>
978_Tp*
979function<_Rp(_A0)>::target()
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000980{
981 if (__f_ == 0)
Howard Hinnant99968442011-11-29 18:15:50 +0000982 return (_Tp*)0;
Marshall Clowff5f9b22017-06-14 20:00:36 +0000983 return (_Tp*) const_cast<void *>(__f_->target(typeid(_Tp)));
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000984}
985
Howard Hinnant99968442011-11-29 18:15:50 +0000986template<class _Rp, class _A0>
987template <typename _Tp>
988const _Tp*
989function<_Rp(_A0)>::target() const
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000990{
991 if (__f_ == 0)
Howard Hinnant99968442011-11-29 18:15:50 +0000992 return (const _Tp*)0;
993 return (const _Tp*)__f_->target(typeid(_Tp));
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000994}
995
Howard Hinnant324bb032010-08-22 00:02:43 +0000996#endif // _LIBCPP_NO_RTTI
Howard Hinnantd4444702010-08-11 17:04:31 +0000997
Howard Hinnant99968442011-11-29 18:15:50 +0000998template<class _Rp, class _A0, class _A1>
Eric Fiselierc3589a82017-01-04 23:56:00 +0000999class _LIBCPP_TEMPLATE_VIS function<_Rp(_A0, _A1)>
Howard Hinnant99968442011-11-29 18:15:50 +00001000 : public binary_function<_A0, _A1, _Rp>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001001{
Howard Hinnant99968442011-11-29 18:15:50 +00001002 typedef __function::__base<_Rp(_A0, _A1)> __base;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001003 aligned_storage<3*sizeof(void*)>::type __buf_;
1004 __base* __f_;
1005
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001006public:
Howard Hinnant99968442011-11-29 18:15:50 +00001007 typedef _Rp result_type;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001008
1009 // 20.7.16.2.1, construct/copy/destroy:
Howard Hinnant99acc502010-09-21 17:32:39 +00001010 _LIBCPP_INLINE_VISIBILITY explicit function() : __f_(0) {}
1011 _LIBCPP_INLINE_VISIBILITY function(nullptr_t) : __f_(0) {}
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001012 function(const function&);
Howard Hinnant99968442011-11-29 18:15:50 +00001013 template<class _Fp>
1014 function(_Fp,
1015 typename enable_if<!is_integral<_Fp>::value>::type* = 0);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001016
Howard Hinnant72552802010-08-20 19:36:46 +00001017 template<class _Alloc>
Howard Hinnant99acc502010-09-21 17:32:39 +00001018 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant72552802010-08-20 19:36:46 +00001019 function(allocator_arg_t, const _Alloc&) : __f_(0) {}
1020 template<class _Alloc>
Howard Hinnant99acc502010-09-21 17:32:39 +00001021 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant72552802010-08-20 19:36:46 +00001022 function(allocator_arg_t, const _Alloc&, nullptr_t) : __f_(0) {}
1023 template<class _Alloc>
1024 function(allocator_arg_t, const _Alloc&, const function&);
Howard Hinnant99968442011-11-29 18:15:50 +00001025 template<class _Fp, class _Alloc>
1026 function(allocator_arg_t, const _Alloc& __a, _Fp __f,
1027 typename enable_if<!is_integral<_Fp>::value>::type* = 0);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001028
1029 function& operator=(const function&);
1030 function& operator=(nullptr_t);
Howard Hinnant99968442011-11-29 18:15:50 +00001031 template<class _Fp>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001032 typename enable_if
1033 <
Howard Hinnant99968442011-11-29 18:15:50 +00001034 !is_integral<_Fp>::value,
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001035 function&
1036 >::type
Howard Hinnant99968442011-11-29 18:15:50 +00001037 operator=(_Fp);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001038
1039 ~function();
1040
1041 // 20.7.16.2.2, function modifiers:
1042 void swap(function&);
Howard Hinnant99968442011-11-29 18:15:50 +00001043 template<class _Fp, class _Alloc>
Howard Hinnant99acc502010-09-21 17:32:39 +00001044 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99968442011-11-29 18:15:50 +00001045 void assign(_Fp __f, const _Alloc& __a)
Howard Hinnant72552802010-08-20 19:36:46 +00001046 {function(allocator_arg, __a, __f).swap(*this);}
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001047
1048 // 20.7.16.2.3, function capacity:
1049 operator bool() const {return __f_;}
1050
1051private:
1052 // deleted overloads close possible hole in the type system
1053 template<class _R2, class _B0, class _B1>
Howard Hinnant99acc502010-09-21 17:32:39 +00001054 bool operator==(const function<_R2(_B0, _B1)>&) const;// = delete;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001055 template<class _R2, class _B0, class _B1>
Howard Hinnant99acc502010-09-21 17:32:39 +00001056 bool operator!=(const function<_R2(_B0, _B1)>&) const;// = delete;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001057public:
1058 // 20.7.16.2.4, function invocation:
Howard Hinnant99968442011-11-29 18:15:50 +00001059 _Rp operator()(_A0, _A1) const;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001060
Howard Hinnantd4444702010-08-11 17:04:31 +00001061#ifndef _LIBCPP_NO_RTTI
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001062 // 20.7.16.2.5, function target access:
1063 const std::type_info& target_type() const;
Howard Hinnant99968442011-11-29 18:15:50 +00001064 template <typename _Tp> _Tp* target();
1065 template <typename _Tp> const _Tp* target() const;
Howard Hinnant324bb032010-08-22 00:02:43 +00001066#endif // _LIBCPP_NO_RTTI
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001067};
1068
Howard Hinnant99968442011-11-29 18:15:50 +00001069template<class _Rp, class _A0, class _A1>
1070function<_Rp(_A0, _A1)>::function(const function& __f)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001071{
1072 if (__f.__f_ == 0)
1073 __f_ = 0;
1074 else if (__f.__f_ == (const __base*)&__f.__buf_)
1075 {
1076 __f_ = (__base*)&__buf_;
1077 __f.__f_->__clone(__f_);
1078 }
1079 else
1080 __f_ = __f.__f_->__clone();
1081}
1082
Howard Hinnant99968442011-11-29 18:15:50 +00001083template<class _Rp, class _A0, class _A1>
Howard Hinnant72552802010-08-20 19:36:46 +00001084template<class _Alloc>
Howard Hinnant99968442011-11-29 18:15:50 +00001085function<_Rp(_A0, _A1)>::function(allocator_arg_t, const _Alloc&, const function& __f)
Howard Hinnant72552802010-08-20 19:36:46 +00001086{
1087 if (__f.__f_ == 0)
1088 __f_ = 0;
1089 else if (__f.__f_ == (const __base*)&__f.__buf_)
1090 {
1091 __f_ = (__base*)&__buf_;
1092 __f.__f_->__clone(__f_);
1093 }
1094 else
1095 __f_ = __f.__f_->__clone();
1096}
1097
Howard Hinnant99968442011-11-29 18:15:50 +00001098template<class _Rp, class _A0, class _A1>
1099template <class _Fp>
1100function<_Rp(_A0, _A1)>::function(_Fp __f,
1101 typename enable_if<!is_integral<_Fp>::value>::type*)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001102 : __f_(0)
1103{
Eric Fiselier8e030712015-08-18 19:41:51 +00001104 if (__function::__not_null(__f))
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001105 {
Howard Hinnant99968442011-11-29 18:15:50 +00001106 typedef __function::__func<_Fp, allocator<_Fp>, _Rp(_A0, _A1)> _FF;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001107 if (sizeof(_FF) <= sizeof(__buf_))
1108 {
1109 __f_ = (__base*)&__buf_;
1110 ::new (__f_) _FF(__f);
1111 }
1112 else
1113 {
Howard Hinnant99968442011-11-29 18:15:50 +00001114 typedef allocator<_FF> _Ap;
1115 _Ap __a;
1116 typedef __allocator_destructor<_Ap> _Dp;
1117 unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
1118 ::new (__hold.get()) _FF(__f, allocator<_Fp>(__a));
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001119 __f_ = __hold.release();
1120 }
1121 }
1122}
1123
Howard Hinnant99968442011-11-29 18:15:50 +00001124template<class _Rp, class _A0, class _A1>
1125template <class _Fp, class _Alloc>
1126function<_Rp(_A0, _A1)>::function(allocator_arg_t, const _Alloc& __a0, _Fp __f,
1127 typename enable_if<!is_integral<_Fp>::value>::type*)
Howard Hinnant72552802010-08-20 19:36:46 +00001128 : __f_(0)
1129{
1130 typedef allocator_traits<_Alloc> __alloc_traits;
Eric Fiselier8e030712015-08-18 19:41:51 +00001131 if (__function::__not_null(__f))
Howard Hinnant72552802010-08-20 19:36:46 +00001132 {
Howard Hinnant99968442011-11-29 18:15:50 +00001133 typedef __function::__func<_Fp, _Alloc, _Rp(_A0, _A1)> _FF;
Howard Hinnant72552802010-08-20 19:36:46 +00001134 if (sizeof(_FF) <= sizeof(__buf_))
1135 {
1136 __f_ = (__base*)&__buf_;
Eric Fiselierb05f0592015-06-14 23:30:09 +00001137 ::new (__f_) _FF(__f, __a0);
Howard Hinnant72552802010-08-20 19:36:46 +00001138 }
1139 else
1140 {
Marshall Clow66302c62015-04-07 05:21:38 +00001141 typedef typename __rebind_alloc_helper<__alloc_traits, _FF>::type _Ap;
Howard Hinnant99968442011-11-29 18:15:50 +00001142 _Ap __a(__a0);
1143 typedef __allocator_destructor<_Ap> _Dp;
1144 unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
Howard Hinnant72552802010-08-20 19:36:46 +00001145 ::new (__hold.get()) _FF(__f, _Alloc(__a));
1146 __f_ = __hold.release();
1147 }
1148 }
1149}
1150
Howard Hinnant99968442011-11-29 18:15:50 +00001151template<class _Rp, class _A0, class _A1>
1152function<_Rp(_A0, _A1)>&
1153function<_Rp(_A0, _A1)>::operator=(const function& __f)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001154{
1155 function(__f).swap(*this);
1156 return *this;
1157}
1158
Howard Hinnant99968442011-11-29 18:15:50 +00001159template<class _Rp, class _A0, class _A1>
1160function<_Rp(_A0, _A1)>&
1161function<_Rp(_A0, _A1)>::operator=(nullptr_t)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001162{
1163 if (__f_ == (__base*)&__buf_)
1164 __f_->destroy();
1165 else if (__f_)
1166 __f_->destroy_deallocate();
1167 __f_ = 0;
Eric Fiselierfa97c2e2015-06-02 01:31:33 +00001168 return *this;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001169}
1170
Howard Hinnant99968442011-11-29 18:15:50 +00001171template<class _Rp, class _A0, class _A1>
1172template <class _Fp>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001173typename enable_if
1174<
Howard Hinnant99968442011-11-29 18:15:50 +00001175 !is_integral<_Fp>::value,
1176 function<_Rp(_A0, _A1)>&
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001177>::type
Howard Hinnant99968442011-11-29 18:15:50 +00001178function<_Rp(_A0, _A1)>::operator=(_Fp __f)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001179{
Howard Hinnant0949eed2011-06-30 21:18:19 +00001180 function(_VSTD::move(__f)).swap(*this);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001181 return *this;
1182}
1183
Howard Hinnant99968442011-11-29 18:15:50 +00001184template<class _Rp, class _A0, class _A1>
1185function<_Rp(_A0, _A1)>::~function()
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001186{
1187 if (__f_ == (__base*)&__buf_)
1188 __f_->destroy();
1189 else if (__f_)
1190 __f_->destroy_deallocate();
1191}
1192
Howard Hinnant99968442011-11-29 18:15:50 +00001193template<class _Rp, class _A0, class _A1>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001194void
Howard Hinnant99968442011-11-29 18:15:50 +00001195function<_Rp(_A0, _A1)>::swap(function& __f)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001196{
Eric Fiselier152e5e62016-12-29 20:03:55 +00001197 if (_VSTD::addressof(__f) == this)
1198 return;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001199 if (__f_ == (__base*)&__buf_ && __f.__f_ == (__base*)&__f.__buf_)
1200 {
1201 typename aligned_storage<sizeof(__buf_)>::type __tempbuf;
1202 __base* __t = (__base*)&__tempbuf;
1203 __f_->__clone(__t);
1204 __f_->destroy();
1205 __f_ = 0;
1206 __f.__f_->__clone((__base*)&__buf_);
1207 __f.__f_->destroy();
1208 __f.__f_ = 0;
1209 __f_ = (__base*)&__buf_;
1210 __t->__clone((__base*)&__f.__buf_);
1211 __t->destroy();
1212 __f.__f_ = (__base*)&__f.__buf_;
1213 }
1214 else if (__f_ == (__base*)&__buf_)
1215 {
1216 __f_->__clone((__base*)&__f.__buf_);
1217 __f_->destroy();
1218 __f_ = __f.__f_;
1219 __f.__f_ = (__base*)&__f.__buf_;
1220 }
1221 else if (__f.__f_ == (__base*)&__f.__buf_)
1222 {
1223 __f.__f_->__clone((__base*)&__buf_);
1224 __f.__f_->destroy();
1225 __f.__f_ = __f_;
1226 __f_ = (__base*)&__buf_;
1227 }
1228 else
Howard Hinnant0949eed2011-06-30 21:18:19 +00001229 _VSTD::swap(__f_, __f.__f_);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001230}
1231
Howard Hinnant99968442011-11-29 18:15:50 +00001232template<class _Rp, class _A0, class _A1>
1233_Rp
1234function<_Rp(_A0, _A1)>::operator()(_A0 __a0, _A1 __a1) const
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001235{
1236 if (__f_ == 0)
Marshall Clow14c09a22016-08-25 15:09:01 +00001237 __throw_bad_function_call();
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001238 return (*__f_)(__a0, __a1);
1239}
1240
Howard Hinnantd4444702010-08-11 17:04:31 +00001241#ifndef _LIBCPP_NO_RTTI
1242
Howard Hinnant99968442011-11-29 18:15:50 +00001243template<class _Rp, class _A0, class _A1>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001244const std::type_info&
Howard Hinnant99968442011-11-29 18:15:50 +00001245function<_Rp(_A0, _A1)>::target_type() const
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001246{
1247 if (__f_ == 0)
1248 return typeid(void);
1249 return __f_->target_type();
1250}
1251
Howard Hinnant99968442011-11-29 18:15:50 +00001252template<class _Rp, class _A0, class _A1>
1253template <typename _Tp>
1254_Tp*
1255function<_Rp(_A0, _A1)>::target()
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001256{
1257 if (__f_ == 0)
Howard Hinnant99968442011-11-29 18:15:50 +00001258 return (_Tp*)0;
Marshall Clowff5f9b22017-06-14 20:00:36 +00001259 return (_Tp*) const_cast<void *>(__f_->target(typeid(_Tp)));
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001260}
1261
Howard Hinnant99968442011-11-29 18:15:50 +00001262template<class _Rp, class _A0, class _A1>
1263template <typename _Tp>
1264const _Tp*
1265function<_Rp(_A0, _A1)>::target() const
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001266{
1267 if (__f_ == 0)
Howard Hinnant99968442011-11-29 18:15:50 +00001268 return (const _Tp*)0;
1269 return (const _Tp*)__f_->target(typeid(_Tp));
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001270}
1271
Howard Hinnant324bb032010-08-22 00:02:43 +00001272#endif // _LIBCPP_NO_RTTI
Howard Hinnantd4444702010-08-11 17:04:31 +00001273
Howard Hinnant99968442011-11-29 18:15:50 +00001274template<class _Rp, class _A0, class _A1, class _A2>
Eric Fiselierc3589a82017-01-04 23:56:00 +00001275class _LIBCPP_TEMPLATE_VIS function<_Rp(_A0, _A1, _A2)>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001276{
Howard Hinnant99968442011-11-29 18:15:50 +00001277 typedef __function::__base<_Rp(_A0, _A1, _A2)> __base;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001278 aligned_storage<3*sizeof(void*)>::type __buf_;
1279 __base* __f_;
1280
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001281public:
Howard Hinnant99968442011-11-29 18:15:50 +00001282 typedef _Rp result_type;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001283
1284 // 20.7.16.2.1, construct/copy/destroy:
Howard Hinnant99acc502010-09-21 17:32:39 +00001285 _LIBCPP_INLINE_VISIBILITY explicit function() : __f_(0) {}
1286 _LIBCPP_INLINE_VISIBILITY function(nullptr_t) : __f_(0) {}
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001287 function(const function&);
Howard Hinnant99968442011-11-29 18:15:50 +00001288 template<class _Fp>
1289 function(_Fp,
1290 typename enable_if<!is_integral<_Fp>::value>::type* = 0);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001291
Howard Hinnant72552802010-08-20 19:36:46 +00001292 template<class _Alloc>
Howard Hinnant99acc502010-09-21 17:32:39 +00001293 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant72552802010-08-20 19:36:46 +00001294 function(allocator_arg_t, const _Alloc&) : __f_(0) {}
1295 template<class _Alloc>
Howard Hinnant99acc502010-09-21 17:32:39 +00001296 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant72552802010-08-20 19:36:46 +00001297 function(allocator_arg_t, const _Alloc&, nullptr_t) : __f_(0) {}
1298 template<class _Alloc>
1299 function(allocator_arg_t, const _Alloc&, const function&);
Howard Hinnant99968442011-11-29 18:15:50 +00001300 template<class _Fp, class _Alloc>
1301 function(allocator_arg_t, const _Alloc& __a, _Fp __f,
1302 typename enable_if<!is_integral<_Fp>::value>::type* = 0);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001303
1304 function& operator=(const function&);
1305 function& operator=(nullptr_t);
Howard Hinnant99968442011-11-29 18:15:50 +00001306 template<class _Fp>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001307 typename enable_if
1308 <
Howard Hinnant99968442011-11-29 18:15:50 +00001309 !is_integral<_Fp>::value,
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001310 function&
1311 >::type
Howard Hinnant99968442011-11-29 18:15:50 +00001312 operator=(_Fp);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001313
1314 ~function();
1315
1316 // 20.7.16.2.2, function modifiers:
1317 void swap(function&);
Howard Hinnant99968442011-11-29 18:15:50 +00001318 template<class _Fp, class _Alloc>
Howard Hinnant99acc502010-09-21 17:32:39 +00001319 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99968442011-11-29 18:15:50 +00001320 void assign(_Fp __f, const _Alloc& __a)
Howard Hinnant72552802010-08-20 19:36:46 +00001321 {function(allocator_arg, __a, __f).swap(*this);}
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001322
1323 // 20.7.16.2.3, function capacity:
Howard Hinnant99acc502010-09-21 17:32:39 +00001324 _LIBCPP_INLINE_VISIBILITY operator bool() const {return __f_;}
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001325
1326private:
1327 // deleted overloads close possible hole in the type system
1328 template<class _R2, class _B0, class _B1, class _B2>
Howard Hinnant99acc502010-09-21 17:32:39 +00001329 bool operator==(const function<_R2(_B0, _B1, _B2)>&) const;// = delete;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001330 template<class _R2, class _B0, class _B1, class _B2>
Howard Hinnant99acc502010-09-21 17:32:39 +00001331 bool operator!=(const function<_R2(_B0, _B1, _B2)>&) const;// = delete;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001332public:
1333 // 20.7.16.2.4, function invocation:
Howard Hinnant99968442011-11-29 18:15:50 +00001334 _Rp operator()(_A0, _A1, _A2) const;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001335
Howard Hinnantd4444702010-08-11 17:04:31 +00001336#ifndef _LIBCPP_NO_RTTI
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001337 // 20.7.16.2.5, function target access:
1338 const std::type_info& target_type() const;
Howard Hinnant99968442011-11-29 18:15:50 +00001339 template <typename _Tp> _Tp* target();
1340 template <typename _Tp> const _Tp* target() const;
Howard Hinnant324bb032010-08-22 00:02:43 +00001341#endif // _LIBCPP_NO_RTTI
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001342};
1343
Howard Hinnant99968442011-11-29 18:15:50 +00001344template<class _Rp, class _A0, class _A1, class _A2>
1345function<_Rp(_A0, _A1, _A2)>::function(const function& __f)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001346{
1347 if (__f.__f_ == 0)
1348 __f_ = 0;
1349 else if (__f.__f_ == (const __base*)&__f.__buf_)
1350 {
1351 __f_ = (__base*)&__buf_;
1352 __f.__f_->__clone(__f_);
1353 }
1354 else
1355 __f_ = __f.__f_->__clone();
1356}
1357
Howard Hinnant99968442011-11-29 18:15:50 +00001358template<class _Rp, class _A0, class _A1, class _A2>
Howard Hinnant72552802010-08-20 19:36:46 +00001359template<class _Alloc>
Howard Hinnant99968442011-11-29 18:15:50 +00001360function<_Rp(_A0, _A1, _A2)>::function(allocator_arg_t, const _Alloc&,
Howard Hinnant72552802010-08-20 19:36:46 +00001361 const function& __f)
1362{
1363 if (__f.__f_ == 0)
1364 __f_ = 0;
1365 else if (__f.__f_ == (const __base*)&__f.__buf_)
1366 {
1367 __f_ = (__base*)&__buf_;
1368 __f.__f_->__clone(__f_);
1369 }
1370 else
1371 __f_ = __f.__f_->__clone();
1372}
1373
Howard Hinnant99968442011-11-29 18:15:50 +00001374template<class _Rp, class _A0, class _A1, class _A2>
1375template <class _Fp>
1376function<_Rp(_A0, _A1, _A2)>::function(_Fp __f,
1377 typename enable_if<!is_integral<_Fp>::value>::type*)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001378 : __f_(0)
1379{
Eric Fiselier8e030712015-08-18 19:41:51 +00001380 if (__function::__not_null(__f))
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001381 {
Howard Hinnant99968442011-11-29 18:15:50 +00001382 typedef __function::__func<_Fp, allocator<_Fp>, _Rp(_A0, _A1, _A2)> _FF;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001383 if (sizeof(_FF) <= sizeof(__buf_))
1384 {
1385 __f_ = (__base*)&__buf_;
1386 ::new (__f_) _FF(__f);
1387 }
1388 else
1389 {
Howard Hinnant99968442011-11-29 18:15:50 +00001390 typedef allocator<_FF> _Ap;
1391 _Ap __a;
1392 typedef __allocator_destructor<_Ap> _Dp;
1393 unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
1394 ::new (__hold.get()) _FF(__f, allocator<_Fp>(__a));
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001395 __f_ = __hold.release();
1396 }
1397 }
1398}
1399
Howard Hinnant99968442011-11-29 18:15:50 +00001400template<class _Rp, class _A0, class _A1, class _A2>
1401template <class _Fp, class _Alloc>
1402function<_Rp(_A0, _A1, _A2)>::function(allocator_arg_t, const _Alloc& __a0, _Fp __f,
1403 typename enable_if<!is_integral<_Fp>::value>::type*)
Howard Hinnant72552802010-08-20 19:36:46 +00001404 : __f_(0)
1405{
1406 typedef allocator_traits<_Alloc> __alloc_traits;
Eric Fiselier8e030712015-08-18 19:41:51 +00001407 if (__function::__not_null(__f))
Howard Hinnant72552802010-08-20 19:36:46 +00001408 {
Howard Hinnant99968442011-11-29 18:15:50 +00001409 typedef __function::__func<_Fp, _Alloc, _Rp(_A0, _A1, _A2)> _FF;
Howard Hinnant72552802010-08-20 19:36:46 +00001410 if (sizeof(_FF) <= sizeof(__buf_))
1411 {
1412 __f_ = (__base*)&__buf_;
Eric Fiselierb05f0592015-06-14 23:30:09 +00001413 ::new (__f_) _FF(__f, __a0);
Howard Hinnant72552802010-08-20 19:36:46 +00001414 }
1415 else
1416 {
Marshall Clow66302c62015-04-07 05:21:38 +00001417 typedef typename __rebind_alloc_helper<__alloc_traits, _FF>::type _Ap;
Howard Hinnant99968442011-11-29 18:15:50 +00001418 _Ap __a(__a0);
1419 typedef __allocator_destructor<_Ap> _Dp;
1420 unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
Howard Hinnant72552802010-08-20 19:36:46 +00001421 ::new (__hold.get()) _FF(__f, _Alloc(__a));
1422 __f_ = __hold.release();
1423 }
1424 }
1425}
1426
Howard Hinnant99968442011-11-29 18:15:50 +00001427template<class _Rp, class _A0, class _A1, class _A2>
1428function<_Rp(_A0, _A1, _A2)>&
1429function<_Rp(_A0, _A1, _A2)>::operator=(const function& __f)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001430{
1431 function(__f).swap(*this);
1432 return *this;
1433}
1434
Howard Hinnant99968442011-11-29 18:15:50 +00001435template<class _Rp, class _A0, class _A1, class _A2>
1436function<_Rp(_A0, _A1, _A2)>&
1437function<_Rp(_A0, _A1, _A2)>::operator=(nullptr_t)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001438{
1439 if (__f_ == (__base*)&__buf_)
1440 __f_->destroy();
1441 else if (__f_)
1442 __f_->destroy_deallocate();
1443 __f_ = 0;
Eric Fiselierfa97c2e2015-06-02 01:31:33 +00001444 return *this;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001445}
1446
Howard Hinnant99968442011-11-29 18:15:50 +00001447template<class _Rp, class _A0, class _A1, class _A2>
1448template <class _Fp>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001449typename enable_if
1450<
Howard Hinnant99968442011-11-29 18:15:50 +00001451 !is_integral<_Fp>::value,
1452 function<_Rp(_A0, _A1, _A2)>&
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001453>::type
Howard Hinnant99968442011-11-29 18:15:50 +00001454function<_Rp(_A0, _A1, _A2)>::operator=(_Fp __f)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001455{
Howard Hinnant0949eed2011-06-30 21:18:19 +00001456 function(_VSTD::move(__f)).swap(*this);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001457 return *this;
1458}
1459
Howard Hinnant99968442011-11-29 18:15:50 +00001460template<class _Rp, class _A0, class _A1, class _A2>
1461function<_Rp(_A0, _A1, _A2)>::~function()
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001462{
1463 if (__f_ == (__base*)&__buf_)
1464 __f_->destroy();
1465 else if (__f_)
1466 __f_->destroy_deallocate();
1467}
1468
Howard Hinnant99968442011-11-29 18:15:50 +00001469template<class _Rp, class _A0, class _A1, class _A2>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001470void
Howard Hinnant99968442011-11-29 18:15:50 +00001471function<_Rp(_A0, _A1, _A2)>::swap(function& __f)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001472{
Eric Fiselier152e5e62016-12-29 20:03:55 +00001473 if (_VSTD::addressof(__f) == this)
1474 return;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001475 if (__f_ == (__base*)&__buf_ && __f.__f_ == (__base*)&__f.__buf_)
1476 {
1477 typename aligned_storage<sizeof(__buf_)>::type __tempbuf;
1478 __base* __t = (__base*)&__tempbuf;
1479 __f_->__clone(__t);
1480 __f_->destroy();
1481 __f_ = 0;
1482 __f.__f_->__clone((__base*)&__buf_);
1483 __f.__f_->destroy();
1484 __f.__f_ = 0;
1485 __f_ = (__base*)&__buf_;
1486 __t->__clone((__base*)&__f.__buf_);
1487 __t->destroy();
1488 __f.__f_ = (__base*)&__f.__buf_;
1489 }
1490 else if (__f_ == (__base*)&__buf_)
1491 {
1492 __f_->__clone((__base*)&__f.__buf_);
1493 __f_->destroy();
1494 __f_ = __f.__f_;
1495 __f.__f_ = (__base*)&__f.__buf_;
1496 }
1497 else if (__f.__f_ == (__base*)&__f.__buf_)
1498 {
1499 __f.__f_->__clone((__base*)&__buf_);
1500 __f.__f_->destroy();
1501 __f.__f_ = __f_;
1502 __f_ = (__base*)&__buf_;
1503 }
1504 else
Howard Hinnant0949eed2011-06-30 21:18:19 +00001505 _VSTD::swap(__f_, __f.__f_);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001506}
1507
Howard Hinnant99968442011-11-29 18:15:50 +00001508template<class _Rp, class _A0, class _A1, class _A2>
1509_Rp
1510function<_Rp(_A0, _A1, _A2)>::operator()(_A0 __a0, _A1 __a1, _A2 __a2) const
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001511{
1512 if (__f_ == 0)
Marshall Clow14c09a22016-08-25 15:09:01 +00001513 __throw_bad_function_call();
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001514 return (*__f_)(__a0, __a1, __a2);
1515}
1516
Howard Hinnantd4444702010-08-11 17:04:31 +00001517#ifndef _LIBCPP_NO_RTTI
1518
Howard Hinnant99968442011-11-29 18:15:50 +00001519template<class _Rp, class _A0, class _A1, class _A2>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001520const std::type_info&
Howard Hinnant99968442011-11-29 18:15:50 +00001521function<_Rp(_A0, _A1, _A2)>::target_type() const
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001522{
1523 if (__f_ == 0)
1524 return typeid(void);
1525 return __f_->target_type();
1526}
1527
Howard Hinnant99968442011-11-29 18:15:50 +00001528template<class _Rp, class _A0, class _A1, class _A2>
1529template <typename _Tp>
1530_Tp*
1531function<_Rp(_A0, _A1, _A2)>::target()
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001532{
1533 if (__f_ == 0)
Howard Hinnant99968442011-11-29 18:15:50 +00001534 return (_Tp*)0;
Marshall Clowff5f9b22017-06-14 20:00:36 +00001535 return (_Tp*) const_cast<void *>(__f_->target(typeid(_Tp)));
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001536}
1537
Howard Hinnant99968442011-11-29 18:15:50 +00001538template<class _Rp, class _A0, class _A1, class _A2>
1539template <typename _Tp>
1540const _Tp*
1541function<_Rp(_A0, _A1, _A2)>::target() const
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001542{
1543 if (__f_ == 0)
Howard Hinnant99968442011-11-29 18:15:50 +00001544 return (const _Tp*)0;
1545 return (const _Tp*)__f_->target(typeid(_Tp));
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001546}
1547
Howard Hinnant324bb032010-08-22 00:02:43 +00001548#endif // _LIBCPP_NO_RTTI
Howard Hinnantd4444702010-08-11 17:04:31 +00001549
Howard Hinnant99968442011-11-29 18:15:50 +00001550template <class _Fp>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001551inline _LIBCPP_INLINE_VISIBILITY
1552bool
Howard Hinnant99968442011-11-29 18:15:50 +00001553operator==(const function<_Fp>& __f, nullptr_t) {return !__f;}
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001554
Howard Hinnant99968442011-11-29 18:15:50 +00001555template <class _Fp>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001556inline _LIBCPP_INLINE_VISIBILITY
1557bool
Howard Hinnant99968442011-11-29 18:15:50 +00001558operator==(nullptr_t, const function<_Fp>& __f) {return !__f;}
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001559
Howard Hinnant99968442011-11-29 18:15:50 +00001560template <class _Fp>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001561inline _LIBCPP_INLINE_VISIBILITY
1562bool
Howard Hinnant99968442011-11-29 18:15:50 +00001563operator!=(const function<_Fp>& __f, nullptr_t) {return (bool)__f;}
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001564
Howard Hinnant99968442011-11-29 18:15:50 +00001565template <class _Fp>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001566inline _LIBCPP_INLINE_VISIBILITY
1567bool
Howard Hinnant99968442011-11-29 18:15:50 +00001568operator!=(nullptr_t, const function<_Fp>& __f) {return (bool)__f;}
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001569
Howard Hinnant99968442011-11-29 18:15:50 +00001570template <class _Fp>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001571inline _LIBCPP_INLINE_VISIBILITY
1572void
Howard Hinnant99968442011-11-29 18:15:50 +00001573swap(function<_Fp>& __x, function<_Fp>& __y)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001574{return __x.swap(__y);}
1575
Howard Hinnant324bb032010-08-22 00:02:43 +00001576#endif // _LIBCPP_FUNCTIONAL_03