aboutsummaryrefslogtreecommitdiff
path: root/libcxx/include/__ranges
diff options
context:
space:
mode:
Diffstat (limited to 'libcxx/include/__ranges')
-rw-r--r--libcxx/include/__ranges/access.h10
-rw-r--r--libcxx/include/__ranges/all.h7
-rw-r--r--libcxx/include/__ranges/as_rvalue_view.h137
-rw-r--r--libcxx/include/__ranges/common_view.h8
-rw-r--r--libcxx/include/__ranges/concepts.h11
-rw-r--r--libcxx/include/__ranges/copyable_box.h8
-rw-r--r--libcxx/include/__ranges/counted.h5
-rw-r--r--libcxx/include/__ranges/dangling.h2
-rw-r--r--libcxx/include/__ranges/data.h8
-rw-r--r--libcxx/include/__ranges/drop_view.h8
-rw-r--r--libcxx/include/__ranges/drop_while_view.h129
-rw-r--r--libcxx/include/__ranges/elements_view.h423
-rw-r--r--libcxx/include/__ranges/empty.h6
-rw-r--r--libcxx/include/__ranges/empty_view.h5
-rw-r--r--libcxx/include/__ranges/enable_view.h7
-rw-r--r--libcxx/include/__ranges/filter_view.h63
-rw-r--r--libcxx/include/__ranges/iota_view.h436
-rw-r--r--libcxx/include/__ranges/istream_view.h149
-rw-r--r--libcxx/include/__ranges/join_view.h138
-rw-r--r--libcxx/include/__ranges/lazy_split_view.h6
-rw-r--r--libcxx/include/__ranges/non_propagating_cache.h6
-rw-r--r--libcxx/include/__ranges/owning_view.h6
-rw-r--r--libcxx/include/__ranges/range_adaptor.h10
-rw-r--r--libcxx/include/__ranges/rbegin.h5
-rw-r--r--libcxx/include/__ranges/ref_view.h10
-rw-r--r--libcxx/include/__ranges/rend.h5
-rw-r--r--libcxx/include/__ranges/reverse_view.h5
-rw-r--r--libcxx/include/__ranges/single_view.h7
-rw-r--r--libcxx/include/__ranges/size.h12
-rw-r--r--libcxx/include/__ranges/split_view.h232
-rw-r--r--libcxx/include/__ranges/subrange.h33
-rw-r--r--libcxx/include/__ranges/take_view.h18
-rw-r--r--libcxx/include/__ranges/take_while_view.h183
-rw-r--r--libcxx/include/__ranges/transform_view.h133
-rw-r--r--libcxx/include/__ranges/view_interface.h13
-rw-r--r--libcxx/include/__ranges/views.h4
-rw-r--r--libcxx/include/__ranges/zip_view.h11
37 files changed, 1862 insertions, 397 deletions
diff --git a/libcxx/include/__ranges/access.h b/libcxx/include/__ranges/access.h
index 0f1cca033a23..e48a71adf7e8 100644
--- a/libcxx/include/__ranges/access.h
+++ b/libcxx/include/__ranges/access.h
@@ -6,6 +6,7 @@
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
+
#ifndef _LIBCPP___RANGES_ACCESS_H
#define _LIBCPP___RANGES_ACCESS_H
@@ -14,8 +15,13 @@
#include <__iterator/concepts.h>
#include <__iterator/readable_traits.h>
#include <__ranges/enable_borrowed_range.h>
+#include <__type_traits/decay.h>
+#include <__type_traits/is_reference.h>
+#include <__type_traits/remove_cvref.h>
+#include <__type_traits/remove_reference.h>
#include <__utility/auto_cast.h>
-#include <type_traits>
+#include <__utility/declval.h>
+#include <cstddef>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
@@ -99,7 +105,7 @@ inline namespace __cpo {
namespace ranges {
template <class _Tp>
- using iterator_t = decltype(ranges::begin(declval<_Tp&>()));
+ using iterator_t = decltype(ranges::begin(std::declval<_Tp&>()));
} // namespace ranges
// [range.access.end]
diff --git a/libcxx/include/__ranges/all.h b/libcxx/include/__ranges/all.h
index 181477419c85..511f7b3b46f3 100644
--- a/libcxx/include/__ranges/all.h
+++ b/libcxx/include/__ranges/all.h
@@ -6,6 +6,7 @@
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
+
#ifndef _LIBCPP___RANGES_ALL_H
#define _LIBCPP___RANGES_ALL_H
@@ -28,7 +29,7 @@
_LIBCPP_BEGIN_NAMESPACE_STD
-#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
+#if _LIBCPP_STD_VER > 17
namespace ranges::views {
@@ -72,11 +73,11 @@ inline namespace __cpo {
} // namespace __cpo
template<ranges::viewable_range _Range>
-using all_t = decltype(views::all(declval<_Range>()));
+using all_t = decltype(views::all(std::declval<_Range>()));
} // namespace ranges::views
-#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
+#endif // _LIBCPP_STD_VER > 17
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__ranges/as_rvalue_view.h b/libcxx/include/__ranges/as_rvalue_view.h
new file mode 100644
index 000000000000..422d8a8e0834
--- /dev/null
+++ b/libcxx/include/__ranges/as_rvalue_view.h
@@ -0,0 +1,137 @@
+//===----------------------------------------------------------------------===//
+//
+// 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_AS_RVALUE_H
+#define _LIBCPP___RANGES_AS_RVALUE_H
+
+#include <__concepts/constructible.h>
+#include <__concepts/same_as.h>
+#include <__config>
+#include <__iterator/move_iterator.h>
+#include <__iterator/move_sentinel.h>
+#include <__ranges/access.h>
+#include <__ranges/all.h>
+#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 <__utility/forward.h>
+#include <__utility/move.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+#if _LIBCPP_STD_VER >= 23
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+namespace ranges {
+template <view _View>
+ requires input_range<_View>
+class as_rvalue_view : public view_interface<as_rvalue_view<_View>> {
+ _LIBCPP_NO_UNIQUE_ADDRESS _View __base_ = _View();
+
+public:
+ _LIBCPP_HIDE_FROM_ABI as_rvalue_view()
+ requires default_initializable<_View>
+ = default;
+
+ _LIBCPP_HIDE_FROM_ABI constexpr explicit as_rvalue_view(_View __base) : __base_(std::move(__base)) {}
+
+ _LIBCPP_HIDE_FROM_ABI constexpr _View base() const&
+ requires copy_constructible<_View>
+ {
+ return __base_;
+ }
+
+ _LIBCPP_HIDE_FROM_ABI constexpr _View base() && { return std::move(__base_); }
+
+ _LIBCPP_HIDE_FROM_ABI constexpr auto begin()
+ requires(!__simple_view<_View>)
+ {
+ return move_iterator(ranges::begin(__base_));
+ }
+
+ _LIBCPP_HIDE_FROM_ABI constexpr auto begin() const
+ requires range<const _View>
+ {
+ return move_iterator(ranges::begin(__base_));
+ }
+
+ _LIBCPP_HIDE_FROM_ABI constexpr auto end()
+ requires(!__simple_view<_View>)
+ {
+ if constexpr (common_range<_View>) {
+ return move_iterator(ranges::end(__base_));
+ } else {
+ return move_sentinel(ranges::end(__base_));
+ }
+ }
+
+ _LIBCPP_HIDE_FROM_ABI constexpr auto end() const
+ requires range<const _View>
+ {
+ if constexpr (common_range<const _View>) {
+ return move_iterator(ranges::end(__base_));
+ } else {
+ return move_sentinel(ranges::end(__base_));
+ }
+ }
+
+ _LIBCPP_HIDE_FROM_ABI constexpr auto size()
+ requires sized_range<_View>
+ {
+ return ranges::size(__base_);
+ }
+
+ _LIBCPP_HIDE_FROM_ABI constexpr auto size() const
+ requires sized_range<const _View>
+ {
+ return ranges::size(__base_);
+ }
+};
+
+template <class _Range>
+as_rvalue_view(_Range&&) -> as_rvalue_view<views::all_t<_Range>>;
+
+template <class _View>
+inline constexpr bool enable_borrowed_range<as_rvalue_view<_View>> = enable_borrowed_range<_View>;
+
+namespace views {
+namespace __as_rvalue {
+struct __fn : __range_adaptor_closure<__fn> {
+ template <class _Range>
+ _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Range&& __range) const
+ noexcept(noexcept(/**/ as_rvalue_view(std::forward<_Range>(__range))))
+ -> decltype(/*--*/ as_rvalue_view(std::forward<_Range>(__range))) {
+ return /*-------------*/ as_rvalue_view(std::forward<_Range>(__range));
+ }
+
+ template <class _Range>
+ requires same_as<range_rvalue_reference_t<_Range>, range_reference_t<_Range>>
+ _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Range&& __range) const
+ noexcept(noexcept(/**/ views::all(std::forward<_Range>(__range))))
+ -> decltype(/*--*/ views::all(std::forward<_Range>(__range))) {
+ return /*-------------*/ views::all(std::forward<_Range>(__range));
+ }
+};
+} // namespace __as_rvalue
+
+inline namespace __cpo {
+constexpr auto as_rvalue = __as_rvalue::__fn{};
+} // namespace __cpo
+} // namespace views
+} // namespace ranges
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP_STD_VER >= 23
+
+#endif // _LIBCPP___RANGES_AS_RVALUE_H
diff --git a/libcxx/include/__ranges/common_view.h b/libcxx/include/__ranges/common_view.h
index 61b9b61f26aa..8d7ae5841579 100644
--- a/libcxx/include/__ranges/common_view.h
+++ b/libcxx/include/__ranges/common_view.h
@@ -6,9 +6,12 @@
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
+
#ifndef _LIBCPP___RANGES_COMMON_VIEW_H
#define _LIBCPP___RANGES_COMMON_VIEW_H
+#include <__concepts/constructible.h>
+#include <__concepts/copyable.h>
#include <__config>
#include <__iterator/common_iterator.h>
#include <__iterator/iterator_traits.h>
@@ -21,7 +24,6 @@
#include <__ranges/view_interface.h>
#include <__utility/forward.h>
#include <__utility/move.h>
-#include <concepts>
#include <type_traits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
@@ -30,7 +32,7 @@
_LIBCPP_BEGIN_NAMESPACE_STD
-#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
+#if _LIBCPP_STD_VER > 17
namespace ranges {
@@ -128,7 +130,7 @@ inline namespace __cpo {
} // namespace views
} // namespace ranges
-#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
+#endif // _LIBCPP_STD_VER > 17
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__ranges/concepts.h b/libcxx/include/__ranges/concepts.h
index 87df1d18baf8..e34c545578ab 100644
--- a/libcxx/include/__ranges/concepts.h
+++ b/libcxx/include/__ranges/concepts.h
@@ -6,6 +6,7 @@
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
+
#ifndef _LIBCPP___RANGES_CONCEPTS_H
#define _LIBCPP___RANGES_CONCEPTS_H
@@ -23,8 +24,12 @@
#include <__ranges/enable_borrowed_range.h>
#include <__ranges/enable_view.h>
#include <__ranges/size.h>
+#include <__type_traits/add_pointer.h>
+#include <__type_traits/is_reference.h>
+#include <__type_traits/remove_cvref.h>
+#include <__type_traits/remove_reference.h>
+#include <__utility/declval.h>
#include <initializer_list>
-#include <type_traits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
@@ -54,7 +59,7 @@ namespace ranges {
// `iterator_t` defined in <__ranges/access.h>
template <range _Rp>
- using sentinel_t = decltype(ranges::end(declval<_Rp&>()));
+ using sentinel_t = decltype(ranges::end(std::declval<_Rp&>()));
template <range _Rp>
using range_difference_t = iter_difference_t<iterator_t<_Rp>>;
@@ -73,7 +78,7 @@ namespace ranges {
concept sized_range = range<_Tp> && requires(_Tp& __t) { ranges::size(__t); };
template<sized_range _Rp>
- using range_size_t = decltype(ranges::size(declval<_Rp&>()));
+ using range_size_t = decltype(ranges::size(std::declval<_Rp&>()));
// `disable_sized_range` defined in `<__ranges/size.h>`
diff --git a/libcxx/include/__ranges/copyable_box.h b/libcxx/include/__ranges/copyable_box.h
index 6012497db5e8..fb3d6e409c8f 100644
--- a/libcxx/include/__ranges/copyable_box.h
+++ b/libcxx/include/__ranges/copyable_box.h
@@ -10,11 +10,13 @@
#ifndef _LIBCPP___RANGES_COPYABLE_BOX_H
#define _LIBCPP___RANGES_COPYABLE_BOX_H
+#include <__concepts/constructible.h>
+#include <__concepts/copyable.h>
+#include <__concepts/movable.h>
#include <__config>
#include <__memory/addressof.h>
#include <__memory/construct_at.h>
#include <__utility/move.h>
-#include <concepts>
#include <optional>
#include <type_traits>
@@ -24,7 +26,7 @@
_LIBCPP_BEGIN_NAMESPACE_STD
-#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
+#if _LIBCPP_STD_VER > 17
// __copyable_box allows turning a type that is copy-constructible (but maybe not copy-assignable) into
// a type that is both copy-constructible and copy-assignable. It does that by introducing an empty state
@@ -171,7 +173,7 @@ namespace ranges {
};
} // namespace ranges
-#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
+#endif // _LIBCPP_STD_VER > 17
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__ranges/counted.h b/libcxx/include/__ranges/counted.h
index f45f1e890085..138aa0e1dde5 100644
--- a/libcxx/include/__ranges/counted.h
+++ b/libcxx/include/__ranges/counted.h
@@ -6,6 +6,7 @@
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
+
#ifndef _LIBCPP___RANGES_COUNTED_H
#define _LIBCPP___RANGES_COUNTED_H
@@ -29,7 +30,7 @@
_LIBCPP_BEGIN_NAMESPACE_STD
-#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
+#if _LIBCPP_STD_VER > 17
namespace ranges::views {
@@ -74,7 +75,7 @@ inline namespace __cpo {
} // namespace ranges::views
-#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
+#endif // _LIBCPP_STD_VER > 17
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__ranges/dangling.h b/libcxx/include/__ranges/dangling.h
index 525b5ff0aabe..c10453454dc3 100644
--- a/libcxx/include/__ranges/dangling.h
+++ b/libcxx/include/__ranges/dangling.h
@@ -13,7 +13,7 @@
#include <__config>
#include <__ranges/access.h>
#include <__ranges/concepts.h>
-#include <type_traits>
+#include <__type_traits/conditional.h>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
diff --git a/libcxx/include/__ranges/data.h b/libcxx/include/__ranges/data.h
index 35d1af1e648f..0ac25b52c727 100644
--- a/libcxx/include/__ranges/data.h
+++ b/libcxx/include/__ranges/data.h
@@ -6,6 +6,7 @@
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
+
#ifndef _LIBCPP___RANGES_DATA_H
#define _LIBCPP___RANGES_DATA_H
@@ -15,8 +16,13 @@
#include <__iterator/iterator_traits.h>
#include <__memory/pointer_traits.h>
#include <__ranges/access.h>
+#include <__type_traits/decay.h>
+#include <__type_traits/is_object.h>
+#include <__type_traits/is_pointer.h>
+#include <__type_traits/is_reference.h>
+#include <__type_traits/remove_pointer.h>
+#include <__type_traits/remove_reference.h>
#include <__utility/auto_cast.h>
-#include <type_traits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
diff --git a/libcxx/include/__ranges/drop_view.h b/libcxx/include/__ranges/drop_view.h
index b2a8ee581475..8f3564a8c760 100644
--- a/libcxx/include/__ranges/drop_view.h
+++ b/libcxx/include/__ranges/drop_view.h
@@ -6,11 +6,14 @@
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
+
#ifndef _LIBCPP___RANGES_DROP_VIEW_H
#define _LIBCPP___RANGES_DROP_VIEW_H
#include <__algorithm/min.h>
#include <__assert>
+#include <__concepts/constructible.h>
+#include <__concepts/convertible_to.h>
#include <__config>
#include <__functional/bind_back.h>
#include <__fwd/span.h>
@@ -33,7 +36,6 @@
#include <__utility/auto_cast.h>
#include <__utility/forward.h>
#include <__utility/move.h>
-#include <concepts>
#include <type_traits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
@@ -45,7 +47,7 @@ _LIBCPP_PUSH_MACROS
_LIBCPP_BEGIN_NAMESPACE_STD
-#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
+#if _LIBCPP_STD_VER > 17
namespace ranges {
template<view _View>
@@ -297,7 +299,7 @@ inline namespace __cpo {
} // namespace ranges
-#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
+#endif // _LIBCPP_STD_VER > 17
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__ranges/drop_while_view.h b/libcxx/include/__ranges/drop_while_view.h
new file mode 100644
index 000000000000..7c28992f1874
--- /dev/null
+++ b/libcxx/include/__ranges/drop_while_view.h
@@ -0,0 +1,129 @@
+// -*- 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_DROP_WHILE_VIEW_H
+#define _LIBCPP___RANGES_DROP_WHILE_VIEW_H
+
+#include <__algorithm/ranges_find_if_not.h>
+#include <__assert>
+#include <__concepts/constructible.h>
+#include <__config>
+#include <__functional/bind_back.h>
+#include <__functional/reference_wrapper.h>
+#include <__iterator/concepts.h>
+#include <__ranges/access.h>
+#include <__ranges/all.h>
+#include <__ranges/concepts.h>
+#include <__ranges/copyable_box.h>
+#include <__ranges/enable_borrowed_range.h>
+#include <__ranges/non_propagating_cache.h>
+#include <__ranges/range_adaptor.h>
+#include <__ranges/view_interface.h>
+#include <__type_traits/conditional.h>
+#include <__type_traits/decay.h>
+#include <__type_traits/is_nothrow_constructible.h>
+#include <__type_traits/is_object.h>
+#include <__utility/forward.h>
+#include <__utility/in_place.h>
+#include <__utility/move.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#if _LIBCPP_STD_VER >= 20
+
+namespace ranges {
+
+template <view _View, class _Pred>
+ requires input_range<_View> && is_object_v<_Pred> && indirect_unary_predicate<const _Pred, iterator_t<_View>>
+class drop_while_view : public view_interface<drop_while_view<_View, _Pred>> {
+public:
+ _LIBCPP_HIDE_FROM_ABI drop_while_view()
+ requires default_initializable<_View> && default_initializable<_Pred>
+ = default;
+
+ _LIBCPP_HIDE_FROM_ABI constexpr drop_while_view(_View __base, _Pred __pred)
+ : __base_(std::move(__base)), __pred_(std::in_place, std::move(__pred)) {}
+
+ _LIBCPP_HIDE_FROM_ABI constexpr _View base() const&
+ requires copy_constructible<_View>
+ {
+ return __base_;
+ }
+
+ _LIBCPP_HIDE_FROM_ABI constexpr _View base() && { return std::move(__base_); }
+
+ _LIBCPP_HIDE_FROM_ABI constexpr const _Pred& pred() const { return *__pred_; }
+
+ _LIBCPP_HIDE_FROM_ABI constexpr auto begin() {
+ _LIBCPP_ASSERT(__pred_.__has_value(),
+ "drop_while_view needs to have a non-empty predicate before calling begin() -- did a previous "
+ "assignment to this drop_while_view fail?");
+ if constexpr (_UseCache) {
+ if (!__cached_begin_.__has_value()) {
+ __cached_begin_.__emplace(ranges::find_if_not(__base_, std::cref(*__pred_)));
+ }
+ return *__cached_begin_;
+ } else {
+ return ranges::find_if_not(__base_, std::cref(*__pred_));
+ }
+ }
+
+ _LIBCPP_HIDE_FROM_ABI constexpr auto end() { return ranges::end(__base_); }
+
+private:
+ _LIBCPP_NO_UNIQUE_ADDRESS _View __base_ = _View();
+ _LIBCPP_NO_UNIQUE_ADDRESS __copyable_box<_Pred> __pred_;
+
+ static constexpr bool _UseCache = forward_range<_View>;
+ using _Cache = _If<_UseCache, __non_propagating_cache<iterator_t<_View>>, __empty_cache>;
+ _LIBCPP_NO_UNIQUE_ADDRESS _Cache __cached_begin_ = _Cache();
+};
+
+template <class _View, class _Pred>
+inline constexpr bool enable_borrowed_range<drop_while_view<_View, _Pred>> = enable_borrowed_range<_View>;
+
+template <class _Range, class _Pred>
+drop_while_view(_Range&&, _Pred) -> drop_while_view<views::all_t<_Range>, _Pred>;
+
+namespace views {
+namespace __drop_while {
+
+struct __fn {
+ template <class _Range, class _Pred>
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Range&& __range, _Pred&& __pred) const
+ noexcept(noexcept(/**/ drop_while_view(std::forward<_Range>(__range), std::forward<_Pred>(__pred))))
+ -> decltype(/*--*/ drop_while_view(std::forward<_Range>(__range), std::forward<_Pred>(__pred))) {
+ return /*-------------*/ drop_while_view(std::forward<_Range>(__range), std::forward<_Pred>(__pred));
+ }
+
+ template <class _Pred>
+ requires constructible_from<decay_t<_Pred>, _Pred>
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Pred&& __pred) const
+ noexcept(is_nothrow_constructible_v<decay_t<_Pred>, _Pred>) {
+ return __range_adaptor_closure_t(std::__bind_back(*this, std::forward<_Pred>(__pred)));
+ }
+};
+
+} // namespace __drop_while
+
+inline namespace __cpo {
+inline constexpr auto drop_while = __drop_while::__fn{};
+} // namespace __cpo
+} // namespace views
+} // namespace ranges
+
+#endif // _LIBCPP_STD_VER >= 20
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___RANGES_DROP_WHILE_VIEW_H
diff --git a/libcxx/include/__ranges/elements_view.h b/libcxx/include/__ranges/elements_view.h
new file mode 100644
index 000000000000..3afd6ddbe8f2
--- /dev/null
+++ b/libcxx/include/__ranges/elements_view.h
@@ -0,0 +1,423 @@
+// -*- 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_ELEMENTS_VIEW_H
+#define _LIBCPP___RANGES_ELEMENTS_VIEW_H
+
+#include <__compare/three_way_comparable.h>
+#include <__concepts/constructible.h>
+#include <__concepts/convertible_to.h>
+#include <__concepts/derived_from.h>
+#include <__concepts/equality_comparable.h>
+#include <__config>
+#include <__fwd/get.h>
+#include <__iterator/concepts.h>
+#include <__iterator/iterator_traits.h>
+#include <__ranges/access.h>
+#include <__ranges/all.h>
+#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 <__tuple_dir/tuple_element.h>
+#include <__tuple_dir/tuple_like.h>
+#include <__tuple_dir/tuple_size.h>
+#include <__type_traits/is_reference.h>
+#include <__type_traits/maybe_const.h>
+#include <__type_traits/remove_cv.h>
+#include <__type_traits/remove_cvref.h>
+#include <__type_traits/remove_reference.h>
+#include <__utility/declval.h>
+#include <__utility/forward.h>
+#include <__utility/move.h>
+#include <cstddef>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#if _LIBCPP_STD_VER >= 20
+
+namespace ranges {
+
+template <class _View, size_t _Np, bool _Const>
+class __elements_view_iterator;
+
+template <class _View, size_t _Np, bool _Const>
+class __elements_view_sentinel;
+
+template <class _Tp, size_t _Np>
+concept __has_tuple_element = __tuple_like<_Tp> && _Np < tuple_size<_Tp>::value;
+
+template <class _Tp, size_t _Np>
+concept __returnable_element = is_reference_v<_Tp> || move_constructible<tuple_element_t<_Np, _Tp>>;
+
+template <input_range _View, size_t _Np>
+ requires view<_View> && __has_tuple_element<range_value_t<_View>, _Np> &&
+ __has_tuple_element<remove_reference_t<range_reference_t<_View>>, _Np> &&
+ __returnable_element<range_reference_t<_View>, _Np>
+class elements_view : public view_interface<elements_view<_View, _Np>> {
+public:
+ _LIBCPP_HIDE_FROM_ABI elements_view()
+ requires default_initializable<_View>
+ = default;
+
+ _LIBCPP_HIDE_FROM_ABI constexpr explicit elements_view(_View __base) : __base_(std::move(__base)) {}
+
+ _LIBCPP_HIDE_FROM_ABI constexpr _View base() const&
+ requires copy_constructible<_View>
+ {
+ return __base_;
+ }
+
+ _LIBCPP_HIDE_FROM_ABI constexpr _View base() && { return std::move(__base_); }
+
+ _LIBCPP_HIDE_FROM_ABI constexpr auto begin()
+ requires(!__simple_view<_View>)
+ {
+ return __iterator</*_Const=*/false>(ranges::begin(__base_));
+ }
+
+ _LIBCPP_HIDE_FROM_ABI constexpr auto begin() const
+ requires range<const _View>
+ {
+ return __iterator</*_Const=*/true>(ranges::begin(__base_));
+ }
+
+ _LIBCPP_HIDE_FROM_ABI constexpr auto end()
+ requires(!__simple_view<_View> && !common_range<_View>)
+ {
+ return __sentinel</*_Const=*/false>{ranges::end(__base_)};
+ }
+
+ _LIBCPP_HIDE_FROM_ABI constexpr auto end()
+ requires(!__simple_view<_View> && common_range<_View>)
+ {
+ return __iterator</*_Const=*/false>{ranges::end(__base_)};
+ }
+
+ _LIBCPP_HIDE_FROM_ABI constexpr auto end() const
+ requires range<const _View>
+ {
+ return __sentinel</*_Const=*/true>{ranges::end(__base_)};
+ }
+
+ _LIBCPP_HIDE_FROM_ABI constexpr auto end() const
+ requires common_range<const _View>
+ {
+ return __iterator</*_Const=*/true>{ranges::end(__base_)};
+ }
+
+ _LIBCPP_HIDE_FROM_ABI constexpr auto size()
+ requires sized_range<_View>
+ {
+ return ranges::size(__base_);
+ }
+
+ _LIBCPP_HIDE_FROM_ABI constexpr auto size() const
+ requires sized_range<const _View>
+ {
+ return ranges::size(__base_);
+ }
+
+private:
+ template <bool _Const>
+ using __iterator = __elements_view_iterator<_View, _Np, _Const>;
+
+ template <bool _Const>
+ using __sentinel = __elements_view_sentinel<_View, _Np, _Const>;
+
+ _LIBCPP_NO_UNIQUE_ADDRESS _View __base_ = _View();
+};
+
+template <class, size_t>
+struct __elements_view_iterator_category_base {};
+
+template <forward_range _Base, size_t _Np>
+struct __elements_view_iterator_category_base<_Base, _Np> {
+ static consteval auto __get_iterator_category() {
+ using _Result = decltype(std::get<_Np>(*std::declval<iterator_t<_Base>>()));
+ using _Cat = typename iterator_traits<iterator_t<_Base>>::iterator_category;
+
+ if constexpr (!is_lvalue_reference_v<_Result>) {
+ return input_iterator_tag{};
+ } else if constexpr (derived_from<_Cat, random_access_iterator_tag>) {
+ return random_access_iterator_tag{};
+ } else {
+ return _Cat{};
+ }
+ }
+
+ using iterator_category = decltype(__get_iterator_category());
+};
+
+template <class _View, size_t _Np, bool _Const>
+class __elements_view_iterator : public __elements_view_iterator_category_base<__maybe_const<_Const, _View>, _Np> {
+ template <class, size_t, bool >
+ friend class __elements_view_iterator;
+
+ template <class, size_t, bool >
+ friend class __elements_view_sentinel;
+
+ using _Base = __maybe_const<_Const, _View>;
+
+ iterator_t<_Base> __current_ = iterator_t<_Base>();
+
+ _LIBCPP_HIDE_FROM_ABI static constexpr decltype(auto) __get_element(const iterator_t<_Base>& __i) {
+ if constexpr (is_reference_v<range_reference_t<_Base>>) {
+ return std::get<_Np>(*__i);
+ } else {
+ using _Element = remove_cv_t<tuple_element_t<_Np, range_reference_t<_Base>>>;
+ return static_cast<_Element>(std::get<_Np>(*__i));
+ }
+ }
+
+ static consteval auto __get_iterator_concept() {
+ if constexpr (random_access_range<_Base>) {
+ return random_access_iterator_tag{};
+ } else if constexpr (bidirectional_range<_Base>) {
+ return bidirectional_iterator_tag{};
+ } else if constexpr (forward_range<_Base>) {
+ return forward_iterator_tag{};
+ } else {
+ return input_iterator_tag{};
+ }
+ }
+
+public:
+ using iterator_concept = decltype(__get_iterator_concept());
+ using value_type = remove_cvref_t<tuple_element_t<_Np, range_value_t<_Base>>>;
+ using difference_type = range_difference_t<_Base>;
+
+ _LIBCPP_HIDE_FROM_ABI __elements_view_iterator()
+ requires default_initializable<iterator_t<_Base>>
+ = default;
+
+ _LIBCPP_HIDE_FROM_ABI constexpr explicit __elements_view_iterator(iterator_t<_Base> __current)
+ : __current_(std::move(__current)) {}
+
+ _LIBCPP_HIDE_FROM_ABI constexpr __elements_view_iterator(__elements_view_iterator<_View, _Np, !_Const> __i)
+ requires _Const && convertible_to<iterator_t<_View>, iterator_t<_Base>>
+ : __current_(std::move(__i.__current_)) {}
+
+ _LIBCPP_HIDE_FROM_ABI constexpr const iterator_t<_Base>& base() const& noexcept { return __current_; }
+
+ _LIBCPP_HIDE_FROM_ABI constexpr iterator_t<_Base> base() && { return std::move(__current_); }
+
+ _LIBCPP_HIDE_FROM_ABI constexpr decltype(auto) operator*() const { return __get_element(__current_); }
+
+ _LIBCPP_HIDE_FROM_ABI constexpr __elements_view_iterator& operator++() {
+ ++__current_;
+ return *this;
+ }
+
+ _LIBCPP_HIDE_FROM_ABI constexpr void operator++(int) { ++__current_; }
+
+ _LIBCPP_HIDE_FROM_ABI constexpr __elements_view_iterator operator++(int)
+ requires forward_range<_Base>
+ {
+ auto temp = *this;
+ ++__current_;
+ return temp;
+ }
+
+ _LIBCPP_HIDE_FROM_ABI constexpr __elements_view_iterator& operator--()
+ requires bidirectional_range<_Base>
+ {
+ --__current_;
+ return *this;
+ }
+
+ _LIBCPP_HIDE_FROM_ABI constexpr __elements_view_iterator operator--(int)
+ requires bidirectional_range<_Base>
+ {
+ auto temp = *this;
+ --__current_;
+ return temp;
+ }
+
+ _LIBCPP_HIDE_FROM_ABI constexpr __elements_view_iterator& operator+=(difference_type __n)
+ requires random_access_range<_Base>
+ {
+ __current_ += __n;
+ return *this;
+ }
+
+ _LIBCPP_HIDE_FROM_ABI constexpr __elements_view_iterator& operator-=(difference_type __n)
+ requires random_access_range<_Base>
+ {
+ __current_ -= __n;
+ return *this;
+ }
+
+ _LIBCPP_HIDE_FROM_ABI constexpr decltype(auto) operator[](difference_type __n) const
+ requires random_access_range<_Base>
+ {
+ return __get_element(__current_ + __n);
+ }
+
+ _LIBCPP_HIDE_FROM_ABI friend constexpr bool
+ operator==(const __elements_view_iterator& __x, const __elements_view_iterator& __y)
+ requires equality_comparable<iterator_t<_Base>>
+ {
+ return __x.__current_ == __y.__current_;
+ }
+
+ _LIBCPP_HIDE_FROM_ABI friend constexpr bool
+ operator<(const __elements_view_iterator& __x, const __elements_view_iterator& __y)
+ requires random_access_range<_Base>
+ {
+ return __x.__current_ < __y.__current_;
+ }
+
+ _LIBCPP_HIDE_FROM_ABI friend constexpr bool
+ operator>(const __elements_view_iterator& __x, const __elements_view_iterator& __y)
+ requires random_access_range<_Base>
+ {
+ return __y < __x;
+ }
+
+ _LIBCPP_HIDE_FROM_ABI friend constexpr bool
+ operator<=(const __elements_view_iterator& __x, const __elements_view_iterator& __y)
+ requires random_access_range<_Base>
+ {
+ return !(__y < __x);
+ }
+
+ _LIBCPP_HIDE_FROM_ABI friend constexpr bool
+ operator>=(const __elements_view_iterator& __x, const __elements_view_iterator& __y)
+ requires random_access_range<_Base>
+ {
+ return !(__x < __y);
+ }
+
+ _LIBCPP_HIDE_FROM_ABI friend constexpr auto
+ operator<=>(const __elements_view_iterator& __x, const __elements_view_iterator& __y)
+ requires random_access_range<_Base> && three_way_comparable<iterator_t<_Base>>
+ {
+ return __x.__current_ <=> __y.__current_;
+ }
+
+ _LIBCPP_HIDE_FROM_ABI friend constexpr __elements_view_iterator
+ operator+(const __elements_view_iterator& __x, difference_type __y)
+ requires random_access_range<_Base>
+ {
+ return __elements_view_iterator{__x} += __y;
+ }
+
+ _LIBCPP_HIDE_FROM_ABI friend constexpr __elements_view_iterator
+ operator+(difference_type __x, const __elements_view_iterator& __y)
+ requires random_access_range<_Base>
+ {
+ return __y + __x;
+ }
+
+ _LIBCPP_HIDE_FROM_ABI friend constexpr __elements_view_iterator
+ operator-(const __elements_view_iterator& __x, difference_type __y)
+ requires random_access_range<_Base>
+ {
+ return __elements_view_iterator{__x} -= __y;
+ }
+
+ _LIBCPP_HIDE_FROM_ABI friend constexpr difference_type
+ operator-(const __elements_view_iterator& __x, const __elements_view_iterator& __y)
+ requires sized_sentinel_for<iterator_t<_Base>, iterator_t<_Base>>
+ {
+ return __x.__current_ - __y.__current_;
+ }
+};
+
+template <class _View, size_t _Np, bool _Const>
+class __elements_view_sentinel {
+private:
+ using _Base = __maybe_const<_Const, _View>;
+ _LIBCPP_NO_UNIQUE_ADDRESS sentinel_t<_Base> __end_ = sentinel_t<_Base>();
+
+ template <class, size_t, bool >
+ friend class __elements_view_sentinel;
+
+ template <bool _AnyConst>
+ _LIBCPP_HIDE_FROM_ABI static constexpr decltype(auto)
+ __get_current(const __elements_view_iterator<_View, _Np, _AnyConst>& __iter) {
+ return (__iter.__current_);
+ }
+
+public:
+ _LIBCPP_HIDE_FROM_ABI __elements_view_sentinel() = default;
+
+ _LIBCPP_HIDE_FROM_ABI constexpr explicit __elements_view_sentinel(sentinel_t<_Base> __end)
+ : __end_(std::move(__end)) {}
+
+ _LIBCPP_HIDE_FROM_ABI constexpr __elements_view_sentinel(__elements_view_sentinel<_View, _Np, !_Const> __other)
+ requires _Const && convertible_to<sentinel_t<_View>, sentinel_t<_Base>>
+ : __end_(std::move(__other.__end_)) {}
+
+ _LIBCPP_HIDE_FROM_ABI constexpr sentinel_t<_Base> base() const { return __end_; }
+
+ template <bool _OtherConst>
+ requires sentinel_for<sentinel_t<_Base>, iterator_t<__maybe_const<_OtherConst, _View>>>
+ _LIBCPP_HIDE_FROM_ABI friend constexpr bool
+ operator==(const __elements_view_iterator<_View, _Np, _OtherConst>& __x, const __elements_view_sentinel& __y) {
+ return __get_current(__x) == __y.__end_;
+ }
+
+ template <bool _OtherConst>
+ requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<__maybe_const<_OtherConst, _View>>>
+ _LIBCPP_HIDE_FROM_ABI friend constexpr range_difference_t<__maybe_const<_OtherConst, _View>>
+ operator-(const __elements_view_iterator<_View, _Np, _OtherConst>& __x, const __elements_view_sentinel& __y) {
+ return __get_current(__x) - __y.__end_;
+ }
+
+ template <bool _OtherConst>
+ requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<__maybe_const<_OtherConst, _View>>>
+ _LIBCPP_HIDE_FROM_ABI friend constexpr range_difference_t<__maybe_const<_OtherConst, _View>>
+ operator-(const __elements_view_sentinel& __x, const __elements_view_iterator<_View, _Np, _OtherConst>& __y) {
+ return __x.__end_ - __get_current(__y);
+ }
+};
+
+template <class _Tp, size_t _Np>
+inline constexpr bool enable_borrowed_range<elements_view<_Tp, _Np>> = enable_borrowed_range<_Tp>;
+
+template <class _Tp>
+using keys_view = elements_view<_Tp, 0>;
+template <class _Tp>
+using values_view = elements_view<_Tp, 1>;
+
+namespace views {
+namespace __elements {
+
+template <size_t _Np>
+struct __fn : __range_adaptor_closure<__fn<_Np>> {
+ template <class _Range>
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Range&& __range) const
+ /**/ noexcept(noexcept(elements_view<all_t<_Range&&>, _Np>(std::forward<_Range>(__range))))
+ /*------*/ -> decltype(elements_view<all_t<_Range&&>, _Np>(std::forward<_Range>(__range))) {
+ /*-------------*/ return elements_view<all_t<_Range&&>, _Np>(std::forward<_Range>(__range));
+ }
+};
+} // namespace __elements
+
+inline namespace __cpo {
+template <size_t _Np>
+inline constexpr auto elements = __elements::__fn<_Np>{};
+inline constexpr auto keys = elements<0>;
+inline constexpr auto values = elements<1>;
+} // namespace __cpo
+} // namespace views
+} // namespace ranges
+
+#endif // _LIBCPP_STD_VER >= 20
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___RANGES_ELEMENTS_VIEW_H
diff --git a/libcxx/include/__ranges/empty.h b/libcxx/include/__ranges/empty.h
index 46c97ca7e329..8a1c75c0bae0 100644
--- a/libcxx/include/__ranges/empty.h
+++ b/libcxx/include/__ranges/empty.h
@@ -6,6 +6,7 @@
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
+
#ifndef _LIBCPP___RANGES_EMPTY_H
#define _LIBCPP___RANGES_EMPTY_H
@@ -14,7 +15,6 @@
#include <__iterator/concepts.h>
#include <__ranges/access.h>
#include <__ranges/size.h>
-#include <type_traits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
@@ -22,7 +22,7 @@
_LIBCPP_BEGIN_NAMESPACE_STD
-#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
+#if _LIBCPP_STD_VER > 17
// [range.prim.empty]
@@ -75,7 +75,7 @@ inline namespace __cpo {
} // namespace __cpo
} // namespace ranges
-#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
+#endif // _LIBCPP_STD_VER > 17
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__ranges/empty_view.h b/libcxx/include/__ranges/empty_view.h
index 3299fe825ddf..58e69ac19f29 100644
--- a/libcxx/include/__ranges/empty_view.h
+++ b/libcxx/include/__ranges/empty_view.h
@@ -6,6 +6,7 @@
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
+
#ifndef _LIBCPP___RANGES_EMPTY_VIEW_H
#define _LIBCPP___RANGES_EMPTY_VIEW_H
@@ -20,7 +21,7 @@
_LIBCPP_BEGIN_NAMESPACE_STD
-#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
+#if _LIBCPP_STD_VER > 17
namespace ranges {
template<class _Tp>
@@ -45,7 +46,7 @@ namespace ranges {
} // namespace views
} // namespace ranges
-#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
+#endif // _LIBCPP_STD_VER > 17
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__ranges/enable_view.h b/libcxx/include/__ranges/enable_view.h
index a1e5721404cd..c85064b915ab 100644
--- a/libcxx/include/__ranges/enable_view.h
+++ b/libcxx/include/__ranges/enable_view.h
@@ -10,9 +10,12 @@
#ifndef _LIBCPP___RANGES_ENABLE_VIEW_H
#define _LIBCPP___RANGES_ENABLE_VIEW_H
+#include <__concepts/derived_from.h>
+#include <__concepts/same_as.h>
#include <__config>
-#include <concepts>
-#include <type_traits>
+#include <__type_traits/is_class.h>
+#include <__type_traits/is_convertible.h>
+#include <__type_traits/remove_cv.h>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
diff --git a/libcxx/include/__ranges/filter_view.h b/libcxx/include/__ranges/filter_view.h
index b040ea57b779..f8633a3fee84 100644
--- a/libcxx/include/__ranges/filter_view.h
+++ b/libcxx/include/__ranges/filter_view.h
@@ -6,10 +6,15 @@
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
+
#ifndef _LIBCPP___RANGES_FILTER_VIEW_H
#define _LIBCPP___RANGES_FILTER_VIEW_H
#include <__algorithm/ranges_find_if.h>
+#include <__concepts/constructible.h>
+#include <__concepts/copyable.h>
+#include <__concepts/derived_from.h>
+#include <__concepts/equality_comparable.h>
#include <__config>
#include <__debug>
#include <__functional/bind_back.h>
@@ -30,7 +35,6 @@
#include <__utility/forward.h>
#include <__utility/in_place.h>
#include <__utility/move.h>
-#include <concepts>
#include <type_traits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
@@ -39,9 +43,18 @@
_LIBCPP_BEGIN_NAMESPACE_STD
-#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
+#if _LIBCPP_STD_VER > 17
namespace ranges {
+
+ template <input_range _View, indirect_unary_predicate<iterator_t<_View>> _Pred>
+ requires view<_View> && is_object_v<_Pred>
+ class __filter_view_iterator;
+
+ template <input_range _View, indirect_unary_predicate<iterator_t<_View>> _Pred>
+ requires view<_View> && is_object_v<_Pred>
+ class __filter_view_sentinel;
+
template<input_range _View, indirect_unary_predicate<iterator_t<_View>> _Pred>
requires view<_View> && is_object_v<_Pred>
class filter_view : public view_interface<filter_view<_View, _Pred>> {
@@ -54,8 +67,11 @@ namespace ranges {
using _Cache = _If<_UseCache, __non_propagating_cache<iterator_t<_View>>, __empty_cache>;
_LIBCPP_NO_UNIQUE_ADDRESS _Cache __cached_begin_ = _Cache();
- class __iterator;
- class __sentinel;
+ using __iterator = __filter_view_iterator<_View, _Pred>;
+ using __sentinel = __filter_view_sentinel<_View, _Pred>;
+
+ friend __iterator;
+ friend __sentinel;
public:
_LIBCPP_HIDE_FROM_ABI
@@ -115,10 +131,13 @@ namespace ranges {
template<input_range _View, indirect_unary_predicate<iterator_t<_View>> _Pred>
requires view<_View> && is_object_v<_Pred>
- class filter_view<_View, _Pred>::__iterator : public __filter_iterator_category<_View> {
+ class __filter_view_iterator : public __filter_iterator_category<_View> {
+
+ using __filter_view = filter_view<_View, _Pred>;
+
public:
_LIBCPP_NO_UNIQUE_ADDRESS iterator_t<_View> __current_ = iterator_t<_View>();
- _LIBCPP_NO_UNIQUE_ADDRESS filter_view* __parent_ = nullptr;
+ _LIBCPP_NO_UNIQUE_ADDRESS __filter_view* __parent_ = nullptr;
using iterator_concept =
_If<bidirectional_range<_View>, bidirectional_iterator_tag,
@@ -130,10 +149,10 @@ namespace ranges {
using difference_type = range_difference_t<_View>;
_LIBCPP_HIDE_FROM_ABI
- __iterator() requires default_initializable<iterator_t<_View>> = default;
+ __filter_view_iterator() requires default_initializable<iterator_t<_View>> = default;
_LIBCPP_HIDE_FROM_ABI
- constexpr __iterator(filter_view& __parent, iterator_t<_View> __current)
+ constexpr __filter_view_iterator(__filter_view& __parent, iterator_t<_View> __current)
: __current_(std::move(__current)), __parent_(std::addressof(__parent))
{ }
@@ -152,7 +171,7 @@ namespace ranges {
}
_LIBCPP_HIDE_FROM_ABI
- constexpr __iterator& operator++() {
+ constexpr __filter_view_iterator& operator++() {
__current_ = ranges::find_if(std::move(++__current_), ranges::end(__parent_->__base_),
std::ref(*__parent_->__pred_));
return *this;
@@ -160,42 +179,42 @@ namespace ranges {
_LIBCPP_HIDE_FROM_ABI
constexpr void operator++(int) { ++*this; }
_LIBCPP_HIDE_FROM_ABI
- constexpr __iterator operator++(int) requires forward_range<_View> {
+ constexpr __filter_view_iterator operator++(int) requires forward_range<_View> {
auto __tmp = *this;
++*this;
return __tmp;
}
_LIBCPP_HIDE_FROM_ABI
- constexpr __iterator& operator--() requires bidirectional_range<_View> {
+ constexpr __filter_view_iterator& operator--() requires bidirectional_range<_View> {
do {
--__current_;
} while (!std::invoke(*__parent_->__pred_, *__current_));
return *this;
}
_LIBCPP_HIDE_FROM_ABI
- constexpr __iterator operator--(int) requires bidirectional_range<_View> {
+ constexpr __filter_view_iterator operator--(int) requires bidirectional_range<_View> {
auto tmp = *this;
--*this;
return tmp;
}
_LIBCPP_HIDE_FROM_ABI
- friend constexpr bool operator==(__iterator const& __x, __iterator const& __y)
+ friend constexpr bool operator==(__filter_view_iterator const& __x, __filter_view_iterator const& __y)
requires equality_comparable<iterator_t<_View>>
{
return __x.__current_ == __y.__current_;
}
_LIBCPP_HIDE_FROM_ABI
- friend constexpr range_rvalue_reference_t<_View> iter_move(__iterator const& __it)
+ friend constexpr range_rvalue_reference_t<_View> iter_move(__filter_view_iterator const& __it)
noexcept(noexcept(ranges::iter_move(__it.__current_)))
{
return ranges::iter_move(__it.__current_);
}
_LIBCPP_HIDE_FROM_ABI
- friend constexpr void iter_swap(__iterator const& __x, __iterator const& __y)
+ friend constexpr void iter_swap(__filter_view_iterator const& __x, __filter_view_iterator const& __y)
noexcept(noexcept(ranges::iter_swap(__x.__current_, __y.__current_)))
requires indirectly_swappable<iterator_t<_View>>
{
@@ -205,23 +224,25 @@ namespace ranges {
template<input_range _View, indirect_unary_predicate<iterator_t<_View>> _Pred>
requires view<_View> && is_object_v<_Pred>
- class filter_view<_View, _Pred>::__sentinel {
+ class __filter_view_sentinel {
+ using __filter_view = filter_view<_View, _Pred>;
+
public:
sentinel_t<_View> __end_ = sentinel_t<_View>();
_LIBCPP_HIDE_FROM_ABI
- __sentinel() = default;
+ __filter_view_sentinel() = default;
_LIBCPP_HIDE_FROM_ABI
- constexpr explicit __sentinel(filter_view& __parent)
+ constexpr explicit __filter_view_sentinel(__filter_view& __parent)
: __end_(ranges::end(__parent.__base_))
{ }
_LIBCPP_HIDE_FROM_ABI
constexpr sentinel_t<_View> base() const { return __end_; }
- _LIBCPP_HIDE_FROM_ABI
- friend constexpr bool operator==(__iterator const& __x, __sentinel const& __y) {
+ _LIBCPP_HIDE_FROM_ABI friend constexpr bool
+ operator==(__filter_view_iterator<_View, _Pred> const& __x, __filter_view_sentinel const& __y) {
return __x.__current_ == __y.__end_;
}
};
@@ -252,7 +273,7 @@ inline namespace __cpo {
} // namespace ranges
-#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
+#endif // _LIBCPP_STD_VER > 17
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__ranges/iota_view.h b/libcxx/include/__ranges/iota_view.h
index e1f03bafa03a..3654096b7e17 100644
--- a/libcxx/include/__ranges/iota_view.h
+++ b/libcxx/include/__ranges/iota_view.h
@@ -6,6 +6,7 @@
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
+
#ifndef _LIBCPP___RANGES_IOTA_VIEW_H
#define _LIBCPP___RANGES_IOTA_VIEW_H
@@ -39,7 +40,7 @@
_LIBCPP_BEGIN_NAMESPACE_STD
-#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
+#if _LIBCPP_STD_VER > 17
namespace ranges {
template<class _Int>
@@ -82,6 +83,14 @@ namespace ranges {
{ __j - __j } -> convertible_to<_IotaDiffT<_Iter>>;
};
+ template <weakly_incrementable _Start>
+ requires copyable<_Start>
+ struct __iota_view_iterator;
+
+ template <weakly_incrementable _Start, semiregular _BoundSentinel>
+ requires __weakly_equality_comparable_with<_Start, _BoundSentinel> && copyable<_Start>
+ struct __iota_view_sentinel;
+
template<class>
struct __iota_iterator_category {};
@@ -93,210 +102,9 @@ namespace ranges {
template <weakly_incrementable _Start, semiregular _BoundSentinel = unreachable_sentinel_t>
requires __weakly_equality_comparable_with<_Start, _BoundSentinel> && copyable<_Start>
class iota_view : public view_interface<iota_view<_Start, _BoundSentinel>> {
- struct __iterator : public __iota_iterator_category<_Start> {
- friend class iota_view;
-
- using iterator_concept =
- _If<__advanceable<_Start>, random_access_iterator_tag,
- _If<__decrementable<_Start>, bidirectional_iterator_tag,
- _If<incrementable<_Start>, forward_iterator_tag,
- /*Else*/ input_iterator_tag>>>;
-
- using value_type = _Start;
- using difference_type = _IotaDiffT<_Start>;
-
- _Start __value_ = _Start();
-
- _LIBCPP_HIDE_FROM_ABI
- __iterator() requires default_initializable<_Start> = default;
-
- _LIBCPP_HIDE_FROM_ABI
- constexpr explicit __iterator(_Start __value) : __value_(std::move(__value)) {}
-
- _LIBCPP_HIDE_FROM_ABI
- constexpr _Start operator*() const noexcept(is_nothrow_copy_constructible_v<_Start>) {
- return __value_;
- }
-
- _LIBCPP_HIDE_FROM_ABI
- constexpr __iterator& operator++() {
- ++__value_;
- return *this;
- }
-
- _LIBCPP_HIDE_FROM_ABI
- constexpr void operator++(int) { ++*this; }
-
- _LIBCPP_HIDE_FROM_ABI
- constexpr __iterator operator++(int) requires incrementable<_Start> {
- auto __tmp = *this;
- ++*this;
- return __tmp;
- }
-
- _LIBCPP_HIDE_FROM_ABI
- constexpr __iterator& operator--() requires __decrementable<_Start> {
- --__value_;
- return *this;
- }
-
- _LIBCPP_HIDE_FROM_ABI
- constexpr __iterator operator--(int) requires __decrementable<_Start> {
- auto __tmp = *this;
- --*this;
- return __tmp;
- }
-
- _LIBCPP_HIDE_FROM_ABI
- constexpr __iterator& operator+=(difference_type __n)
- requires __advanceable<_Start>
- {
- if constexpr (__integer_like<_Start> && !__signed_integer_like<_Start>) {
- if (__n >= difference_type(0)) {
- __value_ += static_cast<_Start>(__n);
- } else {
- __value_ -= static_cast<_Start>(-__n);
- }
- } else {
- __value_ += __n;
- }
- return *this;
- }
-
- _LIBCPP_HIDE_FROM_ABI
- constexpr __iterator& operator-=(difference_type __n)
- requires __advanceable<_Start>
- {
- if constexpr (__integer_like<_Start> && !__signed_integer_like<_Start>) {
- if (__n >= difference_type(0)) {
- __value_ -= static_cast<_Start>(__n);
- } else {
- __value_ += static_cast<_Start>(-__n);
- }
- } else {
- __value_ -= __n;
- }
- return *this;
- }
-
- _LIBCPP_HIDE_FROM_ABI
- constexpr _Start operator[](difference_type __n) const
- requires __advanceable<_Start>
- {
- return _Start(__value_ + __n);
- }
-
- _LIBCPP_HIDE_FROM_ABI
- friend constexpr bool operator==(const __iterator& __x, const __iterator& __y)
- requires equality_comparable<_Start>
- {
- return __x.__value_ == __y.__value_;
- }
-
- _LIBCPP_HIDE_FROM_ABI
- friend constexpr bool operator<(const __iterator& __x, const __iterator& __y)
- requires totally_ordered<_Start>
- {
- return __x.__value_ < __y.__value_;
- }
-
- _LIBCPP_HIDE_FROM_ABI
- friend constexpr bool operator>(const __iterator& __x, const __iterator& __y)
- requires totally_ordered<_Start>
- {
- return __y < __x;
- }
-
- _LIBCPP_HIDE_FROM_ABI
- friend constexpr bool operator<=(const __iterator& __x, const __iterator& __y)
- requires totally_ordered<_Start>
- {
- return !(__y < __x);
- }
-
- _LIBCPP_HIDE_FROM_ABI
- friend constexpr bool operator>=(const __iterator& __x, const __iterator& __y)
- requires totally_ordered<_Start>
- {
- return !(__x < __y);
- }
-
- friend constexpr auto operator<=>(const __iterator& __x, const __iterator& __y)
- requires totally_ordered<_Start> && three_way_comparable<_Start>
- {
- return __x.__value_ <=> __y.__value_;
- }
- _LIBCPP_HIDE_FROM_ABI
- friend constexpr __iterator operator+(__iterator __i, difference_type __n)
- requires __advanceable<_Start>
- {
- __i += __n;
- return __i;
- }
-
- _LIBCPP_HIDE_FROM_ABI
- friend constexpr __iterator operator+(difference_type __n, __iterator __i)
- requires __advanceable<_Start>
- {
- return __i + __n;
- }
-
- _LIBCPP_HIDE_FROM_ABI
- friend constexpr __iterator operator-(__iterator __i, difference_type __n)
- requires __advanceable<_Start>
- {
- __i -= __n;
- return __i;
- }
-
- _LIBCPP_HIDE_FROM_ABI
- friend constexpr difference_type operator-(const __iterator& __x, const __iterator& __y)
- requires __advanceable<_Start>
- {
- if constexpr (__integer_like<_Start>) {
- if constexpr (__signed_integer_like<_Start>) {
- return difference_type(difference_type(__x.__value_) - difference_type(__y.__value_));
- }
- if (__y.__value_ > __x.__value_) {
- return difference_type(-difference_type(__y.__value_ - __x.__value_));
- }
- return difference_type(__x.__value_ - __y.__value_);
- }
- return __x.__value_ - __y.__value_;
- }
- };
-
- struct __sentinel {
- friend class iota_view;
-
- private:
- _BoundSentinel __bound_sentinel_ = _BoundSentinel();
-
- public:
- _LIBCPP_HIDE_FROM_ABI
- __sentinel() = default;
- constexpr explicit __sentinel(_BoundSentinel __bound_sentinel) : __bound_sentinel_(std::move(__bound_sentinel)) {}
-
- _LIBCPP_HIDE_FROM_ABI
- friend constexpr bool operator==(const __iterator& __x, const __sentinel& __y) {
- return __x.__value_ == __y.__bound_sentinel_;
- }
-
- _LIBCPP_HIDE_FROM_ABI
- friend constexpr iter_difference_t<_Start> operator-(const __iterator& __x, const __sentinel& __y)
- requires sized_sentinel_for<_BoundSentinel, _Start>
- {
- return __x.__value_ - __y.__bound_sentinel_;
- }
-
- _LIBCPP_HIDE_FROM_ABI
- friend constexpr iter_difference_t<_Start> operator-(const __sentinel& __x, const __iterator& __y)
- requires sized_sentinel_for<_BoundSentinel, _Start>
- {
- return -(__y - __x);
- }
- };
+ using __iterator = __iota_view_iterator<_Start>;
+ using __sentinel = __iota_view_sentinel<_Start, _BoundSentinel>;
_Start __value_ = _Start();
_BoundSentinel __bound_sentinel_ = _BoundSentinel();
@@ -377,6 +185,224 @@ namespace ranges {
template <class _Start, class _BoundSentinel>
inline constexpr bool enable_borrowed_range<iota_view<_Start, _BoundSentinel>> = true;
+ template <weakly_incrementable _Start>
+ requires copyable<_Start>
+ struct __iota_view_iterator : public __iota_iterator_category<_Start> {
+
+ template <weakly_incrementable _StartT, semiregular _BoundSentinelT>
+ requires __weakly_equality_comparable_with<_StartT, _BoundSentinelT> && copyable<_StartT>
+ friend class iota_view;
+
+ using iterator_concept =
+ _If<__advanceable<_Start>, random_access_iterator_tag,
+ _If<__decrementable<_Start>, bidirectional_iterator_tag,
+ _If<incrementable<_Start>, forward_iterator_tag,
+ /*Else*/ input_iterator_tag>>>;
+
+ using value_type = _Start;
+ using difference_type = _IotaDiffT<_Start>;
+
+ _Start __value_ = _Start();
+
+ _LIBCPP_HIDE_FROM_ABI
+ __iota_view_iterator() requires default_initializable<_Start> = default;
+
+ _LIBCPP_HIDE_FROM_ABI
+ constexpr explicit __iota_view_iterator(_Start __value) : __value_(std::move(__value)) {}
+
+ _LIBCPP_HIDE_FROM_ABI
+ constexpr _Start operator*() const noexcept(is_nothrow_copy_constructible_v<_Start>) {
+ return __value_;
+ }
+
+ _LIBCPP_HIDE_FROM_ABI
+ constexpr __iota_view_iterator& operator++() {
+ ++__value_;
+ return *this;
+ }
+
+ _LIBCPP_HIDE_FROM_ABI
+ constexpr void operator++(int) { ++*this; }
+
+ _LIBCPP_HIDE_FROM_ABI
+ constexpr __iota_view_iterator operator++(int) requires incrementable<_Start> {
+ auto __tmp = *this;
+ ++*this;
+ return __tmp;
+ }
+
+ _LIBCPP_HIDE_FROM_ABI
+ constexpr __iota_view_iterator& operator--() requires __decrementable<_Start> {
+ --__value_;
+ return *this;
+ }
+
+ _LIBCPP_HIDE_FROM_ABI
+ constexpr __iota_view_iterator operator--(int) requires __decrementable<_Start> {
+ auto __tmp = *this;
+ --*this;
+ return __tmp;
+ }
+
+ _LIBCPP_HIDE_FROM_ABI
+ constexpr __iota_view_iterator& operator+=(difference_type __n)
+ requires __advanceable<_Start>
+ {
+ if constexpr (__integer_like<_Start> && !__signed_integer_like<_Start>) {
+ if (__n >= difference_type(0)) {
+ __value_ += static_cast<_Start>(__n);
+ } else {
+ __value_ -= static_cast<_Start>(-__n);
+ }
+ } else {
+ __value_ += __n;
+ }
+ return *this;
+ }
+
+ _LIBCPP_HIDE_FROM_ABI
+ constexpr __iota_view_iterator& operator-=(difference_type __n)
+ requires __advanceable<_Start>
+ {
+ if constexpr (__integer_like<_Start> && !__signed_integer_like<_Start>) {
+ if (__n >= difference_type(0)) {
+ __value_ -= static_cast<_Start>(__n);
+ } else {
+ __value_ += static_cast<_Start>(-__n);
+ }
+ } else {
+ __value_ -= __n;
+ }
+ return *this;
+ }
+
+ _LIBCPP_HIDE_FROM_ABI
+ constexpr _Start operator[](difference_type __n) const
+ requires __advanceable<_Start>
+ {
+ return _Start(__value_ + __n);
+ }
+
+ _LIBCPP_HIDE_FROM_ABI
+ friend constexpr bool operator==(const __iota_view_iterator& __x, const __iota_view_iterator& __y)
+ requires equality_comparable<_Start>
+ {
+ return __x.__value_ == __y.__value_;
+ }
+
+ _LIBCPP_HIDE_FROM_ABI
+ friend constexpr bool operator<(const __iota_view_iterator& __x, const __iota_view_iterator& __y)
+ requires totally_ordered<_Start>
+ {
+ return __x.__value_ < __y.__value_;
+ }
+
+ _LIBCPP_HIDE_FROM_ABI
+ friend constexpr bool operator>(const __iota_view_iterator& __x, const __iota_view_iterator& __y)
+ requires totally_ordered<_Start>
+ {
+ return __y < __x;
+ }
+
+ _LIBCPP_HIDE_FROM_ABI
+ friend constexpr bool operator<=(const __iota_view_iterator& __x, const __iota_view_iterator& __y)
+ requires totally_ordered<_Start>
+ {
+ return !(__y < __x);
+ }
+
+ _LIBCPP_HIDE_FROM_ABI
+ friend constexpr bool operator>=(const __iota_view_iterator& __x, const __iota_view_iterator& __y)
+ requires totally_ordered<_Start>
+ {
+ return !(__x < __y);
+ }
+
+ _LIBCPP_HIDE_FROM_ABI
+ friend constexpr auto operator<=>(const __iota_view_iterator& __x, const __iota_view_iterator& __y)
+ requires totally_ordered<_Start> && three_way_comparable<_Start>
+ {
+ return __x.__value_ <=> __y.__value_;
+ }
+
+ _LIBCPP_HIDE_FROM_ABI
+ friend constexpr __iota_view_iterator operator+(__iota_view_iterator __i, difference_type __n)
+ requires __advanceable<_Start>
+ {
+ __i += __n;
+ return __i;
+ }
+
+ _LIBCPP_HIDE_FROM_ABI
+ friend constexpr __iota_view_iterator operator+(difference_type __n, __iota_view_iterator __i)
+ requires __advanceable<_Start>
+ {
+ return __i + __n;
+ }
+
+ _LIBCPP_HIDE_FROM_ABI
+ friend constexpr __iota_view_iterator operator-(__iota_view_iterator __i, difference_type __n)
+ requires __advanceable<_Start>
+ {
+ __i -= __n;
+ return __i;
+ }
+
+ _LIBCPP_HIDE_FROM_ABI
+ friend constexpr difference_type operator-(const __iota_view_iterator& __x, const __iota_view_iterator& __y)
+ requires __advanceable<_Start>
+ {
+ if constexpr (__integer_like<_Start>) {
+ if constexpr (__signed_integer_like<_Start>) {
+ return difference_type(difference_type(__x.__value_) - difference_type(__y.__value_));
+ }
+ if (__y.__value_ > __x.__value_) {
+ return difference_type(-difference_type(__y.__value_ - __x.__value_));
+ }
+ return difference_type(__x.__value_ - __y.__value_);
+ }
+ return __x.__value_ - __y.__value_;
+ }
+ };
+
+ template <weakly_incrementable _Start, semiregular _BoundSentinel>
+ requires __weakly_equality_comparable_with<_Start, _BoundSentinel> && copyable<_Start>
+ struct __iota_view_sentinel {
+
+ template <weakly_incrementable _StartT, semiregular _BoundSentinelT>
+ requires __weakly_equality_comparable_with<_StartT, _BoundSentinelT> && copyable<_StartT>
+ friend class iota_view;
+
+ using __iterator = __iota_view_iterator<_Start>;
+
+ private:
+ _BoundSentinel __bound_sentinel_ = _BoundSentinel();
+
+ public:
+ _LIBCPP_HIDE_FROM_ABI
+ __iota_view_sentinel() = default;
+ constexpr explicit __iota_view_sentinel(_BoundSentinel __bound_sentinel) : __bound_sentinel_(std::move(__bound_sentinel)) {}
+
+ _LIBCPP_HIDE_FROM_ABI
+ friend constexpr bool operator==(const __iterator& __x, const __iota_view_sentinel& __y) {
+ return __x.__value_ == __y.__bound_sentinel_;
+ }
+
+ _LIBCPP_HIDE_FROM_ABI
+ friend constexpr iter_difference_t<_Start> operator-(const __iterator& __x, const __iota_view_sentinel& __y)
+ requires sized_sentinel_for<_BoundSentinel, _Start>
+ {
+ return __x.__value_ - __y.__bound_sentinel_;
+ }
+
+ _LIBCPP_HIDE_FROM_ABI
+ friend constexpr iter_difference_t<_Start> operator-(const __iota_view_sentinel& __x, const __iterator& __y)
+ requires sized_sentinel_for<_BoundSentinel, _Start>
+ {
+ return -(__y - __x);
+ }
+ };
+
namespace views {
namespace __iota {
struct __fn {
@@ -401,7 +427,7 @@ inline namespace __cpo {
} // namespace views
} // namespace ranges
-#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
+#endif // _LIBCPP_STD_VER > 17
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__ranges/istream_view.h b/libcxx/include/__ranges/istream_view.h
new file mode 100644
index 000000000000..69a9df35a4d2
--- /dev/null
+++ b/libcxx/include/__ranges/istream_view.h
@@ -0,0 +1,149 @@
+// -*- 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_ISTREAM_VIEW_H
+#define _LIBCPP___RANGES_ISTREAM_VIEW_H
+
+#include <__concepts/constructible.h>
+#include <__concepts/derived_from.h>
+#include <__concepts/movable.h>
+#include <__config>
+#include <__iterator/default_sentinel.h>
+#include <__iterator/iterator_traits.h>
+#include <__memory/addressof.h>
+#include <__ranges/view_interface.h>
+#include <__type_traits/remove_cvref.h>
+#include <__utility/forward.h>
+#include <cstddef>
+#include <iosfwd>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+#if _LIBCPP_STD_VER >= 20
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+namespace ranges {
+
+template <class _Val, class _CharT, class _Traits>
+concept __stream_extractable = requires(basic_istream<_CharT, _Traits>& __is, _Val& __t) { __is >> __t; };
+
+template <movable _Val, class _CharT, class _Traits>
+ requires default_initializable<_Val> && __stream_extractable<_Val, _CharT, _Traits>
+class __basic_istream_view_iterator;
+
+template <movable _Val, class _CharT, class _Traits = char_traits<_CharT>>
+ requires default_initializable<_Val> && __stream_extractable<_Val, _CharT, _Traits>
+class basic_istream_view : public view_interface<basic_istream_view<_Val, _CharT, _Traits>> {
+ using __iterator = __basic_istream_view_iterator<_Val, _CharT, _Traits>;
+
+ template <movable _ValueType, class _CharType, class _TraitsType>
+ requires default_initializable<_ValueType> && __stream_extractable<_ValueType, _CharType, _TraitsType>
+ friend class __basic_istream_view_iterator;
+
+public:
+ _LIBCPP_HIDE_FROM_ABI constexpr explicit basic_istream_view(basic_istream<_CharT, _Traits>& __stream)
+ : __stream_(std::addressof(__stream)) {}
+
+ _LIBCPP_HIDE_FROM_ABI constexpr auto begin() {
+ *__stream_ >> __value_;
+ return __iterator{*this};
+ }
+
+ _LIBCPP_HIDE_FROM_ABI constexpr default_sentinel_t end() const noexcept { return default_sentinel; }
+
+private:
+ basic_istream<_CharT, _Traits>* __stream_;
+ _LIBCPP_NO_UNIQUE_ADDRESS _Val __value_ = _Val();
+};
+
+template <movable _Val, class _CharT, class _Traits>
+ requires default_initializable<_Val> && __stream_extractable<_Val, _CharT, _Traits>
+class __basic_istream_view_iterator {
+public:
+ using iterator_concept = input_iterator_tag;
+ using difference_type = ptrdiff_t;
+ using value_type = _Val;
+
+ _LIBCPP_HIDE_FROM_ABI constexpr explicit __basic_istream_view_iterator(
+ basic_istream_view<_Val, _CharT, _Traits>& __parent) noexcept
+ : __parent_(std::addressof(__parent)) {}
+
+ __basic_istream_view_iterator(const __basic_istream_view_iterator&) = delete;
+ _LIBCPP_HIDE_FROM_ABI __basic_istream_view_iterator(__basic_istream_view_iterator&&) = default;
+
+ __basic_istream_view_iterator& operator=(const __basic_istream_view_iterator&) = delete;
+ _LIBCPP_HIDE_FROM_ABI __basic_istream_view_iterator& operator=(__basic_istream_view_iterator&&) = default;
+
+ _LIBCPP_HIDE_FROM_ABI __basic_istream_view_iterator& operator++() {
+ *__parent_->__stream_ >> __parent_->__value_;
+ return *this;
+ }
+
+ _LIBCPP_HIDE_FROM_ABI void operator++(int) { ++*this; }
+
+ _LIBCPP_HIDE_FROM_ABI _Val& operator*() const { return __parent_->__value_; }
+
+ _LIBCPP_HIDE_FROM_ABI friend bool operator==(const __basic_istream_view_iterator& __x, default_sentinel_t) {
+ return !*__x.__get_parent_stream();
+ }
+
+private:
+ basic_istream_view<_Val, _CharT, _Traits>* __parent_;
+
+ _LIBCPP_HIDE_FROM_ABI constexpr basic_istream<_CharT, _Traits>* __get_parent_stream() const {
+ return __parent_->__stream_;
+ }
+};
+
+template <class _Val>
+using istream_view = basic_istream_view<_Val, char>;
+
+# ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
+template <class _Val>
+using wistream_view = basic_istream_view<_Val, wchar_t>;
+# endif
+
+namespace views {
+namespace __istream {
+
+// clang-format off
+template <class _Tp>
+struct __fn {
+ template <class _Up, class _UnCVRef = remove_cvref_t<_Up>>
+ requires derived_from<_UnCVRef, basic_istream<typename _UnCVRef::char_type,
+ typename _UnCVRef::traits_type>>
+ _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Up&& __u) const
+ noexcept(noexcept(basic_istream_view<_Tp, typename _UnCVRef::char_type,
+ typename _UnCVRef::traits_type>(std::forward<_Up>(__u))))
+ -> decltype( basic_istream_view<_Tp, typename _UnCVRef::char_type,
+ typename _UnCVRef::traits_type>(std::forward<_Up>(__u)))
+ { return basic_istream_view<_Tp, typename _UnCVRef::char_type,
+ typename _UnCVRef::traits_type>(std::forward<_Up>(__u));
+ }
+};
+// clang-format on
+
+} // namespace __istream
+
+inline namespace __cpo {
+template <class _Tp>
+inline constexpr auto istream = __istream::__fn<_Tp>{};
+} // namespace __cpo
+} // namespace views
+
+} // namespace ranges
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP_STD_VER >= 20
+
+#endif // _LIBCPP___RANGES_ISTREAM_VIEW_H
diff --git a/libcxx/include/__ranges/join_view.h b/libcxx/include/__ranges/join_view.h
index b6fcce95aeda..869540fc99c2 100644
--- a/libcxx/include/__ranges/join_view.h
+++ b/libcxx/include/__ranges/join_view.h
@@ -6,6 +6,7 @@
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
+
#ifndef _LIBCPP___RANGES_JOIN_VIEW_H
#define _LIBCPP___RANGES_JOIN_VIEW_H
@@ -19,12 +20,16 @@
#include <__iterator/iter_move.h>
#include <__iterator/iter_swap.h>
#include <__iterator/iterator_traits.h>
+#include <__iterator/iterator_with_data.h>
+#include <__iterator/segmented_iterator.h>
#include <__ranges/access.h>
#include <__ranges/all.h>
#include <__ranges/concepts.h>
+#include <__ranges/empty.h>
#include <__ranges/non_propagating_cache.h>
#include <__ranges/range_adaptor.h>
#include <__ranges/view_interface.h>
+#include <__type_traits/maybe_const.h>
#include <__utility/forward.h>
#include <optional>
#include <type_traits>
@@ -35,7 +40,7 @@
_LIBCPP_BEGIN_NAMESPACE_STD
-#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
+#if _LIBCPP_STD_VER > 17
namespace ranges {
template<class>
@@ -61,6 +66,14 @@ namespace ranges {
>;
};
+ template <input_range _View, bool _Const>
+ requires view<_View> && input_range<range_reference_t<_View>>
+ struct __join_view_iterator;
+
+ template <input_range _View, bool _Const>
+ requires view<_View> && input_range<range_reference_t<_View>>
+ struct __join_view_sentinel;
+
template<input_range _View>
requires view<_View> && input_range<range_reference_t<_View>>
class join_view
@@ -68,8 +81,22 @@ namespace ranges {
private:
using _InnerRange = range_reference_t<_View>;
- template<bool> struct __iterator;
- template<bool> struct __sentinel;
+ template<bool _Const>
+ using __iterator = __join_view_iterator<_View, _Const>;
+
+ template<bool _Const>
+ using __sentinel = __join_view_sentinel<_View, _Const>;
+
+ template <input_range _View2, bool _Const2>
+ requires view<_View2> && input_range<range_reference_t<_View2>>
+ friend struct __join_view_iterator;
+
+ template <input_range _View2, bool _Const2>
+ requires view<_View2> && input_range<range_reference_t<_View2>>
+ friend struct __join_view_sentinel;
+
+ template <class>
+ friend struct std::__segmented_iterator_traits;
static constexpr bool _UseCache = !is_reference_v<_InnerRange>;
using _Cache = _If<_UseCache, __non_propagating_cache<remove_cvref_t<_InnerRange>>, __empty_cache>;
@@ -137,49 +164,57 @@ namespace ranges {
}
};
- template<input_range _View>
+ template<input_range _View, bool _Const>
requires view<_View> && input_range<range_reference_t<_View>>
- template<bool _Const> struct join_view<_View>::__sentinel {
- template<bool> friend struct __sentinel;
+ struct __join_view_sentinel {
+ template<input_range _View2, bool>
+ requires view<_View2> && input_range<range_reference_t<_View2>>
+ friend struct __join_view_sentinel;
private:
- using _Parent = __maybe_const<_Const, join_view>;
+ using _Parent = __maybe_const<_Const, join_view<_View>>;
using _Base = __maybe_const<_Const, _View>;
sentinel_t<_Base> __end_ = sentinel_t<_Base>();
public:
_LIBCPP_HIDE_FROM_ABI
- __sentinel() = default;
+ __join_view_sentinel() = default;
_LIBCPP_HIDE_FROM_ABI
- constexpr explicit __sentinel(_Parent& __parent)
+ constexpr explicit __join_view_sentinel(_Parent& __parent)
: __end_(ranges::end(__parent.__base_)) {}
_LIBCPP_HIDE_FROM_ABI
- constexpr __sentinel(__sentinel<!_Const> __s)
+ constexpr __join_view_sentinel(__join_view_sentinel<_View, !_Const> __s)
requires _Const && convertible_to<sentinel_t<_View>, sentinel_t<_Base>>
: __end_(std::move(__s.__end_)) {}
template<bool _OtherConst>
requires sentinel_for<sentinel_t<_Base>, iterator_t<__maybe_const<_OtherConst, _View>>>
_LIBCPP_HIDE_FROM_ABI
- friend constexpr bool operator==(const __iterator<_OtherConst>& __x, const __sentinel& __y) {
+ friend constexpr bool operator==(const __join_view_iterator<_View, _OtherConst>& __x, const __join_view_sentinel& __y) {
return __x.__outer_ == __y.__end_;
}
};
- template<input_range _View>
+ template<input_range _View, bool _Const>
requires view<_View> && input_range<range_reference_t<_View>>
- template<bool _Const> struct join_view<_View>::__iterator
+ struct __join_view_iterator
: public __join_view_iterator_category<__maybe_const<_Const, _View>> {
- template<bool> friend struct __iterator;
+ template<input_range _View2, bool>
+ requires view<_View2> && input_range<range_reference_t<_View2>>
+ friend struct __join_view_iterator;
+
+ template <class>
+ friend struct std::__segmented_iterator_traits;
private:
- using _Parent = __maybe_const<_Const, join_view>;
+ using _Parent = __maybe_const<_Const, join_view<_View>>;
using _Base = __maybe_const<_Const, _View>;
using _Outer = iterator_t<_Base>;
using _Inner = iterator_t<range_reference_t<_Base>>;
+ using _InnerRange = range_reference_t<_View>;
static constexpr bool __ref_is_glvalue = is_reference_v<range_reference_t<_Base>>;
@@ -208,9 +243,12 @@ namespace ranges {
__inner_.reset();
}
+ _LIBCPP_HIDE_FROM_ABI constexpr __join_view_iterator(_Parent* __parent, _Outer __outer, _Inner __inner)
+ : __outer_(std::move(__outer)), __inner_(std::move(__inner)), __parent_(__parent) {}
+
public:
using iterator_concept = _If<
- __ref_is_glvalue && bidirectional_range<_Base> && bidirectional_range<range_reference_t<_Base>> &&
+ __ref_is_glvalue && bidirectional_range<_Base> && bidirectional_range<range_reference_t<_Base>> &&
common_range<range_reference_t<_Base>>,
bidirectional_iterator_tag,
_If<
@@ -226,17 +264,17 @@ namespace ranges {
range_difference_t<_Base>, range_difference_t<range_reference_t<_Base>>>;
_LIBCPP_HIDE_FROM_ABI
- __iterator() requires default_initializable<_Outer> = default;
+ __join_view_iterator() requires default_initializable<_Outer> = default;
_LIBCPP_HIDE_FROM_ABI
- constexpr __iterator(_Parent& __parent, _Outer __outer)
+ constexpr __join_view_iterator(_Parent& __parent, _Outer __outer)
: __outer_(std::move(__outer))
, __parent_(std::addressof(__parent)) {
__satisfy();
}
_LIBCPP_HIDE_FROM_ABI
- constexpr __iterator(__iterator<!_Const> __i)
+ constexpr __join_view_iterator(__join_view_iterator<_View, !_Const> __i)
requires _Const &&
convertible_to<iterator_t<_View>, _Outer> &&
convertible_to<iterator_t<_InnerRange>, _Inner>
@@ -257,7 +295,7 @@ namespace ranges {
}
_LIBCPP_HIDE_FROM_ABI
- constexpr __iterator& operator++() {
+ constexpr __join_view_iterator& operator++() {
auto&& __inner = [&]() -> auto&& {
if constexpr (__ref_is_glvalue)
return *__outer_;
@@ -277,7 +315,7 @@ namespace ranges {
}
_LIBCPP_HIDE_FROM_ABI
- constexpr __iterator operator++(int)
+ constexpr __join_view_iterator operator++(int)
requires __ref_is_glvalue &&
forward_range<_Base> &&
forward_range<range_reference_t<_Base>>
@@ -288,7 +326,7 @@ namespace ranges {
}
_LIBCPP_HIDE_FROM_ABI
- constexpr __iterator& operator--()
+ constexpr __join_view_iterator& operator--()
requires __ref_is_glvalue &&
bidirectional_range<_Base> &&
bidirectional_range<range_reference_t<_Base>> &&
@@ -307,7 +345,7 @@ namespace ranges {
}
_LIBCPP_HIDE_FROM_ABI
- constexpr __iterator operator--(int)
+ constexpr __join_view_iterator operator--(int)
requires __ref_is_glvalue &&
bidirectional_range<_Base> &&
bidirectional_range<range_reference_t<_Base>> &&
@@ -319,7 +357,7 @@ namespace ranges {
}
_LIBCPP_HIDE_FROM_ABI
- friend constexpr bool operator==(const __iterator& __x, const __iterator& __y)
+ friend constexpr bool operator==(const __join_view_iterator& __x, const __join_view_iterator& __y)
requires __ref_is_glvalue &&
equality_comparable<iterator_t<_Base>> &&
equality_comparable<iterator_t<range_reference_t<_Base>>>
@@ -328,14 +366,14 @@ namespace ranges {
}
_LIBCPP_HIDE_FROM_ABI
- friend constexpr decltype(auto) iter_move(const __iterator& __i)
+ friend constexpr decltype(auto) iter_move(const __join_view_iterator& __i)
noexcept(noexcept(ranges::iter_move(*__i.__inner_)))
{
return ranges::iter_move(*__i.__inner_);
}
_LIBCPP_HIDE_FROM_ABI
- friend constexpr void iter_swap(const __iterator& __x, const __iterator& __y)
+ friend constexpr void iter_swap(const __join_view_iterator& __x, const __join_view_iterator& __y)
noexcept(noexcept(ranges::iter_swap(*__x.__inner_, *__y.__inner_)))
requires indirectly_swappable<_Inner>
{
@@ -345,7 +383,7 @@ namespace ranges {
template<class _Range>
explicit join_view(_Range&&) -> join_view<views::all_t<_Range>>;
-
+
namespace views {
namespace __join_view {
struct __fn : __range_adaptor_closure<__fn> {
@@ -363,7 +401,51 @@ inline namespace __cpo {
} // namespace views
} // namespace ranges
-#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
+template <class _View, bool _Const>
+ requires(ranges::common_range<typename ranges::__join_view_iterator<_View, _Const>::_Parent> &&
+ __is_cpp17_random_access_iterator<typename ranges::__join_view_iterator<_View, _Const>::_Outer>::value &&
+ __is_cpp17_random_access_iterator<typename ranges::__join_view_iterator<_View, _Const>::_Inner>::value)
+struct __segmented_iterator_traits<ranges::__join_view_iterator<_View, _Const>> {
+ using _JoinViewIterator = ranges::__join_view_iterator<_View, _Const>;
+
+ using __segment_iterator =
+ _LIBCPP_NODEBUG __iterator_with_data<typename _JoinViewIterator::_Outer, typename _JoinViewIterator::_Parent*>;
+ using __local_iterator = typename _JoinViewIterator::_Inner;
+
+ // TODO: Would it make sense to enable the optimization for other iterator types?
+
+ static constexpr _LIBCPP_HIDE_FROM_ABI __segment_iterator __segment(_JoinViewIterator __iter) {
+ if (ranges::empty(__iter.__parent_->__base_))
+ return {};
+ if (!__iter.__inner_.has_value())
+ return __segment_iterator(--__iter.__outer_, __iter.__parent_);
+ return __segment_iterator(__iter.__outer_, __iter.__parent_);
+ }
+
+ static constexpr _LIBCPP_HIDE_FROM_ABI __local_iterator __local(_JoinViewIterator __iter) {
+ if (ranges::empty(__iter.__parent_->__base_))
+ return {};
+ if (!__iter.__inner_.has_value())
+ return ranges::end(*--__iter.__outer_);
+ return *__iter.__inner_;
+ }
+
+ static constexpr _LIBCPP_HIDE_FROM_ABI __local_iterator __begin(__segment_iterator __iter) {
+ return ranges::begin(*__iter.__get_iter());
+ }
+
+ static constexpr _LIBCPP_HIDE_FROM_ABI __local_iterator __end(__segment_iterator __iter) {
+ return ranges::end(*__iter.__get_iter());
+ }
+
+ static constexpr _LIBCPP_HIDE_FROM_ABI _JoinViewIterator
+ __compose(__segment_iterator __seg_iter, __local_iterator __local_iter) {
+ return _JoinViewIterator(
+ std::move(__seg_iter).__get_data(), std::move(__seg_iter).__get_iter(), std::move(__local_iter));
+ }
+};
+
+#endif // _LIBCPP_STD_VER > 17
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__ranges/lazy_split_view.h b/libcxx/include/__ranges/lazy_split_view.h
index e559a76ef7b7..3a95075884b9 100644
--- a/libcxx/include/__ranges/lazy_split_view.h
+++ b/libcxx/include/__ranges/lazy_split_view.h
@@ -10,7 +10,6 @@
#ifndef _LIBCPP___RANGES_LAZY_SPLIT_VIEW_H
#define _LIBCPP___RANGES_LAZY_SPLIT_VIEW_H
-#include <__algorithm/in_in_result.h>
#include <__algorithm/ranges_find.h>
#include <__algorithm/ranges_mismatch.h>
#include <__concepts/constructible.h>
@@ -35,6 +34,7 @@
#include <__ranges/single_view.h>
#include <__ranges/subrange.h>
#include <__ranges/view_interface.h>
+#include <__type_traits/maybe_const.h>
#include <__utility/forward.h>
#include <__utility/move.h>
#include <type_traits>
@@ -45,7 +45,7 @@
_LIBCPP_BEGIN_NAMESPACE_STD
-#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
+#if _LIBCPP_STD_VER > 17
namespace ranges {
@@ -458,7 +458,7 @@ inline namespace __cpo {
} // namespace ranges
-#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
+#endif // _LIBCPP_STD_VER > 17
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__ranges/non_propagating_cache.h b/libcxx/include/__ranges/non_propagating_cache.h
index 7255705256d7..d50c577fc30f 100644
--- a/libcxx/include/__ranges/non_propagating_cache.h
+++ b/libcxx/include/__ranges/non_propagating_cache.h
@@ -6,6 +6,7 @@
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
+
#ifndef _LIBCPP___RANGES_NON_PROPAGATING_CACHE_H
#define _LIBCPP___RANGES_NON_PROPAGATING_CACHE_H
@@ -14,7 +15,6 @@
#include <__iterator/iterator_traits.h> // iter_reference_t
#include <__memory/addressof.h>
#include <__utility/forward.h>
-#include <concepts> // constructible_from
#include <optional>
#include <type_traits>
@@ -24,7 +24,7 @@
_LIBCPP_BEGIN_NAMESPACE_STD
-#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
+#if _LIBCPP_STD_VER > 17
namespace ranges {
// __non_propagating_cache is a helper type that allows storing an optional value in it,
@@ -107,7 +107,7 @@ namespace ranges {
struct __empty_cache { };
} // namespace ranges
-#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
+#endif // _LIBCPP_STD_VER > 17
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__ranges/owning_view.h b/libcxx/include/__ranges/owning_view.h
index ac1ef08fecc2..e150f6d9f248 100644
--- a/libcxx/include/__ranges/owning_view.h
+++ b/libcxx/include/__ranges/owning_view.h
@@ -6,6 +6,7 @@
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
+
#ifndef _LIBCPP___RANGES_OWNING_VIEW_H
#define _LIBCPP___RANGES_OWNING_VIEW_H
@@ -28,7 +29,7 @@
_LIBCPP_BEGIN_NAMESPACE_STD
-#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
+#if _LIBCPP_STD_VER > 17
namespace ranges {
template<range _Rp>
@@ -68,13 +69,14 @@ public:
_LIBCPP_HIDE_FROM_ABI constexpr auto data() const requires contiguous_range<const _Rp>
{ return ranges::data(__r_); }
};
+ _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(owning_view);
template<class _Tp>
inline constexpr bool enable_borrowed_range<owning_view<_Tp>> = enable_borrowed_range<_Tp>;
} // namespace ranges
-#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
+#endif // _LIBCPP_STD_VER > 17
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__ranges/range_adaptor.h b/libcxx/include/__ranges/range_adaptor.h
index b65233b56359..37e48179e378 100644
--- a/libcxx/include/__ranges/range_adaptor.h
+++ b/libcxx/include/__ranges/range_adaptor.h
@@ -10,13 +10,16 @@
#ifndef _LIBCPP___RANGES_RANGE_ADAPTOR_H
#define _LIBCPP___RANGES_RANGE_ADAPTOR_H
+#include <__concepts/constructible.h>
+#include <__concepts/derived_from.h>
+#include <__concepts/invocable.h>
+#include <__concepts/same_as.h>
#include <__config>
#include <__functional/compose.h>
#include <__functional/invoke.h>
#include <__ranges/concepts.h>
#include <__utility/forward.h>
#include <__utility/move.h>
-#include <concepts>
#include <type_traits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
@@ -25,7 +28,7 @@
_LIBCPP_BEGIN_NAMESPACE_STD
-#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
+#if _LIBCPP_STD_VER > 17
// CRTP base that one can derive from in order to be considered a range adaptor closure
// by the library. When deriving from this class, a pipe operator will be provided to
@@ -41,6 +44,7 @@ template <class _Fn>
struct __range_adaptor_closure_t : _Fn, __range_adaptor_closure<__range_adaptor_closure_t<_Fn>> {
constexpr explicit __range_adaptor_closure_t(_Fn&& __f) : _Fn(std::move(__f)) { }
};
+_LIBCPP_CTAD_SUPPORTED_FOR_TYPE(__range_adaptor_closure_t);
template <class _Tp>
concept _RangeAdaptorClosure = derived_from<remove_cvref_t<_Tp>, __range_adaptor_closure<remove_cvref_t<_Tp>>>;
@@ -66,7 +70,7 @@ struct __range_adaptor_closure {
{ return __range_adaptor_closure_t(std::__compose(std::forward<_OtherClosure>(__c2), std::forward<_Closure>(__c1))); }
};
-#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
+#endif // _LIBCPP_STD_VER > 17
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__ranges/rbegin.h b/libcxx/include/__ranges/rbegin.h
index 9291359fdf3b..26b47321de93 100644
--- a/libcxx/include/__ranges/rbegin.h
+++ b/libcxx/include/__ranges/rbegin.h
@@ -6,6 +6,7 @@
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
+
#ifndef _LIBCPP___RANGES_RBEGIN_H
#define _LIBCPP___RANGES_RBEGIN_H
@@ -25,7 +26,7 @@
_LIBCPP_BEGIN_NAMESPACE_STD
-#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
+#if _LIBCPP_STD_VER > 17
// [ranges.access.rbegin]
@@ -123,7 +124,7 @@ inline namespace __cpo {
} // namespace __cpo
} // namespace ranges
-#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
+#endif // _LIBCPP_STD_VER > 17
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__ranges/ref_view.h b/libcxx/include/__ranges/ref_view.h
index e69c715fb9e4..1e5f7466f321 100644
--- a/libcxx/include/__ranges/ref_view.h
+++ b/libcxx/include/__ranges/ref_view.h
@@ -6,9 +6,12 @@
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
+
#ifndef _LIBCPP___RANGES_REF_VIEW_H
#define _LIBCPP___RANGES_REF_VIEW_H
+#include <__concepts/convertible_to.h>
+#include <__concepts/different_from.h>
#include <__config>
#include <__iterator/concepts.h>
#include <__iterator/incrementable_traits.h>
@@ -22,7 +25,6 @@
#include <__ranges/size.h>
#include <__ranges/view_interface.h>
#include <__utility/forward.h>
-#include <concepts>
#include <type_traits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
@@ -31,7 +33,7 @@
_LIBCPP_BEGIN_NAMESPACE_STD
-#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
+#if _LIBCPP_STD_VER > 17
namespace ranges {
template<range _Range>
@@ -45,7 +47,7 @@ namespace ranges {
public:
template<class _Tp>
requires __different_from<_Tp, ref_view> &&
- convertible_to<_Tp, _Range&> && requires { __fun(declval<_Tp>()); }
+ convertible_to<_Tp, _Range&> && requires { __fun(std::declval<_Tp>()); }
_LIBCPP_HIDE_FROM_ABI
constexpr ref_view(_Tp&& __t)
: __range_(std::addressof(static_cast<_Range&>(std::forward<_Tp>(__t))))
@@ -79,7 +81,7 @@ public:
inline constexpr bool enable_borrowed_range<ref_view<_Tp>> = true;
} // namespace ranges
-#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
+#endif // _LIBCPP_STD_VER > 17
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__ranges/rend.h b/libcxx/include/__ranges/rend.h
index e507b2587277..d2987e9fa8c3 100644
--- a/libcxx/include/__ranges/rend.h
+++ b/libcxx/include/__ranges/rend.h
@@ -6,6 +6,7 @@
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
+
#ifndef _LIBCPP___RANGES_REND_H
#define _LIBCPP___RANGES_REND_H
@@ -26,7 +27,7 @@
_LIBCPP_BEGIN_NAMESPACE_STD
-#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
+#if _LIBCPP_STD_VER > 17
// [range.access.rend]
@@ -127,7 +128,7 @@ inline namespace __cpo {
} // namespace __cpo
} // namespace ranges
-#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
+#endif // _LIBCPP_STD_VER > 17
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__ranges/reverse_view.h b/libcxx/include/__ranges/reverse_view.h
index b1df8fbc337b..d7b137805448 100644
--- a/libcxx/include/__ranges/reverse_view.h
+++ b/libcxx/include/__ranges/reverse_view.h
@@ -6,6 +6,7 @@
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
+
#ifndef _LIBCPP___RANGES_REVERSE_VIEW_H
#define _LIBCPP___RANGES_REVERSE_VIEW_H
@@ -33,7 +34,7 @@
_LIBCPP_BEGIN_NAMESPACE_STD
-#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
+#if _LIBCPP_STD_VER > 17
namespace ranges {
template<view _View>
@@ -183,7 +184,7 @@ namespace ranges {
} // namespace views
} // namespace ranges
-#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
+#endif // _LIBCPP_STD_VER > 17
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__ranges/single_view.h b/libcxx/include/__ranges/single_view.h
index 98ebe5f3839f..5c4b91869c1c 100644
--- a/libcxx/include/__ranges/single_view.h
+++ b/libcxx/include/__ranges/single_view.h
@@ -6,9 +6,11 @@
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
+
#ifndef _LIBCPP___RANGES_SINGLE_VIEW_H
#define _LIBCPP___RANGES_SINGLE_VIEW_H
+#include <__concepts/constructible.h>
#include <__config>
#include <__ranges/copyable_box.h>
#include <__ranges/range_adaptor.h>
@@ -16,7 +18,6 @@
#include <__utility/forward.h>
#include <__utility/in_place.h>
#include <__utility/move.h>
-#include <concepts>
#include <type_traits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
@@ -25,7 +26,7 @@
_LIBCPP_BEGIN_NAMESPACE_STD
-#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
+#if _LIBCPP_STD_VER > 17
namespace ranges {
template<copy_constructible _Tp>
@@ -94,7 +95,7 @@ inline namespace __cpo {
} // namespace views
} // namespace ranges
-#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
+#endif // _LIBCPP_STD_VER > 17
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__ranges/size.h b/libcxx/include/__ranges/size.h
index 32ca4b854bc3..0ac8d63063d4 100644
--- a/libcxx/include/__ranges/size.h
+++ b/libcxx/include/__ranges/size.h
@@ -6,17 +6,23 @@
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
+
#ifndef _LIBCPP___RANGES_SIZE_H
#define _LIBCPP___RANGES_SIZE_H
+#include <__concepts/arithmetic.h>
#include <__concepts/class_or_enum.h>
#include <__config>
#include <__iterator/concepts.h>
#include <__iterator/iterator_traits.h>
#include <__ranges/access.h>
+#include <__type_traits/decay.h>
+#include <__type_traits/make_signed.h>
+#include <__type_traits/make_unsigned.h>
+#include <__type_traits/remove_cvref.h>
#include <__utility/auto_cast.h>
-#include <concepts>
-#include <type_traits>
+#include <__utility/declval.h>
+#include <cstddef>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
@@ -65,7 +71,7 @@ concept __difference =
__class_or_enum<remove_cvref_t<_Tp>> &&
requires(_Tp&& __t) {
{ ranges::begin(__t) } -> forward_iterator;
- { ranges::end(__t) } -> sized_sentinel_for<decltype(ranges::begin(declval<_Tp>()))>;
+ { ranges::end(__t) } -> sized_sentinel_for<decltype(ranges::begin(std::declval<_Tp>()))>;
};
struct __fn {
diff --git a/libcxx/include/__ranges/split_view.h b/libcxx/include/__ranges/split_view.h
new file mode 100644
index 000000000000..9758ee935f29
--- /dev/null
+++ b/libcxx/include/__ranges/split_view.h
@@ -0,0 +1,232 @@
+// -*- 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_SPLIT_VIEW_H
+#define _LIBCPP___RANGES_SPLIT_VIEW_H
+
+#include <__algorithm/ranges_search.h>
+#include <__concepts/constructible.h>
+#include <__config>
+#include <__functional/bind_back.h>
+#include <__functional/ranges_operations.h>
+#include <__iterator/indirectly_comparable.h>
+#include <__iterator/iterator_traits.h>
+#include <__memory/addressof.h>
+#include <__ranges/access.h>
+#include <__ranges/all.h>
+#include <__ranges/concepts.h>
+#include <__ranges/empty.h>
+#include <__ranges/non_propagating_cache.h>
+#include <__ranges/range_adaptor.h>
+#include <__ranges/single_view.h>
+#include <__ranges/subrange.h>
+#include <__ranges/view_interface.h>
+#include <__type_traits/decay.h>
+#include <__type_traits/is_nothrow_constructible.h>
+#include <__utility/forward.h>
+#include <__utility/move.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#if _LIBCPP_STD_VER >= 20
+
+namespace ranges {
+
+template <class _View, class _Pattern>
+struct __split_view_iterator;
+
+template <class _View, class _Pattern>
+struct __split_view_sentinel;
+
+template <forward_range _View, forward_range _Pattern>
+ requires view<_View> && view<_Pattern> &&
+ indirectly_comparable<iterator_t<_View>, iterator_t<_Pattern>, ranges::equal_to>
+class split_view : public view_interface<split_view<_View, _Pattern>> {
+private:
+ _LIBCPP_NO_UNIQUE_ADDRESS _View __base_ = _View();
+ _LIBCPP_NO_UNIQUE_ADDRESS _Pattern __pattern_ = _Pattern();
+ using _Cache = __non_propagating_cache<subrange<iterator_t<_View>>>;
+ _Cache __cached_begin_ = _Cache();
+
+ template <class, class>
+ friend struct __split_view_iterator;
+
+ template <class, class>
+ friend struct __split_view_sentinel;
+
+ using __iterator = __split_view_iterator<_View, _Pattern>;
+ using __sentinel = __split_view_sentinel<_View, _Pattern>;
+
+ _LIBCPP_HIDE_FROM_ABI constexpr subrange<iterator_t<_View>> __find_next(iterator_t<_View> __it) {
+ auto [__begin, __end] = ranges::search(subrange(__it, ranges::end(__base_)), __pattern_);
+ if (__begin != ranges::end(__base_) && ranges::empty(__pattern_)) {
+ ++__begin;
+ ++__end;
+ }
+ return {__begin, __end};
+ }
+
+public:
+ _LIBCPP_HIDE_FROM_ABI split_view()
+ requires default_initializable<_View> && default_initializable<_Pattern>
+ = default;
+
+ _LIBCPP_HIDE_FROM_ABI constexpr split_view(_View __base, _Pattern __pattern)
+ : __base_(std::move(__base)), __pattern_(std::move((__pattern))) {}
+
+ template <forward_range _Range>
+ requires constructible_from<_View, views::all_t<_Range>> &&
+ constructible_from<_Pattern, single_view<range_value_t<_Range>>>
+ _LIBCPP_HIDE_FROM_ABI constexpr split_view(_Range&& __range, range_value_t<_Range> __elem)
+ : __base_(views::all(std::forward<_Range>(__range))), __pattern_(views::single(std::move(__elem))) {}
+
+ _LIBCPP_HIDE_FROM_ABI constexpr _View base() const&
+ requires copy_constructible<_View>
+ {
+ return __base_;
+ }
+
+ _LIBCPP_HIDE_FROM_ABI constexpr _View base() && { return std::move(__base_); }
+
+ _LIBCPP_HIDE_FROM_ABI constexpr __iterator begin() {
+ if (!__cached_begin_.__has_value()) {
+ __cached_begin_.__emplace(__find_next(ranges::begin(__base_)));
+ }
+ return {*this, ranges::begin(__base_), *__cached_begin_};
+ }
+
+ _LIBCPP_HIDE_FROM_ABI constexpr auto end() {
+ if constexpr (common_range<_View>) {
+ return __iterator{*this, ranges::end(__base_), {}};
+ } else {
+ return __sentinel{*this};
+ }
+ }
+};
+
+template <class _Range, class _Pattern>
+split_view(_Range&&, _Pattern&&) -> split_view<views::all_t<_Range>, views::all_t<_Pattern>>;
+
+template <forward_range _Range>
+split_view(_Range&&, range_value_t<_Range>) -> split_view<views::all_t<_Range>, single_view<range_value_t<_Range>>>;
+
+template <class _View, class _Pattern>
+struct __split_view_iterator {
+private:
+ split_view<_View, _Pattern>* __parent_ = nullptr;
+ _LIBCPP_NO_UNIQUE_ADDRESS iterator_t<_View> __cur_ = iterator_t<_View>();
+ _LIBCPP_NO_UNIQUE_ADDRESS subrange<iterator_t<_View>> __next_ = subrange<iterator_t<_View>>();
+ bool __trailing_empty_ = false;
+
+ template <class, class>
+ friend struct __split_view_sentinel;
+
+public:
+ using iterator_concept = forward_iterator_tag;
+ using iterator_category = input_iterator_tag;
+ using value_type = subrange<iterator_t<_View>>;
+ using difference_type = range_difference_t<_View>;
+
+ _LIBCPP_HIDE_FROM_ABI __split_view_iterator() = default;
+
+ _LIBCPP_HIDE_FROM_ABI constexpr __split_view_iterator(
+ split_view<_View, _Pattern>& __parent, iterator_t<_View> __current, subrange<iterator_t<_View>> __next)
+ : __parent_(std::addressof(__parent)), __cur_(std::move(__current)), __next_(std::move(__next)) {}
+
+ _LIBCPP_HIDE_FROM_ABI constexpr iterator_t<_View> base() const { return __cur_; }
+
+ _LIBCPP_HIDE_FROM_ABI constexpr value_type operator*() const { return {__cur_, __next_.begin()}; }
+
+ _LIBCPP_HIDE_FROM_ABI constexpr __split_view_iterator& operator++() {
+ __cur_ = __next_.begin();
+ if (__cur_ != ranges::end(__parent_->__base_)) {
+ __cur_ = __next_.end();
+ if (__cur_ == ranges::end(__parent_->__base_)) {
+ __trailing_empty_ = true;
+ __next_ = {__cur_, __cur_};
+ } else {
+ __next_ = __parent_->__find_next(__cur_);
+ }
+ } else {
+ __trailing_empty_ = false;
+ }
+ return *this;
+ }
+
+ _LIBCPP_HIDE_FROM_ABI constexpr __split_view_iterator operator++(int) {
+ auto __tmp = *this;
+ ++*this;
+ return __tmp;
+ }
+
+ _LIBCPP_HIDE_FROM_ABI friend constexpr bool
+ operator==(const __split_view_iterator& __x, const __split_view_iterator& __y) {
+ return __x.__cur_ == __y.__cur_ && __x.__trailing_empty_ == __y.__trailing_empty_;
+ }
+};
+
+template <class _View, class _Pattern>
+struct __split_view_sentinel {
+private:
+ _LIBCPP_NO_UNIQUE_ADDRESS sentinel_t<_View> __end_ = sentinel_t<_View>();
+
+ _LIBCPP_HIDE_FROM_ABI static constexpr bool
+ __equals(const __split_view_iterator<_View, _Pattern>& __x, const __split_view_sentinel& __y) {
+ return __x.__cur_ == __y.__end_ && !__x.__trailing_empty_;
+ }
+
+public:
+ _LIBCPP_HIDE_FROM_ABI __split_view_sentinel() = default;
+
+ _LIBCPP_HIDE_FROM_ABI constexpr explicit __split_view_sentinel(split_view<_View, _Pattern>& __parent)
+ : __end_(ranges::end(__parent.__base_)) {}
+
+ _LIBCPP_HIDE_FROM_ABI friend constexpr bool
+ operator==(const __split_view_iterator<_View, _Pattern>& __x, const __split_view_sentinel& __y) {
+ return __equals(__x, __y);
+ }
+};
+
+namespace views {
+namespace __split_view {
+struct __fn : __range_adaptor_closure<__fn> {
+ // clang-format off
+ template <class _Range, class _Pattern>
+ _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI
+ constexpr auto operator()(_Range&& __range, _Pattern&& __pattern) const
+ noexcept(noexcept(split_view(std::forward<_Range>(__range), std::forward<_Pattern>(__pattern))))
+ -> decltype( split_view(std::forward<_Range>(__range), std::forward<_Pattern>(__pattern)))
+ { return split_view(std::forward<_Range>(__range), std::forward<_Pattern>(__pattern)); }
+ // clang-format on
+
+ template <class _Pattern>
+ requires constructible_from<decay_t<_Pattern>, _Pattern>
+ _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Pattern&& __pattern) const
+ noexcept(is_nothrow_constructible_v<decay_t<_Pattern>, _Pattern>) {
+ return __range_adaptor_closure_t(std::__bind_back(*this, std::forward<_Pattern>(__pattern)));
+ }
+};
+} // namespace __split_view
+
+inline namespace __cpo {
+inline constexpr auto split = __split_view::__fn{};
+} // namespace __cpo
+} // namespace views
+
+} // namespace ranges
+
+#endif // _LIBCPP_STD_VER >= 20
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___RANGES_SPLIT_VIEW_H
diff --git a/libcxx/include/__ranges/subrange.h b/libcxx/include/__ranges/subrange.h
index 7e42da6ce7f9..2d9e4cc7e55e 100644
--- a/libcxx/include/__ranges/subrange.h
+++ b/libcxx/include/__ranges/subrange.h
@@ -6,6 +6,7 @@
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
+
#ifndef _LIBCPP___RANGES_SUBRANGE_H
#define _LIBCPP___RANGES_SUBRANGE_H
@@ -16,6 +17,8 @@
#include <__concepts/derived_from.h>
#include <__concepts/different_from.h>
#include <__config>
+#include <__fwd/get.h>
+#include <__fwd/subrange.h>
#include <__iterator/advance.h>
#include <__iterator/concepts.h>
#include <__iterator/incrementable_traits.h>
@@ -26,9 +29,18 @@
#include <__ranges/enable_borrowed_range.h>
#include <__ranges/size.h>
#include <__ranges/view_interface.h>
-#include <__tuple>
+#include <__tuple_dir/pair_like.h>
+#include <__tuple_dir/tuple_element.h>
+#include <__tuple_dir/tuple_size.h>
+#include <__type_traits/conditional.h>
+#include <__type_traits/decay.h>
+#include <__type_traits/is_pointer.h>
+#include <__type_traits/is_reference.h>
+#include <__type_traits/make_unsigned.h>
+#include <__type_traits/remove_const.h>
+#include <__type_traits/remove_pointer.h>
#include <__utility/move.h>
-#include <type_traits>
+#include <cstddef>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
@@ -36,7 +48,7 @@
_LIBCPP_BEGIN_NAMESPACE_STD
-#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
+#if _LIBCPP_STD_VER > 17
namespace ranges {
template<class _From, class _To>
@@ -49,17 +61,6 @@ namespace ranges {
convertible_to<_From, _To> &&
!__uses_nonqualification_pointer_conversion<decay_t<_From>, decay_t<_To>>;
- template<class _Tp>
- concept __pair_like =
- !is_reference_v<_Tp> && requires(_Tp __t) {
- typename tuple_size<_Tp>::type; // Ensures `tuple_size<T>` is complete.
- requires derived_from<tuple_size<_Tp>, integral_constant<size_t, 2>>;
- typename tuple_element_t<0, remove_const_t<_Tp>>;
- typename tuple_element_t<1, remove_const_t<_Tp>>;
- { std::get<0>(__t) } -> convertible_to<const tuple_element_t<0, _Tp>&>;
- { std::get<1>(__t) } -> convertible_to<const tuple_element_t<1, _Tp>&>;
- };
-
template<class _Pair, class _Iter, class _Sent>
concept __pair_like_convertible_from =
!range<_Pair> && __pair_like<_Pair> &&
@@ -67,8 +68,6 @@ namespace ranges {
__convertible_to_non_slicing<_Iter, tuple_element_t<0, _Pair>> &&
convertible_to<_Sent, tuple_element_t<1, _Pair>>;
- enum class _LIBCPP_ENUM_VIS subrange_kind : bool { unsized, sized };
-
template<input_or_output_iterator _Iter, sentinel_for<_Iter> _Sent = _Iter,
subrange_kind _Kind = sized_sentinel_for<_Sent, _Iter>
? subrange_kind::sized
@@ -285,7 +284,7 @@ struct tuple_element<1, const ranges::subrange<_Ip, _Sp, _Kp>> {
using type = _Sp;
};
-#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
+#endif // _LIBCPP_STD_VER > 17
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__ranges/take_view.h b/libcxx/include/__ranges/take_view.h
index 11d5c9fc36bc..bea3862cd7c8 100644
--- a/libcxx/include/__ranges/take_view.h
+++ b/libcxx/include/__ranges/take_view.h
@@ -6,11 +6,15 @@
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
+
#ifndef _LIBCPP___RANGES_TAKE_VIEW_H
#define _LIBCPP___RANGES_TAKE_VIEW_H
#include <__algorithm/min.h>
#include <__algorithm/ranges_min.h>
+#include <__assert>
+#include <__concepts/constructible.h>
+#include <__concepts/convertible_to.h>
#include <__config>
#include <__functional/bind_back.h>
#include <__fwd/span.h>
@@ -30,10 +34,10 @@
#include <__ranges/size.h>
#include <__ranges/subrange.h>
#include <__ranges/view_interface.h>
+#include <__type_traits/maybe_const.h>
#include <__utility/auto_cast.h>
#include <__utility/forward.h>
#include <__utility/move.h>
-#include <concepts>
#include <type_traits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
@@ -45,7 +49,7 @@ _LIBCPP_PUSH_MACROS
_LIBCPP_BEGIN_NAMESPACE_STD
-#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
+#if _LIBCPP_STD_VER > 17
namespace ranges {
@@ -60,9 +64,10 @@ public:
_LIBCPP_HIDE_FROM_ABI
take_view() requires default_initializable<_View> = default;
- _LIBCPP_HIDE_FROM_ABI
- constexpr take_view(_View __base, range_difference_t<_View> __count)
- : __base_(std::move(__base)), __count_(__count) {}
+ _LIBCPP_HIDE_FROM_ABI constexpr take_view(_View __base, range_difference_t<_View> __count)
+ : __base_(std::move(__base)), __count_(__count) {
+ _LIBCPP_ASSERT(__count >= 0, "count has to be greater than or equal to zero");
+ }
_LIBCPP_HIDE_FROM_ABI
constexpr _View base() const& requires copy_constructible<_View> { return __base_; }
@@ -225,6 +230,7 @@ struct __passthrough_type<basic_string_view<_CharT, _Traits>> {
};
template <class _Iter, class _Sent, subrange_kind _Kind>
+ requires requires{typename subrange<_Iter>;}
struct __passthrough_type<subrange<_Iter, _Sent, _Kind>> {
using type = subrange<_Iter>;
};
@@ -328,7 +334,7 @@ inline namespace __cpo {
} // namespace ranges
-#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
+#endif // _LIBCPP_STD_VER > 17
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__ranges/take_while_view.h b/libcxx/include/__ranges/take_while_view.h
new file mode 100644
index 000000000000..59c0a4f82889
--- /dev/null
+++ b/libcxx/include/__ranges/take_while_view.h
@@ -0,0 +1,183 @@
+// -*- 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_TAKE_WHILE_VIEW_H
+#define _LIBCPP___RANGES_TAKE_WHILE_VIEW_H
+
+#include <__concepts/constructible.h>
+#include <__concepts/convertible_to.h>
+#include <__config>
+#include <__functional/bind_back.h>
+#include <__functional/invoke.h>
+#include <__iterator/concepts.h>
+#include <__memory/addressof.h>
+#include <__ranges/access.h>
+#include <__ranges/all.h>
+#include <__ranges/concepts.h>
+#include <__ranges/copyable_box.h>
+#include <__ranges/range_adaptor.h>
+#include <__ranges/view_interface.h>
+#include <__type_traits/decay.h>
+#include <__type_traits/is_nothrow_constructible.h>
+#include <__type_traits/is_object.h>
+#include <__type_traits/maybe_const.h>
+#include <__utility/forward.h>
+#include <__utility/in_place.h>
+#include <__utility/move.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#if _LIBCPP_STD_VER >= 20
+
+namespace ranges {
+
+// The spec uses the unnamed requirement inside the `begin` and `end` member functions:
+// constexpr auto begin() const
+// requires range<const V> && indirect_unary_predicate<const Pred, iterator_t<const V>>
+// However, due to a clang-14 and clang-15 bug, the above produces a hard error when `const V` is not a range.
+// The workaround is to create a named concept and use the concept instead.
+// As of take_while_view is implemented, the clang-trunk has already fixed the bug.
+// It is OK to remove the workaround once our CI no longer uses clang-14, clang-15 based compilers,
+// because we don't actually expect a lot of vendors to ship a new libc++ with an old clang.
+template <class _View, class _Pred>
+concept __take_while_const_is_range =
+ range<const _View> && indirect_unary_predicate<const _Pred, iterator_t<const _View>>;
+
+template <class, class, bool>
+class __take_while_view_sentinel;
+
+template <view _View, class _Pred>
+ requires input_range<_View> && is_object_v<_Pred> && indirect_unary_predicate<const _Pred, iterator_t<_View>>
+class take_while_view : public view_interface<take_while_view<_View, _Pred>> {
+ template <class, class, bool>
+ friend class __take_while_view_sentinel;
+
+ template <bool _Const>
+ using __sentinel = __take_while_view_sentinel<_View, _Pred, _Const>;
+
+ _LIBCPP_NO_UNIQUE_ADDRESS _View __base_ = _View();
+ _LIBCPP_NO_UNIQUE_ADDRESS __copyable_box<_Pred> __pred_;
+
+public:
+ _LIBCPP_HIDE_FROM_ABI take_while_view()
+ requires default_initializable<_View> && default_initializable<_Pred>
+ = default;
+
+ _LIBCPP_HIDE_FROM_ABI constexpr take_while_view(_View __base, _Pred __pred)
+ : __base_(std::move(__base)), __pred_(std::in_place, std::move(__pred)) {}
+
+ _LIBCPP_HIDE_FROM_ABI constexpr _View base() const&
+ requires copy_constructible<_View>
+ {
+ return __base_;
+ }
+
+ _LIBCPP_HIDE_FROM_ABI constexpr _View base() && { return std::move(__base_); }
+
+ _LIBCPP_HIDE_FROM_ABI constexpr const _Pred& pred() const { return *__pred_; }
+
+ _LIBCPP_HIDE_FROM_ABI constexpr auto begin()
+ requires(!__simple_view<_View>)
+ {
+ return ranges::begin(__base_);
+ }
+
+ _LIBCPP_HIDE_FROM_ABI constexpr auto begin() const
+ requires __take_while_const_is_range<_View, _Pred>
+ {
+ return ranges::begin(__base_);
+ }
+
+ _LIBCPP_HIDE_FROM_ABI constexpr auto end()
+ requires(!__simple_view<_View>)
+ {
+ return __sentinel</*_Const=*/false>(ranges::end(__base_), std::addressof(*__pred_));
+ }
+
+ _LIBCPP_HIDE_FROM_ABI constexpr auto end() const
+ requires __take_while_const_is_range<_View, _Pred>
+ {
+ return __sentinel</*_Const=*/true>(ranges::end(__base_), std::addressof(*__pred_));
+ }
+};
+
+template <class _Range, class _Pred>
+take_while_view(_Range&&, _Pred) -> take_while_view<views::all_t<_Range>, _Pred>;
+
+template <class _View, class _Pred, bool _Const>
+class __take_while_view_sentinel {
+ using _Base = __maybe_const<_Const, _View>;
+
+ sentinel_t<_Base> __end_ = sentinel_t<_Base>();
+ const _Pred* __pred_ = nullptr;
+
+ template <class, class, bool>
+ friend class __take_while_view_sentinel;
+
+public:
+ _LIBCPP_HIDE_FROM_ABI __take_while_view_sentinel() = default;
+
+ _LIBCPP_HIDE_FROM_ABI constexpr explicit __take_while_view_sentinel(sentinel_t<_Base> __end, const _Pred* __pred)
+ : __end_(std::move(__end)), __pred_(__pred) {}
+
+ _LIBCPP_HIDE_FROM_ABI constexpr __take_while_view_sentinel(__take_while_view_sentinel<_View, _Pred, !_Const> __s)
+ requires _Const && convertible_to<sentinel_t<_View>, sentinel_t<_Base>>
+ : __end_(std::move(__s.__end_)), __pred_(__s.__pred_) {}
+
+ _LIBCPP_HIDE_FROM_ABI constexpr sentinel_t<_Base> base() const { return __end_; }
+
+ _LIBCPP_HIDE_FROM_ABI friend constexpr bool
+ operator==(const iterator_t<_Base>& __x, const __take_while_view_sentinel& __y) {
+ return __x == __y.__end_ || !std::invoke(*__y.__pred_, *__x);
+ }
+
+ template <bool _OtherConst = !_Const>
+ requires sentinel_for<sentinel_t<_Base>, iterator_t<__maybe_const<_OtherConst, _View>>>
+ _LIBCPP_HIDE_FROM_ABI friend constexpr bool
+ operator==(const iterator_t<__maybe_const<_OtherConst, _View>>& __x, const __take_while_view_sentinel& __y) {
+ return __x == __y.__end_ || !std::invoke(*__y.__pred_, *__x);
+ }
+};
+
+namespace views {
+namespace __take_while {
+
+struct __fn {
+ template <class _Range, class _Pred>
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Range&& __range, _Pred&& __pred) const
+ noexcept(noexcept(/**/ take_while_view(std::forward<_Range>(__range), std::forward<_Pred>(__pred))))
+ -> decltype(/*--*/ take_while_view(std::forward<_Range>(__range), std::forward<_Pred>(__pred))) {
+ return /*-------------*/ take_while_view(std::forward<_Range>(__range), std::forward<_Pred>(__pred));
+ }
+
+ template <class _Pred>
+ requires constructible_from<decay_t<_Pred>, _Pred>
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Pred&& __pred) const
+ noexcept(is_nothrow_constructible_v<decay_t<_Pred>, _Pred>) {
+ return __range_adaptor_closure_t(std::__bind_back(*this, std::forward<_Pred>(__pred)));
+ }
+};
+
+} // namespace __take_while
+
+inline namespace __cpo {
+inline constexpr auto take_while = __take_while::__fn{};
+} // namespace __cpo
+} // namespace views
+} // namespace ranges
+
+#endif // _LIBCPP_STD_VER >= 20
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___RANGES_TAKE_WHILE_VIEW_H
diff --git a/libcxx/include/__ranges/transform_view.h b/libcxx/include/__ranges/transform_view.h
index c5a7128c366b..66d9e80e6e61 100644
--- a/libcxx/include/__ranges/transform_view.h
+++ b/libcxx/include/__ranges/transform_view.h
@@ -6,6 +6,7 @@
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
+
#ifndef _LIBCPP___RANGES_TRANSFORM_VIEW_H
#define _LIBCPP___RANGES_TRANSFORM_VIEW_H
@@ -30,6 +31,7 @@
#include <__ranges/range_adaptor.h>
#include <__ranges/size.h>
#include <__ranges/view_interface.h>
+#include <__type_traits/maybe_const.h>
#include <__utility/forward.h>
#include <__utility/in_place.h>
#include <__utility/move.h>
@@ -41,7 +43,7 @@
_LIBCPP_BEGIN_NAMESPACE_STD
-#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
+#if _LIBCPP_STD_VER > 17
namespace ranges {
@@ -55,11 +57,31 @@ concept __transform_view_constraints =
regular_invocable<_Fn&, range_reference_t<_View>> &&
__can_reference<invoke_result_t<_Fn&, range_reference_t<_View>>>;
+template <input_range _View, copy_constructible _Function, bool _IsConst>
+ requires __transform_view_constraints<_View, _Function>
+class __transform_view_iterator;
+
+template <input_range _View, copy_constructible _Function, bool _IsConst>
+ requires __transform_view_constraints<_View, _Function>
+class __transform_view_sentinel;
+
template<input_range _View, copy_constructible _Fn>
requires __transform_view_constraints<_View, _Fn>
class transform_view : public view_interface<transform_view<_View, _Fn>> {
- template<bool> class __iterator;
- template<bool> class __sentinel;
+
+ template <bool _IsConst>
+ using __iterator = __transform_view_iterator<_View, _Fn, _IsConst>;
+
+ template <bool _IsConst>
+ using __sentinel = __transform_view_sentinel<_View, _Fn, _IsConst>;
+
+ template <input_range _ViewType, copy_constructible _FunctionType, bool _IsConst>
+ requires __transform_view_constraints<_ViewType, _FunctionType>
+ friend class __transform_view_iterator;
+
+ template <input_range _ViewType, copy_constructible _FunctionType, bool _IsConst>
+ requires __transform_view_constraints<_ViewType, _FunctionType>
+ friend class __transform_view_sentinel;
_LIBCPP_NO_UNIQUE_ADDRESS __copyable_box<_Fn> __func_;
_LIBCPP_NO_UNIQUE_ADDRESS _View __base_ = _View();
@@ -154,22 +176,23 @@ struct __transform_view_iterator_category_base<_View, _Fn> {
>;
};
-template<input_range _View, copy_constructible _Fn>
+template<input_range _View, copy_constructible _Fn, bool _Const>
requires __transform_view_constraints<_View, _Fn>
-template<bool _Const>
-class transform_view<_View, _Fn>::__iterator
+class __transform_view_iterator
: public __transform_view_iterator_category_base<_View, _Fn> {
- using _Parent = __maybe_const<_Const, transform_view>;
+ using _Parent = __maybe_const<_Const, transform_view<_View, _Fn>>;
using _Base = __maybe_const<_Const, _View>;
_Parent *__parent_ = nullptr;
- template<bool>
- friend class transform_view<_View, _Fn>::__iterator;
+ template<input_range _ViewType, copy_constructible _FunctionType, bool _IsConst>
+ requires __transform_view_constraints<_ViewType, _FunctionType>
+ friend class __transform_view_iterator;
- template<bool>
- friend class transform_view<_View, _Fn>::__sentinel;
+ template<input_range _ViewType, copy_constructible _FunctionType, bool _IsConst>
+ requires __transform_view_constraints<_ViewType, _FunctionType>
+ friend class __transform_view_sentinel;
public:
iterator_t<_Base> __current_ = iterator_t<_Base>();
@@ -179,17 +202,17 @@ public:
using difference_type = range_difference_t<_Base>;
_LIBCPP_HIDE_FROM_ABI
- __iterator() requires default_initializable<iterator_t<_Base>> = default;
+ __transform_view_iterator() requires default_initializable<iterator_t<_Base>> = default;
_LIBCPP_HIDE_FROM_ABI
- constexpr __iterator(_Parent& __parent, iterator_t<_Base> __current)
+ constexpr __transform_view_iterator(_Parent& __parent, iterator_t<_Base> __current)
: __parent_(std::addressof(__parent)), __current_(std::move(__current)) {}
- // Note: `__i` should always be `__iterator<false>`, but directly using
- // `__iterator<false>` is ill-formed when `_Const` is false
+ // Note: `__i` should always be `__transform_view_iterator<false>`, but directly using
+ // `__transform_view_iterator<false>` is ill-formed when `_Const` is false
// (see http://wg21.link/class.copy.ctor#5).
_LIBCPP_HIDE_FROM_ABI
- constexpr __iterator(__iterator<!_Const> __i)
+ constexpr __transform_view_iterator(__transform_view_iterator<_View, _Fn, !_Const> __i)
requires _Const && convertible_to<iterator_t<_View>, iterator_t<_Base>>
: __parent_(__i.__parent_), __current_(std::move(__i.__current_)) {}
@@ -211,7 +234,7 @@ public:
}
_LIBCPP_HIDE_FROM_ABI
- constexpr __iterator& operator++() {
+ constexpr __transform_view_iterator& operator++() {
++__current_;
return *this;
}
@@ -220,7 +243,7 @@ public:
constexpr void operator++(int) { ++__current_; }
_LIBCPP_HIDE_FROM_ABI
- constexpr __iterator operator++(int)
+ constexpr __transform_view_iterator operator++(int)
requires forward_range<_Base>
{
auto __tmp = *this;
@@ -229,7 +252,7 @@ public:
}
_LIBCPP_HIDE_FROM_ABI
- constexpr __iterator& operator--()
+ constexpr __transform_view_iterator& operator--()
requires bidirectional_range<_Base>
{
--__current_;
@@ -237,7 +260,7 @@ public:
}
_LIBCPP_HIDE_FROM_ABI
- constexpr __iterator operator--(int)
+ constexpr __transform_view_iterator operator--(int)
requires bidirectional_range<_Base>
{
auto __tmp = *this;
@@ -246,7 +269,7 @@ public:
}
_LIBCPP_HIDE_FROM_ABI
- constexpr __iterator& operator+=(difference_type __n)
+ constexpr __transform_view_iterator& operator+=(difference_type __n)
requires random_access_range<_Base>
{
__current_ += __n;
@@ -254,7 +277,7 @@ public:
}
_LIBCPP_HIDE_FROM_ABI
- constexpr __iterator& operator-=(difference_type __n)
+ constexpr __transform_view_iterator& operator-=(difference_type __n)
requires random_access_range<_Base>
{
__current_ -= __n;
@@ -270,77 +293,77 @@ public:
}
_LIBCPP_HIDE_FROM_ABI
- friend constexpr bool operator==(const __iterator& __x, const __iterator& __y)
+ friend constexpr bool operator==(const __transform_view_iterator& __x, const __transform_view_iterator& __y)
requires equality_comparable<iterator_t<_Base>>
{
return __x.__current_ == __y.__current_;
}
_LIBCPP_HIDE_FROM_ABI
- friend constexpr bool operator<(const __iterator& __x, const __iterator& __y)
+ friend constexpr bool operator<(const __transform_view_iterator& __x, const __transform_view_iterator& __y)
requires random_access_range<_Base>
{
return __x.__current_ < __y.__current_;
}
_LIBCPP_HIDE_FROM_ABI
- friend constexpr bool operator>(const __iterator& __x, const __iterator& __y)
+ friend constexpr bool operator>(const __transform_view_iterator& __x, const __transform_view_iterator& __y)
requires random_access_range<_Base>
{
return __x.__current_ > __y.__current_;
}
_LIBCPP_HIDE_FROM_ABI
- friend constexpr bool operator<=(const __iterator& __x, const __iterator& __y)
+ friend constexpr bool operator<=(const __transform_view_iterator& __x, const __transform_view_iterator& __y)
requires random_access_range<_Base>
{
return __x.__current_ <= __y.__current_;
}
_LIBCPP_HIDE_FROM_ABI
- friend constexpr bool operator>=(const __iterator& __x, const __iterator& __y)
+ friend constexpr bool operator>=(const __transform_view_iterator& __x, const __transform_view_iterator& __y)
requires random_access_range<_Base>
{
return __x.__current_ >= __y.__current_;
}
_LIBCPP_HIDE_FROM_ABI
- friend constexpr auto operator<=>(const __iterator& __x, const __iterator& __y)
+ friend constexpr auto operator<=>(const __transform_view_iterator& __x, const __transform_view_iterator& __y)
requires random_access_range<_Base> && three_way_comparable<iterator_t<_Base>>
{
return __x.__current_ <=> __y.__current_;
}
_LIBCPP_HIDE_FROM_ABI
- friend constexpr __iterator operator+(__iterator __i, difference_type __n)
+ friend constexpr __transform_view_iterator operator+(__transform_view_iterator __i, difference_type __n)
requires random_access_range<_Base>
{
- return __iterator{*__i.__parent_, __i.__current_ + __n};
+ return __transform_view_iterator{*__i.__parent_, __i.__current_ + __n};
}
_LIBCPP_HIDE_FROM_ABI
- friend constexpr __iterator operator+(difference_type __n, __iterator __i)
+ friend constexpr __transform_view_iterator operator+(difference_type __n, __transform_view_iterator __i)
requires random_access_range<_Base>
{
- return __iterator{*__i.__parent_, __i.__current_ + __n};
+ return __transform_view_iterator{*__i.__parent_, __i.__current_ + __n};
}
_LIBCPP_HIDE_FROM_ABI
- friend constexpr __iterator operator-(__iterator __i, difference_type __n)
+ friend constexpr __transform_view_iterator operator-(__transform_view_iterator __i, difference_type __n)
requires random_access_range<_Base>
{
- return __iterator{*__i.__parent_, __i.__current_ - __n};
+ return __transform_view_iterator{*__i.__parent_, __i.__current_ - __n};
}
_LIBCPP_HIDE_FROM_ABI
- friend constexpr difference_type operator-(const __iterator& __x, const __iterator& __y)
+ friend constexpr difference_type operator-(const __transform_view_iterator& __x, const __transform_view_iterator& __y)
requires sized_sentinel_for<iterator_t<_Base>, iterator_t<_Base>>
{
return __x.__current_ - __y.__current_;
}
_LIBCPP_HIDE_FROM_ABI
- friend constexpr decltype(auto) iter_move(const __iterator& __i)
+ friend constexpr decltype(auto) iter_move(const __transform_view_iterator& __i)
noexcept(noexcept(*__i))
{
if constexpr (is_lvalue_reference_v<decltype(*__i)>)
@@ -350,33 +373,37 @@ public:
}
};
-template<input_range _View, copy_constructible _Fn>
+template<input_range _View, copy_constructible _Fn, bool _Const>
requires __transform_view_constraints<_View, _Fn>
-template<bool _Const>
-class transform_view<_View, _Fn>::__sentinel {
- using _Parent = __maybe_const<_Const, transform_view>;
+class __transform_view_sentinel {
+ using _Parent = __maybe_const<_Const, transform_view<_View, _Fn>>;
using _Base = __maybe_const<_Const, _View>;
+ template <bool _IsConst>
+ using __iterator = __transform_view_iterator<_View, _Fn, _IsConst>;
+
sentinel_t<_Base> __end_ = sentinel_t<_Base>();
- template<bool>
- friend class transform_view<_View, _Fn>::__iterator;
+ template<input_range _ViewType, copy_constructible _FunctionType, bool _IsConst>
+ requires __transform_view_constraints<_ViewType, _FunctionType>
+ friend class __transform_view_iterator;
- template<bool>
- friend class transform_view<_View, _Fn>::__sentinel;
+ template<input_range _ViewType, copy_constructible _FunctionType, bool _IsConst>
+ requires __transform_view_constraints<_ViewType, _FunctionType>
+ friend class __transform_view_sentinel;
public:
_LIBCPP_HIDE_FROM_ABI
- __sentinel() = default;
+ __transform_view_sentinel() = default;
_LIBCPP_HIDE_FROM_ABI
- constexpr explicit __sentinel(sentinel_t<_Base> __end) : __end_(__end) {}
+ constexpr explicit __transform_view_sentinel(sentinel_t<_Base> __end) : __end_(__end) {}
- // Note: `__i` should always be `__sentinel<false>`, but directly using
- // `__sentinel<false>` is ill-formed when `_Const` is false
+ // Note: `__i` should always be `__transform_view_sentinel<false>`, but directly using
+ // `__transform_view_sentinel<false>` is ill-formed when `_Const` is false
// (see http://wg21.link/class.copy.ctor#5).
_LIBCPP_HIDE_FROM_ABI
- constexpr __sentinel(__sentinel<!_Const> __i)
+ constexpr __transform_view_sentinel(__transform_view_sentinel<_View, _Fn, !_Const> __i)
requires _Const && convertible_to<sentinel_t<_View>, sentinel_t<_Base>>
: __end_(std::move(__i.__end_)) {}
@@ -386,7 +413,7 @@ public:
template<bool _OtherConst>
requires sentinel_for<sentinel_t<_Base>, iterator_t<__maybe_const<_OtherConst, _View>>>
_LIBCPP_HIDE_FROM_ABI
- friend constexpr bool operator==(const __iterator<_OtherConst>& __x, const __sentinel& __y) {
+ friend constexpr bool operator==(const __iterator<_OtherConst>& __x, const __transform_view_sentinel& __y) {
return __x.__current_ == __y.__end_;
}
@@ -394,7 +421,7 @@ public:
requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<__maybe_const<_OtherConst, _View>>>
_LIBCPP_HIDE_FROM_ABI
friend constexpr range_difference_t<__maybe_const<_OtherConst, _View>>
- operator-(const __iterator<_OtherConst>& __x, const __sentinel& __y) {
+ operator-(const __iterator<_OtherConst>& __x, const __transform_view_sentinel& __y) {
return __x.__current_ - __y.__end_;
}
@@ -402,7 +429,7 @@ public:
requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<__maybe_const<_OtherConst, _View>>>
_LIBCPP_HIDE_FROM_ABI
friend constexpr range_difference_t<__maybe_const<_OtherConst, _View>>
- operator-(const __sentinel& __x, const __iterator<_OtherConst>& __y) {
+ operator-(const __transform_view_sentinel& __x, const __iterator<_OtherConst>& __y) {
return __x.__end_ - __y.__current_;
}
};
@@ -433,7 +460,7 @@ inline namespace __cpo {
} // namespace ranges
-#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
+#endif // _LIBCPP_STD_VER > 17
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__ranges/view_interface.h b/libcxx/include/__ranges/view_interface.h
index 4b36e02f7d6b..5581eb9c732a 100644
--- a/libcxx/include/__ranges/view_interface.h
+++ b/libcxx/include/__ranges/view_interface.h
@@ -6,6 +6,7 @@
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
+
#ifndef _LIBCPP___RANGES_VIEW_INTERFACE_H
#define _LIBCPP___RANGES_VIEW_INTERFACE_H
@@ -20,7 +21,9 @@
#include <__ranges/access.h>
#include <__ranges/concepts.h>
#include <__ranges/empty.h>
-#include <type_traits>
+#include <__type_traits/is_class.h>
+#include <__type_traits/make_unsigned.h>
+#include <__type_traits/remove_cv.h>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
@@ -28,7 +31,7 @@
_LIBCPP_BEGIN_NAMESPACE_STD
-#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
+#if _LIBCPP_STD_VER > 17
namespace ranges {
@@ -99,7 +102,7 @@ public:
constexpr auto size()
requires forward_range<_D2> && sized_sentinel_for<sentinel_t<_D2>, iterator_t<_D2>>
{
- return ranges::end(__derived()) - ranges::begin(__derived());
+ return std::__to_unsigned_like(ranges::end(__derived()) - ranges::begin(__derived()));
}
template<class _D2 = _Derived>
@@ -107,7 +110,7 @@ public:
constexpr auto size() const
requires forward_range<const _D2> && sized_sentinel_for<sentinel_t<const _D2>, iterator_t<const _D2>>
{
- return ranges::end(__derived()) - ranges::begin(__derived());
+ return std::__to_unsigned_like(ranges::end(__derived()) - ranges::begin(__derived()));
}
template<class _D2 = _Derived>
@@ -167,7 +170,7 @@ public:
} // namespace ranges
-#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
+#endif // _LIBCPP_STD_VER > 17
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__ranges/views.h b/libcxx/include/__ranges/views.h
index 8cc5ba3d2aca..d40c64ad8c02 100644
--- a/libcxx/include/__ranges/views.h
+++ b/libcxx/include/__ranges/views.h
@@ -18,7 +18,7 @@
_LIBCPP_BEGIN_NAMESPACE_STD
-#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
+#if _LIBCPP_STD_VER > 17
namespace ranges {
@@ -28,7 +28,7 @@ namespace views { }
namespace views = ranges::views;
-#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
+#endif // _LIBCPP_STD_VER > 17
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__ranges/zip_view.h b/libcxx/include/__ranges/zip_view.h
index a8035bc79e12..5624726e13ee 100644
--- a/libcxx/include/__ranges/zip_view.h
+++ b/libcxx/include/__ranges/zip_view.h
@@ -6,6 +6,7 @@
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
+
#ifndef _LIBCPP___RANGES_ZIP_VIEW_H
#define _LIBCPP___RANGES_ZIP_VIEW_H
@@ -44,7 +45,7 @@ _LIBCPP_PUSH_MACROS
_LIBCPP_BEGIN_NAMESPACE_STD
-#if _LIBCPP_STD_VER > 20 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
+#if _LIBCPP_STD_VER > 20
namespace ranges {
@@ -402,15 +403,15 @@ public:
_LIBCPP_HIDE_FROM_ABI
friend constexpr auto iter_move(const __iterator& __i) noexcept(
- (noexcept(ranges::iter_move(declval<const iterator_t<__maybe_const<_Const, _Views>>&>())) && ...) &&
+ (noexcept(ranges::iter_move(std::declval<const iterator_t<__maybe_const<_Const, _Views>>&>())) && ...) &&
(is_nothrow_move_constructible_v<range_rvalue_reference_t<__maybe_const<_Const, _Views>>> && ...)) {
return ranges::__tuple_transform(ranges::iter_move, __i.__current_);
}
_LIBCPP_HIDE_FROM_ABI
friend constexpr void iter_swap(const __iterator& __l, const __iterator& __r) noexcept(
- (noexcept(ranges::iter_swap(declval<const iterator_t<__maybe_const<_Const, _Views>>&>(),
- declval<const iterator_t<__maybe_const<_Const, _Views>>&>())) &&
+ (noexcept(ranges::iter_swap(std::declval<const iterator_t<__maybe_const<_Const, _Views>>&>(),
+ std::declval<const iterator_t<__maybe_const<_Const, _Views>>&>())) &&
...))
requires(indirectly_swappable<iterator_t<__maybe_const<_Const, _Views>>> && ...) {
ranges::__tuple_zip_for_each(ranges::iter_swap, __l.__current_, __r.__current_);
@@ -502,7 +503,7 @@ inline namespace __cpo {
} // namespace views
} // namespace ranges
-#endif // _LIBCPP_STD_VER > 20 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
+#endif // _LIBCPP_STD_VER > 20
_LIBCPP_END_NAMESPACE_STD