[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