Title
ForwardIterator should only mean forward iterator
Status
resolved
Section
[specialized.algorithms]
Submitter
Casey Carter

Created on 2018-09-06.00:00:00 last changed 48 months ago

Messages

Date: 2020-05-02.16:19:32

Proposed resolution:

Resolved by P1963R0.

Date: 2020-05-15.00:00:00

[ 2020-05-02; Reflector discussions ]

The issue has been resolved by accepting P1963R0 in Prague 2020.

Date: 2020-05-02.16:19:32

[ 2018-09 Reflector prioritization ]

Set Priority to 3

Previous resolution [SUPERSEDED]:

This wording is relative to N4762.

  1. Modify [memory.syn] as indicated:

    […]
    
    // [specialized.algorithms], specialized algorithms
    template<class T>
      constexpr T* addressof(T& r) noexcept;
    template<class T>
      const T* addressof(const T&&) = delete;
    template<class NoThrowForwardIterator>
      void uninitialized_default_construct(NoThrowForwardIterator first, NoThrowForwardIterator last);
    template<class ExecutionPolicy, class NoThrowForwardIterator>
      void uninitialized_default_construct(ExecutionPolicy&& exec, // see [algorithms.parallel.overloads]
                                           NoThrowForwardIterator first, NoThrowForwardIterator last);
    template<class NoThrowForwardIterator, class Size>
      NoThrowForwardIterator uninitialized_default_construct_n(NoThrowForwardIterator first, Size n);
    template<class ExecutionPolicy, class NoThrowForwardIterator, class Size>
      NoThrowForwardIterator uninitialized_default_construct_n(ExecutionPolicy&& exec, // see [algorithms.parallel.overloads]
                                                        NoThrowForwardIterator first, Size n);
    template<class NoThrowForwardIterator>
      void uninitialized_value_construct(NoThrowForwardIterator first, NoThrowForwardIterator last);
    template<class ExecutionPolicy, class NoThrowForwardIterator>
      void uninitialized_value_construct(ExecutionPolicy&& exec, // see [algorithms.parallel.overloads]
                                         NoThrowForwardIterator first, NoThrowForwardIterator last);
    template<class NoThrowForwardIterator, class Size>
      NoThrowForwardIterator uninitialized_value_construct_n(NoThrowForwardIterator first, Size n);
    template<class ExecutionPolicy, class NoThrowForwardIterator, class Size>
      NoThrowForwardIterator uninitialized_value_construct_n(ExecutionPolicy&& exec, // see [algorithms.parallel.overloads]
                                                      NoThrowForwardIterator first, Size n);
    template<class InputIterator, class NoThrowForwardIterator>
      NoThrowForwardIterator uninitialized_copy(InputIterator first, InputIterator last,
                                         NoThrowForwardIterator result);
    template<class ExecutionPolicy, class InputIterator, class NoThrowForwardIterator>
      NoThrowForwardIterator uninitialized_copy(ExecutionPolicy&& exec, // see [algorithms.parallel.overloads]
                                         InputIterator first, InputIterator last,
                                         NoThrowForwardIterator result);
    template<class InputIterator, class Size, class NoThrowForwardIterator>
      NoThrowForwardIterator uninitialized_copy_n(InputIterator first, Size n,
                                           NoThrowForwardIterator result);
    template<class ExecutionPolicy, class InputIterator, class Size, class NoThrowForwardIterator>
      NoThrowForwardIterator uninitialized_copy_n(ExecutionPolicy&& exec, // see [algorithms.parallel.overloads]
                                           InputIterator first, Size n,
                                           NoThrowForwardIterator result);
    template<class InputIterator, class NoThrowForwardIterator>
      NoThrowForwardIterator uninitialized_move(InputIterator first, InputIterator last,
                                         NoThrowForwardIterator result);
    template<class ExecutionPolicy, class InputIterator, class NoThrowForwardIterator>
      NoThrowForwardIterator uninitialized_move(ExecutionPolicy&& exec, // see [algorithms.parallel.overloads]
                                         InputIterator first, InputIterator last,
                                         NoThrowForwardIterator result);
    template<class InputIterator, class Size, class NoThrowForwardIterator>
      pair<InputIterator, NoThrowForwardIterator> uninitialized_move_n(InputIterator first, Size n,
                                                                NoThrowForwardIterator result);
    template<class ExecutionPolicy, class InputIterator, class Size, class NoThrowForwardIterator>
      pair<InputIterator, NoThrowForwardIterator> uninitialized_move_n(ExecutionPolicy&& exec, // see [algorithms.parallel.overloads]
                                                                InputIterator first, Size n,
                                                                NoThrowForwardIterator result);
    template<class NoThrowForwardIterator, class T>
      void uninitialized_fill(NoThrowForwardIterator first, NoThrowForwardIterator last, const T& x);
    template<class ExecutionPolicy, class NoThrowForwardIterator, class T>
      void uninitialized_fill(ExecutionPolicy&& exec, // see [algorithms.parallel.overloads]
                              NoThrowForwardIterator first, NoThrowForwardIterator last, const T& x);
    template<class NoThrowForwardIterator, class Size, class T>
      NoThrowForwardIterator uninitialized_fill_n(NoThrowForwardIterator first, Size n, const T& x);
    template<class ExecutionPolicy, class NoThrowForwardIterator, class Size, class T>
      NoThrowForwardIterator uninitialized_fill_n(ExecutionPolicy&& exec, // see [algorithms.parallel.overloads]
                                           NoThrowForwardIterator first, Size n, const T& x);
    template<class T>
      void destroy_at(T* location);
    template<class NoThrowForwardIterator>
      void destroy(NoThrowForwardIterator first, NoThrowForwardIterator last);
    template<class ExecutionPolicy, class NoThrowForwardIterator>
      void destroy(ExecutionPolicy&& exec, // see [algorithms.parallel.overloads]
                   NoThrowForwardIterator first, NoThrowForwardIterator last);
    template<class NoThrowForwardIterator, class Size>
      NoThrowForwardIterator destroy_n(NoThrowForwardIterator first, Size n);
    template<class ExecutionPolicy, class NoThrowForwardIterator, class Size>
      NoThrowForwardIterator destroy_n(ExecutionPolicy&& exec, // see [algorithms.parallel.overloads]
                                NoThrowForwardIterator first, Size n);
    
    // [unique.ptr], class template unique_ptr
    […]
    
  2. Modify [specialized.algorithms] as indicated:

    […]

    (1.2) — If an algorithm's template parameter is named NoThrowForwardIterator, the template argument shall satisfy the Cpp17ForwardIterator requirements ([forward.iterators]), and is required to have the property that no exceptions are thrown from increment, assignment, comparison, or indirection through valid iterators.

    […]

  3. Modify the declarations of the specialized algorithms in the remainder of [specialized.algorithms] to agree with the proposed changes to [memory.syn] above.

Date: 2018-09-06.00:00:00

[specialized.algorithms] para 1.2 describes how the specialized algorithms with a template parameter named ForwardIterator impose requirements on the type passed as argument for that parameter: it must meet the Cpp17ForwardIterator requirements, which is consistent with how the rest of the Library uses the template parameter name ForwardIterator, and many of the required operations on that type must not throw exceptions, which is not consistent with how the rest of the Library uses that name.

To avoid confusion and keep the meaning of requirements imposed by template parameter names crisp, the specialized memory algorithms should use a different template parameter name for this different set of requirements.

Note that the proposed change has no normative effect; it's simply a clarification of the existing wording.

History
Date User Action Args
2020-05-02 16:19:32adminsetmessages: + msg11258
2020-05-02 16:19:32adminsetstatus: new -> resolved
2018-10-01 03:18:34adminsetmessages: + msg10149
2018-09-06 19:45:22adminsetmessages: + msg10141
2018-09-06 00:00:00admincreate