[libcxx-commits] [libcxx] [libc++]Implement LWG4001(itoa_view should provide empty) (PR #84669)

via libcxx-commits libcxx-commits at lists.llvm.org
Sat Mar 9 20:45:34 PST 2024


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-libcxx

Author: None (ZERO-N)

<details>
<summary>Changes</summary>



---
Full diff: https://github.com/llvm/llvm-project/pull/84669.diff


4 Files Affected:

- (modified) libcxx/docs/Status/Cxx2cIssues.csv (+1-1) 
- (modified) libcxx/include/__ranges/iota_view.h (+5) 
- (added) libcxx/test/libcxx/ranges/range.factories/range.iota.view/empty.verify.cpp (+18) 
- (added) libcxx/test/std/ranges/range.factories/range.iota.view/empty.pass.cpp (+145) 


``````````diff
diff --git a/libcxx/docs/Status/Cxx2cIssues.csv b/libcxx/docs/Status/Cxx2cIssues.csv
index 58e995809777c1..1901c144c9319a 100644
--- a/libcxx/docs/Status/Cxx2cIssues.csv
+++ b/libcxx/docs/Status/Cxx2cIssues.csv
@@ -38,7 +38,7 @@
 "`3974 <https://wg21.link/LWG3974>`__","``mdspan::operator[]`` should not copy ``OtherIndexTypes``","Kona November 2023","","",""
 "`3987 <https://wg21.link/LWG3987>`__","Including ``<flat_foo>`` doesn't provide ``std::begin``/``end``","Kona November 2023","","","|flat_containers|"
 "`3990 <https://wg21.link/LWG3990>`__","Program-defined specializations of ``std::tuple`` and ``std::variant`` can't be properly supported","Kona November 2023","","",""
-"`4001 <https://wg21.link/LWG4001>`__","``iota_view`` should provide ``empty``","Kona November 2023","","","|ranges|"
+"`4001 <https://wg21.link/LWG4001>`__","``iota_view`` should provide ``empty``","Kona November 2023","|Complete|","19.0","|ranges|"
 "","","","","",""
 "`3343 <https://wg21.link/LWG3343>`__","Ordering of calls to ``unlock()`` and ``notify_all()`` in Effects element of ``notify_all_at_thread_exit()`` should be reversed","Not Yet Adopted","|Complete|","16.0",""
 "","","","","",""
diff --git a/libcxx/include/__ranges/iota_view.h b/libcxx/include/__ranges/iota_view.h
index c8314dd848b447..b3ecb61cb2674c 100644
--- a/libcxx/include/__ranges/iota_view.h
+++ b/libcxx/include/__ranges/iota_view.h
@@ -345,6 +345,11 @@ class iota_view : public view_interface<iota_view<_Start, _BoundSentinel>> {
     return __iterator{__bound_sentinel_};
   }
 
+  [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool empty() const
+      noexcept(noexcept(__value_ == __bound_sentinel_)) /* strengthened */ {
+    return __value_ == __bound_sentinel_;
+  }
+
   _LIBCPP_HIDE_FROM_ABI constexpr auto size() const
     requires(same_as<_Start, _BoundSentinel> && __advanceable<_Start>) ||
             (integral<_Start> && integral<_BoundSentinel>) || sized_sentinel_for<_BoundSentinel, _Start>
diff --git a/libcxx/test/libcxx/ranges/range.factories/range.iota.view/empty.verify.cpp b/libcxx/test/libcxx/ranges/range.factories/range.iota.view/empty.verify.cpp
new file mode 100644
index 00000000000000..dceb5ba55880f2
--- /dev/null
+++ b/libcxx/test/libcxx/ranges/range.factories/range.iota.view/empty.verify.cpp
@@ -0,0 +1,18 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20, c++23
+
+// constexpr bool empty() const;
+
+#include <ranges>
+
+void test() {
+  const std::ranges::iota_view<int, int> io(1, 10);
+  io.empty(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+}
diff --git a/libcxx/test/std/ranges/range.factories/range.iota.view/empty.pass.cpp b/libcxx/test/std/ranges/range.factories/range.iota.view/empty.pass.cpp
new file mode 100644
index 00000000000000..93c88acc16c504
--- /dev/null
+++ b/libcxx/test/std/ranges/range.factories/range.iota.view/empty.pass.cpp
@@ -0,0 +1,145 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20, c++23
+
+// constexpr bool empty() const;
+
+#include <cassert>
+#include <concepts>
+#include <limits>
+#include <ranges>
+
+#include "test_macros.h"
+#include "types.h"
+
+struct my_exception {};
+
+struct ThrowBound {
+  int bound;
+  constexpr bool operator==(int x) const {
+    if (x > 0) {
+#if !defined(TEST_HAS_NO_EXCEPTIONS)
+      throw my_exception{};
+#else
+      assert(false && "Exceptions are disabled");
+#endif
+    }
+    return x == bound;
+  }
+
+  constexpr bool operator==(SomeInt x) const {
+#if !defined(TEST_HAS_NO_EXCEPTIONS)
+    throw my_exception();
+#else
+    assert(false && "Exceptions are disabled");
+#endif
+    return x.value_ == bound;
+  }
+};
+
+// clang-format off
+constexpr bool test() {
+  // Both are integer like and neither less than zero.
+  {
+    {
+      const std::ranges::iota_view<int, int> io(1, 10);
+      assert(!io.empty());
+      LIBCPP_ASSERT_NOEXCEPT(io.empty());
+    }
+    {
+      const std::ranges::iota_view<int, int> io(2, 2);
+      assert(io.empty());
+      LIBCPP_ASSERT_NOEXCEPT(io.empty());
+    }
+  }
+
+  // Both are integer like and both are less than zero.
+  {
+    {
+      const std::ranges::iota_view<int, int> io(-10, -5);
+      assert(!io.empty());
+      LIBCPP_ASSERT_NOEXCEPT(io.empty());
+    }
+    {
+      const std::ranges::iota_view<int, int> io(-10, -10);
+      assert(io.empty());
+      LIBCPP_ASSERT_NOEXCEPT(io.empty());
+    }
+    {
+      const std::ranges::iota_view<int, int> io(0, 0);
+      assert(io.empty());
+      LIBCPP_ASSERT_NOEXCEPT(io.empty());
+    }
+  }
+
+  // Both are integer like and "value_" is less than zero.
+  {
+    const std::ranges::iota_view<int, int> io(-10, 10);
+    assert(!io.empty());
+    LIBCPP_ASSERT_NOEXCEPT(io.empty());
+  }
+
+  // Neither are integer like.
+  {
+    const std::ranges::iota_view<SomeInt, SomeInt> io(SomeInt(-20), SomeInt(-10));
+    assert(!io.empty());
+    LIBCPP_ASSERT_NOEXCEPT(io.empty());
+  }
+  {
+    const std::ranges::iota_view<SomeInt, SomeInt> io(SomeInt(-10), SomeInt(-10));
+    assert(io.empty());
+    LIBCPP_ASSERT_NOEXCEPT(io.empty());
+  }
+  {
+    const std::ranges::iota_view<SomeInt, SomeInt> io(SomeInt(0), SomeInt(0));
+    assert(io.empty());
+    LIBCPP_ASSERT_NOEXCEPT(io.empty());
+  }
+  {
+    const std::ranges::iota_view<SomeInt, SomeInt> io(SomeInt(10), SomeInt(20));
+    assert(!io.empty());
+    LIBCPP_ASSERT_NOEXCEPT(io.empty());
+  }
+  {
+    const std::ranges::iota_view<SomeInt, SomeInt> io(SomeInt(10), SomeInt(10));
+    assert(io.empty());
+    LIBCPP_ASSERT_NOEXCEPT(io.empty());
+  }
+
+  return true;
+}
+// clang-format on
+
+void test_throw() {
+#if !defined(TEST_HAS_NO_EXCEPTIONS)
+  try {
+    // Both are integer like and !noexcept(value_ == bound_)
+    {
+      const std::ranges::iota_view<int, ThrowBound> io(10, ThrowBound{10});
+      assert(io.empty());
+      LIBCPP_ASSERT_NOT_NOEXCEPT(io.empty());
+    }
+
+    // Neither are integer like and !noexcept(value_ == bound_)
+    {
+      const std::ranges::iota_view<SomeInt, ThrowBound> io(SomeInt{10}, ThrowBound{10});
+      assert(io.empty());
+      LIBCPP_ASSERT_NOT_NOEXCEPT(io.empty());
+    }
+  } catch (...) {
+  }
+#endif // TEST_HAS_NO_EXCEPTIONS
+}
+
+int main() {
+  test();
+  test_throw();
+  static_assert(test());
+  return 0;
+}

``````````

</details>


https://github.com/llvm/llvm-project/pull/84669


More information about the libcxx-commits mailing list