[PATCH] libstdc++: implement constexpr memory algorithms
Giuseppe D'Angelo
giuseppe.dangelo@kdab.com
Tue Feb 25 17:23:47 GMT 2025
Hello,
Thanks for the review!
On 20/02/2025 17:22, Patrick Palka wrote:
> On Sun, 16 Feb 2025, Giuseppe D'Angelo wrote:
>
>> Hello,
>>
>> the attached patch implements the C++26 papers that add `constexpr` to the
>> specialized memory algorithms (the uninitialized_* family). Tested on x86-64
>> Linux.
>>
>> Thank you,
>> --
>> Giuseppe D'Angelo
>>
>
>> Subject: [PATCH] libstdc++: implement constexpr memory algorithms
>>
>> This commit adds support for C++26's constexpr specialized memory
>> algorithms, introduced by P2283R2, P3508R0, P3369R0.
>>
>> The uninitialized_default, value, copy, move and fill algorithms are
>> affected, in all of their variants (iterator-based, range-based and _n
>> versions.)
>>
>> The changes are mostly mechanical -- add `constexpr` to a number of
>> signatures. I've introduced a helper macro to conditionally expand to
>> `constexpr` only in C++26 and above modes. The internal helper guard
>> class for range algorithms instead can be marked unconditionally.
>>
>> uninitialized_fill is the only algorithm where I had to add a branch to
>> a constexpr-friendly version (already existing).
>
> Seems the patch also adds code to uninitialized_copy and
> uninitialized_fill_n?
Whops, sorry, didn't spot them when I reviewed the diff. You're right.
>> template<typename _T1>
>> +#if __cpp_constexpr >= 202406L // >= C++26
>> + _GLIBCXX26_CONSTEXPR
>> +#endif
>
> Maybe we can get away with unconditionally declaring this
> _GLIBCXX26_CONSTEXPR? If the compiler doesn't support constexpr
> placement new then the 'constexpr' would be silently dropped at
> instantiation time. This would be in line with C++23 P2448R2 which
> made it no longer IFNDR to declare a constexpr function template
> for which no specialization is actually constexpr.
It's fundamentally a judgement / compatibility call.
The patch adding the _GLIBCXX26_CONSTEXPR macro is pending here
https://gcc.gnu.org/pipermail/libstdc++/2025-January/060265.html
and checks for __cplusplus >= 202400L.
According to cppreference only Clang >= 19 fully implements P2448R2, but
Clang 17 and 18 already advertise C++26 compatibility under __cplusplus
set to 202400.
On the other hand the ad-hoc _GLIBCXX26_CONSTEXPR_RAW_MEMORY_ALGORITHMS
has a more stringent version check (uses the feature-testing macro,
which in turn checks for the right value of __cpp_constexpr).
Is switching to _GLIBCXX26_CONSTEXPR going to create compatibility
problems? If not, I'll do the change.
>> +
>> namespace std _GLIBCXX_VISIBILITY(default)
>> {
>> _GLIBCXX_BEGIN_NAMESPACE_VERSION
>> @@ -226,6 +232,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
>> * Like std::copy, but does not require an initialized output range.
>> */
>> template<typename _InputIterator, typename _ForwardIterator>
>> + _GLIBCXX26_CONSTEXPR_RAW_MEMORY_ALGORITHMS
>> inline _ForwardIterator
>> uninitialized_copy(_InputIterator __first, _InputIterator __last,
>> _ForwardIterator __result)
>> @@ -256,6 +263,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
>> using _Src = decltype(std::__niter_base(__first));
>> using _ValT = typename iterator_traits<_ForwardIterator>::value_type;
>>
>> +
>> + if (__is_constant_evaluated())
>
> We typically call __is_constant_evaluated fully qualified (though I
> don't remember why since it's not eligible for ADL?)
Ack, will fix.
>
>> + return std::__do_uninit_copy(__first, __last, __result);
>
> I guess we could instead guard the memcpy code path preceding the
> existing call to __do_uninit_copy with !std::__is_constant_evaluated(),
> rather than adding this new call. But that doesn't seem significantly
> cleaner and I'm personally OK with your approach :)
>
> Same for uninitialized_fill and uninitialized_fill_n
I'm wagering this is the simplest implementation strategy for most
constexpr-ified algorithms -- first thing, check if we're called during
constant evaluation, if so dispatch to a constexpr-friendly implementation.
Thank you,
--
Giuseppe D'Angelo
-------------- next part --------------
A non-text attachment was scrubbed...
Name: smime.p7s
Type: application/pkcs7-signature
Size: 4244 bytes
Desc: S/MIME Cryptographic Signature
URL: <https://gcc.gnu.org/pipermail/libstdc++/attachments/20250225/c82e706b/attachment.p7s>
More information about the Libstdc++
mailing list