[libcxx-commits] [libcxx] 2cb2d76 - [libc++][ranges] Ensure range access CPOs are provided in `<iterator>` (#151745)
via libcxx-commits
libcxx-commits at lists.llvm.org
Sun Aug 17 22:26:16 PDT 2025
Author: A. Jiang
Date: 2025-08-18T13:26:13+08:00
New Revision: 2cb2d76cfa4282b4645c689b66881d9b79933f3e
URL: https://github.com/llvm/llvm-project/commit/2cb2d76cfa4282b4645c689b66881d9b79933f3e
DIFF: https://github.com/llvm/llvm-project/commit/2cb2d76cfa4282b4645c689b66881d9b79933f3e.diff
LOG: [libc++][ranges] Ensure range access CPOs are provided in `<iterator>` (#151745)
Per [range.access.general]/1, these CPOs are also provided in
`<iterator>`. Currently only some of them are provided via transitive
inclusion when only `<iterator>` is included.
Drive-by: Add an entry for `ranges::reserve_hint` in the general test
file for CPOs.
Added:
libcxx/test/std/ranges/range.access/include.iterator.pass.cpp
Modified:
libcxx/include/iterator
libcxx/test/std/library/description/conventions/customization.point.object/cpo.compile.pass.cpp
Removed:
################################################################################
diff --git a/libcxx/include/iterator b/libcxx/include/iterator
index d25fdfd2a8b33..fc8bdc5e6bcf6 100644
--- a/libcxx/include/iterator
+++ b/libcxx/include/iterator
@@ -737,6 +737,16 @@ template <class E> constexpr const E* data(initializer_list<E> il) noexcept;
# include <compare>
# include <concepts>
+// [range.access.general]
+# if _LIBCPP_STD_VER >= 20
+# include <__ranges/access.h>
+# include <__ranges/data.h>
+# include <__ranges/empty.h>
+# include <__ranges/rbegin.h>
+# include <__ranges/rend.h>
+# include <__ranges/size.h>
+# endif
+
# if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
# endif
diff --git a/libcxx/test/std/library/description/conventions/customization.point.object/cpo.compile.pass.cpp b/libcxx/test/std/library/description/conventions/customization.point.object/cpo.compile.pass.cpp
index 678483b9b2f2f..49497875dcf95 100644
--- a/libcxx/test/std/library/description/conventions/customization.point.object/cpo.compile.pass.cpp
+++ b/libcxx/test/std/library/description/conventions/customization.point.object/cpo.compile.pass.cpp
@@ -81,6 +81,10 @@ static_assert(test(std::ranges::rend, a));
static_assert(test(std::ranges::size, a));
static_assert(test(std::ranges::ssize, a));
+#if TEST_STD_VER >= 26
+// static_assert(test(std::views::reserve_hint, a));
+#endif
+
// [range.factories]
// views::empty<T> is not a CPO
static_assert(test(std::views::iota, 1));
diff --git a/libcxx/test/std/ranges/range.access/include.iterator.pass.cpp b/libcxx/test/std/ranges/range.access/include.iterator.pass.cpp
new file mode 100644
index 0000000000000..bb2cda0e4d906
--- /dev/null
+++ b/libcxx/test/std/ranges/range.access/include.iterator.pass.cpp
@@ -0,0 +1,68 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: std-at-least-c++20
+
+// [range.access.general]/1:
+// In addition to being available via inclusion of the <ranges> header, the customization point objects in
+// [range.access] are available when the header <iterator> is included.
+
+#include <iterator>
+#include <type_traits>
+
+#include "test_macros.h"
+
+template <class CPO, class... Args>
+constexpr void test(CPO& o, Args&&... args) {
+ static_assert(std::is_const_v<CPO>);
+ static_assert(std::is_class_v<CPO>);
+ static_assert(std::is_trivially_copyable_v<CPO>);
+ static_assert(std::is_trivially_default_constructible_v<CPO>);
+
+ auto p = o;
+ using T = decltype(p);
+ (void)o(args...); // to make sure the CPO can actually be used
+
+ // The type of a customization point object, ignoring cv-qualifiers, shall model semiregular.
+ static_assert(std::semiregular<T>);
+
+ // The type T of a customization point object, ignoring cv-qualifiers, shall model...
+ static_assert(std::invocable<T&, Args...>);
+ static_assert(std::invocable<const T&, Args...>);
+ static_assert(std::invocable<T, Args...>);
+ static_assert(std::invocable<const T, Args...>);
+}
+
+int a[10];
+
+constexpr bool test() {
+ test(std::ranges::begin, a);
+ test(std::ranges::end, a);
+ test(std::ranges::cbegin, a);
+ test(std::ranges::cdata, a);
+ test(std::ranges::cend, a);
+ test(std::ranges::crbegin, a);
+ test(std::ranges::crend, a);
+ test(std::ranges::data, a);
+ test(std::ranges::empty, a);
+ test(std::ranges::rbegin, a);
+ test(std::ranges::rend, a);
+ test(std::ranges::size, a);
+ test(std::ranges::ssize, a);
+
+#if TEST_STD_VER >= 26
+ // test(std::views::reserve_hint, a);
+#endif
+
+ return true;
+}
+
+int main() {
+ test();
+ static_assert(test());
+}
More information about the libcxx-commits
mailing list