Skip to content

Commit

Permalink
Implement LWG-4027 possibly-const-range should prefer returning `co…
Browse files Browse the repository at this point in the history
…nst R&` (microsoft#5221)

Co-authored-by: Stephan T. Lavavej <[email protected]>
  • Loading branch information
frederick-vs-ja and StephanTLavavej authored Jan 14, 2025
1 parent ba284eb commit 22b5573
Show file tree
Hide file tree
Showing 5 changed files with 19 additions and 4 deletions.
2 changes: 1 addition & 1 deletion stl/inc/xutility
Original file line number Diff line number Diff line change
Expand Up @@ -2893,7 +2893,7 @@ namespace ranges {

template <input_range _Rng>
_NODISCARD _MSVC_INTRINSIC constexpr auto& _Possibly_const_range(_Rng& _Range) noexcept {
if constexpr (constant_range<const _Rng> && !constant_range<_Rng>) {
if constexpr (input_range<const _Rng>) {
return _STD as_const(_Range);
} else {
return _Range;
Expand Down
2 changes: 1 addition & 1 deletion tests/std/tests/P0896R4_views_join/test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -269,7 +269,7 @@ constexpr bool test_one(Outer&& rng, Expected&& expected) {
static_assert(CanMemberCEnd<const R>
== (forward_range<const V> && is_reference_v<range_reference_t<const V>>
&& input_range<range_reference_t<const V>>) );
const same_as<const_sentinel_t<R>> auto cs = r.end();
const auto cs = r.end();
if (!is_empty) {
if constexpr (bidirectional_range<R> && common_range<R>) {
assert(*prev(cs) == *prev(end(expected)));
Expand Down
8 changes: 8 additions & 0 deletions tests/std/tests/P0896R4_views_lazy_split/test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -359,6 +359,14 @@ constexpr bool test_lwg_3904() {
return j != r.end();
}

void test_lwg_4027() { // COMPILE-ONLY
auto r = views::single(0) | views::lazy_split(0);
using R1 = decltype((*ranges::cbegin(r)).front());
using R2 = decltype((*cbegin(r)).front());
static_assert(same_as<R1, R2>);
static_assert(is_const_v<remove_reference_t<R1>>);
}

int main() {
static_assert(instantiation_test());
instantiation_test();
Expand Down
7 changes: 7 additions & 0 deletions tests/std/tests/P0896R4_views_transform/test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -879,6 +879,13 @@ void test_gh_3014() { // COMPILE-ONLY
[[maybe_unused]] decltype(as_const(r).begin()) i = r.begin(); // Check 'iterator(iterator<!Const> i)'
}

void test_lwg_4027() { // COMPILE-ONLY
auto r = views::single(0) | views::transform([](int) { return 0; });
using CIt1 = decltype(ranges::cbegin(r));
using CIt2 = decltype(cbegin(r));
static_assert(same_as<CIt1, CIt2>);
}

int main() {
{ // Validate copyable views
constexpr span<const int> s{some_ints};
Expand Down
4 changes: 2 additions & 2 deletions tests/std/tests/P2278R4_ranges_const_range_machinery/test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -127,8 +127,8 @@ namespace test_prvalue_range {
static_assert(CanRangeConstIterator<Rng>);
static_assert(CanRangeConstSentinel<Rng>);
static_assert(CanRangeConstReference<Rng>);
static_assert(same_as<ranges::const_iterator_t<Rng>, const_iterator<ranges::iterator_t<Rng>>>);
static_assert(same_as<ranges::const_sentinel_t<Rng>, const_iterator<ranges::iterator_t<Rng>>>);
static_assert(!same_as<ranges::const_iterator_t<Rng>, const_iterator<ranges::iterator_t<Rng>>>);
static_assert(!same_as<ranges::const_sentinel_t<Rng>, const_iterator<ranges::iterator_t<Rng>>>);
static_assert(same_as<ranges::range_const_reference_t<Rng>, int>);
static_assert(ranges::constant_range<Rng>);

Expand Down

0 comments on commit 22b5573

Please sign in to comment.