31#ifndef _GLIBCXX_FUNCWRAP_H
32#define _GLIBCXX_FUNCWRAP_H 1
35#pragma GCC system_header
40#if __glibcxx_move_only_function || __glibcxx_copyable_function || __glibcxx_function_ref
44#if __glibcxx_function_ref
48namespace std _GLIBCXX_VISIBILITY(default)
50_GLIBCXX_BEGIN_NAMESPACE_VERSION
53 template<
typename _Tp>
54 inline constexpr bool __is_polymorphic_function_v =
false;
64 template<
typename _Tp>
65 [[__gnu__::__always_inline__]]
67 __cast_to(_Ptrs __ptrs)
noexcept
69 using _Td = remove_reference_t<_Tp>;
70 if constexpr (is_function_v<_Td>)
71 return reinterpret_cast<_Td*
>(__ptrs._M_func);
72 else if constexpr (is_const_v<_Td>)
73 return static_cast<_Td*
>(__ptrs._M_obj);
75 return static_cast<_Td*
>(
const_cast<void*
>(__ptrs._M_obj));
80 void* _M_addr() noexcept {
return &_M_bytes[0]; }
81 void const* _M_addr() const noexcept {
return &_M_bytes[0]; }
83 template<
typename _Tp>
85 _S_stored_locally() noexcept
87 return sizeof(_Tp) <=
sizeof(_Storage)
88 &&
alignof(_Tp) <=
alignof(_Storage)
89 && is_nothrow_move_constructible_v<_Tp>;
92 template<
typename _Tp,
typename... _Args>
94 _S_nothrow_init() noexcept
96 if constexpr (_S_stored_locally<_Tp>())
97 return is_nothrow_constructible_v<_Tp, _Args...>;
101 template<
typename _Tp,
typename... _Args>
103 _M_init(_Args&&... __args)
noexcept(_S_nothrow_init<_Tp, _Args...>())
105 if constexpr (is_function_v<remove_pointer_t<_Tp>>)
107 static_assert(
sizeof...(__args) <= 1 );
109 _Tp __func = (
nullptr, ..., __args);
110 _M_ptrs._M_func =
reinterpret_cast<void(*)()
>(__func);
112 else if constexpr (!_S_stored_locally<_Tp>())
115 ::new (_M_addr()) _Tp(std::forward<_Args>(__args)...);
119 struct _Delegate { void (_Storage::*__pfm)(); _Storage* __obj; };
122 alignas(_Delegate)
alignas(
void(*)())
123 unsigned char _M_bytes[
sizeof(_Delegate)];
127 template<
bool _Noex,
typename _Ret,
typename... _Args>
130 using _Signature = _Ret(*)(_Args...)
noexcept(_Noex);
132 using __storage_func_t = _Ret(*)(
const _Storage&, _Args...)
noexcept(_Noex);
133 template<
typename _Tp>
134 static consteval __storage_func_t
136 {
return &_S_call_storage<_Adjust_target<_Tp>>; }
138 using __ptrs_func_t = _Ret(*)(_Ptrs, _Args...)
noexcept(_Noex);
139 template<
typename _Tp>
140 static consteval __ptrs_func_t
142 {
return &_S_call_ptrs<_Adjust_target<_Tp>>; }
144#ifdef __glibcxx_function_ref
145 template<
typename _Fn>
147 _S_static(_Ptrs, _Args... __args)
noexcept(_Noex)
152 _S_nttp(_Ptrs, _Args... __args)
noexcept(_Noex)
155 template<auto __fn,
typename _Tp>
157 _S_bind_ptr(_Ptrs __ptrs, _Args... __args)
noexcept(_Noex)
159 auto* __p = __polyfunc::__cast_to<_Tp>(__ptrs);
160 return std::__invoke_r<_Ret>(__fn, __p,
164 template<auto __fn,
typename _Ref>
166 _S_bind_ref(_Ptrs __ptrs, _Args... __args)
noexcept(_Noex)
168 auto* __p = __polyfunc::__cast_to<_Ref>(__ptrs);
169 return std::__invoke_r<_Ret>(__fn,
static_cast<_Ref
>(*__p),
175 template<
typename _Tp,
typename _Td = remove_cvref_t<_Tp>>
176 using _Adjust_target =
177 __conditional_t<is_pointer_v<_Td> || is_member_pointer_v<_Td>, _Td, _Tp>;
179 template<
typename _Tp>
181 _S_call_storage(
const _Storage& __ref, _Args... __args)
noexcept(_Noex)
184 if constexpr (is_function_v<remove_pointer_t<_Tp>>)
185 __ptrs._M_func = __ref._M_ptrs._M_func;
186 else if constexpr (!_Storage::_S_stored_locally<remove_cvref_t<_Tp>>())
187 __ptrs._M_obj = __ref._M_ptrs._M_obj;
189 __ptrs._M_obj = __ref._M_addr();
193 template<
typename _Tp>
195 _S_call_ptrs(_Ptrs __ptrs, _Args... __args)
noexcept(_Noex)
197 if constexpr (is_function_v<remove_pointer_t<_Tp>>)
198 return std::__invoke_r<_Ret>(
reinterpret_cast<_Tp
>(__ptrs._M_func),
202 auto* __p = __polyfunc::__cast_to<_Tp>(__ptrs);
203 return std::__invoke_r<_Ret>(
static_cast<_Tp
>(*__p),
209 template<
typename _Tp>
215 if constexpr (is_reference_v<_Tp> || is_scalar_v<_Tp>)
220 if constexpr (std::__is_complete_or_unbounded(__type_identity<_Tp>()))
221 if constexpr (
sizeof(_Tp) <= 2 *
sizeof(
void*))
222 return is_trivially_move_constructible_v<_Tp>
223 && is_trivially_destructible_v<_Tp>;
227 template<
typename _Tp>
228 using __param_t = __conditional_t<__pass_by_value<_Tp>(), _Tp, _Tp&&>;
230 template<
bool _Noex,
typename _Ret,
typename... _Args>
231 using _Invoker = _Base_invoker<_Noex, remove_cv_t<_Ret>, __param_t<_Args>...>;
233 template<
typename _Func>
235 __invoker_of(_Func& __f)
noexcept
236 {
return __f._M_invoke; }
238 template<
typename _Func>
240 __base_of(_Func& __f)
noexcept
241 {
return static_cast<__like_t<_Func&, typename _Func::_Base>
>(__f); }
243 template<
typename _Src,
typename _Dst>
245 __is_invoker_convertible() noexcept
247 if constexpr (
requires {
typename _Src::_Signature; })
248 return is_convertible_v<
typename _Src::_Signature,
249 typename _Dst::_Signature>;
254#if __glibcxx_move_only_function || __glibcxx_copyable_function
271 using _Func = void (*)(_Op __op, _Storage& __target,
const _Storage* __src);
274 static void _S_empty(_Op, _Storage&,
const _Storage*)
noexcept { }
276 template<
bool _Prov
ideCopy,
typename _Tp>
277 consteval static auto
280 if constexpr (is_function_v<remove_pointer_t<_Tp>>)
282 else if constexpr (!_Storage::_S_stored_locally<_Tp>())
283 return &_S_ptr<_ProvideCopy, _Tp>;
284 else if constexpr (is_trivially_copyable_v<_Tp>)
287 return &_S_local<_ProvideCopy, _Tp>;
292 _S_func(_Op __op, _Storage& __target,
const _Storage* __src)
noexcept
299 __target._M_ptrs._M_func = __src->_M_ptrs._M_func;
307 _S_trivial(_Op __op, _Storage& __target,
const _Storage* __src)
noexcept
312 __target._M_ptrs._M_obj = __src->_M_addr();
319 ::new (&__target) _Storage(*__src);
326 template<
bool _Prov
ide_copy,
typename _Tp>
328 _S_local(_Op __op, _Storage& __target,
const _Storage* __src)
329 noexcept(!_Provide_copy)
334 __target._M_ptrs._M_obj = __src->_M_addr();
338 _Tp* __obj =
static_cast<_Tp*
>(
const_cast<void*
>(__src->_M_addr()));
339 ::new(__target._M_addr()) _Tp(std::move(*__obj));
344 static_cast<_Tp*>(__target._M_addr())->~_Tp();
347 if constexpr (_Provide_copy)
349 auto* __obj =
static_cast<const _Tp*
>(__src->_M_addr());
350 ::new (__target._M_addr()) _Tp(*__obj);
353 __builtin_unreachable();
357 template<
bool _Provide_copy, typename _Tp>
359 _S_ptr(_Op __op, _Storage& __target, const _Storage* __src)
360 noexcept(!_Provide_copy)
366 __target._M_ptrs._M_obj = __src->_M_ptrs._M_obj;
369 delete static_cast<const _Tp*
>(__target._M_ptrs._M_obj);
372 if constexpr (_Provide_copy)
374 auto* __obj =
static_cast<const _Tp*
>(__src->_M_ptrs._M_obj);
375 __target._M_ptrs._M_obj =
new _Tp(*__obj);
378 __builtin_unreachable();
387 : _M_manage(_Manager::_S_empty)
390 _Mo_base(_Mo_base&& __x)
noexcept
393 template<
typename _Tp,
typename... _Args>
394 static consteval bool
395 _S_nothrow_init() noexcept
396 {
return _Storage::_S_nothrow_init<_Tp, _Args...>(); }
398 template<
typename _Tp,
typename... _Args>
400 _M_init(_Args&&... __args)
401 noexcept(_S_nothrow_init<_Tp, _Args...>())
404 _M_manage = _Manager::_S_select<false, _Tp>();
408 _M_move(_Mo_base& __x)
noexcept
410 using _Op = _Manager::_Op;
411 _M_manage = std::__exchange(__x._M_manage, _Manager::_S_empty);
412 _M_manage(_Op::_Move, _M_storage, &__x._M_storage);
416 operator=(_Mo_base&& __x)
noexcept
427 _M_manage = _Manager::_S_empty;
430 void _M_destroy() noexcept
431 { _M_manage(_Manager::_Op::_Destroy, _M_storage,
nullptr); }
437 swap(_Mo_base& __x)
noexcept
439 using _Op = _Manager::_Op;
442 __x._M_manage(_Op::_Move, __s, &__x._M_storage);
443 _M_manage(_Op::_Move, __x._M_storage, &_M_storage);
444 __x._M_manage(_Op::_Move, _M_storage, &__s);
445 std::swap(_M_manage, __x._M_manage);
448 _Manager::_Func _M_manage;
455#ifdef __glibcxx_move_only_function
456 template<
typename... _Signature>
457 class move_only_function;
460 template<
typename _Tp>
461 constexpr bool __is_polymorphic_function_v<move_only_function<_Tp>> =
true;
463 namespace __detail::__variant
465 template<
typename>
struct _Never_valueless_alt;
469 template<
typename... _Signature>
470 struct _Never_valueless_alt<std::move_only_function<_Signature...>>
477#ifdef __glibcxx_copyable_function
481 class _Cpy_base :
public _Mo_base
484 _Cpy_base() =
default;
486 template<
typename _Tp,
typename... _Args>
488 _M_init(_Args&&... __args)
489 noexcept(_S_nothrow_init<_Tp, _Args...>())
492 _M_manage = _Manager::_S_select<true, _Tp>();
496 _M_copy(_Cpy_base
const& __x)
498 using _Op = _Manager::_Op;
499 __x._M_manage(_Op::_Copy, _M_storage, &__x._M_storage);
500 _M_manage = __x._M_manage;
503 _Cpy_base(_Cpy_base&&) =
default;
505 _Cpy_base(_Cpy_base
const& __x)
510 operator=(_Cpy_base&&) =
default;
514 operator=(_Cpy_base
const&) =
delete;
519 template<
typename... _Signature>
520 class copyable_function;
522 template<
typename _Tp>
523 constexpr bool __is_polymorphic_function_v<copyable_function<_Tp>> =
true;
525 namespace __detail::__variant
527 template<
typename>
struct _Never_valueless_alt;
531 template<
typename... _Signature>
532 struct _Never_valueless_alt<std::copyable_function<_Signature...>>
538#ifdef __glibcxx_function_ref
542 template<
typename _Sig>
543 struct __skip_first_arg;
546 template<
bool _Noex,
typename _Ret,
typename _Arg,
typename... _Args>
547 struct __skip_first_arg<_Ret(*)(_Arg, _Args...) noexcept(_Noex)>
548 {
using type = _Ret(_Args...) noexcept(_Noex); };
551 template<typename _Fn, typename _Tr>
555 if constexpr (is_member_object_pointer_v<_Fn>)
557 if constexpr (is_invocable_v<_Fn, _Tr>)
561 return static_cast<invoke_result_t<_Fn, _Tr>(*)() noexcept
>(
nullptr);
563 else if constexpr (
requires {
typename __skip_first_arg<_Fn>::type; })
564 return static_cast<__skip_first_arg<_Fn>::type*
>(
nullptr);
569 template<
typename... _Signature>
572 template<
typename _Fn>
573 requires is_function_v<_Fn>
574 function_ref(_Fn*) -> function_ref<_Fn>;
576 template<auto __f,
class _Fn = remove_po
inter_t<decltype(__f)>>
577 requires is_function_v<_Fn>
578 function_ref(nontype_t<__f>) -> function_ref<_Fn>;
580 template<
auto __f,
typename _Tp,
581 typename _SignaturePtr =
582 decltype(__polyfunc::__deduce_funcref<decltype(__f), _Tp&>())>
583 requires (!is_void_v<_SignaturePtr>)
584 function_ref(nontype_t<__f>, _Tp&&)
585 -> function_ref<remove_pointer_t<_SignaturePtr>>;
589_GLIBCXX_END_NAMESPACE_VERSION
592#ifdef __glibcxx_move_only_function
594#define _GLIBCXX_MOF_CV const
596#define _GLIBCXX_MOF_REF &
598#define _GLIBCXX_MOF_REF &&
600#define _GLIBCXX_MOF_CV const
601#define _GLIBCXX_MOF_REF &
603#define _GLIBCXX_MOF_CV const
604#define _GLIBCXX_MOF_REF &&
608#ifdef __glibcxx_copyable_function
610#define _GLIBCXX_MOF_CV const
612#define _GLIBCXX_MOF_REF &
614#define _GLIBCXX_MOF_REF &&
616#define _GLIBCXX_MOF_CV const
617#define _GLIBCXX_MOF_REF &
619#define _GLIBCXX_MOF_CV const
620#define _GLIBCXX_MOF_REF &&
624#ifdef __glibcxx_function_ref
626#define _GLIBCXX_MOF_CV const
__bool_constant< true > true_type
The type used as a compile-time boolean with true value.
constexpr _Tp && forward(typename std::remove_reference< _Tp >::type &__t) noexcept
Forward an lvalue.
ISO C++ entities toplevel namespace is std.
constexpr void _Destroy(_ForwardIterator __first, _ForwardIterator __last)