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

Created on 2018-09-06.00:00:00, last changed 2018-10-01.03:18:34.

Messages

Date: 2018-10-01.03:18:34

Proposed resolution:

This wording is relative to N4762.

  • 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
    […]
    
  • 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.

    […]

  • 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-10-01.03:18:34

[ 2018-09 Reflector prioritization ]

Set Priority to 3

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
2018-10-01 03:18:34adminsetmessages: + msg10112
2018-09-06 19:45:22adminsetmessages: + msg10104
2018-09-06 00:00:00admincreate