This page is a snapshot from the LWG issues list, see the Library Active Issues List for more information and the meaning of C++23 status.

3772. repeat_view's piecewise constructor is missing Postconditions

Section: 25.6.5.2 [range.repeat.view] Status: C++23 Submitter: Hewill Kang Opened: 2022-09-12 Last modified: 2023-11-22

Priority: 2

View all other issues in [range.repeat.view].

View all issues with C++23 status.

Discussion:

The first two value-bound pair constructors of repeat_view have the Preconditions that the integer-like object bound must be non-negative. However, the piecewise constructor does not mention the valid values for bound_args. It would be nice to add a Postconditions that the initialized bound_ must be greater than or equal to 0 here.

[2022-09-23; Reflector poll]

Set priority to 2 after reflector poll.

This is trying to state a requirement on users, but that's not what Postconditions: means. Should be something more like:
Precondition: If Bound is not unreachable_sentinel_t, the bound_ ≥ 0 after its initialization from bound_args.

Previous resolution [SUPERSEDED]:

This wording is relative to N4917.

  1. Modify 25.6.5.2 [range.repeat.view] as shown:

    template<class... WArgs, class... BoundArgs>
      requires constructible_from<W, WArgs...> &&
               constructible_from<Bound, BoundArgs...>
    constexpr explicit repeat_view(piecewise_construct_t,
      tuple<Wargs...> value_args, tuple<BoundArgs...> bound_args = tuple<>{});
    

    -5- Effects: Initializes value_ with arguments of types WArgs... obtained by forwarding the elements of value_args and initializes bound_ with arguments of types BoundArgs... obtained by forwarding the elements of bound_args. (Here, forwarding an element x of type U within a tuple object means calling std::forward<U>(x).)

    -?- Postconditions: If Bound is not unreachable_sentinel_t, bound_ ≥ 0.

[2022-09-23; Jonathan provides improved wording]

Previous resolution [SUPERSEDED]:

This wording is relative to N4917.

  1. Modify 25.6.5.2 [range.repeat.view] as shown:

    template<class... WArgs, class... BoundArgs>
      requires constructible_from<W, WArgs...> &&
               constructible_from<Bound, BoundArgs...>
    constexpr explicit repeat_view(piecewise_construct_t,
      tuple<Wargs...> value_args, tuple<BoundArgs...> bound_args = tuple<>{});
    

    -?- Preconditions: Bound is unreachable_sentinel_t, or the initialization of bound_ yields a non-negative value.

    -5- Effects: Initializes value_ with arguments of types WArgs... obtained by forwarding the elements of value_args and initializes bound_ with arguments of types BoundArgs... obtained by forwarding the elements of bound_args. (Here, forwarding an element x of type U within a tuple object means calling std::forward<U>(x).)

[2023-01-11; Jonathan provides new wording requested by LWG]

[Issaquah 2023-02-07; LWG]

Move to Immediate for C++23

[2023-02-13 Approved at February 2023 meeting in Issaquah. Status changed: Immediate → WP.]

Proposed resolution:

This wording is relative to N4917.

  1. Modify 25.6.5.2 [range.repeat.view] as shown:

    template<class... TArgs, class... BoundArgs>
      requires constructible_from<T, TArgs...> &&
               constructible_from<Bound, BoundArgs...>
    constexpr explicit repeat_view(piecewise_construct_t,
      tuple<Targs...> value_args, tuple<BoundArgs...> bound_args = tuple<>{});
    

    -5- Effects: Initializes value_ with arguments of types TArgs... obtained by forwarding the elements of value_args make_from_tuple<T>(std::move(value_args)) and initializes bound_ with arguments of types BoundArgs... obtained by forwarding the elements of bound_args. (Here, forwarding an element x of type U within a tuple object means calling std::forward<U>(x).) make_from_tuple<Bound>(std::move(bound_args)). The behavior is undefined if Bound is not unreachable_sentinel_t and bound_ is negative.