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 ?


> +       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