Files
Tomasz Kamiński c56ec55c79 libstdc++: Avoid double indirection in function_ref when possible
This implements the P3961R1: Less double indirection in function_ref.

This patch uses provision provided by the paper for implementations, and
expands the set of the compatible signatures to include ParamType&& and
ParamType, and by value return types that differs only in cv-qualifiers.
This follows the move_only_function approach from the r16-617-g708d40ff109c6e.
Futhermore the optimization is also applied when function_ref<Ret(Args...) const>
is constructed from function_ref<Ret(Args...)>, even if the underyling target
is be mutated by the call.

The implementations moves the _M_ptrs members to newly defined base class
__polyfunc::_Ref_base. This allows us to reuse existing __base_of and
__invoker_of accessor in the implementation (after befriending them).
The accessors functions are also now marked as constexpr. Furthermore,
_Ref_base default constructor initializes the _M_ptrs._M_obj to nullptr,
and _M_init function is transfered to it, making it instantiations
independent from callback signature.

To check signature compatiblity required by standard for assignment, new
__is_funcref_assignable function is used, and _ArgsSignature and _TargetQuals
member typedef are defined in function_ref. To avoid confusion between adjusted
and specified signature, _Signature typedef is removed from all wrappers, and
__is_invoker_convertible is updated to use _Invoker::_Signature instead.

Per SG-10 guidance __cpp_lib_function_ref feature test macro is updated to
202604, differntiating from P3948R1 paper accepted at the same time.

	PR libstdc++/119126

libstdc++-v3/ChangeLog:

	* include/bits/funcwrap.h : (__polyfunc::__invoker_of):
	Updated to use _Invoker::_Signature and mark as constexpr.
	(__polyfunc::_base_of): Mark as constexpr.
	(__std:::__is_function_ref_v, __polyfunc::_Ref_base)
	(__polyfunc::__is_funcref_assignable): Define.
	* include/bits/funcref_impl.h (std::function_ref): Add base class
	of type__polyfunc::_Ref_base. Befriend __invoker_of, __base_of,
	__is_invoker_convertible, __is_invoker_convertible.
	(function_ref::_Base): Define.
	(function_ref::_M_init, function_ref::_M_ptrs): Move to base class.
	(function_ref::function_ref(_Fn&&), function_ref::operator=): Handle
	specializations of function_ref with compatible signatures.
	(function_ref::function_ref): Init base class before _M_invoke
	consistently, and remove setting of _M_nullptr.
	* include/bits/cpyfunc_impl.h (copyable_function): Udpdated friend
	declarations.
	(copyable_function::_Signature): Remove.
	* include/bits/mofunc_impl.h (move_only_function): Udpdated friend
	declarations.
	(move_only_function::_Signature): Remove.
	* include/bits/version.def (function_ref): Bump to 202604.
	* include/bits/version.h: Regnerate.
	* testsuite/20_util/function_ref/cons.cc: Updated checked FTM value.
	* testsuite/20_util/function_ref/conv.cc: Updated test to illustrate
	that double indirection is avoided.
	* testsuite/20_util/function_ref/dangling.cc: Test for initializing
	from function_ref with compatible signature.
	* testsuite/20_util/function_ref/dangling_neg.cc: Test for
	initializing from function_ref with incompatible signature.

Reviewed-by: Jonathan Wakely <jwakely@redhat.com>
Signed-off-by: Tomasz Kamiński <tkaminsk@redhat.com>
2026-05-06 13:22:01 +02:00
..
2026-01-02 09:56:11 +01:00
2026-01-02 09:56:11 +01:00
2026-01-02 09:56:11 +01:00
2026-01-02 09:56:11 +01:00
2026-01-02 09:56:11 +01:00
2026-01-02 09:56:11 +01:00
2026-01-02 09:56:11 +01:00
2026-01-02 09:56:11 +01:00
2026-01-02 09:56:11 +01:00
2026-01-02 09:56:11 +01:00