3647. nothrow-input-iterator constraints should not mention copying

Section: 26.11.2 [special.mem.concepts] Status: New Submitter: Konstantin Varlamov Opened: 2021-11-30 Last modified: 2022-01-30

Priority: 3

View all issues with New status.

Discussion:

26.11.2 [special.mem.concepts] states that a type qualifies as a nothrow-input-iterator only if no exceptions are thrown from, among other things, copy construction and copy assignment. However, being copyable isn't part of the requirements for an input_iterator on which nothrow-input-iterator is based (indeed, one of the things forward_iterator adds to input_iterator is copyability), and the nothrow-input-iterator concept doesn't add any new constraints related to copyability.

[2021-12-19; Daniel comments]

During LWG discussion of the issue one argument brought forward against the proposed wording was that it might be incomplete, because it doesn't adjust the nothrow-forward-iterator concept, which adds among other things the copyable requirements. But nothrow-forward-iterator also requires nothrow-sentinel-for<I, I>, which already extends this necessary no-throw requirement for copy operations by p. 4:

Types S and I model nothrow-sentinel-for only if no exceptions are thrown from copy construction, move construction, copy assignment, move assignment, or comparisons between valid values of type I and S.

It should also be emphasized that the definitions of move construction (3.33 [defns.move.constr]) and move assignment (3.32 [defns.move.assign]) are compatible even for copyable input iterator types, because these definitions refer just to expression conditions, and not to concrete operator overloads. So as long as an implementation applies these expression conditions, we are safe.

[2022-01-30; Reflector poll]

Set priority to 3 after reflector poll.

Proposed resolution:

This wording is relative to N4901.

  1. Modify 26.11.2 [special.mem.concepts] as indicated:

    template<class I>
    concept nothrow-input-iterator = // exposition only
      input_iterator<I> &&
      is_lvalue_reference_v<iter_reference_t<I>> &&
      same_as<remove_cvref_t<iter_reference_t<I>>, iter_value_t<I>>;
    

    -2- A type I models nothrow-input-iterator only if no exceptions are thrown from increment, copy construction, move construction, copy assignment, move assignment, or indirection through valid iterators.