mirror of
https://github.com/gcc-mirror/gcc.git
synced 2026-05-06 23:25:24 +02:00
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>