1 | // Implementation of std::function -*- C++ -*- |
2 | |
3 | // Copyright (C) 2004-2024 Free Software Foundation, Inc. |
4 | // |
5 | // This file is part of the GNU ISO C++ Library. This library is free |
6 | // software; you can redistribute it and/or modify it under the |
7 | // terms of the GNU General Public License as published by the |
8 | // Free Software Foundation; either version 3, or (at your option) |
9 | // any later version. |
10 | |
11 | // This library is distributed in the hope that it will be useful, |
12 | // but WITHOUT ANY WARRANTY; without even the implied warranty of |
13 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
14 | // GNU General Public License for more details. |
15 | |
16 | // Under Section 7 of GPL version 3, you are granted additional |
17 | // permissions described in the GCC Runtime Library Exception, version |
18 | // 3.1, as published by the Free Software Foundation. |
19 | |
20 | // You should have received a copy of the GNU General Public License and |
21 | // a copy of the GCC Runtime Library Exception along with this program; |
22 | // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see |
23 | // <http://www.gnu.org/licenses/>. |
24 | |
25 | /** @file include/bits/std_function.h |
26 | * This is an internal header file, included by other library headers. |
27 | * Do not attempt to use it directly. @headername{functional} |
28 | */ |
29 | |
30 | #ifndef _GLIBCXX_STD_FUNCTION_H |
31 | #define _GLIBCXX_STD_FUNCTION_H 1 |
32 | |
33 | #pragma GCC system_header |
34 | |
35 | #if __cplusplus < 201103L |
36 | # include <bits/c++0x_warning.h> |
37 | #else |
38 | |
39 | #include <new> // placement new |
40 | #include <typeinfo> // typeid |
41 | #include <bits/invoke.h> // __invoke_r |
42 | #include <bits/refwrap.h> // ref wrapper, _Maybe_unary_or_binary_function |
43 | #include <bits/functexcept.h> // __throw_bad_function_call |
44 | |
45 | namespace std _GLIBCXX_VISIBILITY(default) |
46 | { |
47 | _GLIBCXX_BEGIN_NAMESPACE_VERSION |
48 | |
49 | /** |
50 | * @brief Exception class thrown when class template function's |
51 | * operator() is called with an empty target. |
52 | * @ingroup exceptions |
53 | */ |
54 | class bad_function_call : public std::exception |
55 | { |
56 | public: |
57 | virtual ~bad_function_call() noexcept; |
58 | |
59 | const char* what() const noexcept; |
60 | }; |
61 | |
62 | /** |
63 | * Trait identifying "location-invariant" types, meaning that the |
64 | * address of the object (or any of its members) will not escape. |
65 | * Trivially copyable types are location-invariant and users can |
66 | * specialize this trait for other types. |
67 | */ |
68 | template<typename _Tp> |
69 | struct __is_location_invariant |
70 | : is_trivially_copyable<_Tp>::type |
71 | { }; |
72 | |
73 | class _Undefined_class; |
74 | |
75 | union _Nocopy_types |
76 | { |
77 | void* _M_object; |
78 | const void* _M_const_object; |
79 | void (*_M_function_pointer)(); |
80 | void (_Undefined_class::*_M_member_pointer)(); |
81 | }; |
82 | |
83 | union [[gnu::may_alias]] _Any_data |
84 | { |
85 | void* _M_access() noexcept { return &_M_pod_data[0]; } |
86 | const void* _M_access() const noexcept { return &_M_pod_data[0]; } |
87 | |
88 | template<typename _Tp> |
89 | _Tp& |
90 | _M_access() noexcept |
91 | { return *static_cast<_Tp*>(_M_access()); } |
92 | |
93 | template<typename _Tp> |
94 | const _Tp& |
95 | _M_access() const noexcept |
96 | { return *static_cast<const _Tp*>(_M_access()); } |
97 | |
98 | _Nocopy_types _M_unused; |
99 | char _M_pod_data[sizeof(_Nocopy_types)]; |
100 | }; |
101 | |
102 | enum _Manager_operation |
103 | { |
104 | __get_type_info, |
105 | __get_functor_ptr, |
106 | __clone_functor, |
107 | __destroy_functor |
108 | }; |
109 | |
110 | template<typename _Signature> |
111 | class function; |
112 | |
113 | /// Base class of all polymorphic function object wrappers. |
114 | class _Function_base |
115 | { |
116 | public: |
117 | static const size_t _M_max_size = sizeof(_Nocopy_types); |
118 | static const size_t _M_max_align = __alignof__(_Nocopy_types); |
119 | |
120 | template<typename _Functor> |
121 | class _Base_manager |
122 | { |
123 | protected: |
124 | static const bool __stored_locally = |
125 | (__is_location_invariant<_Functor>::value |
126 | && sizeof(_Functor) <= _M_max_size |
127 | && __alignof__(_Functor) <= _M_max_align |
128 | && (_M_max_align % __alignof__(_Functor) == 0)); |
129 | |
130 | using _Local_storage = integral_constant<bool, __stored_locally>; |
131 | |
132 | // Retrieve a pointer to the function object |
133 | static _Functor* |
134 | _M_get_pointer(const _Any_data& __source) noexcept |
135 | { |
136 | if _GLIBCXX17_CONSTEXPR (__stored_locally) |
137 | { |
138 | const _Functor& __f = __source._M_access<_Functor>(); |
139 | return const_cast<_Functor*>(std::__addressof(__f)); |
140 | } |
141 | else // have stored a pointer |
142 | return __source._M_access<_Functor*>(); |
143 | } |
144 | |
145 | private: |
146 | // Construct a location-invariant function object that fits within |
147 | // an _Any_data structure. |
148 | template<typename _Fn> |
149 | static void |
150 | _M_create(_Any_data& __dest, _Fn&& __f, true_type) |
151 | { |
152 | ::new (__dest._M_access()) _Functor(std::forward<_Fn>(__f)); |
153 | } |
154 | |
155 | // Construct a function object on the heap and store a pointer. |
156 | template<typename _Fn> |
157 | static void |
158 | _M_create(_Any_data& __dest, _Fn&& __f, false_type) |
159 | { |
160 | __dest._M_access<_Functor*>() |
161 | = new _Functor(std::forward<_Fn>(__f)); |
162 | } |
163 | |
164 | // Destroy an object stored in the internal buffer. |
165 | static void |
166 | _M_destroy(_Any_data& __victim, true_type) |
167 | { |
168 | __victim._M_access<_Functor>().~_Functor(); |
169 | } |
170 | |
171 | // Destroy an object located on the heap. |
172 | static void |
173 | _M_destroy(_Any_data& __victim, false_type) |
174 | { |
175 | delete __victim._M_access<_Functor*>(); |
176 | } |
177 | |
178 | public: |
179 | static bool |
180 | _M_manager(_Any_data& __dest, const _Any_data& __source, |
181 | _Manager_operation __op) |
182 | { |
183 | switch (__op) |
184 | { |
185 | case __get_type_info: |
186 | #if __cpp_rtti |
187 | __dest._M_access<const type_info*>() = &typeid(_Functor); |
188 | #else |
189 | __dest._M_access<const type_info*>() = nullptr; |
190 | #endif |
191 | break; |
192 | |
193 | case __get_functor_ptr: |
194 | __dest._M_access<_Functor*>() = _M_get_pointer(__source); |
195 | break; |
196 | |
197 | case __clone_functor: |
198 | _M_init_functor(__dest, |
199 | *const_cast<const _Functor*>(_M_get_pointer(__source))); |
200 | break; |
201 | |
202 | case __destroy_functor: |
203 | _M_destroy(__dest, _Local_storage()); |
204 | break; |
205 | } |
206 | return false; |
207 | } |
208 | |
209 | template<typename _Fn> |
210 | static void |
211 | _M_init_functor(_Any_data& __functor, _Fn&& __f) |
212 | noexcept(__and_<_Local_storage, |
213 | is_nothrow_constructible<_Functor, _Fn>>::value) |
214 | { |
215 | _M_create(__functor, std::forward<_Fn>(__f), _Local_storage()); |
216 | } |
217 | |
218 | template<typename _Signature> |
219 | static bool |
220 | _M_not_empty_function(const function<_Signature>& __f) noexcept |
221 | { return static_cast<bool>(__f); } |
222 | |
223 | template<typename _Tp> |
224 | static bool |
225 | _M_not_empty_function(_Tp* __fp) noexcept |
226 | { return __fp != nullptr; } |
227 | |
228 | template<typename _Class, typename _Tp> |
229 | static bool |
230 | _M_not_empty_function(_Tp _Class::* __mp) noexcept |
231 | { return __mp != nullptr; } |
232 | |
233 | template<typename _Tp> |
234 | static bool |
235 | _M_not_empty_function(const _Tp&) noexcept |
236 | { return true; } |
237 | }; |
238 | |
239 | _Function_base() = default; |
240 | |
241 | ~_Function_base() |
242 | { |
243 | if (_M_manager) |
244 | _M_manager(_M_functor, _M_functor, __destroy_functor); |
245 | } |
246 | |
247 | bool _M_empty() const { return !_M_manager; } |
248 | |
249 | using _Manager_type |
250 | = bool (*)(_Any_data&, const _Any_data&, _Manager_operation); |
251 | |
252 | _Any_data _M_functor{}; |
253 | _Manager_type _M_manager{}; |
254 | }; |
255 | |
256 | template<typename _Signature, typename _Functor> |
257 | class _Function_handler; |
258 | |
259 | template<typename _Res, typename _Functor, typename... _ArgTypes> |
260 | class _Function_handler<_Res(_ArgTypes...), _Functor> |
261 | : public _Function_base::_Base_manager<_Functor> |
262 | { |
263 | using _Base = _Function_base::_Base_manager<_Functor>; |
264 | |
265 | public: |
266 | static bool |
267 | _M_manager(_Any_data& __dest, const _Any_data& __source, |
268 | _Manager_operation __op) |
269 | { |
270 | switch (__op) |
271 | { |
272 | #if __cpp_rtti |
273 | case __get_type_info: |
274 | __dest._M_access<const type_info*>() = &typeid(_Functor); |
275 | break; |
276 | #endif |
277 | case __get_functor_ptr: |
278 | __dest._M_access<_Functor*>() = _Base::_M_get_pointer(__source); |
279 | break; |
280 | |
281 | default: |
282 | _Base::_M_manager(__dest, __source, __op); |
283 | } |
284 | return false; |
285 | } |
286 | |
287 | static _Res |
288 | _M_invoke(const _Any_data& __functor, _ArgTypes&&... __args) |
289 | { |
290 | return std::__invoke_r<_Res>(*_Base::_M_get_pointer(__functor), |
291 | std::forward<_ArgTypes>(__args)...); |
292 | } |
293 | |
294 | template<typename _Fn> |
295 | static constexpr bool |
296 | _S_nothrow_init() noexcept |
297 | { |
298 | return __and_<typename _Base::_Local_storage, |
299 | is_nothrow_constructible<_Functor, _Fn>>::value; |
300 | } |
301 | }; |
302 | |
303 | // Specialization for invalid types |
304 | template<> |
305 | class _Function_handler<void, void> |
306 | { |
307 | public: |
308 | static bool |
309 | _M_manager(_Any_data&, const _Any_data&, _Manager_operation) |
310 | { return false; } |
311 | }; |
312 | |
313 | // Avoids instantiating ill-formed specializations of _Function_handler |
314 | // in std::function<_Signature>::target<_Functor>(). |
315 | // e.g. _Function_handler<Sig, void()> and _Function_handler<Sig, void> |
316 | // would be ill-formed. |
317 | template<typename _Signature, typename _Functor, |
318 | bool __valid = is_object<_Functor>::value> |
319 | struct _Target_handler |
320 | : _Function_handler<_Signature, typename remove_cv<_Functor>::type> |
321 | { }; |
322 | |
323 | template<typename _Signature, typename _Functor> |
324 | struct _Target_handler<_Signature, _Functor, false> |
325 | : _Function_handler<void, void> |
326 | { }; |
327 | |
328 | /** |
329 | * @brief Polymorphic function wrapper. |
330 | * @ingroup functors |
331 | * @since C++11 |
332 | */ |
333 | template<typename _Res, typename... _ArgTypes> |
334 | class function<_Res(_ArgTypes...)> |
335 | : public _Maybe_unary_or_binary_function<_Res, _ArgTypes...>, |
336 | private _Function_base |
337 | { |
338 | // Equivalent to std::decay_t except that it produces an invalid type |
339 | // if the decayed type is the current specialization of std::function. |
340 | template<typename _Func, |
341 | bool _Self = is_same<__remove_cvref_t<_Func>, function>::value> |
342 | using _Decay_t |
343 | = typename __enable_if_t<!_Self, decay<_Func>>::type; |
344 | |
345 | template<typename _Func, |
346 | typename _DFunc = _Decay_t<_Func>, |
347 | typename _Res2 = __invoke_result<_DFunc&, _ArgTypes...>> |
348 | struct _Callable |
349 | : __is_invocable_impl<_Res2, _Res>::type |
350 | { }; |
351 | |
352 | template<typename _Cond, typename _Tp = void> |
353 | using _Requires = __enable_if_t<_Cond::value, _Tp>; |
354 | |
355 | template<typename _Functor> |
356 | using _Handler |
357 | = _Function_handler<_Res(_ArgTypes...), __decay_t<_Functor>>; |
358 | |
359 | public: |
360 | typedef _Res result_type; |
361 | |
362 | // [3.7.2.1] construct/copy/destroy |
363 | |
364 | /** |
365 | * @brief Default construct creates an empty function call wrapper. |
366 | * @post `!(bool)*this` |
367 | */ |
368 | function() noexcept |
369 | : _Function_base() { } |
370 | |
371 | /** |
372 | * @brief Creates an empty function call wrapper. |
373 | * @post @c !(bool)*this |
374 | */ |
375 | function(nullptr_t) noexcept |
376 | : _Function_base() { } |
377 | |
378 | /** |
379 | * @brief %Function copy constructor. |
380 | * @param __x A %function object with identical call signature. |
381 | * @post `bool(*this) == bool(__x)` |
382 | * |
383 | * The newly-created %function contains a copy of the target of |
384 | * `__x` (if it has one). |
385 | */ |
386 | function(const function& __x) |
387 | : _Function_base() |
388 | { |
389 | if (static_cast<bool>(__x)) |
390 | { |
391 | __x._M_manager(_M_functor, __x._M_functor, __clone_functor); |
392 | _M_invoker = __x._M_invoker; |
393 | _M_manager = __x._M_manager; |
394 | } |
395 | } |
396 | |
397 | /** |
398 | * @brief %Function move constructor. |
399 | * @param __x A %function object rvalue with identical call signature. |
400 | * |
401 | * The newly-created %function contains the target of `__x` |
402 | * (if it has one). |
403 | */ |
404 | function(function&& __x) noexcept |
405 | : _Function_base(), _M_invoker(__x._M_invoker) |
406 | { |
407 | if (static_cast<bool>(__x)) |
408 | { |
409 | _M_functor = __x._M_functor; |
410 | _M_manager = __x._M_manager; |
411 | __x._M_manager = nullptr; |
412 | __x._M_invoker = nullptr; |
413 | } |
414 | } |
415 | |
416 | /** |
417 | * @brief Builds a %function that targets a copy of the incoming |
418 | * function object. |
419 | * @param __f A %function object that is callable with parameters of |
420 | * type `ArgTypes...` and returns a value convertible to `Res`. |
421 | * |
422 | * The newly-created %function object will target a copy of |
423 | * `__f`. If `__f` is `reference_wrapper<F>`, then this function |
424 | * object will contain a reference to the function object `__f.get()`. |
425 | * If `__f` is a null function pointer, null pointer-to-member, or |
426 | * empty `std::function`, the newly-created object will be empty. |
427 | * |
428 | * If `__f` is a non-null function pointer or an object of type |
429 | * `reference_wrapper<F>`, this function will not throw. |
430 | */ |
431 | // _GLIBCXX_RESOLVE_LIB_DEFECTS |
432 | // 2774. std::function construction vs assignment |
433 | template<typename _Functor, |
434 | typename _Constraints = _Requires<_Callable<_Functor>>> |
435 | function(_Functor&& __f) |
436 | noexcept(_Handler<_Functor>::template _S_nothrow_init<_Functor>()) |
437 | : _Function_base() |
438 | { |
439 | static_assert(is_copy_constructible<__decay_t<_Functor>>::value, |
440 | "std::function target must be copy-constructible" ); |
441 | static_assert(is_constructible<__decay_t<_Functor>, _Functor>::value, |
442 | "std::function target must be constructible from the " |
443 | "constructor argument" ); |
444 | |
445 | using _My_handler = _Handler<_Functor>; |
446 | |
447 | if (_My_handler::_M_not_empty_function(__f)) |
448 | { |
449 | _My_handler::_M_init_functor(_M_functor, |
450 | std::forward<_Functor>(__f)); |
451 | _M_invoker = &_My_handler::_M_invoke; |
452 | _M_manager = &_My_handler::_M_manager; |
453 | } |
454 | } |
455 | |
456 | /** |
457 | * @brief Function assignment operator. |
458 | * @param __x A %function with identical call signature. |
459 | * @post `(bool)*this == (bool)x` |
460 | * @returns `*this` |
461 | * |
462 | * The target of `__x` is copied to `*this`. If `__x` has no |
463 | * target, then `*this` will be empty. |
464 | * |
465 | * If `__x` targets a function pointer or a reference to a function |
466 | * object, then this operation will not throw an exception. |
467 | */ |
468 | function& |
469 | operator=(const function& __x) |
470 | { |
471 | function(__x).swap(*this); |
472 | return *this; |
473 | } |
474 | |
475 | /** |
476 | * @brief Function move-assignment operator. |
477 | * @param __x A %function rvalue with identical call signature. |
478 | * @returns `*this` |
479 | * |
480 | * The target of `__x` is moved to `*this`. If `__x` has no |
481 | * target, then `*this` will be empty. |
482 | * |
483 | * If `__x` targets a function pointer or a reference to a function |
484 | * object, then this operation will not throw an exception. |
485 | */ |
486 | function& |
487 | operator=(function&& __x) noexcept |
488 | { |
489 | function(std::move(__x)).swap(*this); |
490 | return *this; |
491 | } |
492 | |
493 | /** |
494 | * @brief Function assignment to empty. |
495 | * @post `!(bool)*this` |
496 | * @returns `*this` |
497 | * |
498 | * The target of `*this` is deallocated, leaving it empty. |
499 | */ |
500 | function& |
501 | operator=(nullptr_t) noexcept |
502 | { |
503 | if (_M_manager) |
504 | { |
505 | _M_manager(_M_functor, _M_functor, __destroy_functor); |
506 | _M_manager = nullptr; |
507 | _M_invoker = nullptr; |
508 | } |
509 | return *this; |
510 | } |
511 | |
512 | /** |
513 | * @brief Function assignment to a new target. |
514 | * @param __f A function object that is callable with parameters of |
515 | * type `_ArgTypes...` and returns a value convertible |
516 | * to `_Res`. |
517 | * @return `*this` |
518 | * @since C++11 |
519 | * |
520 | * This function object wrapper will target a copy of `__f`. If `__f` |
521 | * is `reference_wrapper<F>`, then this function object will contain |
522 | * a reference to the function object `__f.get()`. If `__f` is a null |
523 | * function pointer or null pointer-to-member, this object will be |
524 | * empty. |
525 | * |
526 | * If `__f` is a non-null function pointer or an object of type |
527 | * `reference_wrapper<F>`, this function will not throw. |
528 | */ |
529 | template<typename _Functor> |
530 | _Requires<_Callable<_Functor>, function&> |
531 | operator=(_Functor&& __f) |
532 | noexcept(_Handler<_Functor>::template _S_nothrow_init<_Functor>()) |
533 | { |
534 | function(std::forward<_Functor>(__f)).swap(*this); |
535 | return *this; |
536 | } |
537 | |
538 | /// @overload |
539 | template<typename _Functor> |
540 | function& |
541 | operator=(reference_wrapper<_Functor> __f) noexcept |
542 | { |
543 | function(__f).swap(*this); |
544 | return *this; |
545 | } |
546 | |
547 | // [3.7.2.2] function modifiers |
548 | |
549 | /** |
550 | * @brief Swap the targets of two %function objects. |
551 | * @param __x A %function with identical call signature. |
552 | * |
553 | * Swap the targets of `this` function object and `__f`. |
554 | * This function will not throw exceptions. |
555 | */ |
556 | void swap(function& __x) noexcept |
557 | { |
558 | std::swap(_M_functor, __x._M_functor); |
559 | std::swap(_M_manager, __x._M_manager); |
560 | std::swap(_M_invoker, __x._M_invoker); |
561 | } |
562 | |
563 | // [3.7.2.3] function capacity |
564 | |
565 | /** |
566 | * @brief Determine if the %function wrapper has a target. |
567 | * |
568 | * @return `true` when this function object contains a target, |
569 | * or `false` when it is empty. |
570 | * |
571 | * This function will not throw exceptions. |
572 | */ |
573 | explicit operator bool() const noexcept |
574 | { return !_M_empty(); } |
575 | |
576 | // [3.7.2.4] function invocation |
577 | |
578 | /** |
579 | * @brief Invokes the function targeted by `*this`. |
580 | * @returns the result of the target. |
581 | * @throws `bad_function_call` when `!(bool)*this` |
582 | * |
583 | * The function call operator invokes the target function object |
584 | * stored by `this`. |
585 | */ |
586 | _Res |
587 | operator()(_ArgTypes... __args) const |
588 | { |
589 | if (_M_empty()) |
590 | __throw_bad_function_call(); |
591 | return _M_invoker(_M_functor, std::forward<_ArgTypes>(__args)...); |
592 | } |
593 | |
594 | #if __cpp_rtti |
595 | // [3.7.2.5] function target access |
596 | /** |
597 | * @brief Determine the type of the target of this function object |
598 | * wrapper. |
599 | * |
600 | * @returns the type identifier of the target function object, or |
601 | * `typeid(void)` if `!(bool)*this`. |
602 | * |
603 | * This function will not throw exceptions. |
604 | */ |
605 | const type_info& |
606 | target_type() const noexcept |
607 | { |
608 | if (_M_manager) |
609 | { |
610 | _Any_data __typeinfo_result; |
611 | _M_manager(__typeinfo_result, _M_functor, __get_type_info); |
612 | if (auto __ti = __typeinfo_result._M_access<const type_info*>()) |
613 | return *__ti; |
614 | } |
615 | return typeid(void); |
616 | } |
617 | #endif |
618 | |
619 | /** |
620 | * @brief Access the stored target function object. |
621 | * |
622 | * @return Returns a pointer to the stored target function object, |
623 | * if `typeid(_Functor).equals(target_type())`; otherwise, a null |
624 | * pointer. |
625 | * |
626 | * This function does not throw exceptions. |
627 | * |
628 | * @{ |
629 | */ |
630 | template<typename _Functor> |
631 | _Functor* |
632 | target() noexcept |
633 | { |
634 | const function* __const_this = this; |
635 | const _Functor* __func = __const_this->template target<_Functor>(); |
636 | // If is_function_v<_Functor> is true then const_cast<_Functor*> |
637 | // would be ill-formed, so use *const_cast<_Functor**> instead. |
638 | return *const_cast<_Functor**>(&__func); |
639 | } |
640 | |
641 | template<typename _Functor> |
642 | const _Functor* |
643 | target() const noexcept |
644 | { |
645 | if _GLIBCXX17_CONSTEXPR (is_object<_Functor>::value) |
646 | { |
647 | // For C++11 and C++14 if-constexpr is not used above, so |
648 | // _Target_handler avoids ill-formed _Function_handler types. |
649 | using _Handler = _Target_handler<_Res(_ArgTypes...), _Functor>; |
650 | |
651 | if (_M_manager == &_Handler::_M_manager |
652 | #if __cpp_rtti |
653 | || (_M_manager && typeid(_Functor) == target_type()) |
654 | #endif |
655 | ) |
656 | { |
657 | _Any_data __ptr; |
658 | _M_manager(__ptr, _M_functor, __get_functor_ptr); |
659 | return __ptr._M_access<const _Functor*>(); |
660 | } |
661 | } |
662 | return nullptr; |
663 | } |
664 | /// @} |
665 | |
666 | private: |
667 | using _Invoker_type = _Res (*)(const _Any_data&, _ArgTypes&&...); |
668 | _Invoker_type _M_invoker = nullptr; |
669 | }; |
670 | |
671 | #if __cpp_deduction_guides >= 201606 |
672 | template<typename> |
673 | struct __function_guide_helper |
674 | { }; |
675 | |
676 | template<typename _Res, typename _Tp, bool _Nx, typename... _Args> |
677 | struct __function_guide_helper< |
678 | _Res (_Tp::*) (_Args...) noexcept(_Nx) |
679 | > |
680 | { using type = _Res(_Args...); }; |
681 | |
682 | template<typename _Res, typename _Tp, bool _Nx, typename... _Args> |
683 | struct __function_guide_helper< |
684 | _Res (_Tp::*) (_Args...) & noexcept(_Nx) |
685 | > |
686 | { using type = _Res(_Args...); }; |
687 | |
688 | template<typename _Res, typename _Tp, bool _Nx, typename... _Args> |
689 | struct __function_guide_helper< |
690 | _Res (_Tp::*) (_Args...) const noexcept(_Nx) |
691 | > |
692 | { using type = _Res(_Args...); }; |
693 | |
694 | template<typename _Res, typename _Tp, bool _Nx, typename... _Args> |
695 | struct __function_guide_helper< |
696 | _Res (_Tp::*) (_Args...) const & noexcept(_Nx) |
697 | > |
698 | { using type = _Res(_Args...); }; |
699 | |
700 | #if __cpp_explicit_this_parameter >= 202110L |
701 | template<typename _Res, typename _Tp, bool _Nx, typename... _Args> |
702 | struct __function_guide_helper<_Res (*) (_Tp, _Args...) noexcept(_Nx)> |
703 | { using type = _Res(_Args...); }; |
704 | #endif |
705 | |
706 | #if __cpp_static_call_operator >= 202207L && __cpp_concepts >= 202002L |
707 | template<typename _StaticCallOp> |
708 | struct __function_guide_static_helper |
709 | { }; |
710 | |
711 | template<typename _Res, bool _Nx, typename... _Args> |
712 | struct __function_guide_static_helper<_Res (*) (_Args...) noexcept(_Nx)> |
713 | { using type = _Res(_Args...); }; |
714 | |
715 | template<typename _Fn, typename _Op> |
716 | using __function_guide_t = typename __conditional_t< |
717 | requires (_Fn& __f) { (void) __f.operator(); }, |
718 | __function_guide_static_helper<_Op>, |
719 | __function_guide_helper<_Op>>::type; |
720 | #else |
721 | template<typename _Fn, typename _Op> |
722 | using __function_guide_t = typename __function_guide_helper<_Op>::type; |
723 | #endif |
724 | |
725 | template<typename _Res, typename... _ArgTypes> |
726 | function(_Res(*)(_ArgTypes...)) -> function<_Res(_ArgTypes...)>; |
727 | |
728 | template<typename _Fn, typename _Signature |
729 | = __function_guide_t<_Fn, decltype(&_Fn::operator())>> |
730 | function(_Fn) -> function<_Signature>; |
731 | #endif |
732 | |
733 | // [20.7.15.2.6] null pointer comparisons |
734 | |
735 | /** |
736 | * @brief Test whether a polymorphic function object wrapper is empty. |
737 | * @returns `true` if the wrapper has no target, `false` otherwise |
738 | * |
739 | * This function will not throw exceptions. |
740 | */ |
741 | template<typename _Res, typename... _Args> |
742 | inline bool |
743 | operator==(const function<_Res(_Args...)>& __f, nullptr_t) noexcept |
744 | { return !static_cast<bool>(__f); } |
745 | |
746 | #if __cpp_impl_three_way_comparison < 201907L |
747 | /// @overload |
748 | template<typename _Res, typename... _Args> |
749 | inline bool |
750 | operator==(nullptr_t, const function<_Res(_Args...)>& __f) noexcept |
751 | { return !static_cast<bool>(__f); } |
752 | |
753 | /** |
754 | * @brief Test whether a polymorphic function object wrapper is non-empty. |
755 | * @returns `false` if the wrapper has no target, `true` otherwise |
756 | * |
757 | * This function will not throw exceptions. |
758 | */ |
759 | template<typename _Res, typename... _Args> |
760 | inline bool |
761 | operator!=(const function<_Res(_Args...)>& __f, nullptr_t) noexcept |
762 | { return static_cast<bool>(__f); } |
763 | |
764 | /// @overload |
765 | template<typename _Res, typename... _Args> |
766 | inline bool |
767 | operator!=(nullptr_t, const function<_Res(_Args...)>& __f) noexcept |
768 | { return static_cast<bool>(__f); } |
769 | #endif |
770 | |
771 | // [20.7.15.2.7] specialized algorithms |
772 | |
773 | /** |
774 | * @brief Swap the targets of two polymorphic function object wrappers. |
775 | * |
776 | * This function will not throw exceptions. |
777 | */ |
778 | // _GLIBCXX_RESOLVE_LIB_DEFECTS |
779 | // 2062. Effect contradictions w/o no-throw guarantee of std::function swaps |
780 | template<typename _Res, typename... _Args> |
781 | inline void |
782 | swap(function<_Res(_Args...)>& __x, function<_Res(_Args...)>& __y) noexcept |
783 | { __x.swap(__y); } |
784 | |
785 | #if __cplusplus >= 201703L |
786 | namespace __detail::__variant |
787 | { |
788 | template<typename> struct _Never_valueless_alt; // see <variant> |
789 | |
790 | // Provide the strong exception-safety guarantee when emplacing a |
791 | // function into a variant. |
792 | template<typename _Signature> |
793 | struct _Never_valueless_alt<std::function<_Signature>> |
794 | : std::true_type |
795 | { }; |
796 | } // namespace __detail::__variant |
797 | #endif // C++17 |
798 | |
799 | _GLIBCXX_END_NAMESPACE_VERSION |
800 | } // namespace std |
801 | |
802 | #endif // C++11 |
803 | #endif // _GLIBCXX_STD_FUNCTION_H |
804 | |