1 // Implementation of INVOKE -*- C++ -*-
3 // Copyright (C) 2016-2018 Free Software Foundation, Inc.
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)
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.
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.
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/>.
25 /** @file include/bits/invoke.h
26 * This is an internal header file, included by other library headers.
27 * Do not attempt to use it directly. @headername{functional}
30 #ifndef _GLIBCXX_INVOKE_H
31 #define _GLIBCXX_INVOKE_H 1
33 #pragma GCC system_header
35 #if __cplusplus < 201103L
36 # include <bits/c++0x_warning.h>
39 #include <type_traits>
41 namespace std
_GLIBCXX_VISIBILITY(default)
43 _GLIBCXX_BEGIN_NAMESPACE_VERSION
46 * @addtogroup utilities
50 // Used by __invoke_impl instead of std::forward<_Tp> so that a
51 // reference_wrapper is converted to an lvalue-reference.
52 template<typename _Tp
, typename _Up
= typename __inv_unwrap
<_Tp
>::type
>
54 __invfwd(typename remove_reference
<_Tp
>::type
& __t
) noexcept
55 { return static_cast<_Up
&&>(__t
); }
57 template<typename _Res
, typename _Fn
, typename
... _Args
>
59 __invoke_impl(__invoke_other
, _Fn
&& __f
, _Args
&&... __args
)
60 { return std::forward
<_Fn
>(__f
)(std::forward
<_Args
>(__args
)...); }
62 template<typename _Res
, typename _MemFun
, typename _Tp
, typename
... _Args
>
64 __invoke_impl(__invoke_memfun_ref
, _MemFun
&& __f
, _Tp
&& __t
,
66 { return (__invfwd
<_Tp
>(__t
).*__f
)(std::forward
<_Args
>(__args
)...); }
68 template<typename _Res
, typename _MemFun
, typename _Tp
, typename
... _Args
>
70 __invoke_impl(__invoke_memfun_deref
, _MemFun
&& __f
, _Tp
&& __t
,
73 return ((*std::forward
<_Tp
>(__t
)).*__f
)(std::forward
<_Args
>(__args
)...);
76 template<typename _Res
, typename _MemPtr
, typename _Tp
>
78 __invoke_impl(__invoke_memobj_ref
, _MemPtr
&& __f
, _Tp
&& __t
)
79 { return __invfwd
<_Tp
>(__t
).*__f
; }
81 template<typename _Res
, typename _MemPtr
, typename _Tp
>
83 __invoke_impl(__invoke_memobj_deref
, _MemPtr
&& __f
, _Tp
&& __t
)
84 { return (*std::forward
<_Tp
>(__t
)).*__f
; }
86 /// Invoke a callable object.
87 template<typename _Callable
, typename
... _Args
>
88 constexpr typename __invoke_result
<_Callable
, _Args
...>::type
89 __invoke(_Callable
&& __fn
, _Args
&&... __args
)
90 noexcept(__is_nothrow_invocable
<_Callable
, _Args
...>::value
)
92 using __result
= __invoke_result
<_Callable
, _Args
...>;
93 using __type
= typename
__result::type
;
94 using __tag
= typename
__result::__invoke_type
;
95 return std::__invoke_impl
<__type
>(__tag
{}, std::forward
<_Callable
>(__fn
),
96 std::forward
<_Args
>(__args
)...);
99 _GLIBCXX_END_NAMESPACE_VERSION
104 #endif // _GLIBCXX_INVOKE_H