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
45namespace std _GLIBCXX_VISIBILITY(default)
47_GLIBCXX_BEGIN_NAMESPACE_VERSION
50 template<
typename _Tp>
51 inline constexpr bool __is_polymorphic_function_v =
false;
61 template<
typename _Tp>
62 [[__gnu__::__always_inline__]]
64 __cast_to(_Ptrs __ptrs)
noexcept
66 using _Td = remove_reference_t<_Tp>;
67 if constexpr (is_function_v<_Td>)
68 return reinterpret_cast<_Td*
>(__ptrs._M_func);
69 else if constexpr (is_const_v<_Td>)
70 return static_cast<_Td*
>(__ptrs._M_obj);
72 return static_cast<_Td*
>(
const_cast<void*
>(__ptrs._M_obj));
77 void* _M_addr() noexcept {
return &_M_bytes[0]; }
78 void const* _M_addr() const noexcept {
return &_M_bytes[0]; }
80 template<
typename _Tp>
82 _S_stored_locally() noexcept
84 return sizeof(_Tp) <=
sizeof(_Storage)
85 &&
alignof(_Tp) <=
alignof(_Storage)
86 && is_nothrow_move_constructible_v<_Tp>;
89 template<
typename _Tp,
typename... _Args>
91 _S_nothrow_init() noexcept
93 if constexpr (_S_stored_locally<_Tp>())
94 return is_nothrow_constructible_v<_Tp, _Args...>;
98 template<
typename _Tp,
typename... _Args>
100 _M_init(_Args&&... __args)
noexcept(_S_nothrow_init<_Tp, _Args...>())
102 if constexpr (is_function_v<remove_pointer_t<_Tp>>)
104 static_assert(
sizeof...(__args) <= 1 );
106 _Tp __func = (
nullptr, ..., __args);
107 _M_ptrs._M_func =
reinterpret_cast<void(*)()
>(__func);
109 else if constexpr (!_S_stored_locally<_Tp>())
112 ::new (_M_addr()) _Tp(std::forward<_Args>(__args)...);
116 struct _Delegate { void (_Storage::*__pfm)(); _Storage* __obj; };
119 alignas(_Delegate)
alignas(
void(*)())
120 unsigned char _M_bytes[
sizeof(_Delegate)];
124 template<
bool _Noex,
typename _Ret,
typename... _Args>
127 using _Signature = _Ret(*)(_Args...)
noexcept(_Noex);
129 using __storage_func_t = _Ret(*)(
const _Storage&, _Args...)
noexcept(_Noex);
130 template<
typename _Tp>
131 static consteval __storage_func_t
133 {
return &_S_call_storage<_Adjust_target<_Tp>>; }
135 using __ptrs_func_t = _Ret(*)(_Ptrs, _Args...)
noexcept(_Noex);
136 template<
typename _Tp>
137 static consteval __ptrs_func_t
139 {
return &_S_call_ptrs<_Adjust_target<_Tp>>; }
141#ifdef __glibcxx_function_ref
144 _S_nttp(_Ptrs, _Args... __args)
noexcept(_Noex)
147 template<auto __fn,
typename _Tp>
149 _S_bind_ptr(_Ptrs __ptrs, _Args... __args)
noexcept(_Noex)
151 auto* __p = __polyfunc::__cast_to<_Tp>(__ptrs);
152 return std::__invoke_r<_Ret>(__fn, __p,
156 template<auto __fn,
typename _Ref>
158 _S_bind_ref(_Ptrs __ptrs, _Args... __args)
noexcept(_Noex)
160 auto* __p = __polyfunc::__cast_to<_Ref>(__ptrs);
161 return std::__invoke_r<_Ret>(__fn,
static_cast<_Ref
>(*__p),
167 template<
typename _Tp,
typename _Td = remove_cvref_t<_Tp>>
168 using _Adjust_target =
169 __conditional_t<is_pointer_v<_Td> || is_member_pointer_v<_Td>, _Td, _Tp>;
171 template<
typename _Tp>
173 _S_call_storage(
const _Storage& __ref, _Args... __args)
noexcept(_Noex)
176 if constexpr (is_function_v<remove_pointer_t<_Tp>>)
177 __ptrs._M_func = __ref._M_ptrs._M_func;
178 else if constexpr (!_Storage::_S_stored_locally<remove_cvref_t<_Tp>>())
179 __ptrs._M_obj = __ref._M_ptrs._M_obj;
181 __ptrs._M_obj = __ref._M_addr();
185 template<
typename _Tp>
187 _S_call_ptrs(_Ptrs __ptrs, _Args... __args)
noexcept(_Noex)
189 if constexpr (is_function_v<remove_pointer_t<_Tp>>)
190 return std::__invoke_r<_Ret>(
reinterpret_cast<_Tp
>(__ptrs._M_func),
194 auto* __p = __polyfunc::__cast_to<_Tp>(__ptrs);
195 return std::__invoke_r<_Ret>(
static_cast<_Tp
>(*__p),
201 template<
typename _Tp>
207 if constexpr (is_reference_v<_Tp> || is_scalar_v<_Tp>)
212 if constexpr (std::__is_complete_or_unbounded(__type_identity<_Tp>()))
213 if constexpr (
sizeof(_Tp) <= 2 *
sizeof(
void*))
214 return is_trivially_move_constructible_v<_Tp>
215 && is_trivially_destructible_v<_Tp>;
219 template<
typename _Tp>
220 using __param_t = __conditional_t<__pass_by_value<_Tp>(), _Tp, _Tp&&>;
222 template<
bool _Noex,
typename _Ret,
typename... _Args>
223 using _Invoker = _Base_invoker<_Noex, remove_cv_t<_Ret>, __param_t<_Args>...>;
225 template<
typename _Func>
227 __invoker_of(_Func& __f)
noexcept
228 {
return __f._M_invoke; }
230 template<
typename _Func>
232 __base_of(_Func& __f)
noexcept
233 {
return static_cast<__like_t<_Func&, typename _Func::_Base>
>(__f); }
235 template<
typename _Src,
typename _Dst>
237 __is_invoker_convertible() noexcept
239 if constexpr (
requires {
typename _Src::_Signature; })
240 return is_convertible_v<
typename _Src::_Signature,
241 typename _Dst::_Signature>;
246#if __glibcxx_move_only_function || __glibcxx_copyable_function
263 using _Func = void (*)(_Op __op, _Storage& __target,
const _Storage* __src);
266 static void _S_empty(_Op, _Storage&,
const _Storage*)
noexcept { }
268 template<
bool _Prov
ideCopy,
typename _Tp>
269 consteval static auto
272 if constexpr (is_function_v<remove_pointer_t<_Tp>>)
274 else if constexpr (!_Storage::_S_stored_locally<_Tp>())
275 return &_S_ptr<_ProvideCopy, _Tp>;
276 else if constexpr (is_trivially_copyable_v<_Tp>)
279 return &_S_local<_ProvideCopy, _Tp>;
284 _S_func(_Op __op, _Storage& __target,
const _Storage* __src)
noexcept
291 __target._M_ptrs._M_func = __src->_M_ptrs._M_func;
299 _S_trivial(_Op __op, _Storage& __target,
const _Storage* __src)
noexcept
304 __target._M_ptrs._M_obj = __src->_M_addr();
311 ::new (&__target) _Storage(*__src);
318 template<
bool _Prov
ide_copy,
typename _Tp>
320 _S_local(_Op __op, _Storage& __target,
const _Storage* __src)
321 noexcept(!_Provide_copy)
326 __target._M_ptrs._M_obj = __src->_M_addr();
330 _Tp* __obj =
static_cast<_Tp*
>(
const_cast<void*
>(__src->_M_addr()));
331 ::new(__target._M_addr()) _Tp(std::move(*__obj));
336 static_cast<_Tp*>(__target._M_addr())->~_Tp();
339 if constexpr (_Provide_copy)
341 auto* __obj =
static_cast<const _Tp*
>(__src->_M_addr());
342 ::new (__target._M_addr()) _Tp(*__obj);
345 __builtin_unreachable();
349 template<
bool _Provide_copy, typename _Tp>
351 _S_ptr(_Op __op, _Storage& __target, const _Storage* __src)
352 noexcept(!_Provide_copy)
358 __target._M_ptrs._M_obj = __src->_M_ptrs._M_obj;
361 delete static_cast<const _Tp*
>(__target._M_ptrs._M_obj);
364 if constexpr (_Provide_copy)
366 auto* __obj =
static_cast<const _Tp*
>(__src->_M_ptrs._M_obj);
367 __target._M_ptrs._M_obj =
new _Tp(*__obj);
370 __builtin_unreachable();
379 : _M_manage(_Manager::_S_empty)
382 _Mo_base(_Mo_base&& __x)
noexcept
385 template<
typename _Tp,
typename... _Args>
386 static consteval bool
387 _S_nothrow_init() noexcept
388 {
return _Storage::_S_nothrow_init<_Tp, _Args...>(); }
390 template<
typename _Tp,
typename... _Args>
392 _M_init(_Args&&... __args)
393 noexcept(_S_nothrow_init<_Tp, _Args...>())
396 _M_manage = _Manager::_S_select<false, _Tp>();
400 _M_move(_Mo_base& __x)
noexcept
402 using _Op = _Manager::_Op;
403 _M_manage = std::__exchange(__x._M_manage, _Manager::_S_empty);
404 _M_manage(_Op::_Move, _M_storage, &__x._M_storage);
408 operator=(_Mo_base&& __x)
noexcept
419 _M_manage = _Manager::_S_empty;
422 void _M_destroy() noexcept
423 { _M_manage(_Manager::_Op::_Destroy, _M_storage,
nullptr); }
429 swap(_Mo_base& __x)
noexcept
431 using _Op = _Manager::_Op;
434 __x._M_manage(_Op::_Move, __s, &__x._M_storage);
435 _M_manage(_Op::_Move, __x._M_storage, &_M_storage);
436 __x._M_manage(_Op::_Move, _M_storage, &__s);
437 std::swap(_M_manage, __x._M_manage);
440 _Manager::_Func _M_manage;
447#ifdef __glibcxx_move_only_function
448 template<
typename... _Signature>
449 class move_only_function;
452 template<
typename _Tp>
453 constexpr bool __is_polymorphic_function_v<move_only_function<_Tp>> =
true;
455 namespace __detail::__variant
457 template<
typename>
struct _Never_valueless_alt;
461 template<
typename... _Signature>
462 struct _Never_valueless_alt<std::move_only_function<_Signature...>>
469#ifdef __glibcxx_copyable_function
473 class _Cpy_base :
public _Mo_base
476 _Cpy_base() =
default;
478 template<
typename _Tp,
typename... _Args>
480 _M_init(_Args&&... __args)
481 noexcept(_S_nothrow_init<_Tp, _Args...>())
484 _M_manage = _Manager::_S_select<true, _Tp>();
488 _M_copy(_Cpy_base
const& __x)
490 using _Op = _Manager::_Op;
491 __x._M_manage(_Op::_Copy, _M_storage, &__x._M_storage);
492 _M_manage = __x._M_manage;
495 _Cpy_base(_Cpy_base&&) =
default;
497 _Cpy_base(_Cpy_base
const& __x)
501 operator=(_Cpy_base&&) =
default;
505 operator=(_Cpy_base
const&) =
delete;
510 template<
typename... _Signature>
511 class copyable_function;
513 template<
typename _Tp>
514 constexpr bool __is_polymorphic_function_v<copyable_function<_Tp>> =
true;
516 namespace __detail::__variant
518 template<
typename>
struct _Never_valueless_alt;
522 template<
typename... _Signature>
523 struct _Never_valueless_alt<std::copyable_function<_Signature...>>
529#ifdef __glibcxx_function_ref
533 template<
typename _Sig>
534 struct __skip_first_arg;
537 template<
bool _Noex,
typename _Ret,
typename _Arg,
typename... _Args>
538 struct __skip_first_arg<_Ret(*)(_Arg, _Args...) noexcept(_Noex)>
539 {
using type = _Ret(_Args...) noexcept(_Noex); };
541 template<typename _Fn, typename _Tr>
545 if constexpr (is_member_object_pointer_v<_Fn>)
547 return static_cast<invoke_result_t<_Fn, _Tr>(*)()
>(
nullptr);
549 return static_cast<__skip_first_arg<_Fn>::type*
>(
nullptr);
554 template<
typename... _Signature>
557 template<
typename _Fn>
558 requires is_function_v<_Fn>
559 function_ref(_Fn*) -> function_ref<_Fn>;
561 template<auto __f,
class _Fn = remove_po
inter_t<decltype(__f)>>
562 requires is_function_v<_Fn>
563 function_ref(nontype_t<__f>) -> function_ref<_Fn>;
565 template<auto __f,
typename _Tp,
class _Fn = decltype(__f)>
566 requires is_member_pointer_v<_Fn> || is_function_v<remove_pointer_t<_Fn>>
567 function_ref(nontype_t<__f>, _Tp&&)
569 remove_pointer_t<decltype(__polyfunc::__deduce_funcref<_Fn, _Tp&>())>>;
573_GLIBCXX_END_NAMESPACE_VERSION
576#ifdef __glibcxx_move_only_function
578#define _GLIBCXX_MOF_CV const
580#define _GLIBCXX_MOF_REF &
582#define _GLIBCXX_MOF_REF &&
584#define _GLIBCXX_MOF_CV const
585#define _GLIBCXX_MOF_REF &
587#define _GLIBCXX_MOF_CV const
588#define _GLIBCXX_MOF_REF &&
592#ifdef __glibcxx_copyable_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_function_ref
610#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)