On Fri, 13 Jun 2025 at 10:38, Daniel Krügler <daniel.krueg...@gmail.com> wrote:
>
> Am Fr., 13. Juni 2025 um 11:33 Uhr schrieb Jonathan Wakely 
> <jwak...@redhat.com>:
>>
>> The std::uninitialized_{value,default}_construct{,_n} algorithms should
>> be able to create arrays, but that currently fails because when an
>> exception happens they clean up using std::_Destroy and in C++17 that
>> doesn't support destroying arrays. (For C++20 and later, std::destroy
>> does handle destroying arrays.)
>>
>> This commit adjusts the _UninitDestroyGuard RAII type used by those
>> algos so that in C++17 mode it recursively destroys each rank of an
>> array type, only using std::_Destroy for the last rank when it's
>> destroying non-array objects.
>>
>> libstdc++-v3/ChangeLog:
>>
>>         PR libstdc++/120397
>>         * include/bits/stl_uninitialized.h (_UninitDestroyGuard<I,void>):
>>         Add new member function _S_destroy and call it from the
>>         destructor (for C++17 only).
>>         * 
>> testsuite/20_util/specialized_algorithms/uninitialized_default_construct/120397.cc:
>>         New test.
>>         * 
>> testsuite/20_util/specialized_algorithms/uninitialized_value_construct/120397.cc:
>>         New test.
>> ---
>>
>> v2: Only define+use _S_destroy for C++17, at Tomasz's request.
>>
>> Tested x86_64-linux.
>>
>>  libstdc++-v3/include/bits/stl_uninitialized.h | 21 +++++++++++++++++++
>>  .../uninitialized_default_construct/120397.cc | 19 +++++++++++++++++
>>  .../uninitialized_value_construct/120397.cc   | 19 +++++++++++++++++
>>  3 files changed, 59 insertions(+)
>>  create mode 100644 
>> libstdc++-v3/testsuite/20_util/specialized_algorithms/uninitialized_default_construct/120397.cc
>>  create mode 100644 
>> libstdc++-v3/testsuite/20_util/specialized_algorithms/uninitialized_value_construct/120397.cc
>>
>> diff --git a/libstdc++-v3/include/bits/stl_uninitialized.h 
>> b/libstdc++-v3/include/bits/stl_uninitialized.h
>> index bde787c2beaa..4b3f81604606 100644
>> --- a/libstdc++-v3/include/bits/stl_uninitialized.h
>> +++ b/libstdc++-v3/include/bits/stl_uninitialized.h
>> @@ -118,7 +118,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
>>        ~_UninitDestroyGuard()
>>        {
>>         if (__builtin_expect(_M_cur != 0, 0))
>> +#if __cplusplus == 201703L
>> +         // std::uninitialized_{value,default}{,_n} can construct array 
>> types,
>> +         // but std::_Destroy cannot handle them until C++20 (PR 120397).
>> +         _S_destroy(_M_first, *_M_cur);
>> +#else
>>           std::_Destroy(_M_first, *_M_cur);
>> +#endif
>>        }
>>
>>        _GLIBCXX20_CONSTEXPR
>> @@ -129,6 +135,21 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
>>
>>      private:
>>        _UninitDestroyGuard(const _UninitDestroyGuard&);
>> +
>> +#if __cplusplus == 201703L
>> +      template<typename _Iter>
>> +       _GLIBCXX20_CONSTEXPR
>
>
> Since this signature *only* targets C++17, what is the purpose of the  
> _GLIBCXX20_CONSTEXPR ?

It's just a leftover from the previous patch, I'll remove it, thanks.

>
>>
>> +       static void
>> +       _S_destroy(_Iter __first, _Iter __last)
>> +       {
>> +         using _ValT = typename iterator_traits<_Iter>::value_type;
>> +         if constexpr (is_array<_ValT>::value)
>> +           for (; __first != __last; ++__first)
>> +             _S_destroy(*__first, *__first + extent<_ValT>::value);
>> +         else
>> +           std::_Destroy(__first, __last);
>> +       }
>> +#endif
>>      };
>>
>
> - Daniel
>
>

Reply via email to