[libcxx-commits] [libcxx] [libc++] Fix implementation of iota_view::size (PR #67819)
via libcxx-commits
libcxx-commits at lists.llvm.org
Fri Sep 29 08:27:25 PDT 2023
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-libcxx
<details>
<summary>Changes</summary>
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
---
Full diff: https://github.com/llvm/llvm-project/pull/67819.diff
2 Files Affected:
- (modified) libcxx/include/__ranges/iota_view.h (+7-8)
- (modified) libcxx/test/std/ranges/range.factories/range.iota.view/size.pass.cpp (+11-1)
``````````diff
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;
}
``````````
</details>
https://github.com/llvm/llvm-project/pull/67819
More information about the libcxx-commits
mailing list