On Wed, 11 Jun 2025 at 10:24, Tomasz Kaminski <tkami...@redhat.com> wrote:
>
>
>
> On Tue, Jun 10, 2025 at 12:37 PM Jonathan Wakely <jwak...@redhat.com> wrote:
>>
>> By using std::is_trivially_destructible instead of the old
>> __has_trivial_destructor built-in we no longer need the static_assert to
>> deal with types with deleted destructors. All non-destructible types,
>> including those with deleted destructors, will now give user-friendly
>> diagnostics that clearly explain the problem.
>>
>> Also combine the _Destroy_aux and _Destroy_n_aux class templates used
>> for C++98 into one, so that we perform fewer expensive class template
>> instantiations.
>>
>> libstdc++-v3/ChangeLog:
>>
>>         PR libstdc++/120390
>>         * include/bits/stl_construct.h (_Destroy_aux::__destroy_n): New
>>         static member function.
>>         (_Destroy_aux<true>::__destroy_n): Likewise.
>>         (_Destroy_n_aux): Remove.
>>         (_Destroy(ForwardIterator, ForwardIterator)): Remove
>>         static_assert. Use is_trivially_destructible instead of
>>         __has_trivial_destructor.
>>         (_Destroy_n): Likewise. Use _Destroy_aux::__destroy_n instead of
>>         _Destroy_n_aux::__destroy_n.
>>         * 
>> testsuite/20_util/specialized_algorithms/memory_management_tools/destroy_neg.cc:
>>         Adjust dg-error strings. Move destroy_n tests to ...
>>         * 
>> testsuite/20_util/specialized_algorithms/memory_management_tools/destroy_n_neg.cc:
>>         New test.
>>         * testsuite/23_containers/vector/cons/destructible_debug_neg.cc:
>>         Adjust dg-error strings.
>>         * testsuite/23_containers/vector/cons/destructible_neg.cc:
>>         Likewise.
>> ---
>>
>> Tested x86_64-linux.
>
> LGTM.
> Not directly related to the patch, but I have noticed that for c++98, for 
> trivially destructible
> types we make sure that we traverse range (we call advance) however in C++11+ 
> mode
> we do not do that. Something changed in standard?

I think they should be equivalent. For C++98 the
_Destroy_aux<true>::__destroy_n function calls advance and returns the
result:


>> @@ -189,6 +198,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
>>        template<typename _ForwardIterator>
>>          static void
>>          __destroy(_ForwardIterator, _ForwardIterator) { }
>> +
>> +      template<typename _ForwardIterator, typename _Size>
>> +       static _ForwardIterator
>> +       __destroy_n(_ForwardIterator __first, _Size __count)
>> +       {
>> +         std::advance(__first, __count);
>> +         return __first;
>> +       }
>>      };
>>  #endif

For C++11 we do the same directly in the _Destroy_n function:

>> @@ -260,10 +247,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
>>        typedef typename iterator_traits<_ForwardIterator>::value_type
>>                         _Value_type;
>>  #if __cplusplus >= 201103L
>> -      // A deleted destructor is trivial, this ensures we reject such types:
>> -      static_assert(is_destructible<_Value_type>::value,
>> -                   "value type is destructible");
>> -      if constexpr (!__has_trivial_destructor(_Value_type))
>> +      if constexpr (!is_trivially_destructible<_Value_type>::value)
>>         for (; __count > 0; (void)++__first, --__count)
>>           std::_Destroy(std::__addressof(*__first));
>>  #if __cpp_constexpr_dynamic_alloc // >= C++20
>> @@ -275,7 +259,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
>>         std::advance(__first, __count);
>>        return __first;

^ here.

Reply via email to