diff options
author | Tomasz Kamiński <tkaminsk@redhat.com> | 2025-05-08 08:08:43 +0200 |
---|---|---|
committer | Tomasz Kamiński <tkaminsk@redhat.com> | 2025-05-14 13:34:01 +0200 |
commit | 708d40ff109c6e49d02b684a368571722a160af8 (patch) | |
tree | fe0449edb3c9fd4c55e0a2898901300868fb0dbf /gcc/fortran/dump-parse-tree.cc | |
parent | 9c9a7316adb99693e237164908893a78b86ba000 (diff) | |
download | gcc-708d40ff109c6e49d02b684a368571722a160af8.zip gcc-708d40ff109c6e49d02b684a368571722a160af8.tar.gz gcc-708d40ff109c6e49d02b684a368571722a160af8.tar.bz2 |
libstdc++: Avoid double indirection in move_only_function when possible [PR119125]
Based on the provision in C++26 [func.wrap.general] p2 this patch adjust the generic
move_only_function(_Fn&&) constructor, such that when _Fn refers to selected
move_only_function instantiations, the ownership of the target object is directly
transfered to constructor object. This avoid cost of double indirection in this situation.
We apply this also in C++23 mode.
We also fix handling of self assignments, to match behavior required by standard,
due use of copy and swap idiom.
An instantiations MF1 of move_only_function can transfer target of another
instantiation MF2, if it can be constructed via usual rules (__is_callable_from<_MF2>),
and their invoker are convertible (__is_invoker_convertible<MF2, MF1>()), i.e.:
* MF1 is less noexcept than MF2,
* return types are the same after stripping cv-quals,
* adujsted parameters type are the same (__poly::_param_t), i.e. param of types T and T&&
are compatible for non-trivially copyable objects.
Compatiblity of cv ref qualification is checked via __is_callable_from<_MF2>.
To achieve above the generation of _M_invoke functions is moved to _Invoker class
templates, that only depends on noexcept, return type and adjusted parameter of the
signature. To make the invoker signature compatible between const and mutable
qualified signatures, we always accept _Storage as const& and perform a const_cast
for locally stored object. This approach guarantees that we never strip const from
const object.
Another benefit of this approach is that move_only_function<void(std::string)>
and move_only_function<void(std::string&&)> use same funciton pointer, which should
reduce binary size.
The _Storage and _Manager functionality was also extracted and adjusted from
_Mofunc_base, in preparation for implementation for copyable_function and
function_ref. The _Storage was adjusted to store functions pointers as void(*)().
The manage function, now accepts _Op enum parameter, and supports additional
operations:
* _Op::_Address stores address of target object in destination
* _Op::_Copy, when enabled, copies from source to destination
Furthermore, we provide a type-independent mamange functions for handling all:
* function pointer types
* trivially copyable object stored locally.
Similary as in case of invoker, we always pass source as const (for copy),
and cast away constness in case of move operations, where we know that source
is mutable.
Finally, the new helpers are defined in __polyfunc internal namespace.
PR libstdc++/119125
libstdc++-v3/ChangeLog:
* include/bits/mofunc_impl.h: (std::move_only_function): Adjusted for
changes in bits/move_only_function.h
(move_only_function::move_only_function(_Fn&&)): Special case
move_only_functions with same invoker.
(move_only_function::operator=(move_only_function&&)): Handle self
assigment.
* include/bits/move_only_function.h (__polyfunc::_Ptrs)
(__polyfunc::_Storage): Refactored from _Mo_func::_Storage.
(__polyfunc::__param_t): Moved from move_only_function::__param_t.
(__polyfunc::_Base_invoker, __polyfunc::_Invoke): Refactored from
move_only_function::_S_invoke.
(__polyfunc::_Manager): Refactored from _Mo_func::_S_manager.
(std::_Mofunc_base): Moved into __polyfunc::_Mo_base with parts
extracted to __polyfunc::_Storage and __polyfunc::_Manager.
(__polyfunc::__deref_as, __polyfunc::__invoker_of)
(__polyfunc::__base_of, __polyfunc::__is_invoker_convertible): Define.
(std::__is_move_only_function_v): Renamed to
__is_polymorphic_function_v.
(std::__is_polymorphic_function_v): Renamed from
__is_move_only_function_v.
* testsuite/20_util/move_only_function/call.cc: Test for
functions pointers.
* testsuite/20_util/move_only_function/conv.cc: New test.
* testsuite/20_util/move_only_function/move.cc: Tests for
self assigment.
Reviewed-by: Jonathan Wakely <jwakely@redhat.com>
Signed-off-by: Tomasz Kamiński <tkaminsk@redhat.com>
Diffstat (limited to 'gcc/fortran/dump-parse-tree.cc')
0 files changed, 0 insertions, 0 deletions