[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:08 PST 2024
https://github.com/ZERO-N created https://github.com/llvm/llvm-project/pull/84669
None
>From 030a8841e896925e7e73562774ec745e3557181a Mon Sep 17 00:00:00 2001
From: nwh <nwh_work at foxmail.com>
Date: Sun, 10 Mar 2024 12:42:50 +0800
Subject: [PATCH] [libc++]Implement LWG4001(itoa_view should provide empty)
Signed-off-by: nwh <nwh_work at foxmail.com>
---
libcxx/docs/Status/Cxx2cIssues.csv | 2 +-
libcxx/include/__ranges/iota_view.h | 5 +
.../range.iota.view/empty.verify.cpp | 18 +++
.../range.iota.view/empty.pass.cpp | 145 ++++++++++++++++++
4 files changed, 169 insertions(+), 1 deletion(-)
create mode 100644 libcxx/test/libcxx/ranges/range.factories/range.iota.view/empty.verify.cpp
create mode 100644 libcxx/test/std/ranges/range.factories/range.iota.view/empty.pass.cpp
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;
+}
More information about the libcxx-commits
mailing list