blob: 0a3bfbaa3d2cf6d7af2fb41b96d2f711aad380bc [file] [log] [blame]
Colin Cross8ae06772022-03-02 14:39:53 -08001// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
4// The LLVM Compiler Infrastructure
5//
6// This file is dual licensed under the MIT and the University of Illinois Open
7// Source Licenses. See LICENSE.TXT for details.
8//
9//===----------------------------------------------------------------------===//
10
11#ifndef _LIBCPP_FUNCTIONAL_03
12#define _LIBCPP_FUNCTIONAL_03
13
14// manual variadic expansion for <functional>
15
16#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
17#pragma GCC system_header
18#endif
19
20namespace __function {
21
22template<class _Fp> class __base;
23
24template<class _Rp>
25class __base<_Rp()>
26{
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;
36 virtual _Rp operator()() = 0;
37#ifndef _LIBCPP_NO_RTTI
38 virtual const void* target(const type_info&) const = 0;
39 virtual const std::type_info& target_type() const = 0;
40#endif // _LIBCPP_NO_RTTI
41};
42
43template<class _Rp, class _A0>
44class __base<_Rp(_A0)>
45{
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;
55 virtual _Rp operator()(_A0) = 0;
56#ifndef _LIBCPP_NO_RTTI
57 virtual const void* target(const type_info&) const = 0;
58 virtual const std::type_info& target_type() const = 0;
59#endif // _LIBCPP_NO_RTTI
60};
61
62template<class _Rp, class _A0, class _A1>
63class __base<_Rp(_A0, _A1)>
64{
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;
74 virtual _Rp operator()(_A0, _A1) = 0;
75#ifndef _LIBCPP_NO_RTTI
76 virtual const void* target(const type_info&) const = 0;
77 virtual const std::type_info& target_type() const = 0;
78#endif // _LIBCPP_NO_RTTI
79};
80
81template<class _Rp, class _A0, class _A1, class _A2>
82class __base<_Rp(_A0, _A1, _A2)>
83{
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;
93 virtual _Rp operator()(_A0, _A1, _A2) = 0;
94#ifndef _LIBCPP_NO_RTTI
95 virtual const void* target(const type_info&) const = 0;
96 virtual const std::type_info& target_type() const = 0;
97#endif // _LIBCPP_NO_RTTI
98};
99
100template<class _FD, class _Alloc, class _FB> class __func;
101
102template<class _Fp, class _Alloc, class _Rp>
103class __func<_Fp, _Alloc, _Rp()>
104 : public __base<_Rp()>
105{
106 __compressed_pair<_Fp, _Alloc> __f_;
107public:
108 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;
112 virtual void destroy();
113 virtual void destroy_deallocate();
114 virtual _Rp operator()();
115#ifndef _LIBCPP_NO_RTTI
116 virtual const void* target(const type_info&) const;
117 virtual const std::type_info& target_type() const;
118#endif // _LIBCPP_NO_RTTI
119};
120
121template<class _Fp, class _Alloc, class _Rp>
122__base<_Rp()>*
123__func<_Fp, _Alloc, _Rp()>::__clone() const
124{
125 typedef allocator_traits<_Alloc> __alloc_traits;
126 typedef typename __rebind_alloc_helper<__alloc_traits, __func>::type _Ap;
127 _Ap __a(__f_.second());
128 typedef __allocator_destructor<_Ap> _Dp;
129 unique_ptr<__func, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
130 ::new (__hold.get()) __func(__f_.first(), _Alloc(__a));
131 return __hold.release();
132}
133
134template<class _Fp, class _Alloc, class _Rp>
135void
136__func<_Fp, _Alloc, _Rp()>::__clone(__base<_Rp()>* __p) const
137{
138 ::new (__p) __func(__f_.first(), __f_.second());
139}
140
141template<class _Fp, class _Alloc, class _Rp>
142void
143__func<_Fp, _Alloc, _Rp()>::destroy()
144{
145 __f_.~__compressed_pair<_Fp, _Alloc>();
146}
147
148template<class _Fp, class _Alloc, class _Rp>
149void
150__func<_Fp, _Alloc, _Rp()>::destroy_deallocate()
151{
152 typedef allocator_traits<_Alloc> __alloc_traits;
153 typedef typename __rebind_alloc_helper<__alloc_traits, __func>::type _Ap;
154 _Ap __a(__f_.second());
155 __f_.~__compressed_pair<_Fp, _Alloc>();
156 __a.deallocate(this, 1);
157}
158
159template<class _Fp, class _Alloc, class _Rp>
160_Rp
161__func<_Fp, _Alloc, _Rp()>::operator()()
162{
163 typedef __invoke_void_return_wrapper<_Rp> _Invoker;
164 return _Invoker::__call(__f_.first());
165}
166
167#ifndef _LIBCPP_NO_RTTI
168
169template<class _Fp, class _Alloc, class _Rp>
170const void*
171__func<_Fp, _Alloc, _Rp()>::target(const type_info& __ti) const
172{
173 if (__ti == typeid(_Fp))
174 return &__f_.first();
175 return (const void*)0;
176}
177
178template<class _Fp, class _Alloc, class _Rp>
179const std::type_info&
180__func<_Fp, _Alloc, _Rp()>::target_type() const
181{
182 return typeid(_Fp);
183}
184
185#endif // _LIBCPP_NO_RTTI
186
187template<class _Fp, class _Alloc, class _Rp, class _A0>
188class __func<_Fp, _Alloc, _Rp(_A0)>
189 : public __base<_Rp(_A0)>
190{
191 __compressed_pair<_Fp, _Alloc> __f_;
192public:
193 _LIBCPP_INLINE_VISIBILITY explicit __func(_Fp __f) : __f_(_VSTD::move(__f)) {}
194 _LIBCPP_INLINE_VISIBILITY explicit __func(_Fp __f, _Alloc __a)
195 : __f_(_VSTD::move(__f), _VSTD::move(__a)) {}
196 virtual __base<_Rp(_A0)>* __clone() const;
197 virtual void __clone(__base<_Rp(_A0)>*) const;
198 virtual void destroy();
199 virtual void destroy_deallocate();
200 virtual _Rp operator()(_A0);
201#ifndef _LIBCPP_NO_RTTI
202 virtual const void* target(const type_info&) const;
203 virtual const std::type_info& target_type() const;
204#endif // _LIBCPP_NO_RTTI
205};
206
207template<class _Fp, class _Alloc, class _Rp, class _A0>
208__base<_Rp(_A0)>*
209__func<_Fp, _Alloc, _Rp(_A0)>::__clone() const
210{
211 typedef allocator_traits<_Alloc> __alloc_traits;
212 typedef typename __rebind_alloc_helper<__alloc_traits, __func>::type _Ap;
213 _Ap __a(__f_.second());
214 typedef __allocator_destructor<_Ap> _Dp;
215 unique_ptr<__func, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
216 ::new (__hold.get()) __func(__f_.first(), _Alloc(__a));
217 return __hold.release();
218}
219
220template<class _Fp, class _Alloc, class _Rp, class _A0>
221void
222__func<_Fp, _Alloc, _Rp(_A0)>::__clone(__base<_Rp(_A0)>* __p) const
223{
224 ::new (__p) __func(__f_.first(), __f_.second());
225}
226
227template<class _Fp, class _Alloc, class _Rp, class _A0>
228void
229__func<_Fp, _Alloc, _Rp(_A0)>::destroy()
230{
231 __f_.~__compressed_pair<_Fp, _Alloc>();
232}
233
234template<class _Fp, class _Alloc, class _Rp, class _A0>
235void
236__func<_Fp, _Alloc, _Rp(_A0)>::destroy_deallocate()
237{
238 typedef allocator_traits<_Alloc> __alloc_traits;
239 typedef typename __rebind_alloc_helper<__alloc_traits, __func>::type _Ap;
240 _Ap __a(__f_.second());
241 __f_.~__compressed_pair<_Fp, _Alloc>();
242 __a.deallocate(this, 1);
243}
244
245template<class _Fp, class _Alloc, class _Rp, class _A0>
246_Rp
247__func<_Fp, _Alloc, _Rp(_A0)>::operator()(_A0 __a0)
248{
249 typedef __invoke_void_return_wrapper<_Rp> _Invoker;
250 return _Invoker::__call(__f_.first(), __a0);
251}
252
253#ifndef _LIBCPP_NO_RTTI
254
255template<class _Fp, class _Alloc, class _Rp, class _A0>
256const void*
257__func<_Fp, _Alloc, _Rp(_A0)>::target(const type_info& __ti) const
258{
259 if (__ti == typeid(_Fp))
260 return &__f_.first();
261 return (const void*)0;
262}
263
264template<class _Fp, class _Alloc, class _Rp, class _A0>
265const std::type_info&
266__func<_Fp, _Alloc, _Rp(_A0)>::target_type() const
267{
268 return typeid(_Fp);
269}
270
271#endif // _LIBCPP_NO_RTTI
272
273template<class _Fp, class _Alloc, class _Rp, class _A0, class _A1>
274class __func<_Fp, _Alloc, _Rp(_A0, _A1)>
275 : public __base<_Rp(_A0, _A1)>
276{
277 __compressed_pair<_Fp, _Alloc> __f_;
278public:
279 _LIBCPP_INLINE_VISIBILITY explicit __func(_Fp __f) : __f_(_VSTD::move(__f)) {}
280 _LIBCPP_INLINE_VISIBILITY explicit __func(_Fp __f, _Alloc __a)
281 : __f_(_VSTD::move(__f), _VSTD::move(__a)) {}
282 virtual __base<_Rp(_A0, _A1)>* __clone() const;
283 virtual void __clone(__base<_Rp(_A0, _A1)>*) const;
284 virtual void destroy();
285 virtual void destroy_deallocate();
286 virtual _Rp operator()(_A0, _A1);
287#ifndef _LIBCPP_NO_RTTI
288 virtual const void* target(const type_info&) const;
289 virtual const std::type_info& target_type() const;
290#endif // _LIBCPP_NO_RTTI
291};
292
293template<class _Fp, class _Alloc, class _Rp, class _A0, class _A1>
294__base<_Rp(_A0, _A1)>*
295__func<_Fp, _Alloc, _Rp(_A0, _A1)>::__clone() const
296{
297 typedef allocator_traits<_Alloc> __alloc_traits;
298 typedef typename __rebind_alloc_helper<__alloc_traits, __func>::type _Ap;
299 _Ap __a(__f_.second());
300 typedef __allocator_destructor<_Ap> _Dp;
301 unique_ptr<__func, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
302 ::new (__hold.get()) __func(__f_.first(), _Alloc(__a));
303 return __hold.release();
304}
305
306template<class _Fp, class _Alloc, class _Rp, class _A0, class _A1>
307void
308__func<_Fp, _Alloc, _Rp(_A0, _A1)>::__clone(__base<_Rp(_A0, _A1)>* __p) const
309{
310 ::new (__p) __func(__f_.first(), __f_.second());
311}
312
313template<class _Fp, class _Alloc, class _Rp, class _A0, class _A1>
314void
315__func<_Fp, _Alloc, _Rp(_A0, _A1)>::destroy()
316{
317 __f_.~__compressed_pair<_Fp, _Alloc>();
318}
319
320template<class _Fp, class _Alloc, class _Rp, class _A0, class _A1>
321void
322__func<_Fp, _Alloc, _Rp(_A0, _A1)>::destroy_deallocate()
323{
324 typedef allocator_traits<_Alloc> __alloc_traits;
325 typedef typename __rebind_alloc_helper<__alloc_traits, __func>::type _Ap;
326 _Ap __a(__f_.second());
327 __f_.~__compressed_pair<_Fp, _Alloc>();
328 __a.deallocate(this, 1);
329}
330
331template<class _Fp, class _Alloc, class _Rp, class _A0, class _A1>
332_Rp
333__func<_Fp, _Alloc, _Rp(_A0, _A1)>::operator()(_A0 __a0, _A1 __a1)
334{
335 typedef __invoke_void_return_wrapper<_Rp> _Invoker;
336 return _Invoker::__call(__f_.first(), __a0, __a1);
337}
338
339#ifndef _LIBCPP_NO_RTTI
340
341template<class _Fp, class _Alloc, class _Rp, class _A0, class _A1>
342const void*
343__func<_Fp, _Alloc, _Rp(_A0, _A1)>::target(const type_info& __ti) const
344{
345 if (__ti == typeid(_Fp))
346 return &__f_.first();
347 return (const void*)0;
348}
349
350template<class _Fp, class _Alloc, class _Rp, class _A0, class _A1>
351const std::type_info&
352__func<_Fp, _Alloc, _Rp(_A0, _A1)>::target_type() const
353{
354 return typeid(_Fp);
355}
356
357#endif // _LIBCPP_NO_RTTI
358
359template<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)>
362{
363 __compressed_pair<_Fp, _Alloc> __f_;
364public:
365 _LIBCPP_INLINE_VISIBILITY explicit __func(_Fp __f) : __f_(_VSTD::move(__f)) {}
366 _LIBCPP_INLINE_VISIBILITY explicit __func(_Fp __f, _Alloc __a)
367 : __f_(_VSTD::move(__f), _VSTD::move(__a)) {}
368 virtual __base<_Rp(_A0, _A1, _A2)>* __clone() const;
369 virtual void __clone(__base<_Rp(_A0, _A1, _A2)>*) const;
370 virtual void destroy();
371 virtual void destroy_deallocate();
372 virtual _Rp operator()(_A0, _A1, _A2);
373#ifndef _LIBCPP_NO_RTTI
374 virtual const void* target(const type_info&) const;
375 virtual const std::type_info& target_type() const;
376#endif // _LIBCPP_NO_RTTI
377};
378
379template<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
382{
383 typedef allocator_traits<_Alloc> __alloc_traits;
384 typedef typename __rebind_alloc_helper<__alloc_traits, __func>::type _Ap;
385 _Ap __a(__f_.second());
386 typedef __allocator_destructor<_Ap> _Dp;
387 unique_ptr<__func, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
388 ::new (__hold.get()) __func(__f_.first(), _Alloc(__a));
389 return __hold.release();
390}
391
392template<class _Fp, class _Alloc, class _Rp, class _A0, class _A1, class _A2>
393void
394__func<_Fp, _Alloc, _Rp(_A0, _A1, _A2)>::__clone(__base<_Rp(_A0, _A1, _A2)>* __p) const
395{
396 ::new (__p) __func(__f_.first(), __f_.second());
397}
398
399template<class _Fp, class _Alloc, class _Rp, class _A0, class _A1, class _A2>
400void
401__func<_Fp, _Alloc, _Rp(_A0, _A1, _A2)>::destroy()
402{
403 __f_.~__compressed_pair<_Fp, _Alloc>();
404}
405
406template<class _Fp, class _Alloc, class _Rp, class _A0, class _A1, class _A2>
407void
408__func<_Fp, _Alloc, _Rp(_A0, _A1, _A2)>::destroy_deallocate()
409{
410 typedef allocator_traits<_Alloc> __alloc_traits;
411 typedef typename __rebind_alloc_helper<__alloc_traits, __func>::type _Ap;
412 _Ap __a(__f_.second());
413 __f_.~__compressed_pair<_Fp, _Alloc>();
414 __a.deallocate(this, 1);
415}
416
417template<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)
420{
421 typedef __invoke_void_return_wrapper<_Rp> _Invoker;
422 return _Invoker::__call(__f_.first(), __a0, __a1, __a2);
423}
424
425#ifndef _LIBCPP_NO_RTTI
426
427template<class _Fp, class _Alloc, class _Rp, class _A0, class _A1, class _A2>
428const void*
429__func<_Fp, _Alloc, _Rp(_A0, _A1, _A2)>::target(const type_info& __ti) const
430{
431 if (__ti == typeid(_Fp))
432 return &__f_.first();
433 return (const void*)0;
434}
435
436template<class _Fp, class _Alloc, class _Rp, class _A0, class _A1, class _A2>
437const std::type_info&
438__func<_Fp, _Alloc, _Rp(_A0, _A1, _A2)>::target_type() const
439{
440 return typeid(_Fp);
441}
442
443#endif // _LIBCPP_NO_RTTI
444
445} // __function
446
447template<class _Rp>
448class _LIBCPP_TEMPLATE_VIS function<_Rp()>
449{
450 typedef __function::__base<_Rp()> __base;
451 aligned_storage<3*sizeof(void*)>::type __buf_;
452 __base* __f_;
453
454public:
455 typedef _Rp result_type;
456
457 // 20.7.16.2.1, construct/copy/destroy:
458 _LIBCPP_INLINE_VISIBILITY explicit function() : __f_(0) {}
459 _LIBCPP_INLINE_VISIBILITY function(nullptr_t) : __f_(0) {}
460 function(const function&);
461 template<class _Fp>
462 function(_Fp,
463 typename enable_if<!is_integral<_Fp>::value>::type* = 0);
464
465 template<class _Alloc>
466 _LIBCPP_INLINE_VISIBILITY
467 function(allocator_arg_t, const _Alloc&) : __f_(0) {}
468 template<class _Alloc>
469 _LIBCPP_INLINE_VISIBILITY
470 function(allocator_arg_t, const _Alloc&, nullptr_t) : __f_(0) {}
471 template<class _Alloc>
472 function(allocator_arg_t, const _Alloc&, const function&);
473 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);
476
477 function& operator=(const function&);
478 function& operator=(nullptr_t);
479 template<class _Fp>
480 typename enable_if
481 <
482 !is_integral<_Fp>::value,
483 function&
484 >::type
485 operator=(_Fp);
486
487 ~function();
488
489 // 20.7.16.2.2, function modifiers:
490 void swap(function&);
491 template<class _Fp, class _Alloc>
492 _LIBCPP_INLINE_VISIBILITY
493 void assign(_Fp __f, const _Alloc& __a)
494 {function(allocator_arg, __a, __f).swap(*this);}
495
496 // 20.7.16.2.3, function capacity:
497 _LIBCPP_INLINE_VISIBILITY operator bool() const {return __f_;}
498
499private:
500 // deleted overloads close possible hole in the type system
501 template<class _R2>
502 bool operator==(const function<_R2()>&) const;// = delete;
503 template<class _R2>
504 bool operator!=(const function<_R2()>&) const;// = delete;
505public:
506 // 20.7.16.2.4, function invocation:
507 _Rp operator()() const;
508
509#ifndef _LIBCPP_NO_RTTI
510 // 20.7.16.2.5, function target access:
511 const std::type_info& target_type() const;
512 template <typename _Tp> _Tp* target();
513 template <typename _Tp> const _Tp* target() const;
514#endif // _LIBCPP_NO_RTTI
515};
516
517template<class _Rp>
518function<_Rp()>::function(const function& __f)
519{
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
531template<class _Rp>
532template<class _Alloc>
533function<_Rp()>::function(allocator_arg_t, const _Alloc&, const function& __f)
534{
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
546template<class _Rp>
547template <class _Fp>
548function<_Rp()>::function(_Fp __f,
549 typename enable_if<!is_integral<_Fp>::value>::type*)
550 : __f_(0)
551{
552 if (__function::__not_null(__f))
553 {
554 typedef __function::__func<_Fp, allocator<_Fp>, _Rp()> _FF;
555 if (sizeof(_FF) <= sizeof(__buf_))
556 {
557 __f_ = (__base*)&__buf_;
558 ::new (__f_) _FF(__f);
559 }
560 else
561 {
562 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));
567 __f_ = __hold.release();
568 }
569 }
570}
571
572template<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*)
576 : __f_(0)
577{
578 typedef allocator_traits<_Alloc> __alloc_traits;
579 if (__function::__not_null(__f))
580 {
581 typedef __function::__func<_Fp, _Alloc, _Rp()> _FF;
582 if (sizeof(_FF) <= sizeof(__buf_))
583 {
584 __f_ = (__base*)&__buf_;
585 ::new (__f_) _FF(__f, __a0);
586 }
587 else
588 {
589 typedef typename __rebind_alloc_helper<__alloc_traits, _FF>::type _Ap;
590 _Ap __a(__a0);
591 typedef __allocator_destructor<_Ap> _Dp;
592 unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
593 ::new (__hold.get()) _FF(__f, _Alloc(__a));
594 __f_ = __hold.release();
595 }
596 }
597}
598
599template<class _Rp>
600function<_Rp()>&
601function<_Rp()>::operator=(const function& __f)
602{
603 if (__f)
604 function(__f).swap(*this);
605 else
606 *this = nullptr;
607 return *this;
608}
609
610template<class _Rp>
611function<_Rp()>&
612function<_Rp()>::operator=(nullptr_t)
613{
614 __base* __t = __f_;
615 __f_ = 0;
616 if (__t == (__base*)&__buf_)
617 __t->destroy();
618 else if (__t)
619 __t->destroy_deallocate();
620 return *this;
621}
622
623template<class _Rp>
624template <class _Fp>
625typename enable_if
626<
627 !is_integral<_Fp>::value,
628 function<_Rp()>&
629>::type
630function<_Rp()>::operator=(_Fp __f)
631{
632 function(_VSTD::move(__f)).swap(*this);
633 return *this;
634}
635
636template<class _Rp>
637function<_Rp()>::~function()
638{
639 if (__f_ == (__base*)&__buf_)
640 __f_->destroy();
641 else if (__f_)
642 __f_->destroy_deallocate();
643}
644
645template<class _Rp>
646void
647function<_Rp()>::swap(function& __f)
648{
649 if (_VSTD::addressof(__f) == this)
650 return;
651 if (__f_ == (__base*)&__buf_ && __f.__f_ == (__base*)&__f.__buf_)
652 {
653 typename aligned_storage<sizeof(__buf_)>::type __tempbuf;
654 __base* __t = (__base*)&__tempbuf;
655 __f_->__clone(__t);
656 __f_->destroy();
657 __f_ = 0;
658 __f.__f_->__clone((__base*)&__buf_);
659 __f.__f_->destroy();
660 __f.__f_ = 0;
661 __f_ = (__base*)&__buf_;
662 __t->__clone((__base*)&__f.__buf_);
663 __t->destroy();
664 __f.__f_ = (__base*)&__f.__buf_;
665 }
666 else if (__f_ == (__base*)&__buf_)
667 {
668 __f_->__clone((__base*)&__f.__buf_);
669 __f_->destroy();
670 __f_ = __f.__f_;
671 __f.__f_ = (__base*)&__f.__buf_;
672 }
673 else if (__f.__f_ == (__base*)&__f.__buf_)
674 {
675 __f.__f_->__clone((__base*)&__buf_);
676 __f.__f_->destroy();
677 __f.__f_ = __f_;
678 __f_ = (__base*)&__buf_;
679 }
680 else
681 _VSTD::swap(__f_, __f.__f_);
682}
683
684template<class _Rp>
685_Rp
686function<_Rp()>::operator()() const
687{
688 if (__f_ == 0)
689 __throw_bad_function_call();
690 return (*__f_)();
691}
692
693#ifndef _LIBCPP_NO_RTTI
694
695template<class _Rp>
696const std::type_info&
697function<_Rp()>::target_type() const
698{
699 if (__f_ == 0)
700 return typeid(void);
701 return __f_->target_type();
702}
703
704template<class _Rp>
705template <typename _Tp>
706_Tp*
707function<_Rp()>::target()
708{
709 if (__f_ == 0)
710 return (_Tp*)0;
711 return (_Tp*) const_cast<void *>(__f_->target(typeid(_Tp)));
712}
713
714template<class _Rp>
715template <typename _Tp>
716const _Tp*
717function<_Rp()>::target() const
718{
719 if (__f_ == 0)
720 return (const _Tp*)0;
721 return (const _Tp*)__f_->target(typeid(_Tp));
722}
723
724#endif // _LIBCPP_NO_RTTI
725
726template<class _Rp, class _A0>
727class _LIBCPP_TEMPLATE_VIS function<_Rp(_A0)>
728 : public unary_function<_A0, _Rp>
729{
730 typedef __function::__base<_Rp(_A0)> __base;
731 aligned_storage<3*sizeof(void*)>::type __buf_;
732 __base* __f_;
733
734public:
735 typedef _Rp result_type;
736
737 // 20.7.16.2.1, construct/copy/destroy:
738 _LIBCPP_INLINE_VISIBILITY explicit function() : __f_(0) {}
739 _LIBCPP_INLINE_VISIBILITY function(nullptr_t) : __f_(0) {}
740 function(const function&);
741 template<class _Fp>
742 function(_Fp,
743 typename enable_if<!is_integral<_Fp>::value>::type* = 0);
744
745 template<class _Alloc>
746 _LIBCPP_INLINE_VISIBILITY
747 function(allocator_arg_t, const _Alloc&) : __f_(0) {}
748 template<class _Alloc>
749 _LIBCPP_INLINE_VISIBILITY
750 function(allocator_arg_t, const _Alloc&, nullptr_t) : __f_(0) {}
751 template<class _Alloc>
752 function(allocator_arg_t, const _Alloc&, const function&);
753 template<class _Fp, class _Alloc>
754 function(allocator_arg_t, const _Alloc& __a, _Fp __f,
755 typename enable_if<!is_integral<_Fp>::value>::type* = 0);
756
757 function& operator=(const function&);
758 function& operator=(nullptr_t);
759 template<class _Fp>
760 typename enable_if
761 <
762 !is_integral<_Fp>::value,
763 function&
764 >::type
765 operator=(_Fp);
766
767 ~function();
768
769 // 20.7.16.2.2, function modifiers:
770 void swap(function&);
771 template<class _Fp, class _Alloc>
772 _LIBCPP_INLINE_VISIBILITY
773 void assign(_Fp __f, const _Alloc& __a)
774 {function(allocator_arg, __a, __f).swap(*this);}
775
776 // 20.7.16.2.3, function capacity:
777 _LIBCPP_INLINE_VISIBILITY operator bool() const {return __f_;}
778
779private:
780 // deleted overloads close possible hole in the type system
781 template<class _R2, class _B0>
782 bool operator==(const function<_R2(_B0)>&) const;// = delete;
783 template<class _R2, class _B0>
784 bool operator!=(const function<_R2(_B0)>&) const;// = delete;
785public:
786 // 20.7.16.2.4, function invocation:
787 _Rp operator()(_A0) const;
788
789#ifndef _LIBCPP_NO_RTTI
790 // 20.7.16.2.5, function target access:
791 const std::type_info& target_type() const;
792 template <typename _Tp> _Tp* target();
793 template <typename _Tp> const _Tp* target() const;
794#endif // _LIBCPP_NO_RTTI
795};
796
797template<class _Rp, class _A0>
798function<_Rp(_A0)>::function(const function& __f)
799{
800 if (__f.__f_ == 0)
801 __f_ = 0;
802 else if (__f.__f_ == (const __base*)&__f.__buf_)
803 {
804 __f_ = (__base*)&__buf_;
805 __f.__f_->__clone(__f_);
806 }
807 else
808 __f_ = __f.__f_->__clone();
809}
810
811template<class _Rp, class _A0>
812template<class _Alloc>
813function<_Rp(_A0)>::function(allocator_arg_t, const _Alloc&, const function& __f)
814{
815 if (__f.__f_ == 0)
816 __f_ = 0;
817 else if (__f.__f_ == (const __base*)&__f.__buf_)
818 {
819 __f_ = (__base*)&__buf_;
820 __f.__f_->__clone(__f_);
821 }
822 else
823 __f_ = __f.__f_->__clone();
824}
825
826template<class _Rp, class _A0>
827template <class _Fp>
828function<_Rp(_A0)>::function(_Fp __f,
829 typename enable_if<!is_integral<_Fp>::value>::type*)
830 : __f_(0)
831{
832 if (__function::__not_null(__f))
833 {
834 typedef __function::__func<_Fp, allocator<_Fp>, _Rp(_A0)> _FF;
835 if (sizeof(_FF) <= sizeof(__buf_))
836 {
837 __f_ = (__base*)&__buf_;
838 ::new (__f_) _FF(__f);
839 }
840 else
841 {
842 typedef allocator<_FF> _Ap;
843 _Ap __a;
844 typedef __allocator_destructor<_Ap> _Dp;
845 unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
846 ::new (__hold.get()) _FF(__f, allocator<_Fp>(__a));
847 __f_ = __hold.release();
848 }
849 }
850}
851
852template<class _Rp, class _A0>
853template <class _Fp, class _Alloc>
854function<_Rp(_A0)>::function(allocator_arg_t, const _Alloc& __a0, _Fp __f,
855 typename enable_if<!is_integral<_Fp>::value>::type*)
856 : __f_(0)
857{
858 typedef allocator_traits<_Alloc> __alloc_traits;
859 if (__function::__not_null(__f))
860 {
861 typedef __function::__func<_Fp, _Alloc, _Rp(_A0)> _FF;
862 if (sizeof(_FF) <= sizeof(__buf_))
863 {
864 __f_ = (__base*)&__buf_;
865 ::new (__f_) _FF(__f, __a0);
866 }
867 else
868 {
869 typedef typename __rebind_alloc_helper<__alloc_traits, _FF>::type _Ap;
870 _Ap __a(__a0);
871 typedef __allocator_destructor<_Ap> _Dp;
872 unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
873 ::new (__hold.get()) _FF(__f, _Alloc(__a));
874 __f_ = __hold.release();
875 }
876 }
877}
878
879template<class _Rp, class _A0>
880function<_Rp(_A0)>&
881function<_Rp(_A0)>::operator=(const function& __f)
882{
883 if (__f)
884 function(__f).swap(*this);
885 else
886 *this = nullptr;
887 return *this;
888}
889
890template<class _Rp, class _A0>
891function<_Rp(_A0)>&
892function<_Rp(_A0)>::operator=(nullptr_t)
893{
894 __base* __t = __f_;
895 __f_ = 0;
896 if (__t == (__base*)&__buf_)
897 __t->destroy();
898 else if (__t)
899 __t->destroy_deallocate();
900 return *this;
901}
902
903template<class _Rp, class _A0>
904template <class _Fp>
905typename enable_if
906<
907 !is_integral<_Fp>::value,
908 function<_Rp(_A0)>&
909>::type
910function<_Rp(_A0)>::operator=(_Fp __f)
911{
912 function(_VSTD::move(__f)).swap(*this);
913 return *this;
914}
915
916template<class _Rp, class _A0>
917function<_Rp(_A0)>::~function()
918{
919 if (__f_ == (__base*)&__buf_)
920 __f_->destroy();
921 else if (__f_)
922 __f_->destroy_deallocate();
923}
924
925template<class _Rp, class _A0>
926void
927function<_Rp(_A0)>::swap(function& __f)
928{
929 if (_VSTD::addressof(__f) == this)
930 return;
931 if (__f_ == (__base*)&__buf_ && __f.__f_ == (__base*)&__f.__buf_)
932 {
933 typename aligned_storage<sizeof(__buf_)>::type __tempbuf;
934 __base* __t = (__base*)&__tempbuf;
935 __f_->__clone(__t);
936 __f_->destroy();
937 __f_ = 0;
938 __f.__f_->__clone((__base*)&__buf_);
939 __f.__f_->destroy();
940 __f.__f_ = 0;
941 __f_ = (__base*)&__buf_;
942 __t->__clone((__base*)&__f.__buf_);
943 __t->destroy();
944 __f.__f_ = (__base*)&__f.__buf_;
945 }
946 else if (__f_ == (__base*)&__buf_)
947 {
948 __f_->__clone((__base*)&__f.__buf_);
949 __f_->destroy();
950 __f_ = __f.__f_;
951 __f.__f_ = (__base*)&__f.__buf_;
952 }
953 else if (__f.__f_ == (__base*)&__f.__buf_)
954 {
955 __f.__f_->__clone((__base*)&__buf_);
956 __f.__f_->destroy();
957 __f.__f_ = __f_;
958 __f_ = (__base*)&__buf_;
959 }
960 else
961 _VSTD::swap(__f_, __f.__f_);
962}
963
964template<class _Rp, class _A0>
965_Rp
966function<_Rp(_A0)>::operator()(_A0 __a0) const
967{
968 if (__f_ == 0)
969 __throw_bad_function_call();
970 return (*__f_)(__a0);
971}
972
973#ifndef _LIBCPP_NO_RTTI
974
975template<class _Rp, class _A0>
976const std::type_info&
977function<_Rp(_A0)>::target_type() const
978{
979 if (__f_ == 0)
980 return typeid(void);
981 return __f_->target_type();
982}
983
984template<class _Rp, class _A0>
985template <typename _Tp>
986_Tp*
987function<_Rp(_A0)>::target()
988{
989 if (__f_ == 0)
990 return (_Tp*)0;
991 return (_Tp*) const_cast<void *>(__f_->target(typeid(_Tp)));
992}
993
994template<class _Rp, class _A0>
995template <typename _Tp>
996const _Tp*
997function<_Rp(_A0)>::target() const
998{
999 if (__f_ == 0)
1000 return (const _Tp*)0;
1001 return (const _Tp*)__f_->target(typeid(_Tp));
1002}
1003
1004#endif // _LIBCPP_NO_RTTI
1005
1006template<class _Rp, class _A0, class _A1>
1007class _LIBCPP_TEMPLATE_VIS function<_Rp(_A0, _A1)>
1008 : public binary_function<_A0, _A1, _Rp>
1009{
1010 typedef __function::__base<_Rp(_A0, _A1)> __base;
1011 aligned_storage<3*sizeof(void*)>::type __buf_;
1012 __base* __f_;
1013
1014public:
1015 typedef _Rp result_type;
1016
1017 // 20.7.16.2.1, construct/copy/destroy:
1018 _LIBCPP_INLINE_VISIBILITY explicit function() : __f_(0) {}
1019 _LIBCPP_INLINE_VISIBILITY function(nullptr_t) : __f_(0) {}
1020 function(const function&);
1021 template<class _Fp>
1022 function(_Fp,
1023 typename enable_if<!is_integral<_Fp>::value>::type* = 0);
1024
1025 template<class _Alloc>
1026 _LIBCPP_INLINE_VISIBILITY
1027 function(allocator_arg_t, const _Alloc&) : __f_(0) {}
1028 template<class _Alloc>
1029 _LIBCPP_INLINE_VISIBILITY
1030 function(allocator_arg_t, const _Alloc&, nullptr_t) : __f_(0) {}
1031 template<class _Alloc>
1032 function(allocator_arg_t, const _Alloc&, const function&);
1033 template<class _Fp, class _Alloc>
1034 function(allocator_arg_t, const _Alloc& __a, _Fp __f,
1035 typename enable_if<!is_integral<_Fp>::value>::type* = 0);
1036
1037 function& operator=(const function&);
1038 function& operator=(nullptr_t);
1039 template<class _Fp>
1040 typename enable_if
1041 <
1042 !is_integral<_Fp>::value,
1043 function&
1044 >::type
1045 operator=(_Fp);
1046
1047 ~function();
1048
1049 // 20.7.16.2.2, function modifiers:
1050 void swap(function&);
1051 template<class _Fp, class _Alloc>
1052 _LIBCPP_INLINE_VISIBILITY
1053 void assign(_Fp __f, const _Alloc& __a)
1054 {function(allocator_arg, __a, __f).swap(*this);}
1055
1056 // 20.7.16.2.3, function capacity:
1057 operator bool() const {return __f_;}
1058
1059private:
1060 // deleted overloads close possible hole in the type system
1061 template<class _R2, class _B0, class _B1>
1062 bool operator==(const function<_R2(_B0, _B1)>&) const;// = delete;
1063 template<class _R2, class _B0, class _B1>
1064 bool operator!=(const function<_R2(_B0, _B1)>&) const;// = delete;
1065public:
1066 // 20.7.16.2.4, function invocation:
1067 _Rp operator()(_A0, _A1) const;
1068
1069#ifndef _LIBCPP_NO_RTTI
1070 // 20.7.16.2.5, function target access:
1071 const std::type_info& target_type() const;
1072 template <typename _Tp> _Tp* target();
1073 template <typename _Tp> const _Tp* target() const;
1074#endif // _LIBCPP_NO_RTTI
1075};
1076
1077template<class _Rp, class _A0, class _A1>
1078function<_Rp(_A0, _A1)>::function(const function& __f)
1079{
1080 if (__f.__f_ == 0)
1081 __f_ = 0;
1082 else if (__f.__f_ == (const __base*)&__f.__buf_)
1083 {
1084 __f_ = (__base*)&__buf_;
1085 __f.__f_->__clone(__f_);
1086 }
1087 else
1088 __f_ = __f.__f_->__clone();
1089}
1090
1091template<class _Rp, class _A0, class _A1>
1092template<class _Alloc>
1093function<_Rp(_A0, _A1)>::function(allocator_arg_t, const _Alloc&, const function& __f)
1094{
1095 if (__f.__f_ == 0)
1096 __f_ = 0;
1097 else if (__f.__f_ == (const __base*)&__f.__buf_)
1098 {
1099 __f_ = (__base*)&__buf_;
1100 __f.__f_->__clone(__f_);
1101 }
1102 else
1103 __f_ = __f.__f_->__clone();
1104}
1105
1106template<class _Rp, class _A0, class _A1>
1107template <class _Fp>
1108function<_Rp(_A0, _A1)>::function(_Fp __f,
1109 typename enable_if<!is_integral<_Fp>::value>::type*)
1110 : __f_(0)
1111{
1112 if (__function::__not_null(__f))
1113 {
1114 typedef __function::__func<_Fp, allocator<_Fp>, _Rp(_A0, _A1)> _FF;
1115 if (sizeof(_FF) <= sizeof(__buf_))
1116 {
1117 __f_ = (__base*)&__buf_;
1118 ::new (__f_) _FF(__f);
1119 }
1120 else
1121 {
1122 typedef allocator<_FF> _Ap;
1123 _Ap __a;
1124 typedef __allocator_destructor<_Ap> _Dp;
1125 unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
1126 ::new (__hold.get()) _FF(__f, allocator<_Fp>(__a));
1127 __f_ = __hold.release();
1128 }
1129 }
1130}
1131
1132template<class _Rp, class _A0, class _A1>
1133template <class _Fp, class _Alloc>
1134function<_Rp(_A0, _A1)>::function(allocator_arg_t, const _Alloc& __a0, _Fp __f,
1135 typename enable_if<!is_integral<_Fp>::value>::type*)
1136 : __f_(0)
1137{
1138 typedef allocator_traits<_Alloc> __alloc_traits;
1139 if (__function::__not_null(__f))
1140 {
1141 typedef __function::__func<_Fp, _Alloc, _Rp(_A0, _A1)> _FF;
1142 if (sizeof(_FF) <= sizeof(__buf_))
1143 {
1144 __f_ = (__base*)&__buf_;
1145 ::new (__f_) _FF(__f, __a0);
1146 }
1147 else
1148 {
1149 typedef typename __rebind_alloc_helper<__alloc_traits, _FF>::type _Ap;
1150 _Ap __a(__a0);
1151 typedef __allocator_destructor<_Ap> _Dp;
1152 unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
1153 ::new (__hold.get()) _FF(__f, _Alloc(__a));
1154 __f_ = __hold.release();
1155 }
1156 }
1157}
1158
1159template<class _Rp, class _A0, class _A1>
1160function<_Rp(_A0, _A1)>&
1161function<_Rp(_A0, _A1)>::operator=(const function& __f)
1162{
1163 if (__f)
1164 function(__f).swap(*this);
1165 else
1166 *this = nullptr;
1167 return *this;
1168}
1169
1170template<class _Rp, class _A0, class _A1>
1171function<_Rp(_A0, _A1)>&
1172function<_Rp(_A0, _A1)>::operator=(nullptr_t)
1173{
1174 __base* __t = __f_;
1175 __f_ = 0;
1176 if (__t == (__base*)&__buf_)
1177 __t->destroy();
1178 else if (__t)
1179 __t->destroy_deallocate();
1180 return *this;
1181}
1182
1183template<class _Rp, class _A0, class _A1>
1184template <class _Fp>
1185typename enable_if
1186<
1187 !is_integral<_Fp>::value,
1188 function<_Rp(_A0, _A1)>&
1189>::type
1190function<_Rp(_A0, _A1)>::operator=(_Fp __f)
1191{
1192 function(_VSTD::move(__f)).swap(*this);
1193 return *this;
1194}
1195
1196template<class _Rp, class _A0, class _A1>
1197function<_Rp(_A0, _A1)>::~function()
1198{
1199 if (__f_ == (__base*)&__buf_)
1200 __f_->destroy();
1201 else if (__f_)
1202 __f_->destroy_deallocate();
1203}
1204
1205template<class _Rp, class _A0, class _A1>
1206void
1207function<_Rp(_A0, _A1)>::swap(function& __f)
1208{
1209 if (_VSTD::addressof(__f) == this)
1210 return;
1211 if (__f_ == (__base*)&__buf_ && __f.__f_ == (__base*)&__f.__buf_)
1212 {
1213 typename aligned_storage<sizeof(__buf_)>::type __tempbuf;
1214 __base* __t = (__base*)&__tempbuf;
1215 __f_->__clone(__t);
1216 __f_->destroy();
1217 __f_ = 0;
1218 __f.__f_->__clone((__base*)&__buf_);
1219 __f.__f_->destroy();
1220 __f.__f_ = 0;
1221 __f_ = (__base*)&__buf_;
1222 __t->__clone((__base*)&__f.__buf_);
1223 __t->destroy();
1224 __f.__f_ = (__base*)&__f.__buf_;
1225 }
1226 else if (__f_ == (__base*)&__buf_)
1227 {
1228 __f_->__clone((__base*)&__f.__buf_);
1229 __f_->destroy();
1230 __f_ = __f.__f_;
1231 __f.__f_ = (__base*)&__f.__buf_;
1232 }
1233 else if (__f.__f_ == (__base*)&__f.__buf_)
1234 {
1235 __f.__f_->__clone((__base*)&__buf_);
1236 __f.__f_->destroy();
1237 __f.__f_ = __f_;
1238 __f_ = (__base*)&__buf_;
1239 }
1240 else
1241 _VSTD::swap(__f_, __f.__f_);
1242}
1243
1244template<class _Rp, class _A0, class _A1>
1245_Rp
1246function<_Rp(_A0, _A1)>::operator()(_A0 __a0, _A1 __a1) const
1247{
1248 if (__f_ == 0)
1249 __throw_bad_function_call();
1250 return (*__f_)(__a0, __a1);
1251}
1252
1253#ifndef _LIBCPP_NO_RTTI
1254
1255template<class _Rp, class _A0, class _A1>
1256const std::type_info&
1257function<_Rp(_A0, _A1)>::target_type() const
1258{
1259 if (__f_ == 0)
1260 return typeid(void);
1261 return __f_->target_type();
1262}
1263
1264template<class _Rp, class _A0, class _A1>
1265template <typename _Tp>
1266_Tp*
1267function<_Rp(_A0, _A1)>::target()
1268{
1269 if (__f_ == 0)
1270 return (_Tp*)0;
1271 return (_Tp*) const_cast<void *>(__f_->target(typeid(_Tp)));
1272}
1273
1274template<class _Rp, class _A0, class _A1>
1275template <typename _Tp>
1276const _Tp*
1277function<_Rp(_A0, _A1)>::target() const
1278{
1279 if (__f_ == 0)
1280 return (const _Tp*)0;
1281 return (const _Tp*)__f_->target(typeid(_Tp));
1282}
1283
1284#endif // _LIBCPP_NO_RTTI
1285
1286template<class _Rp, class _A0, class _A1, class _A2>
1287class _LIBCPP_TEMPLATE_VIS function<_Rp(_A0, _A1, _A2)>
1288{
1289 typedef __function::__base<_Rp(_A0, _A1, _A2)> __base;
1290 aligned_storage<3*sizeof(void*)>::type __buf_;
1291 __base* __f_;
1292
1293public:
1294 typedef _Rp result_type;
1295
1296 // 20.7.16.2.1, construct/copy/destroy:
1297 _LIBCPP_INLINE_VISIBILITY explicit function() : __f_(0) {}
1298 _LIBCPP_INLINE_VISIBILITY function(nullptr_t) : __f_(0) {}
1299 function(const function&);
1300 template<class _Fp>
1301 function(_Fp,
1302 typename enable_if<!is_integral<_Fp>::value>::type* = 0);
1303
1304 template<class _Alloc>
1305 _LIBCPP_INLINE_VISIBILITY
1306 function(allocator_arg_t, const _Alloc&) : __f_(0) {}
1307 template<class _Alloc>
1308 _LIBCPP_INLINE_VISIBILITY
1309 function(allocator_arg_t, const _Alloc&, nullptr_t) : __f_(0) {}
1310 template<class _Alloc>
1311 function(allocator_arg_t, const _Alloc&, const function&);
1312 template<class _Fp, class _Alloc>
1313 function(allocator_arg_t, const _Alloc& __a, _Fp __f,
1314 typename enable_if<!is_integral<_Fp>::value>::type* = 0);
1315
1316 function& operator=(const function&);
1317 function& operator=(nullptr_t);
1318 template<class _Fp>
1319 typename enable_if
1320 <
1321 !is_integral<_Fp>::value,
1322 function&
1323 >::type
1324 operator=(_Fp);
1325
1326 ~function();
1327
1328 // 20.7.16.2.2, function modifiers:
1329 void swap(function&);
1330 template<class _Fp, class _Alloc>
1331 _LIBCPP_INLINE_VISIBILITY
1332 void assign(_Fp __f, const _Alloc& __a)
1333 {function(allocator_arg, __a, __f).swap(*this);}
1334
1335 // 20.7.16.2.3, function capacity:
1336 _LIBCPP_INLINE_VISIBILITY operator bool() const {return __f_;}
1337
1338private:
1339 // deleted overloads close possible hole in the type system
1340 template<class _R2, class _B0, class _B1, class _B2>
1341 bool operator==(const function<_R2(_B0, _B1, _B2)>&) const;// = delete;
1342 template<class _R2, class _B0, class _B1, class _B2>
1343 bool operator!=(const function<_R2(_B0, _B1, _B2)>&) const;// = delete;
1344public:
1345 // 20.7.16.2.4, function invocation:
1346 _Rp operator()(_A0, _A1, _A2) const;
1347
1348#ifndef _LIBCPP_NO_RTTI
1349 // 20.7.16.2.5, function target access:
1350 const std::type_info& target_type() const;
1351 template <typename _Tp> _Tp* target();
1352 template <typename _Tp> const _Tp* target() const;
1353#endif // _LIBCPP_NO_RTTI
1354};
1355
1356template<class _Rp, class _A0, class _A1, class _A2>
1357function<_Rp(_A0, _A1, _A2)>::function(const function& __f)
1358{
1359 if (__f.__f_ == 0)
1360 __f_ = 0;
1361 else if (__f.__f_ == (const __base*)&__f.__buf_)
1362 {
1363 __f_ = (__base*)&__buf_;
1364 __f.__f_->__clone(__f_);
1365 }
1366 else
1367 __f_ = __f.__f_->__clone();
1368}
1369
1370template<class _Rp, class _A0, class _A1, class _A2>
1371template<class _Alloc>
1372function<_Rp(_A0, _A1, _A2)>::function(allocator_arg_t, const _Alloc&,
1373 const function& __f)
1374{
1375 if (__f.__f_ == 0)
1376 __f_ = 0;
1377 else if (__f.__f_ == (const __base*)&__f.__buf_)
1378 {
1379 __f_ = (__base*)&__buf_;
1380 __f.__f_->__clone(__f_);
1381 }
1382 else
1383 __f_ = __f.__f_->__clone();
1384}
1385
1386template<class _Rp, class _A0, class _A1, class _A2>
1387template <class _Fp>
1388function<_Rp(_A0, _A1, _A2)>::function(_Fp __f,
1389 typename enable_if<!is_integral<_Fp>::value>::type*)
1390 : __f_(0)
1391{
1392 if (__function::__not_null(__f))
1393 {
1394 typedef __function::__func<_Fp, allocator<_Fp>, _Rp(_A0, _A1, _A2)> _FF;
1395 if (sizeof(_FF) <= sizeof(__buf_))
1396 {
1397 __f_ = (__base*)&__buf_;
1398 ::new (__f_) _FF(__f);
1399 }
1400 else
1401 {
1402 typedef allocator<_FF> _Ap;
1403 _Ap __a;
1404 typedef __allocator_destructor<_Ap> _Dp;
1405 unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
1406 ::new (__hold.get()) _FF(__f, allocator<_Fp>(__a));
1407 __f_ = __hold.release();
1408 }
1409 }
1410}
1411
1412template<class _Rp, class _A0, class _A1, class _A2>
1413template <class _Fp, class _Alloc>
1414function<_Rp(_A0, _A1, _A2)>::function(allocator_arg_t, const _Alloc& __a0, _Fp __f,
1415 typename enable_if<!is_integral<_Fp>::value>::type*)
1416 : __f_(0)
1417{
1418 typedef allocator_traits<_Alloc> __alloc_traits;
1419 if (__function::__not_null(__f))
1420 {
1421 typedef __function::__func<_Fp, _Alloc, _Rp(_A0, _A1, _A2)> _FF;
1422 if (sizeof(_FF) <= sizeof(__buf_))
1423 {
1424 __f_ = (__base*)&__buf_;
1425 ::new (__f_) _FF(__f, __a0);
1426 }
1427 else
1428 {
1429 typedef typename __rebind_alloc_helper<__alloc_traits, _FF>::type _Ap;
1430 _Ap __a(__a0);
1431 typedef __allocator_destructor<_Ap> _Dp;
1432 unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
1433 ::new (__hold.get()) _FF(__f, _Alloc(__a));
1434 __f_ = __hold.release();
1435 }
1436 }
1437}
1438
1439template<class _Rp, class _A0, class _A1, class _A2>
1440function<_Rp(_A0, _A1, _A2)>&
1441function<_Rp(_A0, _A1, _A2)>::operator=(const function& __f)
1442{
1443 if (__f)
1444 function(__f).swap(*this);
1445 else
1446 *this = nullptr;
1447 return *this;
1448}
1449
1450template<class _Rp, class _A0, class _A1, class _A2>
1451function<_Rp(_A0, _A1, _A2)>&
1452function<_Rp(_A0, _A1, _A2)>::operator=(nullptr_t)
1453{
1454 __base* __t = __f_;
1455 __f_ = 0;
1456 if (__t == (__base*)&__buf_)
1457 __t->destroy();
1458 else if (__t)
1459 __t->destroy_deallocate();
1460 return *this;
1461}
1462
1463template<class _Rp, class _A0, class _A1, class _A2>
1464template <class _Fp>
1465typename enable_if
1466<
1467 !is_integral<_Fp>::value,
1468 function<_Rp(_A0, _A1, _A2)>&
1469>::type
1470function<_Rp(_A0, _A1, _A2)>::operator=(_Fp __f)
1471{
1472 function(_VSTD::move(__f)).swap(*this);
1473 return *this;
1474}
1475
1476template<class _Rp, class _A0, class _A1, class _A2>
1477function<_Rp(_A0, _A1, _A2)>::~function()
1478{
1479 if (__f_ == (__base*)&__buf_)
1480 __f_->destroy();
1481 else if (__f_)
1482 __f_->destroy_deallocate();
1483}
1484
1485template<class _Rp, class _A0, class _A1, class _A2>
1486void
1487function<_Rp(_A0, _A1, _A2)>::swap(function& __f)
1488{
1489 if (_VSTD::addressof(__f) == this)
1490 return;
1491 if (__f_ == (__base*)&__buf_ && __f.__f_ == (__base*)&__f.__buf_)
1492 {
1493 typename aligned_storage<sizeof(__buf_)>::type __tempbuf;
1494 __base* __t = (__base*)&__tempbuf;
1495 __f_->__clone(__t);
1496 __f_->destroy();
1497 __f_ = 0;
1498 __f.__f_->__clone((__base*)&__buf_);
1499 __f.__f_->destroy();
1500 __f.__f_ = 0;
1501 __f_ = (__base*)&__buf_;
1502 __t->__clone((__base*)&__f.__buf_);
1503 __t->destroy();
1504 __f.__f_ = (__base*)&__f.__buf_;
1505 }
1506 else if (__f_ == (__base*)&__buf_)
1507 {
1508 __f_->__clone((__base*)&__f.__buf_);
1509 __f_->destroy();
1510 __f_ = __f.__f_;
1511 __f.__f_ = (__base*)&__f.__buf_;
1512 }
1513 else if (__f.__f_ == (__base*)&__f.__buf_)
1514 {
1515 __f.__f_->__clone((__base*)&__buf_);
1516 __f.__f_->destroy();
1517 __f.__f_ = __f_;
1518 __f_ = (__base*)&__buf_;
1519 }
1520 else
1521 _VSTD::swap(__f_, __f.__f_);
1522}
1523
1524template<class _Rp, class _A0, class _A1, class _A2>
1525_Rp
1526function<_Rp(_A0, _A1, _A2)>::operator()(_A0 __a0, _A1 __a1, _A2 __a2) const
1527{
1528 if (__f_ == 0)
1529 __throw_bad_function_call();
1530 return (*__f_)(__a0, __a1, __a2);
1531}
1532
1533#ifndef _LIBCPP_NO_RTTI
1534
1535template<class _Rp, class _A0, class _A1, class _A2>
1536const std::type_info&
1537function<_Rp(_A0, _A1, _A2)>::target_type() const
1538{
1539 if (__f_ == 0)
1540 return typeid(void);
1541 return __f_->target_type();
1542}
1543
1544template<class _Rp, class _A0, class _A1, class _A2>
1545template <typename _Tp>
1546_Tp*
1547function<_Rp(_A0, _A1, _A2)>::target()
1548{
1549 if (__f_ == 0)
1550 return (_Tp*)0;
1551 return (_Tp*) const_cast<void *>(__f_->target(typeid(_Tp)));
1552}
1553
1554template<class _Rp, class _A0, class _A1, class _A2>
1555template <typename _Tp>
1556const _Tp*
1557function<_Rp(_A0, _A1, _A2)>::target() const
1558{
1559 if (__f_ == 0)
1560 return (const _Tp*)0;
1561 return (const _Tp*)__f_->target(typeid(_Tp));
1562}
1563
1564#endif // _LIBCPP_NO_RTTI
1565
1566template <class _Fp>
1567inline _LIBCPP_INLINE_VISIBILITY
1568bool
1569operator==(const function<_Fp>& __f, nullptr_t) {return !__f;}
1570
1571template <class _Fp>
1572inline _LIBCPP_INLINE_VISIBILITY
1573bool
1574operator==(nullptr_t, const function<_Fp>& __f) {return !__f;}
1575
1576template <class _Fp>
1577inline _LIBCPP_INLINE_VISIBILITY
1578bool
1579operator!=(const function<_Fp>& __f, nullptr_t) {return (bool)__f;}
1580
1581template <class _Fp>
1582inline _LIBCPP_INLINE_VISIBILITY
1583bool
1584operator!=(nullptr_t, const function<_Fp>& __f) {return (bool)__f;}
1585
1586template <class _Fp>
1587inline _LIBCPP_INLINE_VISIBILITY
1588void
1589swap(function<_Fp>& __x, function<_Fp>& __y)
1590{return __x.swap(__y);}
1591
1592#endif // _LIBCPP_FUNCTIONAL_03