[libcxx-commits] [libcxx] [libcxx][c++26] P3137R3 views::to_input (PR #146396)
via libcxx-commits
libcxx-commits at lists.llvm.org
Tue Jul 8 02:07:12 PDT 2025
https://github.com/dywoq updated https://github.com/llvm/llvm-project/pull/146396
>From 03ec2ad766833c70aee79402957d26ea614f0d5b Mon Sep 17 00:00:00 2001
From: dywoq <aleks.koyf at gmail.com>
Date: Mon, 30 Jun 2025 18:18:33 +0300
Subject: [PATCH 01/14] [libcxx] add class to_input_view to_input_view.h
---
libcxx/.clangd | 2 +
libcxx/include/__ranges/to_input_view.h | 100 ++++++++++++++++++++++++
2 files changed, 102 insertions(+)
create mode 100644 libcxx/.clangd
create mode 100644 libcxx/include/__ranges/to_input_view.h
diff --git a/libcxx/.clangd b/libcxx/.clangd
new file mode 100644
index 0000000000000..8a80936175292
--- /dev/null
+++ b/libcxx/.clangd
@@ -0,0 +1,2 @@
+CompileFlags:
+ Add: [--std=c++2c]
\ No newline at end of file
diff --git a/libcxx/include/__ranges/to_input_view.h b/libcxx/include/__ranges/to_input_view.h
new file mode 100644
index 0000000000000..eed017a9fadb0
--- /dev/null
+++ b/libcxx/include/__ranges/to_input_view.h
@@ -0,0 +1,100 @@
+// -*- 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_TO_INPUT_VIEW_H
+#define _LIBCPP___RANGES_TO_INPUT_VIEW_H
+
+#include <__concepts/constructible.h>
+#include <__config>
+#include <__ranges/all.h>
+#include <__ranges/concepts.h>
+#include <__ranges/range_adaptor.h>
+#include <__ranges/view_interface.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#if _LIBCPP_STD_VER >= 26
+
+namespace ranges {
+
+template <input_range _V>
+ requires view<_V>
+class to_input_view : public view_interface<to_input_view<_V>> {
+private:
+ _V __base_;
+
+ template <bool _Cont>
+ class __iterator;
+
+public:
+ _LIBCPP_HIDE_FROM_ABI to_input_view()
+ requires default_initializable<_V>
+ = default;
+
+ _LIBCPP_HIDE_FROM_ABI constexpr explicit to_input_view(_V __base) : __base_(std::move(__base)) {}
+
+ // base
+ _LIBCPP_HIDE_FROM_ABI constexpr _V base() const&
+ requires copy_constructible<_V>
+ {
+ return __base_;
+ }
+ _LIBCPP_HIDE_FROM_ABI constexpr _V base() && { return std::move(__base_); }
+
+ // begin
+ _LIBCPP_HIDE_FROM_ABI constexpr auto begin()
+ requires(!__simple_view<_V>)
+ {
+ return __iterator<false>(ranges::begin(__base_));
+ }
+ _LIBCPP_HIDE_FROM_ABI constexpr auto begin() const
+ requires range<const _V>
+ {
+ return __iterator<true>(ranges::begin(__base_));
+ }
+
+ // end
+ _LIBCPP_HIDE_FROM_ABI constexpr auto end()
+ requires(!__simple_view<_V>)
+ {
+ return ranges::end(__base_);
+ }
+ _LIBCPP_HIDE_FROM_ABI constexpr auto end() const
+ requires range<const _V>
+ {
+ return ranges::end(__base_);
+ }
+
+ // size
+ _LIBCPP_HIDE_FROM_ABI constexpr auto size()
+ requires sized_range<_V>
+ {
+ return ranges::size(__base_);
+ }
+ _LIBCPP_HIDE_FROM_ABI constexpr auto size() const
+ requires sized_range<const _V>
+ {
+ return ranges::size(__base_);
+ }
+};
+
+template <class _R>
+to_input_view(_R&&) -> to_input_view<ranges::views::all_t<_R>>;
+
+} // namespace ranges
+
+#endif // _LIBCPP_STD_VER >= 23
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___RANGES_FROM_RANGE_H
>From ae6b1e3d894e63ddfbd67656c638b512cd6c1afa Mon Sep 17 00:00:00 2001
From: dywoq <aleks.koyf at gmail.com>
Date: Mon, 30 Jun 2025 18:45:09 +0300
Subject: [PATCH 02/14] [libcxx] implement to_input_view<_V>::__iterator class
---
libcxx/include/__ranges/to_input_view.h | 76 ++++++++++++++++++++++++-
1 file changed, 74 insertions(+), 2 deletions(-)
diff --git a/libcxx/include/__ranges/to_input_view.h b/libcxx/include/__ranges/to_input_view.h
index eed017a9fadb0..d7d38783585b2 100644
--- a/libcxx/include/__ranges/to_input_view.h
+++ b/libcxx/include/__ranges/to_input_view.h
@@ -10,12 +10,18 @@
#ifndef _LIBCPP___RANGES_TO_INPUT_VIEW_H
#define _LIBCPP___RANGES_TO_INPUT_VIEW_H
+#include <__algorithm/iter_swap.h>
#include <__concepts/constructible.h>
#include <__config>
+#include <__iterator/indirectly_comparable.h>
+#include <__iterator/iter_move.h>
+#include <__iterator/iter_swap.h>
+#include <__ranges/access.h>
#include <__ranges/all.h>
#include <__ranges/concepts.h>
#include <__ranges/range_adaptor.h>
#include <__ranges/view_interface.h>
+#include <__type_traits/maybe_const.h>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
@@ -91,10 +97,76 @@ class to_input_view : public view_interface<to_input_view<_V>> {
template <class _R>
to_input_view(_R&&) -> to_input_view<ranges::views::all_t<_R>>;
+template <input_range _V>
+ requires view<_V>
+template <bool _Const>
+class to_input_view<_V>::__iterator {
+ using _Base = __maybe_const<_Const, _V>;
+ iterator_t<_Base> __current_ = iterator_t<_Base>();
+
+ _LIBCPP_HIDE_FROM_ABI constexpr explicit __iterator(iterator_t<_Base> __current) : __current_(std::move(__current)) {}
+
+public:
+ using difference_type = range_difference_t<_Base>;
+ using value_type = range_value_t<_Base>;
+ using iterator_concept = input_iterator_tag;
+
+ _LIBCPP_HIDE_FROM_ABI __iterator()
+ requires default_initializable<iterator_t<_Base>>
+ = default;
+
+ _LIBCPP_HIDE_FROM_ABI __iterator(__iterator&&) = default;
+ _LIBCPP_HIDE_FROM_ABI __iterator& operator=(__iterator&&) = default;
+
+ _LIBCPP_HIDE_FROM_ABI constexpr __iterator(__iterator<!_Const> __i)
+ requires _Const && convertible_to<iterator_t<_V>, iterator_t<_Base>>
+ : __current_(std::move(__i.__current_)) {}
+
+ // base
+ _LIBCPP_HIDE_FROM_ABI constexpr iterator_t<_Base> base() &&;
+ _LIBCPP_HIDE_FROM_ABI constexpr const iterator_t<_Base>& base() const& noexcept;
+
+ // operator ++
+ _LIBCPP_HIDE_FROM_ABI constexpr __iterator& operator++() {
+ ++__current_;
+ return *this;
+ }
+ _LIBCPP_HIDE_FROM_ABI constexpr void operator++(int) { ++*this; }
+
+ // operator==
+ _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator==(const __iterator& __x, const sentinel_t<_Base>& __y) {
+ return __x.__current_ == __y;
+ }
+
+ // operator --
+ _LIBCPP_HIDE_FROM_ABI friend constexpr difference_type operator-(const sentinel_t<_Base>& __y, const __iterator& __x)
+ requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base>>
+ {
+ return __y - __x.__current_;
+ }
+ _LIBCPP_HIDE_FROM_ABI friend constexpr difference_type operator-(const __iterator& __x, const sentinel_t<_Base>& __y)
+ requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base>>
+ {
+ return __x.__current_ - __y;
+ }
+
+ _LIBCPP_HIDE_FROM_ABI friend constexpr range_rvalue_reference_t<_Base>
+ iter_move(const __iterator& __i) noexcept(noexcept(ranges::iter_move(__i.__current_))) {
+ return ranges::iter_move(__i.__current_);
+ }
+
+ _LIBCPP_HIDE_FROM_ABI friend constexpr void
+ iter_swap(const __iterator& __x, const __iterator& __y) noexcept(noexcept(iter_swap(__x.__current_, __y.__current_)))
+ requires indirectly_swappable<iterator_t<_Base>>
+ {
+ ranges::iter_swap(__x.__current_, __y.__current_);
+ }
+};
+
} // namespace ranges
-#endif // _LIBCPP_STD_VER >= 23
+#endif // _LIBCPP_STD_VER >= 26
_LIBCPP_END_NAMESPACE_STD
-#endif // _LIBCPP___RANGES_FROM_RANGE_H
+#endif // _LIBCPP___RANGES_TO_INPUT_VIEW_H
>From e9c0ff1d0786f3b475513ff19a1ad604d416659f Mon Sep 17 00:00:00 2001
From: dywoq <aleks.koyf at gmail.com>
Date: Mon, 30 Jun 2025 18:45:35 +0300
Subject: [PATCH 03/14] [libcxx] implement adaptor for views::to_input
---
libcxx/include/__ranges/to_input_view.h | 19 +++++++++++++++++++
1 file changed, 19 insertions(+)
diff --git a/libcxx/include/__ranges/to_input_view.h b/libcxx/include/__ranges/to_input_view.h
index d7d38783585b2..7fc526fc01f83 100644
--- a/libcxx/include/__ranges/to_input_view.h
+++ b/libcxx/include/__ranges/to_input_view.h
@@ -163,6 +163,25 @@ class to_input_view<_V>::__iterator {
}
};
+inline namespace __cpo {
+struct __to_input_range_adaptor {
+ template <ranges::input_range _V>
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI inline constexpr auto operator()(_V&& __r) const {
+ return to_input_view<ranges::views::all_t<_V>>(std::forward<_V>(__r));
+ }
+
+ template <ranges::input_range _V>
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI friend inline constexpr auto operator|(_V&& __r, __to_input_range_adaptor) {
+ return to_input_view<ranges::views::all_t<_V>>(std::forward<_V>(__r));
+ }
+};
+} // namespace __cpo
+
+namespace views {
+inline constexpr auto to_input = ranges::__cpo::__to_input_range_adaptor{};
+} // namespace views
+
+
} // namespace ranges
#endif // _LIBCPP_STD_VER >= 26
>From 7c98c8413534212d23aa2d65589e87c8f935b694 Mon Sep 17 00:00:00 2001
From: dywoq <aleks.koyf at gmail.com>
Date: Mon, 30 Jun 2025 18:48:00 +0300
Subject: [PATCH 04/14] [libcxx] add [[nodiscard]] attributes in
__ranges/to_input_view.h
---
libcxx/include/__ranges/to_input_view.h | 34 +++++++++++++------------
1 file changed, 18 insertions(+), 16 deletions(-)
diff --git a/libcxx/include/__ranges/to_input_view.h b/libcxx/include/__ranges/to_input_view.h
index 7fc526fc01f83..2d08c1b05c4f2 100644
--- a/libcxx/include/__ranges/to_input_view.h
+++ b/libcxx/include/__ranges/to_input_view.h
@@ -50,44 +50,44 @@ class to_input_view : public view_interface<to_input_view<_V>> {
_LIBCPP_HIDE_FROM_ABI constexpr explicit to_input_view(_V __base) : __base_(std::move(__base)) {}
// base
- _LIBCPP_HIDE_FROM_ABI constexpr _V base() const&
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr _V base() const&
requires copy_constructible<_V>
{
return __base_;
}
- _LIBCPP_HIDE_FROM_ABI constexpr _V base() && { return std::move(__base_); }
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr _V base() && { return std::move(__base_); }
// begin
- _LIBCPP_HIDE_FROM_ABI constexpr auto begin()
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto begin()
requires(!__simple_view<_V>)
{
return __iterator<false>(ranges::begin(__base_));
}
- _LIBCPP_HIDE_FROM_ABI constexpr auto begin() const
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto begin() const
requires range<const _V>
{
return __iterator<true>(ranges::begin(__base_));
}
// end
- _LIBCPP_HIDE_FROM_ABI constexpr auto end()
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto end()
requires(!__simple_view<_V>)
{
return ranges::end(__base_);
}
- _LIBCPP_HIDE_FROM_ABI constexpr auto end() const
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto end() const
requires range<const _V>
{
return ranges::end(__base_);
}
// size
- _LIBCPP_HIDE_FROM_ABI constexpr auto size()
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto size()
requires sized_range<_V>
{
return ranges::size(__base_);
}
- _LIBCPP_HIDE_FROM_ABI constexpr auto size() const
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto size() const
requires sized_range<const _V>
{
return ranges::size(__base_);
@@ -123,34 +123,37 @@ class to_input_view<_V>::__iterator {
: __current_(std::move(__i.__current_)) {}
// base
- _LIBCPP_HIDE_FROM_ABI constexpr iterator_t<_Base> base() &&;
- _LIBCPP_HIDE_FROM_ABI constexpr const iterator_t<_Base>& base() const& noexcept;
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr iterator_t<_Base> base() &&;
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr const iterator_t<_Base>& base() const& noexcept;
// operator ++
- _LIBCPP_HIDE_FROM_ABI constexpr __iterator& operator++() {
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr __iterator& operator++() {
++__current_;
return *this;
}
_LIBCPP_HIDE_FROM_ABI constexpr void operator++(int) { ++*this; }
// operator==
- _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator==(const __iterator& __x, const sentinel_t<_Base>& __y) {
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI friend constexpr bool
+ operator==(const __iterator& __x, const sentinel_t<_Base>& __y) {
return __x.__current_ == __y;
}
// operator --
- _LIBCPP_HIDE_FROM_ABI friend constexpr difference_type operator-(const sentinel_t<_Base>& __y, const __iterator& __x)
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI friend constexpr difference_type
+ operator-(const sentinel_t<_Base>& __y, const __iterator& __x)
requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base>>
{
return __y - __x.__current_;
}
- _LIBCPP_HIDE_FROM_ABI friend constexpr difference_type operator-(const __iterator& __x, const sentinel_t<_Base>& __y)
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI friend constexpr difference_type
+ operator-(const __iterator& __x, const sentinel_t<_Base>& __y)
requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base>>
{
return __x.__current_ - __y;
}
- _LIBCPP_HIDE_FROM_ABI friend constexpr range_rvalue_reference_t<_Base>
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI friend constexpr range_rvalue_reference_t<_Base>
iter_move(const __iterator& __i) noexcept(noexcept(ranges::iter_move(__i.__current_))) {
return ranges::iter_move(__i.__current_);
}
@@ -181,7 +184,6 @@ namespace views {
inline constexpr auto to_input = ranges::__cpo::__to_input_range_adaptor{};
} // namespace views
-
} // namespace ranges
#endif // _LIBCPP_STD_VER >= 26
>From 1d1ebd6930180fa5a05c0278924669b52b03d771 Mon Sep 17 00:00:00 2001
From: dywoq <aleks.koyf at gmail.com>
Date: Mon, 30 Jun 2025 18:50:09 +0300
Subject: [PATCH 05/14] [libcxx] implement base() method for
to_input_view<_V>::__iterator in __ranges/to_input_view.h
---
libcxx/include/__ranges/to_input_view.h | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/libcxx/include/__ranges/to_input_view.h b/libcxx/include/__ranges/to_input_view.h
index 2d08c1b05c4f2..470c7ee1179c0 100644
--- a/libcxx/include/__ranges/to_input_view.h
+++ b/libcxx/include/__ranges/to_input_view.h
@@ -123,8 +123,8 @@ class to_input_view<_V>::__iterator {
: __current_(std::move(__i.__current_)) {}
// base
- [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr iterator_t<_Base> base() &&;
- [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr const iterator_t<_Base>& base() const& noexcept;
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr iterator_t<_Base> base() && { return std::move(__current_); }
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr const iterator_t<_Base>& base() const& noexcept { return __current_; }
// operator ++
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr __iterator& operator++() {
>From d9fbb993ecd3b59678101d31e22eae5cf3237f6e Mon Sep 17 00:00:00 2001
From: dywoq <aleks.koyf at gmail.com>
Date: Mon, 30 Jun 2025 18:55:03 +0300
Subject: [PATCH 06/14] [libcxx] update synopsis and include
__ranges/to_view_input.h in <ranges> header
---
libcxx/include/ranges | 17 +++++++++++++++++
1 file changed, 17 insertions(+)
diff --git a/libcxx/include/ranges b/libcxx/include/ranges
index 2a6321bd2c5d8..d95e31f9c19ff 100644
--- a/libcxx/include/ranges
+++ b/libcxx/include/ranges
@@ -352,6 +352,19 @@ namespace std::ranges {
class chunk_by_view; // C++23
namespace views { inline constexpr unspecified chunk_by = unspecified; } // C++23
+
+ // [range.to.input], to input view
+ template<input_range V>
+ requires view<V>
+ class to_input_view;
+
+ template<class V>
+ constexpr bool enable_borrowed_range<to_input_view<V>> =
+ enable_borrowed_range<V>;
+
+ namespace views {
+ inline constexpr unspecified to_input = unspecified;
+ }
}
namespace std {
@@ -442,6 +455,10 @@ namespace std {
# include <__ranges/zip_view.h>
# endif
+# if _LIBCPP_STD_VER >= 26
+# include <__ranges/to_input_view.h>
+# endif
+
# include <version>
// standard-mandated includes
>From b249a146086969701ee603f2aba2734279acd7fe Mon Sep 17 00:00:00 2001
From: dywoq <aleks.koyf at gmail.com>
Date: Mon, 30 Jun 2025 19:31:46 +0300
Subject: [PATCH 07/14] [libcxx] add feature test macro
__cpp_lib_ranges_to_input
---
libcxx/docs/FeatureTestMacroTable.rst | 2 ++
libcxx/include/__ranges/to_input_view.h | 8 ++++--
libcxx/include/version | 2 ++
.../ranges.version.compile.pass.cpp | 27 +++++++++++++++++++
.../version.version.compile.pass.cpp | 27 +++++++++++++++++++
.../generate_feature_test_macro_components.py | 5 ++++
6 files changed, 69 insertions(+), 2 deletions(-)
diff --git a/libcxx/docs/FeatureTestMacroTable.rst b/libcxx/docs/FeatureTestMacroTable.rst
index 3c635e5e46bbd..09f2545657e3d 100644
--- a/libcxx/docs/FeatureTestMacroTable.rst
+++ b/libcxx/docs/FeatureTestMacroTable.rst
@@ -484,6 +484,8 @@ Status
---------------------------------------------------------- -----------------
``__cpp_lib_ranges_concat`` *unimplemented*
---------------------------------------------------------- -----------------
+ ``__cpp_lib_ranges_to_input`` ``202502L``
+ ---------------------------------------------------------- -----------------
``__cpp_lib_ratio`` ``202306L``
---------------------------------------------------------- -----------------
``__cpp_lib_rcu`` *unimplemented*
diff --git a/libcxx/include/__ranges/to_input_view.h b/libcxx/include/__ranges/to_input_view.h
index 470c7ee1179c0..974a6204f4881 100644
--- a/libcxx/include/__ranges/to_input_view.h
+++ b/libcxx/include/__ranges/to_input_view.h
@@ -104,13 +104,13 @@ class to_input_view<_V>::__iterator {
using _Base = __maybe_const<_Const, _V>;
iterator_t<_Base> __current_ = iterator_t<_Base>();
- _LIBCPP_HIDE_FROM_ABI constexpr explicit __iterator(iterator_t<_Base> __current) : __current_(std::move(__current)) {}
-
public:
using difference_type = range_difference_t<_Base>;
using value_type = range_value_t<_Base>;
using iterator_concept = input_iterator_tag;
+ _LIBCPP_HIDE_FROM_ABI constexpr explicit __iterator(iterator_t<_Base> __current) : __current_(std::move(__current)) {}
+
_LIBCPP_HIDE_FROM_ABI __iterator()
requires default_initializable<iterator_t<_Base>>
= default;
@@ -126,6 +126,10 @@ class to_input_view<_V>::__iterator {
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr iterator_t<_Base> base() && { return std::move(__current_); }
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr const iterator_t<_Base>& base() const& noexcept { return __current_; }
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr decltype(auto) operator*() const noexcept(noexcept(*__current_)) {
+ return *__current_;
+ }
+
// operator ++
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr __iterator& operator++() {
++__current_;
diff --git a/libcxx/include/version b/libcxx/include/version
index 91fe48351e161..7baf77417c0bb 100644
--- a/libcxx/include/version
+++ b/libcxx/include/version
@@ -209,6 +209,7 @@ __cpp_lib_ranges_repeat 202207L <ranges>
__cpp_lib_ranges_slide 202202L <ranges>
__cpp_lib_ranges_starts_ends_with 202106L <algorithm>
__cpp_lib_ranges_to_container 202202L <ranges>
+__cpp_lib_ranges_to_input 202502L <ranges>
__cpp_lib_ranges_zip 202110L <ranges> <tuple> <utility>
__cpp_lib_ratio 202306L <ratio>
__cpp_lib_raw_memory_algorithms 201606L <memory>
@@ -586,6 +587,7 @@ __cpp_lib_void_t 201411L <type_traits>
# define __cpp_lib_out_ptr 202311L
// # define __cpp_lib_philox_engine 202406L
// # define __cpp_lib_ranges_concat 202403L
+# define __cpp_lib_ranges_to_input 202502L
# define __cpp_lib_ratio 202306L
// # define __cpp_lib_rcu 202306L
# define __cpp_lib_reference_wrapper 202403L
diff --git a/libcxx/test/std/language.support/support.limits/support.limits.general/ranges.version.compile.pass.cpp b/libcxx/test/std/language.support/support.limits/support.limits.general/ranges.version.compile.pass.cpp
index 4cf5178dd7b8f..faea63766f020 100644
--- a/libcxx/test/std/language.support/support.limits/support.limits.general/ranges.version.compile.pass.cpp
+++ b/libcxx/test/std/language.support/support.limits/support.limits.general/ranges.version.compile.pass.cpp
@@ -64,6 +64,10 @@
# error "__cpp_lib_ranges_to_container should not be defined before c++23"
# endif
+# ifdef __cpp_lib_ranges_to_input
+# error "__cpp_lib_ranges_to_input should not be defined before c++26"
+# endif
+
# ifdef __cpp_lib_ranges_zip
# error "__cpp_lib_ranges_zip should not be defined before c++23"
# endif
@@ -114,6 +118,10 @@
# error "__cpp_lib_ranges_to_container should not be defined before c++23"
# endif
+# ifdef __cpp_lib_ranges_to_input
+# error "__cpp_lib_ranges_to_input should not be defined before c++26"
+# endif
+
# ifdef __cpp_lib_ranges_zip
# error "__cpp_lib_ranges_zip should not be defined before c++23"
# endif
@@ -164,6 +172,10 @@
# error "__cpp_lib_ranges_to_container should not be defined before c++23"
# endif
+# ifdef __cpp_lib_ranges_to_input
+# error "__cpp_lib_ranges_to_input should not be defined before c++26"
+# endif
+
# ifdef __cpp_lib_ranges_zip
# error "__cpp_lib_ranges_zip should not be defined before c++23"
# endif
@@ -217,6 +229,10 @@
# error "__cpp_lib_ranges_to_container should not be defined before c++23"
# endif
+# ifdef __cpp_lib_ranges_to_input
+# error "__cpp_lib_ranges_to_input should not be defined before c++26"
+# endif
+
# ifdef __cpp_lib_ranges_zip
# error "__cpp_lib_ranges_zip should not be defined before c++23"
# endif
@@ -312,6 +328,10 @@
# error "__cpp_lib_ranges_to_container should have the value 202202L in c++23"
# endif
+# ifdef __cpp_lib_ranges_to_input
+# error "__cpp_lib_ranges_to_input should not be defined before c++26"
+# endif
+
# if !defined(_LIBCPP_VERSION)
# ifndef __cpp_lib_ranges_zip
# error "__cpp_lib_ranges_zip should be defined in c++23"
@@ -434,6 +454,13 @@
# error "__cpp_lib_ranges_to_container should have the value 202202L in c++26"
# endif
+# ifndef __cpp_lib_ranges_to_input
+# error "__cpp_lib_ranges_to_input should be defined in c++26"
+# endif
+# if __cpp_lib_ranges_to_input != 202502L
+# error "__cpp_lib_ranges_to_input should have the value 202502L in c++26"
+# endif
+
# if !defined(_LIBCPP_VERSION)
# ifndef __cpp_lib_ranges_zip
# error "__cpp_lib_ranges_zip should be defined in c++26"
diff --git a/libcxx/test/std/language.support/support.limits/support.limits.general/version.version.compile.pass.cpp b/libcxx/test/std/language.support/support.limits/support.limits.general/version.version.compile.pass.cpp
index e546719142231..1a6ed20cdbeb2 100644
--- a/libcxx/test/std/language.support/support.limits/support.limits.general/version.version.compile.pass.cpp
+++ b/libcxx/test/std/language.support/support.limits/support.limits.general/version.version.compile.pass.cpp
@@ -680,6 +680,10 @@
# error "__cpp_lib_ranges_to_container should not be defined before c++23"
# endif
+# ifdef __cpp_lib_ranges_to_input
+# error "__cpp_lib_ranges_to_input should not be defined before c++26"
+# endif
+
# ifdef __cpp_lib_ranges_zip
# error "__cpp_lib_ranges_zip should not be defined before c++23"
# endif
@@ -1612,6 +1616,10 @@
# error "__cpp_lib_ranges_to_container should not be defined before c++23"
# endif
+# ifdef __cpp_lib_ranges_to_input
+# error "__cpp_lib_ranges_to_input should not be defined before c++26"
+# endif
+
# ifdef __cpp_lib_ranges_zip
# error "__cpp_lib_ranges_zip should not be defined before c++23"
# endif
@@ -2715,6 +2723,10 @@
# error "__cpp_lib_ranges_to_container should not be defined before c++23"
# endif
+# ifdef __cpp_lib_ranges_to_input
+# error "__cpp_lib_ranges_to_input should not be defined before c++26"
+# endif
+
# ifdef __cpp_lib_ranges_zip
# error "__cpp_lib_ranges_zip should not be defined before c++23"
# endif
@@ -4085,6 +4097,10 @@
# error "__cpp_lib_ranges_to_container should not be defined before c++23"
# endif
+# ifdef __cpp_lib_ranges_to_input
+# error "__cpp_lib_ranges_to_input should not be defined before c++26"
+# endif
+
# ifdef __cpp_lib_ranges_zip
# error "__cpp_lib_ranges_zip should not be defined before c++23"
# endif
@@ -5674,6 +5690,10 @@
# error "__cpp_lib_ranges_to_container should have the value 202202L in c++23"
# endif
+# ifdef __cpp_lib_ranges_to_input
+# error "__cpp_lib_ranges_to_input should not be defined before c++26"
+# endif
+
# if !defined(_LIBCPP_VERSION)
# ifndef __cpp_lib_ranges_zip
# error "__cpp_lib_ranges_zip should be defined in c++23"
@@ -7584,6 +7604,13 @@
# error "__cpp_lib_ranges_to_container should have the value 202202L in c++26"
# endif
+# ifndef __cpp_lib_ranges_to_input
+# error "__cpp_lib_ranges_to_input should be defined in c++26"
+# endif
+# if __cpp_lib_ranges_to_input != 202502L
+# error "__cpp_lib_ranges_to_input should have the value 202502L in c++26"
+# endif
+
# if !defined(_LIBCPP_VERSION)
# ifndef __cpp_lib_ranges_zip
# error "__cpp_lib_ranges_zip should be defined in c++26"
diff --git a/libcxx/utils/generate_feature_test_macro_components.py b/libcxx/utils/generate_feature_test_macro_components.py
index edd7b124a1fb3..8455298d8b12c 100644
--- a/libcxx/utils/generate_feature_test_macro_components.py
+++ b/libcxx/utils/generate_feature_test_macro_components.py
@@ -1137,6 +1137,11 @@ def add_version_header(tc):
"values": {"c++23": 202202},
"headers": ["ranges"],
},
+ {
+ "name": "__cpp_lib_ranges_to_input",
+ "values": {"c++26":202502}, # P3137R3 views::to_input
+ "headers": ["ranges"]
+ },
{
"name": "__cpp_lib_ranges_zip",
"values": {"c++23": 202110},
>From 4cb308111926bfbff5d29f508fd46a3aa396c462 Mon Sep 17 00:00:00 2001
From: dywoq <aleks.koyf at gmail.com>
Date: Mon, 30 Jun 2025 19:35:47 +0300
Subject: [PATCH 08/14] [libcxx] add enable_borrowed_range to
__ranges/to_input_view.h
---
libcxx/include/__ranges/to_input_view.h | 3 +++
1 file changed, 3 insertions(+)
diff --git a/libcxx/include/__ranges/to_input_view.h b/libcxx/include/__ranges/to_input_view.h
index 974a6204f4881..b770730386bb6 100644
--- a/libcxx/include/__ranges/to_input_view.h
+++ b/libcxx/include/__ranges/to_input_view.h
@@ -170,6 +170,9 @@ class to_input_view<_V>::__iterator {
}
};
+template <class _V>
+constexpr bool enable_borrowed_range<to_input_view<_V>> = enable_borrowed_range<_V>;
+
inline namespace __cpo {
struct __to_input_range_adaptor {
template <ranges::input_range _V>
>From 4428225ef0f2c5215388f5b6b371b48bab95f10e Mon Sep 17 00:00:00 2001
From: dywoq <aleks.koyf at gmail.com>
Date: Mon, 30 Jun 2025 20:14:48 +0300
Subject: [PATCH 09/14] [libcxx] write tests for to_input
---
.../range.to_input_view/test.pass.cpp | 75 +++++++++++++++++++
1 file changed, 75 insertions(+)
create mode 100644 libcxx/test/std/ranges/range.adaptors/range.to_input_view/test.pass.cpp
diff --git a/libcxx/test/std/ranges/range.adaptors/range.to_input_view/test.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.to_input_view/test.pass.cpp
new file mode 100644
index 0000000000000..c6ae2b9a132a2
--- /dev/null
+++ b/libcxx/test/std/ranges/range.adaptors/range.to_input_view/test.pass.cpp
@@ -0,0 +1,75 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20, c++23
+
+#include "../../../../support/assert_macros.h"
+#include <iterator>
+#include <memory>
+#include <ranges>
+#include <vector>
+
+int main() {
+ {
+ auto input_view = std::vector<int>{} | std::ranges::views::to_input;
+ TEST_REQUIRE(input_view.begin() == input_view.end(), "begin() == end() is false");
+ }
+
+ {
+ auto input_view = std::vector<int>{100, 200} | std::ranges::views::to_input;
+ auto it = input_view.begin();
+ TEST_REQUIRE(*it == 100, "*it == 100 is false");
+ ++it;
+ TEST_REQUIRE(*it == 200, "*it == 200 is false");
+ ++it;
+ TEST_REQUIRE(it == input_view.end(), "it == input_view.end() is false");
+ }
+
+ {
+ auto input_view = std::vector<int>{1, 2, 3} | std::ranges::views::to_input;
+ auto base_vec = input_view.base();
+ TEST_REQUIRE(base_vec.size() == 3, "base_vec.size() == 0 is false");
+ TEST_REQUIRE(base_vec[0] == 1, "base_vec[0] == 1 is false");
+ }
+
+ {
+ const std::vector<int> vec(5);
+ auto input_view = std::ranges::views::to_input(vec);
+ TEST_REQUIRE(input_view.size() == 5, "input_view.size() == 5 is false");
+ }
+
+ {
+ std::vector<std::unique_ptr<int>> vec;
+ vec.push_back(std::make_unique<int>(10));
+ vec.push_back(std::make_unique<int>(20));
+
+ auto input_view = std::ranges::views::to_input(std::move(vec));
+
+ auto it = input_view.begin();
+ auto val1 = std::ranges::iter_move(it);
+ TEST_REQUIRE(*val1 == 10, "*val1 == 10 is false");
+ TEST_REQUIRE(it->get() == nullptr, "it->get() == nullptr is false");
+
+ ++it;
+ auto val2 = std::ranges::iter_move(it);
+ TEST_REQUIRE(*val2 == 20, "*val2 == 20 is false");
+ TEST_REQUIRE(it->get() == nullptr, "it->get() == nullptr is false");
+ }
+
+ {
+ std::vector<int> vec{1, 2};
+ auto input_view = std::ranges::views::to_input(vec);
+ auto it1 = input_view.begin();
+ auto it2 = std::next(it1);
+
+ std::ranges::iter_swap(it1, it2);
+
+ TEST_REQUIRE(vec[0] == 2, "vec[0] == 2 is false");
+ TEST_REQUIRE(vec[1] == 1, "vec[1] == 1 is false");
+ }
+}
\ No newline at end of file
>From 2e471248204c00581ba0c72b2f5440c19a01963b Mon Sep 17 00:00:00 2001
From: dywoq <aleks.koyf at gmail.com>
Date: Mon, 30 Jun 2025 20:15:50 +0300
Subject: [PATCH 10/14] [libcxx] change path to assert_macros.h header in
to_input tests
---
.../std/ranges/range.adaptors/range.to_input_view/test.pass.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/libcxx/test/std/ranges/range.adaptors/range.to_input_view/test.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.to_input_view/test.pass.cpp
index c6ae2b9a132a2..41cb73b5fa762 100644
--- a/libcxx/test/std/ranges/range.adaptors/range.to_input_view/test.pass.cpp
+++ b/libcxx/test/std/ranges/range.adaptors/range.to_input_view/test.pass.cpp
@@ -8,7 +8,7 @@
// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20, c++23
-#include "../../../../support/assert_macros.h"
+#include "assert_macros.h"
#include <iterator>
#include <memory>
#include <ranges>
>From ec53a77a80cb2cfe0c5ccdaf2f44a03a7e324f19 Mon Sep 17 00:00:00 2001
From: dywoq <aleks.koyf at gmail.com>
Date: Mon, 30 Jun 2025 20:19:53 +0300
Subject: [PATCH 11/14] [libcxx] remove .clangd
---
libcxx/.clangd | 2 --
1 file changed, 2 deletions(-)
delete mode 100644 libcxx/.clangd
diff --git a/libcxx/.clangd b/libcxx/.clangd
deleted file mode 100644
index 8a80936175292..0000000000000
--- a/libcxx/.clangd
+++ /dev/null
@@ -1,2 +0,0 @@
-CompileFlags:
- Add: [--std=c++2c]
\ No newline at end of file
>From 06aa001badce69c891436b00f186d353f4d62aa4 Mon Sep 17 00:00:00 2001
From: dywoq <aleks.koyf at gmail.com>
Date: Sun, 6 Jul 2025 19:51:44 +0300
Subject: [PATCH 12/14] [libcxx] add
range.to_input_view.range_properties.compile.pass test
---
.../range_properties.compile.pass.cpp | 19 +++++
.../range.to_input_view/test.pass.cpp | 75 -------------------
2 files changed, 19 insertions(+), 75 deletions(-)
create mode 100644 libcxx/test/std/ranges/range.adaptors/range.to_input_view/range_properties.compile.pass.cpp
delete mode 100644 libcxx/test/std/ranges/range.adaptors/range.to_input_view/test.pass.cpp
diff --git a/libcxx/test/std/ranges/range.adaptors/range.to_input_view/range_properties.compile.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.to_input_view/range_properties.compile.pass.cpp
new file mode 100644
index 0000000000000..837e3c545db19
--- /dev/null
+++ b/libcxx/test/std/ranges/range.adaptors/range.to_input_view/range_properties.compile.pass.cpp
@@ -0,0 +1,19 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: std-at-least-c++26
+
+#include <ranges>
+#include <vector>
+
+auto vec = std::vector<int>{2, 3, 4};
+auto input_view = vec | std::ranges::views::to_input;
+static_assert(std::ranges::input_range<decltype(input_view)>);
+static_assert(std::ranges::view<decltype(input_view)>);
+static_assert(std::ranges::sized_range<decltype(input_view)>);
+static_assert(std::ranges::borrowed_range<decltype(input_view)>);
diff --git a/libcxx/test/std/ranges/range.adaptors/range.to_input_view/test.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.to_input_view/test.pass.cpp
deleted file mode 100644
index 41cb73b5fa762..0000000000000
--- a/libcxx/test/std/ranges/range.adaptors/range.to_input_view/test.pass.cpp
+++ /dev/null
@@ -1,75 +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
-//
-//===----------------------------------------------------------------------===//
-
-// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20, c++23
-
-#include "assert_macros.h"
-#include <iterator>
-#include <memory>
-#include <ranges>
-#include <vector>
-
-int main() {
- {
- auto input_view = std::vector<int>{} | std::ranges::views::to_input;
- TEST_REQUIRE(input_view.begin() == input_view.end(), "begin() == end() is false");
- }
-
- {
- auto input_view = std::vector<int>{100, 200} | std::ranges::views::to_input;
- auto it = input_view.begin();
- TEST_REQUIRE(*it == 100, "*it == 100 is false");
- ++it;
- TEST_REQUIRE(*it == 200, "*it == 200 is false");
- ++it;
- TEST_REQUIRE(it == input_view.end(), "it == input_view.end() is false");
- }
-
- {
- auto input_view = std::vector<int>{1, 2, 3} | std::ranges::views::to_input;
- auto base_vec = input_view.base();
- TEST_REQUIRE(base_vec.size() == 3, "base_vec.size() == 0 is false");
- TEST_REQUIRE(base_vec[0] == 1, "base_vec[0] == 1 is false");
- }
-
- {
- const std::vector<int> vec(5);
- auto input_view = std::ranges::views::to_input(vec);
- TEST_REQUIRE(input_view.size() == 5, "input_view.size() == 5 is false");
- }
-
- {
- std::vector<std::unique_ptr<int>> vec;
- vec.push_back(std::make_unique<int>(10));
- vec.push_back(std::make_unique<int>(20));
-
- auto input_view = std::ranges::views::to_input(std::move(vec));
-
- auto it = input_view.begin();
- auto val1 = std::ranges::iter_move(it);
- TEST_REQUIRE(*val1 == 10, "*val1 == 10 is false");
- TEST_REQUIRE(it->get() == nullptr, "it->get() == nullptr is false");
-
- ++it;
- auto val2 = std::ranges::iter_move(it);
- TEST_REQUIRE(*val2 == 20, "*val2 == 20 is false");
- TEST_REQUIRE(it->get() == nullptr, "it->get() == nullptr is false");
- }
-
- {
- std::vector<int> vec{1, 2};
- auto input_view = std::ranges::views::to_input(vec);
- auto it1 = input_view.begin();
- auto it2 = std::next(it1);
-
- std::ranges::iter_swap(it1, it2);
-
- TEST_REQUIRE(vec[0] == 2, "vec[0] == 2 is false");
- TEST_REQUIRE(vec[1] == 1, "vec[1] == 1 is false");
- }
-}
\ No newline at end of file
>From 5bdcefc3891d6798ce7d3a637d5fc9616c787b6f Mon Sep 17 00:00:00 2001
From: dywoq <aleks.koyf at gmail.com>
Date: Sun, 6 Jul 2025 19:57:33 +0300
Subject: [PATCH 13/14] [libcxx] add range.to_input_view.empty_vec.compile.pass
test
---
.../empty_vec.compile.pass.cpp | 17 +++++++++++++++++
1 file changed, 17 insertions(+)
create mode 100644 libcxx/test/std/ranges/range.adaptors/range.to_input_view/empty_vec.compile.pass.cpp
diff --git a/libcxx/test/std/ranges/range.adaptors/range.to_input_view/empty_vec.compile.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.to_input_view/empty_vec.compile.pass.cpp
new file mode 100644
index 0000000000000..677f3ba4a67ec
--- /dev/null
+++ b/libcxx/test/std/ranges/range.adaptors/range.to_input_view/empty_vec.compile.pass.cpp
@@ -0,0 +1,17 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: std-at-least-c++26
+
+#include <ranges>
+#include <vector>
+
+std::vector<int> vec;
+auto input_view = vec | std::ranges::views::to_input;
+static_assert(input_view.begin() == input_view.end());
+static_assert(input_view.size() == 0);
>From bd4ff34f552272e8e0f142ad744f3eecd19f2978 Mon Sep 17 00:00:00 2001
From: dywoq <aleks.koyf at gmail.com>
Date: Tue, 8 Jul 2025 12:06:51 +0300
Subject: [PATCH 14/14] [libcxx] edit ranges.inc to include to_input_view
---
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 adabeeb22d551..c699c6062bfeb 100644
--- a/libcxx/modules/std/ranges.inc
+++ b/libcxx/modules/std/ranges.inc
@@ -337,6 +337,15 @@ export namespace std {
}
#endif // _LIBCPP_STD_VER >= 23
+#if _LIBCPP_STD_VER >= 26
+ // [range.to.input], to input view
+ using std::ranges::to_input_view;
+
+ namespace views {
+ using std::ranges::views::to_input;
+ }
+#endif // _LIBCPP_STD_VER >= 26
+
#if 0
// [range.stride], stride view
using std::ranges::stride_view;
More information about the libcxx-commits
mailing list