Skip to content

Commit

Permalink
Verify that arguments to subrange's iter/sentinel constructors deno…
Browse files Browse the repository at this point in the history
…te a range

They must per N4988 [range.subrange.ctor] para 1 and 3. As a rule, we never verify that `[begin(meow), end(meow))` for a range `meow` actually denotes a range, so `subrange`'s constructors are the only chance we have to verify these user-supplied values.
  • Loading branch information
CaseyCarter committed Oct 13, 2024
1 parent cd2726d commit 221be87
Show file tree
Hide file tree
Showing 3 changed files with 14 additions and 7 deletions.
5 changes: 4 additions & 1 deletion stl/inc/xutility
Original file line number Diff line number Diff line change
Expand Up @@ -3959,12 +3959,15 @@ namespace ranges {
template <_Convertible_to_non_slicing<_It> _It2>
constexpr subrange(_It2 _First_, _Se _Last_)
requires (!_Store_size<_It, _Se, _Ki>)
: _First(_STD move(_First_)), _Last(_STD move(_Last_)) {}
: _First(_STD move(_First_)), _Last(_STD move(_Last_)) {
_STD _Adl_verify_range(_First, _Last);
}

template <_Convertible_to_non_slicing<_It> _It2>
constexpr subrange(_It2 _First_, _Se _Last_, const _Size_type _Size_)
requires (_Ki == subrange_kind::sized)
: _Subrange_base<_It, _Se, _Ki>(_Size_), _First(_STD move(_First_)), _Last(_STD move(_Last_)) {
_STD _Adl_verify_range(_First, _Last);
if constexpr (sized_sentinel_for<_Se, _It>) {
_STL_ASSERT(_Size_ == static_cast<_Size_type>(_Last - _First),
"This constructor's third argument should be equal to the distance "
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ namespace test_make_from_tuple {
assert(make_from_tuple<S>(tuple{&a, &b}) == expected_val);
assert(make_from_tuple<S>(pair{&a, &b}) == expected_val);
assert(make_from_tuple<S>(array{&a, &b}) == expected_val);
assert(make_from_tuple<S>(subrange{&a, &b}) == expected_val);
assert(make_from_tuple<S>(subrange{&a, &a + 1}) == (S{&a, &a + 1}));
}

{ // Test make_from_tuple with big tuple-like types
Expand Down Expand Up @@ -180,9 +180,8 @@ namespace test_tuple_cat {

{ // Test tuple_cat with pair-like types
int a = 0;
int b = 1;
assert(
(tuple_cat(tuple{1, 2}, array{3, 4}, pair{5, 6}, subrange{&a, &b}) == tuple{1, 2, 3, 4, 5, 6, &a, &b}));
assert((tuple_cat(tuple{1, 2}, array{3, 4}, pair{5, 6}, subrange{&a, &a + 1})
== tuple{1, 2, 3, 4, 5, 6, &a, &a + 1}));
}

// Test tuple_cat with big tuple-like types
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,8 +76,13 @@ constexpr bool test() {
int a = 0;
int b = 1;
int c[2] = {2, 3};
static_assert(tuple{&a, &b} == subrange{&a, &b});
static_assert(tuple{&b, &a} != subrange{&a, &b});
#ifdef __EDG__ // VSO-2283373
assert(tuple{&c[0], &c[1]} == subrange{&c[0], &c[1]});
assert(tuple{&c[1], &c[0]} != subrange{&c[0], &c[1]});
#else // ^^^ workaround / no workaround vvv
static_assert(tuple{&c[0], &c[1]} == subrange{&c[0], &c[1]});
static_assert(tuple{&c[1], &c[0]} != subrange{&c[0], &c[1]});
#endif // ^^^ no workaround ^^^
static_assert(is_eq(tuple{&a, &b} <=> pair{&a, &b}));
static_assert(is_lt(tuple{&c[0], &c[0]} <=> pair{&c[0], &c[1]}));
static_assert(is_gt(tuple{&c[1], &c[0]} <=> pair{&c[0], &c[1]}));
Expand Down

0 comments on commit 221be87

Please sign in to comment.