13ad841b2Smrg // Implementation of std::function -*- C++ -*-
23ad841b2Smrg
3*4c3eb207Smrg // Copyright (C) 2004-2020 Free Software Foundation, Inc.
43ad841b2Smrg //
53ad841b2Smrg // This file is part of the GNU ISO C++ Library. This library is free
63ad841b2Smrg // software; you can redistribute it and/or modify it under the
73ad841b2Smrg // terms of the GNU General Public License as published by the
83ad841b2Smrg // Free Software Foundation; either version 3, or (at your option)
93ad841b2Smrg // any later version.
103ad841b2Smrg
113ad841b2Smrg // This library is distributed in the hope that it will be useful,
123ad841b2Smrg // but WITHOUT ANY WARRANTY; without even the implied warranty of
133ad841b2Smrg // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
143ad841b2Smrg // GNU General Public License for more details.
153ad841b2Smrg
163ad841b2Smrg // Under Section 7 of GPL version 3, you are granted additional
173ad841b2Smrg // permissions described in the GCC Runtime Library Exception, version
183ad841b2Smrg // 3.1, as published by the Free Software Foundation.
193ad841b2Smrg
203ad841b2Smrg // You should have received a copy of the GNU General Public License and
213ad841b2Smrg // a copy of the GCC Runtime Library Exception along with this program;
223ad841b2Smrg // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
233ad841b2Smrg // <http://www.gnu.org/licenses/>.
243ad841b2Smrg
25cef8759bSmrg /** @file include/bits/std_function.h
263ad841b2Smrg * This is an internal header file, included by other library headers.
273ad841b2Smrg * Do not attempt to use it directly. @headername{functional}
283ad841b2Smrg */
293ad841b2Smrg
303ad841b2Smrg #ifndef _GLIBCXX_STD_FUNCTION_H
313ad841b2Smrg #define _GLIBCXX_STD_FUNCTION_H 1
323ad841b2Smrg
333ad841b2Smrg #pragma GCC system_header
343ad841b2Smrg
353ad841b2Smrg #if __cplusplus < 201103L
363ad841b2Smrg # include <bits/c++0x_warning.h>
373ad841b2Smrg #else
383ad841b2Smrg
393ad841b2Smrg #if __cpp_rtti
403ad841b2Smrg # include <typeinfo>
413ad841b2Smrg #endif
423ad841b2Smrg #include <bits/stl_function.h>
433ad841b2Smrg #include <bits/invoke.h>
443ad841b2Smrg #include <bits/refwrap.h>
453ad841b2Smrg #include <bits/functexcept.h>
463ad841b2Smrg
_GLIBCXX_VISIBILITY(default)473ad841b2Smrg namespace std _GLIBCXX_VISIBILITY(default)
483ad841b2Smrg {
493ad841b2Smrg _GLIBCXX_BEGIN_NAMESPACE_VERSION
503ad841b2Smrg
513ad841b2Smrg /**
523ad841b2Smrg * @brief Exception class thrown when class template function's
533ad841b2Smrg * operator() is called with an empty target.
543ad841b2Smrg * @ingroup exceptions
553ad841b2Smrg */
563ad841b2Smrg class bad_function_call : public std::exception
573ad841b2Smrg {
583ad841b2Smrg public:
593ad841b2Smrg virtual ~bad_function_call() noexcept;
603ad841b2Smrg
613ad841b2Smrg const char* what() const noexcept;
623ad841b2Smrg };
633ad841b2Smrg
643ad841b2Smrg /**
653ad841b2Smrg * Trait identifying "location-invariant" types, meaning that the
663ad841b2Smrg * address of the object (or any of its members) will not escape.
673ad841b2Smrg * Trivially copyable types are location-invariant and users can
683ad841b2Smrg * specialize this trait for other types.
693ad841b2Smrg */
703ad841b2Smrg template<typename _Tp>
713ad841b2Smrg struct __is_location_invariant
723ad841b2Smrg : is_trivially_copyable<_Tp>::type
733ad841b2Smrg { };
743ad841b2Smrg
753ad841b2Smrg class _Undefined_class;
763ad841b2Smrg
773ad841b2Smrg union _Nocopy_types
783ad841b2Smrg {
793ad841b2Smrg void* _M_object;
803ad841b2Smrg const void* _M_const_object;
813ad841b2Smrg void (*_M_function_pointer)();
823ad841b2Smrg void (_Undefined_class::*_M_member_pointer)();
833ad841b2Smrg };
843ad841b2Smrg
853ad841b2Smrg union [[gnu::may_alias]] _Any_data
863ad841b2Smrg {
873ad841b2Smrg void* _M_access() { return &_M_pod_data[0]; }
883ad841b2Smrg const void* _M_access() const { return &_M_pod_data[0]; }
893ad841b2Smrg
903ad841b2Smrg template<typename _Tp>
913ad841b2Smrg _Tp&
923ad841b2Smrg _M_access()
933ad841b2Smrg { return *static_cast<_Tp*>(_M_access()); }
943ad841b2Smrg
953ad841b2Smrg template<typename _Tp>
963ad841b2Smrg const _Tp&
973ad841b2Smrg _M_access() const
983ad841b2Smrg { return *static_cast<const _Tp*>(_M_access()); }
993ad841b2Smrg
1003ad841b2Smrg _Nocopy_types _M_unused;
1013ad841b2Smrg char _M_pod_data[sizeof(_Nocopy_types)];
1023ad841b2Smrg };
1033ad841b2Smrg
1043ad841b2Smrg enum _Manager_operation
1053ad841b2Smrg {
1063ad841b2Smrg __get_type_info,
1073ad841b2Smrg __get_functor_ptr,
1083ad841b2Smrg __clone_functor,
1093ad841b2Smrg __destroy_functor
1103ad841b2Smrg };
1113ad841b2Smrg
1123ad841b2Smrg template<typename _Signature>
1133ad841b2Smrg class function;
1143ad841b2Smrg
1153ad841b2Smrg /// Base class of all polymorphic function object wrappers.
1163ad841b2Smrg class _Function_base
1173ad841b2Smrg {
1183ad841b2Smrg public:
119627f7eb2Smrg static const size_t _M_max_size = sizeof(_Nocopy_types);
120627f7eb2Smrg static const size_t _M_max_align = __alignof__(_Nocopy_types);
1213ad841b2Smrg
1223ad841b2Smrg template<typename _Functor>
1233ad841b2Smrg class _Base_manager
1243ad841b2Smrg {
1253ad841b2Smrg protected:
1263ad841b2Smrg static const bool __stored_locally =
1273ad841b2Smrg (__is_location_invariant<_Functor>::value
1283ad841b2Smrg && sizeof(_Functor) <= _M_max_size
1293ad841b2Smrg && __alignof__(_Functor) <= _M_max_align
1303ad841b2Smrg && (_M_max_align % __alignof__(_Functor) == 0));
1313ad841b2Smrg
1323ad841b2Smrg typedef integral_constant<bool, __stored_locally> _Local_storage;
1333ad841b2Smrg
1343ad841b2Smrg // Retrieve a pointer to the function object
1353ad841b2Smrg static _Functor*
1363ad841b2Smrg _M_get_pointer(const _Any_data& __source)
1373ad841b2Smrg {
138627f7eb2Smrg if _GLIBCXX17_CONSTEXPR (__stored_locally)
139627f7eb2Smrg {
140627f7eb2Smrg const _Functor& __f = __source._M_access<_Functor>();
141627f7eb2Smrg return const_cast<_Functor*>(std::__addressof(__f));
142627f7eb2Smrg }
143627f7eb2Smrg else // have stored a pointer
144627f7eb2Smrg return __source._M_access<_Functor*>();
1453ad841b2Smrg }
1463ad841b2Smrg
1473ad841b2Smrg // Clone a location-invariant function object that fits within
1483ad841b2Smrg // an _Any_data structure.
1493ad841b2Smrg static void
1503ad841b2Smrg _M_clone(_Any_data& __dest, const _Any_data& __source, true_type)
1513ad841b2Smrg {
1523ad841b2Smrg ::new (__dest._M_access()) _Functor(__source._M_access<_Functor>());
1533ad841b2Smrg }
1543ad841b2Smrg
1553ad841b2Smrg // Clone a function object that is not location-invariant or
1563ad841b2Smrg // that cannot fit into an _Any_data structure.
1573ad841b2Smrg static void
1583ad841b2Smrg _M_clone(_Any_data& __dest, const _Any_data& __source, false_type)
1593ad841b2Smrg {
1603ad841b2Smrg __dest._M_access<_Functor*>() =
161627f7eb2Smrg new _Functor(*__source._M_access<const _Functor*>());
1623ad841b2Smrg }
1633ad841b2Smrg
1643ad841b2Smrg // Destroying a location-invariant object may still require
1653ad841b2Smrg // destruction.
1663ad841b2Smrg static void
1673ad841b2Smrg _M_destroy(_Any_data& __victim, true_type)
1683ad841b2Smrg {
1693ad841b2Smrg __victim._M_access<_Functor>().~_Functor();
1703ad841b2Smrg }
1713ad841b2Smrg
1723ad841b2Smrg // Destroying an object located on the heap.
1733ad841b2Smrg static void
1743ad841b2Smrg _M_destroy(_Any_data& __victim, false_type)
1753ad841b2Smrg {
1763ad841b2Smrg delete __victim._M_access<_Functor*>();
1773ad841b2Smrg }
1783ad841b2Smrg
1793ad841b2Smrg public:
1803ad841b2Smrg static bool
1813ad841b2Smrg _M_manager(_Any_data& __dest, const _Any_data& __source,
1823ad841b2Smrg _Manager_operation __op)
1833ad841b2Smrg {
1843ad841b2Smrg switch (__op)
1853ad841b2Smrg {
1863ad841b2Smrg #if __cpp_rtti
1873ad841b2Smrg case __get_type_info:
1883ad841b2Smrg __dest._M_access<const type_info*>() = &typeid(_Functor);
1893ad841b2Smrg break;
1903ad841b2Smrg #endif
1913ad841b2Smrg case __get_functor_ptr:
1923ad841b2Smrg __dest._M_access<_Functor*>() = _M_get_pointer(__source);
1933ad841b2Smrg break;
1943ad841b2Smrg
1953ad841b2Smrg case __clone_functor:
1963ad841b2Smrg _M_clone(__dest, __source, _Local_storage());
1973ad841b2Smrg break;
1983ad841b2Smrg
1993ad841b2Smrg case __destroy_functor:
2003ad841b2Smrg _M_destroy(__dest, _Local_storage());
2013ad841b2Smrg break;
2023ad841b2Smrg }
2033ad841b2Smrg return false;
2043ad841b2Smrg }
2053ad841b2Smrg
2063ad841b2Smrg static void
2073ad841b2Smrg _M_init_functor(_Any_data& __functor, _Functor&& __f)
2083ad841b2Smrg { _M_init_functor(__functor, std::move(__f), _Local_storage()); }
2093ad841b2Smrg
2103ad841b2Smrg template<typename _Signature>
2113ad841b2Smrg static bool
2123ad841b2Smrg _M_not_empty_function(const function<_Signature>& __f)
2133ad841b2Smrg { return static_cast<bool>(__f); }
2143ad841b2Smrg
2153ad841b2Smrg template<typename _Tp>
2163ad841b2Smrg static bool
2173ad841b2Smrg _M_not_empty_function(_Tp* __fp)
2183ad841b2Smrg { return __fp != nullptr; }
2193ad841b2Smrg
2203ad841b2Smrg template<typename _Class, typename _Tp>
2213ad841b2Smrg static bool
2223ad841b2Smrg _M_not_empty_function(_Tp _Class::* __mp)
2233ad841b2Smrg { return __mp != nullptr; }
2243ad841b2Smrg
2253ad841b2Smrg template<typename _Tp>
2263ad841b2Smrg static bool
2273ad841b2Smrg _M_not_empty_function(const _Tp&)
2283ad841b2Smrg { return true; }
2293ad841b2Smrg
2303ad841b2Smrg private:
2313ad841b2Smrg static void
2323ad841b2Smrg _M_init_functor(_Any_data& __functor, _Functor&& __f, true_type)
2333ad841b2Smrg { ::new (__functor._M_access()) _Functor(std::move(__f)); }
2343ad841b2Smrg
2353ad841b2Smrg static void
2363ad841b2Smrg _M_init_functor(_Any_data& __functor, _Functor&& __f, false_type)
2373ad841b2Smrg { __functor._M_access<_Functor*>() = new _Functor(std::move(__f)); }
2383ad841b2Smrg };
2393ad841b2Smrg
2403ad841b2Smrg _Function_base() : _M_manager(nullptr) { }
2413ad841b2Smrg
2423ad841b2Smrg ~_Function_base()
2433ad841b2Smrg {
2443ad841b2Smrg if (_M_manager)
2453ad841b2Smrg _M_manager(_M_functor, _M_functor, __destroy_functor);
2463ad841b2Smrg }
2473ad841b2Smrg
2483ad841b2Smrg bool _M_empty() const { return !_M_manager; }
2493ad841b2Smrg
2503ad841b2Smrg typedef bool (*_Manager_type)(_Any_data&, const _Any_data&,
2513ad841b2Smrg _Manager_operation);
2523ad841b2Smrg
2533ad841b2Smrg _Any_data _M_functor;
2543ad841b2Smrg _Manager_type _M_manager;
2553ad841b2Smrg };
2563ad841b2Smrg
2573ad841b2Smrg template<typename _Signature, typename _Functor>
2583ad841b2Smrg class _Function_handler;
2593ad841b2Smrg
2603ad841b2Smrg template<typename _Res, typename _Functor, typename... _ArgTypes>
2613ad841b2Smrg class _Function_handler<_Res(_ArgTypes...), _Functor>
2623ad841b2Smrg : public _Function_base::_Base_manager<_Functor>
2633ad841b2Smrg {
2643ad841b2Smrg typedef _Function_base::_Base_manager<_Functor> _Base;
2653ad841b2Smrg
2663ad841b2Smrg public:
2673ad841b2Smrg static bool
2683ad841b2Smrg _M_manager(_Any_data& __dest, const _Any_data& __source,
2693ad841b2Smrg _Manager_operation __op)
2703ad841b2Smrg {
2713ad841b2Smrg switch (__op)
2723ad841b2Smrg {
2733ad841b2Smrg #if __cpp_rtti
2743ad841b2Smrg case __get_type_info:
2753ad841b2Smrg __dest._M_access<const type_info*>() = &typeid(_Functor);
2763ad841b2Smrg break;
2773ad841b2Smrg #endif
2783ad841b2Smrg case __get_functor_ptr:
279*4c3eb207Smrg __dest._M_access<_Functor*>() = _Base::_M_get_pointer(__source);
2803ad841b2Smrg break;
2813ad841b2Smrg
2823ad841b2Smrg default:
2833ad841b2Smrg _Base::_M_manager(__dest, __source, __op);
2843ad841b2Smrg }
2853ad841b2Smrg return false;
2863ad841b2Smrg }
2873ad841b2Smrg
288*4c3eb207Smrg static _Res
2893ad841b2Smrg _M_invoke(const _Any_data& __functor, _ArgTypes&&... __args)
2903ad841b2Smrg {
291*4c3eb207Smrg return std::__invoke_r<_Res>(*_Base::_M_get_pointer(__functor),
2923ad841b2Smrg std::forward<_ArgTypes>(__args)...);
2933ad841b2Smrg }
2943ad841b2Smrg };
2953ad841b2Smrg
2963ad841b2Smrg /**
2973ad841b2Smrg * @brief Primary class template for std::function.
2983ad841b2Smrg * @ingroup functors
2993ad841b2Smrg *
3003ad841b2Smrg * Polymorphic function wrapper.
3013ad841b2Smrg */
3023ad841b2Smrg template<typename _Res, typename... _ArgTypes>
3033ad841b2Smrg class function<_Res(_ArgTypes...)>
3043ad841b2Smrg : public _Maybe_unary_or_binary_function<_Res, _ArgTypes...>,
3053ad841b2Smrg private _Function_base
3063ad841b2Smrg {
3073ad841b2Smrg template<typename _Func,
308627f7eb2Smrg typename _Res2 = __invoke_result<_Func&, _ArgTypes...>>
309627f7eb2Smrg struct _Callable
310627f7eb2Smrg : __is_invocable_impl<_Res2, _Res>::type
311627f7eb2Smrg { };
3123ad841b2Smrg
3133ad841b2Smrg // Used so the return type convertibility checks aren't done when
3143ad841b2Smrg // performing overload resolution for copy construction/assignment.
3153ad841b2Smrg template<typename _Tp>
3163ad841b2Smrg struct _Callable<function, _Tp> : false_type { };
3173ad841b2Smrg
3183ad841b2Smrg template<typename _Cond, typename _Tp>
3193ad841b2Smrg using _Requires = typename enable_if<_Cond::value, _Tp>::type;
3203ad841b2Smrg
3213ad841b2Smrg public:
3223ad841b2Smrg typedef _Res result_type;
3233ad841b2Smrg
3243ad841b2Smrg // [3.7.2.1] construct/copy/destroy
3253ad841b2Smrg
3263ad841b2Smrg /**
3273ad841b2Smrg * @brief Default construct creates an empty function call wrapper.
3283ad841b2Smrg * @post @c !(bool)*this
3293ad841b2Smrg */
3303ad841b2Smrg function() noexcept
3313ad841b2Smrg : _Function_base() { }
3323ad841b2Smrg
3333ad841b2Smrg /**
3343ad841b2Smrg * @brief Creates an empty function call wrapper.
3353ad841b2Smrg * @post @c !(bool)*this
3363ad841b2Smrg */
3373ad841b2Smrg function(nullptr_t) noexcept
3383ad841b2Smrg : _Function_base() { }
3393ad841b2Smrg
3403ad841b2Smrg /**
3413ad841b2Smrg * @brief %Function copy constructor.
3423ad841b2Smrg * @param __x A %function object with identical call signature.
3433ad841b2Smrg * @post @c bool(*this) == bool(__x)
3443ad841b2Smrg *
3453ad841b2Smrg * The newly-created %function contains a copy of the target of @a
3463ad841b2Smrg * __x (if it has one).
3473ad841b2Smrg */
3483ad841b2Smrg function(const function& __x);
3493ad841b2Smrg
3503ad841b2Smrg /**
3513ad841b2Smrg * @brief %Function move constructor.
3523ad841b2Smrg * @param __x A %function object rvalue with identical call signature.
3533ad841b2Smrg *
3543ad841b2Smrg * The newly-created %function contains the target of @a __x
3553ad841b2Smrg * (if it has one).
3563ad841b2Smrg */
3573ad841b2Smrg function(function&& __x) noexcept : _Function_base()
3583ad841b2Smrg {
3593ad841b2Smrg __x.swap(*this);
3603ad841b2Smrg }
3613ad841b2Smrg
3623ad841b2Smrg /**
3633ad841b2Smrg * @brief Builds a %function that targets a copy of the incoming
3643ad841b2Smrg * function object.
3653ad841b2Smrg * @param __f A %function object that is callable with parameters of
3663ad841b2Smrg * type @c T1, @c T2, ..., @c TN and returns a value convertible
3673ad841b2Smrg * to @c Res.
3683ad841b2Smrg *
3693ad841b2Smrg * The newly-created %function object will target a copy of
3703ad841b2Smrg * @a __f. If @a __f is @c reference_wrapper<F>, then this function
3713ad841b2Smrg * object will contain a reference to the function object @c
3723ad841b2Smrg * __f.get(). If @a __f is a NULL function pointer or NULL
3733ad841b2Smrg * pointer-to-member, the newly-created object will be empty.
3743ad841b2Smrg *
3753ad841b2Smrg * If @a __f is a non-NULL function pointer or an object of type @c
3763ad841b2Smrg * reference_wrapper<F>, this function will not throw.
3773ad841b2Smrg */
3783ad841b2Smrg template<typename _Functor,
3793ad841b2Smrg typename = _Requires<__not_<is_same<_Functor, function>>, void>,
3803ad841b2Smrg typename = _Requires<_Callable<_Functor>, void>>
3813ad841b2Smrg function(_Functor);
3823ad841b2Smrg
3833ad841b2Smrg /**
3843ad841b2Smrg * @brief %Function assignment operator.
3853ad841b2Smrg * @param __x A %function with identical call signature.
3863ad841b2Smrg * @post @c (bool)*this == (bool)x
3873ad841b2Smrg * @returns @c *this
3883ad841b2Smrg *
3893ad841b2Smrg * The target of @a __x is copied to @c *this. If @a __x has no
3903ad841b2Smrg * target, then @c *this will be empty.
3913ad841b2Smrg *
3923ad841b2Smrg * If @a __x targets a function pointer or a reference to a function
3933ad841b2Smrg * object, then this operation will not throw an %exception.
3943ad841b2Smrg */
3953ad841b2Smrg function&
3963ad841b2Smrg operator=(const function& __x)
3973ad841b2Smrg {
3983ad841b2Smrg function(__x).swap(*this);
3993ad841b2Smrg return *this;
4003ad841b2Smrg }
4013ad841b2Smrg
4023ad841b2Smrg /**
4033ad841b2Smrg * @brief %Function move-assignment operator.
4043ad841b2Smrg * @param __x A %function rvalue with identical call signature.
4053ad841b2Smrg * @returns @c *this
4063ad841b2Smrg *
4073ad841b2Smrg * The target of @a __x is moved to @c *this. If @a __x has no
4083ad841b2Smrg * target, then @c *this will be empty.
4093ad841b2Smrg *
4103ad841b2Smrg * If @a __x targets a function pointer or a reference to a function
4113ad841b2Smrg * object, then this operation will not throw an %exception.
4123ad841b2Smrg */
4133ad841b2Smrg function&
4143ad841b2Smrg operator=(function&& __x) noexcept
4153ad841b2Smrg {
4163ad841b2Smrg function(std::move(__x)).swap(*this);
4173ad841b2Smrg return *this;
4183ad841b2Smrg }
4193ad841b2Smrg
4203ad841b2Smrg /**
4213ad841b2Smrg * @brief %Function assignment to zero.
4223ad841b2Smrg * @post @c !(bool)*this
4233ad841b2Smrg * @returns @c *this
4243ad841b2Smrg *
4253ad841b2Smrg * The target of @c *this is deallocated, leaving it empty.
4263ad841b2Smrg */
4273ad841b2Smrg function&
4283ad841b2Smrg operator=(nullptr_t) noexcept
4293ad841b2Smrg {
4303ad841b2Smrg if (_M_manager)
4313ad841b2Smrg {
4323ad841b2Smrg _M_manager(_M_functor, _M_functor, __destroy_functor);
4333ad841b2Smrg _M_manager = nullptr;
4343ad841b2Smrg _M_invoker = nullptr;
4353ad841b2Smrg }
4363ad841b2Smrg return *this;
4373ad841b2Smrg }
4383ad841b2Smrg
4393ad841b2Smrg /**
4403ad841b2Smrg * @brief %Function assignment to a new target.
4413ad841b2Smrg * @param __f A %function object that is callable with parameters of
4423ad841b2Smrg * type @c T1, @c T2, ..., @c TN and returns a value convertible
4433ad841b2Smrg * to @c Res.
4443ad841b2Smrg * @return @c *this
4453ad841b2Smrg *
4463ad841b2Smrg * This %function object wrapper will target a copy of @a
4473ad841b2Smrg * __f. If @a __f is @c reference_wrapper<F>, then this function
4483ad841b2Smrg * object will contain a reference to the function object @c
4493ad841b2Smrg * __f.get(). If @a __f is a NULL function pointer or NULL
4503ad841b2Smrg * pointer-to-member, @c this object will be empty.
4513ad841b2Smrg *
4523ad841b2Smrg * If @a __f is a non-NULL function pointer or an object of type @c
4533ad841b2Smrg * reference_wrapper<F>, this function will not throw.
4543ad841b2Smrg */
4553ad841b2Smrg template<typename _Functor>
4563ad841b2Smrg _Requires<_Callable<typename decay<_Functor>::type>, function&>
4573ad841b2Smrg operator=(_Functor&& __f)
4583ad841b2Smrg {
4593ad841b2Smrg function(std::forward<_Functor>(__f)).swap(*this);
4603ad841b2Smrg return *this;
4613ad841b2Smrg }
4623ad841b2Smrg
4633ad841b2Smrg /// @overload
4643ad841b2Smrg template<typename _Functor>
4653ad841b2Smrg function&
4663ad841b2Smrg operator=(reference_wrapper<_Functor> __f) noexcept
4673ad841b2Smrg {
4683ad841b2Smrg function(__f).swap(*this);
4693ad841b2Smrg return *this;
4703ad841b2Smrg }
4713ad841b2Smrg
4723ad841b2Smrg // [3.7.2.2] function modifiers
4733ad841b2Smrg
4743ad841b2Smrg /**
4753ad841b2Smrg * @brief Swap the targets of two %function objects.
4763ad841b2Smrg * @param __x A %function with identical call signature.
4773ad841b2Smrg *
4783ad841b2Smrg * Swap the targets of @c this function object and @a __f. This
4793ad841b2Smrg * function will not throw an %exception.
4803ad841b2Smrg */
4813ad841b2Smrg void swap(function& __x) noexcept
4823ad841b2Smrg {
4833ad841b2Smrg std::swap(_M_functor, __x._M_functor);
4843ad841b2Smrg std::swap(_M_manager, __x._M_manager);
4853ad841b2Smrg std::swap(_M_invoker, __x._M_invoker);
4863ad841b2Smrg }
4873ad841b2Smrg
4883ad841b2Smrg // [3.7.2.3] function capacity
4893ad841b2Smrg
4903ad841b2Smrg /**
4913ad841b2Smrg * @brief Determine if the %function wrapper has a target.
4923ad841b2Smrg *
4933ad841b2Smrg * @return @c true when this %function object contains a target,
4943ad841b2Smrg * or @c false when it is empty.
4953ad841b2Smrg *
4963ad841b2Smrg * This function will not throw an %exception.
4973ad841b2Smrg */
4983ad841b2Smrg explicit operator bool() const noexcept
4993ad841b2Smrg { return !_M_empty(); }
5003ad841b2Smrg
5013ad841b2Smrg // [3.7.2.4] function invocation
5023ad841b2Smrg
5033ad841b2Smrg /**
5043ad841b2Smrg * @brief Invokes the function targeted by @c *this.
5053ad841b2Smrg * @returns the result of the target.
5063ad841b2Smrg * @throws bad_function_call when @c !(bool)*this
5073ad841b2Smrg *
5083ad841b2Smrg * The function call operator invokes the target function object
5093ad841b2Smrg * stored by @c this.
5103ad841b2Smrg */
5113ad841b2Smrg _Res operator()(_ArgTypes... __args) const;
5123ad841b2Smrg
5133ad841b2Smrg #if __cpp_rtti
5143ad841b2Smrg // [3.7.2.5] function target access
5153ad841b2Smrg /**
5163ad841b2Smrg * @brief Determine the type of the target of this function object
5173ad841b2Smrg * wrapper.
5183ad841b2Smrg *
5193ad841b2Smrg * @returns the type identifier of the target function object, or
5203ad841b2Smrg * @c typeid(void) if @c !(bool)*this.
5213ad841b2Smrg *
5223ad841b2Smrg * This function will not throw an %exception.
5233ad841b2Smrg */
5243ad841b2Smrg const type_info& target_type() const noexcept;
5253ad841b2Smrg
5263ad841b2Smrg /**
5273ad841b2Smrg * @brief Access the stored target function object.
5283ad841b2Smrg *
5293ad841b2Smrg * @return Returns a pointer to the stored target function object,
5303ad841b2Smrg * if @c typeid(_Functor).equals(target_type()); otherwise, a NULL
5313ad841b2Smrg * pointer.
5323ad841b2Smrg *
5333ad841b2Smrg * This function does not throw exceptions.
5343ad841b2Smrg *
5353ad841b2Smrg * @{
5363ad841b2Smrg */
5373ad841b2Smrg template<typename _Functor> _Functor* target() noexcept;
5383ad841b2Smrg
5393ad841b2Smrg template<typename _Functor> const _Functor* target() const noexcept;
540*4c3eb207Smrg /// @}
5413ad841b2Smrg #endif
5423ad841b2Smrg
5433ad841b2Smrg private:
5443ad841b2Smrg using _Invoker_type = _Res (*)(const _Any_data&, _ArgTypes&&...);
5453ad841b2Smrg _Invoker_type _M_invoker;
5463ad841b2Smrg };
5473ad841b2Smrg
5483ad841b2Smrg #if __cpp_deduction_guides >= 201606
5493ad841b2Smrg template<typename>
5503ad841b2Smrg struct __function_guide_helper
5513ad841b2Smrg { };
5523ad841b2Smrg
5533ad841b2Smrg template<typename _Res, typename _Tp, bool _Nx, typename... _Args>
5543ad841b2Smrg struct __function_guide_helper<
5553ad841b2Smrg _Res (_Tp::*) (_Args...) noexcept(_Nx)
5563ad841b2Smrg >
5573ad841b2Smrg { using type = _Res(_Args...); };
5583ad841b2Smrg
5593ad841b2Smrg template<typename _Res, typename _Tp, bool _Nx, typename... _Args>
5603ad841b2Smrg struct __function_guide_helper<
5613ad841b2Smrg _Res (_Tp::*) (_Args...) & noexcept(_Nx)
5623ad841b2Smrg >
5633ad841b2Smrg { using type = _Res(_Args...); };
5643ad841b2Smrg
5653ad841b2Smrg template<typename _Res, typename _Tp, bool _Nx, typename... _Args>
5663ad841b2Smrg struct __function_guide_helper<
5673ad841b2Smrg _Res (_Tp::*) (_Args...) const noexcept(_Nx)
5683ad841b2Smrg >
5693ad841b2Smrg { using type = _Res(_Args...); };
5703ad841b2Smrg
5713ad841b2Smrg template<typename _Res, typename _Tp, bool _Nx, typename... _Args>
5723ad841b2Smrg struct __function_guide_helper<
5733ad841b2Smrg _Res (_Tp::*) (_Args...) const & noexcept(_Nx)
5743ad841b2Smrg >
5753ad841b2Smrg { using type = _Res(_Args...); };
5763ad841b2Smrg
5773ad841b2Smrg template<typename _Res, typename... _ArgTypes>
5783ad841b2Smrg function(_Res(*)(_ArgTypes...)) -> function<_Res(_ArgTypes...)>;
5793ad841b2Smrg
5803ad841b2Smrg template<typename _Functor, typename _Signature = typename
5813ad841b2Smrg __function_guide_helper<decltype(&_Functor::operator())>::type>
5823ad841b2Smrg function(_Functor) -> function<_Signature>;
5833ad841b2Smrg #endif
5843ad841b2Smrg
5853ad841b2Smrg // Out-of-line member definitions.
5863ad841b2Smrg template<typename _Res, typename... _ArgTypes>
5873ad841b2Smrg function<_Res(_ArgTypes...)>::
5883ad841b2Smrg function(const function& __x)
5893ad841b2Smrg : _Function_base()
5903ad841b2Smrg {
5913ad841b2Smrg if (static_cast<bool>(__x))
5923ad841b2Smrg {
5933ad841b2Smrg __x._M_manager(_M_functor, __x._M_functor, __clone_functor);
5943ad841b2Smrg _M_invoker = __x._M_invoker;
5953ad841b2Smrg _M_manager = __x._M_manager;
5963ad841b2Smrg }
5973ad841b2Smrg }
5983ad841b2Smrg
5993ad841b2Smrg template<typename _Res, typename... _ArgTypes>
6003ad841b2Smrg template<typename _Functor, typename, typename>
6013ad841b2Smrg function<_Res(_ArgTypes...)>::
6023ad841b2Smrg function(_Functor __f)
6033ad841b2Smrg : _Function_base()
6043ad841b2Smrg {
6053ad841b2Smrg typedef _Function_handler<_Res(_ArgTypes...), _Functor> _My_handler;
6063ad841b2Smrg
6073ad841b2Smrg if (_My_handler::_M_not_empty_function(__f))
6083ad841b2Smrg {
6093ad841b2Smrg _My_handler::_M_init_functor(_M_functor, std::move(__f));
6103ad841b2Smrg _M_invoker = &_My_handler::_M_invoke;
6113ad841b2Smrg _M_manager = &_My_handler::_M_manager;
6123ad841b2Smrg }
6133ad841b2Smrg }
6143ad841b2Smrg
6153ad841b2Smrg template<typename _Res, typename... _ArgTypes>
6163ad841b2Smrg _Res
6173ad841b2Smrg function<_Res(_ArgTypes...)>::
6183ad841b2Smrg operator()(_ArgTypes... __args) const
6193ad841b2Smrg {
6203ad841b2Smrg if (_M_empty())
6213ad841b2Smrg __throw_bad_function_call();
6223ad841b2Smrg return _M_invoker(_M_functor, std::forward<_ArgTypes>(__args)...);
6233ad841b2Smrg }
6243ad841b2Smrg
6253ad841b2Smrg #if __cpp_rtti
6263ad841b2Smrg template<typename _Res, typename... _ArgTypes>
6273ad841b2Smrg const type_info&
6283ad841b2Smrg function<_Res(_ArgTypes...)>::
6293ad841b2Smrg target_type() const noexcept
6303ad841b2Smrg {
6313ad841b2Smrg if (_M_manager)
6323ad841b2Smrg {
6333ad841b2Smrg _Any_data __typeinfo_result;
6343ad841b2Smrg _M_manager(__typeinfo_result, _M_functor, __get_type_info);
6353ad841b2Smrg return *__typeinfo_result._M_access<const type_info*>();
6363ad841b2Smrg }
6373ad841b2Smrg else
6383ad841b2Smrg return typeid(void);
6393ad841b2Smrg }
6403ad841b2Smrg
6413ad841b2Smrg template<typename _Res, typename... _ArgTypes>
6423ad841b2Smrg template<typename _Functor>
6433ad841b2Smrg _Functor*
6443ad841b2Smrg function<_Res(_ArgTypes...)>::
6453ad841b2Smrg target() noexcept
6463ad841b2Smrg {
6473ad841b2Smrg const function* __const_this = this;
6483ad841b2Smrg const _Functor* __func = __const_this->template target<_Functor>();
6493ad841b2Smrg return const_cast<_Functor*>(__func);
6503ad841b2Smrg }
6513ad841b2Smrg
6523ad841b2Smrg template<typename _Res, typename... _ArgTypes>
6533ad841b2Smrg template<typename _Functor>
6543ad841b2Smrg const _Functor*
6553ad841b2Smrg function<_Res(_ArgTypes...)>::
6563ad841b2Smrg target() const noexcept
6573ad841b2Smrg {
6583ad841b2Smrg if (typeid(_Functor) == target_type() && _M_manager)
6593ad841b2Smrg {
6603ad841b2Smrg _Any_data __ptr;
6613ad841b2Smrg _M_manager(__ptr, _M_functor, __get_functor_ptr);
6623ad841b2Smrg return __ptr._M_access<const _Functor*>();
6633ad841b2Smrg }
6643ad841b2Smrg else
6653ad841b2Smrg return nullptr;
6663ad841b2Smrg }
6673ad841b2Smrg #endif
6683ad841b2Smrg
6693ad841b2Smrg // [20.7.15.2.6] null pointer comparisons
6703ad841b2Smrg
6713ad841b2Smrg /**
6723ad841b2Smrg * @brief Compares a polymorphic function object wrapper against 0
6733ad841b2Smrg * (the NULL pointer).
6743ad841b2Smrg * @returns @c true if the wrapper has no target, @c false otherwise
6753ad841b2Smrg *
6763ad841b2Smrg * This function will not throw an %exception.
6773ad841b2Smrg */
6783ad841b2Smrg template<typename _Res, typename... _Args>
6793ad841b2Smrg inline bool
6803ad841b2Smrg operator==(const function<_Res(_Args...)>& __f, nullptr_t) noexcept
6813ad841b2Smrg { return !static_cast<bool>(__f); }
6823ad841b2Smrg
683*4c3eb207Smrg #if __cpp_impl_three_way_comparison < 201907L
6843ad841b2Smrg /// @overload
6853ad841b2Smrg template<typename _Res, typename... _Args>
6863ad841b2Smrg inline bool
6873ad841b2Smrg operator==(nullptr_t, const function<_Res(_Args...)>& __f) noexcept
6883ad841b2Smrg { return !static_cast<bool>(__f); }
6893ad841b2Smrg
6903ad841b2Smrg /**
6913ad841b2Smrg * @brief Compares a polymorphic function object wrapper against 0
6923ad841b2Smrg * (the NULL pointer).
6933ad841b2Smrg * @returns @c false if the wrapper has no target, @c true otherwise
6943ad841b2Smrg *
6953ad841b2Smrg * This function will not throw an %exception.
6963ad841b2Smrg */
6973ad841b2Smrg template<typename _Res, typename... _Args>
6983ad841b2Smrg inline bool
6993ad841b2Smrg operator!=(const function<_Res(_Args...)>& __f, nullptr_t) noexcept
7003ad841b2Smrg { return static_cast<bool>(__f); }
7013ad841b2Smrg
7023ad841b2Smrg /// @overload
7033ad841b2Smrg template<typename _Res, typename... _Args>
7043ad841b2Smrg inline bool
7053ad841b2Smrg operator!=(nullptr_t, const function<_Res(_Args...)>& __f) noexcept
7063ad841b2Smrg { return static_cast<bool>(__f); }
707*4c3eb207Smrg #endif
7083ad841b2Smrg
7093ad841b2Smrg // [20.7.15.2.7] specialized algorithms
7103ad841b2Smrg
7113ad841b2Smrg /**
7123ad841b2Smrg * @brief Swap the targets of two polymorphic function object wrappers.
7133ad841b2Smrg *
7143ad841b2Smrg * This function will not throw an %exception.
7153ad841b2Smrg */
7163ad841b2Smrg // _GLIBCXX_RESOLVE_LIB_DEFECTS
7173ad841b2Smrg // 2062. Effect contradictions w/o no-throw guarantee of std::function swaps
7183ad841b2Smrg template<typename _Res, typename... _Args>
7193ad841b2Smrg inline void
7203ad841b2Smrg swap(function<_Res(_Args...)>& __x, function<_Res(_Args...)>& __y) noexcept
7213ad841b2Smrg { __x.swap(__y); }
7223ad841b2Smrg
723627f7eb2Smrg #if __cplusplus >= 201703L
724627f7eb2Smrg namespace __detail::__variant
725627f7eb2Smrg {
726627f7eb2Smrg template<typename> struct _Never_valueless_alt; // see <variant>
727627f7eb2Smrg
728627f7eb2Smrg // Provide the strong exception-safety guarantee when emplacing a
729627f7eb2Smrg // function into a variant.
730627f7eb2Smrg template<typename _Signature>
731627f7eb2Smrg struct _Never_valueless_alt<std::function<_Signature>>
732627f7eb2Smrg : std::true_type
733627f7eb2Smrg { };
734627f7eb2Smrg } // namespace __detail::__variant
735627f7eb2Smrg #endif // C++17
736627f7eb2Smrg
7373ad841b2Smrg _GLIBCXX_END_NAMESPACE_VERSION
7383ad841b2Smrg } // namespace std
7393ad841b2Smrg
7403ad841b2Smrg #endif // C++11
7413ad841b2Smrg #endif // _GLIBCXX_STD_FUNCTION_H
742