This page is a snapshot from the LWG issues list, see the Library Active Issues List for more information and the meaning of WP status.
Section: 26.3.11 [range.prim.ssize] Status: WP Submitter: Jonathan Wakely Opened: 2020-02-19 Last modified: 2020-11-09
Priority: 2
View all issues with WP status.
Discussion:
ranges::size(E) works with a non-range for which E.size() or size(E) is valid. But ranges::ssize(E) requires the type range_difference_t which requires ranges::begin(E) to be valid. This means there are types for which ranges::size(E) is valid but ranges::ssize(E) is not.
Casey's reaction to this is: I believe we want ranges::ssize to work with any argument that ranges::size accepts. That suggest to me that we're going to need make-signed-like-t<T> after all, so we can "Let E be an expression, and let D be the wider of ptrdiff_t or decltype(ranges::size(E)). Then ranges::ssize(E) is expression-equivalent to static_cast<make-signed-like-t<D>>(ranges::size(E))." Although this wording is still slightly icky since D isn't a valid type when ranges::size(E) isn't a valid expression, I think it's an improvement?[2020-03-11 Issue Prioritization]
Priority to 2 after reflector discussion.
[2020-07-22 Casey provides wording]
Previous resolution [SUPERSEDED]:
This wording is relative to N4861.
Add a new paragraph after paragraph 1 in 26.2 [ranges.syn]:
-?- Also within this clause, make-signed-like-t<X> for an integer-like type X denotes make_signed_t<X> if X is an integer type; otherwise, it denotes a corresponding unspecified signed-integer-like type of the same width as X.Modify 26.3.11 [range.prim.ssize] as indicated:
-1- The name ranges::ssize denotes a customization point object (16.3.3.3.5 [customization.point.object]).
The expression ranges::ssize(E) for a subexpression E of type T is expression-equivalent to:
(1.1) — If range_difference_t<T> has width less than ptrdiff_t, static_cast<ptrdiff_t>(ranges::size(E)).
(1.2) — Otherwise, static_cast<range_difference_t<T>>(ranges::size(E)).-?- Given a subexpression E with type T, let t be an lvalue that denotes the reified object for E. If ranges::size(t) is ill-formed, ranges::ssize(E) is ill-formed. Otherwise, let D be the wider of ptrdiff_t or decltype(ranges::size(t)); ranges::ssize(E) is expression-equivalent to static_cast<make-signed-like-t<D>>(ranges::size(t)).
[2020-07-31 Casey provides updated wording]
Per discussion on the reflector.[2020-08-21; Issue processing telecon: Tentatively Ready]
[2020-11-09 Approved In November virtual meeting. Status changed: Tentatively Ready → WP.]
Proposed resolution:
This wording is relative to N4861.
Add a new paragraph after paragraph 1 in 26.2 [ranges.syn]:
[Drafting note: The following does not define an analog to-signed-like for to-unsigned-like since we don't need it at this time.]
-?- Also within this Clause, make-signed-like-t<X> for an integer-like type X denotes make_signed_t<X> if X is an integer type; otherwise, it denotes a corresponding unspecified signed-integer-like type of the same width as X.
Modify 26.3.11 [range.prim.ssize] as indicated:
-1- The name ranges::ssize denotes a customization point object (16.3.3.3.5 [customization.point.object]).
The expression ranges::ssize(E) for a subexpression E of type T is expression-equivalent to:
(1.1) — If range_difference_t<T> has width less than ptrdiff_t, static_cast<ptrdiff_t>(ranges::size(E)).
(1.2) — Otherwise, static_cast<range_difference_t<T>>(ranges::size(E)).-?- Given a subexpression E with type T, let t be an lvalue that denotes the reified object for E. If ranges::size(t) is ill-formed, ranges::ssize(E) is ill-formed. Otherwise let D be make-signed-like-t<decltype(ranges::size(t))>, or ptrdiff_t if it is wider than that type; ranges::ssize(E) is expression-equivalent to static_cast<D>(ranges::size(t)).