From 98bd219618f8283474cdd0c54adcd4182b1374ae Mon Sep 17 00:00:00 2001 From: Louis Dionne Date: Fri, 29 Sep 2023 11:21:03 -0400 Subject: [PATCH] [libc++] Fix implementation of iota_view::size 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 --- libcxx/include/__ranges/iota_view.h | 15 +++++++-------- .../range.factories/range.iota.view/size.pass.cpp | 12 +++++++++++- 2 files changed, 18 insertions(+), 9 deletions(-) diff --git a/libcxx/include/__ranges/iota_view.h b/libcxx/include/__ranges/iota_view.h index f372688abfdaf..ccf0c7a8e8d50 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 07092b74be873..b894bc542be10 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 #include +#include #include +#include #include "test_macros.h" #include "types.h" @@ -89,6 +90,15 @@ constexpr bool test() { assert(io.size() == 0); } + // Make sure iota_view works properly. For details, + // see https://github.com/llvm/llvm-project/issues/67551. + { + static_assert(std::ranges::sized_range>); + std::ranges::iota_view io(10, 20); + std::same_as auto sz = io.size(); + assert(sz == 10); + } + return true; }