Skip to content

Commit b09551f

Browse files
authored
[libc++] Fix implementation of iota_view::size (#67819)
We were incorrectly deducing the return type of size() because we were not using ternary operators in the implementation (as the spec says). Instead of deducing the common type of the expressions in the spec, we would deduce potentially different return types and fail to compile. Fixes #67551
1 parent cb7cf62 commit b09551f

File tree

2 files changed

+18
-9
lines changed

2 files changed

+18
-9
lines changed

libcxx/include/__ranges/iota_view.h

+7-8
Original file line numberDiff line numberDiff line change
@@ -363,15 +363,14 @@ namespace ranges {
363363
(integral<_Start> && integral<_BoundSentinel>) || sized_sentinel_for<_BoundSentinel, _Start>
364364
{
365365
if constexpr (__integer_like<_Start> && __integer_like<_BoundSentinel>) {
366-
if (__value_ < 0) {
367-
if (__bound_sentinel_ < 0) {
368-
return std::__to_unsigned_like(-__value_) - std::__to_unsigned_like(-__bound_sentinel_);
369-
}
370-
return std::__to_unsigned_like(__bound_sentinel_) + std::__to_unsigned_like(-__value_);
371-
}
372-
return std::__to_unsigned_like(__bound_sentinel_) - std::__to_unsigned_like(__value_);
366+
return (__value_ < 0)
367+
? ((__bound_sentinel_ < 0)
368+
? std::__to_unsigned_like(-__value_) - std::__to_unsigned_like(-__bound_sentinel_)
369+
: std::__to_unsigned_like(__bound_sentinel_) + std::__to_unsigned_like(-__value_))
370+
: std::__to_unsigned_like(__bound_sentinel_) - std::__to_unsigned_like(__value_);
371+
} else {
372+
return std::__to_unsigned_like(__bound_sentinel_ - __value_);
373373
}
374-
return std::__to_unsigned_like(__bound_sentinel_ - __value_);
375374
}
376375
};
377376

libcxx/test/std/ranges/range.factories/range.iota.view/size.pass.cpp

+11-1
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,10 @@
1010

1111
// constexpr auto size() const requires see below;
1212

13-
#include <ranges>
1413
#include <cassert>
14+
#include <concepts>
1515
#include <limits>
16+
#include <ranges>
1617

1718
#include "test_macros.h"
1819
#include "types.h"
@@ -89,6 +90,15 @@ constexpr bool test() {
8990
assert(io.size() == 0);
9091
}
9192

93+
// Make sure iota_view<short, short> works properly. For details,
94+
// see https://github.com/llvm/llvm-project/issues/67551.
95+
{
96+
static_assert(std::ranges::sized_range<std::ranges::iota_view<short, short>>);
97+
std::ranges::iota_view<short, short> io(10, 20);
98+
std::same_as<unsigned int> auto sz = io.size();
99+
assert(sz == 10);
100+
}
101+
92102
return true;
93103
}
94104

0 commit comments

Comments
 (0)