Title
Parallel `std::ranges::destroy` should allow exceptions
Status
new
Section
[memory.syn]
Submitter
Ruslan Arutyunyan

Created on 2025-10-24.00:00:00 last changed 5 days ago

Messages

Date: 2025-10-25.17:26:41

Proposed resolution:

This wording is relative to N5014.

  1. Modify [memory.syn], header <memory> synopsis, as indicated:

    [Drafting note: There are no further prototype definitions for the affected execution-policy overloads in [specialized.destroy].]

    […]
    // 26.11.9, [specialized.destroy]
    template<class T>
      constexpr void destroy_at(T* location);                                  // freestanding
    template<class NoThrowForwardIterator>
      constexpr void destroy(NoThrowForwardIterator first,                     // freestanding
                             NoThrowForwardIterator last);
    template<class ExecutionPolicy, class NoThrowForwardIterator>
      void destroy(ExecutionPolicy&& exec,                                     // freestanding-deleted,
                   NoThrowForwardIterator first,                               // see [algorithms.parallel.overloads]
                   NoThrowForwardIterator last);
    template<class NoThrowForwardIterator, class Size>
      constexpr NoThrowForwardIterator destroy_n(NoThrowForwardIterator first, // freestanding
                                                 Size n);
    template<class ExecutionPolicy, class NoThrowForwardIterator, class Size>
      NoThrowForwardIterator destroy_n(ExecutionPolicy&& exec,                 // freestanding-deleted,
                                       NoThrowForwardIterator first, Size n);  // see [algorithms.parallel.overloads]
    namespace ranges {
      template<destructible T>
        constexpr void destroy_at(T* location) noexcept;                       // freestanding
        
      template<nothrow-input-iterator I, nothrow-sentinel-for <I> S>
        requires destructible<iter_value_t<I>>
          constexpr I destroy(I first, S last) noexcept;                       // freestanding     
      template<nothrow-input-range R>
        requires destructible<range_value_t<R>>
          constexpr borrowed_iterator_t<R> destroy(R&& r) noexcept;            // freestanding
          
      template<nothrow-input-iterator I>
        requires destructible<iter_value_t<I>>
        constexpr I destroy_n(I first, iter_difference_t<I> n) noexcept;       // freestanding
        
      template<execution-policy Ep, nothrow-random-access-iterator I,
               nothrow-sized-sentinel-for <I> S>
        requires destructible<iter_value_t<I>>
          I destroy(Ep&& exec, I first, S last) noexcept;                       // freestanding-deleted,
                                                                                // see [algorithms.parallel.overloads]
      template<execution-policy Ep, nothrow-sized-random-access-range R>
        requires destructible<range_value_t<R>>
          borrowed_iterator_t<R> destroy(Ep&& exec, R&& r) noexcept;            // freestanding-deleted,
                                                                                // see [algorithms.parallel.overloads]
      template<execution-policy Ep, nothrow-random-access-iterator I>
        requires destructible<iter_value_t<I>>
          I destroy_n(Ep&& exec, I first, iter_difference_t<I> n) noexcept;     // freestanding-deleted,
                                                                                // see [algorithms.parallel.overloads]
    }
    […]
    
Date: 2025-10-24.00:00:00

The serial `std::ranges::destroy` algorithm is marked as `noexcept`. However, the parallel counterpart should not be marked `noexcept`.

While we generally don't expect any exceptions from the `destroy` algorithm when called with the standard execution policies (`seq`, `unseq`, `par`, `par_unseq`), the implementation-defined policies for parallel algorithms are allowed by the C++ standard, and it is up to the particular execution policy to decide which exceptions can be thrown from parallel algorithms.

History
Date User Action Args
2025-10-25 17:26:41adminsetmessages: + msg15426
2025-10-24 00:00:00admincreate