xref: /netbsd-src/external/gpl3/gcc.old/dist/libstdc++-v3/include/bits/std_function.h (revision 4c3eb207d36f67d31994830c0a694161fc1ca39b)
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