-
Couldn't load subscription status.
- Fork 15k
[libc++] implement adjacent_view #165089
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
[libc++] implement adjacent_view #165089
Conversation
|
@llvm/pr-subscribers-libcxx Author: Hui (huixie90) ChangesPatch is 147.28 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/165089.diff 41 Files Affected:
diff --git a/libcxx/docs/ReleaseNotes/22.rst b/libcxx/docs/ReleaseNotes/22.rst
index ec23ba9d1e3a1..b3186f7e486d7 100644
--- a/libcxx/docs/ReleaseNotes/22.rst
+++ b/libcxx/docs/ReleaseNotes/22.rst
@@ -39,7 +39,7 @@ Implemented Papers
------------------
- P2321R2: ``zip`` (`Github <https://llvm.org/PR105169>`__) (The paper is partially implemented. ``zip_transform_view``
- is implemented in this release)
+ and `adjacent_view` are implemented in this release)
- P3044R2: sub-``string_view`` from ``string`` (`Github <https://llvm.org/PR148140>`__)
- P3223R2: Making ``std::istream::ignore`` less surprising (`Github <https://llvm.org/PR148178>`__)
- P3060R3: Add ``std::views::indices(n)`` (`Github <https://llvm.org/PR148175>`__)
diff --git a/libcxx/include/CMakeLists.txt b/libcxx/include/CMakeLists.txt
index ddace8bf8c728..9d725f49a18f1 100644
--- a/libcxx/include/CMakeLists.txt
+++ b/libcxx/include/CMakeLists.txt
@@ -696,6 +696,7 @@ set(files
__random/uniform_real_distribution.h
__random/weibull_distribution.h
__ranges/access.h
+ __ranges/adjacent_view.h
__ranges/all.h
__ranges/as_rvalue_view.h
__ranges/chunk_by_view.h
@@ -739,6 +740,7 @@ set(files
__ranges/view_interface.h
__ranges/views.h
__ranges/zip_transform_view.h
+ __ranges/zip_utils.h
__ranges/zip_view.h
__split_buffer
__std_mbstate_t.h
diff --git a/libcxx/include/__ranges/adjacent_view.h b/libcxx/include/__ranges/adjacent_view.h
new file mode 100644
index 0000000000000..cdb62385a5795
--- /dev/null
+++ b/libcxx/include/__ranges/adjacent_view.h
@@ -0,0 +1,408 @@
+// -*- 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_ADJACENT_VIEW_H
+#define _LIBCPP___RANGES_ADJACENT_VIEW_H
+
+#include <__config>
+
+#include <__algorithm/min.h>
+#include <__compare/three_way_comparable.h>
+#include <__concepts/constructible.h>
+#include <__concepts/convertible_to.h>
+#include <__concepts/equality_comparable.h>
+#include <__cstddef/size_t.h>
+#include <__functional/invoke.h>
+#include <__functional/operations.h>
+#include <__iterator/concepts.h>
+#include <__iterator/incrementable_traits.h>
+#include <__iterator/iter_move.h>
+#include <__iterator/iter_swap.h>
+#include <__iterator/iterator_traits.h>
+#include <__iterator/next.h>
+#include <__iterator/prev.h>
+#include <__ranges/access.h>
+#include <__ranges/all.h>
+#include <__ranges/concepts.h>
+#include <__ranges/empty_view.h>
+#include <__ranges/enable_borrowed_range.h>
+#include <__ranges/range_adaptor.h>
+#include <__ranges/size.h>
+#include <__ranges/view_interface.h>
+#include <__ranges/zip_utils.h>
+#include <__type_traits/common_type.h>
+#include <__type_traits/is_nothrow_constructible.h>
+#include <__type_traits/make_unsigned.h>
+#include <__type_traits/maybe_const.h>
+#include <__utility/declval.h>
+#include <__utility/forward.h>
+#include <__utility/integer_sequence.h>
+#include <__utility/move.h>
+#include <array>
+#include <tuple>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#if _LIBCPP_STD_VER >= 23
+
+namespace ranges {
+
+template <forward_range _View, size_t _Np>
+ requires view<_View> && (_Np > 0)
+class adjacent_view : public view_interface<adjacent_view<_View, _Np>> {
+private:
+ _LIBCPP_NO_UNIQUE_ADDRESS _View __base_ = _View();
+
+ template <bool>
+ class __iterator;
+
+ template <bool>
+ class __sentinel;
+
+ struct __as_sentinel {};
+
+public:
+ _LIBCPP_HIDE_FROM_ABI adjacent_view()
+ requires default_initializable<_View>
+ = default;
+
+ _LIBCPP_HIDE_FROM_ABI constexpr explicit adjacent_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<false>(ranges::begin(__base_), ranges::end(__base_));
+ }
+
+ _LIBCPP_HIDE_FROM_ABI constexpr auto begin() const
+ requires range<const _View> // todo: this seems under-constrained. lwg issue?
+ {
+ return __iterator<true>(ranges::begin(__base_), ranges::end(__base_));
+ }
+
+ _LIBCPP_HIDE_FROM_ABI constexpr auto end()
+ requires(!__simple_view<_View>)
+ {
+ if constexpr (common_range<_View>) {
+ return __iterator<false>(__as_sentinel{}, ranges::begin(__base_), ranges::end(__base_));
+ } else {
+ return __sentinel<false>(ranges::end(__base_));
+ }
+ }
+
+ _LIBCPP_HIDE_FROM_ABI constexpr auto end() const
+ requires range<const _View>
+ {
+ if constexpr (common_range<const _View>) {
+ return __iterator<true>(__as_sentinel{}, ranges::begin(__base_), ranges::end(__base_));
+ } else {
+ return __sentinel<true>(ranges::end(__base_));
+ }
+ }
+
+ _LIBCPP_HIDE_FROM_ABI constexpr auto size()
+ requires sized_range<_View>
+ {
+ using _ST = decltype(ranges::size(__base_));
+ using _CT = common_type_t<_ST, size_t>;
+ auto __sz = static_cast<_CT>(ranges::size(__base_));
+ __sz -= std::min<_CT>(__sz, _Np - 1);
+ return static_cast<_ST>(__sz);
+ }
+
+ _LIBCPP_HIDE_FROM_ABI constexpr auto size() const
+ requires sized_range<const _View>
+ {
+ using _ST = decltype(ranges::size(__base_));
+ using _CT = common_type_t<_ST, size_t>;
+ auto __sz = static_cast<_CT>(ranges::size(__base_));
+ __sz -= std::min<_CT>(__sz, _Np - 1);
+ return static_cast<_ST>(__sz);
+ }
+};
+
+template <forward_range _View, size_t _Np>
+ requires view<_View> && (_Np > 0)
+template <bool _Const>
+class adjacent_view<_View, _Np>::__iterator {
+ friend adjacent_view;
+ using _Base = __maybe_const<_Const, _View>;
+ array<iterator_t<_Base>, _Np> __current_ = array<iterator_t<_Base>, _Np>();
+
+ _LIBCPP_HIDE_FROM_ABI constexpr __iterator(iterator_t<_Base> __first, sentinel_t<_Base> __last) {
+ __current_[0] = __first;
+ for (int __i = 1; __i < static_cast<int>(_Np); ++__i) {
+ __current_[__i] = ranges::next(__current_[__i - 1], 1, __last);
+ }
+ }
+
+ _LIBCPP_HIDE_FROM_ABI constexpr __iterator(__as_sentinel, iterator_t<_Base> __first, iterator_t<_Base> __last) {
+ if constexpr (!bidirectional_range<_Base>) {
+ __current_.fill(__last);
+ } else {
+ __current_[_Np - 1] = __last;
+ for (int __i = static_cast<int>(_Np) - 2; __i >= 0; --__i) {
+ __current_[__i] = ranges::prev(__current_[__i + 1], 1, __first);
+ }
+ }
+ }
+
+ template <class _Iter, size_t... _Is>
+ _LIBCPP_HIDE_FROM_ABI explicit constexpr __iterator(_Iter&& __i, index_sequence<_Is...>)
+ : __current_{std::move(__i.__current_[_Is])...} {}
+
+ 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
+ return forward_iterator_tag{};
+ }
+
+ template <class _Tp, size_t... _Is>
+ static auto __repeat_tuple_helper(index_sequence<_Is...>) -> tuple<decltype((_Is, std::declval<_Tp (*)()>()()))...>;
+
+public:
+ using iterator_category = input_iterator_tag;
+ using iterator_concept = decltype(__get_iterator_concept());
+ using value_type = decltype(__repeat_tuple_helper<range_value_t<_Base>>(make_index_sequence<_Np>{}));
+ using difference_type = range_difference_t<_Base>;
+
+ _LIBCPP_HIDE_FROM_ABI __iterator() = default;
+ _LIBCPP_HIDE_FROM_ABI constexpr __iterator(__iterator<!_Const> __i)
+ requires _Const && convertible_to<iterator_t<_View>, iterator_t<_Base>>
+ : __iterator(std::move(__i), make_index_sequence<_Np>{}) {}
+
+ _LIBCPP_HIDE_FROM_ABI constexpr auto operator*() const {
+ return ranges::__tuple_transform([](auto& __i) -> decltype(auto) { return *__i; }, __current_);
+ }
+
+ _LIBCPP_HIDE_FROM_ABI constexpr __iterator& operator++() {
+ for (auto& __i : __current_) {
+ ++__i;
+ }
+ return *this;
+ }
+
+ _LIBCPP_HIDE_FROM_ABI constexpr __iterator operator++(int) {
+ auto __tmp = *this;
+ ++*this;
+ return __tmp;
+ }
+
+ _LIBCPP_HIDE_FROM_ABI constexpr __iterator& operator--()
+ requires bidirectional_range<_Base>
+ {
+ for (auto& __i : __current_) {
+ --__i;
+ }
+ return *this;
+ }
+
+ _LIBCPP_HIDE_FROM_ABI constexpr __iterator operator--(int)
+ requires bidirectional_range<_Base>
+ {
+ auto __tmp = *this;
+ --*this;
+ return __tmp;
+ }
+
+ _LIBCPP_HIDE_FROM_ABI constexpr __iterator& operator+=(difference_type __x)
+ requires random_access_range<_Base>
+ {
+ for (auto& __i : __current_) {
+ __i += __x;
+ }
+ return *this;
+ }
+
+ _LIBCPP_HIDE_FROM_ABI constexpr __iterator& operator-=(difference_type __x)
+ requires random_access_range<_Base>
+ {
+ for (auto& __i : __current_) {
+ __i -= __x;
+ }
+ return *this;
+ }
+
+ _LIBCPP_HIDE_FROM_ABI constexpr auto operator[](difference_type n) const
+ requires random_access_range<_Base>
+ {
+ return ranges::__tuple_transform([&](auto& __i) -> decltype(auto) { return __i[n]; }, __current_);
+ }
+
+ _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator==(const __iterator& __x, const __iterator& __y) {
+ return __x.__current_.back() == __y.__current_.back();
+ }
+
+ _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator<(const __iterator& __x, const __iterator& __y)
+ requires random_access_range<_Base>
+ {
+ return __x.__current_.back() < __y.__current_.back();
+ }
+
+ _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator>(const __iterator& __x, const __iterator& __y)
+ requires random_access_range<_Base>
+ {
+ return __y < __x;
+ }
+
+ _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator<=(const __iterator& __x, const __iterator& __y)
+ requires random_access_range<_Base>
+ {
+ return !(__y < __x);
+ }
+
+ _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator>=(const __iterator& __x, const __iterator& __y)
+ requires random_access_range<_Base>
+ {
+ return !(__x < __y);
+ }
+
+ _LIBCPP_HIDE_FROM_ABI friend constexpr auto operator<=>(const __iterator& __x, const __iterator& __y)
+ requires random_access_range<_Base> && three_way_comparable<iterator_t<_Base>>
+ {
+ return __x.__current_.back() <=> __y.__current_.back();
+ }
+
+ _LIBCPP_HIDE_FROM_ABI friend constexpr __iterator operator+(const __iterator& __i, difference_type __n)
+ requires random_access_range<_Base>
+ {
+ auto __r = __i;
+ __r += __n;
+ return __r;
+ }
+
+ _LIBCPP_HIDE_FROM_ABI friend constexpr __iterator operator+(difference_type __n, const __iterator& __i)
+ requires random_access_range<_Base>
+ {
+ return __i + __n;
+ }
+
+ _LIBCPP_HIDE_FROM_ABI friend constexpr __iterator operator-(const __iterator& __i, difference_type __n)
+ requires random_access_range<_Base>
+ {
+ auto __r = __i;
+ __r -= __n;
+ return __r;
+ }
+
+ _LIBCPP_HIDE_FROM_ABI friend constexpr difference_type operator-(const __iterator& __x, const __iterator& __y)
+ requires sized_sentinel_for<iterator_t<_Base>, iterator_t<_Base>>
+ {
+ return __x.__current_.back() - __y.__current_.back();
+ }
+
+ _LIBCPP_HIDE_FROM_ABI friend constexpr auto iter_move(const __iterator& __i) noexcept(
+ noexcept(ranges::iter_move(std::declval<const iterator_t<_Base>&>())) &&
+ is_nothrow_move_constructible_v<range_rvalue_reference_t<_Base>>) {
+ 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(std::declval<iterator_t<_Base>>(), std::declval<iterator_t<_Base>>())))
+ requires indirectly_swappable<iterator_t<_Base>>
+ {
+ for (size_t __i = 0; __i < _Np; ++__i) {
+ ranges::iter_swap(__l.__current_[__i], __r.__current_[__i]);
+ }
+ }
+};
+
+template <forward_range _View, size_t _Np>
+ requires view<_View> && (_Np > 0)
+template <bool _Const>
+class adjacent_view<_View, _Np>::__sentinel {
+ friend adjacent_view;
+ using _Base = __maybe_const<_Const, _View>;
+ sentinel_t<_Base> __end_ = sentinel_t<_Base>();
+
+ _LIBCPP_HIDE_FROM_ABI constexpr explicit __sentinel(sentinel_t<_Base> __end) { __end_ = std::move(__end); }
+
+public:
+ _LIBCPP_HIDE_FROM_ABI __sentinel() = default;
+
+ _LIBCPP_HIDE_FROM_ABI constexpr __sentinel(__sentinel<!_Const> __i)
+ requires _Const && convertible_to<sentinel_t<_View>, sentinel_t<_Base>>
+ : __end_(std::move(__i.__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) {
+ return __x.__current_.back() == __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 __iterator<_OtherConst>& __x, const __sentinel& __y) {
+ return __x.__current_.back() - __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 __sentinel& __y, const __iterator<_OtherConst>& __x) {
+ return __y.__end_ - __x.__current_.back();
+ }
+};
+
+template <class _View, size_t _Np>
+constexpr bool enable_borrowed_range<adjacent_view<_View, _Np>> = enable_borrowed_range<_View>;
+
+namespace views {
+namespace __adjacent {
+
+template <size_t _Np>
+struct __fn : __range_adaptor_closure<__fn<_Np>> {
+ template <class _Range>
+ requires(_Np == 0 && forward_range<_Range &&>)
+ _LIBCPP_HIDE_FROM_ABI static constexpr auto operator()(_Range&&) noexcept {
+ return empty_view<tuple<>>{};
+ }
+
+ template <class _Ranges>
+ _LIBCPP_HIDE_FROM_ABI static constexpr auto operator()(_Ranges&& __range) noexcept(
+ noexcept(adjacent_view<views::all_t<_Ranges&&>, _Np>(std::forward<_Ranges>(__range))))
+ -> decltype(adjacent_view<views::all_t<_Ranges&&>, _Np>(std::forward<_Ranges>(__range))) {
+ return adjacent_view<views::all_t<_Ranges&&>, _Np>(std::forward<_Ranges>(__range));
+ }
+};
+
+} // namespace __adjacent
+inline namespace __cpo {
+template <size_t _Np>
+inline constexpr auto adjacent = __adjacent::__fn<_Np>{};
+inline constexpr auto pairwise = adjacent<2>;
+} // namespace __cpo
+} // namespace views
+} // namespace ranges
+
+#endif // _LIBCPP_STD_VER >= 23
+
+_LIBCPP_END_NAMESPACE_STD
+
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP___RANGES_ADJACENT_VIEW_H
\ No newline at end of file
diff --git a/libcxx/include/__ranges/zip_utils.h b/libcxx/include/__ranges/zip_utils.h
new file mode 100644
index 0000000000000..d993e2c05b0d6
--- /dev/null
+++ b/libcxx/include/__ranges/zip_utils.h
@@ -0,0 +1,49 @@
+
+// -*- 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_ZIP_VIEW_H
+#define _LIBCPP___RANGES_ZIP_VIEW_H
+
+#include <__config>
+
+#include <__functional/invoke.h>
+#include <__utility/forward.h>
+#include <tuple>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#if _LIBCPP_STD_VER >= 23
+
+namespace ranges {
+
+template <class _Fun, class _Tuple>
+_LIBCPP_HIDE_FROM_ABI constexpr auto __tuple_transform(_Fun&& __f, _Tuple&& __tuple) {
+ return std::apply(
+ [&]<class... _Types>(_Types&&... __elements) {
+ return tuple<invoke_result_t<_Fun&, _Types>...>(std::invoke(__f, std::forward<_Types>(__elements))...);
+ },
+ std::forward<_Tuple>(__tuple));
+}
+
+} // namespace ranges
+#endif // _LIBCPP_STD_VER >= 23
+
+_LIBCPP_END_NAMESPACE_STD
+
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP___RANGES_ZIP_VIEW_H
\ No newline at end of file
diff --git a/libcxx/include/__ranges/zip_view.h b/libcxx/include/__ranges/zip_view.h
index ce00c98710c4e..bd54f37028e45 100644
--- a/libcxx/include/__ranges/zip_view.h
+++ b/libcxx/include/__ranges/zip_view.h
@@ -7,8 +7,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef _LIBCPP___RANGES_ZIP_VIEW_H
-#define _LIBCPP___RANGES_ZIP_VIEW_H
+#ifndef _LIBCPP___RANGES_ZIP_UTILS_H
+#define _LIBCPP___RANGES_ZIP_UTILS_H
#include <__config>
@@ -31,6 +31,7 @@
#include <__ranges/enable_borrowed_range.h>
#include <__ranges/size.h>
#include <__ranges/view_interface.h>
+#include <__ranges/zip_utils.h>
#include <__type_traits/is_nothrow_constructible.h>
#include <__type_traits/make_unsigned.h>
#include <__utility/declval.h>
@@ -58,15 +59,6 @@ concept __zip_is_common =
(!(bidirectional_range<_Ranges> && ...) && (common_range<_Ranges> && ...)) ||
((random_access_range<_Ranges> && ...) && (sized_range<_Ranges> && ...));
-template <class _Fun, class _Tuple>
-_LIBCPP_HIDE_FROM_ABI constexpr auto __tuple_transform(_Fun&& __f, _Tuple&& __tuple) {
- return std::apply(
- [&]<class... _Types>(_Types&&... __elements) {
- return tuple<invoke_result_t<_Fun&, _Types>...>(std::invoke(__f, std::forward<_Types>(__elements))...);
- },
- std::forward<_Tuple>(__tuple));
-}
-
template <class _Fun, class _Tuple>
_LIBCPP_HIDE_FROM_ABI constexpr void __tuple_for_each(_Fun&& __f, _Tuple&& __tuple) {
std::apply(
@@ -504,4 +496,4 @@ _LIBCPP_END_NAMESPACE_STD
_LIBCPP_POP_MACROS
-#endif // _LIBCPP___RANGES_ZIP_VIEW_H
+#endif // _LIBCPP___RANGES_ZIP_UTILS_H
diff --git a/libcxx/include/module.modulemap.in b/libcxx/include/module.modulemap.in
index 894093b409e11..e2b60cf8607db 100644
--- a/libcxx/include/module.modulemap.in
+++ b/libcxx/include/module.modulemap.in
@@ -1850,6 +1850,7 @@ module std [system] {
module ranges {
module access { header "__ranges/access.h" }
+ module adjacent_view { header "__ranges/adjacent_view.h" }
module all {
header "__ranges/all.h"
export std.ranges.ref_view
@@ -1947,6 +1948,9 @@ module std [system] {
header "__ranges/zip_view.h"
export std.utility.pair
}
+ module zip_utils {
+ header "__ranges/zip_utils.h"
+ }
module zip_transform_view {
header "__ranges/zip_transform_view.h"
}
diff --git a/libcxx/include/ranges b/libcxx/include/ranges
index cfaa66a0831b3..fe272579ca898 100644
--- a/libcxx/include/ranges
+++ b/libcxx/include/ranges
@@ -353,6 +353,20 @@ namespace std::ranges {
namespace views { inline constexpr unspecified zip_transform = unspecified; } // C++23
+ // [range.adjacent], adjacent view
+ template<forward_range V, size_t N>
+ requires view<V> && (N > 0)
+ class adjacent_view;
+
+ template<class V, size_t N>
+ constexpr bool enable_borrowed_range<adjacent_view<V, N>> =
+ enable_borrowed_range<V>;
+
+ namespace views {
+ template<size_t N>
+ constexpr unspecified adjacent = unspecified;
+ inline constexpr auto pairwise = adjacent<2>;
+ }
// [range.as.rvalue]
template <view V>
@@ -411,6 +425,7 @@ namespace std {
# if _LIBCPP_STD_VER >= 20
# include <__ranges/access.h>
+# include <__ranges/adjacent_view.h>
# include <__ranges/all.h>
# include <__ranges/common_view.h>
# include <__ranges/concepts.h>
diff --git a/libcxx/modules/std/ranges.inc b/libcxx...
[truncated]
|
You can test this locally with the following command:git-clang-format --diff origin/main HEAD --extensions ,h,inc,cpp -- libcxx/include/__ranges/adjacent_view.h libcxx/include/__ranges/zip_utils.h libcxx/test/std/ranges/range.adaptors/range.adjacent/adaptor.pass.cpp libcxx/test/std/ranges/range.adaptors/range.adjacent/base.pass.cpp libcxx/test/std/ranges/range.adaptors/range.adjacent/begin.pass.cpp libcxx/test/std/ranges/range.adaptors/range.adjacent/borrowing.compile.pass.cpp libcxx/test/std/ranges/range.adaptors/range.adjacent/ctor.default.pass.cpp libcxx/test/std/ranges/range.adaptors/range.adjacent/ctor.views.pass.cpp libcxx/test/std/ranges/range.adaptors/range.adjacent/end.pass.cpp libcxx/test/std/ranges/range.adaptors/range.adjacent/general.pass.cpp libcxx/test/std/ranges/range.adaptors/range.adjacent/helpers.h libcxx/test/std/ranges/range.adaptors/range.adjacent/iterator/arithmetic.pass.cpp libcxx/test/std/ranges/range.adaptors/range.adjacent/iterator/compare.pass.cpp libcxx/test/std/ranges/range.adaptors/range.adjacent/iterator/ctor.default.pass.cpp libcxx/test/std/ranges/range.adaptors/range.adjacent/iterator/ctor.other.pass.cpp libcxx/test/std/ranges/range.adaptors/range.adjacent/iterator/decrement.pass.cpp libcxx/test/std/ranges/range.adaptors/range.adjacent/iterator/deref.pass.cpp libcxx/test/std/ranges/range.adaptors/range.adjacent/iterator/increment.pass.cpp libcxx/test/std/ranges/range.adaptors/range.adjacent/iterator/iter_move.pass.cpp libcxx/test/std/ranges/range.adaptors/range.adjacent/iterator/iter_swap.pass.cpp libcxx/test/std/ranges/range.adaptors/range.adjacent/iterator/member_types.compile.pass.cpp libcxx/test/std/ranges/range.adaptors/range.adjacent/iterator/singular.pass.cpp libcxx/test/std/ranges/range.adaptors/range.adjacent/iterator/subscript.pass.cpp libcxx/test/std/ranges/range.adaptors/range.adjacent/range.concept.compile.pass.cpp libcxx/test/std/ranges/range.adaptors/range.adjacent/sentinel/ctor.default.pass.cpp libcxx/test/std/ranges/range.adaptors/range.adjacent/sentinel/ctor.other.pass.cpp libcxx/test/std/ranges/range.adaptors/range.adjacent/sentinel/eq.pass.cpp libcxx/test/std/ranges/range.adaptors/range.adjacent/sentinel/minus.pass.cpp libcxx/test/std/ranges/range.adaptors/range.adjacent/size.pass.cpp libcxx/include/__ranges/zip_view.h libcxx/include/ranges libcxx/modules/std/ranges.inc libcxx/test/std/library/description/conventions/customization.point.object/cpo.compile.pass.cpp libcxx/test/std/ranges/range.adaptors/range.join/adaptor.pass.cpp libcxx/test/std/ranges/range.adaptors/range.zip.transform/sentinel/minus.pass.cpp libcxx/test/std/ranges/range.adaptors/range.zip/sentinel/minus.pass.cpp libcxx/test/std/ranges/range.adaptors/range_adaptor_types.h libcxx/test/std/ranges/ranges_robust_against_no_unique_address.pass.cpp --diff_from_common_commit
View the diff from clang-format here.diff --git a/libcxx/test/std/ranges/range.adaptors/range.join/adaptor.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.join/adaptor.pass.cpp
index 10c092cf3..e990ffa29 100644
--- a/libcxx/test/std/ranges/range.adaptors/range.join/adaptor.pass.cpp
+++ b/libcxx/test/std/ranges/range.adaptors/range.join/adaptor.pass.cpp
@@ -21,10 +21,10 @@
struct MoveOnlyView : SimpleForwardCommonOuter<ForwardCommonInner> {
using SimpleForwardCommonOuter<ForwardCommonInner>::SimpleForwardCommonOuter;
- constexpr MoveOnlyView(MoveOnlyView&&) = default;
+ constexpr MoveOnlyView(MoveOnlyView&&) = default;
constexpr MoveOnlyView(const MoveOnlyView&) = delete;
- constexpr MoveOnlyView& operator=(MoveOnlyView&&) = default;
+ constexpr MoveOnlyView& operator=(MoveOnlyView&&) = default;
constexpr MoveOnlyView& operator=(const MoveOnlyView&) = delete;
};
@@ -51,7 +51,7 @@ constexpr bool test() {
{
// Test `views::join(move-only-view)`
ForwardCommonInner inners[3] = {buffer1, buffer2, buffer3};
- using Result = std::ranges::join_view<MoveOnlyView>;
+ using Result = std::ranges::join_view<MoveOnlyView>;
std::same_as<Result> decltype(auto) v = std::views::join(MoveOnlyView{inners});
assert(std::ranges::next(v.begin(), 9) == v.end());
assert(&(*v.begin()) == buffer1);
@@ -86,7 +86,7 @@ constexpr bool test() {
{
// Test `move-only-view | views::join`
ForwardCommonInner inners[3] = {buffer1, buffer2, buffer3};
- using Result = std::ranges::join_view<MoveOnlyView>;
+ using Result = std::ranges::join_view<MoveOnlyView>;
std::same_as<Result> decltype(auto) v = MoveOnlyView{inners} | std::views::join;
assert(std::ranges::next(v.begin(), 9) == v.end());
assert(&(*v.begin()) == buffer1);
|
No description provided.