[libcxx-commits] [libcxx] [libc++] Partially implement P2846R6: `reserve_hint` (PR #206385)
via libcxx-commits
libcxx-commits at lists.llvm.org
Wed Jul 15 21:12:49 PDT 2026
https://github.com/inquisitivecrystal updated https://github.com/llvm/llvm-project/pull/206385
>From 315066dead028c4df0b8345a1517ae234fc890ff Mon Sep 17 00:00:00 2001
From: inquisitivecrystal
<22333129+inquisitivecrystal at users.noreply.github.com>
Date: Wed, 24 Jun 2026 23:31:10 -0700
Subject: [PATCH 01/29] Implement ranges::reserve_hint CPO
---
libcxx/include/__ranges/size.h | 53 ++++++++++++++++++++++++++++++++++
libcxx/include/ranges | 1 +
2 files changed, 54 insertions(+)
diff --git a/libcxx/include/__ranges/size.h b/libcxx/include/__ranges/size.h
index 5da3a6ff268e8..3dfeade03fce5 100644
--- a/libcxx/include/__ranges/size.h
+++ b/libcxx/include/__ranges/size.h
@@ -131,6 +131,59 @@ inline constexpr auto ssize = __ssize::__fn{};
} // namespace __cpo
} // namespace ranges
+# if _LIBCPP_STD_VER >= 26
+
+// [range.prim.size.hint]
+
+namespace ranges {
+namespace __reserve_hint {
+void reserve_hint() = delete;
+
+template <typename _Tp>
+concept __std_size = requires(_Tp&& __t) { ranges::size(__t); };
+
+template <typename _Tp>
+concept __member_reserve_hint = !__std_size<_Tp> && requires(_Tp&& __t) {
+ { auto(__t.reserve_hint()) } -> __integer_like;
+};
+
+template <typename _Tp>
+concept __freestanding_reserve_hint =
+ !__std_size<_Tp> && !__member_reserve_hint<_Tp> && __class_or_enum<remove_cvref_t<_Tp>> && requires(_Tp&& __t) {
+ { auto(reserve_hint(__t)) } -> __integer_like;
+ };
+
+struct __fn {
+ // `[range.prim.size.hint]`: `std::size(t)` is a valid expression
+ template <__std_size _Tp>
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr __integer_like auto operator()(_Tp&& __t) const
+ noexcept(noexcept(ranges::size(__t))) {
+ return ranges::size(__t);
+ }
+
+ // `[range.prim.size.hint]`: `auto(t.reserve_hint())` is a valid expression
+ template <__member_reserve_hint _Tp>
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr __integer_like auto operator()(_Tp&& __t) const
+ noexcept(noexcept(auto(__t.reserve_hint()))) {
+ return auto(__t.reserve_hint());
+ }
+
+ // `[range.prim.size.hint]`: `auto(reserve_hint(t))` is a valid expression
+ template <__freestanding_reserve_hint _Tp>
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr __integer_like auto operator()(_Tp&& __t) const
+ noexcept(noexcept(auto(reserve_hint(__t)))) {
+ return auto(reserve_hint(__t));
+ }
+};
+} // namespace __reserve_hint
+
+inline namespace __cpo {
+inline constexpr auto reserve_hint = __reserve_hint::__fn{};
+} // namespace __cpo
+} // namespace ranges
+
+# endif // _LIBCPP_STD_VER >= 26
+
#endif // _LIBCPP_STD_VER >= 20
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/ranges b/libcxx/include/ranges
index d82a41942327b..6448e74edb28b 100644
--- a/libcxx/include/ranges
+++ b/libcxx/include/ranges
@@ -26,6 +26,7 @@ namespace std::ranges {
inline constexpr unspecified size = unspecified;
inline constexpr unspecified ssize = unspecified;
+ inline constexpr unspecified reserve_hint = unspecified; // Since C++26
}
// [range.range], ranges
>From c8fca33b7b0d382d3eed0d39adaf2e305a31b35b Mon Sep 17 00:00:00 2001
From: inquisitivecrystal
<22333129+inquisitivecrystal at users.noreply.github.com>
Date: Wed, 24 Jun 2026 23:32:19 -0700
Subject: [PATCH 02/29] Implement approximately_sized_range concept
---
libcxx/include/__ranges/concepts.h | 14 ++++++++++++++
libcxx/include/ranges | 4 ++++
2 files changed, 18 insertions(+)
diff --git a/libcxx/include/__ranges/concepts.h b/libcxx/include/__ranges/concepts.h
index bf75fe8a6fef4..e7cfc94506120 100644
--- a/libcxx/include/__ranges/concepts.h
+++ b/libcxx/include/__ranges/concepts.h
@@ -80,10 +80,24 @@ using range_rvalue_reference_t = iter_rvalue_reference_t<iterator_t<_Rp>>;
template <range _Rp>
using range_common_reference_t = iter_common_reference_t<iterator_t<_Rp>>;
+# if _LIBCPP_STD_VER >= 26
+
+// [range.approximately.sized]
+template <class _Tp>
+concept approximately_sized_range = range<_Tp> && requires(_Tp& __t) { ranges::reserve_hint(__t); };
+
+// [range.sized]
+template <class _Tp>
+concept sized_range = approximately_sized_range<_Tp> && requires(_Tp& __t) { ranges::size(__t); };
+
+# else // _LIBCPP_STD_VER < 26
+
// [range.sized]
template <class _Tp>
concept sized_range = range<_Tp> && requires(_Tp& __t) { ranges::size(__t); };
+# endif
+
template <sized_range _Rp>
using range_size_t = decltype(ranges::size(std::declval<_Rp&>()));
diff --git a/libcxx/include/ranges b/libcxx/include/ranges
index 6448e74edb28b..8e0d464bca6ea 100644
--- a/libcxx/include/ranges
+++ b/libcxx/include/ranges
@@ -53,6 +53,10 @@ namespace std::ranges {
template <range R>
using range_common_reference_t = iter_common_reference_t<iterator_t<R>>;
+ // [range.approximately.sized], approximately sized ranges
+ template<class T>
+ concept approximately_sized_range = ...;
+
// [range.sized], sized ranges
template<class>
inline constexpr bool disable_sized_range = false;
>From f96ffb52ebc591564db86d673ea708a6f873f712 Mon Sep 17 00:00:00 2001
From: inquisitivecrystal
<22333129+inquisitivecrystal at users.noreply.github.com>
Date: Wed, 24 Jun 2026 23:32:53 -0700
Subject: [PATCH 03/29] Implement reserve_hint for views
---
.../__ranges/adjacent_transform_view.h | 16 +++++++++++++
libcxx/include/__ranges/adjacent_view.h | 24 +++++++++++++++++++
libcxx/include/__ranges/as_rvalue_view.h | 16 +++++++++++++
libcxx/include/__ranges/common_view.h | 16 +++++++++++++
libcxx/include/__ranges/drop_view.h | 18 ++++++++++++++
libcxx/include/__ranges/elements_view.h | 16 +++++++++++++
libcxx/include/__ranges/enumerate_view.h | 16 +++++++++++++
libcxx/include/__ranges/owning_view.h | 16 +++++++++++++
libcxx/include/__ranges/ref_view.h | 9 +++++++
libcxx/include/__ranges/reverse_view.h | 16 +++++++++++++
libcxx/include/__ranges/stride_view.h | 19 +++++++++++++++
libcxx/include/__ranges/take_view.h | 20 ++++++++++++++++
libcxx/include/__ranges/transform_view.h | 16 +++++++++++++
13 files changed, 218 insertions(+)
diff --git a/libcxx/include/__ranges/adjacent_transform_view.h b/libcxx/include/__ranges/adjacent_transform_view.h
index 4863d074482dc..e7e05539e8aaa 100644
--- a/libcxx/include/__ranges/adjacent_transform_view.h
+++ b/libcxx/include/__ranges/adjacent_transform_view.h
@@ -149,6 +149,22 @@ class adjacent_transform_view : public view_interface<adjacent_transform_view<_V
{
return __inner_.size();
}
+
+# if _LIBCPP_STD_VER >= 26
+
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto reserve_hint()
+ requires approximately_sized_range<_InnerView>
+ {
+ return __inner_.reserve_hint();
+ }
+
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto reserve_hint() const
+ requires approximately_sized_range<const _InnerView>
+ {
+ return __inner_.reserve_hint();
+ }
+
+# endif //_LIBCPP_STD_VER >= 26
};
template <forward_range _View, move_constructible _Fn, size_t _Np>
diff --git a/libcxx/include/__ranges/adjacent_view.h b/libcxx/include/__ranges/adjacent_view.h
index 40474b85c794f..27b116e30eee9 100644
--- a/libcxx/include/__ranges/adjacent_view.h
+++ b/libcxx/include/__ranges/adjacent_view.h
@@ -139,6 +139,30 @@ class adjacent_view : public view_interface<adjacent_view<_View, _Np>> {
__sz -= std::min<_CT>(__sz, _Np - 1);
return static_cast<_ST>(__sz);
}
+
+# if _LIBCPP_STD_VER >= 26
+
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto reserve_hint()
+ requires approximately_sized_range<_View>
+ {
+ using _ST = decltype(ranges::reserve_hint(__base_));
+ using _CT = common_type_t<_ST, size_t>;
+ auto __sz = static_cast<_CT>(ranges::reserve_hint(__base_));
+ __sz -= std::min<_CT>(__sz, _Np - 1);
+ return static_cast<_ST>(__sz);
+ }
+
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto reserve_hint() const
+ requires approximately_sized_range<const _View>
+ {
+ using _ST = decltype(ranges::reserve_hint(__base_));
+ using _CT = common_type_t<_ST, size_t>;
+ auto __sz = static_cast<_CT>(ranges::reserve_hint(__base_));
+ __sz -= std::min<_CT>(__sz, _Np - 1);
+ return static_cast<_ST>(__sz);
+ }
+
+# endif //_LIBCPP_STD_VER >= 26
};
struct __adjacent_view_iter_access {
diff --git a/libcxx/include/__ranges/as_rvalue_view.h b/libcxx/include/__ranges/as_rvalue_view.h
index a553f39998e0e..705cf559a7ee0 100644
--- a/libcxx/include/__ranges/as_rvalue_view.h
+++ b/libcxx/include/__ranges/as_rvalue_view.h
@@ -99,6 +99,22 @@ class as_rvalue_view : public view_interface<as_rvalue_view<_View>> {
{
return ranges::size(__base_);
}
+
+# if _LIBCPP_STD_VER >= 26
+
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto reserve_hint()
+ requires approximately_sized_range<_View>
+ {
+ return ranges::reserve_hint(__base_);
+ }
+
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto reserve_hint() const
+ requires approximately_sized_range<const _View>
+ {
+ return ranges::reserve_hint(__base_);
+ }
+
+# endif //_LIBCPP_STD_VER >= 26
};
template <class _Range>
diff --git a/libcxx/include/__ranges/common_view.h b/libcxx/include/__ranges/common_view.h
index eec1045c8a758..4f1dfbf5d9ac2 100644
--- a/libcxx/include/__ranges/common_view.h
+++ b/libcxx/include/__ranges/common_view.h
@@ -101,6 +101,22 @@ class common_view : public view_interface<common_view<_View>> {
{
return ranges::size(__base_);
}
+
+# if _LIBCPP_STD_VER >= 26
+
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto reserve_hint()
+ requires approximately_sized_range<_View>
+ {
+ return ranges::reserve_hint(__base_);
+ }
+
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto reserve_hint() const
+ requires approximately_sized_range<const _View>
+ {
+ return ranges::reserve_hint(__base_);
+ }
+
+# endif //_LIBCPP_STD_VER >= 26
};
template <class _Range>
diff --git a/libcxx/include/__ranges/drop_view.h b/libcxx/include/__ranges/drop_view.h
index e3754e64d536f..9cae5c1c30276 100644
--- a/libcxx/include/__ranges/drop_view.h
+++ b/libcxx/include/__ranges/drop_view.h
@@ -139,6 +139,24 @@ class drop_view : public view_interface<drop_view<_View>> {
{
return __size(*this);
}
+
+# if _LIBCPP_STD_VER >= 26
+
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto reserve_hint()
+ requires approximately_sized_range<_View>
+ {
+ const auto __s = static_cast<range_difference_t<_View>>(ranges::reserve_hint(__base_));
+ return __to_unsigned_like(__s < __count_ ? 0 : __s - __count_);
+ }
+
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto reserve_hint() const
+ requires approximately_sized_range<const _View>
+ {
+ const auto __s = static_cast<range_difference_t<const _View>>(ranges::reserve_hint(__base_));
+ return __to_unsigned_like(__s < __count_ ? 0 : __s - __count_);
+ }
+
+# endif //_LIBCPP_STD_VER >= 26
};
template <class _Range>
diff --git a/libcxx/include/__ranges/elements_view.h b/libcxx/include/__ranges/elements_view.h
index b1419f2a1dd91..9ce87e6814dbe 100644
--- a/libcxx/include/__ranges/elements_view.h
+++ b/libcxx/include/__ranges/elements_view.h
@@ -133,6 +133,22 @@ class elements_view : public view_interface<elements_view<_View, _Np>> {
return ranges::size(__base_);
}
+# if _LIBCPP_STD_VER >= 26
+
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto reserve_hint()
+ requires approximately_sized_range<_View>
+ {
+ return ranges::reserve_hint(__base_);
+ }
+
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto reserve_hint() const
+ requires approximately_sized_range<const _View>
+ {
+ return ranges::reserve_hint(__base_);
+ }
+
+# endif //_LIBCPP_STD_VER >= 26
+
private:
_LIBCPP_NO_UNIQUE_ADDRESS _View __base_ = _View();
};
diff --git a/libcxx/include/__ranges/enumerate_view.h b/libcxx/include/__ranges/enumerate_view.h
index bb7696897af00..1a67a23e864d7 100644
--- a/libcxx/include/__ranges/enumerate_view.h
+++ b/libcxx/include/__ranges/enumerate_view.h
@@ -115,6 +115,22 @@ class enumerate_view : public view_interface<enumerate_view<_View>> {
return __base_;
}
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr _View base() && { return std::move(__base_); }
+
+# if _LIBCPP_STD_VER >= 26
+
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto reserve_hint()
+ requires approximately_sized_range<_View>
+ {
+ return ranges::reserve_hint(__base_);
+ }
+
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto reserve_hint() const
+ requires approximately_sized_range<const _View>
+ {
+ return ranges::reserve_hint(__base_);
+ }
+
+# endif //_LIBCPP_STD_VER >= 26
};
template <class _Range>
diff --git a/libcxx/include/__ranges/owning_view.h b/libcxx/include/__ranges/owning_view.h
index 1ab81afee774a..b1e8415c3a477 100644
--- a/libcxx/include/__ranges/owning_view.h
+++ b/libcxx/include/__ranges/owning_view.h
@@ -99,6 +99,22 @@ class owning_view : public view_interface<owning_view<_Rp>> {
{
return ranges::data(__r_);
}
+
+# if _LIBCPP_STD_VER >= 26
+
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto reserve_hint()
+ requires approximately_sized_range<_Rp>
+ {
+ return ranges::reserve_hint(__r_);
+ }
+
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto reserve_hint() const
+ requires approximately_sized_range<const _Rp>
+ {
+ return ranges::reserve_hint(__r_);
+ }
+
+# endif //_LIBCPP_STD_VER >= 26
};
_LIBCPP_CTAD_SUPPORTED_FOR_TYPE(owning_view);
diff --git a/libcxx/include/__ranges/ref_view.h b/libcxx/include/__ranges/ref_view.h
index 109a10cec299e..34f129ace54e7 100644
--- a/libcxx/include/__ranges/ref_view.h
+++ b/libcxx/include/__ranges/ref_view.h
@@ -73,6 +73,15 @@ class ref_view : public view_interface<ref_view<_Range>> {
{
return ranges::data(*__range_);
}
+
+# if _LIBCPP_STD_VER >= 26
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto reserve_hint() const
+ requires approximately_sized_range<_Range>
+ {
+ return ranges::reserve_hint(*__range_);
+ }
+
+# endif //_LIBCPP_STD_VER >= 26
};
template <class _Range>
diff --git a/libcxx/include/__ranges/reverse_view.h b/libcxx/include/__ranges/reverse_view.h
index b016cc231f2b5..fc8e609705661 100644
--- a/libcxx/include/__ranges/reverse_view.h
+++ b/libcxx/include/__ranges/reverse_view.h
@@ -111,6 +111,22 @@ class reverse_view : public view_interface<reverse_view<_View>> {
{
return ranges::size(__base_);
}
+
+# if _LIBCPP_STD_VER >= 26
+
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto reserve_hint()
+ requires approximately_sized_range<_View>
+ {
+ return ranges::reserve_hint(__base_);
+ }
+
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto reserve_hint() const
+ requires approximately_sized_range<const _View>
+ {
+ return ranges::reserve_hint(__base_);
+ }
+
+# endif //_LIBCPP_STD_VER >= 26
};
template <class _Range>
diff --git a/libcxx/include/__ranges/stride_view.h b/libcxx/include/__ranges/stride_view.h
index 780bb25743c15..d4b7cce06eb91 100644
--- a/libcxx/include/__ranges/stride_view.h
+++ b/libcxx/include/__ranges/stride_view.h
@@ -30,6 +30,7 @@
#include <__ranges/concepts.h>
#include <__ranges/enable_borrowed_range.h>
#include <__ranges/range_adaptor.h>
+#include <__ranges/size.h>
#include <__ranges/view_interface.h>
#include <__type_traits/make_unsigned.h>
@@ -129,6 +130,24 @@ class stride_view : public view_interface<stride_view<_View>> {
{
return std::__to_unsigned_like(ranges::__div_ceil(ranges::distance(__base_), __stride_));
}
+
+# if _LIBCPP_STD_VER >= 26
+
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto reserve_hint()
+ requires approximately_sized_range<_View>
+ {
+ auto __s = static_cast<range_difference_t<decltype((__base_))>>(ranges::reserve_hint(__base_));
+ return __to_unsigned_like(__div_ceil(__s, __stride_));
+ }
+
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto reserve_hint() const
+ requires approximately_sized_range<const _View>
+ {
+ auto __s = static_cast<range_difference_t<decltype((__base_))>>(ranges::reserve_hint(__base_));
+ return __to_unsigned_like(__div_ceil(__s, __stride_));
+ }
+
+# endif //_LIBCPP_STD_VER >= 26
}; // class stride_view
template <class _Range>
diff --git a/libcxx/include/__ranges/take_view.h b/libcxx/include/__ranges/take_view.h
index 999f686537f2c..f97a88ccf9297 100644
--- a/libcxx/include/__ranges/take_view.h
+++ b/libcxx/include/__ranges/take_view.h
@@ -155,6 +155,26 @@ class take_view : public view_interface<take_view<_View>> {
auto __n = ranges::size(__base_);
return ranges::min(__n, static_cast<decltype(__n)>(__count_));
}
+
+# if _LIBCPP_STD_VER >= 26
+
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto reserve_hint() {
+ if constexpr (approximately_sized_range<_View>) {
+ auto __n = static_cast<range_difference_t<_View>>(ranges::reserve_hint(__base_));
+ return __to_unsigned_like(ranges::min(__n, __count_));
+ }
+ return __to_unsigned_like(__count_);
+ }
+
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto reserve_hint() const {
+ if constexpr (approximately_sized_range<const _View>) {
+ auto __n = static_cast<range_difference_t<const _View>>(ranges::reserve_hint(__base_));
+ return __to_unsigned_like(ranges::min(__n, __count_));
+ }
+ return __to_unsigned_like(__count_);
+ }
+
+# endif //_LIBCPP_STD_VER >= 26
};
template <view _View>
diff --git a/libcxx/include/__ranges/transform_view.h b/libcxx/include/__ranges/transform_view.h
index 1484be006e841..c26b7ea362a8d 100644
--- a/libcxx/include/__ranges/transform_view.h
+++ b/libcxx/include/__ranges/transform_view.h
@@ -139,6 +139,22 @@ class _LIBCPP_ABI_LLVM18_NO_UNIQUE_ADDRESS transform_view : public view_interfac
{
return ranges::size(__base_);
}
+
+# if _LIBCPP_STD_VER >= 26
+
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto reserve_hint()
+ requires approximately_sized_range<_View>
+ {
+ return ranges::reserve_hint(__base_);
+ }
+
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto reserve_hint() const
+ requires approximately_sized_range<const _View>
+ {
+ return ranges::reserve_hint(__base_);
+ }
+
+# endif //_LIBCPP_STD_VER >= 26
};
template <class _Range, class _Fn>
>From 04c8de26c3707ebea7247894855612f120acb1c0 Mon Sep 17 00:00:00 2001
From: inquisitivecrystal
<22333129+inquisitivecrystal at users.noreply.github.com>
Date: Wed, 24 Jun 2026 23:35:18 -0700
Subject: [PATCH 04/29] Implement reserve_hint for concat_view (LWG4553)
---
libcxx/include/__ranges/concat_view.h | 22 ++++++++++++++++++++++
1 file changed, 22 insertions(+)
diff --git a/libcxx/include/__ranges/concat_view.h b/libcxx/include/__ranges/concat_view.h
index 3bbe9db12e0f8..33d269b9fd09a 100644
--- a/libcxx/include/__ranges/concat_view.h
+++ b/libcxx/include/__ranges/concat_view.h
@@ -176,6 +176,28 @@ class concat_view : public view_interface<concat_view<_Views...>> {
[](auto... __sizes) { return (make_unsigned_t<common_type_t<decltype(__sizes)...>>(__sizes) + ...); },
std::__tuple_transform(ranges::size, __views_));
}
+
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto reserve_hint()
+ requires(approximately_sized_range<_Views> && ...)
+ {
+ return apply(
+ [](auto... __sizes) static {
+ using _CT = make_unsigned_t<common_type_t<decltype(__sizes)...>>;
+ return (_CT(__sizes) + ...);
+ },
+ std::__tuple_transform(ranges::reserve_hint, __views_));
+ }
+
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto reserve_hint() const
+ requires(approximately_sized_range<const _Views> && ...)
+ {
+ return apply(
+ [](auto... __sizes) static {
+ using _CT = make_unsigned_t<common_type_t<decltype(__sizes)...>>;
+ return (_CT(__sizes) + ...);
+ },
+ std::__tuple_transform(ranges::reserve_hint, __views_));
+ }
};
template <class... _Views>
>From 5938495f415e0b8ecf51efe47d5e9189f5968a19 Mon Sep 17 00:00:00 2001
From: inquisitivecrystal
<22333129+inquisitivecrystal at users.noreply.github.com>
Date: Thu, 28 May 2026 01:02:44 -0700
Subject: [PATCH 05/29] Add new items to module
---
libcxx/modules/std/ranges.inc | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/libcxx/modules/std/ranges.inc b/libcxx/modules/std/ranges.inc
index 876942bdffbf5..9e87e2653908a 100644
--- a/libcxx/modules/std/ranges.inc
+++ b/libcxx/modules/std/ranges.inc
@@ -25,6 +25,10 @@ export namespace std {
using std::ranges::__cpo::empty;
using std::ranges::__cpo::size;
using std::ranges::__cpo::ssize;
+
+#if _LIBCPP_STD_VER >= 26
+ using std::ranges::__cpo::reserve_hint;
+#endif
} // namespace __cpo
// [range.range], ranges
@@ -50,6 +54,11 @@ export namespace std {
using std::ranges::disable_sized_range;
using std::ranges::sized_range;
+#if _LIBCPP_STD_VER >= 26
+ // [range.approximately.sized], approximately sized ranges
+ using std::ranges::approximately_sized_range;
+#endif
+
// [range.view], views
using std::ranges::enable_view;
using std::ranges::view;
>From e9a3212c848a9d2a47e1634869b016b488481ee0 Mon Sep 17 00:00:00 2001
From: inquisitivecrystal
<22333129+inquisitivecrystal at users.noreply.github.com>
Date: Thu, 25 Jun 2026 00:12:01 -0700
Subject: [PATCH 06/29] Test reserve_hint
---
.../ranges/range.access/reserve_hint.pass.cpp | 100 ++++++++++++++
.../range.access/reserve_hint.verify.cpp | 21 +++
.../reserve_hint.pass.cpp | 130 ++++++++++++++++++
.../range.adjacent/reserve_hint.pass.cpp | 108 +++++++++++++++
.../range.owning.view/reserve_hint.pass.cpp | 86 ++++++++++++
.../range.ref.view/range.ref.view.pass.cpp | 29 ++++
.../range.as.rvalue/reserve_hint.pass.cpp | 90 ++++++++++++
.../range.common.view/reserve_hint.pass.cpp | 63 +++++++++
.../range.adaptors/range.common.view/types.h | 31 +++++
.../range.concat/reserve_hint.pass.cpp | 107 ++++++++++++++
.../range.drop/reserve_hint.pass.cpp | 59 ++++++++
.../ranges/range.adaptors/range.drop/types.h | 14 ++
.../range.elements/reserve_hint.pass.cpp | 90 ++++++++++++
.../range.enumerate/reserve_hint.pass.cpp | 82 +++++++++++
.../range.reverse/reserve_hint.pass.cpp | 89 ++++++++++++
.../range.stride.view/reserve_hint.pass.cpp | 99 +++++++++++++
.../range.adaptors/range.stride.view/types.h | 19 ++-
.../range.take/reserve_hint.pass.cpp | 87 ++++++++++++
.../ranges/range.adaptors/range.take/types.h | 14 ++
.../range.transform/reserve_hint.pass.cpp | 44 ++++++
.../range.adaptors/range.transform/types.h | 33 +++++
21 files changed, 1391 insertions(+), 4 deletions(-)
create mode 100644 libcxx/test/std/ranges/range.access/reserve_hint.pass.cpp
create mode 100644 libcxx/test/std/ranges/range.access/reserve_hint.verify.cpp
create mode 100644 libcxx/test/std/ranges/range.adaptors/range.adjacent.transform/reserve_hint.pass.cpp
create mode 100644 libcxx/test/std/ranges/range.adaptors/range.adjacent/reserve_hint.pass.cpp
create mode 100644 libcxx/test/std/ranges/range.adaptors/range.all/range.owning.view/reserve_hint.pass.cpp
create mode 100644 libcxx/test/std/ranges/range.adaptors/range.as.rvalue/reserve_hint.pass.cpp
create mode 100644 libcxx/test/std/ranges/range.adaptors/range.common.view/reserve_hint.pass.cpp
create mode 100644 libcxx/test/std/ranges/range.adaptors/range.concat/reserve_hint.pass.cpp
create mode 100644 libcxx/test/std/ranges/range.adaptors/range.drop/reserve_hint.pass.cpp
create mode 100644 libcxx/test/std/ranges/range.adaptors/range.elements/reserve_hint.pass.cpp
create mode 100644 libcxx/test/std/ranges/range.adaptors/range.enumerate/reserve_hint.pass.cpp
create mode 100644 libcxx/test/std/ranges/range.adaptors/range.reverse/reserve_hint.pass.cpp
create mode 100644 libcxx/test/std/ranges/range.adaptors/range.stride.view/reserve_hint.pass.cpp
create mode 100644 libcxx/test/std/ranges/range.adaptors/range.take/reserve_hint.pass.cpp
create mode 100644 libcxx/test/std/ranges/range.adaptors/range.transform/reserve_hint.pass.cpp
diff --git a/libcxx/test/std/ranges/range.access/reserve_hint.pass.cpp b/libcxx/test/std/ranges/range.access/reserve_hint.pass.cpp
new file mode 100644
index 0000000000000..4e5f11fba445e
--- /dev/null
+++ b/libcxx/test/std/ranges/range.access/reserve_hint.pass.cpp
@@ -0,0 +1,100 @@
+//===----------------------------------------------------------------------===//
+//
+// 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++26
+
+// std::ranges::reserve_hint
+
+#include <cassert>
+#include <ranges>
+
+#include "test_macros.h"
+#include "test_iterators.h"
+
+using RangeReserveHintT = decltype(std::ranges::reserve_hint);
+
+struct Incomplete;
+static_assert(!std::is_invocable_v<RangeReserveHintT, Incomplete[]>);
+static_assert(!std::is_invocable_v<RangeReserveHintT, Incomplete(&)[]>);
+static_assert(!std::is_invocable_v<RangeReserveHintT, Incomplete(&&)[]>);
+
+extern int bounded_array[42];
+
+struct SizedSentinelRange {
+ int data_[42] = {};
+ constexpr int* begin() { return data_; }
+ constexpr auto end() { return sized_sentinel<int*>(data_ + 42); }
+};
+
+struct HasSizeMember {
+ constexpr std::size_t size() { return 42; }
+};
+
+struct HasSizeFunction {
+ friend constexpr std::size_t size(HasSizeFunction _) { return 42; }
+};
+
+struct HasReserveHintMember {
+ constexpr std::size_t reserve_hint() { return 42; }
+};
+
+struct HasReserveHintFunction {
+ friend constexpr std::size_t reserve_hint(HasReserveHintFunction _) { return 42; }
+};
+
+struct HasReserveHintMemberBool {
+ constexpr bool reserve_hint() { return false; }
+};
+
+static_assert(!std::is_invocable_v<RangeReserveHintT, HasReserveHintMemberBool>);
+
+static_assert(std::ranges::reserve_hint(bounded_array) == 42);
+ASSERT_SAME_TYPE(decltype(std::ranges::reserve_hint(bounded_array)), std::size_t);
+
+bool constexpr test_sized_sentinel_range() {
+ SizedSentinelRange b;
+ assert(std::ranges::reserve_hint(b) == 42);
+ ASSERT_SAME_TYPE(decltype(std::ranges::reserve_hint(b)), std::size_t);
+
+ return true;
+}
+
+static_assert(std::ranges::reserve_hint(HasSizeMember{}) == 42);
+ASSERT_SAME_TYPE(decltype(std::ranges::reserve_hint(HasSizeMember{})), std::size_t);
+
+static_assert(std::ranges::reserve_hint(HasSizeFunction{}) == 42);
+ASSERT_SAME_TYPE(decltype(std::ranges::reserve_hint(HasSizeFunction{})), std::size_t);
+
+static_assert(std::ranges::reserve_hint(HasReserveHintMember{}) == 42);
+ASSERT_SAME_TYPE(decltype(std::ranges::reserve_hint(HasReserveHintMember{})), std::size_t);
+
+static_assert(std::ranges::reserve_hint(HasReserveHintFunction{}) == 42);
+ASSERT_SAME_TYPE(decltype(std::ranges::reserve_hint(HasReserveHintFunction{})), std::size_t);
+
+// test that the order of preference is ranges::size, then member reserve_hint,
+// then function reserve_hint
+struct HasSizeAndReserveHint {
+ constexpr std::size_t size() { return 42; }
+ constexpr std::size_t reserve_hint() { return 0; }
+ friend constexpr std::size_t reserve_hint(HasSizeAndReserveHint _) { return 0; }
+};
+
+struct HasReserveHintMemberAndFunction {
+ constexpr std::size_t reserve_hint() { return 42; }
+ friend constexpr std::size_t reserve_hint(HasReserveHintMemberAndFunction _) { return 0; }
+};
+
+static_assert(std::ranges::reserve_hint(HasSizeAndReserveHint{}) == 42);
+static_assert(std::ranges::reserve_hint(HasReserveHintMemberAndFunction{}) == 42);
+
+int main(int, char**) {
+ test_sized_sentinel_range();
+ static_assert(test_sized_sentinel_range());
+
+ return 0;
+}
diff --git a/libcxx/test/std/ranges/range.access/reserve_hint.verify.cpp b/libcxx/test/std/ranges/range.access/reserve_hint.verify.cpp
new file mode 100644
index 0000000000000..760620c6bd271
--- /dev/null
+++ b/libcxx/test/std/ranges/range.access/reserve_hint.verify.cpp
@@ -0,0 +1,21 @@
+//===----------------------------------------------------------------------===//
+//
+// 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++26
+
+// std::ranges::reserve_hint
+
+#include <ranges>
+
+extern int arr[];
+
+// Verify that for an array of unknown bound `ranges::reserve_hint` is ill-formed.
+void test() {
+ std::ranges::reserve_hint(arr);
+ // expected-error-re at -1 {{{{no matching function for call to object of type 'const (std::ranges::)?__reserve_hint::__fn'}}}}
+}
diff --git a/libcxx/test/std/ranges/range.adaptors/range.adjacent.transform/reserve_hint.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.adjacent.transform/reserve_hint.pass.cpp
new file mode 100644
index 0000000000000..291810bfecf7d
--- /dev/null
+++ b/libcxx/test/std/ranges/range.adaptors/range.adjacent.transform/reserve_hint.pass.cpp
@@ -0,0 +1,130 @@
+//===----------------------------------------------------------------------===//
+//
+// 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++26
+
+// constexpr auto reserve_hint()
+// requires approximately_sized_range<InnerView>;
+// constexpr auto reserve_hint() const
+// requires approximately_sized_range<const InnerView>;
+
+#include <cassert>
+#include <ranges>
+#include <utility>
+
+#include "test_macros.h"
+#include "test_iterators.h"
+#include "helpers.h"
+
+int buffer[] = {1, 2, 3, 4, 5, 6, 7, 8, 9};
+
+struct NonApproximatelySizedView : std::ranges::view_base {
+ using iterator = forward_iterator<int*>;
+ iterator begin() const;
+ iterator end() const;
+};
+
+struct ApproximatelySizedView : std::ranges::view_base {
+ unsigned int size_;
+ constexpr explicit ApproximatelySizedView(unsigned int size) : size_(size) {}
+ constexpr auto begin() const { return forward_iterator<int*>(buffer); }
+ constexpr auto end() const { return forward_iterator<int*>(buffer + size_); }
+ constexpr unsigned int reserve_hint() const { return size_; }
+};
+
+struct ApproximatelySizedNotConstView : std::ranges::view_base {
+ unsigned int size_;
+ constexpr explicit ApproximatelySizedNotConstView(unsigned int size) : size_(size) {}
+ constexpr auto begin() const { return forward_iterator<int*>(buffer); }
+ constexpr auto end() const { return forward_iterator<int*>(buffer + size_); }
+ constexpr unsigned int reserve_hint() { return size_; }
+};
+
+// Test with different values of N for an approximately sized view
+template <std::size_t N, class Fn>
+constexpr void test_approx_sized_view() {
+ std::ranges::adjacent_transform_view<ApproximatelySizedView, Fn, N> v(ApproximatelySizedView(5), Fn{});
+ static_assert(std::ranges::approximately_sized_range<decltype(v)>);
+ static_assert(std::ranges::approximately_sized_range<const decltype(v)>);
+
+ auto expected_hint = 5 - (N - 1);
+ assert(v.reserve_hint() == expected_hint);
+ assert(std::as_const(v).reserve_hint() == expected_hint);
+}
+
+// Test with different values of N for a non-const approximately sized view
+template <std::size_t N, class Fn>
+constexpr void test_nonconst_approx_sized() {
+ // non-const-only reserve_hint
+ std::ranges::adjacent_transform_view<ApproximatelySizedNotConstView, Fn, N> v(
+ ApproximatelySizedNotConstView(5), Fn{});
+ static_assert(std::ranges::approximately_sized_range<decltype(v)>);
+ static_assert(!std::ranges::approximately_sized_range<const decltype(v)>);
+
+ auto expected_hint = 5 - (N - 1);
+ assert(v.reserve_hint() == expected_hint);
+}
+
+template <std::size_t N, class Fn>
+constexpr void test_empty_range() {
+ std::ranges::adjacent_transform_view<ApproximatelySizedView, Fn, N> v(ApproximatelySizedView(0), Fn{});
+ static_assert(std::ranges::approximately_sized_range<decltype(v)>);
+ static_assert(std::ranges::approximately_sized_range<const decltype(v)>);
+
+ assert(v.reserve_hint() == 0);
+ assert(std::as_const(v).reserve_hint() == 0);
+}
+
+template <std::size_t N, class Fn>
+constexpr void test_N_greater_than_size() {
+ if constexpr (N > 2) {
+ std::ranges::adjacent_transform_view<ApproximatelySizedView, Fn, N> v(ApproximatelySizedView(2), Fn{});
+ static_assert(std::ranges::approximately_sized_range<decltype(v)>);
+ static_assert(std::ranges::approximately_sized_range<const decltype(v)>);
+ assert(v.reserve_hint() == 0);
+ assert(std::as_const(v).reserve_hint() == 0);
+ }
+}
+
+template <std::size_t N, class Fn>
+constexpr void test() {
+ test_approx_sized_view<N, Fn>();
+ test_nonconst_approx_sized<N, Fn>();
+ test_empty_range<N, Fn>();
+ test_N_greater_than_size<N, Fn>();
+}
+
+template <std::size_t N>
+constexpr void test() {
+ test<N, MakeTuple>();
+ test<N, Tie>();
+ test<N, GetFirst>();
+ test<N, Multiply>();
+}
+
+constexpr bool test() {
+ // non-approximately-sized range has no reserve_hint
+ static_assert(!std::ranges::approximately_sized_range<
+ std::ranges::adjacent_transform_view<NonApproximatelySizedView, Multiply, 2>>);
+ static_assert(!std::ranges::approximately_sized_range<
+ const std::ranges::adjacent_transform_view<NonApproximatelySizedView, Multiply, 2>>);
+
+ test<1>();
+ test<2>();
+ test<3>();
+ test<5>();
+
+ return true;
+}
+
+int main(int, char**) {
+ test();
+ static_assert(test());
+
+ return 0;
+}
diff --git a/libcxx/test/std/ranges/range.adaptors/range.adjacent/reserve_hint.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.adjacent/reserve_hint.pass.cpp
new file mode 100644
index 0000000000000..d55e90112fad3
--- /dev/null
+++ b/libcxx/test/std/ranges/range.adaptors/range.adjacent/reserve_hint.pass.cpp
@@ -0,0 +1,108 @@
+//===----------------------------------------------------------------------===//
+//
+// 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++26
+
+// constexpr auto reserve_hint()
+// requires approximately_sized_range<View>;
+// constexpr auto reserve_hint() const
+// requires approximately_sized_range<const View>;
+
+#include <cassert>
+#include <ranges>
+#include <utility>
+
+#include "test_macros.h"
+#include "test_iterators.h"
+
+int buffer[] = {1, 2, 3, 4, 5, 6, 7, 8, 9};
+
+struct NonApproximatelySizedView : std::ranges::view_base {
+ using iterator = forward_iterator<int*>;
+ iterator begin() const;
+ iterator end() const;
+};
+
+struct ApproximatelySizedView : std::ranges::view_base {
+ unsigned int size_;
+ constexpr explicit ApproximatelySizedView(unsigned int size) : size_(size) {}
+ constexpr auto begin() const { return forward_iterator<int*>(buffer); }
+ constexpr auto end() const { return forward_iterator<int*>(buffer + size_); }
+ constexpr unsigned int reserve_hint() const { return size_; }
+};
+
+struct ApproximatelySizedNotConstView : std::ranges::view_base {
+ unsigned int size_;
+ constexpr explicit ApproximatelySizedNotConstView(unsigned int size) : size_(size) {}
+ constexpr auto begin() const { return forward_iterator<int*>(buffer); }
+ constexpr auto end() const { return forward_iterator<int*>(buffer + size_); }
+ constexpr unsigned int reserve_hint() { return size_; }
+};
+
+template <std::size_t N>
+constexpr void test() {
+ {
+ // Test with different values of N for an approximately sized view
+ std::ranges::adjacent_view<ApproximatelySizedView, N> v(ApproximatelySizedView(5));
+ static_assert(std::ranges::approximately_sized_range<decltype(v)>);
+ static_assert(std::ranges::approximately_sized_range<const decltype(v)>);
+
+ auto expected_hint = 5 - (N - 1);
+ assert(v.reserve_hint() == expected_hint);
+ assert(std::as_const(v).reserve_hint() == expected_hint);
+ }
+ {
+ // Test with different values of N for a non-const approximately sized view
+ std::ranges::adjacent_view<ApproximatelySizedNotConstView, N> v(ApproximatelySizedNotConstView(5));
+ static_assert(std::ranges::approximately_sized_range<decltype(v)>);
+ static_assert(!std::ranges::approximately_sized_range<const decltype(v)>);
+
+ auto expected_hint = 5 - (N - 1);
+ assert(v.reserve_hint() == expected_hint);
+ }
+ {
+ // empty range
+ std::ranges::adjacent_view<ApproximatelySizedView, N> v(ApproximatelySizedView(0));
+ static_assert(std::ranges::approximately_sized_range<decltype(v)>);
+ static_assert(std::ranges::approximately_sized_range<const decltype(v)>);
+
+ assert(v.reserve_hint() == 0);
+ assert(std::as_const(v).reserve_hint() == 0);
+ }
+ {
+ // N greater than range size
+ if constexpr (N > 2) {
+ std::ranges::adjacent_view<ApproximatelySizedView, N> v(ApproximatelySizedView(2));
+ static_assert(std::ranges::approximately_sized_range<decltype(v)>);
+ static_assert(std::ranges::approximately_sized_range<const decltype(v)>);
+ assert(v.reserve_hint() == 0);
+ assert(std::as_const(v).reserve_hint() == 0);
+ }
+ }
+}
+
+constexpr bool test() {
+ // non-approximately-sized range has no reserve_hint
+ static_assert(!std::ranges::approximately_sized_range<std::ranges::adjacent_view<NonApproximatelySizedView, 2>>);
+ static_assert(
+ !std::ranges::approximately_sized_range<const std::ranges::adjacent_view<NonApproximatelySizedView, 2>>);
+
+ test<1>();
+ test<2>();
+ test<3>();
+ test<5>();
+
+ return true;
+}
+
+int main(int, char**) {
+ test();
+ static_assert(test());
+
+ return 0;
+}
diff --git a/libcxx/test/std/ranges/range.adaptors/range.all/range.owning.view/reserve_hint.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.all/range.owning.view/reserve_hint.pass.cpp
new file mode 100644
index 0000000000000..41a30d9355429
--- /dev/null
+++ b/libcxx/test/std/ranges/range.adaptors/range.all/range.owning.view/reserve_hint.pass.cpp
@@ -0,0 +1,86 @@
+//===----------------------------------------------------------------------===//
+//
+// 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++26
+
+// constexpr auto reserve_hint()
+// requires approximately_sized_range<R>
+// constexpr auto reserve_hint() const
+// requires approximately_sized_range<const R>
+
+#include <ranges>
+
+#include <array>
+#include <cassert>
+#include <concepts>
+#include <utility>
+
+#include "test_iterators.h"
+
+int globalBuff[8];
+
+template <class T>
+concept HasReserveHint = requires(T t) { t.reserve_hint(); };
+
+constexpr bool test() {
+ {
+ struct NoReserveHint {
+ bidirectional_iterator<int*> begin();
+ bidirectional_iterator<int*> end();
+ };
+ using OwningView = std::ranges::owning_view<NoReserveHint>;
+ static_assert(!HasReserveHint<OwningView&>);
+ static_assert(!HasReserveHint<OwningView&&>);
+ static_assert(!HasReserveHint<const OwningView&>);
+ static_assert(!HasReserveHint<const OwningView&&>);
+ }
+ {
+ struct ReserveHintMember {
+ bidirectional_iterator<int*> begin();
+ bidirectional_iterator<int*> end();
+ int reserve_hint() const;
+ };
+ using OwningView = std::ranges::owning_view<ReserveHintMember>;
+ static_assert(!std::ranges::sized_range<OwningView&>);
+ static_assert(std::ranges::approximately_sized_range<OwningView&>);
+ static_assert(!std::ranges::range<const OwningView&>); // no begin/end
+ static_assert(HasReserveHint<OwningView&>);
+ static_assert(HasReserveHint<OwningView&&>);
+ static_assert(!HasReserveHint<const OwningView&>); // not a range, therefore no reserve_hint()
+ static_assert(!HasReserveHint<const OwningView&&>);
+ }
+ {
+ // Test an empty view.
+ int a[] = {1};
+ auto ov = std::ranges::owning_view(std::ranges::subrange(a, a));
+ assert(ov.reserve_hint() == 0);
+ assert(std::as_const(ov).reserve_hint() == 0);
+ }
+ {
+ // Test a non-empty view.
+ int a[] = {1};
+ auto ov = std::ranges::owning_view(std::ranges::subrange(a, a + 1));
+ assert(ov.reserve_hint() == 1);
+ assert(std::as_const(ov).reserve_hint() == 1);
+ }
+ {
+ // Test a non-view.
+ std::array<int, 2> a = {1, 2};
+ auto ov = std::ranges::owning_view(std::move(a));
+ assert(ov.reserve_hint() == 2);
+ assert(std::as_const(ov).reserve_hint() == 2);
+ }
+ return true;
+}
+
+int main(int, char**) {
+ test();
+ static_assert(test());
+
+ return 0;
+}
diff --git a/libcxx/test/std/ranges/range.adaptors/range.all/range.ref.view/range.ref.view.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.all/range.ref.view/range.ref.view.pass.cpp
index 88e7179da5496..d527ead60cfc3 100644
--- a/libcxx/test/std/ranges/range.adaptors/range.all/range.ref.view/range.ref.view.pass.cpp
+++ b/libcxx/test/std/ranges/range.adaptors/range.all/range.ref.view/range.ref.view.pass.cpp
@@ -109,6 +109,20 @@ concept DataIsInvocable = requires (std::ranges::ref_view<R> view) { view.data()
static_assert(std::same_as<decltype(std::ranges::ref_view(std::declval<Range&>())),
std::ranges::ref_view<Range>>);
+#if TEST_STD_VER >= 26
+template <class R>
+concept ReserveHintIsInvocable = requires(std::ranges::ref_view<R> view) { view.reserve_hint(); };
+
+struct ApproximatelySizedRange {
+ int start_;
+ unsigned int reserve_hint_;
+
+ constexpr auto begin() const { return forward_iterator<int*>(globalBuff + start_); }
+ constexpr auto end() const { return forward_iterator<int*>(globalBuff + 8); }
+ constexpr unsigned int reserve_hint() const { return reserve_hint_; }
+};
+#endif
+
constexpr bool test() {
{
// ref_view::base
@@ -184,6 +198,21 @@ constexpr bool test() {
static_assert(!SizeIsInvocable<ForwardRange>);
}
+#if TEST_STD_VER >= 26
+ // ref_view::reserve_hint
+ {
+ ApproximatelySizedRange range1{2, 5};
+ std::ranges::ref_view<ApproximatelySizedRange> view1 = range1;
+ assert(view1.reserve_hint() == 5);
+
+ ApproximatelySizedRange range2{7, 0};
+ std::ranges::ref_view<ApproximatelySizedRange> view2 = range2;
+ assert(view2.reserve_hint() == 0);
+
+ static_assert(!ReserveHintIsInvocable<ForwardRange>);
+ }
+#endif
+
{
// ref_view::data
Range range1;
diff --git a/libcxx/test/std/ranges/range.adaptors/range.as.rvalue/reserve_hint.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.as.rvalue/reserve_hint.pass.cpp
new file mode 100644
index 0000000000000..2acdb9d6e7ce5
--- /dev/null
+++ b/libcxx/test/std/ranges/range.adaptors/range.as.rvalue/reserve_hint.pass.cpp
@@ -0,0 +1,90 @@
+//===----------------------------------------------------------------------===//
+//
+// 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++26
+
+// <ranges>
+
+// constexpr auto reserve_hint()
+// requires approximately_sized_range<V>;
+// constexpr auto reserve_hint() const
+// requires approximately_sized_range<const V>;
+
+#include <cassert>
+#include <ranges>
+
+#include "test_iterators.h"
+
+// forward_iterator + sentinel end so that ranges::size doesn't apply,
+// making these ranges approximately_sized only via their member reserve_hint().
+
+struct ConstReserveHintView : std::ranges::view_base {
+ bool* hint_called;
+ constexpr auto begin() const { return forward_iterator<int*>(nullptr); }
+ constexpr auto end() const { return sentinel_wrapper<forward_iterator<int*>>(forward_iterator<int*>(nullptr)); }
+
+ constexpr unsigned int reserve_hint() const {
+ *hint_called = true;
+ return 3;
+ }
+};
+
+struct NonConstReserveHintView : std::ranges::view_base {
+ bool* hint_called;
+ constexpr auto begin() const { return forward_iterator<int*>(nullptr); }
+ constexpr auto end() const { return sentinel_wrapper<forward_iterator<int*>>(forward_iterator<int*>(nullptr)); }
+
+ constexpr unsigned int reserve_hint() {
+ *hint_called = true;
+ return 5;
+ }
+};
+
+struct NoReserveHintView : std::ranges::view_base {
+ constexpr auto begin() const { return forward_iterator<int*>(nullptr); }
+ constexpr auto end() const { return sentinel_wrapper<forward_iterator<int*>>(forward_iterator<int*>(nullptr)); }
+};
+
+template <class T>
+concept HasReserveHint = requires(T v) { v.reserve_hint(); };
+
+static_assert(!std::ranges::sized_range<std::ranges::as_rvalue_view<ConstReserveHintView>>);
+static_assert(!std::ranges::sized_range<std::ranges::as_rvalue_view<NonConstReserveHintView>>);
+static_assert(!std::ranges::sized_range<std::ranges::as_rvalue_view<NoReserveHintView>>);
+
+static_assert(HasReserveHint<std::ranges::as_rvalue_view<ConstReserveHintView>>);
+static_assert(HasReserveHint<const std::ranges::as_rvalue_view<ConstReserveHintView>>);
+static_assert(HasReserveHint<std::ranges::as_rvalue_view<NonConstReserveHintView>>);
+static_assert(!HasReserveHint<const std::ranges::as_rvalue_view<NonConstReserveHintView>>);
+static_assert(!HasReserveHint<std::ranges::as_rvalue_view<NoReserveHintView>>);
+static_assert(!HasReserveHint<const std::ranges::as_rvalue_view<NoReserveHintView>>);
+
+constexpr bool test() {
+ {
+ bool hint_called = false;
+ std::ranges::as_rvalue_view view(ConstReserveHintView{{}, &hint_called});
+ assert(view.reserve_hint() == 3);
+ assert(hint_called);
+ }
+
+ {
+ bool hint_called = false;
+ std::ranges::as_rvalue_view view(NonConstReserveHintView{{}, &hint_called});
+ assert(view.reserve_hint() == 5);
+ assert(hint_called);
+ }
+
+ return true;
+}
+
+int main(int, char**) {
+ test();
+ static_assert(test());
+
+ return 0;
+}
diff --git a/libcxx/test/std/ranges/range.adaptors/range.common.view/reserve_hint.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.common.view/reserve_hint.pass.cpp
new file mode 100644
index 0000000000000..eb900e6432fc0
--- /dev/null
+++ b/libcxx/test/std/ranges/range.adaptors/range.common.view/reserve_hint.pass.cpp
@@ -0,0 +1,63 @@
+//===----------------------------------------------------------------------===//
+//
+// 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++26
+
+// constexpr auto reserve_hint()
+// requires approximately_sized_range<V>;
+// constexpr auto reserve_hint() const
+// requires approximately_sized_range<const V>;
+
+#include <ranges>
+#include <cassert>
+
+#include "test_iterators.h"
+#include "types.h"
+
+template <class View>
+concept ReserveHintEnabled = requires(View v) { v.reserve_hint(); };
+
+constexpr bool test() {
+ int buf[8] = {1, 2, 3, 4, 5, 6, 7, 8};
+
+ {
+ static_assert(ReserveHintEnabled<std::ranges::common_view<ApproximatelySizedView>&>);
+ static_assert(ReserveHintEnabled<std::ranges::common_view<ApproximatelySizedView> const&>);
+ static_assert(!ReserveHintEnabled<std::ranges::common_view<CopyableView>&>);
+ static_assert(!ReserveHintEnabled<std::ranges::common_view<CopyableView> const&>);
+ static_assert(ReserveHintEnabled<std::ranges::common_view<NonConstApproximatelySizedView>&>);
+ static_assert(!ReserveHintEnabled<std::ranges::common_view<NonConstApproximatelySizedView> const&>);
+ }
+
+ {
+ ApproximatelySizedView view(buf, buf + 8, 5);
+ std::ranges::common_view<ApproximatelySizedView> common(view);
+ assert(common.reserve_hint() == 5);
+ }
+
+ {
+ ApproximatelySizedView view(buf, buf + 8, 5);
+ const std::ranges::common_view<ApproximatelySizedView> common(view);
+ assert(common.reserve_hint() == 5);
+ }
+
+ {
+ NonConstApproximatelySizedView view(buf, buf + 8, 5);
+ std::ranges::common_view<NonConstApproximatelySizedView> common(view);
+ assert(common.reserve_hint() == 5);
+ }
+
+ return true;
+}
+
+int main(int, char**) {
+ test();
+ static_assert(test());
+
+ return 0;
+}
diff --git a/libcxx/test/std/ranges/range.adaptors/range.common.view/types.h b/libcxx/test/std/ranges/range.adaptors/range.common.view/types.h
index 56f2f6ad5fcbf..3dc8fdc670cb5 100644
--- a/libcxx/test/std/ranges/range.adaptors/range.common.view/types.h
+++ b/libcxx/test/std/ranges/range.adaptors/range.common.view/types.h
@@ -123,4 +123,35 @@ static_assert(HasConstAndNonConstBegin<std::ranges::common_view<NonSimpleNonComm
static_assert(HasConstBegin<const std::ranges::common_view<NonSimpleNonCommonView>>);
static_assert(HasOnlyConstBegin<const std::ranges::common_view<NonSimpleNonCommonView>>);
+#if TEST_STD_VER >= 26
+
+struct ApproximatelySizedView : std::ranges::view_base {
+ int* begin_;
+ int* end_;
+ unsigned int hint_;
+ constexpr explicit ApproximatelySizedView(int* b, int* e, unsigned int hint) : begin_(b), end_(e), hint_(hint) {}
+ constexpr auto begin() const { return forward_iterator<int*>(begin_); }
+ constexpr auto end() const { return sentinel_wrapper<forward_iterator<int*>>(forward_iterator<int*>(end_)); }
+ constexpr unsigned int reserve_hint() const { return hint_; }
+};
+static_assert(!std::ranges::common_range<ApproximatelySizedView>);
+static_assert(std::ranges::approximately_sized_range<ApproximatelySizedView>);
+static_assert(std::ranges::approximately_sized_range<const ApproximatelySizedView>);
+
+struct NonConstApproximatelySizedView : std::ranges::view_base {
+ int* begin_;
+ int* end_;
+ unsigned int hint_;
+ constexpr explicit NonConstApproximatelySizedView(int* b, int* e, unsigned int hint)
+ : begin_(b), end_(e), hint_(hint) {}
+ constexpr auto begin() const { return forward_iterator<int*>(begin_); }
+ constexpr auto end() const { return sentinel_wrapper<forward_iterator<int*>>(forward_iterator<int*>(end_)); }
+ constexpr unsigned int reserve_hint() { return hint_; }
+};
+static_assert(!std::ranges::common_range<NonConstApproximatelySizedView>);
+static_assert(std::ranges::approximately_sized_range<NonConstApproximatelySizedView>);
+static_assert(!std::ranges::approximately_sized_range<const NonConstApproximatelySizedView>);
+
+#endif // TEST_STD_VER >= 26
+
#endif // TEST_STD_RANGES_RANGE_ADAPTORS_RANGE_COMMON_VIEW_TYPES_H
diff --git a/libcxx/test/std/ranges/range.adaptors/range.concat/reserve_hint.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.concat/reserve_hint.pass.cpp
new file mode 100644
index 0000000000000..1652d33eafe0c
--- /dev/null
+++ b/libcxx/test/std/ranges/range.adaptors/range.concat/reserve_hint.pass.cpp
@@ -0,0 +1,107 @@
+//===----------------------------------------------------------------------===//
+//
+// 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++26
+
+// <ranges>
+
+// constexpr auto reserve_hint()
+// requires (approximately_sized_range<Views> && ...);
+// constexpr auto reserve_hint() const
+// requires (approximately_sized_range<const Views> && ...);
+
+#include <cassert>
+#include <ranges>
+
+#include "test_iterators.h"
+#include "test_macros.h"
+
+// All views use forward_iterator as their iterator so that ranges::size doesn't apply,
+// making approximately_sized_range depend solely on the reserve_hint() member.
+
+int buffer[] = {1, 2, 3, 4, 5, 6, 7, 8, 9};
+
+struct ApproximatelySizedView : std::ranges::view_base {
+ unsigned int hint_;
+ constexpr explicit ApproximatelySizedView(unsigned int hint) : hint_(hint) {}
+ constexpr auto begin() const { return forward_iterator<int*>(buffer); }
+ constexpr auto end() const { return forward_iterator<int*>(buffer + hint_); }
+ constexpr unsigned int reserve_hint() const { return hint_; }
+};
+
+struct ApproximatelySizedNotConstView : std::ranges::view_base {
+ unsigned int hint_;
+ constexpr explicit ApproximatelySizedNotConstView(unsigned int hint) : hint_(hint) {}
+ constexpr auto begin() const { return forward_iterator<int*>(buffer); }
+ constexpr auto end() const { return forward_iterator<int*>(buffer + hint_); }
+ constexpr unsigned int reserve_hint() { return hint_; }
+};
+
+struct IntHintView : std::ranges::view_base {
+ constexpr auto begin() const { return forward_iterator<int*>(buffer); }
+ constexpr auto end() const { return forward_iterator<int*>(buffer + 4); }
+ constexpr int reserve_hint() const { return 4; }
+};
+
+struct UnsignedHintView : std::ranges::view_base {
+ constexpr auto begin() const { return forward_iterator<int*>(buffer); }
+ constexpr auto end() const { return forward_iterator<int*>(buffer + 5); }
+ constexpr unsigned int reserve_hint() const { return 5; }
+};
+
+struct NoHintView : std::ranges::view_base {
+ constexpr auto begin() const { return forward_iterator<int*>(buffer); }
+ constexpr auto end() const { return forward_iterator<int*>(buffer + 3); }
+};
+
+constexpr bool test() {
+ {
+ // single range
+ std::ranges::concat_view v(ApproximatelySizedView(8));
+ assert(v.reserve_hint() == 8);
+ assert(std::as_const(v).reserve_hint() == 8);
+ }
+
+ {
+ // multiple ranges same type
+ std::ranges::concat_view v(ApproximatelySizedView(2), ApproximatelySizedView(3));
+ assert(v.reserve_hint() == 5);
+ assert(std::as_const(v).reserve_hint() == 5);
+ }
+
+ {
+ // const-view non-approximately-sized range
+ std::ranges::concat_view v(ApproximatelySizedNotConstView(2), ApproximatelySizedView(3));
+ assert(v.reserve_hint() == 5);
+ static_assert(std::ranges::approximately_sized_range<decltype(v)>);
+ static_assert(!std::ranges::approximately_sized_range<decltype(std::as_const(v))>);
+ }
+
+ {
+ // underlying range not approximately-sized
+ std::ranges::concat_view v(NoHintView{}, ApproximatelySizedView(8));
+ static_assert(!std::ranges::approximately_sized_range<decltype(v)>);
+ static_assert(!std::ranges::approximately_sized_range<decltype(std::as_const(v))>);
+ }
+
+ {
+ // two ranges with different hint types: common type of int and unsigned int is unsigned int
+ std::ranges::concat_view v(IntHintView{}, UnsignedHintView{});
+ assert(v.reserve_hint() == 9);
+ ASSERT_SAME_TYPE(decltype(v.reserve_hint()), unsigned int);
+ }
+
+ return true;
+}
+
+int main(int, char**) {
+ test();
+ static_assert(test());
+
+ return 0;
+}
diff --git a/libcxx/test/std/ranges/range.adaptors/range.drop/reserve_hint.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.drop/reserve_hint.pass.cpp
new file mode 100644
index 0000000000000..33045591c412d
--- /dev/null
+++ b/libcxx/test/std/ranges/range.adaptors/range.drop/reserve_hint.pass.cpp
@@ -0,0 +1,59 @@
+//===----------------------------------------------------------------------===//
+//
+// 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++26
+
+// constexpr auto reserve_hint()
+// requires approximately_sized_range<V>
+// constexpr auto reserve_hint() const
+// requires approximately_sized_range<const V>
+
+#include <cassert>
+#include <ranges>
+
+#include "test_macros.h"
+#include "types.h"
+
+template <class T>
+concept ReserveHintInvocable = requires(std::ranges::drop_view<T> t) { t.reserve_hint(); };
+
+constexpr bool test() {
+ // approximately_sized_range<V>
+ std::ranges::drop_view dropView1(MoveOnlyView(), 4);
+ assert(dropView1.reserve_hint() == 4);
+
+ // approximately_sized_range<V>
+ std::ranges::drop_view dropView2(MoveOnlyView(), 0);
+ assert(dropView2.reserve_hint() == 8);
+
+ // approximately_sized_range<const V>
+ const std::ranges::drop_view dropView3(MoveOnlyView(), 8);
+ assert(dropView3.reserve_hint() == 0);
+
+ // approximately_sized_range<const V>
+ const std::ranges::drop_view dropView4(MoveOnlyView(), 10);
+ assert(dropView4.reserve_hint() == 0);
+
+ // mutable-only approximately_sized_range
+ std::ranges::drop_view dropView5(ApproximatelySizedNotConstView(8), 3);
+ assert(dropView5.reserve_hint() == 5);
+ static_assert(ReserveHintInvocable<ApproximatelySizedNotConstView>);
+ static_assert(!ReserveHintInvocable<const ApproximatelySizedNotConstView>);
+
+ // Because ForwardView is not approximately_sized_range.
+ static_assert(!ReserveHintInvocable<ForwardView>);
+
+ return true;
+}
+
+int main(int, char**) {
+ test();
+ static_assert(test());
+
+ return 0;
+}
diff --git a/libcxx/test/std/ranges/range.adaptors/range.drop/types.h b/libcxx/test/std/ranges/range.adaptors/range.drop/types.h
index 73d1e5045ad22..c0bb72a138d8b 100644
--- a/libcxx/test/std/ranges/range.adaptors/range.drop/types.h
+++ b/libcxx/test/std/ranges/range.adaptors/range.drop/types.h
@@ -141,4 +141,18 @@ struct View : std::ranges::view_base {
int* end_;
};
+#if TEST_STD_VER >= 26
+
+struct ApproximatelySizedNotConstView : std::ranges::view_base {
+ unsigned int hint_;
+ constexpr explicit ApproximatelySizedNotConstView(unsigned int hint) : hint_(hint) {}
+ constexpr forward_iterator<int*> begin() const { return forward_iterator<int*>(globalBuff); }
+ constexpr forward_iterator<int*> end() const { return forward_iterator<int*>(globalBuff + 8); }
+ constexpr unsigned int reserve_hint() { return hint_; }
+};
+static_assert(std::ranges::approximately_sized_range<ApproximatelySizedNotConstView>);
+static_assert(!std::ranges::approximately_sized_range<const ApproximatelySizedNotConstView>);
+
+#endif // TEST_STD_VER >= 26
+
#endif // TEST_STD_RANGES_RANGE_ADAPTORS_RANGE_DROP_TYPES_H
diff --git a/libcxx/test/std/ranges/range.adaptors/range.elements/reserve_hint.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.elements/reserve_hint.pass.cpp
new file mode 100644
index 0000000000000..085648add5c99
--- /dev/null
+++ b/libcxx/test/std/ranges/range.adaptors/range.elements/reserve_hint.pass.cpp
@@ -0,0 +1,90 @@
+//===----------------------------------------------------------------------===//
+//
+// 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++26
+
+// <ranges>
+
+// constexpr auto reserve_hint()
+// requires approximately_sized_range<V>
+// constexpr auto reserve_hint() const
+// requires approximately_sized_range<const V>
+
+#include <cassert>
+#include <ranges>
+#include <tuple>
+
+#include "types.h"
+
+template <class T>
+concept HasReserveHint = requires(T t) { t.reserve_hint(); };
+
+struct NonApproximatelySized : std::ranges::view_base {
+ using iterator = forward_iterator<std::tuple<int>*>;
+ iterator begin() const;
+ iterator end() const;
+};
+static_assert(!std::ranges::approximately_sized_range<NonApproximatelySized>);
+static_assert(!std::ranges::approximately_sized_range<const NonApproximatelySized>);
+
+static_assert(!HasReserveHint<std::ranges::elements_view<NonApproximatelySized, 0>>);
+static_assert(!HasReserveHint<const std::ranges::elements_view<NonApproximatelySized, 0>>);
+
+struct ApproximatelySizedTupleView : TupleBufferView {
+ unsigned int hint_;
+
+ template <std::size_t N>
+ constexpr ApproximatelySizedTupleView(std::tuple<int> (&buf)[N], unsigned int hint)
+ : TupleBufferView(buf), hint_(hint) {}
+
+ constexpr auto begin() const { return forward_iterator<std::tuple<int>*>(buffer_); }
+ constexpr auto end() const { return forward_iterator<std::tuple<int>*>(buffer_ + size_); }
+ constexpr unsigned int reserve_hint() const { return hint_; }
+};
+static_assert(HasReserveHint<std::ranges::elements_view<ApproximatelySizedTupleView, 0>>);
+static_assert(HasReserveHint<const std::ranges::elements_view<ApproximatelySizedTupleView, 0>>);
+
+struct ApproximatelySizedNotConstTupleView : TupleBufferView {
+ unsigned int hint_;
+
+ template <std::size_t N>
+ constexpr ApproximatelySizedNotConstTupleView(std::tuple<int> (&buf)[N], unsigned int hint)
+ : TupleBufferView(buf), hint_(hint) {}
+
+ constexpr auto begin() const { return forward_iterator<std::tuple<int>*>(buffer_); }
+ constexpr auto end() const { return forward_iterator<std::tuple<int>*>(buffer_ + size_); }
+ constexpr unsigned int reserve_hint() { return hint_; }
+};
+static_assert(HasReserveHint<std::ranges::elements_view<ApproximatelySizedNotConstTupleView, 0>>);
+static_assert(!HasReserveHint<const std::ranges::elements_view<ApproximatelySizedNotConstTupleView, 0>>);
+
+constexpr bool test() {
+ std::tuple<int> buffer[] = {{1}, {2}, {3}};
+
+ // non-const and const are approximately_sized
+ {
+ auto ev = std::views::elements<0>(ApproximatelySizedTupleView(buffer, 5));
+ assert(ev.reserve_hint() == 5);
+ assert(std::as_const(ev).reserve_hint() == 5);
+ }
+
+ {
+ // mutable-only approximately_sized_range
+ auto ev = std::views::elements<0>(ApproximatelySizedNotConstTupleView(buffer, 5));
+ assert(ev.reserve_hint() == 5);
+ }
+
+ return true;
+}
+
+int main(int, char**) {
+ test();
+ static_assert(test());
+
+ return 0;
+}
diff --git a/libcxx/test/std/ranges/range.adaptors/range.enumerate/reserve_hint.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.enumerate/reserve_hint.pass.cpp
new file mode 100644
index 0000000000000..bd391377e3a08
--- /dev/null
+++ b/libcxx/test/std/ranges/range.adaptors/range.enumerate/reserve_hint.pass.cpp
@@ -0,0 +1,82 @@
+//===----------------------------------------------------------------------===//
+//
+// 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++26
+
+// <ranges>
+
+// class enumerate_view
+
+// constexpr auto reserve_hint()
+// requires approximately_sized_range<V>;
+// constexpr auto reserve_hint() const
+// requires approximately_sized_range<const V>;
+
+#include <cassert>
+#include <ranges>
+
+#include "test_iterators.h"
+
+#include "types.h"
+
+template <class T>
+concept HasMemberReserveHint = requires(T t) { t.reserve_hint(); };
+
+static constexpr int globalBuff[8] = {};
+
+struct NonApproximatelySizedView : std::ranges::view_base {
+ using iterator = forward_iterator<const int*>;
+ iterator begin() const;
+ iterator end() const;
+};
+
+static_assert(!std::ranges::approximately_sized_range<NonApproximatelySizedView>);
+static_assert(!std::ranges::approximately_sized_range<const NonApproximatelySizedView>);
+
+static_assert(!HasMemberReserveHint<std::ranges::enumerate_view<NonApproximatelySizedView>>);
+static_assert(!HasMemberReserveHint<const std::ranges::enumerate_view<NonApproximatelySizedView>>);
+
+struct ApproximatelySizedView : std::ranges::view_base {
+ unsigned int size_;
+ constexpr explicit ApproximatelySizedView(unsigned int hint) : size_(hint) {}
+ constexpr auto begin() const { return forward_iterator<const int*>(globalBuff); }
+ constexpr auto end() const { return forward_iterator<const int*>(globalBuff + 8); }
+ constexpr unsigned int reserve_hint() const { return size_; }
+};
+
+static_assert(HasMemberReserveHint<std::ranges::enumerate_view<ApproximatelySizedView>>);
+static_assert(HasMemberReserveHint<const std::ranges::enumerate_view<ApproximatelySizedView>>);
+
+struct ApproximatelySizedNotConstView : std::ranges::view_base {
+ unsigned int size_;
+ constexpr explicit ApproximatelySizedNotConstView(unsigned int hint) : size_(hint) {}
+ constexpr auto begin() const { return forward_iterator<const int*>(globalBuff); }
+ constexpr auto end() const { return forward_iterator<const int*>(globalBuff + 8); }
+ constexpr unsigned int reserve_hint() { return size_; }
+};
+
+static_assert(HasMemberReserveHint<std::ranges::enumerate_view<ApproximatelySizedNotConstView>>);
+static_assert(!HasMemberReserveHint<const std::ranges::enumerate_view<ApproximatelySizedNotConstView>>);
+
+constexpr bool test() {
+ // Non-const and const are reserve_hint-able
+ {
+ auto view = std::views::enumerate(ApproximatelySizedView{5});
+ assert(view.reserve_hint() == 5);
+ assert(std::as_const(view).reserve_hint() == 5);
+ }
+
+ return true;
+}
+
+int main(int, char**) {
+ test();
+ static_assert(test());
+
+ return 0;
+}
diff --git a/libcxx/test/std/ranges/range.adaptors/range.reverse/reserve_hint.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.reverse/reserve_hint.pass.cpp
new file mode 100644
index 0000000000000..91ced350bbaad
--- /dev/null
+++ b/libcxx/test/std/ranges/range.adaptors/range.reverse/reserve_hint.pass.cpp
@@ -0,0 +1,89 @@
+//===----------------------------------------------------------------------===//
+//
+// 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++26
+
+// constexpr auto reserve_hint()
+// requires approximately_sized_range<V>
+// constexpr auto reserve_hint() const
+// requires approximately_sized_range<const V>
+
+#include <cassert>
+#include <ranges>
+
+#include "test_macros.h"
+#include "types.h"
+
+// end - begin = 8, but size may return something else.
+template <CopyCategory CC>
+struct BidirApproxSizedRange : std::ranges::view_base {
+ int* ptr_;
+ std::size_t reserve_hint_;
+
+ constexpr BidirApproxSizedRange(int* ptr, std::size_t reserve_hint) : ptr_(ptr), reserve_hint_(reserve_hint) {}
+ constexpr BidirApproxSizedRange(const BidirApproxSizedRange&)
+ requires(CC == Copyable)
+ = default;
+ constexpr BidirApproxSizedRange(BidirApproxSizedRange&&)
+ requires(CC == MoveOnly)
+ = default;
+ constexpr BidirApproxSizedRange& operator=(const BidirApproxSizedRange&)
+ requires(CC == Copyable)
+ = default;
+ constexpr BidirApproxSizedRange& operator=(BidirApproxSizedRange&&)
+ requires(CC == MoveOnly)
+ = default;
+
+ constexpr bidirectional_iterator<int*> begin() { return bidirectional_iterator<int*>{ptr_}; }
+ constexpr bidirectional_iterator<const int*> begin() const { return bidirectional_iterator<const int*>{ptr_}; }
+ constexpr bidirectional_iterator<int*> end() { return bidirectional_iterator<int*>{ptr_ + 8}; }
+ constexpr bidirectional_iterator<const int*> end() const { return bidirectional_iterator<const int*>{ptr_ + 8}; }
+
+ constexpr std::size_t size() const { return reserve_hint_; }
+};
+
+constexpr bool test() {
+ int buffer[8] = {1, 2, 3, 4, 5, 6, 7, 8};
+
+ // Non-common, non-const bidirectional range.
+ {
+ auto rev = std::ranges::reverse_view(BidirApproxSizedRange<Copyable>{buffer, 4});
+ assert(std::ranges::reserve_hint(rev) == 4);
+ assert(rev.reserve_hint() == 4);
+ assert(std::move(rev).reserve_hint() == 4);
+
+ ASSERT_SAME_TYPE(decltype(rev.reserve_hint()), std::size_t);
+ ASSERT_SAME_TYPE(decltype(std::move(rev).reserve_hint()), std::size_t);
+ }
+ // Non-common, const bidirectional range.
+ {
+ const auto rev = std::ranges::reverse_view(BidirApproxSizedRange<Copyable>{buffer, 4});
+ assert(std::ranges::reserve_hint(rev) == 4);
+ assert(rev.reserve_hint() == 4);
+ assert(std::move(rev).reserve_hint() == 4);
+
+ ASSERT_SAME_TYPE(decltype(rev.reserve_hint()), std::size_t);
+ ASSERT_SAME_TYPE(decltype(std::move(rev).reserve_hint()), std::size_t);
+ }
+ // Non-common, non-const (move only) bidirectional range.
+ {
+ auto rev = std::ranges::reverse_view(BidirApproxSizedRange<MoveOnly>{buffer, 4});
+ assert(std::move(rev).reserve_hint() == 4);
+
+ ASSERT_SAME_TYPE(decltype(std::move(rev).reserve_hint()), std::size_t);
+ }
+
+ return true;
+}
+
+int main(int, char**) {
+ test();
+ static_assert(test());
+
+ return 0;
+}
diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/reserve_hint.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.stride.view/reserve_hint.pass.cpp
new file mode 100644
index 0000000000000..97b4dcfc8b4a4
--- /dev/null
+++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/reserve_hint.pass.cpp
@@ -0,0 +1,99 @@
+//===----------------------------------------------------------------------===//
+//
+// 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++26
+
+// constexpr auto reserve_hint()
+// requires approximately_sized_range<V>
+// constexpr auto reserve_hint() const
+// requires approximately_sized_range<const V>
+
+#include <cassert>
+#include <ranges>
+
+#include "types.h"
+
+// There is no reserve_hint function on a stride view over a view that
+// is *not* an approximately sized range
+static_assert(!std::ranges::approximately_sized_range<BasicTestView<cpp17_input_iterator<int*>>>);
+static_assert(
+ !std::ranges::approximately_sized_range<std::ranges::stride_view<BasicTestView<cpp17_input_iterator<int*>>>>);
+
+// There is a reserve_hint function on a stride view over a view that
+// *is *an approximately sized range
+static_assert(std::ranges::approximately_sized_range<
+ BasicTestView<int*, sentinel_wrapper<int*>, /*IsSized=*/false, /*IsApproximatelySized=*/true>>);
+static_assert(std::ranges::approximately_sized_range<std::ranges::stride_view<
+ BasicTestView<int*, sentinel_wrapper<int*>, /*IsSized=*/false, /*IsApproximatelySized=*/true>>>);
+
+using Iota = std::ranges::iota_view<int, int>;
+using ApproximatelySizedView =
+ BasicTestView<std::ranges::iterator_t<Iota>,
+ std::ranges::sentinel_t<Iota>,
+ /*IsSized=*/false,
+ /*IsApproximatelySized=*/true>;
+
+constexpr ApproximatelySizedView make_approximately_sized(Iota&& iota) {
+ return ApproximatelySizedView(std::ranges::begin(iota), std::ranges::end(iota));
+}
+
+constexpr bool test() {
+ {
+ // Test with stride as exact multiple of number of elements in view strided over.
+ auto view = make_approximately_sized(std::views::iota(0, 12));
+ auto strided = std::views::stride(view, 3);
+ static_assert(std::ranges::approximately_sized_range<decltype(strided)>);
+ assert(strided.reserve_hint() == 4);
+ }
+
+ {
+ // Test with stride as inexact multiple of number of elements in view strided over.
+ auto view = make_approximately_sized(std::views::iota(0, 22));
+ static_assert(std::ranges::approximately_sized_range<decltype(view)>);
+ auto strided = std::views::stride(view, 3);
+ static_assert(std::ranges::approximately_sized_range<decltype(strided)>);
+ assert(strided.size() == 8);
+ }
+
+ {
+ // Empty range.
+ auto view = make_approximately_sized(std::views::iota(0, 0));
+ auto strided = view | std::views::stride(3);
+ assert(strided.reserve_hint() == 0);
+ }
+
+ {
+ // Stride larger than range size.
+ auto view = make_approximately_sized(std::views::iota(0, 3));
+ auto strided = view | std::views::stride(10);
+ assert(strided.reserve_hint() == 1);
+ }
+
+ {
+ // Stride equal to range size.
+ auto view = make_approximately_sized(std::views::iota(0, 3));
+ auto strided = view | std::views::stride(5);
+ assert(strided.reserve_hint() == 1);
+ }
+
+ {
+ // Stride of 1.
+ auto view = make_approximately_sized(std::views::iota(0, 7));
+ auto strided = view | std::views::stride(1);
+ assert(strided.size() == 7);
+ }
+
+ return true;
+}
+
+int main(int, char**) {
+ test();
+ static_assert(test());
+
+ return 0;
+}
diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/types.h b/libcxx/test/std/ranges/range.adaptors/range.stride.view/types.h
index 5a8d6b6ca2f71..49da1473dc4e1 100644
--- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/types.h
+++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/types.h
@@ -172,8 +172,9 @@ struct MaybeView<true> : std::ranges::view_base {};
template <std::input_iterator Iter,
std::sentinel_for<Iter> Sent = sentinel_wrapper<Iter>,
bool IsSized = false,
+ bool IsApproximatelySized = false,
bool IsView = false,
- bool IsCopyable = false >
+ bool IsCopyable = false>
requires((!IsSized) || (IsSized && IterDifferable<Iter>))
struct BasicTestViewOrRange : MaybeView<IsView> {
Iter begin_{};
@@ -192,6 +193,12 @@ struct BasicTestViewOrRange : MaybeView<IsView> {
return begin_ - end_;
}
+ constexpr auto reserve_hint() const
+ requires IsApproximatelySized
+ {
+ return begin_ - end_;
+ }
+
constexpr BasicTestViewOrRange(BasicTestViewOrRange&& other) = default;
constexpr BasicTestViewOrRange& operator=(BasicTestViewOrRange&&) = default;
@@ -210,12 +217,16 @@ struct BasicTestViewOrRange : MaybeView<IsView> {
= default;
};
-template <std::input_iterator Iter, std::sentinel_for<Iter> Sent = sentinel_wrapper<Iter>, bool IsSized = false>
+template <std::input_iterator Iter,
+ std::sentinel_for<Iter> Sent = sentinel_wrapper<Iter>,
+ bool IsSized = false,
+ bool IsApproximatelySized = false>
requires((!IsSized) || (IsSized && IterDifferable<Iter>))
-using BasicTestView = BasicTestViewOrRange<Iter, Sent, IsSized, true /* IsView */, true /* IsCopyable */>;
+using BasicTestView =
+ BasicTestViewOrRange<Iter, Sent, IsSized, IsApproximatelySized, true /* IsView */, true /* IsCopyable */>;
template <std::input_iterator Iter, std::sentinel_for<Iter> Sent = sentinel_wrapper<Iter>, bool IsCopyable = true>
-using MaybeCopyableAlwaysMoveableView = BasicTestViewOrRange<Iter, Sent, false, true, IsCopyable>;
+using MaybeCopyableAlwaysMoveableView = BasicTestViewOrRange<Iter, Sent, false, false, true, IsCopyable>;
static_assert(std::ranges::view<MaybeCopyableAlwaysMoveableView<cpp17_input_iterator<int*>>>);
static_assert(std::ranges::view<MaybeCopyableAlwaysMoveableView<cpp17_input_iterator<int*>,
diff --git a/libcxx/test/std/ranges/range.adaptors/range.take/reserve_hint.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.take/reserve_hint.pass.cpp
new file mode 100644
index 0000000000000..65e89e285563f
--- /dev/null
+++ b/libcxx/test/std/ranges/range.adaptors/range.take/reserve_hint.pass.cpp
@@ -0,0 +1,87 @@
+//===----------------------------------------------------------------------===//
+//
+// 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++26
+
+// constexpr auto reserve_hint()
+// requires approximately_sized_range<V>
+// constexpr auto reserve_hint() const
+// requires approximately_sized_range<const V>
+
+#include <ranges>
+#include <cassert>
+
+#include "test_macros.h"
+#include "test_iterators.h"
+#include "test_range.h"
+#include "types.h"
+
+template <class T>
+concept ReserveHintEnabled = requires(const std::ranges::take_view<T>& tv) { tv.reserve_hint(); };
+
+constexpr bool test() {
+ int buffer[8] = {1, 2, 3, 4, 5, 6, 7, 8};
+
+ {
+ static_assert(ReserveHintEnabled<ApproximatelySizedForwardView>);
+ }
+
+ {
+ std::ranges::take_view<SimpleViewNonSized> tv(SimpleViewNonSized{buffer, buffer + 8}, 100);
+ assert(tv.reserve_hint() == 100);
+ }
+
+ {
+ std::ranges::take_view<ApproximatelySizedForwardView> tv(ApproximatelySizedForwardView{buffer}, 0);
+ assert(tv.reserve_hint() == 0);
+ }
+
+ {
+ const std::ranges::take_view<ApproximatelySizedForwardView> tv(ApproximatelySizedForwardView{buffer}, 2);
+ assert(tv.reserve_hint() == 2);
+ }
+
+ {
+ std::ranges::take_view<ApproximatelySizedForwardView> tv(ApproximatelySizedForwardView{buffer}, 4);
+ assert(tv.reserve_hint() == 4);
+ }
+
+ {
+ const std::ranges::take_view<ApproximatelySizedForwardView> tv(ApproximatelySizedForwardView{buffer}, 6);
+ assert(tv.reserve_hint() == 6);
+ }
+
+ {
+ std::ranges::take_view<ApproximatelySizedForwardView> tv(ApproximatelySizedForwardView{buffer}, 8);
+ assert(tv.reserve_hint() == 8);
+ }
+
+ {
+ const std::ranges::take_view<ApproximatelySizedForwardView> tv(ApproximatelySizedForwardView{buffer}, 8);
+ assert(tv.reserve_hint() == 8);
+ }
+
+ {
+ std::ranges::take_view<ApproximatelySizedForwardView> tv(ApproximatelySizedForwardView{buffer}, 10);
+ assert(tv.reserve_hint() == 8);
+ }
+
+ {
+ const std::ranges::take_view<ApproximatelySizedForwardView> tv(ApproximatelySizedForwardView{buffer}, 10);
+ assert(tv.reserve_hint() == 8);
+ }
+
+ return true;
+}
+
+int main(int, char**) {
+ test();
+ static_assert(test());
+
+ return 0;
+}
diff --git a/libcxx/test/std/ranges/range.adaptors/range.take/types.h b/libcxx/test/std/ranges/range.adaptors/range.take/types.h
index 7590ce33bffc1..a51edc93862b1 100644
--- a/libcxx/test/std/ranges/range.adaptors/range.take/types.h
+++ b/libcxx/test/std/ranges/range.adaptors/range.take/types.h
@@ -54,6 +54,20 @@ static_assert(std::ranges::view<SizedRandomAccessView>);
static_assert(std::ranges::random_access_range<SizedRandomAccessView>);
static_assert(std::ranges::sized_range<SizedRandomAccessView>);
+#if TEST_STD_VER >= 26
+using ForwardIter = forward_iterator<int*>;
+struct ApproximatelySizedForwardView : std::ranges::view_base {
+ int* ptr_;
+ constexpr explicit ApproximatelySizedForwardView(int* ptr) : ptr_(ptr) {}
+ constexpr auto begin() const { return ForwardIter(ptr_); }
+ constexpr auto end() const { return ForwardIter(ptr_ + 8); }
+ constexpr std::size_t reserve_hint() const { return 8; }
+};
+static_assert(std::ranges::view<ApproximatelySizedForwardView>);
+static_assert(!std::ranges::sized_range<ApproximatelySizedForwardView>);
+static_assert(std::ranges::approximately_sized_range<ApproximatelySizedForwardView>);
+#endif
+
struct View : std::ranges::view_base {
constexpr explicit View(int* b, int* e) : begin_(b), end_(e) { }
diff --git a/libcxx/test/std/ranges/range.adaptors/range.transform/reserve_hint.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.transform/reserve_hint.pass.cpp
new file mode 100644
index 0000000000000..78ae794f82915
--- /dev/null
+++ b/libcxx/test/std/ranges/range.adaptors/range.transform/reserve_hint.pass.cpp
@@ -0,0 +1,44 @@
+//===----------------------------------------------------------------------===//
+//
+// 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++26
+
+// constexpr auto reserve_hint()
+// requires approximately_sized_range<V>
+// constexpr auto reserve_hint() const
+// requires approximately_sized_range<const V>
+
+#include <cassert>
+#include <ranges>
+
+#include "types.h"
+
+template <class T>
+concept ReserveHintInvocable = requires(T t) { t.reserve_hint(); };
+
+constexpr bool test() {
+ {
+ std::ranges::transform_view transformView(ApproximatelySizedView{5}, PlusOne{});
+ assert(transformView.reserve_hint() == 5);
+ }
+
+ static_assert(ReserveHintInvocable<std::ranges::transform_view<ApproximatelySizedView, PlusOne>>);
+ static_assert(ReserveHintInvocable<const std::ranges::transform_view<ApproximatelySizedView, PlusOne>>);
+
+ static_assert(ReserveHintInvocable<std::ranges::transform_view<ApproximatelySizedNotConstView, PlusOne>>);
+ static_assert(!ReserveHintInvocable<const std::ranges::transform_view<ApproximatelySizedNotConstView, PlusOne>>);
+
+ return true;
+}
+
+int main(int, char**) {
+ test();
+ static_assert(test());
+
+ return 0;
+}
diff --git a/libcxx/test/std/ranges/range.adaptors/range.transform/types.h b/libcxx/test/std/ranges/range.adaptors/range.transform/types.h
index e94e7dfcdaeb7..0d94fc02c1f2e 100644
--- a/libcxx/test/std/ranges/range.adaptors/range.transform/types.h
+++ b/libcxx/test/std/ranges/range.adaptors/range.transform/types.h
@@ -114,6 +114,39 @@ struct SizedSentinelNotConstView : std::ranges::view_base {
bool operator==(const ForwardIter &lhs, int* rhs);
bool operator==(int* lhs, const ForwardIter &rhs);
+#if TEST_STD_VER >= 26
+struct ApproximatelySizedView : std::ranges::view_base {
+ int start_;
+ unsigned int reserve_hint_;
+
+ constexpr explicit ApproximatelySizedView(unsigned int hint, int start = 0) : start_(start), reserve_hint_(hint) {}
+ constexpr auto begin() const { return forward_iterator<int*>(globalBuff + start_); }
+ constexpr auto end() const { return forward_iterator<int*>(globalBuff + 8); }
+ constexpr unsigned int reserve_hint() const { return reserve_hint_; }
+};
+
+static_assert(std::ranges::view<ApproximatelySizedView>);
+static_assert(!std::ranges::sized_range<ApproximatelySizedView>);
+static_assert(std::ranges::approximately_sized_range<ApproximatelySizedView>);
+static_assert(std::ranges::approximately_sized_range<const ApproximatelySizedView>);
+
+struct ApproximatelySizedNotConstView : std::ranges::view_base {
+ int start_;
+ unsigned int reserve_hint_;
+
+ constexpr explicit ApproximatelySizedNotConstView(unsigned int hint, int start = 0)
+ : start_(start), reserve_hint_(hint) {}
+ constexpr auto begin() const { return forward_iterator<int*>(globalBuff + start_); }
+ constexpr auto end() const { return forward_iterator<int*>(globalBuff + 8); }
+ constexpr unsigned int reserve_hint() { return reserve_hint_; }
+};
+
+static_assert(std::ranges::view<ApproximatelySizedNotConstView>);
+static_assert(!std::ranges::sized_range<ApproximatelySizedNotConstView>);
+static_assert(std::ranges::approximately_sized_range<ApproximatelySizedNotConstView>);
+static_assert(!std::ranges::approximately_sized_range<const ApproximatelySizedNotConstView>);
+#endif
+
struct Range {
int *begin() const;
int *end() const;
>From 59df762a288c647f90e8537524cdfbc9b1f22f6f Mon Sep 17 00:00:00 2001
From: inquisitivecrystal
<22333129+inquisitivecrystal at users.noreply.github.com>
Date: Thu, 25 Jun 2026 01:58:37 -0700
Subject: [PATCH 07/29] Update libc++ c++26 status
---
libcxx/docs/Status/Cxx26Issues.csv | 2 +-
libcxx/docs/Status/Cxx26Papers.csv | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/libcxx/docs/Status/Cxx26Issues.csv b/libcxx/docs/Status/Cxx26Issues.csv
index d4f7a44910e00..804cb2580411f 100644
--- a/libcxx/docs/Status/Cxx26Issues.csv
+++ b/libcxx/docs/Status/Cxx26Issues.csv
@@ -336,7 +336,7 @@
"`LWG4549 <https://wg21.link/LWG4549>`__","``vprint_nonunicode_buffered`` ignores its stream parameter","2026-03 (Croydon)","","","`#189878 <https://github.com/llvm/llvm-project/issues/189878>`__",""
"`LWG4550 <https://wg21.link/LWG4550>`__","Need new feature test macros for ``<stdckdint.h>`` and ``<stdbit.h>``","2026-03 (Croydon)","","","`#189879 <https://github.com/llvm/llvm-project/issues/189879>`__",""
"`LWG4552 <https://wg21.link/LWG4552>`__","``compare_exchange_weak`` writes a value on spurious failure, not memory contents","2026-03 (Croydon)","","","`#189880 <https://github.com/llvm/llvm-project/issues/189880>`__",""
-"`LWG4553 <https://wg21.link/LWG4553>`__","Wording for FR-025-246 25.7.18.2 Add a ``reserve_hint`` function to ``concat_view``","2026-03 (Croydon)","","","`#189881 <https://github.com/llvm/llvm-project/issues/189881>`__",""
+"`LWG4553 <https://wg21.link/LWG4553>`__","Wording for FR-025-246 25.7.18.2 Add a ``reserve_hint`` function to ``concat_view``","2026-03 (Croydon)","|Complete|","23","`#189881 <https://github.com/llvm/llvm-project/issues/189881>`__",""
"`LWG4554 <https://wg21.link/LWG4554>`__","Remove undefined behaviour from ``hive`` for invalid limits","2026-03 (Croydon)","","","`#189882 <https://github.com/llvm/llvm-project/issues/189882>`__",""
"`LWG4555 <https://wg21.link/LWG4555>`__","Remove ``is_consteval_only``","2026-03 (Croydon)","","","`#189883 <https://github.com/llvm/llvm-project/issues/189883>`__",""
"`LWG4556 <https://wg21.link/LWG4556>`__","Unclear properties of reflection strings","2026-03 (Croydon)","","","`#189884 <https://github.com/llvm/llvm-project/issues/189884>`__",""
diff --git a/libcxx/docs/Status/Cxx26Papers.csv b/libcxx/docs/Status/Cxx26Papers.csv
index 9744940459bcd..f4d57a47a0c8f 100644
--- a/libcxx/docs/Status/Cxx26Papers.csv
+++ b/libcxx/docs/Status/Cxx26Papers.csv
@@ -112,7 +112,7 @@
"`P3430R3 <https://wg21.link/P3430R3>`__","simd issues: explicit, unsequenced, identity-element position, and members of disabled simd","2025-02 (Hagenberg)","","","`#127881 <https://github.com/llvm/llvm-project/issues/127881>`__",""
"`P2663R7 <https://wg21.link/P2663R7>`__","Interleaved complex values support in ``std::simd``","2025-02 (Hagenberg)","","","`#127882 <https://github.com/llvm/llvm-project/issues/127882>`__",""
"`P2933R4 <https://wg21.link/P2933R4>`__","Extend ``<bit>`` header function with overloads for ``std::simd``","2025-02 (Hagenberg)","","","`#127883 <https://github.com/llvm/llvm-project/issues/127883>`__",""
-"`P2846R6 <https://wg21.link/P2846R6>`__","``reserve_hint``: Eagerly reserving memory for not-quite-sized lazy ranges","2025-02 (Hagenberg)","","","`#127884 <https://github.com/llvm/llvm-project/issues/127884>`__",""
+"`P2846R6 <https://wg21.link/P2846R6>`__","``reserve_hint``: Eagerly reserving memory for not-quite-sized lazy ranges","2025-02 (Hagenberg)","|Partial|","23","`#127884 <https://github.com/llvm/llvm-project/issues/127884>`__","``__cpp_lib_ranges_reserve_hint`` is not set. Container operations that take a range as input do not respect ``reserve_hint``. ``chunk_view`` and ``slide_view`` support blocked on `P2442R1 <https://wg21.link/P2442R1>`__. ``as_const_view`` support blocked on `P2278R4 <https://wg21.link/P2278R4>`__."
"`P3471R4 <https://wg21.link/P3471R4>`__","Standard Library Hardening","2025-02 (Hagenberg)","","","`#127885 <https://github.com/llvm/llvm-project/issues/127885>`__",""
"`P0447R28 <https://wg21.link/P0447R28>`__","Introduction of ``std::hive`` to the standard library","2025-02 (Hagenberg)","","","`#127886 <https://github.com/llvm/llvm-project/issues/127886>`__",""
"`P3019R14 <https://wg21.link/P3019R14>`__","``indirect`` and ``polymorphic``: Vocabulary Types for Composite Class Design","2025-02 (Hagenberg)","","","`#127887 <https://github.com/llvm/llvm-project/issues/127887>`__",""
>From 19d3a72610d4032c3a5ec6282697a9b3e01cbf7f Mon Sep 17 00:00:00 2001
From: inquisitivecrystal
<22333129+inquisitivecrystal at users.noreply.github.com>
Date: Sun, 28 Jun 2026 18:53:59 -0700
Subject: [PATCH 08/29] Change __freestanding to __unqualified per review
---
libcxx/include/__ranges/size.h | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/libcxx/include/__ranges/size.h b/libcxx/include/__ranges/size.h
index 3dfeade03fce5..d442c9972ae91 100644
--- a/libcxx/include/__ranges/size.h
+++ b/libcxx/include/__ranges/size.h
@@ -148,7 +148,7 @@ concept __member_reserve_hint = !__std_size<_Tp> && requires(_Tp&& __t) {
};
template <typename _Tp>
-concept __freestanding_reserve_hint =
+concept __unqualified_reserve_hint =
!__std_size<_Tp> && !__member_reserve_hint<_Tp> && __class_or_enum<remove_cvref_t<_Tp>> && requires(_Tp&& __t) {
{ auto(reserve_hint(__t)) } -> __integer_like;
};
@@ -169,7 +169,7 @@ struct __fn {
}
// `[range.prim.size.hint]`: `auto(reserve_hint(t))` is a valid expression
- template <__freestanding_reserve_hint _Tp>
+ template <__unqualified_reserve_hint _Tp>
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr __integer_like auto operator()(_Tp&& __t) const
noexcept(noexcept(auto(reserve_hint(__t)))) {
return auto(reserve_hint(__t));
>From 8ab948211bb9273b8ac833d3c57883c2f15a9a2c Mon Sep 17 00:00:00 2001
From: inquisitivecrystal
<22333129+inquisitivecrystal at users.noreply.github.com>
Date: Sun, 28 Jun 2026 19:27:00 -0700
Subject: [PATCH 09/29] Add missing includes
---
libcxx/include/__ranges/take_view.h | 1 +
libcxx/test/std/ranges/range.adaptors/range.common.view/types.h | 1 +
.../std/ranges/range.adaptors/range.concat/reserve_hint.pass.cpp | 1 +
.../ranges/range.adaptors/range.elements/reserve_hint.pass.cpp | 1 +
.../ranges/range.adaptors/range.enumerate/reserve_hint.pass.cpp | 1 +
5 files changed, 5 insertions(+)
diff --git a/libcxx/include/__ranges/take_view.h b/libcxx/include/__ranges/take_view.h
index f97a88ccf9297..b252ad3ecf104 100644
--- a/libcxx/include/__ranges/take_view.h
+++ b/libcxx/include/__ranges/take_view.h
@@ -37,6 +37,7 @@
#include <__ranges/view_interface.h>
#include <__type_traits/decay.h>
#include <__type_traits/is_nothrow_constructible.h>
+#include <__type_traits/make_unsigned.h>
#include <__type_traits/maybe_const.h>
#include <__type_traits/remove_cvref.h>
#include <__utility/auto_cast.h>
diff --git a/libcxx/test/std/ranges/range.adaptors/range.common.view/types.h b/libcxx/test/std/ranges/range.adaptors/range.common.view/types.h
index 3dc8fdc670cb5..130423389ad68 100644
--- a/libcxx/test/std/ranges/range.adaptors/range.common.view/types.h
+++ b/libcxx/test/std/ranges/range.adaptors/range.common.view/types.h
@@ -11,6 +11,7 @@
#include <ranges>
+#include "test_macros.h"
#include "test_iterators.h"
struct DefaultConstructibleView : std::ranges::view_base {
diff --git a/libcxx/test/std/ranges/range.adaptors/range.concat/reserve_hint.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.concat/reserve_hint.pass.cpp
index 1652d33eafe0c..e2b4e8400ba86 100644
--- a/libcxx/test/std/ranges/range.adaptors/range.concat/reserve_hint.pass.cpp
+++ b/libcxx/test/std/ranges/range.adaptors/range.concat/reserve_hint.pass.cpp
@@ -17,6 +17,7 @@
#include <cassert>
#include <ranges>
+#include <utility>
#include "test_iterators.h"
#include "test_macros.h"
diff --git a/libcxx/test/std/ranges/range.adaptors/range.elements/reserve_hint.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.elements/reserve_hint.pass.cpp
index 085648add5c99..96be6d3942e1d 100644
--- a/libcxx/test/std/ranges/range.adaptors/range.elements/reserve_hint.pass.cpp
+++ b/libcxx/test/std/ranges/range.adaptors/range.elements/reserve_hint.pass.cpp
@@ -18,6 +18,7 @@
#include <cassert>
#include <ranges>
#include <tuple>
+#include <utility>
#include "types.h"
diff --git a/libcxx/test/std/ranges/range.adaptors/range.enumerate/reserve_hint.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.enumerate/reserve_hint.pass.cpp
index bd391377e3a08..f7ae9c610a4ab 100644
--- a/libcxx/test/std/ranges/range.adaptors/range.enumerate/reserve_hint.pass.cpp
+++ b/libcxx/test/std/ranges/range.adaptors/range.enumerate/reserve_hint.pass.cpp
@@ -19,6 +19,7 @@
#include <cassert>
#include <ranges>
+#include <utility>
#include "test_iterators.h"
>From da29f5a1172f3aa397477dcc31b4155af9896105 Mon Sep 17 00:00:00 2001
From: inquisitivecrystal
<22333129+inquisitivecrystal at users.noreply.github.com>
Date: Sun, 28 Jun 2026 22:07:30 -0700
Subject: [PATCH 10/29] Fully qualify calls to avoid ADL
---
libcxx/include/__ranges/concat_view.h | 4 ++--
libcxx/include/__ranges/drop_view.h | 4 ++--
libcxx/include/__ranges/stride_view.h | 4 ++--
libcxx/include/__ranges/take_view.h | 8 ++++----
4 files changed, 10 insertions(+), 10 deletions(-)
diff --git a/libcxx/include/__ranges/concat_view.h b/libcxx/include/__ranges/concat_view.h
index 33d269b9fd09a..6e1cfa0e3aad1 100644
--- a/libcxx/include/__ranges/concat_view.h
+++ b/libcxx/include/__ranges/concat_view.h
@@ -180,7 +180,7 @@ class concat_view : public view_interface<concat_view<_Views...>> {
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto reserve_hint()
requires(approximately_sized_range<_Views> && ...)
{
- return apply(
+ return std::apply(
[](auto... __sizes) static {
using _CT = make_unsigned_t<common_type_t<decltype(__sizes)...>>;
return (_CT(__sizes) + ...);
@@ -191,7 +191,7 @@ class concat_view : public view_interface<concat_view<_Views...>> {
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto reserve_hint() const
requires(approximately_sized_range<const _Views> && ...)
{
- return apply(
+ return std::apply(
[](auto... __sizes) static {
using _CT = make_unsigned_t<common_type_t<decltype(__sizes)...>>;
return (_CT(__sizes) + ...);
diff --git a/libcxx/include/__ranges/drop_view.h b/libcxx/include/__ranges/drop_view.h
index 9cae5c1c30276..0eb6ece0d9459 100644
--- a/libcxx/include/__ranges/drop_view.h
+++ b/libcxx/include/__ranges/drop_view.h
@@ -146,14 +146,14 @@ class drop_view : public view_interface<drop_view<_View>> {
requires approximately_sized_range<_View>
{
const auto __s = static_cast<range_difference_t<_View>>(ranges::reserve_hint(__base_));
- return __to_unsigned_like(__s < __count_ ? 0 : __s - __count_);
+ return std::__to_unsigned_like(__s < __count_ ? 0 : __s - __count_);
}
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto reserve_hint() const
requires approximately_sized_range<const _View>
{
const auto __s = static_cast<range_difference_t<const _View>>(ranges::reserve_hint(__base_));
- return __to_unsigned_like(__s < __count_ ? 0 : __s - __count_);
+ return std::__to_unsigned_like(__s < __count_ ? 0 : __s - __count_);
}
# endif //_LIBCPP_STD_VER >= 26
diff --git a/libcxx/include/__ranges/stride_view.h b/libcxx/include/__ranges/stride_view.h
index d4b7cce06eb91..d9006d3865d42 100644
--- a/libcxx/include/__ranges/stride_view.h
+++ b/libcxx/include/__ranges/stride_view.h
@@ -137,14 +137,14 @@ class stride_view : public view_interface<stride_view<_View>> {
requires approximately_sized_range<_View>
{
auto __s = static_cast<range_difference_t<decltype((__base_))>>(ranges::reserve_hint(__base_));
- return __to_unsigned_like(__div_ceil(__s, __stride_));
+ return std::__to_unsigned_like(ranges::__div_ceil(__s, __stride_));
}
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto reserve_hint() const
requires approximately_sized_range<const _View>
{
auto __s = static_cast<range_difference_t<decltype((__base_))>>(ranges::reserve_hint(__base_));
- return __to_unsigned_like(__div_ceil(__s, __stride_));
+ return std::__to_unsigned_like(ranges::__div_ceil(__s, __stride_));
}
# endif //_LIBCPP_STD_VER >= 26
diff --git a/libcxx/include/__ranges/take_view.h b/libcxx/include/__ranges/take_view.h
index b252ad3ecf104..00786e2987350 100644
--- a/libcxx/include/__ranges/take_view.h
+++ b/libcxx/include/__ranges/take_view.h
@@ -162,17 +162,17 @@ class take_view : public view_interface<take_view<_View>> {
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto reserve_hint() {
if constexpr (approximately_sized_range<_View>) {
auto __n = static_cast<range_difference_t<_View>>(ranges::reserve_hint(__base_));
- return __to_unsigned_like(ranges::min(__n, __count_));
+ return std::__to_unsigned_like(ranges::min(__n, __count_));
}
- return __to_unsigned_like(__count_);
+ return std::__to_unsigned_like(__count_);
}
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto reserve_hint() const {
if constexpr (approximately_sized_range<const _View>) {
auto __n = static_cast<range_difference_t<const _View>>(ranges::reserve_hint(__base_));
- return __to_unsigned_like(ranges::min(__n, __count_));
+ return std::__to_unsigned_like(ranges::min(__n, __count_));
}
- return __to_unsigned_like(__count_);
+ return std::__to_unsigned_like(__count_);
}
# endif //_LIBCPP_STD_VER >= 26
>From 683d0ee5de3771968c8636562490e143794d066f Mon Sep 17 00:00:00 2001
From: inquisitivecrystal
<22333129+inquisitivecrystal at users.noreply.github.com>
Date: Mon, 29 Jun 2026 19:32:51 -0700
Subject: [PATCH 11/29] Replace `reserve_hint.verify` test with assertion
---
.../ranges/range.access/reserve_hint.pass.cpp | 3 +++
.../range.access/reserve_hint.verify.cpp | 21 -------------------
2 files changed, 3 insertions(+), 21 deletions(-)
delete mode 100644 libcxx/test/std/ranges/range.access/reserve_hint.verify.cpp
diff --git a/libcxx/test/std/ranges/range.access/reserve_hint.pass.cpp b/libcxx/test/std/ranges/range.access/reserve_hint.pass.cpp
index 4e5f11fba445e..c9898c77769af 100644
--- a/libcxx/test/std/ranges/range.access/reserve_hint.pass.cpp
+++ b/libcxx/test/std/ranges/range.access/reserve_hint.pass.cpp
@@ -24,6 +24,7 @@ static_assert(!std::is_invocable_v<RangeReserveHintT, Incomplete(&)[]>);
static_assert(!std::is_invocable_v<RangeReserveHintT, Incomplete(&&)[]>);
extern int bounded_array[42];
+extern int unbounded_array[];
struct SizedSentinelRange {
int data_[42] = {};
@@ -56,6 +57,8 @@ static_assert(!std::is_invocable_v<RangeReserveHintT, HasReserveHintMemberBool>)
static_assert(std::ranges::reserve_hint(bounded_array) == 42);
ASSERT_SAME_TYPE(decltype(std::ranges::reserve_hint(bounded_array)), std::size_t);
+static_assert(!std::is_invocable_v<RangeReserveHintT, decltype(unbounded_array)>);
+
bool constexpr test_sized_sentinel_range() {
SizedSentinelRange b;
assert(std::ranges::reserve_hint(b) == 42);
diff --git a/libcxx/test/std/ranges/range.access/reserve_hint.verify.cpp b/libcxx/test/std/ranges/range.access/reserve_hint.verify.cpp
deleted file mode 100644
index 760620c6bd271..0000000000000
--- a/libcxx/test/std/ranges/range.access/reserve_hint.verify.cpp
+++ /dev/null
@@ -1,21 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// 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++26
-
-// std::ranges::reserve_hint
-
-#include <ranges>
-
-extern int arr[];
-
-// Verify that for an array of unknown bound `ranges::reserve_hint` is ill-formed.
-void test() {
- std::ranges::reserve_hint(arr);
- // expected-error-re at -1 {{{{no matching function for call to object of type 'const (std::ranges::)?__reserve_hint::__fn'}}}}
-}
>From 7e0dd306bf821c4ff7f260634ea6b975cf0c7b4c Mon Sep 17 00:00:00 2001
From: inquisitivecrystal
<22333129+inquisitivecrystal at users.noreply.github.com>
Date: Mon, 29 Jun 2026 19:46:21 -0700
Subject: [PATCH 12/29] Rename __std_size to __sized
The prior name was inaccurate, given that the CPO is called
`ranges::size`. Additionally, the new name matches the sized_range
concept.
---
libcxx/include/__ranges/size.h | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/libcxx/include/__ranges/size.h b/libcxx/include/__ranges/size.h
index d442c9972ae91..05cb501e0c36a 100644
--- a/libcxx/include/__ranges/size.h
+++ b/libcxx/include/__ranges/size.h
@@ -140,22 +140,22 @@ namespace __reserve_hint {
void reserve_hint() = delete;
template <typename _Tp>
-concept __std_size = requires(_Tp&& __t) { ranges::size(__t); };
+concept __sized = requires(_Tp&& __t) { ranges::size(__t); };
template <typename _Tp>
-concept __member_reserve_hint = !__std_size<_Tp> && requires(_Tp&& __t) {
+concept __member_reserve_hint = !__sized<_Tp> && requires(_Tp&& __t) {
{ auto(__t.reserve_hint()) } -> __integer_like;
};
template <typename _Tp>
concept __unqualified_reserve_hint =
- !__std_size<_Tp> && !__member_reserve_hint<_Tp> && __class_or_enum<remove_cvref_t<_Tp>> && requires(_Tp&& __t) {
+ !__sized<_Tp> && !__member_reserve_hint<_Tp> && __class_or_enum<remove_cvref_t<_Tp>> && requires(_Tp&& __t) {
{ auto(reserve_hint(__t)) } -> __integer_like;
};
struct __fn {
- // `[range.prim.size.hint]`: `std::size(t)` is a valid expression
- template <__std_size _Tp>
+ // `[range.prim.size.hint]`: `ranges::size(t)` is a valid expression
+ template <__sized _Tp>
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr __integer_like auto operator()(_Tp&& __t) const
noexcept(noexcept(ranges::size(__t))) {
return ranges::size(__t);
>From 6c8f079e148f2538ab4cc51721d6fc4dcf35a477 Mon Sep 17 00:00:00 2001
From: inquisitivecrystal
<22333129+inquisitivecrystal at users.noreply.github.com>
Date: Mon, 29 Jun 2026 21:12:25 -0700
Subject: [PATCH 13/29] Move `reserve_hint` CPO to new internal header
---
libcxx/include/CMakeLists.txt | 1 +
libcxx/include/__ranges/adjacent_view.h | 1 +
libcxx/include/__ranges/as_rvalue_view.h | 1 +
libcxx/include/__ranges/common_view.h | 1 +
libcxx/include/__ranges/concat_view.h | 1 +
libcxx/include/__ranges/concepts.h | 1 +
libcxx/include/__ranges/drop_view.h | 1 +
libcxx/include/__ranges/elements_view.h | 1 +
libcxx/include/__ranges/enumerate_view.h | 1 +
libcxx/include/__ranges/owning_view.h | 1 +
libcxx/include/__ranges/ref_view.h | 1 +
libcxx/include/__ranges/reserve_hint.h | 79 ++++++++++++++++++++++++
libcxx/include/__ranges/reverse_view.h | 1 +
libcxx/include/__ranges/size.h | 53 ----------------
libcxx/include/__ranges/stride_view.h | 2 +-
libcxx/include/__ranges/take_view.h | 1 +
libcxx/include/__ranges/transform_view.h | 1 +
libcxx/include/module.modulemap.in | 1 +
libcxx/include/ranges | 1 +
19 files changed, 96 insertions(+), 54 deletions(-)
create mode 100644 libcxx/include/__ranges/reserve_hint.h
diff --git a/libcxx/include/CMakeLists.txt b/libcxx/include/CMakeLists.txt
index 618686c685bee..94d12c5128041 100644
--- a/libcxx/include/CMakeLists.txt
+++ b/libcxx/include/CMakeLists.txt
@@ -754,6 +754,7 @@ set(files
__ranges/ref_view.h
__ranges/rend.h
__ranges/repeat_view.h
+ __ranges/reserve_hint.h
__ranges/reverse_view.h
__ranges/single_view.h
__ranges/size.h
diff --git a/libcxx/include/__ranges/adjacent_view.h b/libcxx/include/__ranges/adjacent_view.h
index 27b116e30eee9..095b01b263ffa 100644
--- a/libcxx/include/__ranges/adjacent_view.h
+++ b/libcxx/include/__ranges/adjacent_view.h
@@ -33,6 +33,7 @@
#include <__ranges/empty_view.h>
#include <__ranges/enable_borrowed_range.h>
#include <__ranges/range_adaptor.h>
+#include <__ranges/reserve_hint.h>
#include <__ranges/size.h>
#include <__ranges/view_interface.h>
#include <__tuple/tuple_transform.h>
diff --git a/libcxx/include/__ranges/as_rvalue_view.h b/libcxx/include/__ranges/as_rvalue_view.h
index 705cf559a7ee0..1e1dccf55fe7c 100644
--- a/libcxx/include/__ranges/as_rvalue_view.h
+++ b/libcxx/include/__ranges/as_rvalue_view.h
@@ -19,6 +19,7 @@
#include <__ranges/concepts.h>
#include <__ranges/enable_borrowed_range.h>
#include <__ranges/range_adaptor.h>
+#include <__ranges/reserve_hint.h>
#include <__ranges/size.h>
#include <__ranges/view_interface.h>
#include <__utility/forward.h>
diff --git a/libcxx/include/__ranges/common_view.h b/libcxx/include/__ranges/common_view.h
index 4f1dfbf5d9ac2..40acab0331676 100644
--- a/libcxx/include/__ranges/common_view.h
+++ b/libcxx/include/__ranges/common_view.h
@@ -20,6 +20,7 @@
#include <__ranges/concepts.h>
#include <__ranges/enable_borrowed_range.h>
#include <__ranges/range_adaptor.h>
+#include <__ranges/reserve_hint.h>
#include <__ranges/size.h>
#include <__ranges/view_interface.h>
#include <__utility/forward.h>
diff --git a/libcxx/include/__ranges/concat_view.h b/libcxx/include/__ranges/concat_view.h
index 6e1cfa0e3aad1..7602720576001 100644
--- a/libcxx/include/__ranges/concat_view.h
+++ b/libcxx/include/__ranges/concat_view.h
@@ -32,6 +32,7 @@
#include <__ranges/concepts.h>
#include <__ranges/movable_box.h>
#include <__ranges/range_adaptor.h>
+#include <__ranges/reserve_hint.h>
#include <__ranges/size.h>
#include <__ranges/view_interface.h>
#include <__tuple/tuple_transform.h>
diff --git a/libcxx/include/__ranges/concepts.h b/libcxx/include/__ranges/concepts.h
index e7cfc94506120..fcd079c237300 100644
--- a/libcxx/include/__ranges/concepts.h
+++ b/libcxx/include/__ranges/concepts.h
@@ -25,6 +25,7 @@
#include <__ranges/data.h>
#include <__ranges/enable_borrowed_range.h>
#include <__ranges/enable_view.h>
+#include <__ranges/reserve_hint.h>
#include <__ranges/size.h>
#include <__type_traits/add_pointer.h>
#include <__type_traits/common_reference.h>
diff --git a/libcxx/include/__ranges/drop_view.h b/libcxx/include/__ranges/drop_view.h
index 0eb6ece0d9459..c165e848b6e79 100644
--- a/libcxx/include/__ranges/drop_view.h
+++ b/libcxx/include/__ranges/drop_view.h
@@ -32,6 +32,7 @@
#include <__ranges/non_propagating_cache.h>
#include <__ranges/range_adaptor.h>
#include <__ranges/repeat_view.h>
+#include <__ranges/reserve_hint.h>
#include <__ranges/size.h>
#include <__ranges/subrange.h>
#include <__ranges/view_interface.h>
diff --git a/libcxx/include/__ranges/elements_view.h b/libcxx/include/__ranges/elements_view.h
index 9ce87e6814dbe..f7cc663325006 100644
--- a/libcxx/include/__ranges/elements_view.h
+++ b/libcxx/include/__ranges/elements_view.h
@@ -25,6 +25,7 @@
#include <__ranges/enable_borrowed_range.h>
#include <__ranges/range_adaptor.h>
#include <__ranges/size.h>
+#include <__ranges/reserve_hint.h>
#include <__ranges/view_interface.h>
#include <__tuple/tuple_element.h>
#include <__tuple/tuple_like.h>
diff --git a/libcxx/include/__ranges/enumerate_view.h b/libcxx/include/__ranges/enumerate_view.h
index 1a67a23e864d7..26d9098b40e87 100644
--- a/libcxx/include/__ranges/enumerate_view.h
+++ b/libcxx/include/__ranges/enumerate_view.h
@@ -22,6 +22,7 @@
#include <__ranges/concepts.h>
#include <__ranges/enable_borrowed_range.h>
#include <__ranges/range_adaptor.h>
+#include <__ranges/reserve_hint.h>
#include <__ranges/size.h>
#include <__ranges/view_interface.h>
#include <__type_traits/maybe_const.h>
diff --git a/libcxx/include/__ranges/owning_view.h b/libcxx/include/__ranges/owning_view.h
index b1e8415c3a477..bff1ff62e2284 100644
--- a/libcxx/include/__ranges/owning_view.h
+++ b/libcxx/include/__ranges/owning_view.h
@@ -18,6 +18,7 @@
#include <__ranges/data.h>
#include <__ranges/empty.h>
#include <__ranges/enable_borrowed_range.h>
+#include <__ranges/reserve_hint.h>
#include <__ranges/size.h>
#include <__ranges/view_interface.h>
#include <__type_traits/remove_cvref.h>
diff --git a/libcxx/include/__ranges/ref_view.h b/libcxx/include/__ranges/ref_view.h
index 34f129ace54e7..2c47061ec6f3a 100644
--- a/libcxx/include/__ranges/ref_view.h
+++ b/libcxx/include/__ranges/ref_view.h
@@ -22,6 +22,7 @@
#include <__ranges/data.h>
#include <__ranges/empty.h>
#include <__ranges/enable_borrowed_range.h>
+#include <__ranges/reserve_hint.h>
#include <__ranges/size.h>
#include <__ranges/view_interface.h>
#include <__type_traits/is_object.h>
diff --git a/libcxx/include/__ranges/reserve_hint.h b/libcxx/include/__ranges/reserve_hint.h
new file mode 100644
index 0000000000000..b3b4be59f8941
--- /dev/null
+++ b/libcxx/include/__ranges/reserve_hint.h
@@ -0,0 +1,79 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___RANGES_RESERVE_HINT_H
+#define _LIBCPP___RANGES_RESERVE_HINT_H
+
+#include <__concepts/class_or_enum.h>
+#include <__config>
+#include <__iterator/concepts.h>
+#include <__ranges/size.h>
+#include <__type_traits/remove_cvref.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#if _LIBCPP_STD_VER >= 26
+// [range.prim.size.hint]
+
+namespace ranges {
+namespace __reserve_hint {
+void reserve_hint() = delete;
+
+template <typename _Tp>
+concept __sized = requires(_Tp&& __t) { ranges::size(__t); };
+
+template <typename _Tp>
+concept __member_reserve_hint = !__sized<_Tp> && requires(_Tp&& __t) {
+ { auto(__t.reserve_hint()) } -> __integer_like;
+};
+
+template <typename _Tp>
+concept __unqualified_reserve_hint =
+ !__sized<_Tp> && !__member_reserve_hint<_Tp> && __class_or_enum<remove_cvref_t<_Tp>> && requires(_Tp&& __t) {
+ { auto(reserve_hint(__t)) } -> __integer_like;
+ };
+
+struct __fn {
+ // `[range.prim.size.hint]`: `ranges::size(t)` is a valid expression
+ template <__sized _Tp>
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr __integer_like auto operator()(_Tp&& __t) const
+ noexcept(noexcept(ranges::size(__t))) {
+ return ranges::size(__t);
+ }
+
+ // `[range.prim.size.hint]`: `auto(t.reserve_hint())` is a valid expression
+ template <__member_reserve_hint _Tp>
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr __integer_like auto operator()(_Tp&& __t) const
+ noexcept(noexcept(auto(__t.reserve_hint()))) {
+ return auto(__t.reserve_hint());
+ }
+
+ // `[range.prim.size.hint]`: `auto(reserve_hint(t))` is a valid expression
+ template <__unqualified_reserve_hint _Tp>
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr __integer_like auto operator()(_Tp&& __t) const
+ noexcept(noexcept(auto(reserve_hint(__t)))) {
+ return auto(reserve_hint(__t));
+ }
+};
+} // namespace __reserve_hint
+
+inline namespace __cpo {
+inline constexpr auto reserve_hint = __reserve_hint::__fn{};
+} // namespace __cpo
+} // namespace ranges
+
+#endif // _LIBCPP_STD_VER >= 26
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___RANGES_RESERVE_HINT_H
diff --git a/libcxx/include/__ranges/reverse_view.h b/libcxx/include/__ranges/reverse_view.h
index fc8e609705661..7f2ea094710fb 100644
--- a/libcxx/include/__ranges/reverse_view.h
+++ b/libcxx/include/__ranges/reverse_view.h
@@ -21,6 +21,7 @@
#include <__ranges/enable_borrowed_range.h>
#include <__ranges/non_propagating_cache.h>
#include <__ranges/range_adaptor.h>
+#include <__ranges/reserve_hint.h>
#include <__ranges/size.h>
#include <__ranges/subrange.h>
#include <__ranges/view_interface.h>
diff --git a/libcxx/include/__ranges/size.h b/libcxx/include/__ranges/size.h
index 05cb501e0c36a..5da3a6ff268e8 100644
--- a/libcxx/include/__ranges/size.h
+++ b/libcxx/include/__ranges/size.h
@@ -131,59 +131,6 @@ inline constexpr auto ssize = __ssize::__fn{};
} // namespace __cpo
} // namespace ranges
-# if _LIBCPP_STD_VER >= 26
-
-// [range.prim.size.hint]
-
-namespace ranges {
-namespace __reserve_hint {
-void reserve_hint() = delete;
-
-template <typename _Tp>
-concept __sized = requires(_Tp&& __t) { ranges::size(__t); };
-
-template <typename _Tp>
-concept __member_reserve_hint = !__sized<_Tp> && requires(_Tp&& __t) {
- { auto(__t.reserve_hint()) } -> __integer_like;
-};
-
-template <typename _Tp>
-concept __unqualified_reserve_hint =
- !__sized<_Tp> && !__member_reserve_hint<_Tp> && __class_or_enum<remove_cvref_t<_Tp>> && requires(_Tp&& __t) {
- { auto(reserve_hint(__t)) } -> __integer_like;
- };
-
-struct __fn {
- // `[range.prim.size.hint]`: `ranges::size(t)` is a valid expression
- template <__sized _Tp>
- [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr __integer_like auto operator()(_Tp&& __t) const
- noexcept(noexcept(ranges::size(__t))) {
- return ranges::size(__t);
- }
-
- // `[range.prim.size.hint]`: `auto(t.reserve_hint())` is a valid expression
- template <__member_reserve_hint _Tp>
- [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr __integer_like auto operator()(_Tp&& __t) const
- noexcept(noexcept(auto(__t.reserve_hint()))) {
- return auto(__t.reserve_hint());
- }
-
- // `[range.prim.size.hint]`: `auto(reserve_hint(t))` is a valid expression
- template <__unqualified_reserve_hint _Tp>
- [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr __integer_like auto operator()(_Tp&& __t) const
- noexcept(noexcept(auto(reserve_hint(__t)))) {
- return auto(reserve_hint(__t));
- }
-};
-} // namespace __reserve_hint
-
-inline namespace __cpo {
-inline constexpr auto reserve_hint = __reserve_hint::__fn{};
-} // namespace __cpo
-} // namespace ranges
-
-# endif // _LIBCPP_STD_VER >= 26
-
#endif // _LIBCPP_STD_VER >= 20
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__ranges/stride_view.h b/libcxx/include/__ranges/stride_view.h
index d9006d3865d42..45a57015eab6a 100644
--- a/libcxx/include/__ranges/stride_view.h
+++ b/libcxx/include/__ranges/stride_view.h
@@ -30,7 +30,7 @@
#include <__ranges/concepts.h>
#include <__ranges/enable_borrowed_range.h>
#include <__ranges/range_adaptor.h>
-#include <__ranges/size.h>
+#include <__ranges/reserve_hint.h>
#include <__ranges/view_interface.h>
#include <__type_traits/make_unsigned.h>
diff --git a/libcxx/include/__ranges/take_view.h b/libcxx/include/__ranges/take_view.h
index 00786e2987350..c2c61b1269ade 100644
--- a/libcxx/include/__ranges/take_view.h
+++ b/libcxx/include/__ranges/take_view.h
@@ -32,6 +32,7 @@
#include <__ranges/iota_view.h>
#include <__ranges/range_adaptor.h>
#include <__ranges/repeat_view.h>
+#include <__ranges/reserve_hint.h>
#include <__ranges/size.h>
#include <__ranges/subrange.h>
#include <__ranges/view_interface.h>
diff --git a/libcxx/include/__ranges/transform_view.h b/libcxx/include/__ranges/transform_view.h
index c26b7ea362a8d..95af90468d536 100644
--- a/libcxx/include/__ranges/transform_view.h
+++ b/libcxx/include/__ranges/transform_view.h
@@ -30,6 +30,7 @@
#include <__ranges/empty.h>
#include <__ranges/movable_box.h>
#include <__ranges/range_adaptor.h>
+#include <__ranges/reserve_hint.h>
#include <__ranges/size.h>
#include <__ranges/view_interface.h>
#include <__type_traits/conditional.h>
diff --git a/libcxx/include/module.modulemap.in b/libcxx/include/module.modulemap.in
index d70d0fce52460..c17f4b1a692ef 100644
--- a/libcxx/include/module.modulemap.in
+++ b/libcxx/include/module.modulemap.in
@@ -1942,6 +1942,7 @@ module std [system] {
module ref_view { header "__ranges/ref_view.h" }
module rend { header "__ranges/rend.h" }
module repeat_view { header "__ranges/repeat_view.h" }
+ module reserve_hint { header "__ranges/reserve_hint.h" }
module reverse_view { header "__ranges/reverse_view.h" }
module single_view { header "__ranges/single_view.h" }
module size { header "__ranges/size.h" }
diff --git a/libcxx/include/ranges b/libcxx/include/ranges
index 8e0d464bca6ea..451546335df98 100644
--- a/libcxx/include/ranges
+++ b/libcxx/include/ranges
@@ -531,6 +531,7 @@ namespace std {
# if _LIBCPP_STD_VER >= 26
# include <__ranges/concat_view.h>
+# include <__ranges/reserve_hint.h>
# endif
# include <version>
>From 5ee2311a35f949a5b75c8155706ee576bc93da8b Mon Sep 17 00:00:00 2001
From: inquisitivecrystal
<22333129+inquisitivecrystal at users.noreply.github.com>
Date: Mon, 29 Jun 2026 21:24:19 -0700
Subject: [PATCH 14/29] Sort includes correctly in tests
---
libcxx/test/std/ranges/range.access/reserve_hint.pass.cpp | 2 +-
.../range.adjacent.transform/reserve_hint.pass.cpp | 4 ++--
.../range.adaptors/range.adjacent/reserve_hint.pass.cpp | 2 +-
.../range.all/range.owning.view/reserve_hint.pass.cpp | 3 +--
.../range.adaptors/range.common.view/reserve_hint.pass.cpp | 2 +-
.../range.adaptors/range.enumerate/reserve_hint.pass.cpp | 1 -
.../ranges/range.adaptors/range.take/reserve_hint.pass.cpp | 4 ++--
7 files changed, 8 insertions(+), 10 deletions(-)
diff --git a/libcxx/test/std/ranges/range.access/reserve_hint.pass.cpp b/libcxx/test/std/ranges/range.access/reserve_hint.pass.cpp
index c9898c77769af..ba476f204ffbe 100644
--- a/libcxx/test/std/ranges/range.access/reserve_hint.pass.cpp
+++ b/libcxx/test/std/ranges/range.access/reserve_hint.pass.cpp
@@ -13,8 +13,8 @@
#include <cassert>
#include <ranges>
-#include "test_macros.h"
#include "test_iterators.h"
+#include "test_macros.h"
using RangeReserveHintT = decltype(std::ranges::reserve_hint);
diff --git a/libcxx/test/std/ranges/range.adaptors/range.adjacent.transform/reserve_hint.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.adjacent.transform/reserve_hint.pass.cpp
index 291810bfecf7d..bdc6d08e7b96b 100644
--- a/libcxx/test/std/ranges/range.adaptors/range.adjacent.transform/reserve_hint.pass.cpp
+++ b/libcxx/test/std/ranges/range.adaptors/range.adjacent.transform/reserve_hint.pass.cpp
@@ -17,9 +17,9 @@
#include <ranges>
#include <utility>
-#include "test_macros.h"
-#include "test_iterators.h"
#include "helpers.h"
+#include "test_iterators.h"
+#include "test_macros.h"
int buffer[] = {1, 2, 3, 4, 5, 6, 7, 8, 9};
diff --git a/libcxx/test/std/ranges/range.adaptors/range.adjacent/reserve_hint.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.adjacent/reserve_hint.pass.cpp
index d55e90112fad3..2c6f78b41ba65 100644
--- a/libcxx/test/std/ranges/range.adaptors/range.adjacent/reserve_hint.pass.cpp
+++ b/libcxx/test/std/ranges/range.adaptors/range.adjacent/reserve_hint.pass.cpp
@@ -17,8 +17,8 @@
#include <ranges>
#include <utility>
-#include "test_macros.h"
#include "test_iterators.h"
+#include "test_macros.h"
int buffer[] = {1, 2, 3, 4, 5, 6, 7, 8, 9};
diff --git a/libcxx/test/std/ranges/range.adaptors/range.all/range.owning.view/reserve_hint.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.all/range.owning.view/reserve_hint.pass.cpp
index 41a30d9355429..88fd2bdb589db 100644
--- a/libcxx/test/std/ranges/range.adaptors/range.all/range.owning.view/reserve_hint.pass.cpp
+++ b/libcxx/test/std/ranges/range.adaptors/range.all/range.owning.view/reserve_hint.pass.cpp
@@ -13,11 +13,10 @@
// constexpr auto reserve_hint() const
// requires approximately_sized_range<const R>
-#include <ranges>
-
#include <array>
#include <cassert>
#include <concepts>
+#include <ranges>
#include <utility>
#include "test_iterators.h"
diff --git a/libcxx/test/std/ranges/range.adaptors/range.common.view/reserve_hint.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.common.view/reserve_hint.pass.cpp
index eb900e6432fc0..9833cb5798c41 100644
--- a/libcxx/test/std/ranges/range.adaptors/range.common.view/reserve_hint.pass.cpp
+++ b/libcxx/test/std/ranges/range.adaptors/range.common.view/reserve_hint.pass.cpp
@@ -13,8 +13,8 @@
// constexpr auto reserve_hint() const
// requires approximately_sized_range<const V>;
-#include <ranges>
#include <cassert>
+#include <ranges>
#include "test_iterators.h"
#include "types.h"
diff --git a/libcxx/test/std/ranges/range.adaptors/range.enumerate/reserve_hint.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.enumerate/reserve_hint.pass.cpp
index f7ae9c610a4ab..56f267414f5eb 100644
--- a/libcxx/test/std/ranges/range.adaptors/range.enumerate/reserve_hint.pass.cpp
+++ b/libcxx/test/std/ranges/range.adaptors/range.enumerate/reserve_hint.pass.cpp
@@ -22,7 +22,6 @@
#include <utility>
#include "test_iterators.h"
-
#include "types.h"
template <class T>
diff --git a/libcxx/test/std/ranges/range.adaptors/range.take/reserve_hint.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.take/reserve_hint.pass.cpp
index 65e89e285563f..f82cf4f143a3e 100644
--- a/libcxx/test/std/ranges/range.adaptors/range.take/reserve_hint.pass.cpp
+++ b/libcxx/test/std/ranges/range.adaptors/range.take/reserve_hint.pass.cpp
@@ -13,11 +13,11 @@
// constexpr auto reserve_hint() const
// requires approximately_sized_range<const V>
-#include <ranges>
#include <cassert>
+#include <ranges>
-#include "test_macros.h"
#include "test_iterators.h"
+#include "test_macros.h"
#include "test_range.h"
#include "types.h"
>From fb125188f610122b15febe8da453ab1326eb9f55 Mon Sep 17 00:00:00 2001
From: inquisitivecrystal
<22333129+inquisitivecrystal at users.noreply.github.com>
Date: Mon, 29 Jun 2026 21:30:22 -0700
Subject: [PATCH 15/29] Make test header comments match siblings
Specifically, this change removes "// <ranges>" comments in test
headers where siblings in the same subdirectory don't have them.
---
.../ranges/range.adaptors/range.as.rvalue/reserve_hint.pass.cpp | 2 --
.../ranges/range.adaptors/range.concat/reserve_hint.pass.cpp | 2 --
.../ranges/range.adaptors/range.elements/reserve_hint.pass.cpp | 2 --
3 files changed, 6 deletions(-)
diff --git a/libcxx/test/std/ranges/range.adaptors/range.as.rvalue/reserve_hint.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.as.rvalue/reserve_hint.pass.cpp
index 2acdb9d6e7ce5..8d2f6cb07afbe 100644
--- a/libcxx/test/std/ranges/range.adaptors/range.as.rvalue/reserve_hint.pass.cpp
+++ b/libcxx/test/std/ranges/range.adaptors/range.as.rvalue/reserve_hint.pass.cpp
@@ -8,8 +8,6 @@
// REQUIRES: std-at-least-c++26
-// <ranges>
-
// constexpr auto reserve_hint()
// requires approximately_sized_range<V>;
// constexpr auto reserve_hint() const
diff --git a/libcxx/test/std/ranges/range.adaptors/range.concat/reserve_hint.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.concat/reserve_hint.pass.cpp
index e2b4e8400ba86..ede9050823165 100644
--- a/libcxx/test/std/ranges/range.adaptors/range.concat/reserve_hint.pass.cpp
+++ b/libcxx/test/std/ranges/range.adaptors/range.concat/reserve_hint.pass.cpp
@@ -8,8 +8,6 @@
// REQUIRES: std-at-least-c++26
-// <ranges>
-
// constexpr auto reserve_hint()
// requires (approximately_sized_range<Views> && ...);
// constexpr auto reserve_hint() const
diff --git a/libcxx/test/std/ranges/range.adaptors/range.elements/reserve_hint.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.elements/reserve_hint.pass.cpp
index 96be6d3942e1d..56d1ab13d8a2d 100644
--- a/libcxx/test/std/ranges/range.adaptors/range.elements/reserve_hint.pass.cpp
+++ b/libcxx/test/std/ranges/range.adaptors/range.elements/reserve_hint.pass.cpp
@@ -8,8 +8,6 @@
// REQUIRES: std-at-least-c++26
-// <ranges>
-
// constexpr auto reserve_hint()
// requires approximately_sized_range<V>
// constexpr auto reserve_hint() const
>From b2478fe055d761ab0d7ea7a47db7bc9adda2199a Mon Sep 17 00:00:00 2001
From: inquisitivecrystal
<22333129+inquisitivecrystal at users.noreply.github.com>
Date: Wed, 1 Jul 2026 16:44:00 -0700
Subject: [PATCH 16/29] Fix formatting
---
libcxx/include/__ranges/elements_view.h | 2 +-
libcxx/test/std/ranges/range.access/reserve_hint.pass.cpp | 4 ++--
2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/libcxx/include/__ranges/elements_view.h b/libcxx/include/__ranges/elements_view.h
index f7cc663325006..7e4a0246c2fef 100644
--- a/libcxx/include/__ranges/elements_view.h
+++ b/libcxx/include/__ranges/elements_view.h
@@ -24,8 +24,8 @@
#include <__ranges/concepts.h>
#include <__ranges/enable_borrowed_range.h>
#include <__ranges/range_adaptor.h>
-#include <__ranges/size.h>
#include <__ranges/reserve_hint.h>
+#include <__ranges/size.h>
#include <__ranges/view_interface.h>
#include <__tuple/tuple_element.h>
#include <__tuple/tuple_like.h>
diff --git a/libcxx/test/std/ranges/range.access/reserve_hint.pass.cpp b/libcxx/test/std/ranges/range.access/reserve_hint.pass.cpp
index ba476f204ffbe..5d24a24cd2341 100644
--- a/libcxx/test/std/ranges/range.access/reserve_hint.pass.cpp
+++ b/libcxx/test/std/ranges/range.access/reserve_hint.pass.cpp
@@ -20,8 +20,8 @@ using RangeReserveHintT = decltype(std::ranges::reserve_hint);
struct Incomplete;
static_assert(!std::is_invocable_v<RangeReserveHintT, Incomplete[]>);
-static_assert(!std::is_invocable_v<RangeReserveHintT, Incomplete(&)[]>);
-static_assert(!std::is_invocable_v<RangeReserveHintT, Incomplete(&&)[]>);
+static_assert(!std::is_invocable_v<RangeReserveHintT, Incomplete (&)[]>);
+static_assert(!std::is_invocable_v<RangeReserveHintT, Incomplete (&&)[]>);
extern int bounded_array[42];
extern int unbounded_array[];
>From 5d47b1d9833275624bf4a5f7e4e7fc6f1024f19c Mon Sep 17 00:00:00 2001
From: inquisitivecrystal
<22333129+inquisitivecrystal at users.noreply.github.com>
Date: Wed, 1 Jul 2026 17:13:20 -0700
Subject: [PATCH 17/29] Directly list standard library includes in tests
This avoids relying on transitive includes, per a reviewer comment.
---
libcxx/test/std/ranges/range.access/reserve_hint.pass.cpp | 2 ++
.../range.adjacent.transform/reserve_hint.pass.cpp | 1 +
.../ranges/range.adaptors/range.adjacent/reserve_hint.pass.cpp | 1 +
.../ranges/range.adaptors/range.elements/reserve_hint.pass.cpp | 1 +
.../ranges/range.adaptors/range.reverse/reserve_hint.pass.cpp | 2 ++
libcxx/test/std/ranges/range.adaptors/range.take/types.h | 1 +
6 files changed, 8 insertions(+)
diff --git a/libcxx/test/std/ranges/range.access/reserve_hint.pass.cpp b/libcxx/test/std/ranges/range.access/reserve_hint.pass.cpp
index 5d24a24cd2341..11379bedf7bf2 100644
--- a/libcxx/test/std/ranges/range.access/reserve_hint.pass.cpp
+++ b/libcxx/test/std/ranges/range.access/reserve_hint.pass.cpp
@@ -11,7 +11,9 @@
// std::ranges::reserve_hint
#include <cassert>
+#include <cstddef>
#include <ranges>
+#include <type_traits>
#include "test_iterators.h"
#include "test_macros.h"
diff --git a/libcxx/test/std/ranges/range.adaptors/range.adjacent.transform/reserve_hint.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.adjacent.transform/reserve_hint.pass.cpp
index bdc6d08e7b96b..5a5ed8c8a6983 100644
--- a/libcxx/test/std/ranges/range.adaptors/range.adjacent.transform/reserve_hint.pass.cpp
+++ b/libcxx/test/std/ranges/range.adaptors/range.adjacent.transform/reserve_hint.pass.cpp
@@ -14,6 +14,7 @@
// requires approximately_sized_range<const InnerView>;
#include <cassert>
+#include <cstddef>
#include <ranges>
#include <utility>
diff --git a/libcxx/test/std/ranges/range.adaptors/range.adjacent/reserve_hint.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.adjacent/reserve_hint.pass.cpp
index 2c6f78b41ba65..0546d9dbdb794 100644
--- a/libcxx/test/std/ranges/range.adaptors/range.adjacent/reserve_hint.pass.cpp
+++ b/libcxx/test/std/ranges/range.adaptors/range.adjacent/reserve_hint.pass.cpp
@@ -14,6 +14,7 @@
// requires approximately_sized_range<const View>;
#include <cassert>
+#include <cstddef>
#include <ranges>
#include <utility>
diff --git a/libcxx/test/std/ranges/range.adaptors/range.elements/reserve_hint.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.elements/reserve_hint.pass.cpp
index 56d1ab13d8a2d..6c888f2ae3827 100644
--- a/libcxx/test/std/ranges/range.adaptors/range.elements/reserve_hint.pass.cpp
+++ b/libcxx/test/std/ranges/range.adaptors/range.elements/reserve_hint.pass.cpp
@@ -14,6 +14,7 @@
// requires approximately_sized_range<const V>
#include <cassert>
+#include <cstddef>
#include <ranges>
#include <tuple>
#include <utility>
diff --git a/libcxx/test/std/ranges/range.adaptors/range.reverse/reserve_hint.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.reverse/reserve_hint.pass.cpp
index 91ced350bbaad..e241639d0f6ac 100644
--- a/libcxx/test/std/ranges/range.adaptors/range.reverse/reserve_hint.pass.cpp
+++ b/libcxx/test/std/ranges/range.adaptors/range.reverse/reserve_hint.pass.cpp
@@ -14,7 +14,9 @@
// requires approximately_sized_range<const V>
#include <cassert>
+#include <cstddef>
#include <ranges>
+#include <utility>
#include "test_macros.h"
#include "types.h"
diff --git a/libcxx/test/std/ranges/range.adaptors/range.take/types.h b/libcxx/test/std/ranges/range.adaptors/range.take/types.h
index a51edc93862b1..38b2f8f6ce3b8 100644
--- a/libcxx/test/std/ranges/range.adaptors/range.take/types.h
+++ b/libcxx/test/std/ranges/range.adaptors/range.take/types.h
@@ -1,6 +1,7 @@
#ifndef TEST_STD_RANGES_RANGE_ADAPTORS_RANGE_TAKE_TYPES_H
#define TEST_STD_RANGES_RANGE_ADAPTORS_RANGE_TAKE_TYPES_H
+#include <cstddef>
#include <ranges>
#include "test_macros.h"
>From 1bac7d85fe85ca416fe2ebe48bcd6eb620fe195a Mon Sep 17 00:00:00 2001
From: inquisitivecrystal
<22333129+inquisitivecrystal at users.noreply.github.com>
Date: Wed, 1 Jul 2026 17:20:51 -0700
Subject: [PATCH 18/29] Shorten paper status note in Cxx26Papers.csv
---
libcxx/docs/Status/Cxx26Papers.csv | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/libcxx/docs/Status/Cxx26Papers.csv b/libcxx/docs/Status/Cxx26Papers.csv
index f4d57a47a0c8f..b71a7e5e20d11 100644
--- a/libcxx/docs/Status/Cxx26Papers.csv
+++ b/libcxx/docs/Status/Cxx26Papers.csv
@@ -112,7 +112,7 @@
"`P3430R3 <https://wg21.link/P3430R3>`__","simd issues: explicit, unsequenced, identity-element position, and members of disabled simd","2025-02 (Hagenberg)","","","`#127881 <https://github.com/llvm/llvm-project/issues/127881>`__",""
"`P2663R7 <https://wg21.link/P2663R7>`__","Interleaved complex values support in ``std::simd``","2025-02 (Hagenberg)","","","`#127882 <https://github.com/llvm/llvm-project/issues/127882>`__",""
"`P2933R4 <https://wg21.link/P2933R4>`__","Extend ``<bit>`` header function with overloads for ``std::simd``","2025-02 (Hagenberg)","","","`#127883 <https://github.com/llvm/llvm-project/issues/127883>`__",""
-"`P2846R6 <https://wg21.link/P2846R6>`__","``reserve_hint``: Eagerly reserving memory for not-quite-sized lazy ranges","2025-02 (Hagenberg)","|Partial|","23","`#127884 <https://github.com/llvm/llvm-project/issues/127884>`__","``__cpp_lib_ranges_reserve_hint`` is not set. Container operations that take a range as input do not respect ``reserve_hint``. ``chunk_view`` and ``slide_view`` support blocked on `P2442R1 <https://wg21.link/P2442R1>`__. ``as_const_view`` support blocked on `P2278R4 <https://wg21.link/P2278R4>`__."
+"`P2846R6 <https://wg21.link/P2846R6>`__","``reserve_hint``: Eagerly reserving memory for not-quite-sized lazy ranges","2025-02 (Hagenberg)","|Partial|","23","`#127884 <https://github.com/llvm/llvm-project/issues/127884>`__","``__cpp_lib_ranges_reserve_hint`` is not set. Container operations that take a range as input do not respect ``reserve_hint``. ``as_const_view``, ``chunk_view``, and ``slide_view`` are not yet supported."
"`P3471R4 <https://wg21.link/P3471R4>`__","Standard Library Hardening","2025-02 (Hagenberg)","","","`#127885 <https://github.com/llvm/llvm-project/issues/127885>`__",""
"`P0447R28 <https://wg21.link/P0447R28>`__","Introduction of ``std::hive`` to the standard library","2025-02 (Hagenberg)","","","`#127886 <https://github.com/llvm/llvm-project/issues/127886>`__",""
"`P3019R14 <https://wg21.link/P3019R14>`__","``indirect`` and ``polymorphic``: Vocabulary Types for Composite Class Design","2025-02 (Hagenberg)","","","`#127887 <https://github.com/llvm/llvm-project/issues/127887>`__",""
>From ad137e8728bae1cfc8ca893b3035b6fefc4f495f Mon Sep 17 00:00:00 2001
From: inquisitivecrystal
<22333129+inquisitivecrystal at users.noreply.github.com>
Date: Wed, 1 Jul 2026 17:55:25 -0700
Subject: [PATCH 19/29] Add nodiscard tests for reserve_hint members
This change only adds nodiscard tests for reserve_hint where the view
has an existing nodiscard test. Adding a full set of nodiscard tests
for ranges that don't currently have them seems out of scope.
---
.../range.adaptors/range.all/nodiscard.verify.cpp | 14 ++++++++++++++
.../range.as_rvalue/nodiscard.verify.cpp | 8 ++++++++
.../range.common/nodiscard.verify.cpp | 9 +++++++++
.../range.concat/nodiscard.verify.cpp | 5 +++++
.../range.adaptors/range.drop/nodiscard.verify.cpp | 7 +++++++
.../range.enumerate/nodiscard.verify.cpp | 10 +++++++++-
.../range.reverse/nodiscard.verify.cpp | 8 ++++++++
.../range.stride.view/nodiscard.verify.cpp | 6 ++++++
.../range.adaptors/range.take/nodiscard.verify.cpp | 7 +++++++
.../range.transform/nodiscard.verify.cpp | 8 ++++++++
10 files changed, 81 insertions(+), 1 deletion(-)
diff --git a/libcxx/test/libcxx/ranges/range.adaptors/range.all/nodiscard.verify.cpp b/libcxx/test/libcxx/ranges/range.adaptors/range.all/nodiscard.verify.cpp
index eaa739ca87c13..6471309d39268 100644
--- a/libcxx/test/libcxx/ranges/range.adaptors/range.all/nodiscard.verify.cpp
+++ b/libcxx/test/libcxx/ranges/range.adaptors/range.all/nodiscard.verify.cpp
@@ -14,6 +14,8 @@
#include <vector>
#include <utility>
+#include "test_macros.h"
+
void test() {
std::vector<int> range;
@@ -57,6 +59,13 @@ void test() {
// expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
std::as_const(v).size();
+#if TEST_STD_VER >= 26
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ v.reserve_hint();
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::as_const(v).reserve_hint();
+#endif
+
// expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
v.data();
// expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
@@ -77,6 +86,11 @@ void test() {
// expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
v.size();
+#if TEST_STD_VER >= 26
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ v.reserve_hint();
+#endif
+
// expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
v.data();
}
diff --git a/libcxx/test/libcxx/ranges/range.adaptors/range.as_rvalue/nodiscard.verify.cpp b/libcxx/test/libcxx/ranges/range.adaptors/range.as_rvalue/nodiscard.verify.cpp
index 93e0d50886010..c46bbbb9c664b 100644
--- a/libcxx/test/libcxx/ranges/range.adaptors/range.as_rvalue/nodiscard.verify.cpp
+++ b/libcxx/test/libcxx/ranges/range.adaptors/range.as_rvalue/nodiscard.verify.cpp
@@ -13,6 +13,7 @@
#include <ranges>
#include <utility>
+#include "test_macros.h"
#include "test_range.h"
struct NonSimpleView : std::ranges::view_base {
@@ -53,6 +54,13 @@ void test() {
// expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
std::as_const(v).size();
+#if TEST_STD_VER >= 26
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ v.reserve_hint();
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::as_const(v).reserve_hint();
+#endif
+
// [range.as.rvalue.overview]
// expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
diff --git a/libcxx/test/libcxx/ranges/range.adaptors/range.common/nodiscard.verify.cpp b/libcxx/test/libcxx/ranges/range.adaptors/range.common/nodiscard.verify.cpp
index 3542251b7d436..ad199a06736f6 100644
--- a/libcxx/test/libcxx/ranges/range.adaptors/range.common/nodiscard.verify.cpp
+++ b/libcxx/test/libcxx/ranges/range.adaptors/range.common/nodiscard.verify.cpp
@@ -13,6 +13,8 @@
#include <ranges>
#include <utility>
+#include "test_macros.h"
+
struct NonCommonView : std::ranges::view_base {
int* begin() const;
const int* end() const;
@@ -51,6 +53,13 @@ void test() {
// expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
std::as_const(v).size();
+#if TEST_STD_VER >= 26
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ v.reserve_hint();
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::as_const(v).reserve_hint();
+#endif
+
// [range.common.overview]
// expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
diff --git a/libcxx/test/libcxx/ranges/range.adaptors/range.concat/nodiscard.verify.cpp b/libcxx/test/libcxx/ranges/range.adaptors/range.concat/nodiscard.verify.cpp
index b81e646d381c4..f9a3e732d8ac1 100644
--- a/libcxx/test/libcxx/ranges/range.adaptors/range.concat/nodiscard.verify.cpp
+++ b/libcxx/test/libcxx/ranges/range.adaptors/range.concat/nodiscard.verify.cpp
@@ -36,6 +36,11 @@ void test() {
// expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
std::as_const(cv).size();
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ cv.reserve_hint();
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::as_const(cv).reserve_hint();
+
// [range.concat.iterator]
auto it = cv.begin();
diff --git a/libcxx/test/libcxx/ranges/range.adaptors/range.drop/nodiscard.verify.cpp b/libcxx/test/libcxx/ranges/range.adaptors/range.drop/nodiscard.verify.cpp
index 2633c3b778c01..179bc1ab22c1c 100644
--- a/libcxx/test/libcxx/ranges/range.adaptors/range.drop/nodiscard.verify.cpp
+++ b/libcxx/test/libcxx/ranges/range.adaptors/range.drop/nodiscard.verify.cpp
@@ -45,6 +45,13 @@ void test() {
v.size();
// expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
std::as_const(v).size();
+
+#if TEST_STD_VER >= 26
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ v.reserve_hint();
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::as_const(v).reserve_hint();
+#endif
}
// [range.drop.overview]
diff --git a/libcxx/test/libcxx/ranges/range.adaptors/range.enumerate/nodiscard.verify.cpp b/libcxx/test/libcxx/ranges/range.adaptors/range.enumerate/nodiscard.verify.cpp
index 06b0d6a8c148b..a2c19427f08dd 100644
--- a/libcxx/test/libcxx/ranges/range.adaptors/range.enumerate/nodiscard.verify.cpp
+++ b/libcxx/test/libcxx/ranges/range.adaptors/range.enumerate/nodiscard.verify.cpp
@@ -14,6 +14,8 @@
#include <utility>
#include <vector>
+#include "test_macros.h"
+
void test() {
std::vector<int> range;
std::ranges::enumerate_view ev{range};
@@ -32,6 +34,12 @@ void test() {
ev.size();
// expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
std::as_const(ev).size();
+#if TEST_STD_VER >= 26
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ ev.reserve_hint();
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::as_const(ev).reserve_hint();
+#endif
// expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
ev.base();
// expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
@@ -78,4 +86,4 @@ void test() {
// expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
std::views::enumerate(range);
-}
\ No newline at end of file
+}
diff --git a/libcxx/test/libcxx/ranges/range.adaptors/range.reverse/nodiscard.verify.cpp b/libcxx/test/libcxx/ranges/range.adaptors/range.reverse/nodiscard.verify.cpp
index 6dfa2f5d17c60..612f8a2bec1b8 100644
--- a/libcxx/test/libcxx/ranges/range.adaptors/range.reverse/nodiscard.verify.cpp
+++ b/libcxx/test/libcxx/ranges/range.adaptors/range.reverse/nodiscard.verify.cpp
@@ -14,6 +14,7 @@
#include <utility>
#include "test_iterators.h"
+#include "test_macros.h"
void test() {
int range[] = {19, 28, 29, 49, 82, 94};
@@ -41,6 +42,13 @@ void test() {
// expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
std::as_const(v).size();
+#if TEST_STD_VER >= 26
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ v.reserve_hint();
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::as_const(v).reserve_hint();
+#endif
+
// [range.reverse.overview]
// expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
diff --git a/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/nodiscard.verify.cpp b/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/nodiscard.verify.cpp
index 9c48ecb68e5e3..3cc5b6f2db9b2 100644
--- a/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/nodiscard.verify.cpp
+++ b/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/nodiscard.verify.cpp
@@ -13,6 +13,8 @@
#include <ranges>
#include <utility>
+#include "test_macros.h"
+
void test() {
int range[] = {1, 2, 3};
auto sv = std::ranges::stride_view(range, 2);
@@ -27,6 +29,10 @@ void test() {
sv.end();
// expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
sv.size();
+#if TEST_STD_VER >= 26
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ sv.reserve_hint();
+#endif
// expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
sv.stride();
// expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
diff --git a/libcxx/test/libcxx/ranges/range.adaptors/range.take/nodiscard.verify.cpp b/libcxx/test/libcxx/ranges/range.adaptors/range.take/nodiscard.verify.cpp
index 621b20b29e3a1..457b42296543e 100644
--- a/libcxx/test/libcxx/ranges/range.adaptors/range.take/nodiscard.verify.cpp
+++ b/libcxx/test/libcxx/ranges/range.adaptors/range.take/nodiscard.verify.cpp
@@ -46,6 +46,13 @@ void test() {
v.size();
// expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
std::as_const(v).size();
+
+#if TEST_STD_VER >= 26
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ v.reserve_hint();
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::as_const(v).reserve_hint();
+#endif
}
// [range.take.sentinel]
diff --git a/libcxx/test/libcxx/ranges/range.adaptors/range.transform/nodiscard.verify.cpp b/libcxx/test/libcxx/ranges/range.adaptors/range.transform/nodiscard.verify.cpp
index 76ffa16d233f5..76e4d2dc8d84f 100644
--- a/libcxx/test/libcxx/ranges/range.adaptors/range.transform/nodiscard.verify.cpp
+++ b/libcxx/test/libcxx/ranges/range.adaptors/range.transform/nodiscard.verify.cpp
@@ -15,6 +15,7 @@
#include <functional>
#include "test_iterators.h"
+#include "test_macros.h"
struct View : std::ranges::view_interface<View> {
int* begin();
@@ -51,6 +52,13 @@ void test() {
// expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
std::as_const(v).size();
+#if TEST_STD_VER >= 26
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ v.reserve_hint();
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::as_const(v).reserve_hint();
+#endif
+
// [range.transform.iterator]
auto it = v.begin();
>From 67da03b280caccd291ddd69a5dbd77844c008765 Mon Sep 17 00:00:00 2001
From: inquisitivecrystal
<22333129+inquisitivecrystal at users.noreply.github.com>
Date: Thu, 2 Jul 2026 20:39:38 -0700
Subject: [PATCH 20/29] Add reserve_hint to the library-wide CPO test
---
.../conventions/customization.point.object/cpo.compile.pass.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
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 d83ca7f2eabfc..109ad92f4df3e 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
@@ -82,7 +82,7 @@ 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));
+static_assert(test(std::ranges::reserve_hint, a));
#endif
// [range.factories]
>From 2dee3c1cae9e8a4aff043df30933a34670a26679 Mon Sep 17 00:00:00 2001
From: inquisitivecrystal
<22333129+inquisitivecrystal at users.noreply.github.com>
Date: Thu, 2 Jul 2026 21:35:01 -0700
Subject: [PATCH 21/29] Add remaining reserve_hint nodiscard tests
---
.../nodiscard.verify.cpp | 32 ++++++++++++++++++
.../range.adjacent/nodiscard.verify.cpp | 32 ++++++++++++++++++
.../range.elements/nodiscard.verify.cpp | 33 +++++++++++++++++++
3 files changed, 97 insertions(+)
create mode 100644 libcxx/test/libcxx/ranges/range.adaptors/range.adjacent.transform/nodiscard.verify.cpp
create mode 100644 libcxx/test/libcxx/ranges/range.adaptors/range.adjacent/nodiscard.verify.cpp
create mode 100644 libcxx/test/libcxx/ranges/range.adaptors/range.elements/nodiscard.verify.cpp
diff --git a/libcxx/test/libcxx/ranges/range.adaptors/range.adjacent.transform/nodiscard.verify.cpp b/libcxx/test/libcxx/ranges/range.adaptors/range.adjacent.transform/nodiscard.verify.cpp
new file mode 100644
index 0000000000000..cfc81554ad863
--- /dev/null
+++ b/libcxx/test/libcxx/ranges/range.adaptors/range.adjacent.transform/nodiscard.verify.cpp
@@ -0,0 +1,32 @@
+//===----------------------------------------------------------------------===//
+//
+// 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++26
+
+// Check that functions are marked [[nodiscard]]
+
+// TODO: this test should eventually be expanded to cover functions beyond
+// reserve_hint; at that time, it should be std-at-least-c++23
+
+#include <ranges>
+#include <utility>
+#include <vector>
+
+#include "test_macros.h"
+
+void test() {
+ std::vector<int> range;
+ auto v = std::views::adjacent_transform<2>(range, [](int a, int b) { return a + b; });
+
+#if TEST_STD_VER >= 26
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ v.reserve_hint();
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::as_const(v).reserve_hint();
+#endif
+}
diff --git a/libcxx/test/libcxx/ranges/range.adaptors/range.adjacent/nodiscard.verify.cpp b/libcxx/test/libcxx/ranges/range.adaptors/range.adjacent/nodiscard.verify.cpp
new file mode 100644
index 0000000000000..46872b6e52985
--- /dev/null
+++ b/libcxx/test/libcxx/ranges/range.adaptors/range.adjacent/nodiscard.verify.cpp
@@ -0,0 +1,32 @@
+//===----------------------------------------------------------------------===//
+//
+// 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++26
+
+// Check that functions are marked [[nodiscard]]
+
+// TODO: this test should eventually be expanded to cover functions beyond
+// reserve_hint; at that time, it should be std-at-least-c++23
+
+#include <ranges>
+#include <utility>
+#include <vector>
+
+#include "test_macros.h"
+
+void test() {
+ std::vector<int> range;
+ auto v = std::views::adjacent<2>(range);
+
+#if TEST_STD_VER >= 26
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ v.reserve_hint();
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::as_const(v).reserve_hint();
+#endif
+}
diff --git a/libcxx/test/libcxx/ranges/range.adaptors/range.elements/nodiscard.verify.cpp b/libcxx/test/libcxx/ranges/range.adaptors/range.elements/nodiscard.verify.cpp
new file mode 100644
index 0000000000000..2197a1ea9cde8
--- /dev/null
+++ b/libcxx/test/libcxx/ranges/range.adaptors/range.elements/nodiscard.verify.cpp
@@ -0,0 +1,33 @@
+//===----------------------------------------------------------------------===//
+//
+// 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++26
+
+// Check that functions are marked [[nodiscard]]
+
+// TODO: this test should eventually be expanded to cover functions beyond
+// reserve_hint; at that time, it should be std-at-least-c++20
+
+#include <ranges>
+#include <tuple>
+#include <utility>
+#include <vector>
+
+#include "test_macros.h"
+
+void test() {
+ std::vector<std::tuple<int>> range;
+ auto v = std::views::elements<0>(range);
+
+#if TEST_STD_VER >= 26
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ v.reserve_hint();
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::as_const(v).reserve_hint();
+#endif
+}
>From 86f59d72480a80cb0d3325cac1ee59d5b08524bb Mon Sep 17 00:00:00 2001
From: inquisitivecrystal
<22333129+inquisitivecrystal at users.noreply.github.com>
Date: Tue, 7 Jul 2026 04:18:49 -0700
Subject: [PATCH 22/29] Permit reserve_hint's unqualified lookup
reserve_hint must use ADL per the specification, and thus needs to
be exempted from the libcpp-robust-against-adl check like other
CPOs.
---
libcxx/test/tools/clang_tidy_checks/robust_against_adl.cpp | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/libcxx/test/tools/clang_tidy_checks/robust_against_adl.cpp b/libcxx/test/tools/clang_tidy_checks/robust_against_adl.cpp
index 1bfe96b414b7c..16c45a524811e 100644
--- a/libcxx/test/tools/clang_tidy_checks/robust_against_adl.cpp
+++ b/libcxx/test/tools/clang_tidy_checks/robust_against_adl.cpp
@@ -20,7 +20,8 @@ AST_MATCHER(clang::CallExpr, isOperator) { return llvm::isa<clang::CXXOperatorCa
AST_MATCHER(clang::UnresolvedLookupExpr, isCustomizationPoint) {
return std::ranges::any_of(
- std::array{"swap", "make_error_code", "make_error_condition", "begin", "end", "size", "rend", "rbegin"},
+ std::array{
+ "swap", "make_error_code", "make_error_condition", "begin", "end", "size", "rend", "rbegin", "reserve_hint"},
[&](const char* func) { return Node.getName().getAsString() == func; });
}
>From 0020ac432662be8ace647b3c92368cbc13744c24 Mon Sep 17 00:00:00 2001
From: inquisitivecrystal
<22333129+inquisitivecrystal at users.noreply.github.com>
Date: Tue, 7 Jul 2026 06:14:47 -0700
Subject: [PATCH 23/29] Fix unused variable warning from GCC
---
libcxx/test/std/ranges/range.access/reserve_hint.pass.cpp | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/libcxx/test/std/ranges/range.access/reserve_hint.pass.cpp b/libcxx/test/std/ranges/range.access/reserve_hint.pass.cpp
index 11379bedf7bf2..6b6a8523afbdc 100644
--- a/libcxx/test/std/ranges/range.access/reserve_hint.pass.cpp
+++ b/libcxx/test/std/ranges/range.access/reserve_hint.pass.cpp
@@ -39,7 +39,7 @@ struct HasSizeMember {
};
struct HasSizeFunction {
- friend constexpr std::size_t size(HasSizeFunction _) { return 42; }
+ friend constexpr std::size_t size(HasSizeFunction) { return 42; }
};
struct HasReserveHintMember {
@@ -47,7 +47,7 @@ struct HasReserveHintMember {
};
struct HasReserveHintFunction {
- friend constexpr std::size_t reserve_hint(HasReserveHintFunction _) { return 42; }
+ friend constexpr std::size_t reserve_hint(HasReserveHintFunction) { return 42; }
};
struct HasReserveHintMemberBool {
@@ -86,12 +86,12 @@ ASSERT_SAME_TYPE(decltype(std::ranges::reserve_hint(HasReserveHintFunction{})),
struct HasSizeAndReserveHint {
constexpr std::size_t size() { return 42; }
constexpr std::size_t reserve_hint() { return 0; }
- friend constexpr std::size_t reserve_hint(HasSizeAndReserveHint _) { return 0; }
+ friend constexpr std::size_t reserve_hint(HasSizeAndReserveHint) { return 0; }
};
struct HasReserveHintMemberAndFunction {
constexpr std::size_t reserve_hint() { return 42; }
- friend constexpr std::size_t reserve_hint(HasReserveHintMemberAndFunction _) { return 0; }
+ friend constexpr std::size_t reserve_hint(HasReserveHintMemberAndFunction) { return 0; }
};
static_assert(std::ranges::reserve_hint(HasSizeAndReserveHint{}) == 42);
>From 6b09d9baea9a8cd77b0c916fcc0ae043fe8a1d0d Mon Sep 17 00:00:00 2001
From: inquisitivecrystal
<22333129+inquisitivecrystal at users.noreply.github.com>
Date: Tue, 7 Jul 2026 22:24:20 -0700
Subject: [PATCH 24/29] Address review comments
---
.../range.adaptors/range.stride.view/nodiscard.verify.cpp | 4 ++++
.../test/std/ranges/range.adaptors/range.common.view/types.h | 2 +-
2 files changed, 5 insertions(+), 1 deletion(-)
diff --git a/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/nodiscard.verify.cpp b/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/nodiscard.verify.cpp
index 3cc5b6f2db9b2..e4df227ff44c8 100644
--- a/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/nodiscard.verify.cpp
+++ b/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/nodiscard.verify.cpp
@@ -32,6 +32,10 @@ void test() {
#if TEST_STD_VER >= 26
// expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
sv.reserve_hint();
+
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::as_const(sv).reserve_hint();
+
#endif
// expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
sv.stride();
diff --git a/libcxx/test/std/ranges/range.adaptors/range.common.view/types.h b/libcxx/test/std/ranges/range.adaptors/range.common.view/types.h
index 130423389ad68..670837aa47744 100644
--- a/libcxx/test/std/ranges/range.adaptors/range.common.view/types.h
+++ b/libcxx/test/std/ranges/range.adaptors/range.common.view/types.h
@@ -11,8 +11,8 @@
#include <ranges>
-#include "test_macros.h"
#include "test_iterators.h"
+#include "test_macros.h"
struct DefaultConstructibleView : std::ranges::view_base {
int* begin_ = nullptr;
>From d02f2fb321edd1e7d48f651d6d39a7954b251206 Mon Sep 17 00:00:00 2001
From: inquisitivecrystal <open-source at inquisitivecrystal.addy.io>
Date: Fri, 10 Jul 2026 19:29:28 -0700
Subject: [PATCH 25/29] Empty commit for CI
>From fdb58ee8c8174b1bd8162cb7729cdff9e65eb98f Mon Sep 17 00:00:00 2001
From: inquisitivecrystal <open-source at inquisitivecrystal.addy.io>
Date: Fri, 10 Jul 2026 20:10:21 -0700
Subject: [PATCH 26/29] Avoid creating an empty namespace before c++26
---
libcxx/include/__ranges/reserve_hint.h | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/libcxx/include/__ranges/reserve_hint.h b/libcxx/include/__ranges/reserve_hint.h
index b3b4be59f8941..e58990bf1194e 100644
--- a/libcxx/include/__ranges/reserve_hint.h
+++ b/libcxx/include/__ranges/reserve_hint.h
@@ -20,9 +20,10 @@
# pragma GCC system_header
#endif
+#if _LIBCPP_STD_VER >= 26
+
_LIBCPP_BEGIN_NAMESPACE_STD
-#if _LIBCPP_STD_VER >= 26
// [range.prim.size.hint]
namespace ranges {
@@ -72,8 +73,8 @@ inline constexpr auto reserve_hint = __reserve_hint::__fn{};
} // namespace __cpo
} // namespace ranges
-#endif // _LIBCPP_STD_VER >= 26
-
_LIBCPP_END_NAMESPACE_STD
+#endif // _LIBCPP_STD_VER >= 26
+
#endif // _LIBCPP___RANGES_RESERVE_HINT_H
>From f09928004b010011e4cb7db2f9fbbc01cedab590 Mon Sep 17 00:00:00 2001
From: inquisitivecrystal <open-source at inquisitivecrystal.addy.io>
Date: Wed, 15 Jul 2026 14:50:58 -0700
Subject: [PATCH 27/29] Bump version in reserve_hint status entries
This updates the status page to show that we are now targeting
libc++24.
---
libcxx/docs/Status/Cxx26Issues.csv | 2 +-
libcxx/docs/Status/Cxx26Papers.csv | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/libcxx/docs/Status/Cxx26Issues.csv b/libcxx/docs/Status/Cxx26Issues.csv
index 718dbf6677aba..7a4c7087dfd11 100644
--- a/libcxx/docs/Status/Cxx26Issues.csv
+++ b/libcxx/docs/Status/Cxx26Issues.csv
@@ -336,7 +336,7 @@
"`LWG4549 <https://wg21.link/LWG4549>`__","``vprint_nonunicode_buffered`` ignores its stream parameter","2026-03 (Croydon)","","","`#189878 <https://github.com/llvm/llvm-project/issues/189878>`__",""
"`LWG4550 <https://wg21.link/LWG4550>`__","Need new feature test macros for ``<stdckdint.h>`` and ``<stdbit.h>``","2026-03 (Croydon)","","","`#189879 <https://github.com/llvm/llvm-project/issues/189879>`__",""
"`LWG4552 <https://wg21.link/LWG4552>`__","``compare_exchange_weak`` writes a value on spurious failure, not memory contents","2026-03 (Croydon)","","","`#189880 <https://github.com/llvm/llvm-project/issues/189880>`__",""
-"`LWG4553 <https://wg21.link/LWG4553>`__","Wording for FR-025-246 25.7.18.2 Add a ``reserve_hint`` function to ``concat_view``","2026-03 (Croydon)","|Complete|","23","`#189881 <https://github.com/llvm/llvm-project/issues/189881>`__",""
+"`LWG4553 <https://wg21.link/LWG4553>`__","Wording for FR-025-246 25.7.18.2 Add a ``reserve_hint`` function to ``concat_view``","2026-03 (Croydon)","|Complete|","24","`#189881 <https://github.com/llvm/llvm-project/issues/189881>`__",""
"`LWG4554 <https://wg21.link/LWG4554>`__","Remove undefined behaviour from ``hive`` for invalid limits","2026-03 (Croydon)","","","`#189882 <https://github.com/llvm/llvm-project/issues/189882>`__",""
"`LWG4555 <https://wg21.link/LWG4555>`__","Remove ``is_consteval_only``","2026-03 (Croydon)","","","`#189883 <https://github.com/llvm/llvm-project/issues/189883>`__",""
"`LWG4556 <https://wg21.link/LWG4556>`__","Unclear properties of reflection strings","2026-03 (Croydon)","","","`#189884 <https://github.com/llvm/llvm-project/issues/189884>`__",""
diff --git a/libcxx/docs/Status/Cxx26Papers.csv b/libcxx/docs/Status/Cxx26Papers.csv
index 398ba8e4d60bd..d98a62cfa3418 100644
--- a/libcxx/docs/Status/Cxx26Papers.csv
+++ b/libcxx/docs/Status/Cxx26Papers.csv
@@ -112,7 +112,7 @@
"`P3430R3 <https://wg21.link/P3430R3>`__","simd issues: explicit, unsequenced, identity-element position, and members of disabled simd","2025-02 (Hagenberg)","","","`#127881 <https://github.com/llvm/llvm-project/issues/127881>`__",""
"`P2663R7 <https://wg21.link/P2663R7>`__","Interleaved complex values support in ``std::simd``","2025-02 (Hagenberg)","","","`#127882 <https://github.com/llvm/llvm-project/issues/127882>`__",""
"`P2933R4 <https://wg21.link/P2933R4>`__","Extend ``<bit>`` header function with overloads for ``std::simd``","2025-02 (Hagenberg)","","","`#127883 <https://github.com/llvm/llvm-project/issues/127883>`__",""
-"`P2846R6 <https://wg21.link/P2846R6>`__","``reserve_hint``: Eagerly reserving memory for not-quite-sized lazy ranges","2025-02 (Hagenberg)","|Partial|","23","`#127884 <https://github.com/llvm/llvm-project/issues/127884>`__","``__cpp_lib_ranges_reserve_hint`` is not set. Container operations that take a range as input do not respect ``reserve_hint``. ``as_const_view``, ``chunk_view``, and ``slide_view`` are not yet supported."
+"`P2846R6 <https://wg21.link/P2846R6>`__","``reserve_hint``: Eagerly reserving memory for not-quite-sized lazy ranges","2025-02 (Hagenberg)","|Partial|","24","`#127884 <https://github.com/llvm/llvm-project/issues/127884>`__","``__cpp_lib_ranges_reserve_hint`` is not set. Container operations that take a range as input do not respect ``reserve_hint``. ``as_const_view``, ``chunk_view``, and ``slide_view`` are not yet supported."
"`P3471R4 <https://wg21.link/P3471R4>`__","Standard Library Hardening","2025-02 (Hagenberg)","","","`#127885 <https://github.com/llvm/llvm-project/issues/127885>`__",""
"`P0447R28 <https://wg21.link/P0447R28>`__","Introduction of ``std::hive`` to the standard library","2025-02 (Hagenberg)","","","`#127886 <https://github.com/llvm/llvm-project/issues/127886>`__",""
"`P3019R14 <https://wg21.link/P3019R14>`__","``indirect`` and ``polymorphic``: Vocabulary Types for Composite Class Design","2025-02 (Hagenberg)","","","`#127887 <https://github.com/llvm/llvm-project/issues/127887>`__",""
>From 4453a8674737ea7dc8155a860bf891d5d947f37a Mon Sep 17 00:00:00 2001
From: inquisitivecrystal <open-source at inquisitivecrystal.addy.io>
Date: Wed, 15 Jul 2026 20:57:39 -0700
Subject: [PATCH 28/29] Remove comment on #else block in concepts.h
This seems to better align with standard practice.
---
libcxx/include/__ranges/concepts.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/libcxx/include/__ranges/concepts.h b/libcxx/include/__ranges/concepts.h
index cae59e3946daa..99a2acfe922c5 100644
--- a/libcxx/include/__ranges/concepts.h
+++ b/libcxx/include/__ranges/concepts.h
@@ -91,7 +91,7 @@ concept approximately_sized_range = range<_Tp> && requires(_Tp& __t) { ranges::r
template <class _Tp>
concept sized_range = approximately_sized_range<_Tp> && requires(_Tp& __t) { ranges::size(__t); };
-# else // _LIBCPP_STD_VER < 26
+# else
// [range.sized]
template <class _Tp>
>From 4e65763bcb696ecda24693a6b67cc7e0318ceea3 Mon Sep 17 00:00:00 2001
From: inquisitivecrystal <open-source at inquisitivecrystal.addy.io>
Date: Wed, 15 Jul 2026 21:06:33 -0700
Subject: [PATCH 29/29] Add spaces between `//`` and comment text
This change is applied on all of my `#endif` comments, which were
consistently irregular in missing spaces in this location.
---
libcxx/include/__ranges/adjacent_transform_view.h | 2 +-
libcxx/include/__ranges/adjacent_view.h | 2 +-
libcxx/include/__ranges/as_rvalue_view.h | 2 +-
libcxx/include/__ranges/common_view.h | 2 +-
libcxx/include/__ranges/drop_view.h | 2 +-
libcxx/include/__ranges/elements_view.h | 2 +-
libcxx/include/__ranges/enumerate_view.h | 2 +-
libcxx/include/__ranges/owning_view.h | 2 +-
libcxx/include/__ranges/ref_view.h | 2 +-
libcxx/include/__ranges/reverse_view.h | 2 +-
libcxx/include/__ranges/stride_view.h | 2 +-
libcxx/include/__ranges/take_view.h | 2 +-
libcxx/include/__ranges/transform_view.h | 2 +-
13 files changed, 13 insertions(+), 13 deletions(-)
diff --git a/libcxx/include/__ranges/adjacent_transform_view.h b/libcxx/include/__ranges/adjacent_transform_view.h
index 6991fe2e19803..a833c0dee4fd4 100644
--- a/libcxx/include/__ranges/adjacent_transform_view.h
+++ b/libcxx/include/__ranges/adjacent_transform_view.h
@@ -164,7 +164,7 @@ class adjacent_transform_view : public view_interface<adjacent_transform_view<_V
return __inner_.reserve_hint();
}
-# endif //_LIBCPP_STD_VER >= 26
+# endif // _LIBCPP_STD_VER >= 26
};
template <forward_range _View, move_constructible _Fn, size_t _Np>
diff --git a/libcxx/include/__ranges/adjacent_view.h b/libcxx/include/__ranges/adjacent_view.h
index c483c04a11373..db9edb5cf46f2 100644
--- a/libcxx/include/__ranges/adjacent_view.h
+++ b/libcxx/include/__ranges/adjacent_view.h
@@ -163,7 +163,7 @@ class adjacent_view : public view_interface<adjacent_view<_View, _Np>> {
return static_cast<_ST>(__sz);
}
-# endif //_LIBCPP_STD_VER >= 26
+# endif // _LIBCPP_STD_VER >= 26
};
struct __adjacent_view_iter_access {
diff --git a/libcxx/include/__ranges/as_rvalue_view.h b/libcxx/include/__ranges/as_rvalue_view.h
index 1e1dccf55fe7c..ddd2f9a75c267 100644
--- a/libcxx/include/__ranges/as_rvalue_view.h
+++ b/libcxx/include/__ranges/as_rvalue_view.h
@@ -115,7 +115,7 @@ class as_rvalue_view : public view_interface<as_rvalue_view<_View>> {
return ranges::reserve_hint(__base_);
}
-# endif //_LIBCPP_STD_VER >= 26
+# endif // _LIBCPP_STD_VER >= 26
};
template <class _Range>
diff --git a/libcxx/include/__ranges/common_view.h b/libcxx/include/__ranges/common_view.h
index 40acab0331676..c232fb533e1db 100644
--- a/libcxx/include/__ranges/common_view.h
+++ b/libcxx/include/__ranges/common_view.h
@@ -117,7 +117,7 @@ class common_view : public view_interface<common_view<_View>> {
return ranges::reserve_hint(__base_);
}
-# endif //_LIBCPP_STD_VER >= 26
+# endif // _LIBCPP_STD_VER >= 26
};
template <class _Range>
diff --git a/libcxx/include/__ranges/drop_view.h b/libcxx/include/__ranges/drop_view.h
index c165e848b6e79..2776df6175797 100644
--- a/libcxx/include/__ranges/drop_view.h
+++ b/libcxx/include/__ranges/drop_view.h
@@ -157,7 +157,7 @@ class drop_view : public view_interface<drop_view<_View>> {
return std::__to_unsigned_like(__s < __count_ ? 0 : __s - __count_);
}
-# endif //_LIBCPP_STD_VER >= 26
+# endif // _LIBCPP_STD_VER >= 26
};
template <class _Range>
diff --git a/libcxx/include/__ranges/elements_view.h b/libcxx/include/__ranges/elements_view.h
index 9397e6b109aa6..3d91f5e4c1d6e 100644
--- a/libcxx/include/__ranges/elements_view.h
+++ b/libcxx/include/__ranges/elements_view.h
@@ -148,7 +148,7 @@ class elements_view : public view_interface<elements_view<_View, _Np>> {
return ranges::reserve_hint(__base_);
}
-# endif //_LIBCPP_STD_VER >= 26
+# endif // _LIBCPP_STD_VER >= 26
private:
_LIBCPP_NO_UNIQUE_ADDRESS _View __base_ = _View();
diff --git a/libcxx/include/__ranges/enumerate_view.h b/libcxx/include/__ranges/enumerate_view.h
index 26d9098b40e87..8845e6caa1421 100644
--- a/libcxx/include/__ranges/enumerate_view.h
+++ b/libcxx/include/__ranges/enumerate_view.h
@@ -131,7 +131,7 @@ class enumerate_view : public view_interface<enumerate_view<_View>> {
return ranges::reserve_hint(__base_);
}
-# endif //_LIBCPP_STD_VER >= 26
+# endif // _LIBCPP_STD_VER >= 26
};
template <class _Range>
diff --git a/libcxx/include/__ranges/owning_view.h b/libcxx/include/__ranges/owning_view.h
index 4b154b7c0b9aa..e30f6da11f907 100644
--- a/libcxx/include/__ranges/owning_view.h
+++ b/libcxx/include/__ranges/owning_view.h
@@ -115,7 +115,7 @@ class owning_view : public view_interface<owning_view<_Rp>> {
return ranges::reserve_hint(__r_);
}
-# endif //_LIBCPP_STD_VER >= 26
+# endif // _LIBCPP_STD_VER >= 26
};
_LIBCPP_CTAD_SUPPORTED_FOR_TYPE(owning_view);
diff --git a/libcxx/include/__ranges/ref_view.h b/libcxx/include/__ranges/ref_view.h
index f3f6eb11620fd..9d65a536d5a09 100644
--- a/libcxx/include/__ranges/ref_view.h
+++ b/libcxx/include/__ranges/ref_view.h
@@ -82,7 +82,7 @@ class ref_view : public view_interface<ref_view<_Range>> {
return ranges::reserve_hint(*__range_);
}
-# endif //_LIBCPP_STD_VER >= 26
+# endif // _LIBCPP_STD_VER >= 26
};
template <class _Range>
diff --git a/libcxx/include/__ranges/reverse_view.h b/libcxx/include/__ranges/reverse_view.h
index 7f2ea094710fb..fe8e40b74e1b7 100644
--- a/libcxx/include/__ranges/reverse_view.h
+++ b/libcxx/include/__ranges/reverse_view.h
@@ -127,7 +127,7 @@ class reverse_view : public view_interface<reverse_view<_View>> {
return ranges::reserve_hint(__base_);
}
-# endif //_LIBCPP_STD_VER >= 26
+# endif // _LIBCPP_STD_VER >= 26
};
template <class _Range>
diff --git a/libcxx/include/__ranges/stride_view.h b/libcxx/include/__ranges/stride_view.h
index 45a57015eab6a..3f1c841cdd047 100644
--- a/libcxx/include/__ranges/stride_view.h
+++ b/libcxx/include/__ranges/stride_view.h
@@ -147,7 +147,7 @@ class stride_view : public view_interface<stride_view<_View>> {
return std::__to_unsigned_like(ranges::__div_ceil(__s, __stride_));
}
-# endif //_LIBCPP_STD_VER >= 26
+# endif // _LIBCPP_STD_VER >= 26
}; // class stride_view
template <class _Range>
diff --git a/libcxx/include/__ranges/take_view.h b/libcxx/include/__ranges/take_view.h
index c2c61b1269ade..53a800f7f4b44 100644
--- a/libcxx/include/__ranges/take_view.h
+++ b/libcxx/include/__ranges/take_view.h
@@ -176,7 +176,7 @@ class take_view : public view_interface<take_view<_View>> {
return std::__to_unsigned_like(__count_);
}
-# endif //_LIBCPP_STD_VER >= 26
+# endif // _LIBCPP_STD_VER >= 26
};
template <view _View>
diff --git a/libcxx/include/__ranges/transform_view.h b/libcxx/include/__ranges/transform_view.h
index 95af90468d536..be4ae7da77f4e 100644
--- a/libcxx/include/__ranges/transform_view.h
+++ b/libcxx/include/__ranges/transform_view.h
@@ -155,7 +155,7 @@ class _LIBCPP_ABI_LLVM18_NO_UNIQUE_ADDRESS transform_view : public view_interfac
return ranges::reserve_hint(__base_);
}
-# endif //_LIBCPP_STD_VER >= 26
+# endif // _LIBCPP_STD_VER >= 26
};
template <class _Range, class _Fn>
More information about the libcxx-commits
mailing list