Created on 2018-04-13.00:00:00 last changed 43 months ago
Proposed resolution:
This wording is relative to N4820.
[Drafting note: This wording relies on observation, that the condition in formExtent == dynamic_extent || Count <= Extent
, can be simplified intoCount <= Extent
, becausedynamic_extent
is equal tonumeric_limits<size_t>::max()
, thussize() <= Extent
is always true, andExtent == dynamic_extent
implies thatCount <= Extent
. Furthermore we check thatCount != dynamic_extent || Count <= Extent - Offset
, as theOffset + Count <= Extent
may overflow (defined for unsigned integers) and produce false positive result. This change is also applied to Expects clause. ]
Edit [span.sub] as indicated:
template<size_t Count> constexpr span<element_type, Count> first() const;-?- Mandates: Count <= Extent is true.
-1- Expects: Count <= size() is true. -2- Effects: Equivalent to: return {data(), Count};template<size_t Count> constexpr span<element_type, Count> last() const;-?- Mandates: Count <= Extent is true.
-3- Expects: Count <= size() is true. -4- Effects: Equivalent to: return {data() + (size() - Count), Count};template<size_t Offset, size_t Count = dynamic_extent> constexpr span<element_type, see below> subspan() const;[…]-?- Mandates: Offset <= Extent && (Count == dynamic_extent || Count <= Extent - Offset) is true.
-5- Expects: Offset <= size() && (Count == dynamic_extent ||Offset + Count <= size()Count <= size() - Offset) is true. -6- Effects: Equivalent to: return span<ElementType, see below>(data() + Offset, Count != dynamic_extent ? Count : size() - Offset); -7- Remarks: The second template argument of the returned span type is:Count != dynamic_extent ? Count : (Extent != dynamic_extent ? Extent - Offset : dynamic_extent)constexpr span<element_type, dynamic_extent> subspan( index_type offset, index_type count = dynamic_extent) const;-12- Expects: offset <= size() && (count == dynamic_extent ||
-13- Effects: Equivalent to: return {data() + offset, count == dynamic_extent ? size() - offset : count};offset + count <= size()count <= size() - offset) is true.
[ 2019 Cologne Wednesday night ]
Status to Ready
[ 2018-11-09; Tomasz provides updated wording ]
I have decided to replace all Requires: elements in the section [span.sub] to preserve consistency.
Previous resolution: [SUPERSEDED]This wording is relative to N4778.
Edit [span.sub] as indicated:
template<ptrdiff_t Count> constexpr span<element_type, Count> first() const;-?- Mandates: Count >= 0 && (Extent == dynamic_extent || Count <= Extent).
-1-RequiresExpects:0 <= Count &&Count <= size(). -2- Effects: Equivalent to: return {data(), Count};template<ptrdiff_t Count> constexpr span<element_type, Count> last() const;-?- Mandates: Count >= 0 && (Extent == dynamic_extent || Count <= Extent).
-3-RequiresExpects:0 <= Count &&Count <= size(). -4- Effects: Equivalent to: return {data() + (size() - Count), Count};template<ptrdiff_t Offset, ptrdiff_t Count = dynamic_extent> constexpr span<element_type, see below> subspan() const;-?- Mandates: Offset >= 0 && (Count >= 0 || Count == dynamic_extent) && (Extent == dynamic_extent || (Offset <= Extent && (Count == dynamic_extent || Offset + Count <= Extent))).
-5-RequiresExpects:(0 <= Offset &&Offset <= size())&& (Count == dynamic_extent ||Count >= 0 &&Offset + Count <= size()). -6- Effects: Equivalent to: return span<ElementType, see below>( data() + Offset, Count != dynamic_extent ? Count : size() - Offset); -7- Remarks: The second template argument of the returned span type is:Count != dynamic_extent ? Count : (Extent != dynamic_extent ? Extent - Offset : dynamic_extent)constexpr span<element_type, dynamic_extent> first(index_type count) const;-8-
-9- Effects: Equivalent to: return {data(), count};RequiresExpects: 0 <= count && count <= size().constexpr span<element_type, dynamic_extent> last(index_type count) const;-10-
-11- Effects: Equivalent to: return {data() + (size() - count), count};RequiresExpects: 0 <= count && count <= size().constexpr span<element_type, dynamic_extent> subspan( index_type offset, index_type count = dynamic_extent) const;-12-
-13- Effects: Equivalent to: return {data() + offset, count == dynamic_extent ? size() - offset : count};RequiresExpects: (0 <= offset && offset <= size()) && (count == dynamic_extent || count >= 0 && offset + count <= size())
[ 2018-11 San Diego Thursday night issue processing ]
Tomasz to provide updated wording.
Previous resolution: [SUPERSEDED]This wording is relative to N4741.
Edit [span.sub] as indicated:
template<ptrdiff_t Count> constexpr span<element_type, Count> first() const;-?- Remarks: If Count < 0 || (Extent != dynamic_extent && Count > Extent), the program is ill-formed.
-1- Requires:0 <= Count &&Count <= size(). -2- Effects: Equivalent to: return {data(), Count};template<ptrdiff_t Count> constexpr span<element_type, Count> last() const;-?- Remarks: If Count < 0 || (Extent != dynamic_extent && Count > Extent), the program is ill-formed.
-3- Requires:0 <= Count &&Count <= size(). -4- Effects: Equivalent to: return {data() + (size() - Count), Count};template<ptrdiff_t Offset, ptrdiff_t Count = dynamic_extent> constexpr span<element_type, see below> subspan() const;-?- Remarks: The program is ill-formed if:
-5- Requires:
Offset < 0 || (Count < 0 && Count != dynamic_extent), or
Extend != dynamic_extent && (Offset > Extent || (Count != dynamic_extent && Offset + Count > Extent)).
(0 <= Offset &&Offset <= size())&& (Count == dynamic_extent ||Count >= 0 &&Offset + Count <= size()). -6- Effects: Equivalent to: return span<ElementType, see below>( data() + Offset, Count != dynamic_extent ? Count : size() - Offset); -7- Remarks: The second template argument of the returned span type is:Count != dynamic_extent ? Count : (Extent != dynamic_extent ? Extent - Offset : dynamic_extent)
[ 2018-04-24 Priority set to 3 after discussion on the reflector. ]
Currently all out-of-bound/inputs errors in the functions taking an subview of span lead to undefined behavior, even in the situation when they could be detected at compile time. This is inconsistent with the behavior of the span constructors, which make similar constructs ill-formed.
Furthermore, with the current specification of the subspan function, the following invocation:span<T, N> s; // N > 0 s.subspan<O>(); // with O > 0
is ill-formed when O > N + 1, as the return of the function is span<T, K> with K < -1. However in case when O == N + 1, runtime sized span is returned (span<T, -1>) instead and the behavior of the function is undefined.
Firstly, for either run time sized (N == dynamic_extent) and fixed sized (N > 0) object s of type span<T, N>, the following constructs should be ill-formed, instead of having undefined behavior:s.first<C>() with C < 0
s.last<C>() with C < 0
s.subspan<O, E> with O < 0 or E < 0 and E != dynamic_extent.
This would follow span specification, that make instantiation of span<T, N> ill-formed for N < 0 and N != dynamic_extent.
In addition the following constructs should be made ill-formed for fixed size span s of type span<T, N> (with N > 0):s.first<C>() with C > N
s.last<C>() with C > N
s.subspan<O, dynamic_extent>() with O > N
s.subspan<O, C>() with O + C > N
This will match the span constructor that made construction of fixed size span<T, N> from fixed size span of different size ill-formed.
History | |||
---|---|---|---|
Date | User | Action | Args |
2021-02-25 10:48:01 | admin | set | status: wp -> c++20 |
2019-11-19 14:48:30 | admin | set | status: voting -> wp |
2019-10-07 02:48:00 | admin | set | status: ready -> voting |
2019-07-22 17:12:46 | admin | set | messages: + msg10489 |
2019-07-22 17:12:46 | admin | set | status: open -> ready |
2019-06-23 17:55:19 | admin | set | messages: + msg10464 |
2018-11-14 18:19:04 | admin | set | messages: + msg10223 |
2018-11-12 05:21:03 | admin | set | messages: + msg10219 |
2018-11-12 05:21:03 | admin | set | status: new -> open |
2018-05-05 12:47:02 | admin | set | messages: + msg9836 |
2018-04-22 15:46:08 | admin | set | messages: + msg9825 |
2018-04-13 00:00:00 | admin | create |