30 #ifndef _GLIBCXX_MOF_CV
31 # define _GLIBCXX_MOF_CV
34 namespace std _GLIBCXX_VISIBILITY(default)
36 _GLIBCXX_BEGIN_NAMESPACE_VERSION
41 template<
bool _Noex,
typename _Ret,
typename _Class,
typename... _Args>
42 struct __skip_first_arg<_Ret(_Class::*)(_Args...) _GLIBCXX_MOF_CV
44 {
using type = _Ret(_Args...) noexcept(_Noex); };
46 template<
bool _Noex, typename _Ret, typename _Class, typename... _Args>
47 struct __skip_first_arg<_Ret(_Class::*)(_Args...) _GLIBCXX_MOF_CV&
49 {
using type = _Ret(_Args...) noexcept(_Noex); };
67 template<typename _Res, typename... _ArgTypes,
bool _Noex>
68 class function_ref<_Res(_ArgTypes...) _GLIBCXX_MOF_CV
72 (std::__is_complete_or_unbounded(__type_identity<_ArgTypes>()) && ...),
73 "each parameter type must be a complete class");
75 using _Invoker = __polyfunc::_Invoker<_Noex, _Res, _ArgTypes...>;
76 using _Signature = _Invoker::_Signature;
79 template<
typename... _Tps>
80 static constexpr
bool __is_invocable_using
81 = __conditional_t<_Noex,
82 is_nothrow_invocable_r<_Res, _Tps..., _ArgTypes...>,
83 is_invocable_r<_Res, _Tps..., _ArgTypes...>>::value;
87 template<
typename _Fn>
88 requires is_function_v<_Fn> && __is_invocable_using<_Fn*>
91 __glibcxx_assert(__fn !=
nullptr);
92 _M_invoke = _Invoker::template _S_ptrs<_Fn*>();
97 template<
typename _Fn,
typename _Vt = remove_reference_t<_Fn>>
98 requires (!is_same_v<remove_cv_t<_Vt>, function_ref>)
99 && (!is_member_pointer_v<_Vt>)
104 && (!is_function_v<_Vt>)
105 && __is_invocable_using<_Vt _GLIBCXX_MOF_CV&>
107 function_ref(_Fn&& __f) noexcept
109 using _Fd = remove_cv_t<_Vt>;
110 if constexpr (__is_std_op_wrapper<_Fd>)
112 _M_invoke = _Invoker::template _S_nttp<_Fd{}>;
113 _M_ptrs._M_obj =
nullptr;
115 else if constexpr (requires (_ArgTypes&&... __args) {
116 _Fd::operator()(std::forward<_ArgTypes>(__args)...);
119 _M_invoke = _Invoker::template _S_static<_Fd>;
120 _M_ptrs._M_obj =
nullptr;
124 _M_invoke = _Invoker::template _S_ptrs<_Vt _GLIBCXX_MOF_CV&>();
133 requires __is_invocable_using<
const decltype(__fn)&>
135 function_ref(nontype_t<__fn>) noexcept
137 using _Fn = remove_cv_t<decltype(__fn)>;
138 if constexpr (is_pointer_v<_Fn> || is_member_pointer_v<_Fn>)
139 static_assert(__fn !=
nullptr);
141 _M_invoke = &_Invoker::template _S_nttp<__fn>;
142 _M_ptrs._M_obj =
nullptr;
147 template<auto __fn,
typename _Up,
typename _Td = remove_reference_t<_Up>>
148 requires (!is_rvalue_reference_v<_Up&&>)
149 && __is_invocable_using<
const decltype(__fn)&, _Td _GLIBCXX_MOF_CV&>
151 function_ref(nontype_t<__fn>, _Up&& __ref) noexcept
153 using _Fn = remove_cv_t<decltype(__fn)>;
154 if constexpr (is_pointer_v<_Fn> || is_member_pointer_v<_Fn>)
155 static_assert(__fn !=
nullptr);
157 if constexpr (is_member_pointer_v<_Fn>
158 &&
same_as<_Td,
typename __inv_unwrap<_Td>::type>)
161 _M_invoke = &_Invoker::template _S_bind_ptr<__fn, _Td _GLIBCXX_MOF_CV>;
163 _M_invoke = &_Invoker::template _S_bind_ref<__fn, _Td _GLIBCXX_MOF_CV&>;
169 template<auto __fn, typename _Td>
170 requires __is_invocable_using<const decltype(__fn)&, _Td _GLIBCXX_MOF_CV*>
172 function_ref(nontype_t<__fn>, _Td _GLIBCXX_MOF_CV* __ptr) noexcept
174 using _Fn = remove_cv_t<decltype(__fn)>;
175 if constexpr (is_pointer_v<_Fn> || is_member_pointer_v<_Fn>)
176 static_assert(__fn !=
nullptr);
177 if constexpr (is_member_pointer_v<_Fn>)
178 __glibcxx_assert(__ptr !=
nullptr);
180 _M_invoke = &_Invoker::template _S_bind_ptr<__fn, _Td _GLIBCXX_MOF_CV>;
184 template<
typename _Tp>
185 requires (!is_same_v<_Tp, function_ref>)
186 && (!is_pointer_v<_Tp>) && (!__is_nontype_v<_Tp>)
188 operator=(_Tp) =
delete;
197 operator()(_ArgTypes... __args)
const noexcept(_Noex)
198 {
return _M_invoke(_M_ptrs, std::forward<_ArgTypes>(__args)...); }
201 template<
typename _Tp>
203 _M_init(_Tp* __ptr) noexcept
205 if constexpr (is_function_v<_Tp>)
206 _M_ptrs._M_func =
reinterpret_cast<void(*)()
>(__ptr);
208 _M_ptrs._M_obj = __ptr;
211 typename _Invoker::__ptrs_func_t _M_invoke;
212 __polyfunc::_Ptrs _M_ptrs;
215 #undef _GLIBCXX_MOF_CV
217 _GLIBCXX_END_NAMESPACE_VERSION