1// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef _LIBCPP___FUNCTIONAL_FUNCTION_H
11#define _LIBCPP___FUNCTIONAL_FUNCTION_H
12
13#include <__assert>
14#include <__config>
15#include <__cstddef/nullptr_t.h>
16#include <__exception/exception.h>
17#include <__functional/binary_function.h>
18#include <__functional/unary_function.h>
19#include <__memory/addressof.h>
20#include <__type_traits/aligned_storage.h>
21#include <__type_traits/decay.h>
22#include <__type_traits/invoke.h>
23#include <__type_traits/is_scalar.h>
24#include <__type_traits/is_trivially_constructible.h>
25#include <__type_traits/is_trivially_destructible.h>
26#include <__type_traits/strip_signature.h>
27#include <__utility/forward.h>
28#include <__utility/move.h>
29#include <__utility/swap.h>
30#include <tuple>
31#include <typeinfo>
32
33#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
34# pragma GCC system_header
35#endif
36
37_LIBCPP_PUSH_MACROS
38#include <__undef_macros>
39
40#ifndef _LIBCPP_CXX03_LANG
41
42_LIBCPP_BEGIN_NAMESPACE_STD
43
44// bad_function_call
45
46_LIBCPP_DIAGNOSTIC_PUSH
47# if !_LIBCPP_AVAILABILITY_HAS_BAD_FUNCTION_CALL_KEY_FUNCTION
48_LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wweak-vtables")
49# endif
50class _LIBCPP_EXPORTED_FROM_ABI bad_function_call : public exception {
51public:
52 _LIBCPP_HIDE_FROM_ABI bad_function_call() _NOEXCEPT = default;
53 _LIBCPP_HIDE_FROM_ABI bad_function_call(const bad_function_call&) _NOEXCEPT = default;
54 _LIBCPP_HIDE_FROM_ABI bad_function_call& operator=(const bad_function_call&) _NOEXCEPT = default;
55// Note that when a key function is not used, every translation unit that uses
56// bad_function_call will end up containing a weak definition of the vtable and
57// typeinfo.
58# if _LIBCPP_AVAILABILITY_HAS_BAD_FUNCTION_CALL_KEY_FUNCTION
59 ~bad_function_call() _NOEXCEPT override;
60# else
61 _LIBCPP_HIDE_FROM_ABI_VIRTUAL ~bad_function_call() _NOEXCEPT override {}
62# endif
63
64# if _LIBCPP_AVAILABILITY_HAS_BAD_FUNCTION_CALL_GOOD_WHAT_MESSAGE
65 const char* what() const _NOEXCEPT override;
66# endif
67};
68_LIBCPP_DIAGNOSTIC_POP
69
70[[__noreturn__]] inline _LIBCPP_HIDE_FROM_ABI void __throw_bad_function_call() {
71# if _LIBCPP_HAS_EXCEPTIONS
72 throw bad_function_call();
73# else
74 _LIBCPP_VERBOSE_ABORT("bad_function_call was thrown in -fno-exceptions mode");
75# endif
76}
77
78template <class _Fp>
79class function; // undefined
80
81namespace __function {
82
83template <class _Rp>
84struct __maybe_derive_from_unary_function {};
85
86template <class _Rp, class _A1>
87struct __maybe_derive_from_unary_function<_Rp(_A1)> : public __unary_function<_A1, _Rp> {};
88
89template <class _Rp>
90struct __maybe_derive_from_binary_function {};
91
92template <class _Rp, class _A1, class _A2>
93struct __maybe_derive_from_binary_function<_Rp(_A1, _A2)> : public __binary_function<_A1, _A2, _Rp> {};
94
95template <class _Fp>
96_LIBCPP_HIDE_FROM_ABI bool __is_null(_Fp const&) {
97 return false;
98}
99
100template <class _Fp>
101_LIBCPP_HIDE_FROM_ABI bool __is_null(_Fp* __ptr) {
102 return !__ptr;
103}
104
105template <class _Ret, class _Class>
106_LIBCPP_HIDE_FROM_ABI bool __is_null(_Ret _Class::* __ptr) {
107 return !__ptr;
108}
109
110template <class _Fp>
111_LIBCPP_HIDE_FROM_ABI bool __is_null(function<_Fp> const& __f) {
112 return !__f;
113}
114
115# if __has_extension(blocks)
116template <class _Rp, class... _Args>
117_LIBCPP_HIDE_FROM_ABI bool __is_null(_Rp (^__p)(_Args...)) {
118 return !__p;
119}
120# endif
121
122} // namespace __function
123
124namespace __function {
125
126// __base provides an abstract interface for copyable functors.
127
128template <class _Fp>
129class __base;
130
131template <class _Rp, class... _ArgTypes>
132class __base<_Rp(_ArgTypes...)> {
133public:
134 __base(const __base&) = delete;
135 __base& operator=(const __base&) = delete;
136
137 _LIBCPP_HIDE_FROM_ABI __base() {}
138 _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual ~__base() {}
139 virtual __base* __clone() const = 0;
140 virtual void __clone(__base*) const = 0;
141 virtual void destroy() _NOEXCEPT = 0;
142 virtual void destroy_deallocate() _NOEXCEPT = 0;
143 virtual _Rp operator()(_ArgTypes&&...) = 0;
144# if _LIBCPP_HAS_RTTI
145 virtual const void* target(const type_info&) const _NOEXCEPT = 0;
146 virtual const std::type_info& target_type() const _NOEXCEPT = 0;
147# endif // _LIBCPP_HAS_RTTI
148};
149
150// __func implements __base for a given functor type.
151
152template <class _FD, class _FB>
153class __func;
154
155template <class _Fp, class _Rp, class... _ArgTypes>
156class __func<_Fp, _Rp(_ArgTypes...)> : public __base<_Rp(_ArgTypes...)> {
157 _Fp __func_;
158
159public:
160 _LIBCPP_HIDE_FROM_ABI explicit __func(_Fp&& __f) : __func_(std::move(__f)) {}
161 _LIBCPP_HIDE_FROM_ABI explicit __func(const _Fp& __f) : __func_(__f) {}
162
163 _LIBCPP_HIDE_FROM_ABI_VIRTUAL __base<_Rp(_ArgTypes...)>* __clone() const override { return new __func(__func_); }
164
165 _LIBCPP_HIDE_FROM_ABI_VIRTUAL void __clone(__base<_Rp(_ArgTypes...)>* __p) const override {
166 ::new ((void*)__p) __func(__func_);
167 }
168
169 _LIBCPP_HIDE_FROM_ABI_VIRTUAL void destroy() _NOEXCEPT override { __func_.~_Fp(); }
170 _LIBCPP_HIDE_FROM_ABI_VIRTUAL void destroy_deallocate() _NOEXCEPT override { delete this; }
171 _LIBCPP_HIDE_FROM_ABI_VIRTUAL _Rp operator()(_ArgTypes&&... __arg) override {
172 return std::__invoke_r<_Rp>(__func_, std::forward<_ArgTypes>(__arg)...);
173 }
174# if _LIBCPP_HAS_RTTI
175 _LIBCPP_HIDE_FROM_ABI_VIRTUAL const void* target(const type_info& __ti) const _NOEXCEPT override {
176 if (__ti == typeid(_Fp))
177 return std::addressof(__func_);
178 return nullptr;
179 }
180 _LIBCPP_HIDE_FROM_ABI_VIRTUAL const std::type_info& target_type() const _NOEXCEPT override { return typeid(_Fp); }
181# endif // _LIBCPP_HAS_RTTI
182};
183
184// __value_func creates a value-type from a __func.
185
186template <class _Fp>
187class __value_func;
188
189template <class _Rp, class... _ArgTypes>
190class __value_func<_Rp(_ArgTypes...)> {
191 _LIBCPP_SUPPRESS_DEPRECATED_PUSH
192 typename aligned_storage<3 * sizeof(void*)>::type __buf_;
193 _LIBCPP_SUPPRESS_DEPRECATED_POP
194
195 typedef __base<_Rp(_ArgTypes...)> __func;
196 __func* __f_;
197
198 _LIBCPP_HIDE_FROM_ABI _LIBCPP_NO_CFI static __func* __as_base(void* __p) { return reinterpret_cast<__func*>(__p); }
199
200public:
201 _LIBCPP_HIDE_FROM_ABI __value_func() _NOEXCEPT : __f_(nullptr) {}
202
203 template <class _Fp, __enable_if_t<!is_same<__decay_t<_Fp>, __value_func>::value, int> = 0>
204 _LIBCPP_HIDE_FROM_ABI explicit __value_func(_Fp&& __f) : __f_(nullptr) {
205 typedef __function::__func<_Fp, _Rp(_ArgTypes...)> _Fun;
206
207 if (__function::__is_null(__f))
208 return;
209
210 if (sizeof(_Fun) <= sizeof(__buf_) && is_nothrow_copy_constructible<_Fp>::value) {
211 __f_ = ::new (std::addressof(__buf_)) _Fun(std::move(__f));
212 } else {
213 __f_ = new _Fun(std::move(__f));
214 }
215 }
216
217 _LIBCPP_HIDE_FROM_ABI __value_func(const __value_func& __f) {
218 if (__f.__f_ == nullptr)
219 __f_ = nullptr;
220 else if ((void*)__f.__f_ == &__f.__buf_) {
221 __f_ = __as_base(&__buf_);
222 __f.__f_->__clone(__f_);
223 } else
224 __f_ = __f.__f_->__clone();
225 }
226
227 _LIBCPP_HIDE_FROM_ABI __value_func(__value_func&& __f) _NOEXCEPT {
228 if (__f.__f_ == nullptr)
229 __f_ = nullptr;
230 else if ((void*)__f.__f_ == &__f.__buf_) {
231 __f_ = __as_base(&__buf_);
232 __f.__f_->__clone(__f_);
233 } else {
234 __f_ = __f.__f_;
235 __f.__f_ = nullptr;
236 }
237 }
238
239 _LIBCPP_HIDE_FROM_ABI ~__value_func() {
240 if ((void*)__f_ == &__buf_)
241 __f_->destroy();
242 else if (__f_)
243 __f_->destroy_deallocate();
244 }
245
246 _LIBCPP_HIDE_FROM_ABI __value_func& operator=(__value_func&& __f) {
247 *this = nullptr;
248 if (__f.__f_ == nullptr)
249 __f_ = nullptr;
250 else if ((void*)__f.__f_ == &__f.__buf_) {
251 __f_ = __as_base(&__buf_);
252 __f.__f_->__clone(__f_);
253 } else {
254 __f_ = __f.__f_;
255 __f.__f_ = nullptr;
256 }
257 return *this;
258 }
259
260 _LIBCPP_HIDE_FROM_ABI __value_func& operator=(nullptr_t) {
261 __func* __f = __f_;
262 __f_ = nullptr;
263 if ((void*)__f == &__buf_)
264 __f->destroy();
265 else if (__f)
266 __f->destroy_deallocate();
267 return *this;
268 }
269
270 _LIBCPP_HIDE_FROM_ABI _Rp operator()(_ArgTypes&&... __args) const {
271 if (__f_ == nullptr)
272 std::__throw_bad_function_call();
273 return (*__f_)(std::forward<_ArgTypes>(__args)...);
274 }
275
276 _LIBCPP_HIDE_FROM_ABI void swap(__value_func& __f) _NOEXCEPT {
277 if (std::addressof(__f) == this)
278 return;
279 if ((void*)__f_ == &__buf_ && (void*)__f.__f_ == &__f.__buf_) {
280 _LIBCPP_SUPPRESS_DEPRECATED_PUSH
281 typename aligned_storage<sizeof(__buf_)>::type __tempbuf;
282 _LIBCPP_SUPPRESS_DEPRECATED_POP
283 __func* __t = __as_base(p: &__tempbuf);
284 __f_->__clone(__t);
285 __f_->destroy();
286 __f_ = nullptr;
287 __f.__f_->__clone(__as_base(&__buf_));
288 __f.__f_->destroy();
289 __f.__f_ = nullptr;
290 __f_ = __as_base(&__buf_);
291 __t->__clone(__as_base(p: &__f.__buf_));
292 __t->destroy();
293 __f.__f_ = __as_base(p: &__f.__buf_);
294 } else if ((void*)__f_ == &__buf_) {
295 __f_->__clone(__as_base(p: &__f.__buf_));
296 __f_->destroy();
297 __f_ = __f.__f_;
298 __f.__f_ = __as_base(p: &__f.__buf_);
299 } else if ((void*)__f.__f_ == &__f.__buf_) {
300 __f.__f_->__clone(__as_base(&__buf_));
301 __f.__f_->destroy();
302 __f.__f_ = __f_;
303 __f_ = __as_base(&__buf_);
304 } else
305 std::swap(__f_, __f.__f_);
306 }
307
308 _LIBCPP_HIDE_FROM_ABI explicit operator bool() const _NOEXCEPT { return __f_ != nullptr; }
309
310# if _LIBCPP_HAS_RTTI
311 _LIBCPP_HIDE_FROM_ABI const std::type_info& target_type() const _NOEXCEPT {
312 if (__f_ == nullptr)
313 return typeid(void);
314 return __f_->target_type();
315 }
316
317 template <typename _Tp>
318 _LIBCPP_HIDE_FROM_ABI const _Tp* target() const _NOEXCEPT {
319 if (__f_ == nullptr)
320 return nullptr;
321 return (const _Tp*)__f_->target(typeid(_Tp));
322 }
323# endif // _LIBCPP_HAS_RTTI
324};
325
326// Storage for a functor object, to be used with __policy to manage copy and
327// destruction.
328union __policy_storage {
329 mutable char __small[sizeof(void*) * 2];
330 void* __large;
331};
332
333// True if _Fun can safely be held in __policy_storage.__small.
334template <typename _Fun>
335struct __use_small_storage
336 : public integral_constant<
337 bool,
338 sizeof(_Fun) <= sizeof(__policy_storage)&& _LIBCPP_ALIGNOF(_Fun) <= _LIBCPP_ALIGNOF(__policy_storage) &&
339 is_trivially_copy_constructible<_Fun>::value && is_trivially_destructible<_Fun>::value> {};
340
341// Policy contains information about how to copy, destroy, and move the
342// underlying functor. You can think of it as a vtable of sorts.
343struct __policy {
344 // Used to copy or destroy __large values. null for trivial objects.
345 void* (*const __clone)(const void*);
346 void (*const __destroy)(void*);
347
348 // True if this is the null policy (no value).
349 const bool __is_null;
350
351 // The target type. May be null if RTTI is disabled.
352 const std::type_info* const __type_info;
353
354 // Returns a pointer to a static policy object suitable for the functor
355 // type.
356 template <typename _Fun>
357 _LIBCPP_HIDE_FROM_ABI static const __policy* __create() {
358 if constexpr (__use_small_storage<_Fun>::value) {
359 static constexpr __policy __policy = {
360 nullptr,
361 nullptr,
362 false,
363# if _LIBCPP_HAS_RTTI
364 &typeid(_Fun)
365# else
366 nullptr
367# endif
368 };
369 return &__policy;
370 } else {
371 static constexpr __policy __policy = {
372 std::addressof(__large_clone<_Fun>),
373 std::addressof(__large_destroy<_Fun>),
374 false,
375# if _LIBCPP_HAS_RTTI
376 &typeid(_Fun)
377# else
378 nullptr
379# endif
380 };
381 return &__policy;
382 }
383 }
384
385 _LIBCPP_HIDE_FROM_ABI static const __policy* __create_empty() {
386 static constexpr __policy __policy = {
387 nullptr,
388 nullptr,
389 true,
390# if _LIBCPP_HAS_RTTI
391 &typeid(void)
392# else
393 nullptr
394# endif
395 };
396 return &__policy;
397 }
398
399private:
400 template <typename _Fun>
401 _LIBCPP_HIDE_FROM_ABI static void* __large_clone(const void* __s) {
402 const _Fun* __f = static_cast<const _Fun*>(__s);
403 return new _Fun(*__f);
404 }
405
406 template <typename _Fun>
407 _LIBCPP_HIDE_FROM_ABI static void __large_destroy(void* __s) {
408 delete static_cast<_Fun*>(__s);
409 }
410};
411
412// Used to choose between perfect forwarding or pass-by-value. Pass-by-value is
413// faster for types that can be passed in registers.
414template <typename _Tp>
415using __fast_forward _LIBCPP_NODEBUG = __conditional_t<is_scalar<_Tp>::value, _Tp, _Tp&&>;
416
417// __policy_func uses a __policy to create a type-erased, copyable functor.
418
419template <class _Fp>
420class __policy_func;
421
422template <class _Rp, class... _ArgTypes>
423class __policy_func<_Rp(_ArgTypes...)> {
424 // Inline storage for small objects.
425 __policy_storage __buf_;
426
427 using _ErasedFunc _LIBCPP_NODEBUG = _Rp(const __policy_storage*, __fast_forward<_ArgTypes>...);
428
429 _ErasedFunc* __func_;
430
431 // The policy that describes how to move / copy / destroy __buf_. Never
432 // null, even if the function is empty.
433 const __policy* __policy_;
434
435 _LIBCPP_HIDE_FROM_ABI static _Rp __empty_func(const __policy_storage*, __fast_forward<_ArgTypes>...) {
436 std::__throw_bad_function_call();
437 }
438
439 template <class _Fun>
440 _LIBCPP_HIDE_FROM_ABI static _Rp __call_func(const __policy_storage* __buf, __fast_forward<_ArgTypes>... __args) {
441 _Fun* __func = reinterpret_cast<_Fun*>(__use_small_storage<_Fun>::value ? &__buf->__small : __buf->__large);
442
443 return std::__invoke_r<_Rp>(*__func, std::forward<_ArgTypes>(__args)...);
444 }
445
446public:
447 _LIBCPP_HIDE_FROM_ABI __policy_func() : __func_(__empty_func), __policy_(__policy::__create_empty()) {}
448
449 template <class _Fp, __enable_if_t<!is_same<__decay_t<_Fp>, __policy_func>::value, int> = 0>
450 _LIBCPP_HIDE_FROM_ABI explicit __policy_func(_Fp&& __f) : __policy_(__policy::__create_empty()) {
451 if (__function::__is_null(__f))
452 return;
453
454 __func_ = __call_func<_Fp>;
455 __policy_ = __policy::__create<_Fp>();
456 if (__use_small_storage<_Fp>()) {
457 ::new ((void*)&__buf_.__small) _Fp(std::move(__f));
458 } else {
459 __buf_.__large = ::new _Fp(std::move(__f));
460 }
461 }
462
463 _LIBCPP_HIDE_FROM_ABI __policy_func(const __policy_func& __f)
464 : __buf_(__f.__buf_), __func_(__f.__func_), __policy_(__f.__policy_) {
465 if (__policy_->__clone)
466 __buf_.__large = __policy_->__clone(__f.__buf_.__large);
467 }
468
469 _LIBCPP_HIDE_FROM_ABI __policy_func(__policy_func&& __f)
470 : __buf_(__f.__buf_), __func_(__f.__func_), __policy_(__f.__policy_) {
471 if (__policy_->__destroy) {
472 __f.__policy_ = __policy::__create_empty();
473 __f.__func_ = {};
474 }
475 }
476
477 _LIBCPP_HIDE_FROM_ABI ~__policy_func() {
478 if (__policy_->__destroy)
479 __policy_->__destroy(__buf_.__large);
480 }
481
482 _LIBCPP_HIDE_FROM_ABI __policy_func& operator=(__policy_func&& __f) {
483 *this = nullptr;
484 __buf_ = __f.__buf_;
485 __func_ = __f.__func_;
486 __policy_ = __f.__policy_;
487 __f.__policy_ = __policy::__create_empty();
488 __f.__func_ = {};
489 return *this;
490 }
491
492 _LIBCPP_HIDE_FROM_ABI __policy_func& operator=(nullptr_t) {
493 const __policy* __p = __policy_;
494 __policy_ = __policy::__create_empty();
495 __func_ = {};
496 if (__p->__destroy)
497 __p->__destroy(__buf_.__large);
498 return *this;
499 }
500
501 _LIBCPP_HIDE_FROM_ABI _Rp operator()(_ArgTypes&&... __args) const {
502 return __func_(std::addressof(x: __buf_), std::forward<_ArgTypes>(__args)...);
503 }
504
505 _LIBCPP_HIDE_FROM_ABI void swap(__policy_func& __f) {
506 std::swap(__func_, __f.__func_);
507 std::swap(__policy_, __f.__policy_);
508 std::swap(__buf_, __f.__buf_);
509 }
510
511 _LIBCPP_HIDE_FROM_ABI explicit operator bool() const _NOEXCEPT { return !__policy_->__is_null; }
512
513# if _LIBCPP_HAS_RTTI
514 _LIBCPP_HIDE_FROM_ABI const std::type_info& target_type() const _NOEXCEPT { return *__policy_->__type_info; }
515
516 template <typename _Tp>
517 _LIBCPP_HIDE_FROM_ABI const _Tp* target() const _NOEXCEPT {
518 if (__policy_->__is_null || typeid(_Tp) != *__policy_->__type_info)
519 return nullptr;
520 if (__policy_->__clone) // Out of line storage.
521 return reinterpret_cast<const _Tp*>(__buf_.__large);
522 else
523 return reinterpret_cast<const _Tp*>(&__buf_.__small);
524 }
525# endif // _LIBCPP_HAS_RTTI
526};
527
528# if _LIBCPP_HAS_BLOCKS_RUNTIME
529
530extern "C" void* _Block_copy(const void*);
531extern "C" void _Block_release(const void*);
532
533template <class _Rp1, class... _ArgTypes1, class _Rp, class... _ArgTypes>
534class __func<_Rp1 (^)(_ArgTypes1...), _Rp(_ArgTypes...)> : public __base<_Rp(_ArgTypes...)> {
535 typedef _Rp1 (^__block_type)(_ArgTypes1...);
536 __block_type __f_;
537
538public:
539 _LIBCPP_HIDE_FROM_ABI explicit __func(__block_type const& __f)
540# if __has_feature(objc_arc)
541 : __f_(__f)
542# else
543 : __f_(reinterpret_cast<__block_type>(__f ? _Block_copy(__f) : nullptr))
544# endif
545 {
546 }
547
548 // [TODO] add && to save on a retain
549
550 _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual __base<_Rp(_ArgTypes...)>* __clone() const {
551 _LIBCPP_ASSERT_INTERNAL(
552 false,
553 "Block pointers are just pointers, so they should always fit into "
554 "std::function's small buffer optimization. This function should "
555 "never be invoked.");
556 return nullptr;
557 }
558
559 _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void __clone(__base<_Rp(_ArgTypes...)>* __p) const {
560 ::new ((void*)__p) __func(__f_);
561 }
562
563 _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void destroy() _NOEXCEPT {
564# if !__has_feature(objc_arc)
565 if (__f_)
566 _Block_release(__f_);
567# endif
568 __f_ = 0;
569 }
570
571 _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void destroy_deallocate() _NOEXCEPT {
572 _LIBCPP_ASSERT_INTERNAL(
573 false,
574 "Block pointers are just pointers, so they should always fit into "
575 "std::function's small buffer optimization. This function should "
576 "never be invoked.");
577 }
578
579 _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual _Rp operator()(_ArgTypes&&... __arg) {
580 return std::__invoke(__f_, std::forward<_ArgTypes>(__arg)...);
581 }
582
583# if _LIBCPP_HAS_RTTI
584 _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual const void* target(type_info const& __ti) const _NOEXCEPT {
585 if (__ti == typeid(__func::__block_type))
586 return &__f_;
587 return (const void*)nullptr;
588 }
589
590 _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual const std::type_info& target_type() const _NOEXCEPT {
591 return typeid(__func::__block_type);
592 }
593# endif // _LIBCPP_HAS_RTTI
594};
595
596# endif // _LIBCPP_HAS_BLOCKS_RUNTIME
597
598} // namespace __function
599
600template <class _Rp, class... _ArgTypes>
601class function<_Rp(_ArgTypes...)>
602 : public __function::__maybe_derive_from_unary_function<_Rp(_ArgTypes...)>,
603 public __function::__maybe_derive_from_binary_function<_Rp(_ArgTypes...)> {
604# ifndef _LIBCPP_ABI_OPTIMIZED_FUNCTION
605 typedef __function::__value_func<_Rp(_ArgTypes...)> __func;
606# else
607 typedef __function::__policy_func<_Rp(_ArgTypes...)> __func;
608# endif
609
610 __func __f_;
611
612 template <class _Fp>
613 using _EnableIfLValueCallable _LIBCPP_NODEBUG = __enable_if_t<
614 _And<_IsNotSame<__remove_cvref_t<_Fp>, function>, __is_invocable_r<_Rp, _Fp&, _ArgTypes...>>::value>;
615
616public:
617 typedef _Rp result_type;
618
619 // construct/copy/destroy:
620 _LIBCPP_HIDE_FROM_ABI function() _NOEXCEPT {}
621 _LIBCPP_HIDE_FROM_ABI function(nullptr_t) _NOEXCEPT {}
622 _LIBCPP_HIDE_FROM_ABI function(const function&);
623 _LIBCPP_HIDE_FROM_ABI function(function&&) _NOEXCEPT;
624 template <class _Fp, class = _EnableIfLValueCallable<_Fp>>
625 _LIBCPP_HIDE_FROM_ABI function(_Fp);
626
627# if _LIBCPP_STD_VER <= 14
628 template <class _Alloc>
629 _LIBCPP_HIDE_FROM_ABI function(allocator_arg_t, const _Alloc&) _NOEXCEPT {}
630 template <class _Alloc>
631 _LIBCPP_HIDE_FROM_ABI function(allocator_arg_t, const _Alloc&, nullptr_t) _NOEXCEPT {}
632 template <class _Alloc>
633 _LIBCPP_HIDE_FROM_ABI function(allocator_arg_t, const _Alloc&, const function&);
634 template <class _Alloc>
635 _LIBCPP_HIDE_FROM_ABI function(allocator_arg_t, const _Alloc&, function&&);
636 template <class _Fp, class _Alloc, class = _EnableIfLValueCallable<_Fp>>
637 _LIBCPP_HIDE_FROM_ABI function(allocator_arg_t, const _Alloc& __a, _Fp __f);
638# endif
639
640 _LIBCPP_HIDE_FROM_ABI function& operator=(const function&);
641 _LIBCPP_HIDE_FROM_ABI function& operator=(function&&) _NOEXCEPT;
642 _LIBCPP_HIDE_FROM_ABI function& operator=(nullptr_t) _NOEXCEPT;
643 template <class _Fp, class = _EnableIfLValueCallable<__decay_t<_Fp>>>
644 _LIBCPP_HIDE_FROM_ABI function& operator=(_Fp&&);
645
646 _LIBCPP_HIDE_FROM_ABI ~function();
647
648 // function modifiers:
649 _LIBCPP_HIDE_FROM_ABI void swap(function&) _NOEXCEPT;
650
651# if _LIBCPP_STD_VER <= 14
652 template <class _Fp, class _Alloc>
653 _LIBCPP_HIDE_FROM_ABI void assign(_Fp&& __f, const _Alloc& __a) {
654 function(allocator_arg, __a, std::forward<_Fp>(__f)).swap(*this);
655 }
656# endif
657
658 // function capacity:
659 _LIBCPP_HIDE_FROM_ABI explicit operator bool() const _NOEXCEPT { return static_cast<bool>(__f_); }
660
661 // deleted overloads close possible hole in the type system
662 template <class _R2, class... _ArgTypes2>
663 bool operator==(const function<_R2(_ArgTypes2...)>&) const = delete;
664# if _LIBCPP_STD_VER <= 17
665 template <class _R2, class... _ArgTypes2>
666 bool operator!=(const function<_R2(_ArgTypes2...)>&) const = delete;
667# endif
668
669public:
670 // function invocation:
671 _LIBCPP_HIDE_FROM_ABI _Rp operator()(_ArgTypes...) const;
672
673# if _LIBCPP_HAS_RTTI
674 // function target access:
675 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const std::type_info& target_type() const _NOEXCEPT;
676 template <typename _Tp>
677 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _Tp* target() _NOEXCEPT;
678 template <typename _Tp>
679 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const _Tp* target() const _NOEXCEPT;
680# endif // _LIBCPP_HAS_RTTI
681};
682
683# if _LIBCPP_STD_VER >= 17
684template <class _Rp, class... _Ap>
685function(_Rp (*)(_Ap...)) -> function<_Rp(_Ap...)>;
686
687template <class _Fp, class _Stripped = typename __strip_signature<decltype(&_Fp::operator())>::type>
688function(_Fp) -> function<_Stripped>;
689# endif // _LIBCPP_STD_VER >= 17
690
691template <class _Rp, class... _ArgTypes>
692function<_Rp(_ArgTypes...)>::function(const function& __f) : __f_(__f.__f_) {}
693
694# if _LIBCPP_STD_VER <= 14
695template <class _Rp, class... _ArgTypes>
696template <class _Alloc>
697function<_Rp(_ArgTypes...)>::function(allocator_arg_t, const _Alloc&, const function& __f) : __f_(__f.__f_) {}
698# endif
699
700template <class _Rp, class... _ArgTypes>
701function<_Rp(_ArgTypes...)>::function(function&& __f) _NOEXCEPT : __f_(std::move(__f.__f_)) {}
702
703# if _LIBCPP_STD_VER <= 14
704template <class _Rp, class... _ArgTypes>
705template <class _Alloc>
706function<_Rp(_ArgTypes...)>::function(allocator_arg_t, const _Alloc&, function&& __f) : __f_(std::move(__f.__f_)) {}
707# endif
708
709template <class _Rp, class... _ArgTypes>
710template <class _Fp, class>
711function<_Rp(_ArgTypes...)>::function(_Fp __f) : __f_(std::move(__f)) {}
712
713# if _LIBCPP_STD_VER <= 14
714template <class _Rp, class... _ArgTypes>
715template <class _Fp, class _Alloc, class>
716function<_Rp(_ArgTypes...)>::function(allocator_arg_t, const _Alloc&, _Fp __f) : __f_(std::move(__f)) {}
717# endif
718
719template <class _Rp, class... _ArgTypes>
720function<_Rp(_ArgTypes...)>& function<_Rp(_ArgTypes...)>::operator=(const function& __f) {
721 function(__f).swap(*this);
722 return *this;
723}
724
725template <class _Rp, class... _ArgTypes>
726function<_Rp(_ArgTypes...)>& function<_Rp(_ArgTypes...)>::operator=(function&& __f) _NOEXCEPT {
727 __f_ = std::move(__f.__f_);
728 return *this;
729}
730
731template <class _Rp, class... _ArgTypes>
732function<_Rp(_ArgTypes...)>& function<_Rp(_ArgTypes...)>::operator=(nullptr_t) _NOEXCEPT {
733 __f_ = nullptr;
734 return *this;
735}
736
737template <class _Rp, class... _ArgTypes>
738template <class _Fp, class>
739function<_Rp(_ArgTypes...)>& function<_Rp(_ArgTypes...)>::operator=(_Fp&& __f) {
740 function(std::forward<_Fp>(__f)).swap(*this);
741 return *this;
742}
743
744template <class _Rp, class... _ArgTypes>
745function<_Rp(_ArgTypes...)>::~function() {}
746
747template <class _Rp, class... _ArgTypes>
748void function<_Rp(_ArgTypes...)>::swap(function& __f) _NOEXCEPT {
749 __f_.swap(__f.__f_);
750}
751
752template <class _Rp, class... _ArgTypes>
753_Rp function<_Rp(_ArgTypes...)>::operator()(_ArgTypes... __arg) const {
754 return __f_(std::forward<_ArgTypes>(__arg)...);
755}
756
757# if _LIBCPP_HAS_RTTI
758
759template <class _Rp, class... _ArgTypes>
760const std::type_info& function<_Rp(_ArgTypes...)>::target_type() const _NOEXCEPT {
761 return __f_.target_type();
762}
763
764template <class _Rp, class... _ArgTypes>
765template <typename _Tp>
766_Tp* function<_Rp(_ArgTypes...)>::target() _NOEXCEPT {
767 return (_Tp*)(__f_.template target<_Tp>());
768}
769
770template <class _Rp, class... _ArgTypes>
771template <typename _Tp>
772const _Tp* function<_Rp(_ArgTypes...)>::target() const _NOEXCEPT {
773 return __f_.template target<_Tp>();
774}
775
776# endif // _LIBCPP_HAS_RTTI
777
778template <class _Rp, class... _ArgTypes>
779inline _LIBCPP_HIDE_FROM_ABI bool operator==(const function<_Rp(_ArgTypes...)>& __f, nullptr_t) _NOEXCEPT {
780 return !__f;
781}
782
783# if _LIBCPP_STD_VER <= 17
784
785template <class _Rp, class... _ArgTypes>
786inline _LIBCPP_HIDE_FROM_ABI bool operator==(nullptr_t, const function<_Rp(_ArgTypes...)>& __f) _NOEXCEPT {
787 return !__f;
788}
789
790template <class _Rp, class... _ArgTypes>
791inline _LIBCPP_HIDE_FROM_ABI bool operator!=(const function<_Rp(_ArgTypes...)>& __f, nullptr_t) _NOEXCEPT {
792 return (bool)__f;
793}
794
795template <class _Rp, class... _ArgTypes>
796inline _LIBCPP_HIDE_FROM_ABI bool operator!=(nullptr_t, const function<_Rp(_ArgTypes...)>& __f) _NOEXCEPT {
797 return (bool)__f;
798}
799
800# endif // _LIBCPP_STD_VER <= 17
801
802template <class _Rp, class... _ArgTypes>
803inline _LIBCPP_HIDE_FROM_ABI void swap(function<_Rp(_ArgTypes...)>& __x, function<_Rp(_ArgTypes...)>& __y) _NOEXCEPT {
804 return __x.swap(__y);
805}
806
807_LIBCPP_END_NAMESPACE_STD
808
809#endif // _LIBCPP_CXX03_LANG
810
811_LIBCPP_POP_MACROS
812
813#endif // _LIBCPP___FUNCTIONAL_FUNCTION_H
814