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.
ranges::ssize(E) doesn't match ranges::size(E)Section: 25.3.11 [range.prim.ssize] Status: C++23 Submitter: Jonathan Wakely Opened: 2020-02-19 Last modified: 2023-11-22
Priority: 2
View all issues with C++23 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.
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 25.2 [ranges.syn]:
-?- Also within this clause,make-signed-like-t<X>for an integer-like typeXdenotesmake_signed_t<X>ifXis an integer type; otherwise, it denotes a corresponding unspecified signed-integer-like type of the same width asX.Modify 25.3.11 [range.prim.ssize] as indicated:
-1- The name
ranges::ssizedenotes a customization point object (16.3.3.3.5 [customization.point.object]).The expressionranges::ssize(E)for a subexpressionEof typeTis expression-equivalent to:
(1.1) — Ifrange_difference_t<T>has width less thanptrdiff_t,static_cast<ptrdiff_t>(ranges::size(E)).
(1.2) — Otherwise,static_cast<range_difference_t<T>>(ranges::size(E)).-?- Given a subexpression
Ewith typeT, lettbe an lvalue that denotes the reified object forE. Ifranges::size(t)is ill-formed,ranges::ssize(E)is ill-formed. Otherwise, letDbe the wider ofptrdiff_tordecltype(ranges::size(t));ranges::ssize(E)is expression-equivalent tostatic_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 25.2 [ranges.syn]:
[Drafting note: The following does not define an analog
to-signed-likeforto-unsigned-likesince we don't need it at this time.]
-?- Also within this Clause,make-signed-like-t<X>for an integer-like typeXdenotesmake_signed_t<X>ifXis an integer type; otherwise, it denotes a corresponding unspecified signed-integer-like type of the same width asX.
Modify 25.3.11 [range.prim.ssize] as indicated:
-1- The name
ranges::ssizedenotes a customization point object (16.3.3.3.5 [customization.point.object]).The expressionranges::ssize(E)for a subexpressionEof typeTis expression-equivalent to:
(1.1) — Ifrange_difference_t<T>has width less thanptrdiff_t,static_cast<ptrdiff_t>(ranges::size(E)).
(1.2) — Otherwise,static_cast<range_difference_t<T>>(ranges::size(E)).-?- Given a subexpression
Ewith typeT, lettbe an lvalue that denotes the reified object forE. Ifranges::size(t)is ill-formed,ranges::ssize(E)is ill-formed. Otherwise letDbemake-signed-like-t<decltype(ranges::size(t))>, orptrdiff_tif it is wider than that type;ranges::ssize(E)is expression-equivalent tostatic_cast<D>(ranges::size(t)).