]> git.ipfire.org Git - thirdparty/gcc.git/commit
libstdc++: port the ranges::uninitialized_* algorithms away from is_trivial
authorGiuseppe D'Angelo <giuseppe.dangelo@kdab.com>
Mon, 9 Dec 2024 01:22:23 +0000 (02:22 +0100)
committerJonathan Wakely <redi@gcc.gnu.org>
Tue, 10 Dec 2024 00:50:25 +0000 (00:50 +0000)
commit95c7a61a8b5003793d156c2833e350dd1e96712c
tree20598ecd2c91e5cadcd80c0f1b3ced0674cb1d7e
parente4a0157c2397c9b582cff71d114240a6b083a3dc
libstdc++: port the ranges::uninitialized_* algorithms away from is_trivial

In preparation for the deprecation of is_trivial (P3247R2).
The rangified uninitialized_* specialized memory algorithms have code
paths where they call the non-uninitialized versions, because the latter
are usually optimized. The detection in these code paths uses is_trivial;
port it away from it towards more specific checks.

The detection for the copy/move algorithms was suspicious: it checked
that the output type was trivial, and that assignment from the input
range reference type was nothrow. If so, the algorithm would copy/move
assign (by calling the ranges::copy/move algorithms) instead of
constructing elements. I think this is off because:

1) the constructor that would be called by the algorithm (which may be
   neither a copy or a move constructor) wasn't checked. If that
   constructor isn't trivial the caller might detect that we're not
   calling it, and that goes against the algorithms' specifications.
2) a nothrow assignment is necessary but not sufficient, as again we
   need to check for triviality, or the caller can detect we're calling
   an assignment operator we were never meant to be calling from these
   algorithms.

Therefore I've amended the respective detections.

libstdc++-v3/ChangeLog:

* include/bits/ranges_uninitialized.h: port some if
constexpr away from is_trivial, and towards more specific
detections instead.

Signed-off-by: Giuseppe D'Angelo <giuseppe.dangelo@kdab.com>
libstdc++-v3/include/bits/ranges_uninitialized.h