This page is a snapshot from the LWG issues list, see the Library Active Issues List for more information and the meaning of New status.
take
/drop
adaptorSection: 25.7.10.1 [range.take.overview], 25.7.12.1 [range.drop.overview] Status: New Submitter: Hewill Kang Opened: 2025-02-15 Last modified: 2025-02-24
Priority: Not Prioritized
View other active issues in [range.take.overview].
View all other issues in [range.take.overview].
View all issues with New status.
Discussion:
The take
/drop
adaptor does not explicitly require N to be non-negative (although
the view class does), which makes it possible for some specialized cases to be well-defined when N is negative,
since no Preconditions are violated:
auto e = std::views::empty<int> | std::views::take(-1); // [] auto i = std::views::iota(1, 5) | std::views::drop(-1); // [0, 1, 2, 3, 4] auto r = std::views::repeat('a', 2) | std::views::drop(-1); // ['a', 'a', 'a']
This is not the intention, we should ban these cases.
Previous resolution [SUPERSEDED]:
This wording is relative to N5001.
Modify 25.7.10.1 [range.take.overview] as indicated:
-2- The name
views::take
denotes a range adaptor object (25.7.2 [range.adaptor.object]). LetE
andF
be expressions, letT
beremove_cvref_t<decltype((E))>
, and letD
berange_difference_t<decltype((E))>
. Ifdecltype((F))
does not modelconvertible_to<D>
,views::take(E, F)
is ill-formed. Otherwise, the expressionviews::take(E, F)
is expression-equivalent to:
(2.?) — Preconditions:
static_cast<D>(F) >= 0
istrue
.(2.1) — if
T
is a specialization ofempty_view
(25.6.2.2 [range.empty.view]), then((void)F, decay-copy(E))
, except that the evaluations ofE
andF
are indeterminately sequenced.Modify 25.7.12.1 [range.drop.overview] as indicated:
-2- The name
views::drop
denotes a range adaptor object (25.7.2 [range.adaptor.object]). LetE
andF
be expressions, letT
beremove_cvref_t<decltype((E))>
, and letD
berange_difference_t<decltype((E))>
. Ifdecltype((F))
does not modelconvertible_to<D>
,views::drop(E, F)
is ill-formed. Otherwise, the expressionviews::drop(E, F)
is expression-equivalent to:
(2.?) — Preconditions:
static_cast<D>(F) >= 0
istrue
.(2.1) — if
T
is a specialization ofempty_view
(25.6.2.2 [range.empty.view]), then((void)F, decay-copy(E))
, except that the evaluations ofE
andF
are indeterminately sequenced.
[2025-02-24]
Upon reflector discussion many preferred to use instead the new Hardened preconditions: element which have been introduced by the recently voted in P3471R4.
Proposed resolution:
This wording is relative to N5001 plus additions from P3471R4.
Modify 25.7.10.1 [range.take.overview] as indicated:
-2- The name
views::take
denotes a range adaptor object (25.7.2 [range.adaptor.object]). LetE
andF
be expressions, letT
beremove_cvref_t<decltype((E))>
, and letD
berange_difference_t<decltype((E))>
. Ifdecltype((F))
does not modelconvertible_to<D>
,views::take(E, F)
is ill-formed. Otherwise, the expressionviews::take(E, F)
is expression-equivalent to:
(2.?) — Hardened preconditions:
static_cast<D>(F) >= 0
istrue
.(2.1) — if
T
is a specialization ofempty_view
(25.6.2.2 [range.empty.view]), then((void)F, decay-copy(E))
, except that the evaluations ofE
andF
are indeterminately sequenced.
Modify 25.7.12.1 [range.drop.overview] as indicated:
-2- The name
views::drop
denotes a range adaptor object (25.7.2 [range.adaptor.object]). LetE
andF
be expressions, letT
beremove_cvref_t<decltype((E))>
, and letD
berange_difference_t<decltype((E))>
. Ifdecltype((F))
does not modelconvertible_to<D>
,views::drop(E, F)
is ill-formed. Otherwise, the expressionviews::drop(E, F)
is expression-equivalent to:
(2.?) — Hardened preconditions:
static_cast<D>(F) >= 0
istrue
.(2.1) — if
T
is a specialization ofempty_view
(25.6.2.2 [range.empty.view]), then((void)F, decay-copy(E))
, except that the evaluations ofE
andF
are indeterminately sequenced.