2 //===----------------------------------------------------------------------===//
4 // The LLVM Compiler Infrastructure
6 // This file is dual licensed under the MIT and the University of Illinois Open
7 // Source Licenses. See LICENSE.TXT for details.
9 //===----------------------------------------------------------------------===//
11 #ifndef _LIBCPP_FUNCTIONAL_03
12 #define _LIBCPP_FUNCTIONAL_03
14 // manual variadic expansion for <functional>
16 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
17 #pragma GCC system_header
20 namespace __function {
22 template<class _Fp> class __base;
27 __base(const __base&);
28 __base& operator=(const __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
43 template<class _Rp, class _A0>
44 class __base<_Rp(_A0)>
46 __base(const __base&);
47 __base& operator=(const __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
62 template<class _Rp, class _A0, class _A1>
63 class __base<_Rp(_A0, _A1)>
65 __base(const __base&);
66 __base& operator=(const __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
81 template<class _Rp, class _A0, class _A1, class _A2>
82 class __base<_Rp(_A0, _A1, _A2)>
84 __base(const __base&);
85 __base& operator=(const __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
100 template<class _FD, class _Alloc, class _FB> class __func;
102 template<class _Fp, class _Alloc, class _Rp>
103 class __func<_Fp, _Alloc, _Rp()>
104 : public __base<_Rp()>
106 __compressed_pair<_Fp, _Alloc> __f_;
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
121 template<class _Fp, class _Alloc, class _Rp>
123 __func<_Fp, _Alloc, _Rp()>::__clone() const
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();
134 template<class _Fp, class _Alloc, class _Rp>
136 __func<_Fp, _Alloc, _Rp()>::__clone(__base<_Rp()>* __p) const
138 ::new (__p) __func(__f_.first(), __f_.second());
141 template<class _Fp, class _Alloc, class _Rp>
143 __func<_Fp, _Alloc, _Rp()>::destroy()
145 __f_.~__compressed_pair<_Fp, _Alloc>();
148 template<class _Fp, class _Alloc, class _Rp>
150 __func<_Fp, _Alloc, _Rp()>::destroy_deallocate()
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);
159 template<class _Fp, class _Alloc, class _Rp>
161 __func<_Fp, _Alloc, _Rp()>::operator()()
163 typedef __invoke_void_return_wrapper<_Rp> _Invoker;
164 return _Invoker::__call(__f_.first());
167 #ifndef _LIBCPP_NO_RTTI
169 template<class _Fp, class _Alloc, class _Rp>
171 __func<_Fp, _Alloc, _Rp()>::target(const type_info& __ti) const
173 if (__ti == typeid(_Fp))
174 return &__f_.first();
175 return (const void*)0;
178 template<class _Fp, class _Alloc, class _Rp>
179 const std::type_info&
180 __func<_Fp, _Alloc, _Rp()>::target_type() const
185 #endif // _LIBCPP_NO_RTTI
187 template<class _Fp, class _Alloc, class _Rp, class _A0>
188 class __func<_Fp, _Alloc, _Rp(_A0)>
189 : public __base<_Rp(_A0)>
191 __compressed_pair<_Fp, _Alloc> __f_;
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
207 template<class _Fp, class _Alloc, class _Rp, class _A0>
209 __func<_Fp, _Alloc, _Rp(_A0)>::__clone() const
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();
220 template<class _Fp, class _Alloc, class _Rp, class _A0>
222 __func<_Fp, _Alloc, _Rp(_A0)>::__clone(__base<_Rp(_A0)>* __p) const
224 ::new (__p) __func(__f_.first(), __f_.second());
227 template<class _Fp, class _Alloc, class _Rp, class _A0>
229 __func<_Fp, _Alloc, _Rp(_A0)>::destroy()
231 __f_.~__compressed_pair<_Fp, _Alloc>();
234 template<class _Fp, class _Alloc, class _Rp, class _A0>
236 __func<_Fp, _Alloc, _Rp(_A0)>::destroy_deallocate()
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);
245 template<class _Fp, class _Alloc, class _Rp, class _A0>
247 __func<_Fp, _Alloc, _Rp(_A0)>::operator()(_A0 __a0)
249 typedef __invoke_void_return_wrapper<_Rp> _Invoker;
250 return _Invoker::__call(__f_.first(), __a0);
253 #ifndef _LIBCPP_NO_RTTI
255 template<class _Fp, class _Alloc, class _Rp, class _A0>
257 __func<_Fp, _Alloc, _Rp(_A0)>::target(const type_info& __ti) const
259 if (__ti == typeid(_Fp))
260 return &__f_.first();
261 return (const void*)0;
264 template<class _Fp, class _Alloc, class _Rp, class _A0>
265 const std::type_info&
266 __func<_Fp, _Alloc, _Rp(_A0)>::target_type() const
271 #endif // _LIBCPP_NO_RTTI
273 template<class _Fp, class _Alloc, class _Rp, class _A0, class _A1>
274 class __func<_Fp, _Alloc, _Rp(_A0, _A1)>
275 : public __base<_Rp(_A0, _A1)>
277 __compressed_pair<_Fp, _Alloc> __f_;
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
293 template<class _Fp, class _Alloc, class _Rp, class _A0, class _A1>
294 __base<_Rp(_A0, _A1)>*
295 __func<_Fp, _Alloc, _Rp(_A0, _A1)>::__clone() const
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();
306 template<class _Fp, class _Alloc, class _Rp, class _A0, class _A1>
308 __func<_Fp, _Alloc, _Rp(_A0, _A1)>::__clone(__base<_Rp(_A0, _A1)>* __p) const
310 ::new (__p) __func(__f_.first(), __f_.second());
313 template<class _Fp, class _Alloc, class _Rp, class _A0, class _A1>
315 __func<_Fp, _Alloc, _Rp(_A0, _A1)>::destroy()
317 __f_.~__compressed_pair<_Fp, _Alloc>();
320 template<class _Fp, class _Alloc, class _Rp, class _A0, class _A1>
322 __func<_Fp, _Alloc, _Rp(_A0, _A1)>::destroy_deallocate()
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);
331 template<class _Fp, class _Alloc, class _Rp, class _A0, class _A1>
333 __func<_Fp, _Alloc, _Rp(_A0, _A1)>::operator()(_A0 __a0, _A1 __a1)
335 typedef __invoke_void_return_wrapper<_Rp> _Invoker;
336 return _Invoker::__call(__f_.first(), __a0, __a1);
339 #ifndef _LIBCPP_NO_RTTI
341 template<class _Fp, class _Alloc, class _Rp, class _A0, class _A1>
343 __func<_Fp, _Alloc, _Rp(_A0, _A1)>::target(const type_info& __ti) const
345 if (__ti == typeid(_Fp))
346 return &__f_.first();
347 return (const void*)0;
350 template<class _Fp, class _Alloc, class _Rp, class _A0, class _A1>
351 const std::type_info&
352 __func<_Fp, _Alloc, _Rp(_A0, _A1)>::target_type() const
357 #endif // _LIBCPP_NO_RTTI
359 template<class _Fp, class _Alloc, class _Rp, class _A0, class _A1, class _A2>
360 class __func<_Fp, _Alloc, _Rp(_A0, _A1, _A2)>
361 : public __base<_Rp(_A0, _A1, _A2)>
363 __compressed_pair<_Fp, _Alloc> __f_;
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
379 template<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
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();
392 template<class _Fp, class _Alloc, class _Rp, class _A0, class _A1, class _A2>
394 __func<_Fp, _Alloc, _Rp(_A0, _A1, _A2)>::__clone(__base<_Rp(_A0, _A1, _A2)>* __p) const
396 ::new (__p) __func(__f_.first(), __f_.second());
399 template<class _Fp, class _Alloc, class _Rp, class _A0, class _A1, class _A2>
401 __func<_Fp, _Alloc, _Rp(_A0, _A1, _A2)>::destroy()
403 __f_.~__compressed_pair<_Fp, _Alloc>();
406 template<class _Fp, class _Alloc, class _Rp, class _A0, class _A1, class _A2>
408 __func<_Fp, _Alloc, _Rp(_A0, _A1, _A2)>::destroy_deallocate()
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);
417 template<class _Fp, class _Alloc, class _Rp, class _A0, class _A1, class _A2>
419 __func<_Fp, _Alloc, _Rp(_A0, _A1, _A2)>::operator()(_A0 __a0, _A1 __a1, _A2 __a2)
421 typedef __invoke_void_return_wrapper<_Rp> _Invoker;
422 return _Invoker::__call(__f_.first(), __a0, __a1, __a2);
425 #ifndef _LIBCPP_NO_RTTI
427 template<class _Fp, class _Alloc, class _Rp, class _A0, class _A1, class _A2>
429 __func<_Fp, _Alloc, _Rp(_A0, _A1, _A2)>::target(const type_info& __ti) const
431 if (__ti == typeid(_Fp))
432 return &__f_.first();
433 return (const void*)0;
436 template<class _Fp, class _Alloc, class _Rp, class _A0, class _A1, class _A2>
437 const std::type_info&
438 __func<_Fp, _Alloc, _Rp(_A0, _A1, _A2)>::target_type() const
443 #endif // _LIBCPP_NO_RTTI
448 class _LIBCPP_TEMPLATE_VIS function<_Rp()>
450 typedef __function::__base<_Rp()> __base;
451 aligned_storage<3*sizeof(void*)>::type __buf_;
455 typedef _Rp result_type;
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&);
463 typename enable_if<!is_integral<_Fp>::value>::type* = 0);
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);
477 function& operator=(const function&);
478 function& operator=(nullptr_t);
482 !is_integral<_Fp>::value,
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);}
496 // 20.7.16.2.3, function capacity:
497 _LIBCPP_INLINE_VISIBILITY operator bool() const {return __f_;}
500 // deleted overloads close possible hole in the type system
502 bool operator==(const function<_R2()>&) const;// = delete;
504 bool operator!=(const function<_R2()>&) const;// = delete;
506 // 20.7.16.2.4, function invocation:
507 _Rp operator()() const;
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
518 function<_Rp()>::function(const function& __f)
522 else if (__f.__f_ == (const __base*)&__f.__buf_)
524 __f_ = (__base*)&__buf_;
525 __f.__f_->__clone(__f_);
528 __f_ = __f.__f_->__clone();
532 template<class _Alloc>
533 function<_Rp()>::function(allocator_arg_t, const _Alloc&, const function& __f)
537 else if (__f.__f_ == (const __base*)&__f.__buf_)
539 __f_ = (__base*)&__buf_;
540 __f.__f_->__clone(__f_);
543 __f_ = __f.__f_->__clone();
548 function<_Rp()>::function(_Fp __f,
549 typename enable_if<!is_integral<_Fp>::value>::type*)
552 if (__function::__not_null(__f))
554 typedef __function::__func<_Fp, allocator<_Fp>, _Rp()> _FF;
555 if (sizeof(_FF) <= sizeof(__buf_))
557 __f_ = (__base*)&__buf_;
558 ::new (__f_) _FF(__f);
562 typedef allocator<_FF> _Ap;
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();
573 template <class _Fp, class _Alloc>
574 function<_Rp()>::function(allocator_arg_t, const _Alloc& __a0, _Fp __f,
575 typename enable_if<!is_integral<_Fp>::value>::type*)
578 typedef allocator_traits<_Alloc> __alloc_traits;
579 if (__function::__not_null(__f))
581 typedef __function::__func<_Fp, _Alloc, _Rp()> _FF;
582 if (sizeof(_FF) <= sizeof(__buf_))
584 __f_ = (__base*)&__buf_;
585 ::new (__f_) _FF(__f, __a0);
589 typedef typename __rebind_alloc_helper<__alloc_traits, _FF>::type _Ap;
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();
601 function<_Rp()>::operator=(const function& __f)
604 function(__f).swap(*this);
612 function<_Rp()>::operator=(nullptr_t)
616 if (__t == (__base*)&__buf_)
619 __t->destroy_deallocate();
627 !is_integral<_Fp>::value,
630 function<_Rp()>::operator=(_Fp __f)
632 function(_VSTD::move(__f)).swap(*this);
637 function<_Rp()>::~function()
639 if (__f_ == (__base*)&__buf_)
642 __f_->destroy_deallocate();
647 function<_Rp()>::swap(function& __f)
649 if (_VSTD::addressof(__f) == this)
651 if (__f_ == (__base*)&__buf_ && __f.__f_ == (__base*)&__f.__buf_)
653 typename aligned_storage<sizeof(__buf_)>::type __tempbuf;
654 __base* __t = (__base*)&__tempbuf;
658 __f.__f_->__clone((__base*)&__buf_);
661 __f_ = (__base*)&__buf_;
662 __t->__clone((__base*)&__f.__buf_);
664 __f.__f_ = (__base*)&__f.__buf_;
666 else if (__f_ == (__base*)&__buf_)
668 __f_->__clone((__base*)&__f.__buf_);
671 __f.__f_ = (__base*)&__f.__buf_;
673 else if (__f.__f_ == (__base*)&__f.__buf_)
675 __f.__f_->__clone((__base*)&__buf_);
678 __f_ = (__base*)&__buf_;
681 _VSTD::swap(__f_, __f.__f_);
686 function<_Rp()>::operator()() const
689 __throw_bad_function_call();
693 #ifndef _LIBCPP_NO_RTTI
696 const std::type_info&
697 function<_Rp()>::target_type() const
701 return __f_->target_type();
705 template <typename _Tp>
707 function<_Rp()>::target()
711 return (_Tp*) const_cast<void *>(__f_->target(typeid(_Tp)));
715 template <typename _Tp>
717 function<_Rp()>::target() const
720 return (const _Tp*)0;
721 return (const _Tp*)__f_->target(typeid(_Tp));
724 #endif // _LIBCPP_NO_RTTI
726 template<class _Rp, class _A0>
727 class _LIBCPP_TEMPLATE_VIS function<_Rp(_A0)>
728 : public unary_function<_A0, _Rp>
730 typedef __function::__base<_Rp(_A0)> __base;
731 aligned_storage<3*sizeof(void*)>::type __buf_;
735 typedef _Rp result_type;
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&);
743 typename enable_if<!is_integral<_Fp>::value>::type* = 0);
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);
757 function& operator=(const function&);
758 function& operator=(nullptr_t);
762 !is_integral<_Fp>::value,
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);}
776 // 20.7.16.2.3, function capacity:
777 _LIBCPP_INLINE_VISIBILITY operator bool() const {return __f_;}
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;
786 // 20.7.16.2.4, function invocation:
787 _Rp operator()(_A0) const;
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
797 template<class _Rp, class _A0>
798 function<_Rp(_A0)>::function(const function& __f)
802 else if (__f.__f_ == (const __base*)&__f.__buf_)
804 __f_ = (__base*)&__buf_;
805 __f.__f_->__clone(__f_);
808 __f_ = __f.__f_->__clone();
811 template<class _Rp, class _A0>
812 template<class _Alloc>
813 function<_Rp(_A0)>::function(allocator_arg_t, const _Alloc&, const function& __f)
817 else if (__f.__f_ == (const __base*)&__f.__buf_)
819 __f_ = (__base*)&__buf_;
820 __f.__f_->__clone(__f_);
823 __f_ = __f.__f_->__clone();
826 template<class _Rp, class _A0>
828 function<_Rp(_A0)>::function(_Fp __f,
829 typename enable_if<!is_integral<_Fp>::value>::type*)
832 if (__function::__not_null(__f))
834 typedef __function::__func<_Fp, allocator<_Fp>, _Rp(_A0)> _FF;
835 if (sizeof(_FF) <= sizeof(__buf_))
837 __f_ = (__base*)&__buf_;
838 ::new (__f_) _FF(__f);
842 typedef allocator<_FF> _Ap;
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();
852 template<class _Rp, class _A0>
853 template <class _Fp, class _Alloc>
854 function<_Rp(_A0)>::function(allocator_arg_t, const _Alloc& __a0, _Fp __f,
855 typename enable_if<!is_integral<_Fp>::value>::type*)
858 typedef allocator_traits<_Alloc> __alloc_traits;
859 if (__function::__not_null(__f))
861 typedef __function::__func<_Fp, _Alloc, _Rp(_A0)> _FF;
862 if (sizeof(_FF) <= sizeof(__buf_))
864 __f_ = (__base*)&__buf_;
865 ::new (__f_) _FF(__f, __a0);
869 typedef typename __rebind_alloc_helper<__alloc_traits, _FF>::type _Ap;
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();
879 template<class _Rp, class _A0>
881 function<_Rp(_A0)>::operator=(const function& __f)
884 function(__f).swap(*this);
890 template<class _Rp, class _A0>
892 function<_Rp(_A0)>::operator=(nullptr_t)
896 if (__t == (__base*)&__buf_)
899 __t->destroy_deallocate();
903 template<class _Rp, class _A0>
907 !is_integral<_Fp>::value,
910 function<_Rp(_A0)>::operator=(_Fp __f)
912 function(_VSTD::move(__f)).swap(*this);
916 template<class _Rp, class _A0>
917 function<_Rp(_A0)>::~function()
919 if (__f_ == (__base*)&__buf_)
922 __f_->destroy_deallocate();
925 template<class _Rp, class _A0>
927 function<_Rp(_A0)>::swap(function& __f)
929 if (_VSTD::addressof(__f) == this)
931 if (__f_ == (__base*)&__buf_ && __f.__f_ == (__base*)&__f.__buf_)
933 typename aligned_storage<sizeof(__buf_)>::type __tempbuf;
934 __base* __t = (__base*)&__tempbuf;
938 __f.__f_->__clone((__base*)&__buf_);
941 __f_ = (__base*)&__buf_;
942 __t->__clone((__base*)&__f.__buf_);
944 __f.__f_ = (__base*)&__f.__buf_;
946 else if (__f_ == (__base*)&__buf_)
948 __f_->__clone((__base*)&__f.__buf_);
951 __f.__f_ = (__base*)&__f.__buf_;
953 else if (__f.__f_ == (__base*)&__f.__buf_)
955 __f.__f_->__clone((__base*)&__buf_);
958 __f_ = (__base*)&__buf_;
961 _VSTD::swap(__f_, __f.__f_);
964 template<class _Rp, class _A0>
966 function<_Rp(_A0)>::operator()(_A0 __a0) const
969 __throw_bad_function_call();
970 return (*__f_)(__a0);
973 #ifndef _LIBCPP_NO_RTTI
975 template<class _Rp, class _A0>
976 const std::type_info&
977 function<_Rp(_A0)>::target_type() const
981 return __f_->target_type();
984 template<class _Rp, class _A0>
985 template <typename _Tp>
987 function<_Rp(_A0)>::target()
991 return (_Tp*) const_cast<void *>(__f_->target(typeid(_Tp)));
994 template<class _Rp, class _A0>
995 template <typename _Tp>
997 function<_Rp(_A0)>::target() const
1000 return (const _Tp*)0;
1001 return (const _Tp*)__f_->target(typeid(_Tp));
1004 #endif // _LIBCPP_NO_RTTI
1006 template<class _Rp, class _A0, class _A1>
1007 class _LIBCPP_TEMPLATE_VIS function<_Rp(_A0, _A1)>
1008 : public binary_function<_A0, _A1, _Rp>
1010 typedef __function::__base<_Rp(_A0, _A1)> __base;
1011 aligned_storage<3*sizeof(void*)>::type __buf_;
1015 typedef _Rp result_type;
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&);
1023 typename enable_if<!is_integral<_Fp>::value>::type* = 0);
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);
1037 function& operator=(const function&);
1038 function& operator=(nullptr_t);
1042 !is_integral<_Fp>::value,
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);}
1056 // 20.7.16.2.3, function capacity:
1057 operator bool() const {return __f_;}
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;
1066 // 20.7.16.2.4, function invocation:
1067 _Rp operator()(_A0, _A1) const;
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
1077 template<class _Rp, class _A0, class _A1>
1078 function<_Rp(_A0, _A1)>::function(const function& __f)
1082 else if (__f.__f_ == (const __base*)&__f.__buf_)
1084 __f_ = (__base*)&__buf_;
1085 __f.__f_->__clone(__f_);
1088 __f_ = __f.__f_->__clone();
1091 template<class _Rp, class _A0, class _A1>
1092 template<class _Alloc>
1093 function<_Rp(_A0, _A1)>::function(allocator_arg_t, const _Alloc&, const function& __f)
1097 else if (__f.__f_ == (const __base*)&__f.__buf_)
1099 __f_ = (__base*)&__buf_;
1100 __f.__f_->__clone(__f_);
1103 __f_ = __f.__f_->__clone();
1106 template<class _Rp, class _A0, class _A1>
1107 template <class _Fp>
1108 function<_Rp(_A0, _A1)>::function(_Fp __f,
1109 typename enable_if<!is_integral<_Fp>::value>::type*)
1112 if (__function::__not_null(__f))
1114 typedef __function::__func<_Fp, allocator<_Fp>, _Rp(_A0, _A1)> _FF;
1115 if (sizeof(_FF) <= sizeof(__buf_))
1117 __f_ = (__base*)&__buf_;
1118 ::new (__f_) _FF(__f);
1122 typedef allocator<_FF> _Ap;
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();
1132 template<class _Rp, class _A0, class _A1>
1133 template <class _Fp, class _Alloc>
1134 function<_Rp(_A0, _A1)>::function(allocator_arg_t, const _Alloc& __a0, _Fp __f,
1135 typename enable_if<!is_integral<_Fp>::value>::type*)
1138 typedef allocator_traits<_Alloc> __alloc_traits;
1139 if (__function::__not_null(__f))
1141 typedef __function::__func<_Fp, _Alloc, _Rp(_A0, _A1)> _FF;
1142 if (sizeof(_FF) <= sizeof(__buf_))
1144 __f_ = (__base*)&__buf_;
1145 ::new (__f_) _FF(__f, __a0);
1149 typedef typename __rebind_alloc_helper<__alloc_traits, _FF>::type _Ap;
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();
1159 template<class _Rp, class _A0, class _A1>
1160 function<_Rp(_A0, _A1)>&
1161 function<_Rp(_A0, _A1)>::operator=(const function& __f)
1164 function(__f).swap(*this);
1170 template<class _Rp, class _A0, class _A1>
1171 function<_Rp(_A0, _A1)>&
1172 function<_Rp(_A0, _A1)>::operator=(nullptr_t)
1176 if (__t == (__base*)&__buf_)
1179 __t->destroy_deallocate();
1183 template<class _Rp, class _A0, class _A1>
1184 template <class _Fp>
1187 !is_integral<_Fp>::value,
1188 function<_Rp(_A0, _A1)>&
1190 function<_Rp(_A0, _A1)>::operator=(_Fp __f)
1192 function(_VSTD::move(__f)).swap(*this);
1196 template<class _Rp, class _A0, class _A1>
1197 function<_Rp(_A0, _A1)>::~function()
1199 if (__f_ == (__base*)&__buf_)
1202 __f_->destroy_deallocate();
1205 template<class _Rp, class _A0, class _A1>
1207 function<_Rp(_A0, _A1)>::swap(function& __f)
1209 if (_VSTD::addressof(__f) == this)
1211 if (__f_ == (__base*)&__buf_ && __f.__f_ == (__base*)&__f.__buf_)
1213 typename aligned_storage<sizeof(__buf_)>::type __tempbuf;
1214 __base* __t = (__base*)&__tempbuf;
1218 __f.__f_->__clone((__base*)&__buf_);
1219 __f.__f_->destroy();
1221 __f_ = (__base*)&__buf_;
1222 __t->__clone((__base*)&__f.__buf_);
1224 __f.__f_ = (__base*)&__f.__buf_;
1226 else if (__f_ == (__base*)&__buf_)
1228 __f_->__clone((__base*)&__f.__buf_);
1231 __f.__f_ = (__base*)&__f.__buf_;
1233 else if (__f.__f_ == (__base*)&__f.__buf_)
1235 __f.__f_->__clone((__base*)&__buf_);
1236 __f.__f_->destroy();
1238 __f_ = (__base*)&__buf_;
1241 _VSTD::swap(__f_, __f.__f_);
1244 template<class _Rp, class _A0, class _A1>
1246 function<_Rp(_A0, _A1)>::operator()(_A0 __a0, _A1 __a1) const
1249 __throw_bad_function_call();
1250 return (*__f_)(__a0, __a1);
1253 #ifndef _LIBCPP_NO_RTTI
1255 template<class _Rp, class _A0, class _A1>
1256 const std::type_info&
1257 function<_Rp(_A0, _A1)>::target_type() const
1260 return typeid(void);
1261 return __f_->target_type();
1264 template<class _Rp, class _A0, class _A1>
1265 template <typename _Tp>
1267 function<_Rp(_A0, _A1)>::target()
1271 return (_Tp*) const_cast<void *>(__f_->target(typeid(_Tp)));
1274 template<class _Rp, class _A0, class _A1>
1275 template <typename _Tp>
1277 function<_Rp(_A0, _A1)>::target() const
1280 return (const _Tp*)0;
1281 return (const _Tp*)__f_->target(typeid(_Tp));
1284 #endif // _LIBCPP_NO_RTTI
1286 template<class _Rp, class _A0, class _A1, class _A2>
1287 class _LIBCPP_TEMPLATE_VIS function<_Rp(_A0, _A1, _A2)>
1289 typedef __function::__base<_Rp(_A0, _A1, _A2)> __base;
1290 aligned_storage<3*sizeof(void*)>::type __buf_;
1294 typedef _Rp result_type;
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&);
1302 typename enable_if<!is_integral<_Fp>::value>::type* = 0);
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);
1316 function& operator=(const function&);
1317 function& operator=(nullptr_t);
1321 !is_integral<_Fp>::value,
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);}
1335 // 20.7.16.2.3, function capacity:
1336 _LIBCPP_INLINE_VISIBILITY operator bool() const {return __f_;}
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;
1345 // 20.7.16.2.4, function invocation:
1346 _Rp operator()(_A0, _A1, _A2) const;
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
1356 template<class _Rp, class _A0, class _A1, class _A2>
1357 function<_Rp(_A0, _A1, _A2)>::function(const function& __f)
1361 else if (__f.__f_ == (const __base*)&__f.__buf_)
1363 __f_ = (__base*)&__buf_;
1364 __f.__f_->__clone(__f_);
1367 __f_ = __f.__f_->__clone();
1370 template<class _Rp, class _A0, class _A1, class _A2>
1371 template<class _Alloc>
1372 function<_Rp(_A0, _A1, _A2)>::function(allocator_arg_t, const _Alloc&,
1373 const function& __f)
1377 else if (__f.__f_ == (const __base*)&__f.__buf_)
1379 __f_ = (__base*)&__buf_;
1380 __f.__f_->__clone(__f_);
1383 __f_ = __f.__f_->__clone();
1386 template<class _Rp, class _A0, class _A1, class _A2>
1387 template <class _Fp>
1388 function<_Rp(_A0, _A1, _A2)>::function(_Fp __f,
1389 typename enable_if<!is_integral<_Fp>::value>::type*)
1392 if (__function::__not_null(__f))
1394 typedef __function::__func<_Fp, allocator<_Fp>, _Rp(_A0, _A1, _A2)> _FF;
1395 if (sizeof(_FF) <= sizeof(__buf_))
1397 __f_ = (__base*)&__buf_;
1398 ::new (__f_) _FF(__f);
1402 typedef allocator<_FF> _Ap;
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();
1412 template<class _Rp, class _A0, class _A1, class _A2>
1413 template <class _Fp, class _Alloc>
1414 function<_Rp(_A0, _A1, _A2)>::function(allocator_arg_t, const _Alloc& __a0, _Fp __f,
1415 typename enable_if<!is_integral<_Fp>::value>::type*)
1418 typedef allocator_traits<_Alloc> __alloc_traits;
1419 if (__function::__not_null(__f))
1421 typedef __function::__func<_Fp, _Alloc, _Rp(_A0, _A1, _A2)> _FF;
1422 if (sizeof(_FF) <= sizeof(__buf_))
1424 __f_ = (__base*)&__buf_;
1425 ::new (__f_) _FF(__f, __a0);
1429 typedef typename __rebind_alloc_helper<__alloc_traits, _FF>::type _Ap;
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();
1439 template<class _Rp, class _A0, class _A1, class _A2>
1440 function<_Rp(_A0, _A1, _A2)>&
1441 function<_Rp(_A0, _A1, _A2)>::operator=(const function& __f)
1444 function(__f).swap(*this);
1450 template<class _Rp, class _A0, class _A1, class _A2>
1451 function<_Rp(_A0, _A1, _A2)>&
1452 function<_Rp(_A0, _A1, _A2)>::operator=(nullptr_t)
1456 if (__t == (__base*)&__buf_)
1459 __t->destroy_deallocate();
1463 template<class _Rp, class _A0, class _A1, class _A2>
1464 template <class _Fp>
1467 !is_integral<_Fp>::value,
1468 function<_Rp(_A0, _A1, _A2)>&
1470 function<_Rp(_A0, _A1, _A2)>::operator=(_Fp __f)
1472 function(_VSTD::move(__f)).swap(*this);
1476 template<class _Rp, class _A0, class _A1, class _A2>
1477 function<_Rp(_A0, _A1, _A2)>::~function()
1479 if (__f_ == (__base*)&__buf_)
1482 __f_->destroy_deallocate();
1485 template<class _Rp, class _A0, class _A1, class _A2>
1487 function<_Rp(_A0, _A1, _A2)>::swap(function& __f)
1489 if (_VSTD::addressof(__f) == this)
1491 if (__f_ == (__base*)&__buf_ && __f.__f_ == (__base*)&__f.__buf_)
1493 typename aligned_storage<sizeof(__buf_)>::type __tempbuf;
1494 __base* __t = (__base*)&__tempbuf;
1498 __f.__f_->__clone((__base*)&__buf_);
1499 __f.__f_->destroy();
1501 __f_ = (__base*)&__buf_;
1502 __t->__clone((__base*)&__f.__buf_);
1504 __f.__f_ = (__base*)&__f.__buf_;
1506 else if (__f_ == (__base*)&__buf_)
1508 __f_->__clone((__base*)&__f.__buf_);
1511 __f.__f_ = (__base*)&__f.__buf_;
1513 else if (__f.__f_ == (__base*)&__f.__buf_)
1515 __f.__f_->__clone((__base*)&__buf_);
1516 __f.__f_->destroy();
1518 __f_ = (__base*)&__buf_;
1521 _VSTD::swap(__f_, __f.__f_);
1524 template<class _Rp, class _A0, class _A1, class _A2>
1526 function<_Rp(_A0, _A1, _A2)>::operator()(_A0 __a0, _A1 __a1, _A2 __a2) const
1529 __throw_bad_function_call();
1530 return (*__f_)(__a0, __a1, __a2);
1533 #ifndef _LIBCPP_NO_RTTI
1535 template<class _Rp, class _A0, class _A1, class _A2>
1536 const std::type_info&
1537 function<_Rp(_A0, _A1, _A2)>::target_type() const
1540 return typeid(void);
1541 return __f_->target_type();
1544 template<class _Rp, class _A0, class _A1, class _A2>
1545 template <typename _Tp>
1547 function<_Rp(_A0, _A1, _A2)>::target()
1551 return (_Tp*) const_cast<void *>(__f_->target(typeid(_Tp)));
1554 template<class _Rp, class _A0, class _A1, class _A2>
1555 template <typename _Tp>
1557 function<_Rp(_A0, _A1, _A2)>::target() const
1560 return (const _Tp*)0;
1561 return (const _Tp*)__f_->target(typeid(_Tp));
1564 #endif // _LIBCPP_NO_RTTI
1566 template <class _Fp>
1567 inline _LIBCPP_INLINE_VISIBILITY
1569 operator==(const function<_Fp>& __f, nullptr_t) {return !__f;}
1571 template <class _Fp>
1572 inline _LIBCPP_INLINE_VISIBILITY
1574 operator==(nullptr_t, const function<_Fp>& __f) {return !__f;}
1576 template <class _Fp>
1577 inline _LIBCPP_INLINE_VISIBILITY
1579 operator!=(const function<_Fp>& __f, nullptr_t) {return (bool)__f;}
1581 template <class _Fp>
1582 inline _LIBCPP_INLINE_VISIBILITY
1584 operator!=(nullptr_t, const function<_Fp>& __f) {return (bool)__f;}
1586 template <class _Fp>
1587 inline _LIBCPP_INLINE_VISIBILITY
1589 swap(function<_Fp>& __x, function<_Fp>& __y)
1590 {return __x.swap(__y);}
1592 #endif // _LIBCPP_FUNCTIONAL_03