[libcxx-commits] [libcxx] b09551f - [libc++] Fix implementation of iota_view::size (#67819)
via libcxx-commits
libcxx-commits at lists.llvm.org
Wed Oct 4 15:34:48 PDT 2023
Author: Louis Dionne
Date: 2023-10-04T18:34:43-04:00
New Revision: b09551f07408aad37c5be7fdbd8dd5a6f9056738
URL: https://github.com/llvm/llvm-project/commit/b09551f07408aad37c5be7fdbd8dd5a6f9056738
DIFF: https://github.com/llvm/llvm-project/commit/b09551f07408aad37c5be7fdbd8dd5a6f9056738.diff
LOG: [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
Added:
Modified:
libcxx/include/__ranges/iota_view.h
libcxx/test/std/ranges/range.factories/range.iota.view/size.pass.cpp
Removed:
################################################################################
diff --git a/libcxx/include/__ranges/iota_view.h b/libcxx/include/__ranges/iota_view.h
index f372688abfdaf32..ccf0c7a8e8d50e4 100644
--- a/libcxx/include/__ranges/iota_view.h
+++ b/libcxx/include/__ranges/iota_view.h
@@ -363,15 +363,14 @@ namespace ranges {
(integral<_Start> && integral<_BoundSentinel>) || sized_sentinel_for<_BoundSentinel, _Start>
{
if constexpr (__integer_like<_Start> && __integer_like<_BoundSentinel>) {
- if (__value_ < 0) {
- if (__bound_sentinel_ < 0) {
- return std::__to_unsigned_like(-__value_) - std::__to_unsigned_like(-__bound_sentinel_);
- }
- return std::__to_unsigned_like(__bound_sentinel_) + std::__to_unsigned_like(-__value_);
- }
- return std::__to_unsigned_like(__bound_sentinel_) - std::__to_unsigned_like(__value_);
+ return (__value_ < 0)
+ ? ((__bound_sentinel_ < 0)
+ ? std::__to_unsigned_like(-__value_) - std::__to_unsigned_like(-__bound_sentinel_)
+ : std::__to_unsigned_like(__bound_sentinel_) + std::__to_unsigned_like(-__value_))
+ : std::__to_unsigned_like(__bound_sentinel_) - std::__to_unsigned_like(__value_);
+ } else {
+ return std::__to_unsigned_like(__bound_sentinel_ - __value_);
}
- return std::__to_unsigned_like(__bound_sentinel_ - __value_);
}
};
diff --git a/libcxx/test/std/ranges/range.factories/range.iota.view/size.pass.cpp b/libcxx/test/std/ranges/range.factories/range.iota.view/size.pass.cpp
index 07092b74be87389..b894bc542be10b6 100644
--- a/libcxx/test/std/ranges/range.factories/range.iota.view/size.pass.cpp
+++ b/libcxx/test/std/ranges/range.factories/range.iota.view/size.pass.cpp
@@ -10,9 +10,10 @@
// constexpr auto size() const requires see below;
-#include <ranges>
#include <cassert>
+#include <concepts>
#include <limits>
+#include <ranges>
#include "test_macros.h"
#include "types.h"
@@ -89,6 +90,15 @@ constexpr bool test() {
assert(io.size() == 0);
}
+ // Make sure iota_view<short, short> works properly. For details,
+ // see https://github.com/llvm/llvm-project/issues/67551.
+ {
+ static_assert(std::ranges::sized_range<std::ranges::iota_view<short, short>>);
+ std::ranges::iota_view<short, short> io(10, 20);
+ std::same_as<unsigned int> auto sz = io.size();
+ assert(sz == 10);
+ }
+
return true;
}
More information about the libcxx-commits
mailing list