blob: 25d8ab93e93156db45d3273eb1c338c08b9c8739 [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
16#pragma GCC system_header
17
18template <class _Tp>
19class __mem_fn
20 : public __weak_result_type<_Tp>
21{
22public:
23 // types
24 typedef _Tp type;
25private:
26 type __f_;
27
28public:
29 _LIBCPP_INLINE_VISIBILITY __mem_fn(type __f) : __f_(__f) {}
30
31 // invoke
32
33 typename __invoke_return<type>::type
34 operator() ()
35 {
36 return __invoke(__f_);
37 }
38
39 template <class _A0>
40 typename __invoke_return0<type, _A0>::type
41 operator() (_A0& __a0)
42 {
43 return __invoke(__f_, __a0);
44 }
45
46 template <class _A0, class _A1>
47 typename __invoke_return1<type, _A0, _A1>::type
48 operator() (_A0& __a0, _A1& __a1)
49 {
50 return __invoke(__f_, __a0, __a1);
51 }
52
53 template <class _A0, class _A1, class _A2>
54 typename __invoke_return2<type, _A0, _A1, _A2>::type
55 operator() (_A0& __a0, _A1& __a1, _A2& __a2)
56 {
57 return __invoke(__f_, __a0, __a1, __a2);
58 }
59};
60
61template<class _R, class _T>
62inline _LIBCPP_INLINE_VISIBILITY
63__mem_fn<_R _T::*>
64mem_fn(_R _T::* __pm)
65{
66 return __mem_fn<_R _T::*>(__pm);
67}
68
69template<class _R, class _T>
70inline _LIBCPP_INLINE_VISIBILITY
71__mem_fn<_R (_T::*)()>
72mem_fn(_R (_T::* __pm)())
73{
74 return __mem_fn<_R (_T::*)()>(__pm);
75}
76
77template<class _R, class _T, class _A0>
78inline _LIBCPP_INLINE_VISIBILITY
79__mem_fn<_R (_T::*)(_A0)>
80mem_fn(_R (_T::* __pm)(_A0))
81{
82 return __mem_fn<_R (_T::*)(_A0)>(__pm);
83}
84
85template<class _R, class _T, class _A0, class _A1>
86inline _LIBCPP_INLINE_VISIBILITY
87__mem_fn<_R (_T::*)(_A0, _A1)>
88mem_fn(_R (_T::* __pm)(_A0, _A1))
89{
90 return __mem_fn<_R (_T::*)(_A0, _A1)>(__pm);
91}
92
93template<class _R, class _T, class _A0, class _A1, class _A2>
94inline _LIBCPP_INLINE_VISIBILITY
95__mem_fn<_R (_T::*)(_A0, _A1, _A2)>
96mem_fn(_R (_T::* __pm)(_A0, _A1, _A2))
97{
98 return __mem_fn<_R (_T::*)(_A0, _A1, _A2)>(__pm);
99}
100
101template<class _R, class _T>
102inline _LIBCPP_INLINE_VISIBILITY
103__mem_fn<_R (_T::*)()>
104mem_fn(_R (_T::* __pm)() const)
105{
106 return __mem_fn<_R (_T::*)()>(__pm);
107}
108
109template<class _R, class _T, class _A0>
110inline _LIBCPP_INLINE_VISIBILITY
111__mem_fn<_R (_T::*)(_A0)>
112mem_fn(_R (_T::* __pm)(_A0) const)
113{
114 return __mem_fn<_R (_T::*)(_A0)>(__pm);
115}
116
117template<class _R, class _T, class _A0, class _A1>
118inline _LIBCPP_INLINE_VISIBILITY
119__mem_fn<_R (_T::*)(_A0, _A1)>
120mem_fn(_R (_T::* __pm)(_A0, _A1) const)
121{
122 return __mem_fn<_R (_T::*)(_A0, _A1)>(__pm);
123}
124
125template<class _R, class _T, class _A0, class _A1, class _A2>
126inline _LIBCPP_INLINE_VISIBILITY
127__mem_fn<_R (_T::*)(_A0, _A1, _A2)>
128mem_fn(_R (_T::* __pm)(_A0, _A1, _A2) const)
129{
130 return __mem_fn<_R (_T::*)(_A0, _A1, _A2)>(__pm);
131}
132
133template<class _R, class _T>
134inline _LIBCPP_INLINE_VISIBILITY
135__mem_fn<_R (_T::*)()>
136mem_fn(_R (_T::* __pm)() volatile)
137{
138 return __mem_fn<_R (_T::*)()>(__pm);
139}
140
141template<class _R, class _T, class _A0>
142inline _LIBCPP_INLINE_VISIBILITY
143__mem_fn<_R (_T::*)(_A0)>
144mem_fn(_R (_T::* __pm)(_A0) volatile)
145{
146 return __mem_fn<_R (_T::*)(_A0)>(__pm);
147}
148
149template<class _R, class _T, class _A0, class _A1>
150inline _LIBCPP_INLINE_VISIBILITY
151__mem_fn<_R (_T::*)(_A0, _A1)>
152mem_fn(_R (_T::* __pm)(_A0, _A1) volatile)
153{
154 return __mem_fn<_R (_T::*)(_A0, _A1)>(__pm);
155}
156
157template<class _R, class _T, class _A0, class _A1, class _A2>
158inline _LIBCPP_INLINE_VISIBILITY
159__mem_fn<_R (_T::*)(_A0, _A1, _A2)>
160mem_fn(_R (_T::* __pm)(_A0, _A1, _A2) volatile)
161{
162 return __mem_fn<_R (_T::*)(_A0, _A1, _A2)>(__pm);
163}
164
165template<class _R, class _T>
166inline _LIBCPP_INLINE_VISIBILITY
167__mem_fn<_R (_T::*)()>
168mem_fn(_R (_T::* __pm)() const volatile)
169{
170 return __mem_fn<_R (_T::*)()>(__pm);
171}
172
173template<class _R, class _T, class _A0>
174inline _LIBCPP_INLINE_VISIBILITY
175__mem_fn<_R (_T::*)(_A0)>
176mem_fn(_R (_T::* __pm)(_A0) const volatile)
177{
178 return __mem_fn<_R (_T::*)(_A0)>(__pm);
179}
180
181template<class _R, class _T, class _A0, class _A1>
182inline _LIBCPP_INLINE_VISIBILITY
183__mem_fn<_R (_T::*)(_A0, _A1)>
184mem_fn(_R (_T::* __pm)(_A0, _A1) const volatile)
185{
186 return __mem_fn<_R (_T::*)(_A0, _A1)>(__pm);
187}
188
189template<class _R, class _T, class _A0, class _A1, class _A2>
190inline _LIBCPP_INLINE_VISIBILITY
191__mem_fn<_R (_T::*)(_A0, _A1, _A2)>
192mem_fn(_R (_T::* __pm)(_A0, _A1, _A2) const volatile)
193{
194 return __mem_fn<_R (_T::*)(_A0, _A1, _A2)>(__pm);
195}
196
197// bad_function_call
198
Howard Hinnant99acc502010-09-21 17:32:39 +0000199class _LIBCPP_EXCEPTION_ABI bad_function_call
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000200 : public exception
201{
202};
203
Howard Hinnant99acc502010-09-21 17:32:39 +0000204template<class _Fp> class _LIBCPP_VISIBLE function; // undefined
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000205
206namespace __function
207{
208
209template<class _F>
210struct __maybe_derive_from_unary_function
211{
212};
213
214template<class _R, class _A1>
215struct __maybe_derive_from_unary_function<_R(_A1)>
216 : public unary_function<_A1, _R>
217{
218};
219
220template<class _F>
221struct __maybe_derive_from_binary_function
222{
223};
224
225template<class _R, class _A1, class _A2>
226struct __maybe_derive_from_binary_function<_R(_A1, _A2)>
227 : public binary_function<_A1, _A2, _R>
228{
229};
230
231template<class _Fp> class __base;
232
233template<class _R>
234class __base<_R()>
235{
236 __base(const __base&);
237 __base& operator=(const __base&);
238public:
239 __base() {}
240 virtual ~__base() {}
241 virtual __base* __clone() const = 0;
242 virtual void __clone(__base*) const = 0;
243 virtual void destroy() = 0;
244 virtual void destroy_deallocate() = 0;
245 virtual _R operator()() = 0;
Howard Hinnantd4444702010-08-11 17:04:31 +0000246#ifndef _LIBCPP_NO_RTTI
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000247 virtual const void* target(const type_info&) const = 0;
248 virtual const std::type_info& target_type() const = 0;
Howard Hinnant324bb032010-08-22 00:02:43 +0000249#endif // _LIBCPP_NO_RTTI
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000250};
251
252template<class _R, class _A0>
253class __base<_R(_A0)>
254{
255 __base(const __base&);
256 __base& operator=(const __base&);
257public:
258 __base() {}
259 virtual ~__base() {}
260 virtual __base* __clone() const = 0;
261 virtual void __clone(__base*) const = 0;
262 virtual void destroy() = 0;
263 virtual void destroy_deallocate() = 0;
264 virtual _R operator()(_A0) = 0;
Howard Hinnantd4444702010-08-11 17:04:31 +0000265#ifndef _LIBCPP_NO_RTTI
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000266 virtual const void* target(const type_info&) const = 0;
267 virtual const std::type_info& target_type() const = 0;
Howard Hinnant324bb032010-08-22 00:02:43 +0000268#endif // _LIBCPP_NO_RTTI
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000269};
270
271template<class _R, class _A0, class _A1>
272class __base<_R(_A0, _A1)>
273{
274 __base(const __base&);
275 __base& operator=(const __base&);
276public:
277 __base() {}
278 virtual ~__base() {}
279 virtual __base* __clone() const = 0;
280 virtual void __clone(__base*) const = 0;
281 virtual void destroy() = 0;
282 virtual void destroy_deallocate() = 0;
283 virtual _R operator()(_A0, _A1) = 0;
Howard Hinnantd4444702010-08-11 17:04:31 +0000284#ifndef _LIBCPP_NO_RTTI
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000285 virtual const void* target(const type_info&) const = 0;
286 virtual const std::type_info& target_type() const = 0;
Howard Hinnant324bb032010-08-22 00:02:43 +0000287#endif // _LIBCPP_NO_RTTI
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000288};
289
290template<class _R, class _A0, class _A1, class _A2>
291class __base<_R(_A0, _A1, _A2)>
292{
293 __base(const __base&);
294 __base& operator=(const __base&);
295public:
296 __base() {}
297 virtual ~__base() {}
298 virtual __base* __clone() const = 0;
299 virtual void __clone(__base*) const = 0;
300 virtual void destroy() = 0;
301 virtual void destroy_deallocate() = 0;
302 virtual _R operator()(_A0, _A1, _A2) = 0;
Howard Hinnantd4444702010-08-11 17:04:31 +0000303#ifndef _LIBCPP_NO_RTTI
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000304 virtual const void* target(const type_info&) const = 0;
305 virtual const std::type_info& target_type() const = 0;
Howard Hinnant324bb032010-08-22 00:02:43 +0000306#endif // _LIBCPP_NO_RTTI
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000307};
308
309template<class _FD, class _Alloc, class _FB> class __func;
310
311template<class _F, class _Alloc, class _R>
312class __func<_F, _Alloc, _R()>
313 : public __base<_R()>
314{
315 __compressed_pair<_F, _Alloc> __f_;
316public:
317 explicit __func(_F __f) : __f_(_STD::move(__f)) {}
318 explicit __func(_F __f, _Alloc __a) : __f_(_STD::move(__f), _STD::move(__a)) {}
319 virtual __base<_R()>* __clone() const;
320 virtual void __clone(__base<_R()>*) const;
321 virtual void destroy();
322 virtual void destroy_deallocate();
323 virtual _R operator()();
Howard Hinnantd4444702010-08-11 17:04:31 +0000324#ifndef _LIBCPP_NO_RTTI
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000325 virtual const void* target(const type_info&) const;
326 virtual const std::type_info& target_type() const;
Howard Hinnant324bb032010-08-22 00:02:43 +0000327#endif // _LIBCPP_NO_RTTI
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000328};
329
330template<class _F, class _Alloc, class _R>
331__base<_R()>*
332__func<_F, _Alloc, _R()>::__clone() const
333{
334 typedef typename _Alloc::template rebind<__func>::other _A;
335 _A __a(__f_.second());
336 typedef __allocator_destructor<_A> _D;
337 unique_ptr<__func, _D> __hold(__a.allocate(1), _D(__a, 1));
338 ::new (__hold.get()) __func(__f_.first(), _Alloc(__a));
339 return __hold.release();
340}
341
342template<class _F, class _Alloc, class _R>
343void
344__func<_F, _Alloc, _R()>::__clone(__base<_R()>* __p) const
345{
346 ::new (__p) __func(__f_.first(), __f_.second());
347}
348
349template<class _F, class _Alloc, class _R>
350void
351__func<_F, _Alloc, _R()>::destroy()
352{
353 __f_.~__compressed_pair<_F, _Alloc>();
354}
355
356template<class _F, class _Alloc, class _R>
357void
358__func<_F, _Alloc, _R()>::destroy_deallocate()
359{
360 typedef typename _Alloc::template rebind<__func>::other _A;
361 _A __a(__f_.second());
362 __f_.~__compressed_pair<_F, _Alloc>();
363 __a.deallocate(this, 1);
364}
365
366template<class _F, class _Alloc, class _R>
367_R
368__func<_F, _Alloc, _R()>::operator()()
369{
Howard Hinnant72552802010-08-20 19:36:46 +0000370 return __invoke(__f_.first());
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000371}
372
Howard Hinnantd4444702010-08-11 17:04:31 +0000373#ifndef _LIBCPP_NO_RTTI
374
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000375template<class _F, class _Alloc, class _R>
376const void*
377__func<_F, _Alloc, _R()>::target(const type_info& __ti) const
378{
379 if (__ti == typeid(_F))
380 return &__f_.first();
381 return (const void*)0;
382}
383
384template<class _F, class _Alloc, class _R>
385const std::type_info&
386__func<_F, _Alloc, _R()>::target_type() const
387{
388 return typeid(_F);
389}
390
Howard Hinnant324bb032010-08-22 00:02:43 +0000391#endif // _LIBCPP_NO_RTTI
Howard Hinnantd4444702010-08-11 17:04:31 +0000392
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000393template<class _F, class _Alloc, class _R, class _A0>
394class __func<_F, _Alloc, _R(_A0)>
395 : public __base<_R(_A0)>
396{
397 __compressed_pair<_F, _Alloc> __f_;
398public:
Howard Hinnant99acc502010-09-21 17:32:39 +0000399 _LIBCPP_INLINE_VISIBILITY explicit __func(_F __f) : __f_(_STD::move(__f)) {}
400 _LIBCPP_INLINE_VISIBILITY explicit __func(_F __f, _Alloc __a)
401 : __f_(_STD::move(__f), _STD::move(__a)) {}
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000402 virtual __base<_R(_A0)>* __clone() const;
403 virtual void __clone(__base<_R(_A0)>*) const;
404 virtual void destroy();
405 virtual void destroy_deallocate();
406 virtual _R operator()(_A0);
Howard Hinnantd4444702010-08-11 17:04:31 +0000407#ifndef _LIBCPP_NO_RTTI
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000408 virtual const void* target(const type_info&) const;
409 virtual const std::type_info& target_type() const;
Howard Hinnant324bb032010-08-22 00:02:43 +0000410#endif // _LIBCPP_NO_RTTI
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000411};
412
413template<class _F, class _Alloc, class _R, class _A0>
414__base<_R(_A0)>*
415__func<_F, _Alloc, _R(_A0)>::__clone() const
416{
417 typedef typename _Alloc::template rebind<__func>::other _A;
418 _A __a(__f_.second());
419 typedef __allocator_destructor<_A> _D;
420 unique_ptr<__func, _D> __hold(__a.allocate(1), _D(__a, 1));
421 ::new (__hold.get()) __func(__f_.first(), _Alloc(__a));
422 return __hold.release();
423}
424
425template<class _F, class _Alloc, class _R, class _A0>
426void
427__func<_F, _Alloc, _R(_A0)>::__clone(__base<_R(_A0)>* __p) const
428{
429 ::new (__p) __func(__f_.first(), __f_.second());
430}
431
432template<class _F, class _Alloc, class _R, class _A0>
433void
434__func<_F, _Alloc, _R(_A0)>::destroy()
435{
436 __f_.~__compressed_pair<_F, _Alloc>();
437}
438
439template<class _F, class _Alloc, class _R, class _A0>
440void
441__func<_F, _Alloc, _R(_A0)>::destroy_deallocate()
442{
443 typedef typename _Alloc::template rebind<__func>::other _A;
444 _A __a(__f_.second());
445 __f_.~__compressed_pair<_F, _Alloc>();
446 __a.deallocate(this, 1);
447}
448
449template<class _F, class _Alloc, class _R, class _A0>
450_R
451__func<_F, _Alloc, _R(_A0)>::operator()(_A0 __a0)
452{
453 return __invoke(__f_.first(), __a0);
454}
455
Howard Hinnantd4444702010-08-11 17:04:31 +0000456#ifndef _LIBCPP_NO_RTTI
457
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000458template<class _F, class _Alloc, class _R, class _A0>
459const void*
460__func<_F, _Alloc, _R(_A0)>::target(const type_info& __ti) const
461{
462 if (__ti == typeid(_F))
463 return &__f_.first();
464 return (const void*)0;
465}
466
467template<class _F, class _Alloc, class _R, class _A0>
468const std::type_info&
469__func<_F, _Alloc, _R(_A0)>::target_type() const
470{
471 return typeid(_F);
472}
473
Howard Hinnant324bb032010-08-22 00:02:43 +0000474#endif // _LIBCPP_NO_RTTI
Howard Hinnantd4444702010-08-11 17:04:31 +0000475
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000476template<class _F, class _Alloc, class _R, class _A0, class _A1>
477class __func<_F, _Alloc, _R(_A0, _A1)>
478 : public __base<_R(_A0, _A1)>
479{
480 __compressed_pair<_F, _Alloc> __f_;
481public:
Howard Hinnant99acc502010-09-21 17:32:39 +0000482 _LIBCPP_INLINE_VISIBILITY explicit __func(_F __f) : __f_(_STD::move(__f)) {}
483 _LIBCPP_INLINE_VISIBILITY explicit __func(_F __f, _Alloc __a)
484 : __f_(_STD::move(__f), _STD::move(__a)) {}
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000485 virtual __base<_R(_A0, _A1)>* __clone() const;
486 virtual void __clone(__base<_R(_A0, _A1)>*) const;
487 virtual void destroy();
488 virtual void destroy_deallocate();
489 virtual _R operator()(_A0, _A1);
Howard Hinnantd4444702010-08-11 17:04:31 +0000490#ifndef _LIBCPP_NO_RTTI
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000491 virtual const void* target(const type_info&) const;
492 virtual const std::type_info& target_type() const;
Howard Hinnant324bb032010-08-22 00:02:43 +0000493#endif // _LIBCPP_NO_RTTI
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000494};
495
496template<class _F, class _Alloc, class _R, class _A0, class _A1>
497__base<_R(_A0, _A1)>*
498__func<_F, _Alloc, _R(_A0, _A1)>::__clone() const
499{
500 typedef typename _Alloc::template rebind<__func>::other _A;
501 _A __a(__f_.second());
502 typedef __allocator_destructor<_A> _D;
503 unique_ptr<__func, _D> __hold(__a.allocate(1), _D(__a, 1));
504 ::new (__hold.get()) __func(__f_.first(), _Alloc(__a));
505 return __hold.release();
506}
507
508template<class _F, class _Alloc, class _R, class _A0, class _A1>
509void
510__func<_F, _Alloc, _R(_A0, _A1)>::__clone(__base<_R(_A0, _A1)>* __p) const
511{
512 ::new (__p) __func(__f_.first(), __f_.second());
513}
514
515template<class _F, class _Alloc, class _R, class _A0, class _A1>
516void
517__func<_F, _Alloc, _R(_A0, _A1)>::destroy()
518{
519 __f_.~__compressed_pair<_F, _Alloc>();
520}
521
522template<class _F, class _Alloc, class _R, class _A0, class _A1>
523void
524__func<_F, _Alloc, _R(_A0, _A1)>::destroy_deallocate()
525{
526 typedef typename _Alloc::template rebind<__func>::other _A;
527 _A __a(__f_.second());
528 __f_.~__compressed_pair<_F, _Alloc>();
529 __a.deallocate(this, 1);
530}
531
532template<class _F, class _Alloc, class _R, class _A0, class _A1>
533_R
534__func<_F, _Alloc, _R(_A0, _A1)>::operator()(_A0 __a0, _A1 __a1)
535{
536 return __invoke(__f_.first(), __a0, __a1);
537}
538
Howard Hinnantd4444702010-08-11 17:04:31 +0000539#ifndef _LIBCPP_NO_RTTI
540
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000541template<class _F, class _Alloc, class _R, class _A0, class _A1>
542const void*
543__func<_F, _Alloc, _R(_A0, _A1)>::target(const type_info& __ti) const
544{
545 if (__ti == typeid(_F))
546 return &__f_.first();
547 return (const void*)0;
548}
549
550template<class _F, class _Alloc, class _R, class _A0, class _A1>
551const std::type_info&
552__func<_F, _Alloc, _R(_A0, _A1)>::target_type() const
553{
554 return typeid(_F);
555}
556
Howard Hinnant324bb032010-08-22 00:02:43 +0000557#endif // _LIBCPP_NO_RTTI
Howard Hinnantd4444702010-08-11 17:04:31 +0000558
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000559template<class _F, class _Alloc, class _R, class _A0, class _A1, class _A2>
560class __func<_F, _Alloc, _R(_A0, _A1, _A2)>
561 : public __base<_R(_A0, _A1, _A2)>
562{
563 __compressed_pair<_F, _Alloc> __f_;
564public:
Howard Hinnant99acc502010-09-21 17:32:39 +0000565 _LIBCPP_INLINE_VISIBILITY explicit __func(_F __f) : __f_(_STD::move(__f)) {}
566 _LIBCPP_INLINE_VISIBILITY explicit __func(_F __f, _Alloc __a)
567 : __f_(_STD::move(__f), _STD::move(__a)) {}
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000568 virtual __base<_R(_A0, _A1, _A2)>* __clone() const;
569 virtual void __clone(__base<_R(_A0, _A1, _A2)>*) const;
570 virtual void destroy();
571 virtual void destroy_deallocate();
572 virtual _R operator()(_A0, _A1, _A2);
Howard Hinnantd4444702010-08-11 17:04:31 +0000573#ifndef _LIBCPP_NO_RTTI
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000574 virtual const void* target(const type_info&) const;
575 virtual const std::type_info& target_type() const;
Howard Hinnant324bb032010-08-22 00:02:43 +0000576#endif // _LIBCPP_NO_RTTI
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000577};
578
579template<class _F, class _Alloc, class _R, class _A0, class _A1, class _A2>
580__base<_R(_A0, _A1, _A2)>*
581__func<_F, _Alloc, _R(_A0, _A1, _A2)>::__clone() const
582{
583 typedef typename _Alloc::template rebind<__func>::other _A;
584 _A __a(__f_.second());
585 typedef __allocator_destructor<_A> _D;
586 unique_ptr<__func, _D> __hold(__a.allocate(1), _D(__a, 1));
587 ::new (__hold.get()) __func(__f_.first(), _Alloc(__a));
588 return __hold.release();
589}
590
591template<class _F, class _Alloc, class _R, class _A0, class _A1, class _A2>
592void
593__func<_F, _Alloc, _R(_A0, _A1, _A2)>::__clone(__base<_R(_A0, _A1, _A2)>* __p) const
594{
595 ::new (__p) __func(__f_.first(), __f_.second());
596}
597
598template<class _F, class _Alloc, class _R, class _A0, class _A1, class _A2>
599void
600__func<_F, _Alloc, _R(_A0, _A1, _A2)>::destroy()
601{
602 __f_.~__compressed_pair<_F, _Alloc>();
603}
604
605template<class _F, class _Alloc, class _R, class _A0, class _A1, class _A2>
606void
607__func<_F, _Alloc, _R(_A0, _A1, _A2)>::destroy_deallocate()
608{
609 typedef typename _Alloc::template rebind<__func>::other _A;
610 _A __a(__f_.second());
611 __f_.~__compressed_pair<_F, _Alloc>();
612 __a.deallocate(this, 1);
613}
614
615template<class _F, class _Alloc, class _R, class _A0, class _A1, class _A2>
616_R
617__func<_F, _Alloc, _R(_A0, _A1, _A2)>::operator()(_A0 __a0, _A1 __a1, _A2 __a2)
618{
619 return __invoke(__f_.first(), __a0, __a1, __a2);
620}
621
Howard Hinnantd4444702010-08-11 17:04:31 +0000622#ifndef _LIBCPP_NO_RTTI
623
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000624template<class _F, class _Alloc, class _R, class _A0, class _A1, class _A2>
625const void*
626__func<_F, _Alloc, _R(_A0, _A1, _A2)>::target(const type_info& __ti) const
627{
628 if (__ti == typeid(_F))
629 return &__f_.first();
630 return (const void*)0;
631}
632
633template<class _F, class _Alloc, class _R, class _A0, class _A1, class _A2>
634const std::type_info&
635__func<_F, _Alloc, _R(_A0, _A1, _A2)>::target_type() const
636{
637 return typeid(_F);
638}
639
Howard Hinnant324bb032010-08-22 00:02:43 +0000640#endif // _LIBCPP_NO_RTTI
Howard Hinnantd4444702010-08-11 17:04:31 +0000641
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000642} // __function
643
644template<class _R>
Howard Hinnant99acc502010-09-21 17:32:39 +0000645class _LIBCPP_VISIBLE function<_R()>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000646{
647 typedef __function::__base<_R()> __base;
648 aligned_storage<3*sizeof(void*)>::type __buf_;
649 __base* __f_;
650
651 template <class _F>
652 static bool __not_null(const _F&) {return true;}
653 template <class _R2>
654 static bool __not_null(const function<_R()>& __p) {return __p;}
655public:
656 typedef _R result_type;
657
658 // 20.7.16.2.1, construct/copy/destroy:
Howard Hinnant99acc502010-09-21 17:32:39 +0000659 _LIBCPP_INLINE_VISIBILITY explicit function() : __f_(0) {}
660 _LIBCPP_INLINE_VISIBILITY function(nullptr_t) : __f_(0) {}
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000661 function(const function&);
662 template<class _F>
663 function(_F,
664 typename enable_if<!is_integral<_F>::value>::type* = 0);
665
Howard Hinnant72552802010-08-20 19:36:46 +0000666 template<class _Alloc>
Howard Hinnant99acc502010-09-21 17:32:39 +0000667 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant72552802010-08-20 19:36:46 +0000668 function(allocator_arg_t, const _Alloc&) : __f_(0) {}
669 template<class _Alloc>
Howard Hinnant99acc502010-09-21 17:32:39 +0000670 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant72552802010-08-20 19:36:46 +0000671 function(allocator_arg_t, const _Alloc&, nullptr_t) : __f_(0) {}
672 template<class _Alloc>
673 function(allocator_arg_t, const _Alloc&, const function&);
674 template<class _F, class _Alloc>
675 function(allocator_arg_t, const _Alloc& __a, _F __f,
676 typename enable_if<!is_integral<_F>::value>::type* = 0);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000677
678 function& operator=(const function&);
679 function& operator=(nullptr_t);
680 template<class _F>
681 typename enable_if
682 <
683 !is_integral<_F>::value,
684 function&
685 >::type
686 operator=(_F);
687
688 ~function();
689
690 // 20.7.16.2.2, function modifiers:
691 void swap(function&);
Howard Hinnant72552802010-08-20 19:36:46 +0000692 template<class _F, class _Alloc>
Howard Hinnant99acc502010-09-21 17:32:39 +0000693 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant72552802010-08-20 19:36:46 +0000694 void assign(_F __f, const _Alloc& __a)
695 {function(allocator_arg, __a, __f).swap(*this);}
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000696
697 // 20.7.16.2.3, function capacity:
Howard Hinnant99acc502010-09-21 17:32:39 +0000698 _LIBCPP_INLINE_VISIBILITY operator bool() const {return __f_;}
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000699
700private:
701 // deleted overloads close possible hole in the type system
702 template<class _R2>
Howard Hinnant99acc502010-09-21 17:32:39 +0000703 bool operator==(const function<_R2()>&) const;// = delete;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000704 template<class _R2>
Howard Hinnant99acc502010-09-21 17:32:39 +0000705 bool operator!=(const function<_R2()>&) const;// = delete;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000706public:
707 // 20.7.16.2.4, function invocation:
708 _R operator()() const;
709
Howard Hinnantd4444702010-08-11 17:04:31 +0000710#ifndef _LIBCPP_NO_RTTI
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000711 // 20.7.16.2.5, function target access:
712 const std::type_info& target_type() const;
713 template <typename _T> _T* target();
714 template <typename _T> const _T* target() const;
Howard Hinnant324bb032010-08-22 00:02:43 +0000715#endif // _LIBCPP_NO_RTTI
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000716};
717
718template<class _R>
719function<_R()>::function(const function& __f)
720{
721 if (__f.__f_ == 0)
722 __f_ = 0;
723 else if (__f.__f_ == (const __base*)&__f.__buf_)
724 {
725 __f_ = (__base*)&__buf_;
726 __f.__f_->__clone(__f_);
727 }
728 else
729 __f_ = __f.__f_->__clone();
730}
731
732template<class _R>
Howard Hinnant72552802010-08-20 19:36:46 +0000733template<class _Alloc>
734function<_R()>::function(allocator_arg_t, const _Alloc&, const function& __f)
735{
736 if (__f.__f_ == 0)
737 __f_ = 0;
738 else if (__f.__f_ == (const __base*)&__f.__buf_)
739 {
740 __f_ = (__base*)&__buf_;
741 __f.__f_->__clone(__f_);
742 }
743 else
744 __f_ = __f.__f_->__clone();
745}
746
747template<class _R>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000748template <class _F>
749function<_R()>::function(_F __f,
750 typename enable_if<!is_integral<_F>::value>::type*)
751 : __f_(0)
752{
753 if (__not_null(__f))
754 {
755 typedef __function::__func<_F, allocator<_F>, _R()> _FF;
756 if (sizeof(_FF) <= sizeof(__buf_))
757 {
758 __f_ = (__base*)&__buf_;
759 ::new (__f_) _FF(__f);
760 }
761 else
762 {
763 typedef allocator<_FF> _A;
764 _A __a;
765 typedef __allocator_destructor<_A> _D;
766 unique_ptr<__base, _D> __hold(__a.allocate(1), _D(__a, 1));
767 ::new (__hold.get()) _FF(__f, allocator<_F>(__a));
768 __f_ = __hold.release();
769 }
770 }
771}
772
773template<class _R>
Howard Hinnant72552802010-08-20 19:36:46 +0000774template <class _F, class _Alloc>
775function<_R()>::function(allocator_arg_t, const _Alloc& __a0, _F __f,
776 typename enable_if<!is_integral<_F>::value>::type*)
777 : __f_(0)
778{
779 typedef allocator_traits<_Alloc> __alloc_traits;
780 if (__not_null(__f))
781 {
782 typedef __function::__func<_F, _Alloc, _R()> _FF;
783 if (sizeof(_FF) <= sizeof(__buf_))
784 {
785 __f_ = (__base*)&__buf_;
786 ::new (__f_) _FF(__f);
787 }
788 else
789 {
790 typedef typename __alloc_traits::template
791#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
792 rebind_alloc<_FF>
793#else
794 rebind_alloc<_FF>::other
795#endif
796 _A;
797 _A __a(__a0);
798 typedef __allocator_destructor<_A> _D;
799 unique_ptr<__base, _D> __hold(__a.allocate(1), _D(__a, 1));
800 ::new (__hold.get()) _FF(__f, _Alloc(__a));
801 __f_ = __hold.release();
802 }
803 }
804}
805
806template<class _R>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000807function<_R()>&
808function<_R()>::operator=(const function& __f)
809{
810 function(__f).swap(*this);
811 return *this;
812}
813
814template<class _R>
815function<_R()>&
816function<_R()>::operator=(nullptr_t)
817{
818 if (__f_ == (__base*)&__buf_)
819 __f_->destroy();
820 else if (__f_)
821 __f_->destroy_deallocate();
822 __f_ = 0;
823}
824
825template<class _R>
826template <class _F>
827typename enable_if
828<
829 !is_integral<_F>::value,
830 function<_R()>&
831>::type
832function<_R()>::operator=(_F __f)
833{
834 function(_STD::move(__f)).swap(*this);
835 return *this;
836}
837
838template<class _R>
839function<_R()>::~function()
840{
841 if (__f_ == (__base*)&__buf_)
842 __f_->destroy();
843 else if (__f_)
844 __f_->destroy_deallocate();
845}
846
847template<class _R>
848void
849function<_R()>::swap(function& __f)
850{
851 if (__f_ == (__base*)&__buf_ && __f.__f_ == (__base*)&__f.__buf_)
852 {
853 typename aligned_storage<sizeof(__buf_)>::type __tempbuf;
854 __base* __t = (__base*)&__tempbuf;
855 __f_->__clone(__t);
856 __f_->destroy();
857 __f_ = 0;
858 __f.__f_->__clone((__base*)&__buf_);
859 __f.__f_->destroy();
860 __f.__f_ = 0;
861 __f_ = (__base*)&__buf_;
862 __t->__clone((__base*)&__f.__buf_);
863 __t->destroy();
864 __f.__f_ = (__base*)&__f.__buf_;
865 }
866 else if (__f_ == (__base*)&__buf_)
867 {
868 __f_->__clone((__base*)&__f.__buf_);
869 __f_->destroy();
870 __f_ = __f.__f_;
871 __f.__f_ = (__base*)&__f.__buf_;
872 }
873 else if (__f.__f_ == (__base*)&__f.__buf_)
874 {
875 __f.__f_->__clone((__base*)&__buf_);
876 __f.__f_->destroy();
877 __f.__f_ = __f_;
878 __f_ = (__base*)&__buf_;
879 }
880 else
881 _STD::swap(__f_, __f.__f_);
882}
883
884template<class _R>
885_R
886function<_R()>::operator()() const
887{
Howard Hinnantd4444702010-08-11 17:04:31 +0000888#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000889 if (__f_ == 0)
890 throw bad_function_call();
Howard Hinnant324bb032010-08-22 00:02:43 +0000891#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000892 return (*__f_)();
893}
894
Howard Hinnantd4444702010-08-11 17:04:31 +0000895#ifndef _LIBCPP_NO_RTTI
896
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000897template<class _R>
898const std::type_info&
899function<_R()>::target_type() const
900{
901 if (__f_ == 0)
902 return typeid(void);
903 return __f_->target_type();
904}
905
906template<class _R>
907template <typename _T>
908_T*
909function<_R()>::target()
910{
911 if (__f_ == 0)
912 return (_T*)0;
913 return (_T*)__f_->target(typeid(_T));
914}
915
916template<class _R>
917template <typename _T>
918const _T*
919function<_R()>::target() const
920{
921 if (__f_ == 0)
922 return (const _T*)0;
923 return (const _T*)__f_->target(typeid(_T));
924}
925
Howard Hinnant324bb032010-08-22 00:02:43 +0000926#endif // _LIBCPP_NO_RTTI
Howard Hinnantd4444702010-08-11 17:04:31 +0000927
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000928template<class _R, class _A0>
Howard Hinnant99acc502010-09-21 17:32:39 +0000929class _LIBCPP_VISIBLE function<_R(_A0)>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000930 : public unary_function<_A0, _R>
931{
932 typedef __function::__base<_R(_A0)> __base;
933 aligned_storage<3*sizeof(void*)>::type __buf_;
934 __base* __f_;
935
936 template <class _F>
Howard Hinnant99acc502010-09-21 17:32:39 +0000937 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000938 static bool __not_null(const _F&) {return true;}
939 template <class _R2, class _B0>
Howard Hinnant99acc502010-09-21 17:32:39 +0000940 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000941 static bool __not_null(_R2 (*__p)(_B0)) {return __p;}
942 template <class _R2, class _C>
Howard Hinnant99acc502010-09-21 17:32:39 +0000943 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000944 static bool __not_null(_R2 (_C::*__p)()) {return __p;}
945 template <class _R2, class _C>
Howard Hinnant99acc502010-09-21 17:32:39 +0000946 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000947 static bool __not_null(_R2 (_C::*__p)() const) {return __p;}
948 template <class _R2, class _C>
Howard Hinnant99acc502010-09-21 17:32:39 +0000949 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000950 static bool __not_null(_R2 (_C::*__p)() volatile) {return __p;}
951 template <class _R2, class _C>
Howard Hinnant99acc502010-09-21 17:32:39 +0000952 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000953 static bool __not_null(_R2 (_C::*__p)() const volatile) {return __p;}
954 template <class _R2, class _B0>
Howard Hinnant99acc502010-09-21 17:32:39 +0000955 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000956 static bool __not_null(const function<_R(_B0)>& __p) {return __p;}
957public:
958 typedef _R result_type;
959
960 // 20.7.16.2.1, construct/copy/destroy:
Howard Hinnant99acc502010-09-21 17:32:39 +0000961 _LIBCPP_INLINE_VISIBILITY explicit function() : __f_(0) {}
962 _LIBCPP_INLINE_VISIBILITY function(nullptr_t) : __f_(0) {}
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000963 function(const function&);
964 template<class _F>
965 function(_F,
966 typename enable_if<!is_integral<_F>::value>::type* = 0);
967
Howard Hinnant72552802010-08-20 19:36:46 +0000968 template<class _Alloc>
Howard Hinnant99acc502010-09-21 17:32:39 +0000969 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant72552802010-08-20 19:36:46 +0000970 function(allocator_arg_t, const _Alloc&) : __f_(0) {}
971 template<class _Alloc>
Howard Hinnant99acc502010-09-21 17:32:39 +0000972 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant72552802010-08-20 19:36:46 +0000973 function(allocator_arg_t, const _Alloc&, nullptr_t) : __f_(0) {}
974 template<class _Alloc>
975 function(allocator_arg_t, const _Alloc&, const function&);
976 template<class _F, class _Alloc>
977 function(allocator_arg_t, const _Alloc& __a, _F __f,
978 typename enable_if<!is_integral<_F>::value>::type* = 0);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000979
980 function& operator=(const function&);
981 function& operator=(nullptr_t);
982 template<class _F>
983 typename enable_if
984 <
985 !is_integral<_F>::value,
986 function&
987 >::type
988 operator=(_F);
989
990 ~function();
991
992 // 20.7.16.2.2, function modifiers:
993 void swap(function&);
Howard Hinnant72552802010-08-20 19:36:46 +0000994 template<class _F, class _Alloc>
Howard Hinnant99acc502010-09-21 17:32:39 +0000995 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant72552802010-08-20 19:36:46 +0000996 void assign(_F __f, const _Alloc& __a)
997 {function(allocator_arg, __a, __f).swap(*this);}
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000998
999 // 20.7.16.2.3, function capacity:
Howard Hinnant99acc502010-09-21 17:32:39 +00001000 _LIBCPP_INLINE_VISIBILITY operator bool() const {return __f_;}
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001001
1002private:
1003 // deleted overloads close possible hole in the type system
1004 template<class _R2, class _B0>
Howard Hinnant99acc502010-09-21 17:32:39 +00001005 bool operator==(const function<_R2(_B0)>&) const;// = delete;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001006 template<class _R2, class _B0>
Howard Hinnant99acc502010-09-21 17:32:39 +00001007 bool operator!=(const function<_R2(_B0)>&) const;// = delete;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001008public:
1009 // 20.7.16.2.4, function invocation:
1010 _R operator()(_A0) const;
1011
Howard Hinnantd4444702010-08-11 17:04:31 +00001012#ifndef _LIBCPP_NO_RTTI
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001013 // 20.7.16.2.5, function target access:
1014 const std::type_info& target_type() const;
1015 template <typename _T> _T* target();
1016 template <typename _T> const _T* target() const;
Howard Hinnant324bb032010-08-22 00:02:43 +00001017#endif // _LIBCPP_NO_RTTI
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001018};
1019
1020template<class _R, class _A0>
1021function<_R(_A0)>::function(const function& __f)
1022{
1023 if (__f.__f_ == 0)
1024 __f_ = 0;
1025 else if (__f.__f_ == (const __base*)&__f.__buf_)
1026 {
1027 __f_ = (__base*)&__buf_;
1028 __f.__f_->__clone(__f_);
1029 }
1030 else
1031 __f_ = __f.__f_->__clone();
1032}
1033
1034template<class _R, class _A0>
Howard Hinnant72552802010-08-20 19:36:46 +00001035template<class _Alloc>
1036function<_R(_A0)>::function(allocator_arg_t, const _Alloc&, const function& __f)
1037{
1038 if (__f.__f_ == 0)
1039 __f_ = 0;
1040 else if (__f.__f_ == (const __base*)&__f.__buf_)
1041 {
1042 __f_ = (__base*)&__buf_;
1043 __f.__f_->__clone(__f_);
1044 }
1045 else
1046 __f_ = __f.__f_->__clone();
1047}
1048
1049template<class _R, class _A0>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001050template <class _F>
1051function<_R(_A0)>::function(_F __f,
1052 typename enable_if<!is_integral<_F>::value>::type*)
1053 : __f_(0)
1054{
1055 if (__not_null(__f))
1056 {
1057 typedef __function::__func<_F, allocator<_F>, _R(_A0)> _FF;
1058 if (sizeof(_FF) <= sizeof(__buf_))
1059 {
1060 __f_ = (__base*)&__buf_;
1061 ::new (__f_) _FF(__f);
1062 }
1063 else
1064 {
1065 typedef allocator<_FF> _A;
1066 _A __a;
1067 typedef __allocator_destructor<_A> _D;
1068 unique_ptr<__base, _D> __hold(__a.allocate(1), _D(__a, 1));
1069 ::new (__hold.get()) _FF(__f, allocator<_F>(__a));
1070 __f_ = __hold.release();
1071 }
1072 }
1073}
1074
1075template<class _R, class _A0>
Howard Hinnant72552802010-08-20 19:36:46 +00001076template <class _F, class _Alloc>
1077function<_R(_A0)>::function(allocator_arg_t, const _Alloc& __a0, _F __f,
1078 typename enable_if<!is_integral<_F>::value>::type*)
1079 : __f_(0)
1080{
1081 typedef allocator_traits<_Alloc> __alloc_traits;
1082 if (__not_null(__f))
1083 {
1084 typedef __function::__func<_F, _Alloc, _R(_A0)> _FF;
1085 if (sizeof(_FF) <= sizeof(__buf_))
1086 {
1087 __f_ = (__base*)&__buf_;
1088 ::new (__f_) _FF(__f);
1089 }
1090 else
1091 {
1092 typedef typename __alloc_traits::template
1093#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
1094 rebind_alloc<_FF>
1095#else
1096 rebind_alloc<_FF>::other
1097#endif
1098 _A;
1099 _A __a(__a0);
1100 typedef __allocator_destructor<_A> _D;
1101 unique_ptr<__base, _D> __hold(__a.allocate(1), _D(__a, 1));
1102 ::new (__hold.get()) _FF(__f, _Alloc(__a));
1103 __f_ = __hold.release();
1104 }
1105 }
1106}
1107
1108template<class _R, class _A0>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001109function<_R(_A0)>&
1110function<_R(_A0)>::operator=(const function& __f)
1111{
1112 function(__f).swap(*this);
1113 return *this;
1114}
1115
1116template<class _R, class _A0>
1117function<_R(_A0)>&
1118function<_R(_A0)>::operator=(nullptr_t)
1119{
1120 if (__f_ == (__base*)&__buf_)
1121 __f_->destroy();
1122 else if (__f_)
1123 __f_->destroy_deallocate();
1124 __f_ = 0;
1125}
1126
1127template<class _R, class _A0>
1128template <class _F>
1129typename enable_if
1130<
1131 !is_integral<_F>::value,
1132 function<_R(_A0)>&
1133>::type
1134function<_R(_A0)>::operator=(_F __f)
1135{
1136 function(_STD::move(__f)).swap(*this);
1137 return *this;
1138}
1139
1140template<class _R, class _A0>
1141function<_R(_A0)>::~function()
1142{
1143 if (__f_ == (__base*)&__buf_)
1144 __f_->destroy();
1145 else if (__f_)
1146 __f_->destroy_deallocate();
1147}
1148
1149template<class _R, class _A0>
1150void
1151function<_R(_A0)>::swap(function& __f)
1152{
1153 if (__f_ == (__base*)&__buf_ && __f.__f_ == (__base*)&__f.__buf_)
1154 {
1155 typename aligned_storage<sizeof(__buf_)>::type __tempbuf;
1156 __base* __t = (__base*)&__tempbuf;
1157 __f_->__clone(__t);
1158 __f_->destroy();
1159 __f_ = 0;
1160 __f.__f_->__clone((__base*)&__buf_);
1161 __f.__f_->destroy();
1162 __f.__f_ = 0;
1163 __f_ = (__base*)&__buf_;
1164 __t->__clone((__base*)&__f.__buf_);
1165 __t->destroy();
1166 __f.__f_ = (__base*)&__f.__buf_;
1167 }
1168 else if (__f_ == (__base*)&__buf_)
1169 {
1170 __f_->__clone((__base*)&__f.__buf_);
1171 __f_->destroy();
1172 __f_ = __f.__f_;
1173 __f.__f_ = (__base*)&__f.__buf_;
1174 }
1175 else if (__f.__f_ == (__base*)&__f.__buf_)
1176 {
1177 __f.__f_->__clone((__base*)&__buf_);
1178 __f.__f_->destroy();
1179 __f.__f_ = __f_;
1180 __f_ = (__base*)&__buf_;
1181 }
1182 else
1183 _STD::swap(__f_, __f.__f_);
1184}
1185
1186template<class _R, class _A0>
1187_R
1188function<_R(_A0)>::operator()(_A0 __a0) const
1189{
Howard Hinnantd4444702010-08-11 17:04:31 +00001190#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001191 if (__f_ == 0)
1192 throw bad_function_call();
Howard Hinnant324bb032010-08-22 00:02:43 +00001193#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001194 return (*__f_)(__a0);
1195}
1196
Howard Hinnantd4444702010-08-11 17:04:31 +00001197#ifndef _LIBCPP_NO_RTTI
1198
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001199template<class _R, class _A0>
1200const std::type_info&
1201function<_R(_A0)>::target_type() const
1202{
1203 if (__f_ == 0)
1204 return typeid(void);
1205 return __f_->target_type();
1206}
1207
1208template<class _R, class _A0>
1209template <typename _T>
1210_T*
1211function<_R(_A0)>::target()
1212{
1213 if (__f_ == 0)
1214 return (_T*)0;
1215 return (_T*)__f_->target(typeid(_T));
1216}
1217
1218template<class _R, class _A0>
1219template <typename _T>
1220const _T*
1221function<_R(_A0)>::target() const
1222{
1223 if (__f_ == 0)
1224 return (const _T*)0;
1225 return (const _T*)__f_->target(typeid(_T));
1226}
1227
Howard Hinnant324bb032010-08-22 00:02:43 +00001228#endif // _LIBCPP_NO_RTTI
Howard Hinnantd4444702010-08-11 17:04:31 +00001229
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001230template<class _R, class _A0, class _A1>
Howard Hinnant99acc502010-09-21 17:32:39 +00001231class _LIBCPP_VISIBLE function<_R(_A0, _A1)>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001232 : public binary_function<_A0, _A1, _R>
1233{
1234 typedef __function::__base<_R(_A0, _A1)> __base;
1235 aligned_storage<3*sizeof(void*)>::type __buf_;
1236 __base* __f_;
1237
1238 template <class _F>
Howard Hinnant99acc502010-09-21 17:32:39 +00001239 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001240 static bool __not_null(const _F&) {return true;}
1241 template <class _R2, class _B0, class _B1>
Howard Hinnant99acc502010-09-21 17:32:39 +00001242 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001243 static bool __not_null(_R2 (*__p)(_B0, _B1)) {return __p;}
1244 template <class _R2, class _C, class _B1>
Howard Hinnant99acc502010-09-21 17:32:39 +00001245 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001246 static bool __not_null(_R2 (_C::*__p)(_B1)) {return __p;}
1247 template <class _R2, class _C, class _B1>
Howard Hinnant99acc502010-09-21 17:32:39 +00001248 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001249 static bool __not_null(_R2 (_C::*__p)(_B1) const) {return __p;}
1250 template <class _R2, class _C, class _B1>
Howard Hinnant99acc502010-09-21 17:32:39 +00001251 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001252 static bool __not_null(_R2 (_C::*__p)(_B1) volatile) {return __p;}
1253 template <class _R2, class _C, class _B1>
Howard Hinnant99acc502010-09-21 17:32:39 +00001254 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001255 static bool __not_null(_R2 (_C::*__p)(_B1) const volatile) {return __p;}
1256 template <class _R2, class _B0, class _B1>
Howard Hinnant99acc502010-09-21 17:32:39 +00001257 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001258 static bool __not_null(const function<_R(_B0, _B1)>& __p) {return __p;}
1259public:
1260 typedef _R result_type;
1261
1262 // 20.7.16.2.1, construct/copy/destroy:
Howard Hinnant99acc502010-09-21 17:32:39 +00001263 _LIBCPP_INLINE_VISIBILITY explicit function() : __f_(0) {}
1264 _LIBCPP_INLINE_VISIBILITY function(nullptr_t) : __f_(0) {}
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001265 function(const function&);
1266 template<class _F>
1267 function(_F,
1268 typename enable_if<!is_integral<_F>::value>::type* = 0);
1269
Howard Hinnant72552802010-08-20 19:36:46 +00001270 template<class _Alloc>
Howard Hinnant99acc502010-09-21 17:32:39 +00001271 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant72552802010-08-20 19:36:46 +00001272 function(allocator_arg_t, const _Alloc&) : __f_(0) {}
1273 template<class _Alloc>
Howard Hinnant99acc502010-09-21 17:32:39 +00001274 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant72552802010-08-20 19:36:46 +00001275 function(allocator_arg_t, const _Alloc&, nullptr_t) : __f_(0) {}
1276 template<class _Alloc>
1277 function(allocator_arg_t, const _Alloc&, const function&);
1278 template<class _F, class _Alloc>
1279 function(allocator_arg_t, const _Alloc& __a, _F __f,
1280 typename enable_if<!is_integral<_F>::value>::type* = 0);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001281
1282 function& operator=(const function&);
1283 function& operator=(nullptr_t);
1284 template<class _F>
1285 typename enable_if
1286 <
1287 !is_integral<_F>::value,
1288 function&
1289 >::type
1290 operator=(_F);
1291
1292 ~function();
1293
1294 // 20.7.16.2.2, function modifiers:
1295 void swap(function&);
Howard Hinnant72552802010-08-20 19:36:46 +00001296 template<class _F, class _Alloc>
Howard Hinnant99acc502010-09-21 17:32:39 +00001297 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant72552802010-08-20 19:36:46 +00001298 void assign(_F __f, const _Alloc& __a)
1299 {function(allocator_arg, __a, __f).swap(*this);}
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001300
1301 // 20.7.16.2.3, function capacity:
1302 operator bool() const {return __f_;}
1303
1304private:
1305 // deleted overloads close possible hole in the type system
1306 template<class _R2, class _B0, class _B1>
Howard Hinnant99acc502010-09-21 17:32:39 +00001307 bool operator==(const function<_R2(_B0, _B1)>&) const;// = delete;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001308 template<class _R2, class _B0, class _B1>
Howard Hinnant99acc502010-09-21 17:32:39 +00001309 bool operator!=(const function<_R2(_B0, _B1)>&) const;// = delete;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001310public:
1311 // 20.7.16.2.4, function invocation:
1312 _R operator()(_A0, _A1) const;
1313
Howard Hinnantd4444702010-08-11 17:04:31 +00001314#ifndef _LIBCPP_NO_RTTI
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001315 // 20.7.16.2.5, function target access:
1316 const std::type_info& target_type() const;
1317 template <typename _T> _T* target();
1318 template <typename _T> const _T* target() const;
Howard Hinnant324bb032010-08-22 00:02:43 +00001319#endif // _LIBCPP_NO_RTTI
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001320};
1321
1322template<class _R, class _A0, class _A1>
1323function<_R(_A0, _A1)>::function(const function& __f)
1324{
1325 if (__f.__f_ == 0)
1326 __f_ = 0;
1327 else if (__f.__f_ == (const __base*)&__f.__buf_)
1328 {
1329 __f_ = (__base*)&__buf_;
1330 __f.__f_->__clone(__f_);
1331 }
1332 else
1333 __f_ = __f.__f_->__clone();
1334}
1335
1336template<class _R, class _A0, class _A1>
Howard Hinnant72552802010-08-20 19:36:46 +00001337template<class _Alloc>
1338function<_R(_A0, _A1)>::function(allocator_arg_t, const _Alloc&, const function& __f)
1339{
1340 if (__f.__f_ == 0)
1341 __f_ = 0;
1342 else if (__f.__f_ == (const __base*)&__f.__buf_)
1343 {
1344 __f_ = (__base*)&__buf_;
1345 __f.__f_->__clone(__f_);
1346 }
1347 else
1348 __f_ = __f.__f_->__clone();
1349}
1350
1351template<class _R, class _A0, class _A1>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001352template <class _F>
1353function<_R(_A0, _A1)>::function(_F __f,
Howard Hinnant72552802010-08-20 19:36:46 +00001354 typename enable_if<!is_integral<_F>::value>::type*)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001355 : __f_(0)
1356{
1357 if (__not_null(__f))
1358 {
1359 typedef __function::__func<_F, allocator<_F>, _R(_A0, _A1)> _FF;
1360 if (sizeof(_FF) <= sizeof(__buf_))
1361 {
1362 __f_ = (__base*)&__buf_;
1363 ::new (__f_) _FF(__f);
1364 }
1365 else
1366 {
1367 typedef allocator<_FF> _A;
1368 _A __a;
1369 typedef __allocator_destructor<_A> _D;
1370 unique_ptr<__base, _D> __hold(__a.allocate(1), _D(__a, 1));
1371 ::new (__hold.get()) _FF(__f, allocator<_F>(__a));
1372 __f_ = __hold.release();
1373 }
1374 }
1375}
1376
1377template<class _R, class _A0, class _A1>
Howard Hinnant72552802010-08-20 19:36:46 +00001378template <class _F, class _Alloc>
1379function<_R(_A0, _A1)>::function(allocator_arg_t, const _Alloc& __a0, _F __f,
1380 typename enable_if<!is_integral<_F>::value>::type*)
1381 : __f_(0)
1382{
1383 typedef allocator_traits<_Alloc> __alloc_traits;
1384 if (__not_null(__f))
1385 {
1386 typedef __function::__func<_F, _Alloc, _R(_A0, _A1)> _FF;
1387 if (sizeof(_FF) <= sizeof(__buf_))
1388 {
1389 __f_ = (__base*)&__buf_;
1390 ::new (__f_) _FF(__f);
1391 }
1392 else
1393 {
1394 typedef typename __alloc_traits::template
1395#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
1396 rebind_alloc<_FF>
1397#else
1398 rebind_alloc<_FF>::other
1399#endif
1400 _A;
1401 _A __a(__a0);
1402 typedef __allocator_destructor<_A> _D;
1403 unique_ptr<__base, _D> __hold(__a.allocate(1), _D(__a, 1));
1404 ::new (__hold.get()) _FF(__f, _Alloc(__a));
1405 __f_ = __hold.release();
1406 }
1407 }
1408}
1409
1410template<class _R, class _A0, class _A1>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001411function<_R(_A0, _A1)>&
1412function<_R(_A0, _A1)>::operator=(const function& __f)
1413{
1414 function(__f).swap(*this);
1415 return *this;
1416}
1417
1418template<class _R, class _A0, class _A1>
1419function<_R(_A0, _A1)>&
1420function<_R(_A0, _A1)>::operator=(nullptr_t)
1421{
1422 if (__f_ == (__base*)&__buf_)
1423 __f_->destroy();
1424 else if (__f_)
1425 __f_->destroy_deallocate();
1426 __f_ = 0;
1427}
1428
1429template<class _R, class _A0, class _A1>
1430template <class _F>
1431typename enable_if
1432<
1433 !is_integral<_F>::value,
1434 function<_R(_A0, _A1)>&
1435>::type
1436function<_R(_A0, _A1)>::operator=(_F __f)
1437{
1438 function(_STD::move(__f)).swap(*this);
1439 return *this;
1440}
1441
1442template<class _R, class _A0, class _A1>
1443function<_R(_A0, _A1)>::~function()
1444{
1445 if (__f_ == (__base*)&__buf_)
1446 __f_->destroy();
1447 else if (__f_)
1448 __f_->destroy_deallocate();
1449}
1450
1451template<class _R, class _A0, class _A1>
1452void
1453function<_R(_A0, _A1)>::swap(function& __f)
1454{
1455 if (__f_ == (__base*)&__buf_ && __f.__f_ == (__base*)&__f.__buf_)
1456 {
1457 typename aligned_storage<sizeof(__buf_)>::type __tempbuf;
1458 __base* __t = (__base*)&__tempbuf;
1459 __f_->__clone(__t);
1460 __f_->destroy();
1461 __f_ = 0;
1462 __f.__f_->__clone((__base*)&__buf_);
1463 __f.__f_->destroy();
1464 __f.__f_ = 0;
1465 __f_ = (__base*)&__buf_;
1466 __t->__clone((__base*)&__f.__buf_);
1467 __t->destroy();
1468 __f.__f_ = (__base*)&__f.__buf_;
1469 }
1470 else if (__f_ == (__base*)&__buf_)
1471 {
1472 __f_->__clone((__base*)&__f.__buf_);
1473 __f_->destroy();
1474 __f_ = __f.__f_;
1475 __f.__f_ = (__base*)&__f.__buf_;
1476 }
1477 else if (__f.__f_ == (__base*)&__f.__buf_)
1478 {
1479 __f.__f_->__clone((__base*)&__buf_);
1480 __f.__f_->destroy();
1481 __f.__f_ = __f_;
1482 __f_ = (__base*)&__buf_;
1483 }
1484 else
1485 _STD::swap(__f_, __f.__f_);
1486}
1487
1488template<class _R, class _A0, class _A1>
1489_R
1490function<_R(_A0, _A1)>::operator()(_A0 __a0, _A1 __a1) const
1491{
Howard Hinnantd4444702010-08-11 17:04:31 +00001492#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001493 if (__f_ == 0)
1494 throw bad_function_call();
Howard Hinnant324bb032010-08-22 00:02:43 +00001495#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001496 return (*__f_)(__a0, __a1);
1497}
1498
Howard Hinnantd4444702010-08-11 17:04:31 +00001499#ifndef _LIBCPP_NO_RTTI
1500
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001501template<class _R, class _A0, class _A1>
1502const std::type_info&
1503function<_R(_A0, _A1)>::target_type() const
1504{
1505 if (__f_ == 0)
1506 return typeid(void);
1507 return __f_->target_type();
1508}
1509
1510template<class _R, class _A0, class _A1>
1511template <typename _T>
1512_T*
1513function<_R(_A0, _A1)>::target()
1514{
1515 if (__f_ == 0)
1516 return (_T*)0;
1517 return (_T*)__f_->target(typeid(_T));
1518}
1519
1520template<class _R, class _A0, class _A1>
1521template <typename _T>
1522const _T*
1523function<_R(_A0, _A1)>::target() const
1524{
1525 if (__f_ == 0)
1526 return (const _T*)0;
1527 return (const _T*)__f_->target(typeid(_T));
1528}
1529
Howard Hinnant324bb032010-08-22 00:02:43 +00001530#endif // _LIBCPP_NO_RTTI
Howard Hinnantd4444702010-08-11 17:04:31 +00001531
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001532template<class _R, class _A0, class _A1, class _A2>
Howard Hinnant99acc502010-09-21 17:32:39 +00001533class _LIBCPP_VISIBLE function<_R(_A0, _A1, _A2)>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001534{
1535 typedef __function::__base<_R(_A0, _A1, _A2)> __base;
1536 aligned_storage<3*sizeof(void*)>::type __buf_;
1537 __base* __f_;
1538
1539 template <class _F>
Howard Hinnant99acc502010-09-21 17:32:39 +00001540 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001541 static bool __not_null(const _F&) {return true;}
1542 template <class _R2, class _B0, class _B1, class _B2>
Howard Hinnant99acc502010-09-21 17:32:39 +00001543 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001544 static bool __not_null(_R2 (*__p)(_B0, _B1, _B2)) {return __p;}
1545 template <class _R2, class _C, class _B1, class _B2>
Howard Hinnant99acc502010-09-21 17:32:39 +00001546 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001547 static bool __not_null(_R2 (_C::*__p)(_B1, _B2)) {return __p;}
1548 template <class _R2, class _C, class _B1, class _B2>
Howard Hinnant99acc502010-09-21 17:32:39 +00001549 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001550 static bool __not_null(_R2 (_C::*__p)(_B1, _B2) const) {return __p;}
1551 template <class _R2, class _C, class _B1, class _B2>
Howard Hinnant99acc502010-09-21 17:32:39 +00001552 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001553 static bool __not_null(_R2 (_C::*__p)(_B1, _B2) volatile) {return __p;}
1554 template <class _R2, class _C, class _B1, class _B2>
Howard Hinnant99acc502010-09-21 17:32:39 +00001555 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001556 static bool __not_null(_R2 (_C::*__p)(_B1, _B2) const volatile) {return __p;}
1557 template <class _R2, class _B0, class _B1, class _B2>
Howard Hinnant99acc502010-09-21 17:32:39 +00001558 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001559 static bool __not_null(const function<_R(_B0, _B1, _B2)>& __p) {return __p;}
1560public:
1561 typedef _R result_type;
1562
1563 // 20.7.16.2.1, construct/copy/destroy:
Howard Hinnant99acc502010-09-21 17:32:39 +00001564 _LIBCPP_INLINE_VISIBILITY explicit function() : __f_(0) {}
1565 _LIBCPP_INLINE_VISIBILITY function(nullptr_t) : __f_(0) {}
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001566 function(const function&);
1567 template<class _F>
1568 function(_F,
1569 typename enable_if<!is_integral<_F>::value>::type* = 0);
1570
Howard Hinnant72552802010-08-20 19:36:46 +00001571 template<class _Alloc>
Howard Hinnant99acc502010-09-21 17:32:39 +00001572 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant72552802010-08-20 19:36:46 +00001573 function(allocator_arg_t, const _Alloc&) : __f_(0) {}
1574 template<class _Alloc>
Howard Hinnant99acc502010-09-21 17:32:39 +00001575 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant72552802010-08-20 19:36:46 +00001576 function(allocator_arg_t, const _Alloc&, nullptr_t) : __f_(0) {}
1577 template<class _Alloc>
1578 function(allocator_arg_t, const _Alloc&, const function&);
1579 template<class _F, class _Alloc>
1580 function(allocator_arg_t, const _Alloc& __a, _F __f,
1581 typename enable_if<!is_integral<_F>::value>::type* = 0);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001582
1583 function& operator=(const function&);
1584 function& operator=(nullptr_t);
1585 template<class _F>
1586 typename enable_if
1587 <
1588 !is_integral<_F>::value,
1589 function&
1590 >::type
1591 operator=(_F);
1592
1593 ~function();
1594
1595 // 20.7.16.2.2, function modifiers:
1596 void swap(function&);
Howard Hinnant72552802010-08-20 19:36:46 +00001597 template<class _F, class _Alloc>
Howard Hinnant99acc502010-09-21 17:32:39 +00001598 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant72552802010-08-20 19:36:46 +00001599 void assign(_F __f, const _Alloc& __a)
1600 {function(allocator_arg, __a, __f).swap(*this);}
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001601
1602 // 20.7.16.2.3, function capacity:
Howard Hinnant99acc502010-09-21 17:32:39 +00001603 _LIBCPP_INLINE_VISIBILITY operator bool() const {return __f_;}
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001604
1605private:
1606 // deleted overloads close possible hole in the type system
1607 template<class _R2, class _B0, class _B1, class _B2>
Howard Hinnant99acc502010-09-21 17:32:39 +00001608 bool operator==(const function<_R2(_B0, _B1, _B2)>&) const;// = delete;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001609 template<class _R2, class _B0, class _B1, class _B2>
Howard Hinnant99acc502010-09-21 17:32:39 +00001610 bool operator!=(const function<_R2(_B0, _B1, _B2)>&) const;// = delete;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001611public:
1612 // 20.7.16.2.4, function invocation:
1613 _R operator()(_A0, _A1, _A2) const;
1614
Howard Hinnantd4444702010-08-11 17:04:31 +00001615#ifndef _LIBCPP_NO_RTTI
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001616 // 20.7.16.2.5, function target access:
1617 const std::type_info& target_type() const;
1618 template <typename _T> _T* target();
1619 template <typename _T> const _T* target() const;
Howard Hinnant324bb032010-08-22 00:02:43 +00001620#endif // _LIBCPP_NO_RTTI
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001621};
1622
1623template<class _R, class _A0, class _A1, class _A2>
1624function<_R(_A0, _A1, _A2)>::function(const function& __f)
1625{
1626 if (__f.__f_ == 0)
1627 __f_ = 0;
1628 else if (__f.__f_ == (const __base*)&__f.__buf_)
1629 {
1630 __f_ = (__base*)&__buf_;
1631 __f.__f_->__clone(__f_);
1632 }
1633 else
1634 __f_ = __f.__f_->__clone();
1635}
1636
1637template<class _R, class _A0, class _A1, class _A2>
Howard Hinnant72552802010-08-20 19:36:46 +00001638template<class _Alloc>
1639function<_R(_A0, _A1, _A2)>::function(allocator_arg_t, const _Alloc&,
1640 const function& __f)
1641{
1642 if (__f.__f_ == 0)
1643 __f_ = 0;
1644 else if (__f.__f_ == (const __base*)&__f.__buf_)
1645 {
1646 __f_ = (__base*)&__buf_;
1647 __f.__f_->__clone(__f_);
1648 }
1649 else
1650 __f_ = __f.__f_->__clone();
1651}
1652
1653template<class _R, class _A0, class _A1, class _A2>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001654template <class _F>
1655function<_R(_A0, _A1, _A2)>::function(_F __f,
1656 typename enable_if<!is_integral<_F>::value>::type*)
1657 : __f_(0)
1658{
1659 if (__not_null(__f))
1660 {
1661 typedef __function::__func<_F, allocator<_F>, _R(_A0, _A1, _A2)> _FF;
1662 if (sizeof(_FF) <= sizeof(__buf_))
1663 {
1664 __f_ = (__base*)&__buf_;
1665 ::new (__f_) _FF(__f);
1666 }
1667 else
1668 {
1669 typedef allocator<_FF> _A;
1670 _A __a;
1671 typedef __allocator_destructor<_A> _D;
1672 unique_ptr<__base, _D> __hold(__a.allocate(1), _D(__a, 1));
1673 ::new (__hold.get()) _FF(__f, allocator<_F>(__a));
1674 __f_ = __hold.release();
1675 }
1676 }
1677}
1678
1679template<class _R, class _A0, class _A1, class _A2>
Howard Hinnant72552802010-08-20 19:36:46 +00001680template <class _F, class _Alloc>
1681function<_R(_A0, _A1, _A2)>::function(allocator_arg_t, const _Alloc& __a0, _F __f,
1682 typename enable_if<!is_integral<_F>::value>::type*)
1683 : __f_(0)
1684{
1685 typedef allocator_traits<_Alloc> __alloc_traits;
1686 if (__not_null(__f))
1687 {
1688 typedef __function::__func<_F, _Alloc, _R(_A0, _A1, _A2)> _FF;
1689 if (sizeof(_FF) <= sizeof(__buf_))
1690 {
1691 __f_ = (__base*)&__buf_;
1692 ::new (__f_) _FF(__f);
1693 }
1694 else
1695 {
1696 typedef typename __alloc_traits::template
1697#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
1698 rebind_alloc<_FF>
1699#else
1700 rebind_alloc<_FF>::other
1701#endif
1702 _A;
1703 _A __a(__a0);
1704 typedef __allocator_destructor<_A> _D;
1705 unique_ptr<__base, _D> __hold(__a.allocate(1), _D(__a, 1));
1706 ::new (__hold.get()) _FF(__f, _Alloc(__a));
1707 __f_ = __hold.release();
1708 }
1709 }
1710}
1711
1712template<class _R, class _A0, class _A1, class _A2>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001713function<_R(_A0, _A1, _A2)>&
1714function<_R(_A0, _A1, _A2)>::operator=(const function& __f)
1715{
1716 function(__f).swap(*this);
1717 return *this;
1718}
1719
1720template<class _R, class _A0, class _A1, class _A2>
1721function<_R(_A0, _A1, _A2)>&
1722function<_R(_A0, _A1, _A2)>::operator=(nullptr_t)
1723{
1724 if (__f_ == (__base*)&__buf_)
1725 __f_->destroy();
1726 else if (__f_)
1727 __f_->destroy_deallocate();
1728 __f_ = 0;
1729}
1730
1731template<class _R, class _A0, class _A1, class _A2>
1732template <class _F>
1733typename enable_if
1734<
1735 !is_integral<_F>::value,
1736 function<_R(_A0, _A1, _A2)>&
1737>::type
1738function<_R(_A0, _A1, _A2)>::operator=(_F __f)
1739{
1740 function(_STD::move(__f)).swap(*this);
1741 return *this;
1742}
1743
1744template<class _R, class _A0, class _A1, class _A2>
1745function<_R(_A0, _A1, _A2)>::~function()
1746{
1747 if (__f_ == (__base*)&__buf_)
1748 __f_->destroy();
1749 else if (__f_)
1750 __f_->destroy_deallocate();
1751}
1752
1753template<class _R, class _A0, class _A1, class _A2>
1754void
1755function<_R(_A0, _A1, _A2)>::swap(function& __f)
1756{
1757 if (__f_ == (__base*)&__buf_ && __f.__f_ == (__base*)&__f.__buf_)
1758 {
1759 typename aligned_storage<sizeof(__buf_)>::type __tempbuf;
1760 __base* __t = (__base*)&__tempbuf;
1761 __f_->__clone(__t);
1762 __f_->destroy();
1763 __f_ = 0;
1764 __f.__f_->__clone((__base*)&__buf_);
1765 __f.__f_->destroy();
1766 __f.__f_ = 0;
1767 __f_ = (__base*)&__buf_;
1768 __t->__clone((__base*)&__f.__buf_);
1769 __t->destroy();
1770 __f.__f_ = (__base*)&__f.__buf_;
1771 }
1772 else if (__f_ == (__base*)&__buf_)
1773 {
1774 __f_->__clone((__base*)&__f.__buf_);
1775 __f_->destroy();
1776 __f_ = __f.__f_;
1777 __f.__f_ = (__base*)&__f.__buf_;
1778 }
1779 else if (__f.__f_ == (__base*)&__f.__buf_)
1780 {
1781 __f.__f_->__clone((__base*)&__buf_);
1782 __f.__f_->destroy();
1783 __f.__f_ = __f_;
1784 __f_ = (__base*)&__buf_;
1785 }
1786 else
1787 _STD::swap(__f_, __f.__f_);
1788}
1789
1790template<class _R, class _A0, class _A1, class _A2>
1791_R
1792function<_R(_A0, _A1, _A2)>::operator()(_A0 __a0, _A1 __a1, _A2 __a2) const
1793{
Howard Hinnantd4444702010-08-11 17:04:31 +00001794#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001795 if (__f_ == 0)
1796 throw bad_function_call();
Howard Hinnant324bb032010-08-22 00:02:43 +00001797#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001798 return (*__f_)(__a0, __a1, __a2);
1799}
1800
Howard Hinnantd4444702010-08-11 17:04:31 +00001801#ifndef _LIBCPP_NO_RTTI
1802
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001803template<class _R, class _A0, class _A1, class _A2>
1804const std::type_info&
1805function<_R(_A0, _A1, _A2)>::target_type() const
1806{
1807 if (__f_ == 0)
1808 return typeid(void);
1809 return __f_->target_type();
1810}
1811
1812template<class _R, class _A0, class _A1, class _A2>
1813template <typename _T>
1814_T*
1815function<_R(_A0, _A1, _A2)>::target()
1816{
1817 if (__f_ == 0)
1818 return (_T*)0;
1819 return (_T*)__f_->target(typeid(_T));
1820}
1821
1822template<class _R, class _A0, class _A1, class _A2>
1823template <typename _T>
1824const _T*
1825function<_R(_A0, _A1, _A2)>::target() const
1826{
1827 if (__f_ == 0)
1828 return (const _T*)0;
1829 return (const _T*)__f_->target(typeid(_T));
1830}
1831
Howard Hinnant324bb032010-08-22 00:02:43 +00001832#endif // _LIBCPP_NO_RTTI
Howard Hinnantd4444702010-08-11 17:04:31 +00001833
Howard Hinnant324bb032010-08-22 00:02:43 +00001834template <class _F>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001835inline _LIBCPP_INLINE_VISIBILITY
1836bool
1837operator==(const function<_F>& __f, nullptr_t) {return !__f;}
1838
Howard Hinnant324bb032010-08-22 00:02:43 +00001839template <class _F>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001840inline _LIBCPP_INLINE_VISIBILITY
1841bool
1842operator==(nullptr_t, const function<_F>& __f) {return !__f;}
1843
Howard Hinnant324bb032010-08-22 00:02:43 +00001844template <class _F>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001845inline _LIBCPP_INLINE_VISIBILITY
1846bool
1847operator!=(const function<_F>& __f, nullptr_t) {return (bool)__f;}
1848
Howard Hinnant324bb032010-08-22 00:02:43 +00001849template <class _F>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001850inline _LIBCPP_INLINE_VISIBILITY
1851bool
1852operator!=(nullptr_t, const function<_F>& __f) {return (bool)__f;}
1853
Howard Hinnant324bb032010-08-22 00:02:43 +00001854template <class _F>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001855inline _LIBCPP_INLINE_VISIBILITY
1856void
1857swap(function<_F>& __x, function<_F>& __y)
1858{return __x.swap(__y);}
1859
1860template<class _Tp> struct __is_bind_expression : public false_type {};
Howard Hinnant99acc502010-09-21 17:32:39 +00001861template<class _Tp> struct _LIBCPP_VISIBLE is_bind_expression
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001862 : public __is_bind_expression<typename remove_cv<_Tp>::type> {};
1863
1864template<class _Tp> struct __is_placeholder : public integral_constant<int, 0> {};
Howard Hinnant99acc502010-09-21 17:32:39 +00001865template<class _Tp> struct _LIBCPP_VISIBLE is_placeholder
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001866 : public __is_placeholder<typename remove_cv<_Tp>::type> {};
1867
1868namespace placeholders
1869{
1870
1871template <int _N> struct __ph {};
1872
1873extern __ph<1> _1;
1874extern __ph<2> _2;
1875extern __ph<3> _3;
1876extern __ph<4> _4;
1877extern __ph<5> _5;
1878extern __ph<6> _6;
1879extern __ph<7> _7;
1880extern __ph<8> _8;
1881extern __ph<9> _9;
1882extern __ph<10> _10;
1883
1884} // placeholders
1885
1886template<int _N>
1887struct __is_placeholder<placeholders::__ph<_N> >
1888 : public integral_constant<int, _N> {};
1889
1890template <class _Tp, class _Uj>
1891inline _LIBCPP_INLINE_VISIBILITY
1892_Tp&
1893__mu(reference_wrapper<_Tp> __t, _Uj&)
1894{
1895 return __t.get();
1896}
1897/*
1898template <bool _IsBindExpr, class _Ti, class ..._Uj>
1899struct __mu_return1 {};
1900
1901template <class _Ti, class ..._Uj>
1902struct __mu_return1<true, _Ti, _Uj...>
1903{
1904 typedef typename result_of<_Ti(_Uj...)>::type type;
1905};
1906
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001907template <class _Ti, class ..._Uj, size_t ..._Indx>
1908inline _LIBCPP_INLINE_VISIBILITY
1909typename __mu_return1<true, _Ti, _Uj...>::type
1910__mu_expand(_Ti& __ti, tuple<_Uj...>&& __uj, __tuple_indices<_Indx...>)
1911{
1912 __ti(_STD::forward<typename tuple_element<_Indx, _Uj>::type>(get<_Indx>(__uj))...);
1913}
1914
1915template <class _Ti, class ..._Uj>
1916inline _LIBCPP_INLINE_VISIBILITY
1917typename enable_if
1918<
1919 is_bind_expression<_Ti>::value,
1920 typename __mu_return1<is_bind_expression<_Ti>::value, _Ti, _Uj...>::type
1921>::type
1922__mu(_Ti& __ti, tuple<_Uj...>& __uj)
1923{
1924 typedef typename __make_tuple_indices<sizeof...(_Uj)>::type __indices;
1925 return __mu_expand(__ti, __uj, __indices());
1926}
1927
1928template <bool IsPh, class _Ti, class _Uj>
1929struct __mu_return2 {};
1930
1931template <class _Ti, class _Uj>
1932struct __mu_return2<true, _Ti, _Uj>
1933{
1934 typedef typename tuple_element<is_placeholder<_Ti>::value - 1, _Uj>::type type;
1935};
1936
1937template <class _Ti, class _Uj>
1938inline _LIBCPP_INLINE_VISIBILITY
1939typename enable_if
1940<
1941 0 < is_placeholder<_Ti>::value,
1942 typename __mu_return2<0 < is_placeholder<_Ti>::value, _Ti, _Uj>::type
1943>::type
1944__mu(_Ti&, _Uj& __uj)
1945{
1946 const size_t _Indx = is_placeholder<_Ti>::value - 1;
1947 // compiler bug workaround
1948 typename tuple_element<_Indx, _Uj>::type __t = get<_Indx>(__uj);
1949 return __t;
1950// return _STD::forward<typename tuple_element<_Indx, _Uj>::type>(get<_Indx>(__uj));
1951}
1952
1953template <class _Ti, class _Uj>
1954inline _LIBCPP_INLINE_VISIBILITY
1955typename enable_if
1956<
1957 !is_bind_expression<_Ti>::value &&
1958 is_placeholder<_Ti>::value == 0 &&
1959 !__is_reference_wrapper<_Ti>::value,
1960 _Ti&
1961>::type
1962__mu(_Ti& __ti, _Uj& __uj)
1963{
1964 return __ti;
1965}
1966
1967template <class _Ti, bool IsBindEx, bool IsPh, class _TupleUj>
1968struct ____mu_return;
1969
1970template <class _Ti, class ..._Uj>
1971struct ____mu_return<_Ti, true, false, tuple<_Uj...> >
1972{
1973 typedef typename result_of<_Ti(_Uj...)>::type type;
1974};
1975
1976template <class _Ti, class _TupleUj>
1977struct ____mu_return<_Ti, false, true, _TupleUj>
1978{
1979 typedef typename tuple_element<is_placeholder<_Ti>::value - 1,
1980 _TupleUj>::type&& type;
1981};
1982
1983template <class _Ti, class _TupleUj>
1984struct ____mu_return<_Ti, false, false, _TupleUj>
1985{
1986 typedef _Ti& type;
1987};
1988
1989template <class _Ti, class _TupleUj>
1990struct __mu_return
1991 : public ____mu_return<_Ti,
1992 is_bind_expression<_Ti>::value,
1993 0 < is_placeholder<_Ti>::value,
1994 _TupleUj>
1995{
1996};
1997
1998template <class _Ti, class _TupleUj>
1999struct __mu_return<reference_wrapper<_Ti>, _TupleUj>
2000{
2001 typedef _Ti& type;
2002};
2003
2004template <class _F, class _BoundArgs, class _TupleUj>
2005struct __bind_return;
2006
2007template <class _F, class ..._BoundArgs, class _TupleUj>
2008struct __bind_return<_F, tuple<_BoundArgs...>, _TupleUj>
2009{
2010 typedef typename __ref_return
2011 <
2012 _F&,
2013 typename __mu_return
2014 <
2015 _BoundArgs,
2016 _TupleUj
2017 >::type...
2018 >::type type;
2019};
2020
2021template <class _F, class ..._BoundArgs, class _TupleUj>
2022struct __bind_return<_F, const tuple<_BoundArgs...>, _TupleUj>
2023{
2024 typedef typename __ref_return
2025 <
2026 _F&,
2027 typename __mu_return
2028 <
2029 const _BoundArgs,
2030 _TupleUj
2031 >::type...
2032 >::type type;
2033};
2034
2035template <class _F, class _BoundArgs, size_t ..._Indx, class _Args>
2036inline _LIBCPP_INLINE_VISIBILITY
2037typename __bind_return<_F, _BoundArgs, _Args>::type
2038__apply_functor(_F& __f, _BoundArgs& __bound_args, __tuple_indices<_Indx...>,
2039 _Args&& __args)
2040{
2041 return __invoke(__f, __mu(get<_Indx>(__bound_args), __args)...);
2042}
2043
Howard Hinnant324bb032010-08-22 00:02:43 +00002044template<class _F, class ..._BoundArgs>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002045class __bind
2046{
2047 _F __f_;
2048 tuple<_BoundArgs...> __bound_args_;
2049
2050 typedef typename __make_tuple_indices<sizeof...(_BoundArgs)>::type __indices;
2051public:
2052 template <class _G, class ..._BA>
2053 explicit __bind(_G&& __f, _BA&& ...__bound_args)
2054 : __f_(_STD::forward<_G>(__f)),
2055 __bound_args_(_STD::forward<_BA>(__bound_args)...) {}
2056
2057 template <class ..._Args>
2058 typename __bind_return<_F, tuple<_BoundArgs...>, tuple<_Args&&...> >::type
2059 operator()(_Args&& ...__args)
2060 {
2061 // compiler bug workaround
Howard Hinnant324bb032010-08-22 00:02:43 +00002062 return __apply_functor(__f_, __bound_args_, __indices(),
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002063 tuple<_Args&&...>(__args...));
2064 }
2065
2066 template <class ..._Args>
2067 typename __bind_return<_F, tuple<_BoundArgs...>, tuple<_Args&&...> >::type
2068 operator()(_Args&& ...__args) const
2069 {
Howard Hinnant324bb032010-08-22 00:02:43 +00002070 return __apply_functor(__f_, __bound_args_, __indices(),
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002071 tuple<_Args&&...>(__args...));
2072 }
2073};
2074
Howard Hinnant324bb032010-08-22 00:02:43 +00002075template<class _F, class ..._BoundArgs>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002076struct __is_bind_expression<__bind<_F, _BoundArgs...> > : public true_type {};
2077
Howard Hinnant324bb032010-08-22 00:02:43 +00002078template<class _R, class _F, class ..._BoundArgs>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002079class __bind_r
2080 : public __bind<_F, _BoundArgs...>
2081{
2082 typedef __bind<_F, _BoundArgs...> base;
2083public:
2084 typedef _R result_type;
2085
2086 template <class _G, class ..._BA>
2087 explicit __bind_r(_G&& __f, _BA&& ...__bound_args)
2088 : base(_STD::forward<_G>(__f),
2089 _STD::forward<_BA>(__bound_args)...) {}
2090
2091 template <class ..._Args>
2092 result_type
2093 operator()(_Args&& ...__args)
2094 {
2095 return base::operator()(_STD::forward<_Args>(__args)...);
2096 }
2097
2098 template <class ..._Args>
2099 result_type
2100 operator()(_Args&& ...__args) const
2101 {
2102 return base::operator()(_STD::forward<_Args>(__args)...);
2103 }
2104};
2105
Howard Hinnant324bb032010-08-22 00:02:43 +00002106template<class _R, class _F, class ..._BoundArgs>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002107struct __is_bind_expression<__bind_r<_R, _F, _BoundArgs...> > : public true_type {};
2108
Howard Hinnant324bb032010-08-22 00:02:43 +00002109template<class _F, class ..._BoundArgs>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002110inline _LIBCPP_INLINE_VISIBILITY
2111__bind<typename decay<_F>::type, typename decay<_BoundArgs>::type...>
2112bind(_F&& __f, _BoundArgs&&... __bound_args)
2113{
2114 typedef __bind<typename decay<_F>::type, typename decay<_BoundArgs>::type...> type;
2115 return type(_STD::forward<_F>(__f), _STD::forward<_BoundArgs>(__bound_args)...);
2116}
2117
Howard Hinnant324bb032010-08-22 00:02:43 +00002118template<class _R, class _F, class ..._BoundArgs>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002119inline _LIBCPP_INLINE_VISIBILITY
2120__bind_r<_R, typename decay<_F>::type, typename decay<_BoundArgs>::type...>
2121bind(_F&& __f, _BoundArgs&&... __bound_args)
2122{
2123 typedef __bind_r<_R, typename decay<_F>::type, typename decay<_BoundArgs>::type...> type;
2124 return type(_STD::forward<_F>(__f), _STD::forward<_BoundArgs>(__bound_args)...);
2125}
2126*/
2127
Howard Hinnant324bb032010-08-22 00:02:43 +00002128#endif // _LIBCPP_FUNCTIONAL_03