From 25afd3bbf2b053e5ee99195ba7b4c0268cced6c0 Mon Sep 17 00:00:00 2001 From: anonymouspc Date: Mon, 8 Dec 2025 17:55:02 +0800 Subject: [PATCH 01/34] [libc++] Implement P2242R1 `std::views::chunk` This PR implements libc++ `std::ranges::chunk_view` in header <__ranges/chunk_view.h>. --- libcxx/docs/FeatureTestMacroTable.rst | 2 +- libcxx/docs/ReleaseNotes/22.rst | 1 + libcxx/docs/Status/Cxx23Papers.csv | 2 +- libcxx/include/CMakeLists.txt | 1 + libcxx/include/__cxx03/module.modulemap | 1 + libcxx/include/__ranges/chunk_view.h | 544 ++++++++++++++++++ libcxx/include/module.modulemap.in | 4 + libcxx/include/ranges | 12 + libcxx/include/version | 2 +- libcxx/modules/std/ranges.inc | 6 +- .../ranges.version.compile.pass.cpp | 32 +- .../version.version.compile.pass.cpp | 32 +- .../range.chunk/adaptor.pass.cpp | 73 +++ .../range.adaptors/range.chunk/base.pass.cpp | 41 ++ .../range.adaptors/range.chunk/begin.pass.cpp | 63 ++ .../range.chunk/ctad.compile.pass.cpp | 48 ++ .../range.adaptors/range.chunk/end.pass.cpp | 64 +++ .../range.chunk/general.pass.cpp | 47 ++ .../range.chunk.iter/compare.pass.cpp | 44 ++ .../range.chunk.iter/decrement.pass.cpp | 48 ++ .../range.chunk.iter/increment.pass.cpp | 46 ++ .../ranges/range.adaptors/range.chunk/types.h | 70 +++ .../generate_feature_test_macro_components.py | 1 - .../gn/secondary/libcxx/include/BUILD.gn | 1 + 24 files changed, 1135 insertions(+), 50 deletions(-) create mode 100644 libcxx/include/__ranges/chunk_view.h create mode 100644 libcxx/test/std/ranges/range.adaptors/range.chunk/adaptor.pass.cpp create mode 100644 libcxx/test/std/ranges/range.adaptors/range.chunk/base.pass.cpp create mode 100644 libcxx/test/std/ranges/range.adaptors/range.chunk/begin.pass.cpp create mode 100644 libcxx/test/std/ranges/range.adaptors/range.chunk/ctad.compile.pass.cpp create mode 100644 libcxx/test/std/ranges/range.adaptors/range.chunk/end.pass.cpp create mode 100644 libcxx/test/std/ranges/range.adaptors/range.chunk/general.pass.cpp create mode 100644 libcxx/test/std/ranges/range.adaptors/range.chunk/range.chunk.iter/compare.pass.cpp create mode 100644 libcxx/test/std/ranges/range.adaptors/range.chunk/range.chunk.iter/decrement.pass.cpp create mode 100644 libcxx/test/std/ranges/range.adaptors/range.chunk/range.chunk.iter/increment.pass.cpp create mode 100644 libcxx/test/std/ranges/range.adaptors/range.chunk/types.h diff --git a/libcxx/docs/FeatureTestMacroTable.rst b/libcxx/docs/FeatureTestMacroTable.rst index 756bdf71f8b22..49672e5ccf70a 100644 --- a/libcxx/docs/FeatureTestMacroTable.rst +++ b/libcxx/docs/FeatureTestMacroTable.rst @@ -370,7 +370,7 @@ Status ---------------------------------------------------------- ----------------- ``__cpp_lib_ranges_as_rvalue`` ``202207L`` ---------------------------------------------------------- ----------------- - ``__cpp_lib_ranges_chunk`` *unimplemented* + ``__cpp_lib_ranges_chunk`` ``202202L`` ---------------------------------------------------------- ----------------- ``__cpp_lib_ranges_chunk_by`` ``202202L`` ---------------------------------------------------------- ----------------- diff --git a/libcxx/docs/ReleaseNotes/22.rst b/libcxx/docs/ReleaseNotes/22.rst index 9f1e3d570f254..151bd6233ba60 100644 --- a/libcxx/docs/ReleaseNotes/22.rst +++ b/libcxx/docs/ReleaseNotes/22.rst @@ -49,6 +49,7 @@ Implemented Papers - P2835R7: Expose ``std::atomic_ref``'s object address (`Github `__) - P2944R3: Comparisons for ``reference_wrapper`` (`Github `__) - P3168R2: Give ``std::optional`` Range Support (`Github `__) +- P2442R1: Add ``std::views::chunk`` (`Github `__) Improvements and New Features ----------------------------- diff --git a/libcxx/docs/Status/Cxx23Papers.csv b/libcxx/docs/Status/Cxx23Papers.csv index b655384bad7f2..7aa2f07d9bb57 100644 --- a/libcxx/docs/Status/Cxx23Papers.csv +++ b/libcxx/docs/Status/Cxx23Papers.csv @@ -48,7 +48,7 @@ "`P2387R3 `__","Pipe support for user-defined range adaptors","2022-02 (Virtual)","|Complete|","19","`#105183 `__","" "`P2440R1 `__","``ranges::iota``, ``ranges::shift_left`` and ``ranges::shift_right``","2022-02 (Virtual)","|Partial|","","`#105184 `__","Only ``ranges::iota`` is implemented." "`P2441R2 `__","``views::join_with``","2022-02 (Virtual)","|Complete|","21","`#105185 `__","" -"`P2442R1 `__","Windowing range adaptors: ``views::chunk`` and ``views::slide``","2022-02 (Virtual)","","","`#105187 `__","" +"`P2442R1 `__","Windowing range adaptors: ``views::chunk`` and ``views::slide``","2022-02 (Virtual)","|Partial|","22","`#105187 `__","Only ``views::chunk`` is implemented." "`P2443R1 `__","``views::chunk_by``","2022-02 (Virtual)","|Complete|","18","`#105188 `__","" "","","","","","","" "`P0009R18 `__","mdspan: A Non-Owning Multidimensional Array Reference","2022-07 (Virtual)","|Complete|","18","`#105189 `__","" diff --git a/libcxx/include/CMakeLists.txt b/libcxx/include/CMakeLists.txt index cbcd764e67d93..afe8391f1a5d5 100644 --- a/libcxx/include/CMakeLists.txt +++ b/libcxx/include/CMakeLists.txt @@ -703,6 +703,7 @@ set(files __ranges/all.h __ranges/as_rvalue_view.h __ranges/chunk_by_view.h + __ranges/chunk_view.h __ranges/common_view.h __ranges/concepts.h __ranges/container_compatible_range.h diff --git a/libcxx/include/__cxx03/module.modulemap b/libcxx/include/__cxx03/module.modulemap index 34a2d0f25fc45..b7eee575090ce 100644 --- a/libcxx/include/__cxx03/module.modulemap +++ b/libcxx/include/__cxx03/module.modulemap @@ -1701,6 +1701,7 @@ module cxx03_std_private_ranges_all [system] { } module cxx03_std_private_ranges_as_rvalue_view [system] { header "__ranges/as_rvalue_view.h" } module cxx03_std_private_ranges_chunk_by_view [system] { header "__ranges/chunk_by_view.h" } +module cxx03_std_private_ranges_chunk_view [system] { header "__ranges/chunk_view.h" } module cxx03_std_private_ranges_common_view [system] { header "__ranges/common_view.h" } module cxx03_std_private_ranges_concepts [system] { header "__ranges/concepts.h" diff --git a/libcxx/include/__ranges/chunk_view.h b/libcxx/include/__ranges/chunk_view.h new file mode 100644 index 0000000000000..ae37c9784e081 --- /dev/null +++ b/libcxx/include/__ranges/chunk_view.h @@ -0,0 +1,544 @@ +// -*- 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_CHUNK_VIEW_H +#define _LIBCPP___RANGES_CHUNK_VIEW_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 <__iterator/advance.h> +#include <__iterator/concepts.h> +#include <__iterator/default_sentinel.h> +#include <__iterator/distance.h> +#include <__iterator/iter_move.h> +#include <__iterator/iter_swap.h> +#include <__iterator/iterator_traits.h> +#include <__memory/addressof.h> +#include <__ranges/access.h> +#include <__ranges/all.h> +#include <__ranges/concepts.h> +#include <__ranges/enable_borrowed_range.h> +#include <__ranges/non_propagating_cache.h> +#include <__ranges/range_adaptor.h> +#include <__ranges/take_view.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/make_unsigned.h> +#include <__utility/forward.h> +#include <__utility/move.h> + +#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 +inline _LIBCPP_HIDE_FROM_ABI constexpr auto __div_ceil(_Integral __num, _Integral __denom) { + _Integral __r = __num / __denom; + if (__num % __denom) + ++__r; + return __r; +} + +template + requires input_range<_View> +class _LIBCPP_ABI_LLVM18_NO_UNIQUE_ADDRESS chunk_view : public view_interface> { + _LIBCPP_NO_UNIQUE_ADDRESS _View __base_; + _LIBCPP_NO_UNIQUE_ADDRESS range_difference_t<_View> __n_; + _LIBCPP_NO_UNIQUE_ADDRESS range_difference_t<_View> __remainder_; + _LIBCPP_NO_UNIQUE_ADDRESS __non_propagating_cache> __current_; + + class __outer_iterator; + class __inner_iterator; + +public: + _LIBCPP_HIDE_FROM_ABI constexpr explicit chunk_view(_View __base, range_difference_t<_View> __n) + : __base_(std::move(__base)), __n_(__n), __remainder_(0) { + _LIBCPP_ASSERT_PEDANTIC(__n > 0, "Trying to construct a chunk_view with chunk size <= 0"); + } + + _LIBCPP_HIDE_FROM_ABI constexpr _View base() const& + requires std::copy_constructible<_View> + { + return __base_; + } + + _LIBCPP_HIDE_FROM_ABI constexpr _View base() && { return std::move(__base_); } + + _LIBCPP_HIDE_FROM_ABI constexpr __outer_iterator begin() { + __current_.__emplace(ranges::begin(__base_)); + __remainder_ = __n_; + return __outer_iterator(*this); + } + + _LIBCPP_HIDE_FROM_ABI constexpr default_sentinel_t end() const noexcept { return std::default_sentinel; } + + _LIBCPP_HIDE_FROM_ABI constexpr auto size() + requires sized_range<_View> + { + return std::__to_unsigned_like(ranges::__div_ceil(ranges::distance(__base_), __n_)); + } + + _LIBCPP_HIDE_FROM_ABI constexpr auto size() const + requires sized_range + { + return std::__to_unsigned_like(ranges::__div_ceil(ranges::distance(__base_), __n_)); + } +}; + +template + requires input_range<_View> +class chunk_view<_View>::__outer_iterator { + friend chunk_view; + + chunk_view* __parent_; + + _LIBCPP_HIDE_FROM_ABI constexpr explicit __outer_iterator(chunk_view& __parent) + : __parent_(std::addressof(__parent)) {} + +public: + class value_type; + using iterator_concept = input_iterator_tag; + using difference_type = range_difference_t<_View>; + + _LIBCPP_HIDE_FROM_ABI __outer_iterator(__outer_iterator&&) = default; + + _LIBCPP_HIDE_FROM_ABI __outer_iterator& operator=(__outer_iterator&&) = default; + + _LIBCPP_HIDE_FROM_ABI constexpr value_type operator*() const { + _LIBCPP_ASSERT_PEDANTIC(*this != default_sentinel, "Trying to dereference past-the-end chunk_view iterator."); + return value_type(*__parent_); + } + + _LIBCPP_HIDE_FROM_ABI constexpr __outer_iterator& operator++() { + ranges::advance(*__parent_->__current_, __parent_->__remainder_, ranges::end(__parent_->__base_)); + __parent_->__remainder_ = __parent_->__n_; + return *this; + } + + _LIBCPP_HIDE_FROM_ABI constexpr void operator++(int) { ++*this; } + + _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator==(const __outer_iterator& __i, default_sentinel_t) { + return *__i.__parent_->__current_ == ranges::end(__i.__parent_->__base_) && __i.__parent_->__remainder_ != 0; + } + + _LIBCPP_HIDE_FROM_ABI friend constexpr difference_type operator-(default_sentinel_t, const __outer_iterator& __i) + requires sized_sentinel_for, iterator_t<_View>> + { + const auto __dist = ranges::end(__i.__parent_->__base_) - *__i.__parent_->__current_; + if (__dist < __i.__parent_->__remainder_) + return __dist == 0 ? 0 : 1; + return ranges::__div_ceil(__dist - __i.__parent_->__remainder_, __i.__parent_->__n_) + 1; + } + + _LIBCPP_HIDE_FROM_ABI friend constexpr difference_type operator-(const __outer_iterator& __i, default_sentinel_t __s) + requires sized_sentinel_for, iterator_t<_View>> + { + return -(__s - __i); + } +}; + +template + requires input_range<_View> +class chunk_view<_View>::__outer_iterator::value_type : public view_interface { + friend __outer_iterator; + + chunk_view* __parent_; + + _LIBCPP_HIDE_FROM_ABI constexpr explicit value_type(chunk_view& __parent) : __parent_(std::addressof(__parent)) {} + +public: + _LIBCPP_HIDE_FROM_ABI constexpr __inner_iterator begin() const noexcept { return __inner_iterator(*__parent_); } + + _LIBCPP_HIDE_FROM_ABI constexpr default_sentinel_t end() const noexcept { return default_sentinel; } + + _LIBCPP_HIDE_FROM_ABI constexpr auto size() const + requires sized_sentinel_for, iterator_t<_View>> + { + return std::__to_unsigned_like( + ranges::min(__parent_->__remainder_, ranges::end(__parent_->__base_) - *__parent_->__current_)); + } +}; + +template + requires input_range<_View> +class chunk_view<_View>::__inner_iterator { + friend chunk_view; + + chunk_view* __parent_; + + _LIBCPP_HIDE_FROM_ABI constexpr explicit __inner_iterator(chunk_view& __parent) + : __parent_(std::addressof(__parent)) {} + +public: + using iterator_concept = input_iterator_tag; + using difference_type = range_difference_t<_View>; + using value_type = range_value_t<_View>; + + _LIBCPP_HIDE_FROM_ABI __inner_iterator(__inner_iterator&&) = default; + + _LIBCPP_HIDE_FROM_ABI __inner_iterator& operator=(__inner_iterator&&) = default; + + _LIBCPP_HIDE_FROM_ABI constexpr const iterator_t<_View> base() const& { return *__parent_->__current_; } + + _LIBCPP_HIDE_FROM_ABI constexpr range_reference_t<_View> operator*() const { + _LIBCPP_ASSERT_PEDANTIC(*this != default_sentinel, "Trying to dereference past-the-end chunk_view iterator"); + return **__parent_->__current_; + } + + _LIBCPP_HIDE_FROM_ABI constexpr __inner_iterator& operator++() { + ++*__parent_->__current_; + if (*__parent_->__current_ == ranges::end(__parent_->__base_)) + __parent_->__remainder_ = 0; + else + --__parent_->__remainder_; + return *this; + } + + _LIBCPP_HIDE_FROM_ABI constexpr void operator++(int) { ++*this; } + + _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator==(const __inner_iterator& __i, default_sentinel_t) { + return __i.__parent_->__remainder_ == 0; + } + + _LIBCPP_HIDE_FROM_ABI friend constexpr difference_type operator-(default_sentinel_t, const __inner_iterator& __i) + requires sized_sentinel_for, iterator_t<_View>> + { + return ranges::min(__i.__parent_->__remainder_, ranges::end(__i.__parent_->__base_) - *__i.__parent_->__current_); + } + + _LIBCPP_HIDE_FROM_ABI friend constexpr difference_type operator-(const __inner_iterator& __i, default_sentinel_t __s) + requires sized_sentinel_for, iterator_t<_View>> + { + return -(__s - __i); + } + + _LIBCPP_HIDE_FROM_ABI friend constexpr auto + iter_move(const __inner_iterator& __i) noexcept(noexcept(ranges::iter_move(*__i.__parent_->__current_))) { + return ranges::iter_move(*__i.__parent_->__current_); + } + + _LIBCPP_HIDE_FROM_ABI friend constexpr void + iter_swap(const __inner_iterator& __x, const __inner_iterator& __y) noexcept( + noexcept((ranges::iter_swap(*__x.__parent_->__current_, *__y.__parent_->__current_)))) + requires indirectly_swappable> + { + return ranges::iter_swap(*__x.__parent_->__current_, *__y.__parent_->__current_); + } +}; + +template + requires forward_range<_View> +class _LIBCPP_ABI_LLVM18_NO_UNIQUE_ADDRESS chunk_view<_View> : public view_interface> { + _LIBCPP_NO_UNIQUE_ADDRESS _View __base_; + _LIBCPP_NO_UNIQUE_ADDRESS range_difference_t<_View> __n_; + + template + class __iterator; + +public: + _LIBCPP_HIDE_FROM_ABI constexpr explicit chunk_view(_View __base, range_difference_t<_View> __n) + : __base_(std::move(__base)), __n_(__n) { + _LIBCPP_ASSERT_PEDANTIC(__n > 0, "Trying to construct a chunk_view with chunk size <= 0"); + } + + _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(this, ranges::begin(__base_)); + } + + _LIBCPP_HIDE_FROM_ABI constexpr auto begin() const + requires forward_range + { + return __iterator(this, ranges::begin(__base_)); + } + + _LIBCPP_HIDE_FROM_ABI constexpr auto end() + requires(!__simple_view<_View>) + { + if constexpr (common_range<_View> && sized_range<_View>) { + auto __missing = (__n_ - ranges::distance(__base_) % __n_) % __n_; + return __iterator(this, ranges::end(__base_), __missing); + } else if constexpr (common_range<_View> && !bidirectional_range<_View>) + return __iterator(this, ranges::end(__base_)); + else + return default_sentinel; + } + + _LIBCPP_HIDE_FROM_ABI constexpr auto end() const + requires forward_range + { + if constexpr (common_range && sized_range) { + auto __missing = (__n_ - ranges::distance(__base_) % __n_) % __n_; + return __iterator(this, ranges::end(__base_), __missing); + } else if constexpr (common_range && !bidirectional_range) + return __iterator(this, ranges::end(__base_)); + else + return default_sentinel; + } + + _LIBCPP_HIDE_FROM_ABI constexpr auto size() + requires sized_range<_View> + { + return std::__to_unsigned_like(ranges::__div_ceil(ranges::distance(__base_), __n_)); + } + + _LIBCPP_HIDE_FROM_ABI constexpr auto size() const + requires sized_range + { + return std::__to_unsigned_like(ranges::__div_ceil(ranges::distance(__base_), __n_)); + } +}; + +template + requires forward_range<_View> +template +class chunk_view<_View>::__iterator { + friend chunk_view; + + using _Parent _LIBCPP_NODEBUG = __maybe_const<_Const, chunk_view>; + using _Base _LIBCPP_NODEBUG = __maybe_const<_Const, _View>; + + iterator_t<_Base> __current_ = iterator_t<_Base>(); + sentinel_t<_Base> __end_ = sentinel_t<_Base>(); + range_difference_t<_Base> __n_ = 0; + range_difference_t<_Base> __missing_ = 0; + + _LIBCPP_HIDE_FROM_ABI constexpr __iterator( + _Parent* __parent, iterator_t<_Base> __current, range_difference_t<_Base> __missing = 0) + : __current_(__current), __end_(ranges::end(__parent->__base_)), __n_(__parent->__n_), __missing_(__missing) {} + + 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{}; + } + +public: + using iterator_category = input_iterator_tag; + using iterator_concept = decltype(__iterator::__get_iterator_concept()); + using value_type = decltype(views::take(subrange(__current_, __end_), __n_)); + using difference_type = range_difference_t<_Base>; + + _LIBCPP_HIDE_FROM_ABI __iterator() = default; + + _LIBCPP_HIDE_FROM_ABI constexpr __iterator(__iterator __i) + requires _Const && convertible_to, iterator_t<_Base>> && + convertible_to, sentinel_t<_Base>> + : __current_(std::move(__i.__current_)), + __end_(std::move(__i.__end_)), + __n_(__i.__n_), + __missing_(__i.__missing_) {} + + _LIBCPP_HIDE_FROM_ABI constexpr iterator_t<_Base> base() const { return __current_; } + + _LIBCPP_HIDE_FROM_ABI constexpr value_type operator*() const { + _LIBCPP_ASSERT_PEDANTIC(__current_ != __end_, "Trying to dereference past-the-end chunk_view iterator"); + return views::take(subrange(__current_, __end_), __n_); + } + + _LIBCPP_HIDE_FROM_ABI constexpr value_type operator[](difference_type __pos) const + requires random_access_range<_Base> + { + return *(*this + __pos); + } + + _LIBCPP_HIDE_FROM_ABI constexpr __iterator& operator++() { + _LIBCPP_ASSERT_PEDANTIC(__current_ != __end_, "Trying to advance past-the-end chunk_view iterator"); + __missing_ = ranges::advance(__current_, __n_, __end_); + 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> + { + ranges::advance(__current_, __missing_ - __n_); + __missing_ = 0; + return *this; + } + + _LIBCPP_HIDE_FROM_ABI constexpr __iterator operator--(int) { + auto __tmp = *this; + --*this; + return __tmp; + } + + _LIBCPP_HIDE_FROM_ABI constexpr __iterator& operator+=(difference_type __x) + requires random_access_range<_Base> + { + if (__x > 0) { + _LIBCPP_ASSERT_PEDANTIC(ranges::distance(__current_, __end_) > __n_ * (__x - 1), + "Trying to advance chunk_view iterator out of range"); + ranges::advance(__current_, __n_ * (__x - 1)); + __missing_ = ranges::advance(__current_, __n_, __end_); + } else if (__x < 0) { + ranges::advance(__current_, __n_ * __x + __missing_); + __missing_ = 0; + } + return *this; + } + + _LIBCPP_HIDE_FROM_ABI constexpr __iterator& operator-=(difference_type __x) + requires random_access_range<_Base> + { + return *this += -__x; + } + + _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator==(const __iterator& __x, const __iterator& __y) { + return __x.__current_ == __y.__current_; + } + + _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator==(const __iterator& __x, default_sentinel_t) { + return __x.__current_ == __x.__end_; + } + + _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator<(const __iterator& __x, const __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) + 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> + { + return __x.__current_ <=> __y.__current_; + } + + _LIBCPP_HIDE_FROM_ABI friend constexpr __iterator operator+(const __iterator& __i, difference_type __pos) + requires random_access_range<_Base> + { + auto __r = __i; + __r += __pos; + return __r; + } + + _LIBCPP_HIDE_FROM_ABI friend constexpr __iterator operator+(difference_type __pos, const __iterator& __i) + requires random_access_range<_Base> + { + auto __r = __i; + __r += __pos; + return __r; + } + + _LIBCPP_HIDE_FROM_ABI friend constexpr __iterator operator-(const __iterator& __i, difference_type __pos) + requires random_access_range<_Base> + { + auto __r = __i; + __r -= __pos; + return __r; + } + + _LIBCPP_HIDE_FROM_ABI friend constexpr difference_type operator-(const __iterator& __i, const __iterator& __j) + requires sized_sentinel_for, iterator_t<_Base>> + { + return (__i.__current_ - __j.__current_ + __i.__missing_ - __j.__missing_) / __i.__n_; + } + + _LIBCPP_HIDE_FROM_ABI friend constexpr difference_type operator-(default_sentinel_t, const __iterator& __i) + requires sized_sentinel_for, iterator_t<_Base>> + { + return ranges::__div_ceil(__i.__end_ - __i.__current_, __i.__n_); + } + + _LIBCPP_HIDE_FROM_ABI friend constexpr difference_type operator-(const __iterator& __i, default_sentinel_t __s) + requires sized_sentinel_for, iterator_t<_Base>> + { + return -(__s - __i); + } +}; + +template +chunk_view(_Range&&, range_difference_t<_Range>) -> chunk_view>; + +template +inline constexpr bool enable_borrowed_range> = forward_range<_View> && enable_borrowed_range<_View>; + +namespace views { +namespace __chunk { +struct __fn { + template + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Range&& __range, range_difference_t<_Range> __n) const + noexcept(noexcept(/**/ chunk_view(std::forward<_Range>(__range), std::forward>(__n)))) + -> decltype(/*--*/ chunk_view(std::forward<_Range>(__range), std::forward>(__n))) { + return /*-------------*/ chunk_view(std::forward<_Range>(__range), std::forward>(__n)); + } + + template + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_DifferenceType __n) const + noexcept(is_nothrow_constructible_v, _DifferenceType>) { + return __pipeable(std::__bind_back(*this, std::forward<_DifferenceType>(__n))); + } +}; + +} // namespace __chunk + +inline namespace __cpo { +inline constexpr auto chunk = __chunk::__fn{}; +} // namespace __cpo +} // namespace views + +} // namespace ranges + +#endif // _LIBCPP_STD_VER >= 23 + +_LIBCPP_END_NAMESPACE_STD + +_LIBCPP_POP_MACROS + +#endif // _LIBCPP___RANGES_CHUNK_VIEW_H diff --git a/libcxx/include/module.modulemap.in b/libcxx/include/module.modulemap.in index 955a7cc3e364a..8d4123a1e6bb2 100644 --- a/libcxx/include/module.modulemap.in +++ b/libcxx/include/module.modulemap.in @@ -1855,6 +1855,10 @@ module std [system] { header "__ranges/chunk_by_view.h" export std.functional.bind_back } + module chunk_view { + header "__ranges/chunk_view.h" + export std.functional.bind_back + } module common_view { header "__ranges/common_view.h" } module concepts { header "__ranges/concepts.h" } module container_compatible_range { header "__ranges/container_compatible_range.h" } diff --git a/libcxx/include/ranges b/libcxx/include/ranges index cfaa66a0831b3..8fb65f5f4cad2 100644 --- a/libcxx/include/ranges +++ b/libcxx/include/ranges @@ -367,6 +367,17 @@ namespace std::ranges { class chunk_by_view; // C++23 namespace views { inline constexpr unspecified chunk_by = unspecified; } // C++23 + + // [range.chunk] + template + requires input_range + class chunk_view; // C++23 + + template + requires forward_range + class chunk_view; // C++23 + + namespace views { inline constexpr unspecified chunk = unspecified; } // C++23 } namespace std { @@ -450,6 +461,7 @@ namespace std { # if _LIBCPP_STD_VER >= 23 # include <__ranges/as_rvalue_view.h> # include <__ranges/chunk_by_view.h> +# include <__ranges/chunk_view.h> # include <__ranges/from_range.h> # include <__ranges/join_with_view.h> # include <__ranges/repeat_view.h> diff --git a/libcxx/include/version b/libcxx/include/version index 05532ea731ff3..daeb88aa2a79d 100644 --- a/libcxx/include/version +++ b/libcxx/include/version @@ -522,7 +522,7 @@ __cpp_lib_void_t 201411L # define __cpp_lib_ranges 202406L // # define __cpp_lib_ranges_as_const 202207L # define __cpp_lib_ranges_as_rvalue 202207L -// # define __cpp_lib_ranges_chunk 202202L +# define __cpp_lib_ranges_chunk 202202L # define __cpp_lib_ranges_chunk_by 202202L # define __cpp_lib_ranges_contains 202207L # define __cpp_lib_ranges_find_last 202207L diff --git a/libcxx/modules/std/ranges.inc b/libcxx/modules/std/ranges.inc index cc7daa3cd1aec..8f571eaec2536 100644 --- a/libcxx/modules/std/ranges.inc +++ b/libcxx/modules/std/ranges.inc @@ -315,15 +315,17 @@ export namespace std { using std::ranges::views::adjacent_transform; using std::ranges::views::pairwise_transform; } // namespace views +#endif +#if _LIBCPP_STD_VER >= 23 using std::ranges::chunk_view; - using std::ranges::chunk_view; - namespace views { using std::ranges::views::chunk; } +#endif +#if 0 using std::ranges::slide_view; namespace views { diff --git a/libcxx/test/std/language.support/support.limits/support.limits.general/ranges.version.compile.pass.cpp b/libcxx/test/std/language.support/support.limits/support.limits.general/ranges.version.compile.pass.cpp index 5116864879485..41e1603f62350 100644 --- a/libcxx/test/std/language.support/support.limits/support.limits.general/ranges.version.compile.pass.cpp +++ b/libcxx/test/std/language.support/support.limits/support.limits.general/ranges.version.compile.pass.cpp @@ -270,17 +270,11 @@ # error "__cpp_lib_ranges_as_rvalue should have the value 202207L in c++23" # endif -# if !defined(_LIBCPP_VERSION) -# ifndef __cpp_lib_ranges_chunk -# error "__cpp_lib_ranges_chunk should be defined in c++23" -# endif -# if __cpp_lib_ranges_chunk != 202202L -# error "__cpp_lib_ranges_chunk should have the value 202202L in c++23" -# endif -# else -# ifdef __cpp_lib_ranges_chunk -# error "__cpp_lib_ranges_chunk should not be defined because it is unimplemented in libc++!" -# endif +# ifndef __cpp_lib_ranges_chunk +# error "__cpp_lib_ranges_chunk should be defined in c++23" +# endif +# if __cpp_lib_ranges_chunk != 202202L +# error "__cpp_lib_ranges_chunk should have the value 202202L in c++23" # endif # ifndef __cpp_lib_ranges_chunk_by @@ -387,17 +381,11 @@ # error "__cpp_lib_ranges_as_rvalue should have the value 202207L in c++26" # endif -# if !defined(_LIBCPP_VERSION) -# ifndef __cpp_lib_ranges_chunk -# error "__cpp_lib_ranges_chunk should be defined in c++26" -# endif -# if __cpp_lib_ranges_chunk != 202202L -# error "__cpp_lib_ranges_chunk should have the value 202202L in c++26" -# endif -# else -# ifdef __cpp_lib_ranges_chunk -# error "__cpp_lib_ranges_chunk should not be defined because it is unimplemented in libc++!" -# endif +# ifndef __cpp_lib_ranges_chunk +# error "__cpp_lib_ranges_chunk should be defined in c++26" +# endif +# if __cpp_lib_ranges_chunk != 202202L +# error "__cpp_lib_ranges_chunk should have the value 202202L in c++26" # endif # ifndef __cpp_lib_ranges_chunk_by diff --git a/libcxx/test/std/language.support/support.limits/support.limits.general/version.version.compile.pass.cpp b/libcxx/test/std/language.support/support.limits/support.limits.general/version.version.compile.pass.cpp index 996ec29dce697..a825934e49b3a 100644 --- a/libcxx/test/std/language.support/support.limits/support.limits.general/version.version.compile.pass.cpp +++ b/libcxx/test/std/language.support/support.limits/support.limits.general/version.version.compile.pass.cpp @@ -5700,17 +5700,11 @@ # error "__cpp_lib_ranges_as_rvalue should have the value 202207L in c++23" # endif -# if !defined(_LIBCPP_VERSION) -# ifndef __cpp_lib_ranges_chunk -# error "__cpp_lib_ranges_chunk should be defined in c++23" -# endif -# if __cpp_lib_ranges_chunk != 202202L -# error "__cpp_lib_ranges_chunk should have the value 202202L in c++23" -# endif -# else -# ifdef __cpp_lib_ranges_chunk -# error "__cpp_lib_ranges_chunk should not be defined because it is unimplemented in libc++!" -# endif +# ifndef __cpp_lib_ranges_chunk +# error "__cpp_lib_ranges_chunk should be defined in c++23" +# endif +# if __cpp_lib_ranges_chunk != 202202L +# error "__cpp_lib_ranges_chunk should have the value 202202L in c++23" # endif # ifndef __cpp_lib_ranges_chunk_by @@ -7619,17 +7613,11 @@ # error "__cpp_lib_ranges_as_rvalue should have the value 202207L in c++26" # endif -# if !defined(_LIBCPP_VERSION) -# ifndef __cpp_lib_ranges_chunk -# error "__cpp_lib_ranges_chunk should be defined in c++26" -# endif -# if __cpp_lib_ranges_chunk != 202202L -# error "__cpp_lib_ranges_chunk should have the value 202202L in c++26" -# endif -# else -# ifdef __cpp_lib_ranges_chunk -# error "__cpp_lib_ranges_chunk should not be defined because it is unimplemented in libc++!" -# endif +# ifndef __cpp_lib_ranges_chunk +# error "__cpp_lib_ranges_chunk should be defined in c++26" +# endif +# if __cpp_lib_ranges_chunk != 202202L +# error "__cpp_lib_ranges_chunk should have the value 202202L in c++26" # endif # ifndef __cpp_lib_ranges_chunk_by diff --git a/libcxx/test/std/ranges/range.adaptors/range.chunk/adaptor.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.chunk/adaptor.pass.cpp new file mode 100644 index 0000000000000..8993c54ea4565 --- /dev/null +++ b/libcxx/test/std/ranges/range.adaptors/range.chunk/adaptor.pass.cpp @@ -0,0 +1,73 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++03, c++11, c++14, c++17 + +// std::views::chunk + +#include + +#include +#include +#include +#include +#include + +#include "test_range.h" +#include "types.h" + +constexpr bool test() { + std::array array = {1, 1, 1, 2, 2, 2, 3, 3}; + std::span span = {array.data(), 8}; + + // Test `views::chunk(view, n)` + { + auto chunked = std::views::chunk(span, 2); + static_assert(std::same_as>>); + assert(std::ranges::equal(*chunked.begin(), std::array{1, 1})); + } + + // Test `views::chunk(input_view, n)` + { + auto input = exactly_input_view(span); + auto chunked = std::views::chunk(input, 3); + assert(std::ranges::equal(*chunked.begin(), std::array{1, 1, 1})); + } + + // Test `views::chunk(n)(range)` + { + auto adaptor = std::views::chunk(4); + auto chunked = adaptor(span); + static_assert(std::same_as>>); + assert(std::ranges::equal(*chunked.begin(), std::array{1, 1, 1, 2})); + } + + // Test `view | views::chunk` + { + auto chunked = span | std::views::chunk(5); + static_assert(std::same_as>>); + static_assert(std::ranges::random_access_range); + assert(std::ranges::equal(*chunked.begin(), std::array{1, 1, 1, 2, 2})); + } + + // Test `views::chunk | adaptor` + { + auto multi_adaptor = std::views::chunk(1) | std::views::join; + auto rejoined = span | multi_adaptor; + assert(std::ranges::equal(rejoined, span)); + } + + return true; +} + +int main(int, char**) { + test(); + static_assert(test()); + + return 0; +} \ No newline at end of file diff --git a/libcxx/test/std/ranges/range.adaptors/range.chunk/base.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.chunk/base.pass.cpp new file mode 100644 index 0000000000000..798349a7784d8 --- /dev/null +++ b/libcxx/test/std/ranges/range.adaptors/range.chunk/base.pass.cpp @@ -0,0 +1,41 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++03, c++11, c++14, c++17 + +// std::views::chunk + +#include + +#include +#include +#include + +#include "test_range.h" + +constexpr bool test() { + std::array array = {1, 1, 1, 2, 2, 2, 3, 3}; + + // Test `chunk_view.base()` + { + auto view = array | std::views::chunk(3); + auto base = view.begin().base(); + assert(base == array.begin()); + base = view.end().base(); + assert(base == array.end()); + } + + return true; +} + +int main(int, char**) { + test(); + static_assert(test()); + + return 0; +} \ No newline at end of file diff --git a/libcxx/test/std/ranges/range.adaptors/range.chunk/begin.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.chunk/begin.pass.cpp new file mode 100644 index 0000000000000..eb4818b838725 --- /dev/null +++ b/libcxx/test/std/ranges/range.adaptors/range.chunk/begin.pass.cpp @@ -0,0 +1,63 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++03, c++11, c++14, c++17 + +// std::views::chunk + +#include + +#include +#include +#include + +#include "test_range.h" + +constexpr bool test() { + std::list full_list = {1, 1, 1, 2, 2, 2, 3, 3}; + std::list empty_list = {}; + + // Test `chunk_view.begin()` + { + auto view = full_list | std::views::chunk(3); + auto it = view.begin(); + assert(std::ranges::equal(*it, std::list{1, 1, 1})); + assert(std::ranges::equal(*++it, std::list{2, 2, 2})); + assert(std::ranges::equal(*++it, std::list{3, 3})); // The last chunk has only 2 elements. + assert(++it == view.end()); // Reaches end. + + view = full_list | std::views::chunk(5); + it = view.begin(); + assert(std::ranges::equal(*it, std::list{1, 1, 1, 2, 2})); + assert(std::ranges::equal(*++it, std::list{2, 3, 3})); + } + + // Test `empty_chunk_view.begin()` + { + auto view = empty_list | std::views::chunk(3); + assert(view.size() == 0); + assert(view.begin() == view.end()); + } + + // Test `small_view_with_big_chunk.begin()` + { + auto view = full_list | std::views::chunk(314159); + assert(view.size() == 1); + assert(std::ranges::equal(*view.begin(), full_list)); + assert(++view.begin() == view.end()); + } + + return true; +} + +int main(int, char**) { + test(); + static_assert(test()); + + return 0; +} \ No newline at end of file diff --git a/libcxx/test/std/ranges/range.adaptors/range.chunk/ctad.compile.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.chunk/ctad.compile.pass.cpp new file mode 100644 index 0000000000000..55fe4ca976976 --- /dev/null +++ b/libcxx/test/std/ranges/range.adaptors/range.chunk/ctad.compile.pass.cpp @@ -0,0 +1,48 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++03, c++11, c++14, c++17 + +// std::views::chunk + +#include + +struct view : std::ranges::view_base { + int* begin() const; + int* end() const; +}; + +struct range { + int* begin() const; + int* end() const; +}; + +struct borrowed_range { + int* begin() const; + int* end() const; +}; + +template <> +inline constexpr bool std::ranges::enable_borrowed_range = true; + +void testCTAD() { + view v; + range r; + borrowed_range br; + + static_assert(std::same_as< decltype(std::ranges::chunk_view(v, 0)), std::ranges::chunk_view >); + static_assert(std::same_as< decltype(std::ranges::chunk_view(std::move(v), 0)), std::ranges::chunk_view >); + static_assert( + std::same_as< decltype(std::ranges::chunk_view(r, 0)), std::ranges::chunk_view> >); + static_assert(std::same_as< decltype(std::ranges::chunk_view(std::move(r), 0)), + std::ranges::chunk_view> >); + static_assert(std::same_as< decltype(std::ranges::chunk_view(br, 0)), + std::ranges::chunk_view> >); + static_assert(std::same_as< decltype(std::ranges::chunk_view(std::move(br), 0)), + std::ranges::chunk_view> >); +} diff --git a/libcxx/test/std/ranges/range.adaptors/range.chunk/end.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.chunk/end.pass.cpp new file mode 100644 index 0000000000000..056e7bb57fa5b --- /dev/null +++ b/libcxx/test/std/ranges/range.adaptors/range.chunk/end.pass.cpp @@ -0,0 +1,64 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++03, c++11, c++14, c++17 + +// std::views::chunk + +#include + +#include +#include +#include +#include +#include + +#include "test_range.h" +#include "types.h" + +constexpr bool test() { + std::list list = {1, 1, 1, 2, 2, 2, 3, 3}; + std::forward_list forward_list = {1, 1, 1, 2, 2, 2, 3, 3}; + + // Test `chunk_view.end()` + { + auto view = list | std::views::chunk(3); + auto it = view.end(); + assert(std::ranges::equal(*--it, std::list{3, 3})); // We can adjust the tailing chunk-size. + assert(std::ranges::equal(*--it, std::list{2, 2, 2})); + assert(std::ranges::equal(*--it, std::list{1, 1, 1})); + } + + // Test `not_sized_chunk_view.end()` + { + auto not_sized_list = not_sized_view(list | std::views::all); + auto view = not_sized_list | std::views::chunk(4); + static_assert(std::ranges::bidirectional_range); + static_assert(!std::ranges::sized_range); + static_assert( + std::same_as< + decltype(view.end()), + std:: + default_sentinel_t>); // We cannot handle the tailing chunk without size info, so we forbids one to derement from end(). + } + + // Test `forward_chunk_view.end()` + { + auto view = list | std::views::chunk(5); + assert(++(++view.begin()) == view.end()); + } + + return true; +} + +int main(int, char**) { + test(); + static_assert(test()); + + return 0; +} \ No newline at end of file diff --git a/libcxx/test/std/ranges/range.adaptors/range.chunk/general.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.chunk/general.pass.cpp new file mode 100644 index 0000000000000..cdfb3edee38cb --- /dev/null +++ b/libcxx/test/std/ranges/range.adaptors/range.chunk/general.pass.cpp @@ -0,0 +1,47 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++03, c++11, c++14, c++17 + +// std::views::chunk + +#include + +#include +#include +#include + +#include "test_range.h" + +constexpr bool test() { + auto str = std::string_view("Cheese the chicken chunk by chunk on truck by truck"); + // clang-format off + auto str2 = str + | std::views::chunk(4) + | std::views::join + | std::views::chunk(314159) + | std::views::take(1) + | std::views::join + | std::views::lazy_split(' ') + | std::views::chunk(2) + | std::views::transform([] (auto&& subview) + { + return subview | std::views::join_with(' '); + }) + | std::views::join_with(' '); + // clang-format on + assert(std::ranges::equal(str, str2)); + return true; +} + +int main(int, char**) { + test(); + static_assert(test()); + + return 0; +} \ No newline at end of file diff --git a/libcxx/test/std/ranges/range.adaptors/range.chunk/range.chunk.iter/compare.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.chunk/range.chunk.iter/compare.pass.cpp new file mode 100644 index 0000000000000..ade621351a6cb --- /dev/null +++ b/libcxx/test/std/ranges/range.adaptors/range.chunk/range.chunk.iter/compare.pass.cpp @@ -0,0 +1,44 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++03, c++11, c++14, c++17 + +// std::views::chunk + +#include + +#include +#include +#include + +#include "test_range.h" + +constexpr bool test() { + std::vector vector = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}; + + // Test `chunk_view.__iterator.operator<=>` + { + auto view = vector | std::views::chunk(5); + assert(view.begin() < view.end()); + assert(++view.begin() < view.end()); + assert(view.begin() + 3 == view.end()); + assert(view.begin() + 3 > view.end() - 1); + assert((view.begin() <=> view.end()) == std::strong_ordering::less); + assert((view.begin() + 1 <=> view.end() - 2) == std::strong_ordering::equal); + assert((view.end() <=> view.begin()) == std::strong_ordering::greater); + } + + return true; +} + +int main(int, char**) { + test(); + static_assert(test()); + + return 0; +} \ No newline at end of file diff --git a/libcxx/test/std/ranges/range.adaptors/range.chunk/range.chunk.iter/decrement.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.chunk/range.chunk.iter/decrement.pass.cpp new file mode 100644 index 0000000000000..32ad809eda1b8 --- /dev/null +++ b/libcxx/test/std/ranges/range.adaptors/range.chunk/range.chunk.iter/decrement.pass.cpp @@ -0,0 +1,48 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++03, c++11, c++14, c++17 + +// std::views::chunk + +#include + +#include +#include +#include + +#include "test_range.h" + +constexpr bool test() { + std::vector vector = {1, 2, 3, 4, 5, 6, 7, 8}; + + // Test `chunk_view.__iterator.operator--` + { + auto view = vector | std::views::chunk(2); + assert(std::ranges::equal(*(--view.end()), std::vector{7, 8})); + } + + // Test `chunk_view.__iterator.operator-` + { + auto view = vector | std::views::chunk(3); + assert(view.end() - 3 == view.begin()); + assert((view.end() -= 3) == view.begin()); + assert(view.size() == 3); + assert(view.end() - view.begin() == 3); + assert(std::ranges::equal(*(view.end() - 2), std::vector{4, 5, 6})); + } + + return true; +} + +int main(int, char**) { + test(); + static_assert(test()); + + return 0; +} \ No newline at end of file diff --git a/libcxx/test/std/ranges/range.adaptors/range.chunk/range.chunk.iter/increment.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.chunk/range.chunk.iter/increment.pass.cpp new file mode 100644 index 0000000000000..2e12b90344ea2 --- /dev/null +++ b/libcxx/test/std/ranges/range.adaptors/range.chunk/range.chunk.iter/increment.pass.cpp @@ -0,0 +1,46 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++03, c++11, c++14, c++17 + +// std::views::chunk + +#include + +#include +#include +#include + +#include "test_range.h" + +constexpr bool test() { + std::vector vector = {1, 2, 3, 4, 5, 6, 7, 8}; + + // Test `chunk_view.__iterator.operator++` + { + auto view = vector | std::views::chunk(2); + assert(std::ranges::equal(*(++view.begin()), std::vector{3, 4})); + } + + // Test `chunk_view.__iterator.operator+` + { + auto view = vector | std::views::chunk(3); + assert(view.begin() + 3 == view.end()); + assert((view.begin() += 3) == view.end()); + assert(std::ranges::equal(*(view.begin() + 2), std::vector{7, 8})); + } + + return true; +} + +int main(int, char**) { + test(); + static_assert(test()); + + return 0; +} \ No newline at end of file diff --git a/libcxx/test/std/ranges/range.adaptors/range.chunk/types.h b/libcxx/test/std/ranges/range.adaptors/range.chunk/types.h new file mode 100644 index 0000000000000..09942d4212ef1 --- /dev/null +++ b/libcxx/test/std/ranges/range.adaptors/range.chunk/types.h @@ -0,0 +1,70 @@ +//===----------------------------------------------------------------------===// +// +// 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 TEST_STD_RANGES_RANGE_ADAPTORS_RANGE_CHUNK_TYPES_H +#define TEST_STD_RANGES_RANGE_ADAPTORS_RANGE_CHUNK_TYPES_H + +#include +#include +#include + +template +struct exactly_input_view : View, std::ranges::view_interface> { + struct iterator : std::ranges::iterator_t { + using iterator_concept = std::input_iterator_tag; + constexpr iterator() = default; + constexpr iterator(std::ranges::iterator_t i) : std::ranges::iterator_t(i) {} + constexpr auto operator*() const { return std::ranges::iterator_t::operator*(); } + friend constexpr void operator+(iterator, int) = delete; + friend constexpr void operator+(int, iterator) = delete; + friend constexpr void operator-(iterator, int) = delete; + friend constexpr void operator-(iterator, iterator) = delete; + friend constexpr iterator& operator++(iterator& self) { + self.std::ranges::template iterator_t::operator++(); + return self; + } + friend constexpr void operator++(iterator& self, int) { ++self; } + friend constexpr void operator--(iterator&) = delete; + friend constexpr void operator--(iterator&, int) = delete; + }; + + constexpr iterator begin(this auto&& self) { return iterator(self.View::begin()); } + constexpr iterator end(this auto&& self) { return iterator(self.View::end()); } +}; + +template +struct not_sized_view : View, std::ranges::view_interface> { + struct iterator : std::ranges::iterator_t { + using iterator_concept = std::bidirectional_iterator_tag; + constexpr iterator() = default; + constexpr iterator(std::ranges::iterator_t i) : std::ranges::iterator_t(i) {} + friend constexpr void operator-(iterator, iterator) = delete; + friend constexpr iterator& operator++(iterator& self) { + self.std::ranges::template iterator_t::operator++(); + return self; + } + friend constexpr iterator operator++(iterator& self, int) { return ++self; } + friend constexpr iterator& operator--(iterator& self) { + self.std::ranges::template iterator_t::operator--(); + return self; + } + friend constexpr iterator operator--(iterator& self, int) { return --self; } + }; + + constexpr iterator begin(this auto&& self) { return iterator(self.View::begin()); } + constexpr iterator end(this auto&& self) { return iterator(self.View::end()); } + constexpr auto size() const = delete; +}; + +template +not_sized_view(View) -> not_sized_view; + +template +inline constexpr bool std::ranges::disable_sized_range> = true; + +#endif \ No newline at end of file diff --git a/libcxx/utils/generate_feature_test_macro_components.py b/libcxx/utils/generate_feature_test_macro_components.py index 0802f865f9406..8cec6fe9b971b 100644 --- a/libcxx/utils/generate_feature_test_macro_components.py +++ b/libcxx/utils/generate_feature_test_macro_components.py @@ -1103,7 +1103,6 @@ def add_version_header(tc): "name": "__cpp_lib_ranges_chunk", "values": {"c++23": 202202}, "headers": ["ranges"], - "unimplemented": True, }, { "name": "__cpp_lib_ranges_chunk_by", diff --git a/llvm/utils/gn/secondary/libcxx/include/BUILD.gn b/llvm/utils/gn/secondary/libcxx/include/BUILD.gn index 9755fe3a7ea50..16be8fa8de795 100644 --- a/llvm/utils/gn/secondary/libcxx/include/BUILD.gn +++ b/llvm/utils/gn/secondary/libcxx/include/BUILD.gn @@ -1352,6 +1352,7 @@ if (current_toolchain == default_toolchain) { "__ranges/all.h", "__ranges/as_rvalue_view.h", "__ranges/chunk_by_view.h", + "__ranges/chunk_view.h", "__ranges/common_view.h", "__ranges/concepts.h", "__ranges/container_compatible_range.h", From f5f374fbd3b24c3749f98f960dd58ee9881dcdcb Mon Sep 17 00:00:00 2001 From: anonymouspc Date: Tue, 9 Dec 2025 11:03:07 +0800 Subject: [PATCH 02/34] post-code-review --- libcxx/include/__cxx03/module.modulemap | 1 - libcxx/include/__ranges/chunk_view.h | 8 ++++---- .../ranges/range.adaptors/range.chunk/adaptor.pass.cpp | 4 ++-- .../std/ranges/range.adaptors/range.chunk/base.pass.cpp | 4 ++-- .../std/ranges/range.adaptors/range.chunk/begin.pass.cpp | 4 ++-- .../range.adaptors/range.chunk/ctad.compile.pass.cpp | 2 +- .../std/ranges/range.adaptors/range.chunk/end.pass.cpp | 4 ++-- .../ranges/range.adaptors/range.chunk/general.pass.cpp | 4 ++-- .../range.chunk/range.chunk.iter/compare.pass.cpp | 4 ++-- .../range.chunk/range.chunk.iter/decrement.pass.cpp | 4 ++-- .../range.chunk/range.chunk.iter/increment.pass.cpp | 4 ++-- libcxx/test/std/ranges/range.adaptors/range.chunk/types.h | 2 +- 12 files changed, 22 insertions(+), 23 deletions(-) diff --git a/libcxx/include/__cxx03/module.modulemap b/libcxx/include/__cxx03/module.modulemap index b7eee575090ce..34a2d0f25fc45 100644 --- a/libcxx/include/__cxx03/module.modulemap +++ b/libcxx/include/__cxx03/module.modulemap @@ -1701,7 +1701,6 @@ module cxx03_std_private_ranges_all [system] { } module cxx03_std_private_ranges_as_rvalue_view [system] { header "__ranges/as_rvalue_view.h" } module cxx03_std_private_ranges_chunk_by_view [system] { header "__ranges/chunk_by_view.h" } -module cxx03_std_private_ranges_chunk_view [system] { header "__ranges/chunk_view.h" } module cxx03_std_private_ranges_common_view [system] { header "__ranges/common_view.h" } module cxx03_std_private_ranges_concepts [system] { header "__ranges/concepts.h" diff --git a/libcxx/include/__ranges/chunk_view.h b/libcxx/include/__ranges/chunk_view.h index ae37c9784e081..25fc018ba63f9 100644 --- a/libcxx/include/__ranges/chunk_view.h +++ b/libcxx/include/__ranges/chunk_view.h @@ -53,7 +53,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD namespace ranges { template -inline _LIBCPP_HIDE_FROM_ABI constexpr auto __div_ceil(_Integral __num, _Integral __denom) { +_LIBCPP_HIDE_FROM_ABI constexpr auto __div_ceil(_Integral __num, _Integral __denom) { _Integral __r = __num / __denom; if (__num % __denom) ++__r; @@ -62,7 +62,7 @@ inline _LIBCPP_HIDE_FROM_ABI constexpr auto __div_ceil(_Integral __num, _Integra template requires input_range<_View> -class _LIBCPP_ABI_LLVM18_NO_UNIQUE_ADDRESS chunk_view : public view_interface> { +class chunk_view : public view_interface> { _LIBCPP_NO_UNIQUE_ADDRESS _View __base_; _LIBCPP_NO_UNIQUE_ADDRESS range_difference_t<_View> __n_; _LIBCPP_NO_UNIQUE_ADDRESS range_difference_t<_View> __remainder_; @@ -249,7 +249,7 @@ class chunk_view<_View>::__inner_iterator { template requires forward_range<_View> -class _LIBCPP_ABI_LLVM18_NO_UNIQUE_ADDRESS chunk_view<_View> : public view_interface> { +class chunk_view<_View> : public view_interface> { _LIBCPP_NO_UNIQUE_ADDRESS _View __base_; _LIBCPP_NO_UNIQUE_ADDRESS range_difference_t<_View> __n_; @@ -513,7 +513,7 @@ namespace views { namespace __chunk { struct __fn { template - [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Range&& __range, range_difference_t<_Range> __n) const + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI static constexpr auto operator()(_Range&& __range, range_difference_t<_Range> __n) noexcept(noexcept(/**/ chunk_view(std::forward<_Range>(__range), std::forward>(__n)))) -> decltype(/*--*/ chunk_view(std::forward<_Range>(__range), std::forward>(__n))) { return /*-------------*/ chunk_view(std::forward<_Range>(__range), std::forward>(__n)); diff --git a/libcxx/test/std/ranges/range.adaptors/range.chunk/adaptor.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.chunk/adaptor.pass.cpp index 8993c54ea4565..d37d2a25c5298 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.chunk/adaptor.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.chunk/adaptor.pass.cpp @@ -6,7 +6,7 @@ // //===----------------------------------------------------------------------===// -// UNSUPPORTED: c++03, c++11, c++14, c++17 +// REQUIRES: std-at-least-c++23 // std::views::chunk @@ -70,4 +70,4 @@ int main(int, char**) { static_assert(test()); return 0; -} \ No newline at end of file +} diff --git a/libcxx/test/std/ranges/range.adaptors/range.chunk/base.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.chunk/base.pass.cpp index 798349a7784d8..0cca883399e7f 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.chunk/base.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.chunk/base.pass.cpp @@ -6,7 +6,7 @@ // //===----------------------------------------------------------------------===// -// UNSUPPORTED: c++03, c++11, c++14, c++17 +// REQUIRES: std-at-least-c++23 // std::views::chunk @@ -38,4 +38,4 @@ int main(int, char**) { static_assert(test()); return 0; -} \ No newline at end of file +} diff --git a/libcxx/test/std/ranges/range.adaptors/range.chunk/begin.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.chunk/begin.pass.cpp index eb4818b838725..5a55d1e343139 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.chunk/begin.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.chunk/begin.pass.cpp @@ -6,7 +6,7 @@ // //===----------------------------------------------------------------------===// -// UNSUPPORTED: c++03, c++11, c++14, c++17 +// REQUIRES: std-at-least-c++23 // std::views::chunk @@ -60,4 +60,4 @@ int main(int, char**) { static_assert(test()); return 0; -} \ No newline at end of file +} diff --git a/libcxx/test/std/ranges/range.adaptors/range.chunk/ctad.compile.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.chunk/ctad.compile.pass.cpp index 55fe4ca976976..ed04cd57555ff 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.chunk/ctad.compile.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.chunk/ctad.compile.pass.cpp @@ -6,7 +6,7 @@ // //===----------------------------------------------------------------------===// -// UNSUPPORTED: c++03, c++11, c++14, c++17 +// REQUIRES: std-at-least-c++23 // std::views::chunk diff --git a/libcxx/test/std/ranges/range.adaptors/range.chunk/end.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.chunk/end.pass.cpp index 056e7bb57fa5b..ccd136ab193a0 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.chunk/end.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.chunk/end.pass.cpp @@ -6,7 +6,7 @@ // //===----------------------------------------------------------------------===// -// UNSUPPORTED: c++03, c++11, c++14, c++17 +// REQUIRES: std-at-least-c++23 // std::views::chunk @@ -61,4 +61,4 @@ int main(int, char**) { static_assert(test()); return 0; -} \ No newline at end of file +} diff --git a/libcxx/test/std/ranges/range.adaptors/range.chunk/general.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.chunk/general.pass.cpp index cdfb3edee38cb..b9e81314a9580 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.chunk/general.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.chunk/general.pass.cpp @@ -6,7 +6,7 @@ // //===----------------------------------------------------------------------===// -// UNSUPPORTED: c++03, c++11, c++14, c++17 +// REQUIRES: std-at-least-c++23 // std::views::chunk @@ -44,4 +44,4 @@ int main(int, char**) { static_assert(test()); return 0; -} \ No newline at end of file +} diff --git a/libcxx/test/std/ranges/range.adaptors/range.chunk/range.chunk.iter/compare.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.chunk/range.chunk.iter/compare.pass.cpp index ade621351a6cb..0d335914b71c2 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.chunk/range.chunk.iter/compare.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.chunk/range.chunk.iter/compare.pass.cpp @@ -6,7 +6,7 @@ // //===----------------------------------------------------------------------===// -// UNSUPPORTED: c++03, c++11, c++14, c++17 +// REQUIRES: std-at-least-c++23 // std::views::chunk @@ -41,4 +41,4 @@ int main(int, char**) { static_assert(test()); return 0; -} \ No newline at end of file +} diff --git a/libcxx/test/std/ranges/range.adaptors/range.chunk/range.chunk.iter/decrement.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.chunk/range.chunk.iter/decrement.pass.cpp index 32ad809eda1b8..7bf2026c1f95d 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.chunk/range.chunk.iter/decrement.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.chunk/range.chunk.iter/decrement.pass.cpp @@ -6,7 +6,7 @@ // //===----------------------------------------------------------------------===// -// UNSUPPORTED: c++03, c++11, c++14, c++17 +// REQUIRES: std-at-least-c++23 // std::views::chunk @@ -45,4 +45,4 @@ int main(int, char**) { static_assert(test()); return 0; -} \ No newline at end of file +} diff --git a/libcxx/test/std/ranges/range.adaptors/range.chunk/range.chunk.iter/increment.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.chunk/range.chunk.iter/increment.pass.cpp index 2e12b90344ea2..fee4b0d2dda04 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.chunk/range.chunk.iter/increment.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.chunk/range.chunk.iter/increment.pass.cpp @@ -6,7 +6,7 @@ // //===----------------------------------------------------------------------===// -// UNSUPPORTED: c++03, c++11, c++14, c++17 +// REQUIRES: std-at-least-c++23 // std::views::chunk @@ -43,4 +43,4 @@ int main(int, char**) { static_assert(test()); return 0; -} \ No newline at end of file +} diff --git a/libcxx/test/std/ranges/range.adaptors/range.chunk/types.h b/libcxx/test/std/ranges/range.adaptors/range.chunk/types.h index 09942d4212ef1..78d41a8ec3665 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.chunk/types.h +++ b/libcxx/test/std/ranges/range.adaptors/range.chunk/types.h @@ -67,4 +67,4 @@ not_sized_view(View) -> not_sized_view; template inline constexpr bool std::ranges::disable_sized_range> = true; -#endif \ No newline at end of file +#endif From b97b20c03b2f41538f34d804d4db38779e665058 Mon Sep 17 00:00:00 2001 From: anonymouspc Date: Tue, 9 Dec 2025 11:03:30 +0800 Subject: [PATCH 03/34] clang-format --- libcxx/include/__ranges/chunk_view.h | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/libcxx/include/__ranges/chunk_view.h b/libcxx/include/__ranges/chunk_view.h index 25fc018ba63f9..fd9733ecffcb6 100644 --- a/libcxx/include/__ranges/chunk_view.h +++ b/libcxx/include/__ranges/chunk_view.h @@ -513,9 +513,10 @@ namespace views { namespace __chunk { struct __fn { template - [[nodiscard]] _LIBCPP_HIDE_FROM_ABI static constexpr auto operator()(_Range&& __range, range_difference_t<_Range> __n) - noexcept(noexcept(/**/ chunk_view(std::forward<_Range>(__range), std::forward>(__n)))) - -> decltype(/*--*/ chunk_view(std::forward<_Range>(__range), std::forward>(__n))) { + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI static constexpr auto + operator()(_Range&& __range, range_difference_t<_Range> __n) noexcept( + noexcept(/**/ chunk_view(std::forward<_Range>(__range), std::forward>(__n)))) + -> decltype(/*--*/ chunk_view(std::forward<_Range>(__range), std::forward>(__n))) { return /*-------------*/ chunk_view(std::forward<_Range>(__range), std::forward>(__n)); } From 1b4367d2d1cb4ce534cbd500c008d5be83615e7d Mon Sep 17 00:00:00 2001 From: anonymouspc Date: Tue, 9 Dec 2025 11:59:57 +0800 Subject: [PATCH 04/34] add nodiscard attributes --- libcxx/include/__ranges/chunk_view.h | 107 ++++++++++-------- .../ranges/range.adaptors/range.chunk/types.h | 1 - 2 files changed, 61 insertions(+), 47 deletions(-) diff --git a/libcxx/include/__ranges/chunk_view.h b/libcxx/include/__ranges/chunk_view.h index fd9733ecffcb6..e0495b7e9f7ab 100644 --- a/libcxx/include/__ranges/chunk_view.h +++ b/libcxx/include/__ranges/chunk_view.h @@ -53,7 +53,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD namespace ranges { template -_LIBCPP_HIDE_FROM_ABI constexpr auto __div_ceil(_Integral __num, _Integral __denom) { +[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto __div_ceil(_Integral __num, _Integral __denom) { _Integral __r = __num / __denom; if (__num % __denom) ++__r; @@ -77,29 +77,31 @@ class chunk_view : public view_interface> { _LIBCPP_ASSERT_PEDANTIC(__n > 0, "Trying to construct a chunk_view with chunk size <= 0"); } - _LIBCPP_HIDE_FROM_ABI constexpr _View base() const& + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr _View base() const& requires std::copy_constructible<_View> { return __base_; } - _LIBCPP_HIDE_FROM_ABI constexpr _View base() && { return std::move(__base_); } + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr _View base() && { return std::move(__base_); } - _LIBCPP_HIDE_FROM_ABI constexpr __outer_iterator begin() { + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr __outer_iterator begin() { __current_.__emplace(ranges::begin(__base_)); __remainder_ = __n_; return __outer_iterator(*this); } - _LIBCPP_HIDE_FROM_ABI constexpr default_sentinel_t end() const noexcept { return std::default_sentinel; } + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr default_sentinel_t end() const noexcept { + return std::default_sentinel; + } - _LIBCPP_HIDE_FROM_ABI constexpr auto size() + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto size() requires sized_range<_View> { return std::__to_unsigned_like(ranges::__div_ceil(ranges::distance(__base_), __n_)); } - _LIBCPP_HIDE_FROM_ABI constexpr auto size() const + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto size() const requires sized_range { return std::__to_unsigned_like(ranges::__div_ceil(ranges::distance(__base_), __n_)); @@ -125,7 +127,7 @@ class chunk_view<_View>::__outer_iterator { _LIBCPP_HIDE_FROM_ABI __outer_iterator& operator=(__outer_iterator&&) = default; - _LIBCPP_HIDE_FROM_ABI constexpr value_type operator*() const { + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr value_type operator*() const { _LIBCPP_ASSERT_PEDANTIC(*this != default_sentinel, "Trying to dereference past-the-end chunk_view iterator."); return value_type(*__parent_); } @@ -142,7 +144,8 @@ class chunk_view<_View>::__outer_iterator { return *__i.__parent_->__current_ == ranges::end(__i.__parent_->__base_) && __i.__parent_->__remainder_ != 0; } - _LIBCPP_HIDE_FROM_ABI friend constexpr difference_type operator-(default_sentinel_t, const __outer_iterator& __i) + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI friend constexpr difference_type + operator-(default_sentinel_t, const __outer_iterator& __i) requires sized_sentinel_for, iterator_t<_View>> { const auto __dist = ranges::end(__i.__parent_->__base_) - *__i.__parent_->__current_; @@ -151,7 +154,8 @@ class chunk_view<_View>::__outer_iterator { return ranges::__div_ceil(__dist - __i.__parent_->__remainder_, __i.__parent_->__n_) + 1; } - _LIBCPP_HIDE_FROM_ABI friend constexpr difference_type operator-(const __outer_iterator& __i, default_sentinel_t __s) + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI friend constexpr difference_type + operator-(const __outer_iterator& __i, default_sentinel_t __s) requires sized_sentinel_for, iterator_t<_View>> { return -(__s - __i); @@ -168,11 +172,13 @@ class chunk_view<_View>::__outer_iterator::value_type : public view_interface, iterator_t<_View>> { return std::__to_unsigned_like( @@ -199,9 +205,9 @@ class chunk_view<_View>::__inner_iterator { _LIBCPP_HIDE_FROM_ABI __inner_iterator& operator=(__inner_iterator&&) = default; - _LIBCPP_HIDE_FROM_ABI constexpr const iterator_t<_View> base() const& { return *__parent_->__current_; } + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr const iterator_t<_View> base() const& { return *__parent_->__current_; } - _LIBCPP_HIDE_FROM_ABI constexpr range_reference_t<_View> operator*() const { + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr range_reference_t<_View> operator*() const { _LIBCPP_ASSERT_PEDANTIC(*this != default_sentinel, "Trying to dereference past-the-end chunk_view iterator"); return **__parent_->__current_; } @@ -217,23 +223,26 @@ class chunk_view<_View>::__inner_iterator { _LIBCPP_HIDE_FROM_ABI constexpr void operator++(int) { ++*this; } - _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator==(const __inner_iterator& __i, default_sentinel_t) { + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI friend constexpr bool + operator==(const __inner_iterator& __i, default_sentinel_t) { return __i.__parent_->__remainder_ == 0; } - _LIBCPP_HIDE_FROM_ABI friend constexpr difference_type operator-(default_sentinel_t, const __inner_iterator& __i) + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI friend constexpr difference_type + operator-(default_sentinel_t, const __inner_iterator& __i) requires sized_sentinel_for, iterator_t<_View>> { return ranges::min(__i.__parent_->__remainder_, ranges::end(__i.__parent_->__base_) - *__i.__parent_->__current_); } - _LIBCPP_HIDE_FROM_ABI friend constexpr difference_type operator-(const __inner_iterator& __i, default_sentinel_t __s) + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI friend constexpr difference_type + operator-(const __inner_iterator& __i, default_sentinel_t __s) requires sized_sentinel_for, iterator_t<_View>> { return -(__s - __i); } - _LIBCPP_HIDE_FROM_ABI friend constexpr auto + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI friend constexpr auto iter_move(const __inner_iterator& __i) noexcept(noexcept(ranges::iter_move(*__i.__parent_->__current_))) { return ranges::iter_move(*__i.__parent_->__current_); } @@ -262,27 +271,27 @@ class chunk_view<_View> : public view_interface> { _LIBCPP_ASSERT_PEDANTIC(__n > 0, "Trying to construct a chunk_view with chunk size <= 0"); } - _LIBCPP_HIDE_FROM_ABI constexpr _View base() const& + [[nodiscard]] _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_); } + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr _View base() && { return std::move(__base_); } - _LIBCPP_HIDE_FROM_ABI constexpr auto begin() + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto begin() requires(!__simple_view<_View>) { return __iterator(this, ranges::begin(__base_)); } - _LIBCPP_HIDE_FROM_ABI constexpr auto begin() const + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto begin() const requires forward_range { return __iterator(this, ranges::begin(__base_)); } - _LIBCPP_HIDE_FROM_ABI constexpr auto end() + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto end() requires(!__simple_view<_View>) { if constexpr (common_range<_View> && sized_range<_View>) { @@ -294,7 +303,7 @@ class chunk_view<_View> : public view_interface> { return default_sentinel; } - _LIBCPP_HIDE_FROM_ABI constexpr auto end() const + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto end() const requires forward_range { if constexpr (common_range && sized_range) { @@ -306,13 +315,13 @@ class chunk_view<_View> : public view_interface> { return default_sentinel; } - _LIBCPP_HIDE_FROM_ABI constexpr auto size() + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto size() requires sized_range<_View> { return std::__to_unsigned_like(ranges::__div_ceil(ranges::distance(__base_), __n_)); } - _LIBCPP_HIDE_FROM_ABI constexpr auto size() const + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto size() const requires sized_range { return std::__to_unsigned_like(ranges::__div_ceil(ranges::distance(__base_), __n_)); @@ -337,7 +346,7 @@ class chunk_view<_View>::__iterator { _Parent* __parent, iterator_t<_Base> __current, range_difference_t<_Base> __missing = 0) : __current_(__current), __end_(ranges::end(__parent->__base_)), __n_(__parent->__n_), __missing_(__missing) {} - static consteval auto __get_iterator_concept() { + [[nodiscard]] static consteval auto __get_iterator_concept() { if constexpr (random_access_range<_Base>) return random_access_iterator_tag{}; else if constexpr (bidirectional_range<_Base>) @@ -362,14 +371,14 @@ class chunk_view<_View>::__iterator { __n_(__i.__n_), __missing_(__i.__missing_) {} - _LIBCPP_HIDE_FROM_ABI constexpr iterator_t<_Base> base() const { return __current_; } + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr iterator_t<_Base> base() const { return __current_; } - _LIBCPP_HIDE_FROM_ABI constexpr value_type operator*() const { + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr value_type operator*() const { _LIBCPP_ASSERT_PEDANTIC(__current_ != __end_, "Trying to dereference past-the-end chunk_view iterator"); return views::take(subrange(__current_, __end_), __n_); } - _LIBCPP_HIDE_FROM_ABI constexpr value_type operator[](difference_type __pos) const + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr value_type operator[](difference_type __pos) const requires random_access_range<_Base> { return *(*this + __pos); @@ -422,45 +431,46 @@ class chunk_view<_View>::__iterator { return *this += -__x; } - _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator==(const __iterator& __x, const __iterator& __y) { + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator==(const __iterator& __x, const __iterator& __y) { return __x.__current_ == __y.__current_; } - _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator==(const __iterator& __x, default_sentinel_t) { + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator==(const __iterator& __x, default_sentinel_t) { return __x.__current_ == __x.__end_; } - _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator<(const __iterator& __x, const __iterator& __y) + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator<(const __iterator& __x, const __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) + [[nodiscard]] _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) + [[nodiscard]] _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) + [[nodiscard]] _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) + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI friend constexpr auto operator<=>(const __iterator& __x, const __iterator& __y) requires random_access_range<_Base> && three_way_comparable> { return __x.__current_ <=> __y.__current_; } - _LIBCPP_HIDE_FROM_ABI friend constexpr __iterator operator+(const __iterator& __i, difference_type __pos) + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI friend constexpr __iterator + operator+(const __iterator& __i, difference_type __pos) requires random_access_range<_Base> { auto __r = __i; @@ -468,7 +478,8 @@ class chunk_view<_View>::__iterator { return __r; } - _LIBCPP_HIDE_FROM_ABI friend constexpr __iterator operator+(difference_type __pos, const __iterator& __i) + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI friend constexpr __iterator + operator+(difference_type __pos, const __iterator& __i) requires random_access_range<_Base> { auto __r = __i; @@ -476,7 +487,8 @@ class chunk_view<_View>::__iterator { return __r; } - _LIBCPP_HIDE_FROM_ABI friend constexpr __iterator operator-(const __iterator& __i, difference_type __pos) + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI friend constexpr __iterator + operator-(const __iterator& __i, difference_type __pos) requires random_access_range<_Base> { auto __r = __i; @@ -484,19 +496,22 @@ class chunk_view<_View>::__iterator { return __r; } - _LIBCPP_HIDE_FROM_ABI friend constexpr difference_type operator-(const __iterator& __i, const __iterator& __j) + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI friend constexpr difference_type + operator-(const __iterator& __i, const __iterator& __j) requires sized_sentinel_for, iterator_t<_Base>> { return (__i.__current_ - __j.__current_ + __i.__missing_ - __j.__missing_) / __i.__n_; } - _LIBCPP_HIDE_FROM_ABI friend constexpr difference_type operator-(default_sentinel_t, const __iterator& __i) + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI friend constexpr difference_type + operator-(default_sentinel_t, const __iterator& __i) requires sized_sentinel_for, iterator_t<_Base>> { return ranges::__div_ceil(__i.__end_ - __i.__current_, __i.__n_); } - _LIBCPP_HIDE_FROM_ABI friend constexpr difference_type operator-(const __iterator& __i, default_sentinel_t __s) + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI friend constexpr difference_type + operator-(const __iterator& __i, default_sentinel_t __s) requires sized_sentinel_for, iterator_t<_Base>> { return -(__s - __i); @@ -515,9 +530,9 @@ struct __fn { template [[nodiscard]] _LIBCPP_HIDE_FROM_ABI static constexpr auto operator()(_Range&& __range, range_difference_t<_Range> __n) noexcept( - noexcept(/**/ chunk_view(std::forward<_Range>(__range), std::forward>(__n)))) + noexcept(/*-----*/ chunk_view(std::forward<_Range>(__range), std::forward>(__n)))) -> decltype(/*--*/ chunk_view(std::forward<_Range>(__range), std::forward>(__n))) { - return /*-------------*/ chunk_view(std::forward<_Range>(__range), std::forward>(__n)); + return /*---------*/ chunk_view(std::forward<_Range>(__range), std::forward>(__n)); } template diff --git a/libcxx/test/std/ranges/range.adaptors/range.chunk/types.h b/libcxx/test/std/ranges/range.adaptors/range.chunk/types.h index 78d41a8ec3665..5c6f3ef21ddb8 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.chunk/types.h +++ b/libcxx/test/std/ranges/range.adaptors/range.chunk/types.h @@ -9,7 +9,6 @@ #ifndef TEST_STD_RANGES_RANGE_ADAPTORS_RANGE_CHUNK_TYPES_H #define TEST_STD_RANGES_RANGE_ADAPTORS_RANGE_CHUNK_TYPES_H -#include #include #include From 2f19c922db4b43f2b77c3950b8f17e84c7d07bd7 Mon Sep 17 00:00:00 2001 From: anonymouspc Date: Tue, 9 Dec 2025 12:01:09 +0800 Subject: [PATCH 05/34] nodiscard tests --- .../deref.nodiscard.verify.cpp | 26 +++++++++++++++ .../eq.nodiscard.verify.cpp | 28 ++++++++++++++++ .../iter_move.nodiscard.verify.cpp | 26 +++++++++++++++ .../adaptor.nodiscard.verify.cpp | 31 +++++++++++++++++ .../eq.nodiscard.verify.cpp | 33 +++++++++++++++++++ .../base.nodiscard.verify.cpp | 28 ++++++++++++++++ .../begin.nodiscard.verify.cpp | 26 +++++++++++++++ .../range.chunk.view/end.nodiscard.verify.cpp | 26 +++++++++++++++ 8 files changed, 224 insertions(+) create mode 100644 libcxx/test/libcxx/ranges/range.adaptors/range.chunk/range.chunk.iterator/deref.nodiscard.verify.cpp create mode 100644 libcxx/test/libcxx/ranges/range.adaptors/range.chunk/range.chunk.iterator/eq.nodiscard.verify.cpp create mode 100644 libcxx/test/libcxx/ranges/range.adaptors/range.chunk/range.chunk.iterator/iter_move.nodiscard.verify.cpp create mode 100644 libcxx/test/libcxx/ranges/range.adaptors/range.chunk/range.chunk.overview/adaptor.nodiscard.verify.cpp create mode 100644 libcxx/test/libcxx/ranges/range.adaptors/range.chunk/range.chunk.sentinel/eq.nodiscard.verify.cpp create mode 100644 libcxx/test/libcxx/ranges/range.adaptors/range.chunk/range.chunk.view/base.nodiscard.verify.cpp create mode 100644 libcxx/test/libcxx/ranges/range.adaptors/range.chunk/range.chunk.view/begin.nodiscard.verify.cpp create mode 100644 libcxx/test/libcxx/ranges/range.adaptors/range.chunk/range.chunk.view/end.nodiscard.verify.cpp diff --git a/libcxx/test/libcxx/ranges/range.adaptors/range.chunk/range.chunk.iterator/deref.nodiscard.verify.cpp b/libcxx/test/libcxx/ranges/range.adaptors/range.chunk/range.chunk.iterator/deref.nodiscard.verify.cpp new file mode 100644 index 0000000000000..f62c42e5259dd --- /dev/null +++ b/libcxx/test/libcxx/ranges/range.adaptors/range.chunk/range.chunk.iterator/deref.nodiscard.verify.cpp @@ -0,0 +1,26 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// REQUIRES: std-at-least-c++23 + +// + +// Test the libc++ extension that std::ranges::chunk_view::iterator::operator* is marked as [[nodiscard]]. + +#include +#include + +void test() { + char range[6] = {'x', 'x', 'y', 'y', 'z', 'z'}; + auto view = range | std::views::chunk(2); + + // clang-format off + *view.begin(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + *std::as_const(view).begin(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + // clang-format on +} diff --git a/libcxx/test/libcxx/ranges/range.adaptors/range.chunk/range.chunk.iterator/eq.nodiscard.verify.cpp b/libcxx/test/libcxx/ranges/range.adaptors/range.chunk/range.chunk.iterator/eq.nodiscard.verify.cpp new file mode 100644 index 0000000000000..fdcf17a0c8155 --- /dev/null +++ b/libcxx/test/libcxx/ranges/range.adaptors/range.chunk/range.chunk.iterator/eq.nodiscard.verify.cpp @@ -0,0 +1,28 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// REQUIRES: std-at-least-c++23 + +// + +// Test the libc++ extension that std::ranges::chunk_view::iterator::operator== is marked as [[nodiscard]]. + +#include +#include + +void test() { + char16_t range[3] = {u'x', u'y', u'z'}; + auto view = range | std::views::chunk(3); + + // clang-format off + (view.begin() == view.end()); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + (std::as_const(view).begin() == view.end()); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + (view.begin() == std::as_const(view).end()); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + (std::as_const(view).begin() == std::as_const(view).end()); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + // clang-format on +} diff --git a/libcxx/test/libcxx/ranges/range.adaptors/range.chunk/range.chunk.iterator/iter_move.nodiscard.verify.cpp b/libcxx/test/libcxx/ranges/range.adaptors/range.chunk/range.chunk.iterator/iter_move.nodiscard.verify.cpp new file mode 100644 index 0000000000000..f5e26938094fd --- /dev/null +++ b/libcxx/test/libcxx/ranges/range.adaptors/range.chunk/range.chunk.iterator/iter_move.nodiscard.verify.cpp @@ -0,0 +1,26 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// REQUIRES: std-at-least-c++23 + +// + +// Test the libc++ extension that std::ranges::chunk::iterator::iter_move is marked as [[nodiscard]]. + +#include +#include + +void test() { + long range[2] = {0L, 2L}; + auto view = range | std::views::chunk(1); + + // clang-format off + std::ranges::iter_move(view.begin()); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + std::ranges::iter_move(std::as_const(view).begin()); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + // clang-format on +} diff --git a/libcxx/test/libcxx/ranges/range.adaptors/range.chunk/range.chunk.overview/adaptor.nodiscard.verify.cpp b/libcxx/test/libcxx/ranges/range.adaptors/range.chunk/range.chunk.overview/adaptor.nodiscard.verify.cpp new file mode 100644 index 0000000000000..0bf8e2f99633e --- /dev/null +++ b/libcxx/test/libcxx/ranges/range.adaptors/range.chunk/range.chunk.overview/adaptor.nodiscard.verify.cpp @@ -0,0 +1,31 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// REQUIRES: std-at-least-c++23 + +// + +// Test the libc++ extension that std::views::chunk is marked as [[nodiscard]]. + +#include + +void test() { + int range[9] = {1, 2, 3, 4, 5, 6, 7, 8, 9}; + + // clang-format off + std::views::chunk(3); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + std::views::chunk(range, 3); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + range | std::views::chunk(3); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + std::views::reverse | std::views::chunk(3); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + + std::views::chunk(3); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + std::views::chunk(range, 3); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + range | std::views::chunk(3); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + std::views::reverse | std::views::chunk(3); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + // clang-format on +} diff --git a/libcxx/test/libcxx/ranges/range.adaptors/range.chunk/range.chunk.sentinel/eq.nodiscard.verify.cpp b/libcxx/test/libcxx/ranges/range.adaptors/range.chunk/range.chunk.sentinel/eq.nodiscard.verify.cpp new file mode 100644 index 0000000000000..41e2072640641 --- /dev/null +++ b/libcxx/test/libcxx/ranges/range.adaptors/range.chunk/range.chunk.sentinel/eq.nodiscard.verify.cpp @@ -0,0 +1,33 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// REQUIRES: std-at-least-c++23 + +// + +// Test the libc++ extension that std::ranges::chunk_view::sentinel::operator== is marked as [[nodiscard]]. + +#include +#include +#include + +#include "test_iterators.h" +#include "test_range.h" + +void test() { + int range[6] = {1, 3, 4, 6, 7, 9}; + + std::ranges::chunk_view view(range, 2); + + // clang-format off + (view.begin() == view.end()); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + (std::as_const(view).begin() == view.end()); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + (view.begin() == std::as_const(view).end()); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + (std::as_const(view).begin() == std::as_const(view).end()); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + // clang-format on +} diff --git a/libcxx/test/libcxx/ranges/range.adaptors/range.chunk/range.chunk.view/base.nodiscard.verify.cpp b/libcxx/test/libcxx/ranges/range.adaptors/range.chunk/range.chunk.view/base.nodiscard.verify.cpp new file mode 100644 index 0000000000000..9f2d946d173f2 --- /dev/null +++ b/libcxx/test/libcxx/ranges/range.adaptors/range.chunk/range.chunk.view/base.nodiscard.verify.cpp @@ -0,0 +1,28 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// REQUIRES: std-at-least-c++23 + +// + +// Test the libc++ extension that std::ranges:chunk_view::base is marked as [[nodiscard]]. + +#include +#include + +void test() { + int range[9] = {1, 2, 3, 4, 5, 6, 7, 8, 9}; + auto view = range | std::views::chunk(3); + + // clang-format off + view.base(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + std::as_const(view).base(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + std::move(std::as_const(view)).base(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + std::move(view).base(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + // clang-format on +} diff --git a/libcxx/test/libcxx/ranges/range.adaptors/range.chunk/range.chunk.view/begin.nodiscard.verify.cpp b/libcxx/test/libcxx/ranges/range.adaptors/range.chunk/range.chunk.view/begin.nodiscard.verify.cpp new file mode 100644 index 0000000000000..ba9520dff23a3 --- /dev/null +++ b/libcxx/test/libcxx/ranges/range.adaptors/range.chunk/range.chunk.view/begin.nodiscard.verify.cpp @@ -0,0 +1,26 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// REQUIRES: std-at-least-c++23 + +// + +// Test the libc++ extension that std::ranges::chunk_view::begin is marked as [[nodiscard]]. + +#include +#include + +void test() { + int range[6] = {1, 3, 4, 6, 7, 9}; + auto view = range | std::views::chunk(3); + + // clang-format off + view.begin(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + std::as_const(view).begin(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + // clang-format on +} diff --git a/libcxx/test/libcxx/ranges/range.adaptors/range.chunk/range.chunk.view/end.nodiscard.verify.cpp b/libcxx/test/libcxx/ranges/range.adaptors/range.chunk/range.chunk.view/end.nodiscard.verify.cpp new file mode 100644 index 0000000000000..124fe707ac41e --- /dev/null +++ b/libcxx/test/libcxx/ranges/range.adaptors/range.chunk/range.chunk.view/end.nodiscard.verify.cpp @@ -0,0 +1,26 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// REQUIRES: std-at-least-c++23 + +// + +// Test the libc++ extension that std::ranges::chunk_view::end is marked as [[nodiscard]]. + +#include +#include + +void test() { + int range[6] = {1, 2, 4, 5, 7, 8}; + auto view = range | std::views::chunk(3); + + // clang-format off + view.end(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + td::as_const(view).end(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + // clang-format on +} From 09f85db75b0d1113efbf75c8d9b7e0376ba60ecc Mon Sep 17 00:00:00 2001 From: anonymouspc Date: Tue, 9 Dec 2025 12:01:17 +0800 Subject: [PATCH 06/34] no_unique_address tests --- .../no_unique_address.compile.pass.cpp | 55 +++++++++++++++++++ 1 file changed, 55 insertions(+) create mode 100644 libcxx/test/libcxx/ranges/range.adaptors/range.chunk/range.chunk.view/no_unique_address.compile.pass.cpp diff --git a/libcxx/test/libcxx/ranges/range.adaptors/range.chunk/range.chunk.view/no_unique_address.compile.pass.cpp b/libcxx/test/libcxx/ranges/range.adaptors/range.chunk/range.chunk.view/no_unique_address.compile.pass.cpp new file mode 100644 index 0000000000000..2b7e8effcc59e --- /dev/null +++ b/libcxx/test/libcxx/ranges/range.adaptors/range.chunk/range.chunk.view/no_unique_address.compile.pass.cpp @@ -0,0 +1,55 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// REQUIRES: std-at-least-c++23 + +// XFAIL: msvc + +// + +// This test ensures that we use `[[no_unique_address]]` in `chunk_view`. + +#include +#include +#include +#include +#include + +#include "test_iterators.h" +#include "test_range.h" + +using input_view = std::views::all_t>; +static_assert(std::ranges::input_range && !std::ranges::forward_range); + +struct forward_view : std::ranges::view_base { + std::string* begin() const; + std::string* end() const; +}; +static_assert(std::ranges::forward_range); +static_assert(std::is_reference_v>); + +template +struct Test { + [[no_unique_address]] View view; + unsigned char pad; +}; + +using CV1 = std::ranges::chunk_view; +// Expected CV1 (with View == input) layout: +// [[no_unique_address]] _View __base_ // offset: 0 +// [[no_unique_address]] range_difference_t<_View> __n_ // offset: sizeof(std::ptrdiff_t) +// [[no_unique_address]] range_difference_t<_View> __remainder_ // offset: sizeof(std::ptrdiff_t) +// [[no_unique_address]] __non_propagating_cache> __current_ // offset: ? +// TODO: how to test this ? + +using CV2 = std::ranges::chunk_view; +// Expected CV2 (with View >= forward) layout: +// [[no_unique_address]] _View __base_ // offset: 0 +// [[no_unique_address]] range_difference_t<_View> // offset: sizeof(std::ptrdiff_t) +static_assert(sizeof(CV2) == sizeof(std::ptrdiff_t)); +static_assert(sizeof(Test) == sizeof(std::ptrdiff_t) * 2); From a33c1be53aa771927656e4ed625d8c0ba83563ae Mon Sep 17 00:00:00 2001 From: anonymouspc Date: Tue, 9 Dec 2025 12:01:54 +0800 Subject: [PATCH 07/34] clang-format --- .../range.chunk.iterator/deref.nodiscard.verify.cpp | 2 +- .../range.chunk/range.chunk.iterator/eq.nodiscard.verify.cpp | 2 +- .../range.chunk.iterator/iter_move.nodiscard.verify.cpp | 4 ++-- .../range.chunk/range.chunk.view/base.nodiscard.verify.cpp | 2 +- .../range.chunk/range.chunk.view/begin.nodiscard.verify.cpp | 2 +- .../range.chunk/range.chunk.view/end.nodiscard.verify.cpp | 2 +- 6 files changed, 7 insertions(+), 7 deletions(-) diff --git a/libcxx/test/libcxx/ranges/range.adaptors/range.chunk/range.chunk.iterator/deref.nodiscard.verify.cpp b/libcxx/test/libcxx/ranges/range.adaptors/range.chunk/range.chunk.iterator/deref.nodiscard.verify.cpp index f62c42e5259dd..d3722f961234c 100644 --- a/libcxx/test/libcxx/ranges/range.adaptors/range.chunk/range.chunk.iterator/deref.nodiscard.verify.cpp +++ b/libcxx/test/libcxx/ranges/range.adaptors/range.chunk/range.chunk.iterator/deref.nodiscard.verify.cpp @@ -17,7 +17,7 @@ void test() { char range[6] = {'x', 'x', 'y', 'y', 'z', 'z'}; - auto view = range | std::views::chunk(2); + auto view = range | std::views::chunk(2); // clang-format off *view.begin(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} diff --git a/libcxx/test/libcxx/ranges/range.adaptors/range.chunk/range.chunk.iterator/eq.nodiscard.verify.cpp b/libcxx/test/libcxx/ranges/range.adaptors/range.chunk/range.chunk.iterator/eq.nodiscard.verify.cpp index fdcf17a0c8155..d743d1e7c40d3 100644 --- a/libcxx/test/libcxx/ranges/range.adaptors/range.chunk/range.chunk.iterator/eq.nodiscard.verify.cpp +++ b/libcxx/test/libcxx/ranges/range.adaptors/range.chunk/range.chunk.iterator/eq.nodiscard.verify.cpp @@ -17,7 +17,7 @@ void test() { char16_t range[3] = {u'x', u'y', u'z'}; - auto view = range | std::views::chunk(3); + auto view = range | std::views::chunk(3); // clang-format off (view.begin() == view.end()); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} diff --git a/libcxx/test/libcxx/ranges/range.adaptors/range.chunk/range.chunk.iterator/iter_move.nodiscard.verify.cpp b/libcxx/test/libcxx/ranges/range.adaptors/range.chunk/range.chunk.iterator/iter_move.nodiscard.verify.cpp index f5e26938094fd..b1f13ae6ee14f 100644 --- a/libcxx/test/libcxx/ranges/range.adaptors/range.chunk/range.chunk.iterator/iter_move.nodiscard.verify.cpp +++ b/libcxx/test/libcxx/ranges/range.adaptors/range.chunk/range.chunk.iterator/iter_move.nodiscard.verify.cpp @@ -17,8 +17,8 @@ void test() { long range[2] = {0L, 2L}; - auto view = range | std::views::chunk(1); - + auto view = range | std::views::chunk(1); + // clang-format off std::ranges::iter_move(view.begin()); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} std::ranges::iter_move(std::as_const(view).begin()); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} diff --git a/libcxx/test/libcxx/ranges/range.adaptors/range.chunk/range.chunk.view/base.nodiscard.verify.cpp b/libcxx/test/libcxx/ranges/range.adaptors/range.chunk/range.chunk.view/base.nodiscard.verify.cpp index 9f2d946d173f2..ecd0d92aa861e 100644 --- a/libcxx/test/libcxx/ranges/range.adaptors/range.chunk/range.chunk.view/base.nodiscard.verify.cpp +++ b/libcxx/test/libcxx/ranges/range.adaptors/range.chunk/range.chunk.view/base.nodiscard.verify.cpp @@ -17,7 +17,7 @@ void test() { int range[9] = {1, 2, 3, 4, 5, 6, 7, 8, 9}; - auto view = range | std::views::chunk(3); + auto view = range | std::views::chunk(3); // clang-format off view.base(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} diff --git a/libcxx/test/libcxx/ranges/range.adaptors/range.chunk/range.chunk.view/begin.nodiscard.verify.cpp b/libcxx/test/libcxx/ranges/range.adaptors/range.chunk/range.chunk.view/begin.nodiscard.verify.cpp index ba9520dff23a3..02e7fc8a2686c 100644 --- a/libcxx/test/libcxx/ranges/range.adaptors/range.chunk/range.chunk.view/begin.nodiscard.verify.cpp +++ b/libcxx/test/libcxx/ranges/range.adaptors/range.chunk/range.chunk.view/begin.nodiscard.verify.cpp @@ -17,7 +17,7 @@ void test() { int range[6] = {1, 3, 4, 6, 7, 9}; - auto view = range | std::views::chunk(3); + auto view = range | std::views::chunk(3); // clang-format off view.begin(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} diff --git a/libcxx/test/libcxx/ranges/range.adaptors/range.chunk/range.chunk.view/end.nodiscard.verify.cpp b/libcxx/test/libcxx/ranges/range.adaptors/range.chunk/range.chunk.view/end.nodiscard.verify.cpp index 124fe707ac41e..dd011bb47770a 100644 --- a/libcxx/test/libcxx/ranges/range.adaptors/range.chunk/range.chunk.view/end.nodiscard.verify.cpp +++ b/libcxx/test/libcxx/ranges/range.adaptors/range.chunk/range.chunk.view/end.nodiscard.verify.cpp @@ -17,7 +17,7 @@ void test() { int range[6] = {1, 2, 4, 5, 7, 8}; - auto view = range | std::views::chunk(3); + auto view = range | std::views::chunk(3); // clang-format off view.end(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} From 5704a7ba02aa8ab78219b6529e03c588a4aadc08 Mon Sep 17 00:00:00 2001 From: anonymouspc Date: Tue, 9 Dec 2025 12:09:32 +0800 Subject: [PATCH 08/34] list is not constexpr until C++26, thus not testable in C++23 --- .../range.chunk.view/end.nodiscard.verify.cpp | 2 +- .../range.adaptors/range.chunk/begin.pass.cpp | 26 +++++++++--------- .../range.adaptors/range.chunk/end.pass.cpp | 27 ++++++++----------- 3 files changed, 25 insertions(+), 30 deletions(-) diff --git a/libcxx/test/libcxx/ranges/range.adaptors/range.chunk/range.chunk.view/end.nodiscard.verify.cpp b/libcxx/test/libcxx/ranges/range.adaptors/range.chunk/range.chunk.view/end.nodiscard.verify.cpp index dd011bb47770a..ba3c75376c526 100644 --- a/libcxx/test/libcxx/ranges/range.adaptors/range.chunk/range.chunk.view/end.nodiscard.verify.cpp +++ b/libcxx/test/libcxx/ranges/range.adaptors/range.chunk/range.chunk.view/end.nodiscard.verify.cpp @@ -21,6 +21,6 @@ void test() { // clang-format off view.end(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} - td::as_const(view).end(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + std::as_const(view).end(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} // clang-format on } diff --git a/libcxx/test/std/ranges/range.adaptors/range.chunk/begin.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.chunk/begin.pass.cpp index 5a55d1e343139..c90c1543dd43f 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.chunk/begin.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.chunk/begin.pass.cpp @@ -14,41 +14,41 @@ #include #include -#include +#include #include "test_range.h" constexpr bool test() { - std::list full_list = {1, 1, 1, 2, 2, 2, 3, 3}; - std::list empty_list = {}; + std::vector full_vector = {1, 1, 1, 2, 2, 2, 3, 3}; + std::vector empty_vector = {}; // Test `chunk_view.begin()` { - auto view = full_list | std::views::chunk(3); + auto view = full_vector | std::views::chunk(3); auto it = view.begin(); - assert(std::ranges::equal(*it, std::list{1, 1, 1})); - assert(std::ranges::equal(*++it, std::list{2, 2, 2})); - assert(std::ranges::equal(*++it, std::list{3, 3})); // The last chunk has only 2 elements. + assert(std::ranges::equal(*it, std::vector{1, 1, 1})); + assert(std::ranges::equal(*++it, std::vector{2, 2, 2})); + assert(std::ranges::equal(*++it, std::vector{3, 3})); // The last chunk has only 2 elements. assert(++it == view.end()); // Reaches end. - view = full_list | std::views::chunk(5); + view = full_vector | std::views::chunk(5); it = view.begin(); - assert(std::ranges::equal(*it, std::list{1, 1, 1, 2, 2})); - assert(std::ranges::equal(*++it, std::list{2, 3, 3})); + assert(std::ranges::equal(*it, std::vector{1, 1, 1, 2, 2})); + assert(std::ranges::equal(*++it, std::vector{2, 3, 3})); } // Test `empty_chunk_view.begin()` { - auto view = empty_list | std::views::chunk(3); + auto view = empty_vector | std::views::chunk(3); assert(view.size() == 0); assert(view.begin() == view.end()); } // Test `small_view_with_big_chunk.begin()` { - auto view = full_list | std::views::chunk(314159); + auto view = full_vector | std::views::chunk(314159); assert(view.size() == 1); - assert(std::ranges::equal(*view.begin(), full_list)); + assert(std::ranges::equal(*view.begin(), full_vector)); assert(++view.begin() == view.end()); } diff --git a/libcxx/test/std/ranges/range.adaptors/range.chunk/end.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.chunk/end.pass.cpp index ccd136ab193a0..affb5074e3885 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.chunk/end.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.chunk/end.pass.cpp @@ -15,41 +15,36 @@ #include #include #include -#include -#include +#include #include "test_range.h" #include "types.h" constexpr bool test() { - std::list list = {1, 1, 1, 2, 2, 2, 3, 3}; - std::forward_list forward_list = {1, 1, 1, 2, 2, 2, 3, 3}; + std::vector vector = {1, 1, 1, 2, 2, 2, 3, 3}; // Test `chunk_view.end()` { - auto view = list | std::views::chunk(3); + auto view = vector | std::views::chunk(3); auto it = view.end(); - assert(std::ranges::equal(*--it, std::list{3, 3})); // We can adjust the tailing chunk-size. - assert(std::ranges::equal(*--it, std::list{2, 2, 2})); - assert(std::ranges::equal(*--it, std::list{1, 1, 1})); + assert(std::ranges::equal(*--it, std::vector{3, 3})); // We can adjust the tailing chunk-size. + assert(std::ranges::equal(*--it, std::vector{2, 2, 2})); + assert(std::ranges::equal(*--it, std::vector{1, 1, 1})); } // Test `not_sized_chunk_view.end()` { - auto not_sized_list = not_sized_view(list | std::views::all); - auto view = not_sized_list | std::views::chunk(4); + auto not_sized_vector = not_sized_view(vector | std::views::all); + auto view = not_sized_vector | std::views::chunk(4); static_assert(std::ranges::bidirectional_range); static_assert(!std::ranges::sized_range); - static_assert( - std::same_as< - decltype(view.end()), - std:: - default_sentinel_t>); // We cannot handle the tailing chunk without size info, so we forbids one to derement from end(). + // We cannot handle the tailing chunk without size info, so we forbids one to derement from end(). + static_assert(std::same_as< decltype(view.end()), std::default_sentinel_t>); } // Test `forward_chunk_view.end()` { - auto view = list | std::views::chunk(5); + auto view = vector | std::views::chunk(5); assert(++(++view.begin()) == view.end()); } From 0bce4e1925d2ecb6f26d149641a107e597256f8e Mon Sep 17 00:00:00 2001 From: anonymouspc Date: Tue, 9 Dec 2025 12:11:45 +0800 Subject: [PATCH 09/34] clang-format --- .../test/std/ranges/range.adaptors/range.chunk/begin.pass.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libcxx/test/std/ranges/range.adaptors/range.chunk/begin.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.chunk/begin.pass.cpp index c90c1543dd43f..5c8951f3bb10e 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.chunk/begin.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.chunk/begin.pass.cpp @@ -29,7 +29,7 @@ constexpr bool test() { assert(std::ranges::equal(*it, std::vector{1, 1, 1})); assert(std::ranges::equal(*++it, std::vector{2, 2, 2})); assert(std::ranges::equal(*++it, std::vector{3, 3})); // The last chunk has only 2 elements. - assert(++it == view.end()); // Reaches end. + assert(++it == view.end()); // Reaches end. view = full_vector | std::views::chunk(5); it = view.begin(); From 202a86cd4ad8d01205c6c33c52579dfe64bd81de Mon Sep 17 00:00:00 2001 From: anonymous Date: Tue, 9 Dec 2025 12:35:08 +0800 Subject: [PATCH 10/34] Apply suggestion from @H-G-Hristov Co-authored-by: Hristo Hristov --- .../range.adaptors/range.chunk/ctad.compile.pass.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/libcxx/test/std/ranges/range.adaptors/range.chunk/ctad.compile.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.chunk/ctad.compile.pass.cpp index ed04cd57555ff..862accc4063b1 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.chunk/ctad.compile.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.chunk/ctad.compile.pass.cpp @@ -39,10 +39,10 @@ void testCTAD() { static_assert(std::same_as< decltype(std::ranges::chunk_view(std::move(v), 0)), std::ranges::chunk_view >); static_assert( std::same_as< decltype(std::ranges::chunk_view(r, 0)), std::ranges::chunk_view> >); - static_assert(std::same_as< decltype(std::ranges::chunk_view(std::move(r), 0)), - std::ranges::chunk_view> >); - static_assert(std::same_as< decltype(std::ranges::chunk_view(br, 0)), - std::ranges::chunk_view> >); - static_assert(std::same_as< decltype(std::ranges::chunk_view(std::move(br), 0)), - std::ranges::chunk_view> >); + static_assert(std::same_as>>); + static_assert(std::same_as>>); + static_assert(std::same_as>>); } From 99d53843d60f3a66a7fbd3bf2ac42c3a3ce79612 Mon Sep 17 00:00:00 2001 From: anonymouspc Date: Tue, 9 Dec 2025 12:54:18 +0800 Subject: [PATCH 11/34] revert BUILD.gn --- llvm/utils/gn/secondary/libcxx/include/BUILD.gn | 1 - 1 file changed, 1 deletion(-) diff --git a/llvm/utils/gn/secondary/libcxx/include/BUILD.gn b/llvm/utils/gn/secondary/libcxx/include/BUILD.gn index 16be8fa8de795..9755fe3a7ea50 100644 --- a/llvm/utils/gn/secondary/libcxx/include/BUILD.gn +++ b/llvm/utils/gn/secondary/libcxx/include/BUILD.gn @@ -1352,7 +1352,6 @@ if (current_toolchain == default_toolchain) { "__ranges/all.h", "__ranges/as_rvalue_view.h", "__ranges/chunk_by_view.h", - "__ranges/chunk_view.h", "__ranges/common_view.h", "__ranges/concepts.h", "__ranges/container_compatible_range.h", From 26cd668e7af68a03c29c3caaf457a739f03aca9d Mon Sep 17 00:00:00 2001 From: anonymous Date: Tue, 9 Dec 2025 12:58:27 +0800 Subject: [PATCH 12/34] Apply suggestion from @H-G-Hristov Co-authored-by: Hristo Hristov --- .../range.chunk.iter/compare.pass.cpp | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/libcxx/test/std/ranges/range.adaptors/range.chunk/range.chunk.iter/compare.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.chunk/range.chunk.iter/compare.pass.cpp index 0d335914b71c2..63bfed60e5574 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.chunk/range.chunk.iter/compare.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.chunk/range.chunk.iter/compare.pass.cpp @@ -8,12 +8,23 @@ // REQUIRES: std-at-least-c++23 -// std::views::chunk - -#include +// + +// friend constexpr bool operator<(const iterator& x, const iterator& y) +// requires [random_access_range](https://eel.is/c++draft/range.refinements#concept:random_access_range); +// friend constexpr bool operator>(const iterator& x, const iterator& y) +// requires [random_access_range](https://eel.is/c++draft/range.refinements#concept:random_access_range); +// friend constexpr bool operator<=(const iterator& x, const iterator& y) +// requires [random_access_range](https://eel.is/c++draft/range.refinements#concept:random_access_range); +// friend constexpr bool operator>=(const iterator& x, const iterator& y) +// requires [random_access_range](https://eel.is/c++draft/range.refinements#concept:random_access_range); +// friend constexpr auto operator<=>(const iterator& x, const iterator& y) +// requires [random_access_range](https://eel.is/c++draft/range.refinements#concept:random_access_range) && + // [three_way_comparable](https://eel.is/c++draft/cmp.concept#concept:three_way_comparable)>; #include #include +#include #include #include "test_range.h" From 70b8d1394579d556aac3ec4f7ff09b936de64dd5 Mon Sep 17 00:00:00 2001 From: anonymous Date: Tue, 9 Dec 2025 12:58:52 +0800 Subject: [PATCH 13/34] Apply suggestion from @H-G-Hristov Co-authored-by: Hristo Hristov --- .../std/ranges/range.adaptors/range.chunk/adaptor.pass.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/libcxx/test/std/ranges/range.adaptors/range.chunk/adaptor.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.chunk/adaptor.pass.cpp index d37d2a25c5298..f85ca3c47c661 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.chunk/adaptor.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.chunk/adaptor.pass.cpp @@ -27,8 +27,7 @@ constexpr bool test() { // Test `views::chunk(view, n)` { - auto chunked = std::views::chunk(span, 2); - static_assert(std::same_as>>); + std::same_as>>> decltype(auto) chunked = std::views::chunk(span, 2); assert(std::ranges::equal(*chunked.begin(), std::array{1, 1})); } From ff2fa8e3752afb6a86d2b417d42af2ee72d8e80c Mon Sep 17 00:00:00 2001 From: anonymouspc Date: Tue, 9 Dec 2025 14:07:22 +0800 Subject: [PATCH 14/34] make views::chunk(n) to be static operator() <- **needs to be tested** --- libcxx/include/__ranges/chunk_view.h | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/libcxx/include/__ranges/chunk_view.h b/libcxx/include/__ranges/chunk_view.h index e0495b7e9f7ab..bc8ff5bb5ce59 100644 --- a/libcxx/include/__ranges/chunk_view.h +++ b/libcxx/include/__ranges/chunk_view.h @@ -140,7 +140,7 @@ class chunk_view<_View>::__outer_iterator { _LIBCPP_HIDE_FROM_ABI constexpr void operator++(int) { ++*this; } - _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator==(const __outer_iterator& __i, default_sentinel_t) { + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator==(const __outer_iterator& __i, default_sentinel_t) { return *__i.__parent_->__current_ == ranges::end(__i.__parent_->__base_) && __i.__parent_->__remainder_ != 0; } @@ -536,9 +536,9 @@ struct __fn { } template - [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_DifferenceType __n) const + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI static constexpr auto operator()(_DifferenceType __n) noexcept(is_nothrow_constructible_v, _DifferenceType>) { - return __pipeable(std::__bind_back(*this, std::forward<_DifferenceType>(__n))); + return __pipeable(std::__bind_back(__fn{}, std::forward<_DifferenceType>(__n))); } }; @@ -546,6 +546,7 @@ struct __fn { inline namespace __cpo { inline constexpr auto chunk = __chunk::__fn{}; + } // namespace __cpo } // namespace views From e63f929fc974dadd1fc6f58de7a87a3322df8eb2 Mon Sep 17 00:00:00 2001 From: anonymouspc Date: Tue, 9 Dec 2025 15:59:38 +0800 Subject: [PATCH 15/34] update test/std --- .../range.chunk/adaptor.pass.cpp | 48 ++++----- .../range.adaptors/range.chunk/base.pass.cpp | 27 +++-- .../range.adaptors/range.chunk/begin.pass.cpp | 60 +++++------ .../range.chunk/ctad.compile.pass.cpp | 13 ++- .../range.adaptors/range.chunk/end.pass.cpp | 53 +++++----- .../range.chunk/general.pass.cpp | 11 ++- .../ranges/range.adaptors/range.chunk/types.h | 99 +++++++++++-------- 7 files changed, 178 insertions(+), 133 deletions(-) diff --git a/libcxx/test/std/ranges/range.adaptors/range.chunk/adaptor.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.chunk/adaptor.pass.cpp index f85ca3c47c661..d4592272bfd36 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.chunk/adaptor.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.chunk/adaptor.pass.cpp @@ -8,57 +8,57 @@ // REQUIRES: std-at-least-c++23 -// std::views::chunk +// -#include +// std::views::chunk #include #include #include #include +#include #include +#include #include "test_range.h" #include "types.h" constexpr bool test() { - std::array array = {1, 1, 1, 2, 2, 2, 3, 3}; - std::span span = {array.data(), 8}; + std::array array = {1, 2, 3, 4, 5, 6, 7, 8}; + std::span view = {array.data(), 8}; // Test `views::chunk(view, n)` { - std::same_as>>> decltype(auto) chunked = std::views::chunk(span, 2); - assert(std::ranges::equal(*chunked.begin(), std::array{1, 1})); - } - - // Test `views::chunk(input_view, n)` - { - auto input = exactly_input_view(span); - auto chunked = std::views::chunk(input, 3); - assert(std::ranges::equal(*chunked.begin(), std::array{1, 1, 1})); + std::same_as>> decltype(auto) chunked = std::views::chunk(view, 2); + assert(std::ranges::equal(*chunked.begin(), std::array{1, 2})); + std::same_as>> decltype(auto) const_chunked = std::views::chunk(std::as_const(view), 2); + assert(std::ranges::equal(*const_chunked.begin(), std::array{1, 2})); } // Test `views::chunk(n)(range)` { - auto adaptor = std::views::chunk(4); - auto chunked = adaptor(span); - static_assert(std::same_as>>); - assert(std::ranges::equal(*chunked.begin(), std::array{1, 1, 1, 2})); + auto adaptor = std::views::chunk(3); + std::same_as>> decltype(auto) chunked = adaptor(view); + assert(std::ranges::equal(*chunked.begin(), std::array{1, 2, 3})); + std::same_as>> decltype(auto) const_chunked = adaptor(std::as_const(view)); + assert(std::ranges::equal(*const_chunked.begin(), std::array{1, 2, 3})); } // Test `view | views::chunk` { - auto chunked = span | std::views::chunk(5); - static_assert(std::same_as>>); - static_assert(std::ranges::random_access_range); - assert(std::ranges::equal(*chunked.begin(), std::array{1, 1, 1, 2, 2})); + std::same_as>> decltype(auto) chunked = view | std::views::chunk(4); + assert(std::ranges::equal(*chunked.begin(), std::array{1, 2, 3, 4})); + std::same_as>> decltype(auto) const_chunked = std::as_const(view) | std::views::chunk(4); + assert(std::ranges::equal(*const_chunked.begin(), std::array{1, 2, 3, 4})); } // Test `views::chunk | adaptor` { - auto multi_adaptor = std::views::chunk(1) | std::views::join; - auto rejoined = span | multi_adaptor; - assert(std::ranges::equal(rejoined, span)); + auto adaptors = std::views::chunk(5) | std::views::join; + std::ranges::input_range auto rejoined = view | adaptors; + assert(std::ranges::equal(rejoined, view)); + std::ranges::input_range auto const_rejoined = std::as_const(view) | adaptors; + assert(std::ranges::equal(const_rejoined, view)); } return true; diff --git a/libcxx/test/std/ranges/range.adaptors/range.chunk/base.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.chunk/base.pass.cpp index 0cca883399e7f..a9f27b15891ce 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.chunk/base.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.chunk/base.pass.cpp @@ -8,26 +8,37 @@ // REQUIRES: std-at-least-c++23 -// std::views::chunk +// -#include +// constexpr V base() const& requires copyy_constructible; +// constexpr V base() &&; #include #include +#include +#include #include +#include #include "test_range.h" constexpr bool test() { - std::array array = {1, 1, 1, 2, 2, 2, 3, 3}; + std::array array = {1, 2, 3, 4, 5, 6, 7, 8}; + std::span view = {array.data(), 8}; // Test `chunk_view.base()` { - auto view = array | std::views::chunk(3); - auto base = view.begin().base(); - assert(base == array.begin()); - base = view.end().base(); - assert(base == array.end()); + auto chunked = view | std::views::chunk(3); + std::same_as::iterator> decltype(auto) begin = chunked.begin().base(); + std::same_as::iterator> decltype(auto) end = chunked.end().base(); + assert(begin == view.begin()); + assert(end == view.end()); + + auto const_chunked = std::as_const(view) | std::views::chunk(4); + std::same_as::iterator> decltype(auto) const_begin = const_chunked.begin().base(); + std::same_as::iterator> decltype(auto) const_end = const_chunked.end().base(); + assert(const_begin == std::as_const(view).begin()); + assert(const_end == std::as_const(view).end()); } return true; diff --git a/libcxx/test/std/ranges/range.adaptors/range.chunk/begin.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.chunk/begin.pass.cpp index 5c8951f3bb10e..bea6e727af865 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.chunk/begin.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.chunk/begin.pass.cpp @@ -8,48 +8,52 @@ // REQUIRES: std-at-least-c++23 -// std::views::chunk +// -#include +// V models only input_range: +// constexpr __outer_iterator begin(); + +// V models forward_range: +// constexpr auto begin() requires (!__simple_view); +// constexpr auto begin() const requires forward_range; #include #include +#include #include #include "test_range.h" +#include "types.h" constexpr bool test() { - std::vector full_vector = {1, 1, 1, 2, 2, 2, 3, 3}; - std::vector empty_vector = {}; - - // Test `chunk_view.begin()` - { - auto view = full_vector | std::views::chunk(3); - auto it = view.begin(); - assert(std::ranges::equal(*it, std::vector{1, 1, 1})); - assert(std::ranges::equal(*++it, std::vector{2, 2, 2})); - assert(std::ranges::equal(*++it, std::vector{3, 3})); // The last chunk has only 2 elements. - assert(++it == view.end()); // Reaches end. - - view = full_vector | std::views::chunk(5); - it = view.begin(); - assert(std::ranges::equal(*it, std::vector{1, 1, 1, 2, 2})); - assert(std::ranges::equal(*++it, std::vector{2, 3, 3})); - } + std::vector vector = {1, 2, 3, 4, 5, 6, 7, 8}; + std::span random_access_view = {vector.data(), 8}; + input_span input_view = {vector.data(), 8}; - // Test `empty_chunk_view.begin()` + // Test `chunk_view.begin()` when V models only input_range { - auto view = empty_vector | std::views::chunk(3); - assert(view.size() == 0); - assert(view.begin() == view.end()); + auto chunked = input_view | std::views::chunk(3); + auto it = chunked.begin(); + assert(std::ranges::equal(*it, std::vector{1, 2, 3})); + assert(std::ranges::equal(*++it, std::vector{4, 5, 6})); + assert(std::ranges::equal(*++it, std::vector{7, 8})); + assert(++it == chunked.end()); } - // Test `small_view_with_big_chunk.begin()` + // Test `chunk_view.begin()` when V models forward_range { - auto view = full_vector | std::views::chunk(314159); - assert(view.size() == 1); - assert(std::ranges::equal(*view.begin(), full_vector)); - assert(++view.begin() == view.end()); + auto chunked = random_access_view | std::views::chunk(3); + auto it = chunked.begin(); + assert(std::ranges::equal(*it, std::vector{1, 2, 3})); + assert(std::ranges::equal(*++it, std::vector{4, 5, 6})); + assert(std::ranges::equal(*++it, std::vector{7, 8})); + assert(++it == chunked.end()); + auto const_chunked = std::as_const(random_access_view) | std::views::chunk(3); + auto const_it = const_chunked.begin(); + assert(std::ranges::equal(*const_it, std::vector{1, 2, 3})); + assert(std::ranges::equal(*++const_it, std::vector{4, 5, 6})); + assert(std::ranges::equal(*++const_it, std::vector{7, 8})); + assert(++it == const_chunked.end()); } return true; diff --git a/libcxx/test/std/ranges/range.adaptors/range.chunk/ctad.compile.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.chunk/ctad.compile.pass.cpp index 862accc4063b1..20844d921bfca 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.chunk/ctad.compile.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.chunk/ctad.compile.pass.cpp @@ -8,7 +8,10 @@ // REQUIRES: std-at-least-c++23 -// std::views::chunk +// + +// template +// chunk_view(R&&, range_difference_t) -> chunk_view>; #include @@ -30,15 +33,15 @@ struct borrowed_range { template <> inline constexpr bool std::ranges::enable_borrowed_range = true; -void testCTAD() { +void test_ctad() { view v; range r; borrowed_range br; - static_assert(std::same_as< decltype(std::ranges::chunk_view(v, 0)), std::ranges::chunk_view >); - static_assert(std::same_as< decltype(std::ranges::chunk_view(std::move(v), 0)), std::ranges::chunk_view >); + static_assert(std::same_as>); + static_assert(std::same_as>); static_assert( - std::same_as< decltype(std::ranges::chunk_view(r, 0)), std::ranges::chunk_view> >); + std::same_as< decltype(std::ranges::chunk_view(r, 0)), std::ranges::chunk_view>>); static_assert(std::same_as>>); static_assert(std::same_as + +// V models only input_range: +// constexpr default_sentinel_t end(); + +// V moduels forward_range: +// constexpr auto end() requires (!__simple_view); +// constexpr auto end() const requires forward_range; -#include #include #include #include +#include +#include #include #include "test_range.h" #include "types.h" constexpr bool test() { - std::vector vector = {1, 1, 1, 2, 2, 2, 3, 3}; + std::vector vector = {1, 2, 3, 4, 5, 6, 7, 8}; + std::span random_access_view = {vector.data(), 8}; + input_span input_view = {vector.data(), 8}; - // Test `chunk_view.end()` + // Test `chunk_view.end()` when V models only input_range { - auto view = vector | std::views::chunk(3); - auto it = view.end(); - assert(std::ranges::equal(*--it, std::vector{3, 3})); // We can adjust the tailing chunk-size. - assert(std::ranges::equal(*--it, std::vector{2, 2, 2})); - assert(std::ranges::equal(*--it, std::vector{1, 1, 1})); + auto chunked = input_view | std::views::chunk(3); + [[maybe_unused]] std::same_as auto it = chunked.end(); } - - // Test `not_sized_chunk_view.end()` - { - auto not_sized_vector = not_sized_view(vector | std::views::all); - auto view = not_sized_vector | std::views::chunk(4); - static_assert(std::ranges::bidirectional_range); - static_assert(!std::ranges::sized_range); - // We cannot handle the tailing chunk without size info, so we forbids one to derement from end(). - static_assert(std::same_as< decltype(view.end()), std::default_sentinel_t>); - } - - // Test `forward_chunk_view.end()` + + // Test `chunk_view.end()` when V models forward_range { - auto view = vector | std::views::chunk(5); - assert(++(++view.begin()) == view.end()); + auto chunked = random_access_view | std::views::chunk(3); + std::random_access_iterator auto it = chunked.end(); + assert(std::ranges::equal(*--it, std::vector{7, 8})); + assert(std::ranges::equal(*--it, std::vector{4, 5, 6})); + assert(std::ranges::equal(*--it, std::vector{1, 2,3 })); + assert(it == chunked.begin()); + auto const_chunked = std::as_const(random_access_view) | std::views::chunk(3); + std::random_access_iterator auto const_it = const_chunked.end(); + assert(std::ranges::equal(*--const_it, std::vector{7, 8})); + assert(std::ranges::equal(*--const_it, std::vector{4, 5, 6})); + assert(std::ranges::equal(*--const_it, std::vector{1, 2, 3})); + assert(const_it == const_chunked.begin()); } return true; diff --git a/libcxx/test/std/ranges/range.adaptors/range.chunk/general.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.chunk/general.pass.cpp index b9e81314a9580..7eaffb3bf0293 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.chunk/general.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.chunk/general.pass.cpp @@ -8,12 +8,13 @@ // REQUIRES: std-at-least-c++23 -// std::views::chunk +// -#include +// General tests for chunk_view. This file does not test anything specifically. #include #include +#include #include #include "test_range.h" @@ -30,9 +31,9 @@ constexpr bool test() { | std::views::lazy_split(' ') | std::views::chunk(2) | std::views::transform([] (auto&& subview) - { - return subview | std::views::join_with(' '); - }) + { + return subview | std::views::join_with(' '); + }) | std::views::join_with(' '); // clang-format on assert(std::ranges::equal(str, str2)); diff --git a/libcxx/test/std/ranges/range.adaptors/range.chunk/types.h b/libcxx/test/std/ranges/range.adaptors/range.chunk/types.h index 5c6f3ef21ddb8..99bd23778b162 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.chunk/types.h +++ b/libcxx/test/std/ranges/range.adaptors/range.chunk/types.h @@ -9,61 +9,80 @@ #ifndef TEST_STD_RANGES_RANGE_ADAPTORS_RANGE_CHUNK_TYPES_H #define TEST_STD_RANGES_RANGE_ADAPTORS_RANGE_CHUNK_TYPES_H +#include #include #include -template -struct exactly_input_view : View, std::ranges::view_interface> { - struct iterator : std::ranges::iterator_t { +// input_span + +template +struct input_span : std::span { + struct iterator : std::span::iterator { using iterator_concept = std::input_iterator_tag; constexpr iterator() = default; - constexpr iterator(std::ranges::iterator_t i) : std::ranges::iterator_t(i) {} - constexpr auto operator*() const { return std::ranges::iterator_t::operator*(); } - friend constexpr void operator+(iterator, int) = delete; - friend constexpr void operator+(int, iterator) = delete; - friend constexpr void operator-(iterator, int) = delete; - friend constexpr void operator-(iterator, iterator) = delete; + constexpr iterator(std::span::iterator i) : std::span::iterator(i) {} + constexpr auto operator*() const { return std::span::iterator::operator*(); } + friend constexpr auto operator+(iterator, auto) = delete; + friend constexpr auto operator+(auto, iterator) = delete; + friend constexpr auto operator-(iterator, auto) = delete; + friend constexpr auto operator-(auto, iterator) = delete; friend constexpr iterator& operator++(iterator& self) { - self.std::ranges::template iterator_t::operator++(); + ++static_cast::iterator&>(self); return self; } friend constexpr void operator++(iterator& self, int) { ++self; } - friend constexpr void operator--(iterator&) = delete; + friend constexpr iterator& operator--(iterator&) = delete; friend constexpr void operator--(iterator&, int) = delete; }; - - constexpr iterator begin(this auto&& self) { return iterator(self.View::begin()); } - constexpr iterator end(this auto&& self) { return iterator(self.View::end()); } + + using std::span::span; + constexpr iterator begin() { return iterator(std::span::begin()); } + constexpr iterator end() { return iterator(std::span::end()); } }; -template -struct not_sized_view : View, std::ranges::view_interface> { - struct iterator : std::ranges::iterator_t { - using iterator_concept = std::bidirectional_iterator_tag; - constexpr iterator() = default; - constexpr iterator(std::ranges::iterator_t i) : std::ranges::iterator_t(i) {} - friend constexpr void operator-(iterator, iterator) = delete; - friend constexpr iterator& operator++(iterator& self) { - self.std::ranges::template iterator_t::operator++(); - return self; - } - friend constexpr iterator operator++(iterator& self, int) { return ++self; } - friend constexpr iterator& operator--(iterator& self) { - self.std::ranges::template iterator_t::operator--(); - return self; - } - friend constexpr iterator operator--(iterator& self, int) { return --self; } - }; +template +inline constexpr bool std::ranges::enable_view> = true; - constexpr iterator begin(this auto&& self) { return iterator(self.View::begin()); } - constexpr iterator end(this auto&& self) { return iterator(self.View::end()); } - constexpr auto size() const = delete; -}; +static_assert( std::ranges::input_range> && + !std::ranges::forward_range> && + std::ranges::view>); + +// // not_sized_view + +// template +// requires std::ranges::random_access_range && +// std::ranges::view +// struct not_sized_view : View, std::ranges::view_interface> { +// template +// struct not_sized_iterator : Iterator { +// using iterator_concept = std::bidirectional_iterator_tag; +// constexpr not_sized_iterator() = default; +// constexpr not_sized_iterator(Iterator i) : Iterator(i) {} +// friend constexpr void operator-(not_sized_iterator, not_sized_iterator) = delete; +// friend constexpr not_sized_iterator& operator++(not_sized_iterator& self) { +// self.Iterator::operator++(); +// return self; +// } +// friend constexpr not_sized_iterator operator++(not_sized_iterator& self, int) { return ++self; } +// friend constexpr not_sized_iterator& operator--(not_sized_iterator& self) { +// self.Iterator::operator--(); +// return self; +// } +// friend constexpr not_sized_iterator operator--(not_sized_iterator& self, int) { return --self; } +// }; + +// constexpr std::bidirectional_iterator auto begin(this auto&& self) { return iterator(self.View::begin()); } +// constexpr std::bidirectional_iterator auto end(this auto&& self) { return iterator(self.View::end()); } +// constexpr auto size() const = delete; +// }; + +// template +// not_sized_view(View) -> not_sized_view; -template -not_sized_view(View) -> not_sized_view; +// template +// inline constexpr bool std::ranges::enable_view> = true; -template -inline constexpr bool std::ranges::disable_sized_range> = true; +// template +// inline constexpr bool std::ranges::disable_sized_range> = true; #endif From 078190ab1ad5ecaad4d1f1425bbfeac51e08109b Mon Sep 17 00:00:00 2001 From: anonymouspc Date: Tue, 9 Dec 2025 16:01:25 +0800 Subject: [PATCH 16/34] clang-format --- .../range.chunk/adaptor.pass.cpp | 12 +++-- .../range.adaptors/range.chunk/base.pass.cpp | 10 ++-- .../range.adaptors/range.chunk/begin.pass.cpp | 18 +++---- .../range.adaptors/range.chunk/end.pass.cpp | 19 ++++--- .../ranges/range.adaptors/range.chunk/types.h | 51 +++---------------- 5 files changed, 36 insertions(+), 74 deletions(-) diff --git a/libcxx/test/std/ranges/range.adaptors/range.chunk/adaptor.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.chunk/adaptor.pass.cpp index d4592272bfd36..cced11ce940bf 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.chunk/adaptor.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.chunk/adaptor.pass.cpp @@ -24,20 +24,21 @@ #include "types.h" constexpr bool test() { - std::array array = {1, 2, 3, 4, 5, 6, 7, 8}; + std::array array = {1, 2, 3, 4, 5, 6, 7, 8}; std::span view = {array.data(), 8}; // Test `views::chunk(view, n)` { std::same_as>> decltype(auto) chunked = std::views::chunk(view, 2); assert(std::ranges::equal(*chunked.begin(), std::array{1, 2})); - std::same_as>> decltype(auto) const_chunked = std::views::chunk(std::as_const(view), 2); + std::same_as>> decltype(auto) const_chunked = + std::views::chunk(std::as_const(view), 2); assert(std::ranges::equal(*const_chunked.begin(), std::array{1, 2})); } // Test `views::chunk(n)(range)` { - auto adaptor = std::views::chunk(3); + auto adaptor = std::views::chunk(3); std::same_as>> decltype(auto) chunked = adaptor(view); assert(std::ranges::equal(*chunked.begin(), std::array{1, 2, 3})); std::same_as>> decltype(auto) const_chunked = adaptor(std::as_const(view)); @@ -48,13 +49,14 @@ constexpr bool test() { { std::same_as>> decltype(auto) chunked = view | std::views::chunk(4); assert(std::ranges::equal(*chunked.begin(), std::array{1, 2, 3, 4})); - std::same_as>> decltype(auto) const_chunked = std::as_const(view) | std::views::chunk(4); + std::same_as>> decltype(auto) const_chunked = + std::as_const(view) | std::views::chunk(4); assert(std::ranges::equal(*const_chunked.begin(), std::array{1, 2, 3, 4})); } // Test `views::chunk | adaptor` { - auto adaptors = std::views::chunk(5) | std::views::join; + auto adaptors = std::views::chunk(5) | std::views::join; std::ranges::input_range auto rejoined = view | adaptors; assert(std::ranges::equal(rejoined, view)); std::ranges::input_range auto const_rejoined = std::as_const(view) | adaptors; diff --git a/libcxx/test/std/ranges/range.adaptors/range.chunk/base.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.chunk/base.pass.cpp index a9f27b15891ce..15b30d4398b28 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.chunk/base.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.chunk/base.pass.cpp @@ -23,20 +23,20 @@ #include "test_range.h" constexpr bool test() { - std::array array = {1, 2, 3, 4, 5, 6, 7, 8}; + std::array array = {1, 2, 3, 4, 5, 6, 7, 8}; std::span view = {array.data(), 8}; // Test `chunk_view.base()` { - auto chunked = view | std::views::chunk(3); + auto chunked = view | std::views::chunk(3); std::same_as::iterator> decltype(auto) begin = chunked.begin().base(); - std::same_as::iterator> decltype(auto) end = chunked.end().base(); + std::same_as::iterator> decltype(auto) end = chunked.end().base(); assert(begin == view.begin()); assert(end == view.end()); - auto const_chunked = std::as_const(view) | std::views::chunk(4); + auto const_chunked = std::as_const(view) | std::views::chunk(4); std::same_as::iterator> decltype(auto) const_begin = const_chunked.begin().base(); - std::same_as::iterator> decltype(auto) const_end = const_chunked.end().base(); + std::same_as::iterator> decltype(auto) const_end = const_chunked.end().base(); assert(const_begin == std::as_const(view).begin()); assert(const_end == std::as_const(view).end()); } diff --git a/libcxx/test/std/ranges/range.adaptors/range.chunk/begin.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.chunk/begin.pass.cpp index bea6e727af865..e8a7c39e7643d 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.chunk/begin.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.chunk/begin.pass.cpp @@ -26,15 +26,15 @@ #include "types.h" constexpr bool test() { - std::vector vector = {1, 2, 3, 4, 5, 6, 7, 8}; - std::span random_access_view = {vector.data(), 8}; - input_span input_view = {vector.data(), 8}; + std::vector vector = {1, 2, 3, 4, 5, 6, 7, 8}; + std::span random_access_view = {vector.data(), 8}; + input_span input_view = {vector.data(), 8}; // Test `chunk_view.begin()` when V models only input_range { auto chunked = input_view | std::views::chunk(3); - auto it = chunked.begin(); - assert(std::ranges::equal(*it, std::vector{1, 2, 3})); + auto it = chunked.begin(); + assert(std::ranges::equal(*it, std::vector{1, 2, 3})); assert(std::ranges::equal(*++it, std::vector{4, 5, 6})); assert(std::ranges::equal(*++it, std::vector{7, 8})); assert(++it == chunked.end()); @@ -43,14 +43,14 @@ constexpr bool test() { // Test `chunk_view.begin()` when V models forward_range { auto chunked = random_access_view | std::views::chunk(3); - auto it = chunked.begin(); - assert(std::ranges::equal(*it, std::vector{1, 2, 3})); + auto it = chunked.begin(); + assert(std::ranges::equal(*it, std::vector{1, 2, 3})); assert(std::ranges::equal(*++it, std::vector{4, 5, 6})); assert(std::ranges::equal(*++it, std::vector{7, 8})); assert(++it == chunked.end()); auto const_chunked = std::as_const(random_access_view) | std::views::chunk(3); - auto const_it = const_chunked.begin(); - assert(std::ranges::equal(*const_it, std::vector{1, 2, 3})); + auto const_it = const_chunked.begin(); + assert(std::ranges::equal(*const_it, std::vector{1, 2, 3})); assert(std::ranges::equal(*++const_it, std::vector{4, 5, 6})); assert(std::ranges::equal(*++const_it, std::vector{7, 8})); assert(++it == const_chunked.end()); diff --git a/libcxx/test/std/ranges/range.adaptors/range.chunk/end.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.chunk/end.pass.cpp index 05e42a5e4d253..edeaf7ac74ef4 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.chunk/end.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.chunk/end.pass.cpp @@ -17,7 +17,6 @@ // constexpr auto end() requires (!__simple_view); // constexpr auto end() const requires forward_range; - #include #include #include @@ -29,25 +28,25 @@ #include "types.h" constexpr bool test() { - std::vector vector = {1, 2, 3, 4, 5, 6, 7, 8}; - std::span random_access_view = {vector.data(), 8}; - input_span input_view = {vector.data(), 8}; + std::vector vector = {1, 2, 3, 4, 5, 6, 7, 8}; + std::span random_access_view = {vector.data(), 8}; + input_span input_view = {vector.data(), 8}; // Test `chunk_view.end()` when V models only input_range { - auto chunked = input_view | std::views::chunk(3); + auto chunked = input_view | std::views::chunk(3); [[maybe_unused]] std::same_as auto it = chunked.end(); } - + // Test `chunk_view.end()` when V models forward_range { - auto chunked = random_access_view | std::views::chunk(3); + auto chunked = random_access_view | std::views::chunk(3); std::random_access_iterator auto it = chunked.end(); - assert(std::ranges::equal(*--it, std::vector{7, 8})); + assert(std::ranges::equal(*--it, std::vector{7, 8})); assert(std::ranges::equal(*--it, std::vector{4, 5, 6})); - assert(std::ranges::equal(*--it, std::vector{1, 2,3 })); + assert(std::ranges::equal(*--it, std::vector{1, 2, 3})); assert(it == chunked.begin()); - auto const_chunked = std::as_const(random_access_view) | std::views::chunk(3); + auto const_chunked = std::as_const(random_access_view) | std::views::chunk(3); std::random_access_iterator auto const_it = const_chunked.end(); assert(std::ranges::equal(*--const_it, std::vector{7, 8})); assert(std::ranges::equal(*--const_it, std::vector{4, 5, 6})); diff --git a/libcxx/test/std/ranges/range.adaptors/range.chunk/types.h b/libcxx/test/std/ranges/range.adaptors/range.chunk/types.h index 99bd23778b162..907f5940cf21d 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.chunk/types.h +++ b/libcxx/test/std/ranges/range.adaptors/range.chunk/types.h @@ -22,9 +22,9 @@ struct input_span : std::span { constexpr iterator() = default; constexpr iterator(std::span::iterator i) : std::span::iterator(i) {} constexpr auto operator*() const { return std::span::iterator::operator*(); } - friend constexpr auto operator+(iterator, auto) = delete; - friend constexpr auto operator+(auto, iterator) = delete; - friend constexpr auto operator-(iterator, auto) = delete; + friend constexpr auto operator+(iterator, auto) = delete; + friend constexpr auto operator+(auto, iterator) = delete; + friend constexpr auto operator-(iterator, auto) = delete; friend constexpr auto operator-(auto, iterator) = delete; friend constexpr iterator& operator++(iterator& self) { ++static_cast::iterator&>(self); @@ -34,7 +34,7 @@ struct input_span : std::span { friend constexpr iterator& operator--(iterator&) = delete; friend constexpr void operator--(iterator&, int) = delete; }; - + using std::span::span; constexpr iterator begin() { return iterator(std::span::begin()); } constexpr iterator end() { return iterator(std::span::end()); } @@ -43,46 +43,7 @@ struct input_span : std::span { template inline constexpr bool std::ranges::enable_view> = true; -static_assert( std::ranges::input_range> && - !std::ranges::forward_range> && - std::ranges::view>); - -// // not_sized_view - -// template -// requires std::ranges::random_access_range && -// std::ranges::view -// struct not_sized_view : View, std::ranges::view_interface> { -// template -// struct not_sized_iterator : Iterator { -// using iterator_concept = std::bidirectional_iterator_tag; -// constexpr not_sized_iterator() = default; -// constexpr not_sized_iterator(Iterator i) : Iterator(i) {} -// friend constexpr void operator-(not_sized_iterator, not_sized_iterator) = delete; -// friend constexpr not_sized_iterator& operator++(not_sized_iterator& self) { -// self.Iterator::operator++(); -// return self; -// } -// friend constexpr not_sized_iterator operator++(not_sized_iterator& self, int) { return ++self; } -// friend constexpr not_sized_iterator& operator--(not_sized_iterator& self) { -// self.Iterator::operator--(); -// return self; -// } -// friend constexpr not_sized_iterator operator--(not_sized_iterator& self, int) { return --self; } -// }; - -// constexpr std::bidirectional_iterator auto begin(this auto&& self) { return iterator(self.View::begin()); } -// constexpr std::bidirectional_iterator auto end(this auto&& self) { return iterator(self.View::end()); } -// constexpr auto size() const = delete; -// }; - -// template -// not_sized_view(View) -> not_sized_view; - -// template -// inline constexpr bool std::ranges::enable_view> = true; - -// template -// inline constexpr bool std::ranges::disable_sized_range> = true; +static_assert(std::ranges::input_range> && !std::ranges::forward_range> && + std::ranges::view>); #endif From f420def2e96ba9da84215fa7f3062c245d9eb964 Mon Sep 17 00:00:00 2001 From: anonymouspc Date: Tue, 9 Dec 2025 16:03:15 +0800 Subject: [PATCH 17/34] clang-format --- libcxx/include/__ranges/chunk_view.h | 7 ++++--- .../range.adaptors/range.chunk/ctad.compile.pass.cpp | 6 +++--- .../range.chunk/range.chunk.iter/compare.pass.cpp | 2 +- 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/libcxx/include/__ranges/chunk_view.h b/libcxx/include/__ranges/chunk_view.h index bc8ff5bb5ce59..2a10a3a05b792 100644 --- a/libcxx/include/__ranges/chunk_view.h +++ b/libcxx/include/__ranges/chunk_view.h @@ -140,7 +140,8 @@ class chunk_view<_View>::__outer_iterator { _LIBCPP_HIDE_FROM_ABI constexpr void operator++(int) { ++*this; } - [[nodiscard]] _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator==(const __outer_iterator& __i, default_sentinel_t) { + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI friend constexpr bool + operator==(const __outer_iterator& __i, default_sentinel_t) { return *__i.__parent_->__current_ == ranges::end(__i.__parent_->__base_) && __i.__parent_->__remainder_ != 0; } @@ -536,8 +537,8 @@ struct __fn { } template - [[nodiscard]] _LIBCPP_HIDE_FROM_ABI static constexpr auto operator()(_DifferenceType __n) - noexcept(is_nothrow_constructible_v, _DifferenceType>) { + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI static constexpr auto + operator()(_DifferenceType __n) noexcept(is_nothrow_constructible_v, _DifferenceType>) { return __pipeable(std::__bind_back(__fn{}, std::forward<_DifferenceType>(__n))); } }; diff --git a/libcxx/test/std/ranges/range.adaptors/range.chunk/ctad.compile.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.chunk/ctad.compile.pass.cpp index 20844d921bfca..862782e0a835d 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.chunk/ctad.compile.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.chunk/ctad.compile.pass.cpp @@ -43,9 +43,9 @@ void test_ctad() { static_assert( std::same_as< decltype(std::ranges::chunk_view(r, 0)), std::ranges::chunk_view>>); static_assert(std::same_as>>); + std::ranges::chunk_view>>); static_assert(std::same_as>>); + std::ranges::chunk_view>>); static_assert(std::same_as>>); + std::ranges::chunk_view>>); } diff --git a/libcxx/test/std/ranges/range.adaptors/range.chunk/range.chunk.iter/compare.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.chunk/range.chunk.iter/compare.pass.cpp index 63bfed60e5574..7ba898b599a30 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.chunk/range.chunk.iter/compare.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.chunk/range.chunk.iter/compare.pass.cpp @@ -20,7 +20,7 @@ // requires [random_access_range](https://eel.is/c++draft/range.refinements#concept:random_access_range); // friend constexpr auto operator<=>(const iterator& x, const iterator& y) // requires [random_access_range](https://eel.is/c++draft/range.refinements#concept:random_access_range) && - // [three_way_comparable](https://eel.is/c++draft/cmp.concept#concept:three_way_comparable)>; +// [three_way_comparable](https://eel.is/c++draft/cmp.concept#concept:three_way_comparable)>; #include #include From 9f03400a97cdca9cf6ce838b4d25052f97f6d139 Mon Sep 17 00:00:00 2001 From: anonymouspc Date: Tue, 9 Dec 2025 16:21:27 +0800 Subject: [PATCH 18/34] get rid of span --- .../range.chunk/adaptor.pass.cpp | 22 +++++++++---------- .../range.adaptors/range.chunk/base.pass.cpp | 17 +++++++------- .../range.adaptors/range.chunk/begin.pass.cpp | 6 ++--- .../range.adaptors/range.chunk/end.pass.cpp | 8 +++---- 4 files changed, 25 insertions(+), 28 deletions(-) diff --git a/libcxx/test/std/ranges/range.adaptors/range.chunk/adaptor.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.chunk/adaptor.pass.cpp index cced11ce940bf..01648c9a685d8 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.chunk/adaptor.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.chunk/adaptor.pass.cpp @@ -17,46 +17,44 @@ #include #include #include -#include #include #include "test_range.h" #include "types.h" constexpr bool test() { - std::array array = {1, 2, 3, 4, 5, 6, 7, 8}; - std::span view = {array.data(), 8}; + std::array array = {1, 2, 3, 4, 5, 6, 7, 8}; + auto view = array | std::views::all; // Test `views::chunk(view, n)` { - std::same_as>> decltype(auto) chunked = std::views::chunk(view, 2); + std::same_as>>> decltype(auto) chunked = std::views::chunk(view, 2); assert(std::ranges::equal(*chunked.begin(), std::array{1, 2})); - std::same_as>> decltype(auto) const_chunked = - std::views::chunk(std::as_const(view), 2); + std::same_as>>> decltype(auto) const_chunked = std::views::chunk(std::as_const(view), 2); assert(std::ranges::equal(*const_chunked.begin(), std::array{1, 2})); } // Test `views::chunk(n)(range)` { - auto adaptor = std::views::chunk(3); - std::same_as>> decltype(auto) chunked = adaptor(view); + auto adaptor = std::views::chunk(3); + std::same_as>>> decltype(auto) chunked = adaptor(view); assert(std::ranges::equal(*chunked.begin(), std::array{1, 2, 3})); - std::same_as>> decltype(auto) const_chunked = adaptor(std::as_const(view)); + std::same_as>>> decltype(auto) const_chunked = adaptor(std::as_const(view)); assert(std::ranges::equal(*const_chunked.begin(), std::array{1, 2, 3})); } // Test `view | views::chunk` { - std::same_as>> decltype(auto) chunked = view | std::views::chunk(4); + std::same_as>>> decltype(auto) chunked = view | std::views::chunk(4); assert(std::ranges::equal(*chunked.begin(), std::array{1, 2, 3, 4})); - std::same_as>> decltype(auto) const_chunked = + std::same_as>>> decltype(auto) const_chunked = std::as_const(view) | std::views::chunk(4); assert(std::ranges::equal(*const_chunked.begin(), std::array{1, 2, 3, 4})); } // Test `views::chunk | adaptor` { - auto adaptors = std::views::chunk(5) | std::views::join; + auto adaptors = std::views::chunk(5) | std::views::join; std::ranges::input_range auto rejoined = view | adaptors; assert(std::ranges::equal(rejoined, view)); std::ranges::input_range auto const_rejoined = std::as_const(view) | adaptors; diff --git a/libcxx/test/std/ranges/range.adaptors/range.chunk/base.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.chunk/base.pass.cpp index 15b30d4398b28..54002efd7d966 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.chunk/base.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.chunk/base.pass.cpp @@ -17,26 +17,25 @@ #include #include #include -#include #include #include "test_range.h" constexpr bool test() { - std::array array = {1, 2, 3, 4, 5, 6, 7, 8}; - std::span view = {array.data(), 8}; + std::array array = {1, 2, 3, 4, 5, 6, 7, 8}; + auto view = array | std::views::all; // Test `chunk_view.base()` { - auto chunked = view | std::views::chunk(3); - std::same_as::iterator> decltype(auto) begin = chunked.begin().base(); - std::same_as::iterator> decltype(auto) end = chunked.end().base(); + auto chunked = view | std::views::chunk(3); + std::same_as::iterator> decltype(auto) begin = chunked.begin().base(); + std::same_as::iterator> decltype(auto) end = chunked.end().base(); assert(begin == view.begin()); assert(end == view.end()); - auto const_chunked = std::as_const(view) | std::views::chunk(4); - std::same_as::iterator> decltype(auto) const_begin = const_chunked.begin().base(); - std::same_as::iterator> decltype(auto) const_end = const_chunked.end().base(); + auto const_chunked = std::as_const(view) | std::views::chunk(4); + std::same_as::iterator> decltype(auto) const_begin = const_chunked.begin().base(); + std::same_as::iterator> decltype(auto) const_end = const_chunked.end().base(); assert(const_begin == std::as_const(view).begin()); assert(const_end == std::as_const(view).end()); } diff --git a/libcxx/test/std/ranges/range.adaptors/range.chunk/begin.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.chunk/begin.pass.cpp index e8a7c39e7643d..da16ec89875de 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.chunk/begin.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.chunk/begin.pass.cpp @@ -26,9 +26,9 @@ #include "types.h" constexpr bool test() { - std::vector vector = {1, 2, 3, 4, 5, 6, 7, 8}; - std::span random_access_view = {vector.data(), 8}; - input_span input_view = {vector.data(), 8}; + std::vector vector = {1, 2, 3, 4, 5, 6, 7, 8}; + auto random_access_view = vector | std::views::all; + auto input_view = input_span{vector.data(), 8}; // Test `chunk_view.begin()` when V models only input_range { diff --git a/libcxx/test/std/ranges/range.adaptors/range.chunk/end.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.chunk/end.pass.cpp index edeaf7ac74ef4..bc0b44b972d2c 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.chunk/end.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.chunk/end.pass.cpp @@ -28,13 +28,13 @@ #include "types.h" constexpr bool test() { - std::vector vector = {1, 2, 3, 4, 5, 6, 7, 8}; - std::span random_access_view = {vector.data(), 8}; - input_span input_view = {vector.data(), 8}; + std::vector vector = {1, 2, 3, 4, 5, 6, 7, 8}; + auto random_access_view = vector | std::views::all; + auto input_view = input_span{vector.data(), 8}; // Test `chunk_view.end()` when V models only input_range { - auto chunked = input_view | std::views::chunk(3); + auto chunked = input_view | std::views::chunk(3); [[maybe_unused]] std::same_as auto it = chunked.end(); } From 89fe519a6411a773f9bb0a3b05a09d2daf32f7e7 Mon Sep 17 00:00:00 2001 From: anonymouspc Date: Tue, 9 Dec 2025 16:32:07 +0800 Subject: [PATCH 19/34] get rid of span --- .../range.adaptors/range.chunk/base.pass.cpp | 20 +++++++++---------- .../range.adaptors/range.chunk/begin.pass.cpp | 18 ++++++++--------- .../range.adaptors/range.chunk/end.pass.cpp | 12 +++++------ .../ranges/range.adaptors/range.chunk/types.h | 1 + 4 files changed, 24 insertions(+), 27 deletions(-) diff --git a/libcxx/test/std/ranges/range.adaptors/range.chunk/base.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.chunk/base.pass.cpp index 54002efd7d966..de845ab9700de 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.chunk/base.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.chunk/base.pass.cpp @@ -23,21 +23,21 @@ constexpr bool test() { std::array array = {1, 2, 3, 4, 5, 6, 7, 8}; - auto view = array | std::views::all; + auto chunked = array | std::views::chunk(3); + auto const_chunked = std::as_const(array) | std::views::chunk(4); // Test `chunk_view.base()` { - auto chunked = view | std::views::chunk(3); std::same_as::iterator> decltype(auto) begin = chunked.begin().base(); std::same_as::iterator> decltype(auto) end = chunked.end().base(); - assert(begin == view.begin()); - assert(end == view.end()); - - auto const_chunked = std::as_const(view) | std::views::chunk(4); - std::same_as::iterator> decltype(auto) const_begin = const_chunked.begin().base(); - std::same_as::iterator> decltype(auto) const_end = const_chunked.end().base(); - assert(const_begin == std::as_const(view).begin()); - assert(const_end == std::as_const(view).end()); + assert(begin == array.begin()); + assert(end == array.end()); + + + std::same_as::const_iterator> decltype(auto) const_begin = const_chunked.begin().base(); + std::same_as::const_iterator> decltype(auto) const_end = const_chunked.end().base(); + assert(const_begin == std::as_const(array).begin()); + assert(const_end == std::as_const(array).end()); } return true; diff --git a/libcxx/test/std/ranges/range.adaptors/range.chunk/begin.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.chunk/begin.pass.cpp index da16ec89875de..8725667df7159 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.chunk/begin.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.chunk/begin.pass.cpp @@ -27,33 +27,31 @@ constexpr bool test() { std::vector vector = {1, 2, 3, 4, 5, 6, 7, 8}; - auto random_access_view = vector | std::views::all; - auto input_view = input_span{vector.data(), 8}; + auto chunked = vector | std::views::chunk(3); + auto const_chunked = std::as_const(vector) | std::views::chunk(3); + auto input_chunked = input_span(vector.data(), 8) | std::views::chunk(3); // Test `chunk_view.begin()` when V models only input_range { - auto chunked = input_view | std::views::chunk(3); - auto it = chunked.begin(); + auto it = input_chunked.begin(); assert(std::ranges::equal(*it, std::vector{1, 2, 3})); assert(std::ranges::equal(*++it, std::vector{4, 5, 6})); assert(std::ranges::equal(*++it, std::vector{7, 8})); - assert(++it == chunked.end()); + assert(++it == input_chunked.end()); } // Test `chunk_view.begin()` when V models forward_range { - auto chunked = random_access_view | std::views::chunk(3); - auto it = chunked.begin(); + auto it = chunked.begin(); assert(std::ranges::equal(*it, std::vector{1, 2, 3})); assert(std::ranges::equal(*++it, std::vector{4, 5, 6})); assert(std::ranges::equal(*++it, std::vector{7, 8})); assert(++it == chunked.end()); - auto const_chunked = std::as_const(random_access_view) | std::views::chunk(3); - auto const_it = const_chunked.begin(); + auto const_it = const_chunked.begin(); assert(std::ranges::equal(*const_it, std::vector{1, 2, 3})); assert(std::ranges::equal(*++const_it, std::vector{4, 5, 6})); assert(std::ranges::equal(*++const_it, std::vector{7, 8})); - assert(++it == const_chunked.end()); + assert(++const_it == const_chunked.end()); } return true; diff --git a/libcxx/test/std/ranges/range.adaptors/range.chunk/end.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.chunk/end.pass.cpp index bc0b44b972d2c..bcb81c8981e52 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.chunk/end.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.chunk/end.pass.cpp @@ -28,25 +28,23 @@ #include "types.h" constexpr bool test() { - std::vector vector = {1, 2, 3, 4, 5, 6, 7, 8}; - auto random_access_view = vector | std::views::all; - auto input_view = input_span{vector.data(), 8}; + std::vector vector = {1, 2, 3, 4, 5, 6, 7, 8}; + auto chunked = vector | std::views::chunk(3); + auto const_chunked = std::as_const(vector) | std::views::chunk(3); + auto input_chunked = input_span(vector.data(), 8) | std::views::chunk(3); // Test `chunk_view.end()` when V models only input_range { - auto chunked = input_view | std::views::chunk(3); - [[maybe_unused]] std::same_as auto it = chunked.end(); + [[maybe_unused]] std::same_as auto it = input_chunked.end(); } // Test `chunk_view.end()` when V models forward_range { - auto chunked = random_access_view | std::views::chunk(3); std::random_access_iterator auto it = chunked.end(); assert(std::ranges::equal(*--it, std::vector{7, 8})); assert(std::ranges::equal(*--it, std::vector{4, 5, 6})); assert(std::ranges::equal(*--it, std::vector{1, 2, 3})); assert(it == chunked.begin()); - auto const_chunked = std::as_const(random_access_view) | std::views::chunk(3); std::random_access_iterator auto const_it = const_chunked.end(); assert(std::ranges::equal(*--const_it, std::vector{7, 8})); assert(std::ranges::equal(*--const_it, std::vector{4, 5, 6})); diff --git a/libcxx/test/std/ranges/range.adaptors/range.chunk/types.h b/libcxx/test/std/ranges/range.adaptors/range.chunk/types.h index 907f5940cf21d..f5c09215b8b4c 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.chunk/types.h +++ b/libcxx/test/std/ranges/range.adaptors/range.chunk/types.h @@ -11,6 +11,7 @@ #include #include +#include #include // input_span From e7f4b4d1a4ee878fee5888bbfcd7c5961ff116c1 Mon Sep 17 00:00:00 2001 From: anonymouspc Date: Tue, 9 Dec 2025 16:35:23 +0800 Subject: [PATCH 20/34] test/iter --- .../range.chunk.iter/compare.pass.cpp | 68 +++++++++++++------ .../range.chunk.iter/decrement.pass.cpp | 37 ++++++---- .../range.chunk.iter/increment.pass.cpp | 32 ++++++--- 3 files changed, 94 insertions(+), 43 deletions(-) diff --git a/libcxx/test/std/ranges/range.adaptors/range.chunk/range.chunk.iter/compare.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.chunk/range.chunk.iter/compare.pass.cpp index 7ba898b599a30..6ac1e51ca4192 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.chunk/range.chunk.iter/compare.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.chunk/range.chunk.iter/compare.pass.cpp @@ -10,38 +10,64 @@ // -// friend constexpr bool operator<(const iterator& x, const iterator& y) -// requires [random_access_range](https://eel.is/c++draft/range.refinements#concept:random_access_range); -// friend constexpr bool operator>(const iterator& x, const iterator& y) -// requires [random_access_range](https://eel.is/c++draft/range.refinements#concept:random_access_range); -// friend constexpr bool operator<=(const iterator& x, const iterator& y) -// requires [random_access_range](https://eel.is/c++draft/range.refinements#concept:random_access_range); -// friend constexpr bool operator>=(const iterator& x, const iterator& y) -// requires [random_access_range](https://eel.is/c++draft/range.refinements#concept:random_access_range); -// friend constexpr auto operator<=>(const iterator& x, const iterator& y) -// requires [random_access_range](https://eel.is/c++draft/range.refinements#concept:random_access_range) && -// [three_way_comparable](https://eel.is/c++draft/cmp.concept#concept:three_way_comparable)>; +// friend constexpr bool operator==(const iterator& x, const iterator& y) +// friend constexpr bool operator<(const iterator& x, const iterator& y) +// requires random_access_range; +// friend constexpr bool operator>(const iterator& x, const iterator& y) +// requires random_access_range; +// friend constexpr bool operator<=(const iterator& x, const iterator& y) +// requires random_access_range; +// friend constexpr bool operator>=(const iterator& x, const iterator& y) +// requires random_access_range; +// friend constexpr auto operator<=>(const iterator& x, const iterator& y) +// requires random_access_range && +// three_way_comparable>; #include #include +#include #include #include #include "test_range.h" constexpr bool test() { - std::vector vector = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}; + std::vector vector = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}; + auto chunked = vector | std::views::chunk(3); - // Test `chunk_view.__iterator.operator<=>` + // Test `friend constexpr bool operator==(const iterator& x, const iterator& y)` { - auto view = vector | std::views::chunk(5); - assert(view.begin() < view.end()); - assert(++view.begin() < view.end()); - assert(view.begin() + 3 == view.end()); - assert(view.begin() + 3 > view.end() - 1); - assert((view.begin() <=> view.end()) == std::strong_ordering::less); - assert((view.begin() + 1 <=> view.end() - 2) == std::strong_ordering::equal); - assert((view.end() <=> view.begin()) == std::strong_ordering::greater); + assert(chunked.begin() == chunked.begin()); + assert(chunked.end() == chunked.end()); + } + + // Test `friend constexpr bool operator<(const iterator& x, const iterator& y)` + { + assert(chunked.begin() < chunked.end()); + } + + // Test `friend constexpr bool operator>(const iterator& x, const iterator& y)` + { + assert(chunked.end() > chunked.begin()); + } + + // Test `friend constexpr bool operator>=(const iterator& x, const iterator& y)` + { + assert(chunked.begin() <= chunked.begin()); + assert(chunked.begin() <= chunked.end()); + } + + // Test `friend constexpr bool operator>=(const iterator& x, const iterator& y)` + { + assert(chunked.end() >= chunked.end()); + assert(chunked.end() >= chunked.begin()); + } + + // Test `friend constexpr auto operator<=>(const iterator& x, const iterator& y)` + { + assert((chunked.begin() <=> chunked.begin()) == std::strong_ordering::equal); + assert((chunked.begin() <=> chunked.end()) == std::strong_ordering::less); + assert((chunked.end() <=> chunked.begin()) == std::strong_ordering::greater); } return true; diff --git a/libcxx/test/std/ranges/range.adaptors/range.chunk/range.chunk.iter/decrement.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.chunk/range.chunk.iter/decrement.pass.cpp index 7bf2026c1f95d..772640372ecea 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.chunk/range.chunk.iter/decrement.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.chunk/range.chunk.iter/decrement.pass.cpp @@ -8,33 +8,46 @@ // REQUIRES: std-at-least-c++23 -// std::views::chunk +// + +// constexpr iterator& operator--() +// requires bidirectional_range; +// constexpr iterator operator--(int) +// requires bidirectional_range; +// constexpr iterator& operator-=(difference_type) +// requires random_access_range; -#include #include #include +#include #include #include "test_range.h" constexpr bool test() { std::vector vector = {1, 2, 3, 4, 5, 6, 7, 8}; + auto chunked = vector | std::views::chunk(2); + + + // Test `constexpr iterator& operator--();` + { + auto it = chunked.end(); + assert(std::ranges::equal(*--it, std::vector{7, 8})); + } - // Test `chunk_view.__iterator.operator--` + // Test `constexpr iterator operator--(int)` { - auto view = vector | std::views::chunk(2); - assert(std::ranges::equal(*(--view.end()), std::vector{7, 8})); + auto it = chunked.end(); + it--; + assert(std::ranges::equal(*it, std::vector{7, 8})); } - // Test `chunk_view.__iterator.operator-` + // Test `constexpr iterator& operator-=(difference_type)` { - auto view = vector | std::views::chunk(3); - assert(view.end() - 3 == view.begin()); - assert((view.end() -= 3) == view.begin()); - assert(view.size() == 3); - assert(view.end() - view.begin() == 3); - assert(std::ranges::equal(*(view.end() - 2), std::vector{4, 5, 6})); + auto it = chunked.end(); + it -= 3; + assert(std::ranges::equal(*it, std::vector{3, 4})); } return true; diff --git a/libcxx/test/std/ranges/range.adaptors/range.chunk/range.chunk.iter/increment.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.chunk/range.chunk.iter/increment.pass.cpp index fee4b0d2dda04..30555217e030d 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.chunk/range.chunk.iter/increment.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.chunk/range.chunk.iter/increment.pass.cpp @@ -8,31 +8,43 @@ // REQUIRES: std-at-least-c++23 -// std::views::chunk +// -#include +// constexpr iterator& operator++(); +// constexpr iterator operator++(int); +// constexpr iterator& operator+=(difference_type) +// requires random_access_range; #include #include +#include #include #include "test_range.h" constexpr bool test() { std::vector vector = {1, 2, 3, 4, 5, 6, 7, 8}; + auto chunked = vector | std::views::chunk(2); + + + // Test `constexpr iterator& operator++();` + { + auto it = chunked.begin(); + assert(std::ranges::equal(*++it, std::vector{3, 4})); + } - // Test `chunk_view.__iterator.operator++` + // Test `constexpr iterator operator++(int)` { - auto view = vector | std::views::chunk(2); - assert(std::ranges::equal(*(++view.begin()), std::vector{3, 4})); + auto it = chunked.begin(); + it++; + assert(std::ranges::equal(*it, std::vector{3, 4})); } - // Test `chunk_view.__iterator.operator+` + // Test `constexpr iterator& operator+=(difference_type)` { - auto view = vector | std::views::chunk(3); - assert(view.begin() + 3 == view.end()); - assert((view.begin() += 3) == view.end()); - assert(std::ranges::equal(*(view.begin() + 2), std::vector{7, 8})); + auto it = chunked.begin(); + it += 3; + assert(std::ranges::equal(*it, std::vector{7, 8})); } return true; From 11e74667ef7ae61af578e1e9c12decdcfb80e7af Mon Sep 17 00:00:00 2001 From: anonymouspc Date: Tue, 9 Dec 2025 16:36:00 +0800 Subject: [PATCH 21/34] clang-format --- .../range.chunk/adaptor.pass.cpp | 21 ++++++++++++------- .../range.adaptors/range.chunk/base.pass.cpp | 13 ++++++------ .../range.adaptors/range.chunk/begin.pass.cpp | 8 +++---- .../range.adaptors/range.chunk/end.pass.cpp | 6 +++--- .../range.chunk.iter/compare.pass.cpp | 4 ++-- .../range.chunk.iter/decrement.pass.cpp | 4 +--- .../range.chunk.iter/increment.pass.cpp | 3 +-- 7 files changed, 30 insertions(+), 29 deletions(-) diff --git a/libcxx/test/std/ranges/range.adaptors/range.chunk/adaptor.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.chunk/adaptor.pass.cpp index 01648c9a685d8..4d8d91c0d4edb 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.chunk/adaptor.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.chunk/adaptor.pass.cpp @@ -24,37 +24,42 @@ constexpr bool test() { std::array array = {1, 2, 3, 4, 5, 6, 7, 8}; - auto view = array | std::views::all; + auto view = array | std::views::all; // Test `views::chunk(view, n)` { - std::same_as>>> decltype(auto) chunked = std::views::chunk(view, 2); + std::same_as>>> decltype(auto) chunked = + std::views::chunk(view, 2); assert(std::ranges::equal(*chunked.begin(), std::array{1, 2})); - std::same_as>>> decltype(auto) const_chunked = std::views::chunk(std::as_const(view), 2); + std::same_as>>> decltype(auto) const_chunked = + std::views::chunk(std::as_const(view), 2); assert(std::ranges::equal(*const_chunked.begin(), std::array{1, 2})); } // Test `views::chunk(n)(range)` { auto adaptor = std::views::chunk(3); - std::same_as>>> decltype(auto) chunked = adaptor(view); + std::same_as>>> decltype(auto) chunked = + adaptor(view); assert(std::ranges::equal(*chunked.begin(), std::array{1, 2, 3})); - std::same_as>>> decltype(auto) const_chunked = adaptor(std::as_const(view)); + std::same_as>>> decltype(auto) const_chunked = + adaptor(std::as_const(view)); assert(std::ranges::equal(*const_chunked.begin(), std::array{1, 2, 3})); } // Test `view | views::chunk` { - std::same_as>>> decltype(auto) chunked = view | std::views::chunk(4); + std::same_as>>> decltype(auto) chunked = + view | std::views::chunk(4); assert(std::ranges::equal(*chunked.begin(), std::array{1, 2, 3, 4})); - std::same_as>>> decltype(auto) const_chunked = + std::same_as>>> decltype(auto) const_chunked = std::as_const(view) | std::views::chunk(4); assert(std::ranges::equal(*const_chunked.begin(), std::array{1, 2, 3, 4})); } // Test `views::chunk | adaptor` { - auto adaptors = std::views::chunk(5) | std::views::join; + auto adaptors = std::views::chunk(5) | std::views::join; std::ranges::input_range auto rejoined = view | adaptors; assert(std::ranges::equal(rejoined, view)); std::ranges::input_range auto const_rejoined = std::as_const(view) | adaptors; diff --git a/libcxx/test/std/ranges/range.adaptors/range.chunk/base.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.chunk/base.pass.cpp index de845ab9700de..a28bf246a567a 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.chunk/base.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.chunk/base.pass.cpp @@ -22,20 +22,19 @@ #include "test_range.h" constexpr bool test() { - std::array array = {1, 2, 3, 4, 5, 6, 7, 8}; - auto chunked = array | std::views::chunk(3); + std::array array = {1, 2, 3, 4, 5, 6, 7, 8}; + auto chunked = array | std::views::chunk(3); auto const_chunked = std::as_const(array) | std::views::chunk(4); // Test `chunk_view.base()` { - std::same_as::iterator> decltype(auto) begin = chunked.begin().base(); - std::same_as::iterator> decltype(auto) end = chunked.end().base(); + std::same_as::iterator> decltype(auto) begin = chunked.begin().base(); + std::same_as::iterator> decltype(auto) end = chunked.end().base(); assert(begin == array.begin()); assert(end == array.end()); - - std::same_as::const_iterator> decltype(auto) const_begin = const_chunked.begin().base(); - std::same_as::const_iterator> decltype(auto) const_end = const_chunked.end().base(); + std::same_as::const_iterator> decltype(auto) const_begin = const_chunked.begin().base(); + std::same_as::const_iterator> decltype(auto) const_end = const_chunked.end().base(); assert(const_begin == std::as_const(array).begin()); assert(const_end == std::as_const(array).end()); } diff --git a/libcxx/test/std/ranges/range.adaptors/range.chunk/begin.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.chunk/begin.pass.cpp index 8725667df7159..cd42aaa4793aa 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.chunk/begin.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.chunk/begin.pass.cpp @@ -27,13 +27,13 @@ constexpr bool test() { std::vector vector = {1, 2, 3, 4, 5, 6, 7, 8}; - auto chunked = vector | std::views::chunk(3); - auto const_chunked = std::as_const(vector) | std::views::chunk(3); - auto input_chunked = input_span(vector.data(), 8) | std::views::chunk(3); + auto chunked = vector | std::views::chunk(3); + auto const_chunked = std::as_const(vector) | std::views::chunk(3); + auto input_chunked = input_span(vector.data(), 8) | std::views::chunk(3); // Test `chunk_view.begin()` when V models only input_range { - auto it = input_chunked.begin(); + auto it = input_chunked.begin(); assert(std::ranges::equal(*it, std::vector{1, 2, 3})); assert(std::ranges::equal(*++it, std::vector{4, 5, 6})); assert(std::ranges::equal(*++it, std::vector{7, 8})); diff --git a/libcxx/test/std/ranges/range.adaptors/range.chunk/end.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.chunk/end.pass.cpp index bcb81c8981e52..4e7f96e7319f7 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.chunk/end.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.chunk/end.pass.cpp @@ -29,9 +29,9 @@ constexpr bool test() { std::vector vector = {1, 2, 3, 4, 5, 6, 7, 8}; - auto chunked = vector | std::views::chunk(3); - auto const_chunked = std::as_const(vector) | std::views::chunk(3); - auto input_chunked = input_span(vector.data(), 8) | std::views::chunk(3); + auto chunked = vector | std::views::chunk(3); + auto const_chunked = std::as_const(vector) | std::views::chunk(3); + auto input_chunked = input_span(vector.data(), 8) | std::views::chunk(3); // Test `chunk_view.end()` when V models only input_range { diff --git a/libcxx/test/std/ranges/range.adaptors/range.chunk/range.chunk.iter/compare.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.chunk/range.chunk.iter/compare.pass.cpp index 6ac1e51ca4192..9b41b62cab554 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.chunk/range.chunk.iter/compare.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.chunk/range.chunk.iter/compare.pass.cpp @@ -32,8 +32,8 @@ #include "test_range.h" constexpr bool test() { - std::vector vector = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}; - auto chunked = vector | std::views::chunk(3); + std::vector vector = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}; + auto chunked = vector | std::views::chunk(3); // Test `friend constexpr bool operator==(const iterator& x, const iterator& y)` { diff --git a/libcxx/test/std/ranges/range.adaptors/range.chunk/range.chunk.iter/decrement.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.chunk/range.chunk.iter/decrement.pass.cpp index 772640372ecea..8ae43e42b64c0 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.chunk/range.chunk.iter/decrement.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.chunk/range.chunk.iter/decrement.pass.cpp @@ -17,7 +17,6 @@ // constexpr iterator& operator-=(difference_type) // requires random_access_range; - #include #include #include @@ -27,8 +26,7 @@ constexpr bool test() { std::vector vector = {1, 2, 3, 4, 5, 6, 7, 8}; - auto chunked = vector | std::views::chunk(2); - + auto chunked = vector | std::views::chunk(2); // Test `constexpr iterator& operator--();` { diff --git a/libcxx/test/std/ranges/range.adaptors/range.chunk/range.chunk.iter/increment.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.chunk/range.chunk.iter/increment.pass.cpp index 30555217e030d..48ef0a8dd885e 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.chunk/range.chunk.iter/increment.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.chunk/range.chunk.iter/increment.pass.cpp @@ -24,8 +24,7 @@ constexpr bool test() { std::vector vector = {1, 2, 3, 4, 5, 6, 7, 8}; - auto chunked = vector | std::views::chunk(2); - + auto chunked = vector | std::views::chunk(2); // Test `constexpr iterator& operator++();` { From f1f97af822ff6b4a93867bcd3f78f034fdda5d3e Mon Sep 17 00:00:00 2001 From: anonymouspc Date: Tue, 9 Dec 2025 16:49:19 +0800 Subject: [PATCH 22/34] update nodiscard tests and no_unqiue_address_tests --- .../no_unique_address.compile.pass.cpp | 5 +- .../range.chunk/nodiscard.verify.cpp | 86 +++++++++++++++++++ .../deref.nodiscard.verify.cpp | 26 ------ .../eq.nodiscard.verify.cpp | 28 ------ .../iter_move.nodiscard.verify.cpp | 26 ------ .../adaptor.nodiscard.verify.cpp | 31 ------- .../eq.nodiscard.verify.cpp | 33 ------- .../base.nodiscard.verify.cpp | 28 ------ .../begin.nodiscard.verify.cpp | 26 ------ .../range.chunk.view/end.nodiscard.verify.cpp | 26 ------ 10 files changed, 89 insertions(+), 226 deletions(-) rename libcxx/test/libcxx/ranges/range.adaptors/range.chunk/{range.chunk.view => }/no_unique_address.compile.pass.cpp (92%) create mode 100644 libcxx/test/libcxx/ranges/range.adaptors/range.chunk/nodiscard.verify.cpp delete mode 100644 libcxx/test/libcxx/ranges/range.adaptors/range.chunk/range.chunk.iterator/deref.nodiscard.verify.cpp delete mode 100644 libcxx/test/libcxx/ranges/range.adaptors/range.chunk/range.chunk.iterator/eq.nodiscard.verify.cpp delete mode 100644 libcxx/test/libcxx/ranges/range.adaptors/range.chunk/range.chunk.iterator/iter_move.nodiscard.verify.cpp delete mode 100644 libcxx/test/libcxx/ranges/range.adaptors/range.chunk/range.chunk.overview/adaptor.nodiscard.verify.cpp delete mode 100644 libcxx/test/libcxx/ranges/range.adaptors/range.chunk/range.chunk.sentinel/eq.nodiscard.verify.cpp delete mode 100644 libcxx/test/libcxx/ranges/range.adaptors/range.chunk/range.chunk.view/base.nodiscard.verify.cpp delete mode 100644 libcxx/test/libcxx/ranges/range.adaptors/range.chunk/range.chunk.view/begin.nodiscard.verify.cpp delete mode 100644 libcxx/test/libcxx/ranges/range.adaptors/range.chunk/range.chunk.view/end.nodiscard.verify.cpp diff --git a/libcxx/test/libcxx/ranges/range.adaptors/range.chunk/range.chunk.view/no_unique_address.compile.pass.cpp b/libcxx/test/libcxx/ranges/range.adaptors/range.chunk/no_unique_address.compile.pass.cpp similarity index 92% rename from libcxx/test/libcxx/ranges/range.adaptors/range.chunk/range.chunk.view/no_unique_address.compile.pass.cpp rename to libcxx/test/libcxx/ranges/range.adaptors/range.chunk/no_unique_address.compile.pass.cpp index 2b7e8effcc59e..505235bd23e0f 100644 --- a/libcxx/test/libcxx/ranges/range.adaptors/range.chunk/range.chunk.view/no_unique_address.compile.pass.cpp +++ b/libcxx/test/libcxx/ranges/range.adaptors/range.chunk/no_unique_address.compile.pass.cpp @@ -15,7 +15,6 @@ // This test ensures that we use `[[no_unique_address]]` in `chunk_view`. #include -#include #include #include #include @@ -45,7 +44,9 @@ using CV1 = std::ranges::chunk_view; // [[no_unique_address]] range_difference_t<_View> __n_ // offset: sizeof(std::ptrdiff_t) // [[no_unique_address]] range_difference_t<_View> __remainder_ // offset: sizeof(std::ptrdiff_t) // [[no_unique_address]] __non_propagating_cache> __current_ // offset: ? -// TODO: how to test this ? +// TODO: hmmm I'm a new C++ learner (having been exposed to C++ 2 years) +// and I do not know about the memory layout here too... +// What is the layout like? using CV2 = std::ranges::chunk_view; // Expected CV2 (with View >= forward) layout: diff --git a/libcxx/test/libcxx/ranges/range.adaptors/range.chunk/nodiscard.verify.cpp b/libcxx/test/libcxx/ranges/range.adaptors/range.chunk/nodiscard.verify.cpp new file mode 100644 index 0000000000000..acdfde03131d5 --- /dev/null +++ b/libcxx/test/libcxx/ranges/range.adaptors/range.chunk/nodiscard.verify.cpp @@ -0,0 +1,86 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// REQUIRES: std-at-least-c++23 + +// + +// Test the libc++ extension that std::ranges::chunk_view::iterator::operator* is marked as [[nodiscard]]. + +#include +#include + +void test() { + char range[6] = {'x', 'x', 'y', 'y', 'z', 'z'}; + auto view = range | std::views::chunk(2); + + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + std::views::chunk(3); + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + std::views::chunk(range, 3); + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + range | std::views::chunk(3); + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + std::views::reverse | std::views::chunk(3); + + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + view.base(); + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + std::as_const(view).base(); + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + std::move(std::as_const(view)).base(); + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + std::move(view).base(); + + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + view.begin(); + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + std::as_const(view).begin(); + + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + view.end(); + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + std::as_const(view).end(); + + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + std::views::chunk(3); + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + std::views::chunk(range, 3); + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + range | std::views::chunk(3); + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + std::views::reverse | std::views::chunk(3); + + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + *view.begin(); + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + *std::as_const(view).begin(); + + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + (view.begin() == view.end()); + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + (std::as_const(view).begin() == view.end()); + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + (view.begin() == std::as_const(view).end()); + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + (std::as_const(view).begin() == std::as_const(view).end()); + + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + (view.begin() == view.end()); + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + (std::as_const(view).begin() == view.end()); + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + (view.begin() == std::as_const(view).end()); + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + (std::as_const(view).begin() == std::as_const(view).end()); + + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + std::ranges::iter_move(view.begin()); + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + std::ranges::iter_move(std::as_const(view).begin()); +} diff --git a/libcxx/test/libcxx/ranges/range.adaptors/range.chunk/range.chunk.iterator/deref.nodiscard.verify.cpp b/libcxx/test/libcxx/ranges/range.adaptors/range.chunk/range.chunk.iterator/deref.nodiscard.verify.cpp deleted file mode 100644 index d3722f961234c..0000000000000 --- a/libcxx/test/libcxx/ranges/range.adaptors/range.chunk/range.chunk.iterator/deref.nodiscard.verify.cpp +++ /dev/null @@ -1,26 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -// REQUIRES: std-at-least-c++23 - -// - -// Test the libc++ extension that std::ranges::chunk_view::iterator::operator* is marked as [[nodiscard]]. - -#include -#include - -void test() { - char range[6] = {'x', 'x', 'y', 'y', 'z', 'z'}; - auto view = range | std::views::chunk(2); - - // clang-format off - *view.begin(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} - *std::as_const(view).begin(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} - // clang-format on -} diff --git a/libcxx/test/libcxx/ranges/range.adaptors/range.chunk/range.chunk.iterator/eq.nodiscard.verify.cpp b/libcxx/test/libcxx/ranges/range.adaptors/range.chunk/range.chunk.iterator/eq.nodiscard.verify.cpp deleted file mode 100644 index d743d1e7c40d3..0000000000000 --- a/libcxx/test/libcxx/ranges/range.adaptors/range.chunk/range.chunk.iterator/eq.nodiscard.verify.cpp +++ /dev/null @@ -1,28 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -// REQUIRES: std-at-least-c++23 - -// - -// Test the libc++ extension that std::ranges::chunk_view::iterator::operator== is marked as [[nodiscard]]. - -#include -#include - -void test() { - char16_t range[3] = {u'x', u'y', u'z'}; - auto view = range | std::views::chunk(3); - - // clang-format off - (view.begin() == view.end()); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} - (std::as_const(view).begin() == view.end()); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} - (view.begin() == std::as_const(view).end()); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} - (std::as_const(view).begin() == std::as_const(view).end()); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} - // clang-format on -} diff --git a/libcxx/test/libcxx/ranges/range.adaptors/range.chunk/range.chunk.iterator/iter_move.nodiscard.verify.cpp b/libcxx/test/libcxx/ranges/range.adaptors/range.chunk/range.chunk.iterator/iter_move.nodiscard.verify.cpp deleted file mode 100644 index b1f13ae6ee14f..0000000000000 --- a/libcxx/test/libcxx/ranges/range.adaptors/range.chunk/range.chunk.iterator/iter_move.nodiscard.verify.cpp +++ /dev/null @@ -1,26 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -// REQUIRES: std-at-least-c++23 - -// - -// Test the libc++ extension that std::ranges::chunk::iterator::iter_move is marked as [[nodiscard]]. - -#include -#include - -void test() { - long range[2] = {0L, 2L}; - auto view = range | std::views::chunk(1); - - // clang-format off - std::ranges::iter_move(view.begin()); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} - std::ranges::iter_move(std::as_const(view).begin()); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} - // clang-format on -} diff --git a/libcxx/test/libcxx/ranges/range.adaptors/range.chunk/range.chunk.overview/adaptor.nodiscard.verify.cpp b/libcxx/test/libcxx/ranges/range.adaptors/range.chunk/range.chunk.overview/adaptor.nodiscard.verify.cpp deleted file mode 100644 index 0bf8e2f99633e..0000000000000 --- a/libcxx/test/libcxx/ranges/range.adaptors/range.chunk/range.chunk.overview/adaptor.nodiscard.verify.cpp +++ /dev/null @@ -1,31 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -// REQUIRES: std-at-least-c++23 - -// - -// Test the libc++ extension that std::views::chunk is marked as [[nodiscard]]. - -#include - -void test() { - int range[9] = {1, 2, 3, 4, 5, 6, 7, 8, 9}; - - // clang-format off - std::views::chunk(3); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} - std::views::chunk(range, 3); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} - range | std::views::chunk(3); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} - std::views::reverse | std::views::chunk(3); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} - - std::views::chunk(3); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} - std::views::chunk(range, 3); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} - range | std::views::chunk(3); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} - std::views::reverse | std::views::chunk(3); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} - // clang-format on -} diff --git a/libcxx/test/libcxx/ranges/range.adaptors/range.chunk/range.chunk.sentinel/eq.nodiscard.verify.cpp b/libcxx/test/libcxx/ranges/range.adaptors/range.chunk/range.chunk.sentinel/eq.nodiscard.verify.cpp deleted file mode 100644 index 41e2072640641..0000000000000 --- a/libcxx/test/libcxx/ranges/range.adaptors/range.chunk/range.chunk.sentinel/eq.nodiscard.verify.cpp +++ /dev/null @@ -1,33 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -// REQUIRES: std-at-least-c++23 - -// - -// Test the libc++ extension that std::ranges::chunk_view::sentinel::operator== is marked as [[nodiscard]]. - -#include -#include -#include - -#include "test_iterators.h" -#include "test_range.h" - -void test() { - int range[6] = {1, 3, 4, 6, 7, 9}; - - std::ranges::chunk_view view(range, 2); - - // clang-format off - (view.begin() == view.end()); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} - (std::as_const(view).begin() == view.end()); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} - (view.begin() == std::as_const(view).end()); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} - (std::as_const(view).begin() == std::as_const(view).end()); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} - // clang-format on -} diff --git a/libcxx/test/libcxx/ranges/range.adaptors/range.chunk/range.chunk.view/base.nodiscard.verify.cpp b/libcxx/test/libcxx/ranges/range.adaptors/range.chunk/range.chunk.view/base.nodiscard.verify.cpp deleted file mode 100644 index ecd0d92aa861e..0000000000000 --- a/libcxx/test/libcxx/ranges/range.adaptors/range.chunk/range.chunk.view/base.nodiscard.verify.cpp +++ /dev/null @@ -1,28 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -// REQUIRES: std-at-least-c++23 - -// - -// Test the libc++ extension that std::ranges:chunk_view::base is marked as [[nodiscard]]. - -#include -#include - -void test() { - int range[9] = {1, 2, 3, 4, 5, 6, 7, 8, 9}; - auto view = range | std::views::chunk(3); - - // clang-format off - view.base(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} - std::as_const(view).base(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} - std::move(std::as_const(view)).base(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} - std::move(view).base(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} - // clang-format on -} diff --git a/libcxx/test/libcxx/ranges/range.adaptors/range.chunk/range.chunk.view/begin.nodiscard.verify.cpp b/libcxx/test/libcxx/ranges/range.adaptors/range.chunk/range.chunk.view/begin.nodiscard.verify.cpp deleted file mode 100644 index 02e7fc8a2686c..0000000000000 --- a/libcxx/test/libcxx/ranges/range.adaptors/range.chunk/range.chunk.view/begin.nodiscard.verify.cpp +++ /dev/null @@ -1,26 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -// REQUIRES: std-at-least-c++23 - -// - -// Test the libc++ extension that std::ranges::chunk_view::begin is marked as [[nodiscard]]. - -#include -#include - -void test() { - int range[6] = {1, 3, 4, 6, 7, 9}; - auto view = range | std::views::chunk(3); - - // clang-format off - view.begin(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} - std::as_const(view).begin(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} - // clang-format on -} diff --git a/libcxx/test/libcxx/ranges/range.adaptors/range.chunk/range.chunk.view/end.nodiscard.verify.cpp b/libcxx/test/libcxx/ranges/range.adaptors/range.chunk/range.chunk.view/end.nodiscard.verify.cpp deleted file mode 100644 index ba3c75376c526..0000000000000 --- a/libcxx/test/libcxx/ranges/range.adaptors/range.chunk/range.chunk.view/end.nodiscard.verify.cpp +++ /dev/null @@ -1,26 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -// REQUIRES: std-at-least-c++23 - -// - -// Test the libc++ extension that std::ranges::chunk_view::end is marked as [[nodiscard]]. - -#include -#include - -void test() { - int range[6] = {1, 2, 4, 5, 7, 8}; - auto view = range | std::views::chunk(3); - - // clang-format off - view.end(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} - std::as_const(view).end(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} - // clang-format on -} From 5eead26f9876e8bbc56ba35ec366ec4b7026a749 Mon Sep 17 00:00:00 2001 From: anonymouspc Date: Tue, 9 Dec 2025 16:52:28 +0800 Subject: [PATCH 23/34] clang-format --- .../no_unique_address.compile.pass.cpp | 2 +- .../range.chunk/nodiscard.verify.cpp | 52 +++++++++---------- 2 files changed, 27 insertions(+), 27 deletions(-) diff --git a/libcxx/test/libcxx/ranges/range.adaptors/range.chunk/no_unique_address.compile.pass.cpp b/libcxx/test/libcxx/ranges/range.adaptors/range.chunk/no_unique_address.compile.pass.cpp index 505235bd23e0f..b661c26e56492 100644 --- a/libcxx/test/libcxx/ranges/range.adaptors/range.chunk/no_unique_address.compile.pass.cpp +++ b/libcxx/test/libcxx/ranges/range.adaptors/range.chunk/no_unique_address.compile.pass.cpp @@ -44,7 +44,7 @@ using CV1 = std::ranges::chunk_view; // [[no_unique_address]] range_difference_t<_View> __n_ // offset: sizeof(std::ptrdiff_t) // [[no_unique_address]] range_difference_t<_View> __remainder_ // offset: sizeof(std::ptrdiff_t) // [[no_unique_address]] __non_propagating_cache> __current_ // offset: ? -// TODO: hmmm I'm a new C++ learner (having been exposed to C++ 2 years) +// TODO: hmmm I'm a pure new C++ learner (having been exposed to C++ for 2 years) // and I do not know about the memory layout here too... // What is the layout like? diff --git a/libcxx/test/libcxx/ranges/range.adaptors/range.chunk/nodiscard.verify.cpp b/libcxx/test/libcxx/ranges/range.adaptors/range.chunk/nodiscard.verify.cpp index acdfde03131d5..5e557715f4b03 100644 --- a/libcxx/test/libcxx/ranges/range.adaptors/range.chunk/nodiscard.verify.cpp +++ b/libcxx/test/libcxx/ranges/range.adaptors/range.chunk/nodiscard.verify.cpp @@ -22,65 +22,65 @@ void test() { // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} std::views::chunk(3); // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} - std::views::chunk(range, 3); + std::views::chunk(range, 3); // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} - range | std::views::chunk(3); + range | std::views::chunk(3); // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} - std::views::reverse | std::views::chunk(3); + std::views::reverse | std::views::chunk(3); // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} - view.base(); + view.base(); // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} - std::as_const(view).base(); + std::as_const(view).base(); // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} - std::move(std::as_const(view)).base(); + std::move(std::as_const(view)).base(); // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} - std::move(view).base(); + std::move(view).base(); // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} - view.begin(); + view.begin(); // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} - std::as_const(view).begin(); + std::as_const(view).begin(); // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} - view.end(); + view.end(); // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} - std::as_const(view).end(); + std::as_const(view).end(); // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} - std::views::chunk(3); + std::views::chunk(3); // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} - std::views::chunk(range, 3); + std::views::chunk(range, 3); // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} - range | std::views::chunk(3); + range | std::views::chunk(3); // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} - std::views::reverse | std::views::chunk(3); + std::views::reverse | std::views::chunk(3); // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} - *view.begin(); + *view.begin(); // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} *std::as_const(view).begin(); // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} - (view.begin() == view.end()); + (view.begin() == view.end()); // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} - (std::as_const(view).begin() == view.end()); + (std::as_const(view).begin() == view.end()); // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} - (view.begin() == std::as_const(view).end()); + (view.begin() == std::as_const(view).end()); // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} - (std::as_const(view).begin() == std::as_const(view).end()); + (std::as_const(view).begin() == std::as_const(view).end()); // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} - (view.begin() == view.end()); + (view.begin() == view.end()); // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} - (std::as_const(view).begin() == view.end()); + (std::as_const(view).begin() == view.end()); // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} - (view.begin() == std::as_const(view).end()); + (view.begin() == std::as_const(view).end()); // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} - (std::as_const(view).begin() == std::as_const(view).end()); + (std::as_const(view).begin() == std::as_const(view).end()); // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} - std::ranges::iter_move(view.begin()); + std::ranges::iter_move(view.begin()); // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} - std::ranges::iter_move(std::as_const(view).begin()); + std::ranges::iter_move(std::as_const(view).begin()); } From ca3055a0912c2c412207535d2478f0059ff54ef4 Mon Sep 17 00:00:00 2001 From: anonymous Date: Tue, 9 Dec 2025 16:57:01 +0800 Subject: [PATCH 24/34] Update libcxx/docs/ReleaseNotes/22.rst Co-authored-by: Hristo Hristov --- libcxx/docs/ReleaseNotes/22.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libcxx/docs/ReleaseNotes/22.rst b/libcxx/docs/ReleaseNotes/22.rst index 151bd6233ba60..a44fd57b624fa 100644 --- a/libcxx/docs/ReleaseNotes/22.rst +++ b/libcxx/docs/ReleaseNotes/22.rst @@ -49,7 +49,7 @@ Implemented Papers - P2835R7: Expose ``std::atomic_ref``'s object address (`Github `__) - P2944R3: Comparisons for ``reference_wrapper`` (`Github `__) - P3168R2: Give ``std::optional`` Range Support (`Github `__) -- P2442R1: Add ``std::views::chunk`` (`Github `__) +- P2442R1: P2442R1: Windowing range adaptors: ``views::chunk`` and ``views::slide`` (`Github `__) (Implemented ``views::slide`` only) Improvements and New Features ----------------------------- From dafb95ed6fac4ded98c05e269513c519556b5f2a Mon Sep 17 00:00:00 2001 From: anonymouspc Date: Tue, 9 Dec 2025 17:47:30 +0800 Subject: [PATCH 25/34] noexcept test --- libcxx/include/__ranges/chunk_view.h | 2 +- .../test/std/ranges/range.adaptors/range.chunk/adaptor.pass.cpp | 1 + libcxx/test/std/ranges/range.adaptors/range.chunk/end.pass.cpp | 1 + 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/libcxx/include/__ranges/chunk_view.h b/libcxx/include/__ranges/chunk_view.h index 2a10a3a05b792..f19d2c9ede8a7 100644 --- a/libcxx/include/__ranges/chunk_view.h +++ b/libcxx/include/__ranges/chunk_view.h @@ -194,7 +194,7 @@ class chunk_view<_View>::__inner_iterator { chunk_view* __parent_; - _LIBCPP_HIDE_FROM_ABI constexpr explicit __inner_iterator(chunk_view& __parent) + _LIBCPP_HIDE_FROM_ABI constexpr explicit __inner_iterator(chunk_view& __parent) noexcept : __parent_(std::addressof(__parent)) {} public: diff --git a/libcxx/test/std/ranges/range.adaptors/range.chunk/adaptor.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.chunk/adaptor.pass.cpp index 4d8d91c0d4edb..4cd5b671bdee2 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.chunk/adaptor.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.chunk/adaptor.pass.cpp @@ -38,6 +38,7 @@ constexpr bool test() { // Test `views::chunk(n)(range)` { + static_assert(noexcept(std::views::chunk(2))); auto adaptor = std::views::chunk(3); std::same_as>>> decltype(auto) chunked = adaptor(view); diff --git a/libcxx/test/std/ranges/range.adaptors/range.chunk/end.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.chunk/end.pass.cpp index 4e7f96e7319f7..5efb5e56af923 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.chunk/end.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.chunk/end.pass.cpp @@ -35,6 +35,7 @@ constexpr bool test() { // Test `chunk_view.end()` when V models only input_range { + static_assert(noexcept(input_chunked.end())); [[maybe_unused]] std::same_as auto it = input_chunked.end(); } From 996918dcb021689e8e17c47a90e3954ca6d1efa9 Mon Sep 17 00:00:00 2001 From: anonymouspc Date: Tue, 9 Dec 2025 18:55:45 +0800 Subject: [PATCH 26/34] add nested-iterator tests --- .../range.chunk.iter/compare.pass.cpp | 52 ++++++++++--- .../range.chunk.iter/deref.pass.cpp | 76 +++++++++++++++++++ .../range.chunk.iter/increment.pass.cpp | 45 ++++++++++- .../ranges/range.adaptors/range.chunk/types.h | 8 +- 4 files changed, 161 insertions(+), 20 deletions(-) create mode 100644 libcxx/test/std/ranges/range.adaptors/range.chunk/range.chunk.iter/deref.pass.cpp diff --git a/libcxx/test/std/ranges/range.adaptors/range.chunk/range.chunk.iter/compare.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.chunk/range.chunk.iter/compare.pass.cpp index 9b41b62cab554..66c689a53d1e1 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.chunk/range.chunk.iter/compare.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.chunk/range.chunk.iter/compare.pass.cpp @@ -10,30 +10,58 @@ // -// friend constexpr bool operator==(const iterator& x, const iterator& y) -// friend constexpr bool operator<(const iterator& x, const iterator& y) -// requires random_access_range; -// friend constexpr bool operator>(const iterator& x, const iterator& y) -// requires random_access_range; -// friend constexpr bool operator<=(const iterator& x, const iterator& y) -// requires random_access_range; -// friend constexpr bool operator>=(const iterator& x, const iterator& y) -// requires random_access_range; -// friend constexpr auto operator<=>(const iterator& x, const iterator& y) -// requires random_access_range && -// three_way_comparable>; +// V models only input_range +// friend constexpr bool opreator==(const outer_iterator& x, default_sentinel_t); +// friend constexpr difference_type operator-(default_sentinel_t t, const outer_iterator& i) +// requires sized_sentinel_for, iterator_t>; +// friend constexpr difference_type operator-(const outer_iterator& i, default_sentinel_t t) +// requires sized_sentinel_for, iterator_t>; + +// V models forward_range +// friend constexpr bool operator==(const iterator& x, const iterator& y) +// friend constexpr bool operator<(const iterator& x, const iterator& y) +// requires random_access_range; +// friend constexpr bool operator>(const iterator& x, const iterator& y) +// requires random_access_range; +// friend constexpr bool operator<=(const iterator& x, const iterator& y) +// requires random_access_range; +// friend constexpr bool operator>=(const iterator& x, const iterator& y) +// requires random_access_range; +// friend constexpr auto operator<=>(const iterator& x, const iterator& y) +// requires random_access_range && +// three_way_comparable>; #include #include #include +#include #include #include #include "test_range.h" +#include "../types.h" constexpr bool test() { std::vector vector = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}; auto chunked = vector | std::views::chunk(3); + auto input_chunked = input_span(vector) | std::views::chunk(3); + + // Test `friend constexpr bool opreator==(const outer_iterator& x, default_sentinel_t)` + { + auto it = input_chunked.begin(); + std::ranges::advance(it, 4); + assert(it == std::default_sentinel); + } + + // Test `friend constexpr difference_type operator-(default_sentinel_t t, const outer_iterator& i)` + { + assert(input_chunked.end() - input_chunked.begin() == 4); + } + + // Test `friend constexpr difference_type operator-(const outer_iterator& i, default_sentinel_t)` + { + assert(input_chunked.begin() - input_chunked.end() == -4); + } // Test `friend constexpr bool operator==(const iterator& x, const iterator& y)` { diff --git a/libcxx/test/std/ranges/range.adaptors/range.chunk/range.chunk.iter/deref.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.chunk/range.chunk.iter/deref.pass.cpp new file mode 100644 index 0000000000000..e45e6b3ea1b10 --- /dev/null +++ b/libcxx/test/std/ranges/range.adaptors/range.chunk/range.chunk.iter/deref.pass.cpp @@ -0,0 +1,76 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// REQUIRES: std-at-least-c++23 + +// + +// V models only input_range: +// constexpr value_type outer_iterator::operator*() const; +// constexpr inner_iterator outer_iterator::value_type::begin() const noexcept; +// constexpr default_sentinel_t outer_iterator::value_type::end() const noexcept; +// constexpr range_reference_v inner_iterator::operator*() const; + +// V models forward_range: +// constexpr value_type iterator::operator*() const; + +#include +#include +#include +#include +#include +#include + +#include "test_range.h" +#include "../types.h" + +constexpr bool test() { + std::vector vector = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}; + auto chunked = vector | std::views::chunk(3); + auto input_chunked = input_span(vector) | std::views::chunk(3); + + // Test `constexpr value_type outer_iterator::operator*() const` + { + static_assert(std::ranges::input_range); + } + + // Test `constexpr inner_iterator outer_iterator::value_type::begin() const noexcept` + { + auto inner = *input_chunked.begin(); + assert(inner.begin().base() == vector.begin()); + static_assert(noexcept(inner.begin())); + } + + // Test `constexpr default_sentinel_t outer_iterator::value_type::end() const noexcept` + { + auto inner = *input_chunked.begin(); + [[maybe_unused]] std::same_as auto it = inner.end(); + static_assert(noexcept((inner.end()))); + } + + // Test `constexpr range_reference_v inner_iterator::operator*() const` + { + std::same_as decltype(auto) v = *(*chunked.begin()).begin(); + assert(v == 1); + } + + // Test `constexpr value_type iterator::operator*() const` + { + auto inner = *input_chunked.begin(); + assert(inner.begin().base() == vector.begin()); + } + + return true; +} + +int main(int, char**) { + test(); + static_assert(test()); + + return 0; +} diff --git a/libcxx/test/std/ranges/range.adaptors/range.chunk/range.chunk.iter/increment.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.chunk/range.chunk.iter/increment.pass.cpp index 48ef0a8dd885e..d0c9aeff848eb 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.chunk/range.chunk.iter/increment.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.chunk/range.chunk.iter/increment.pass.cpp @@ -10,10 +10,17 @@ // -// constexpr iterator& operator++(); -// constexpr iterator operator++(int); -// constexpr iterator& operator+=(difference_type) -// requires random_access_range; +// V models only input_range +// constexpr outer_iterator& operator++(); +// constexpr void operator++(int); +// constexpr inner_iterator& operator++(); +// constexpr void operator++(int); + +// V models forward_range +// constexpr iterator& operator++(); +// constexpr iterator operator++(int); +// constexpr iterator& operator+=(difference_type) +// requires random_access_range; #include #include @@ -21,10 +28,40 @@ #include #include "test_range.h" +#include "../types.h" constexpr bool test() { std::vector vector = {1, 2, 3, 4, 5, 6, 7, 8}; auto chunked = vector | std::views::chunk(2); + auto input_chunked = input_span(vector) | std::views::chunk(2); + + // Test `constexpr outer_iterator& operator++();` + { + auto it = input_chunked.begin(); + assert(std::ranges::equal(*++it, std::vector{3, 4})); + } + + // Test `constexpr void operator++(int);` + { + auto it = input_chunked.begin(); + static_assert(std::same_as); + it++; + assert(std::ranges::equal(*it, std::vector{3, 4})); + } + + // Test `constexpr inner_iterator& operator++();` + { + auto it = (*input_chunked.begin()).begin(); + assert(*++it == 2); + } + + // Test `constexpr inner_iterator& operator++();` + { + auto it = (*input_chunked.begin()).begin(); + static_assert(std::same_as); + it++; + assert(*it == 2); + } // Test `constexpr iterator& operator++();` { diff --git a/libcxx/test/std/ranges/range.adaptors/range.chunk/types.h b/libcxx/test/std/ranges/range.adaptors/range.chunk/types.h index f5c09215b8b4c..09d16c9a48af0 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.chunk/types.h +++ b/libcxx/test/std/ranges/range.adaptors/range.chunk/types.h @@ -23,10 +23,10 @@ struct input_span : std::span { constexpr iterator() = default; constexpr iterator(std::span::iterator i) : std::span::iterator(i) {} constexpr auto operator*() const { return std::span::iterator::operator*(); } - friend constexpr auto operator+(iterator, auto) = delete; - friend constexpr auto operator+(auto, iterator) = delete; - friend constexpr auto operator-(iterator, auto) = delete; - friend constexpr auto operator-(auto, iterator) = delete; + friend constexpr auto operator+(iterator, std::span::difference_type) = delete; + friend constexpr auto operator+(std::span::difference_type, iterator) = delete; + friend constexpr auto operator-(iterator, std::span::difference_type) = delete; + friend constexpr auto operator-(std::span::difference_type, iterator) = delete; friend constexpr iterator& operator++(iterator& self) { ++static_cast::iterator&>(self); return self; From 4d828b6df5eb157f90fa5e55a048ee73313b453c Mon Sep 17 00:00:00 2001 From: anonymouspc Date: Tue, 9 Dec 2025 19:00:48 +0800 Subject: [PATCH 27/34] clang-format --- .../range.chunk/range.chunk.iter/deref.pass.cpp | 8 ++++---- .../range.chunk/range.chunk.iter/increment.pass.cpp | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/libcxx/test/std/ranges/range.adaptors/range.chunk/range.chunk.iter/deref.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.chunk/range.chunk.iter/deref.pass.cpp index e45e6b3ea1b10..54a0f8a3c37dc 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.chunk/range.chunk.iter/deref.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.chunk/range.chunk.iter/deref.pass.cpp @@ -31,8 +31,8 @@ constexpr bool test() { std::vector vector = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}; - auto chunked = vector | std::views::chunk(3); - auto input_chunked = input_span(vector) | std::views::chunk(3); + auto chunked = vector | std::views::chunk(3); + auto input_chunked = input_span(vector) | std::views::chunk(3); // Test `constexpr value_type outer_iterator::operator*() const` { @@ -48,7 +48,7 @@ constexpr bool test() { // Test `constexpr default_sentinel_t outer_iterator::value_type::end() const noexcept` { - auto inner = *input_chunked.begin(); + auto inner = *input_chunked.begin(); [[maybe_unused]] std::same_as auto it = inner.end(); static_assert(noexcept((inner.end()))); } @@ -57,7 +57,7 @@ constexpr bool test() { { std::same_as decltype(auto) v = *(*chunked.begin()).begin(); assert(v == 1); - } + } // Test `constexpr value_type iterator::operator*() const` { diff --git a/libcxx/test/std/ranges/range.adaptors/range.chunk/range.chunk.iter/increment.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.chunk/range.chunk.iter/increment.pass.cpp index d0c9aeff848eb..72c88359503b1 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.chunk/range.chunk.iter/increment.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.chunk/range.chunk.iter/increment.pass.cpp @@ -40,7 +40,7 @@ constexpr bool test() { auto it = input_chunked.begin(); assert(std::ranges::equal(*++it, std::vector{3, 4})); } - + // Test `constexpr void operator++(int);` { auto it = input_chunked.begin(); From 73a7a4818fbe0d45b1a835961bcacfcd6b46c56b Mon Sep 17 00:00:00 2001 From: anonymouspc Date: Tue, 9 Dec 2025 20:07:18 +0800 Subject: [PATCH 28/34] small fix --- .../range.chunk/range.chunk.iter/deref.pass.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libcxx/test/std/ranges/range.adaptors/range.chunk/range.chunk.iter/deref.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.chunk/range.chunk.iter/deref.pass.cpp index 54a0f8a3c37dc..362b935f6afc0 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.chunk/range.chunk.iter/deref.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.chunk/range.chunk.iter/deref.pass.cpp @@ -42,7 +42,7 @@ constexpr bool test() { // Test `constexpr inner_iterator outer_iterator::value_type::begin() const noexcept` { auto inner = *input_chunked.begin(); - assert(inner.begin().base() == vector.begin()); + assert(*inner.begin() == *vector.begin()); static_assert(noexcept(inner.begin())); } @@ -62,7 +62,7 @@ constexpr bool test() { // Test `constexpr value_type iterator::operator*() const` { auto inner = *input_chunked.begin(); - assert(inner.begin().base() == vector.begin()); + assert(*inner.begin() == *vector.begin()); } return true; From dad914f537a0ac449db14e25b9496795af760842 Mon Sep 17 00:00:00 2001 From: anonymouspc Date: Thu, 11 Dec 2025 13:29:00 +0800 Subject: [PATCH 29/34] fix no_unique_address --- .../no_unique_address.compile.pass.cpp | 39 ++++++++----------- 1 file changed, 17 insertions(+), 22 deletions(-) diff --git a/libcxx/test/libcxx/ranges/range.adaptors/range.chunk/no_unique_address.compile.pass.cpp b/libcxx/test/libcxx/ranges/range.adaptors/range.chunk/no_unique_address.compile.pass.cpp index b661c26e56492..d1793e282d084 100644 --- a/libcxx/test/libcxx/ranges/range.adaptors/range.chunk/no_unique_address.compile.pass.cpp +++ b/libcxx/test/libcxx/ranges/range.adaptors/range.chunk/no_unique_address.compile.pass.cpp @@ -22,35 +22,30 @@ #include "test_iterators.h" #include "test_range.h" -using input_view = std::views::all_t>; +struct input_view { + cpp20_input_iterator begin() const; + sentinel_wrapper> end() const; +}; +template <> inline constexpr bool std::ranges::enable_view = true; static_assert(std::ranges::input_range && !std::ranges::forward_range); -struct forward_view : std::ranges::view_base { - std::string* begin() const; - std::string* end() const; +struct forward_view { + int* begin() const; + int* end() const; }; +template <> inline constexpr bool std::ranges::enable_view = true; static_assert(std::ranges::forward_range); -static_assert(std::is_reference_v>); - -template -struct Test { - [[no_unique_address]] View view; - unsigned char pad; -}; using CV1 = std::ranges::chunk_view; // Expected CV1 (with View == input) layout: -// [[no_unique_address]] _View __base_ // offset: 0 -// [[no_unique_address]] range_difference_t<_View> __n_ // offset: sizeof(std::ptrdiff_t) -// [[no_unique_address]] range_difference_t<_View> __remainder_ // offset: sizeof(std::ptrdiff_t) -// [[no_unique_address]] __non_propagating_cache> __current_ // offset: ? -// TODO: hmmm I'm a pure new C++ learner (having been exposed to C++ for 2 years) -// and I do not know about the memory layout here too... -// What is the layout like? +// [[no_unique_address]] _View __base_ // size: 0 +// [[no_unique_address]] range_difference_t<_View> __n_ // size: sizeof(ptrdiff_t) +// [[no_unique_address]] range_difference_t<_View> __remainder_ // size: sizeof(ptrdiff_t) +// [[no_unique_address]] __non_propagating_cache> __current_ // size: sizeof(__non_propagating_cache>), align: std::ptrdiff_t +static_assert(sizeof(CV1) == /*sizeof(__base_) == 0 + */ sizeof(std::ptrdiff_t) * 2 + sizeof(std::ranges::__non_propagating_cache>)); using CV2 = std::ranges::chunk_view; // Expected CV2 (with View >= forward) layout: -// [[no_unique_address]] _View __base_ // offset: 0 -// [[no_unique_address]] range_difference_t<_View> // offset: sizeof(std::ptrdiff_t) -static_assert(sizeof(CV2) == sizeof(std::ptrdiff_t)); -static_assert(sizeof(Test) == sizeof(std::ptrdiff_t) * 2); +// [[no_unique_address]] _View __base_ // size: 0 +// [[no_unique_address]] range_difference_t<_View> // size: sizeof(ptrdiff_t) +static_assert(sizeof(CV2) == /*sizeof(__base_) == 0 + */ sizeof(std::ptrdiff_t)); From 52a93dcef5fea689d6a6b913406256db02291397 Mon Sep 17 00:00:00 2001 From: anonymouspc Date: Thu, 11 Dec 2025 13:47:18 +0800 Subject: [PATCH 30/34] get rid of auto --- .../range.chunk/adaptor.pass.cpp | 8 ++++---- .../range.adaptors/range.chunk/base.pass.cpp | 6 +++--- .../range.adaptors/range.chunk/begin.pass.cpp | 13 +++++++------ .../range.chunk/ctad.compile.pass.cpp | 18 +++++++++++------- .../range.adaptors/range.chunk/end.pass.cpp | 10 +++++----- .../range.chunk/general.pass.cpp | 2 +- .../range.chunk.iter/compare.pass.cpp | 6 +++--- .../range.chunk.iter/decrement.pass.cpp | 9 +++++---- .../range.chunk.iter/deref.pass.cpp | 19 ++++++++++--------- .../range.chunk.iter/increment.pass.cpp | 19 ++++++++++--------- 10 files changed, 59 insertions(+), 51 deletions(-) diff --git a/libcxx/test/std/ranges/range.adaptors/range.chunk/adaptor.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.chunk/adaptor.pass.cpp index 4cd5b671bdee2..edd3c77b38e96 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.chunk/adaptor.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.chunk/adaptor.pass.cpp @@ -23,8 +23,8 @@ #include "types.h" constexpr bool test() { - std::array array = {1, 2, 3, 4, 5, 6, 7, 8}; - auto view = array | std::views::all; + std::array array = {1, 2, 3, 4, 5, 6, 7, 8}; + std::ranges::ref_view> view = array | std::views::all; // Test `views::chunk(view, n)` { @@ -39,7 +39,7 @@ constexpr bool test() { // Test `views::chunk(n)(range)` { static_assert(noexcept(std::views::chunk(2))); - auto adaptor = std::views::chunk(3); + /*__pipable*/ auto adaptor = std::views::chunk(3); std::same_as>>> decltype(auto) chunked = adaptor(view); assert(std::ranges::equal(*chunked.begin(), std::array{1, 2, 3})); @@ -60,7 +60,7 @@ constexpr bool test() { // Test `views::chunk | adaptor` { - auto adaptors = std::views::chunk(5) | std::views::join; + /*__pipable*/ auto adaptors = std::views::chunk(5) | std::views::join; std::ranges::input_range auto rejoined = view | adaptors; assert(std::ranges::equal(rejoined, view)); std::ranges::input_range auto const_rejoined = std::as_const(view) | adaptors; diff --git a/libcxx/test/std/ranges/range.adaptors/range.chunk/base.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.chunk/base.pass.cpp index a28bf246a567a..383b314a5deb0 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.chunk/base.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.chunk/base.pass.cpp @@ -22,9 +22,9 @@ #include "test_range.h" constexpr bool test() { - std::array array = {1, 2, 3, 4, 5, 6, 7, 8}; - auto chunked = array | std::views::chunk(3); - auto const_chunked = std::as_const(array) | std::views::chunk(4); + std::array array = {1, 2, 3, 4, 5, 6, 7, 8}; + std::ranges::chunk_view>> chunked = array | std::views::chunk(3); + std::ranges::chunk_view>> const_chunked = std::as_const(array) | std::views::chunk(4); // Test `chunk_view.base()` { diff --git a/libcxx/test/std/ranges/range.adaptors/range.chunk/begin.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.chunk/begin.pass.cpp index cd42aaa4793aa..02828a8350771 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.chunk/begin.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.chunk/begin.pass.cpp @@ -19,6 +19,7 @@ #include #include +#include #include #include @@ -27,13 +28,13 @@ constexpr bool test() { std::vector vector = {1, 2, 3, 4, 5, 6, 7, 8}; - auto chunked = vector | std::views::chunk(3); - auto const_chunked = std::as_const(vector) | std::views::chunk(3); - auto input_chunked = input_span(vector.data(), 8) | std::views::chunk(3); + std::ranges::chunk_view>> chunked = vector | std::views::chunk(3); + std::ranges::chunk_view>> const_chunked = std::as_const(vector) | std::views::chunk(3); + std::ranges::chunk_view> input_chunked = input_span(vector.data(), 8) | std::views::chunk(3); // Test `chunk_view.begin()` when V models only input_range { - auto it = input_chunked.begin(); + /*chunk_view::__outer_iterator*/ std::input_iterator auto it = input_chunked.begin(); assert(std::ranges::equal(*it, std::vector{1, 2, 3})); assert(std::ranges::equal(*++it, std::vector{4, 5, 6})); assert(std::ranges::equal(*++it, std::vector{7, 8})); @@ -42,12 +43,12 @@ constexpr bool test() { // Test `chunk_view.begin()` when V models forward_range { - auto it = chunked.begin(); + /*chunk_view::__iterator*/ std::forward_iterator auto it = chunked.begin(); assert(std::ranges::equal(*it, std::vector{1, 2, 3})); assert(std::ranges::equal(*++it, std::vector{4, 5, 6})); assert(std::ranges::equal(*++it, std::vector{7, 8})); assert(++it == chunked.end()); - auto const_it = const_chunked.begin(); + /*chunk_view::__iterator*/ std::forward_iterator auto const_it = const_chunked.begin(); assert(std::ranges::equal(*const_it, std::vector{1, 2, 3})); assert(std::ranges::equal(*++const_it, std::vector{4, 5, 6})); assert(std::ranges::equal(*++const_it, std::vector{7, 8})); diff --git a/libcxx/test/std/ranges/range.adaptors/range.chunk/ctad.compile.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.chunk/ctad.compile.pass.cpp index 862782e0a835d..9bf2baba58c78 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.chunk/ctad.compile.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.chunk/ctad.compile.pass.cpp @@ -38,14 +38,18 @@ void test_ctad() { range r; borrowed_range br; - static_assert(std::same_as>); - static_assert(std::same_as>); - static_assert( - std::same_as< decltype(std::ranges::chunk_view(r, 0)), std::ranges::chunk_view>>); + // clang-format off + static_assert(std::same_as>); + static_assert(std::same_as>); + static_assert(std::same_as>>); static_assert(std::same_as>>); + std::ranges::chunk_view>>); static_assert(std::same_as>>); + std::ranges::chunk_view>>); static_assert(std::same_as>>); + std::ranges::chunk_view>>); + // clang-format on } diff --git a/libcxx/test/std/ranges/range.adaptors/range.chunk/end.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.chunk/end.pass.cpp index 5efb5e56af923..20d96ce29fc44 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.chunk/end.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.chunk/end.pass.cpp @@ -29,9 +29,9 @@ constexpr bool test() { std::vector vector = {1, 2, 3, 4, 5, 6, 7, 8}; - auto chunked = vector | std::views::chunk(3); - auto const_chunked = std::as_const(vector) | std::views::chunk(3); - auto input_chunked = input_span(vector.data(), 8) | std::views::chunk(3); + std::ranges::chunk_view>> chunked = vector | std::views::chunk(3); + std::ranges::chunk_view>> const_chunked = std::as_const(vector) | std::views::chunk(3); + std::ranges::chunk_view> input_chunked = input_span(vector.data(), 8) | std::views::chunk(3); // Test `chunk_view.end()` when V models only input_range { @@ -41,12 +41,12 @@ constexpr bool test() { // Test `chunk_view.end()` when V models forward_range { - std::random_access_iterator auto it = chunked.end(); + /*chunk_view::__iterator*/ std::forward_iterator auto it = chunked.end(); assert(std::ranges::equal(*--it, std::vector{7, 8})); assert(std::ranges::equal(*--it, std::vector{4, 5, 6})); assert(std::ranges::equal(*--it, std::vector{1, 2, 3})); assert(it == chunked.begin()); - std::random_access_iterator auto const_it = const_chunked.end(); + /*chunk_view::__iterator*/ std::forward_iterator auto const_it = const_chunked.end(); assert(std::ranges::equal(*--const_it, std::vector{7, 8})); assert(std::ranges::equal(*--const_it, std::vector{4, 5, 6})); assert(std::ranges::equal(*--const_it, std::vector{1, 2, 3})); diff --git a/libcxx/test/std/ranges/range.adaptors/range.chunk/general.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.chunk/general.pass.cpp index 7eaffb3bf0293..89891bc093080 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.chunk/general.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.chunk/general.pass.cpp @@ -20,7 +20,7 @@ #include "test_range.h" constexpr bool test() { - auto str = std::string_view("Cheese the chicken chunk by chunk on truck by truck"); + std::string_view str = "Cheese with chicken chunk by chunk on truck with my trick"; // clang-format off auto str2 = str | std::views::chunk(4) diff --git a/libcxx/test/std/ranges/range.adaptors/range.chunk/range.chunk.iter/compare.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.chunk/range.chunk.iter/compare.pass.cpp index 66c689a53d1e1..0ea21267f8548 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.chunk/range.chunk.iter/compare.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.chunk/range.chunk.iter/compare.pass.cpp @@ -43,12 +43,12 @@ constexpr bool test() { std::vector vector = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}; - auto chunked = vector | std::views::chunk(3); - auto input_chunked = input_span(vector) | std::views::chunk(3); + std::ranges::chunk_view>> chunked = vector | std::views::chunk(3); + std::ranges::chunk_view> input_chunked = input_span(vector) | std::views::chunk(3); // Test `friend constexpr bool opreator==(const outer_iterator& x, default_sentinel_t)` { - auto it = input_chunked.begin(); + /*chunk_view::__outer_iterator*/ std::input_iterator auto it = input_chunked.begin(); std::ranges::advance(it, 4); assert(it == std::default_sentinel); } diff --git a/libcxx/test/std/ranges/range.adaptors/range.chunk/range.chunk.iter/decrement.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.chunk/range.chunk.iter/decrement.pass.cpp index 8ae43e42b64c0..20fda6ff26f6b 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.chunk/range.chunk.iter/decrement.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.chunk/range.chunk.iter/decrement.pass.cpp @@ -19,6 +19,7 @@ #include #include +#include #include #include @@ -26,24 +27,24 @@ constexpr bool test() { std::vector vector = {1, 2, 3, 4, 5, 6, 7, 8}; - auto chunked = vector | std::views::chunk(2); + std::ranges::chunk_view>> chunked = vector | std::views::chunk(2); // Test `constexpr iterator& operator--();` { - auto it = chunked.end(); + /*chunk_view::__outer_iterator*/ std::bidirectional_iterator auto it = chunked.end(); assert(std::ranges::equal(*--it, std::vector{7, 8})); } // Test `constexpr iterator operator--(int)` { - auto it = chunked.end(); + /*chunk_view::__outer_iterator*/ std::bidirectional_iterator auto it = chunked.end(); it--; assert(std::ranges::equal(*it, std::vector{7, 8})); } // Test `constexpr iterator& operator-=(difference_type)` { - auto it = chunked.end(); + /*chunk_view::__iterator*/ std::random_access_iterator auto it = chunked.end(); it -= 3; assert(std::ranges::equal(*it, std::vector{3, 4})); } diff --git a/libcxx/test/std/ranges/range.adaptors/range.chunk/range.chunk.iter/deref.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.chunk/range.chunk.iter/deref.pass.cpp index 362b935f6afc0..cd317e601a9a2 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.chunk/range.chunk.iter/deref.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.chunk/range.chunk.iter/deref.pass.cpp @@ -31,8 +31,8 @@ constexpr bool test() { std::vector vector = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}; - auto chunked = vector | std::views::chunk(3); - auto input_chunked = input_span(vector) | std::views::chunk(3); + std::ranges::chunk_view>> chunked = vector | std::views::chunk(3); + std::ranges::chunk_view> input_chunked = input_span(vector) | std::views::chunk(3); // Test `constexpr value_type outer_iterator::operator*() const` { @@ -41,28 +41,29 @@ constexpr bool test() { // Test `constexpr inner_iterator outer_iterator::value_type::begin() const noexcept` { - auto inner = *input_chunked.begin(); + /*chunk_view::__outer_iterator::value_type*/ std::ranges::input_range auto inner = *input_chunked.begin(); assert(*inner.begin() == *vector.begin()); static_assert(noexcept(inner.begin())); } // Test `constexpr default_sentinel_t outer_iterator::value_type::end() const noexcept` { - auto inner = *input_chunked.begin(); + /*chunk_view::__outer_iterator::value_type*/ std::ranges::input_range auto inner = *input_chunked.begin(); [[maybe_unused]] std::same_as auto it = inner.end(); static_assert(noexcept((inner.end()))); } - // Test `constexpr range_reference_v inner_iterator::operator*() const` + // Test `constexpr value_type iterator::operator*() const` { - std::same_as decltype(auto) v = *(*chunked.begin()).begin(); + /*chunk_view::__inner_iterator*/ std::input_iterator auto it = (*input_chunked.begin()).begin(); + std::same_as decltype(auto) v = *it; assert(v == 1); } - // Test `constexpr value_type iterator::operator*() const` + // Test `constexpr range_reference_v inner_iterator::operator*() const` { - auto inner = *input_chunked.begin(); - assert(*inner.begin() == *vector.begin()); + std::same_as decltype(auto) v = *(*chunked.begin()).begin(); + assert(v == 1); } return true; diff --git a/libcxx/test/std/ranges/range.adaptors/range.chunk/range.chunk.iter/increment.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.chunk/range.chunk.iter/increment.pass.cpp index 72c88359503b1..df99cc03fc831 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.chunk/range.chunk.iter/increment.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.chunk/range.chunk.iter/increment.pass.cpp @@ -24,6 +24,7 @@ #include #include +#include #include #include @@ -32,18 +33,18 @@ constexpr bool test() { std::vector vector = {1, 2, 3, 4, 5, 6, 7, 8}; - auto chunked = vector | std::views::chunk(2); - auto input_chunked = input_span(vector) | std::views::chunk(2); + std::ranges::chunk_view>> chunked = vector | std::views::chunk(2); + std::ranges::chunk_view> input_chunked = input_span(vector) | std::views::chunk(2); // Test `constexpr outer_iterator& operator++();` { - auto it = input_chunked.begin(); + /*chunk_view::__outer_iterator*/ std::input_iterator auto it = input_chunked.begin(); assert(std::ranges::equal(*++it, std::vector{3, 4})); } // Test `constexpr void operator++(int);` { - auto it = input_chunked.begin(); + /*chunk_view::__outer_iterator*/ std::input_iterator auto it = input_chunked.begin(); static_assert(std::same_as); it++; assert(std::ranges::equal(*it, std::vector{3, 4})); @@ -51,13 +52,13 @@ constexpr bool test() { // Test `constexpr inner_iterator& operator++();` { - auto it = (*input_chunked.begin()).begin(); + /*chunk_view::__inner_iterator*/ std::input_iterator auto it = (*input_chunked.begin()).begin(); assert(*++it == 2); } // Test `constexpr inner_iterator& operator++();` { - auto it = (*input_chunked.begin()).begin(); + /*chunk_view::__inner_iterator*/ std::input_iterator auto it = (*input_chunked.begin()).begin(); static_assert(std::same_as); it++; assert(*it == 2); @@ -65,20 +66,20 @@ constexpr bool test() { // Test `constexpr iterator& operator++();` { - auto it = chunked.begin(); + /*chunk_view::__iterator*/ std::forward_iterator auto it = chunked.begin(); assert(std::ranges::equal(*++it, std::vector{3, 4})); } // Test `constexpr iterator operator++(int)` { - auto it = chunked.begin(); + /*chunk_view::__iterator*/ std::forward_iterator auto it = chunked.begin(); it++; assert(std::ranges::equal(*it, std::vector{3, 4})); } // Test `constexpr iterator& operator+=(difference_type)` { - auto it = chunked.begin(); + /*chunk_view::__iterator*/ std::random_access_iterator auto it = chunked.begin(); it += 3; assert(std::ranges::equal(*it, std::vector{7, 8})); } From f08769e4e4a1ffd6b012c554a48580e569771e5d Mon Sep 17 00:00:00 2001 From: anonymouspc Date: Thu, 11 Dec 2025 13:47:58 +0800 Subject: [PATCH 31/34] clang-format --- .../range.chunk/no_unique_address.compile.pass.cpp | 9 ++++++--- .../ranges/range.adaptors/range.chunk/adaptor.pass.cpp | 6 +++--- .../std/ranges/range.adaptors/range.chunk/base.pass.cpp | 7 ++++--- .../std/ranges/range.adaptors/range.chunk/begin.pass.cpp | 3 ++- .../std/ranges/range.adaptors/range.chunk/end.pass.cpp | 3 ++- .../range.chunk/range.chunk.iter/decrement.pass.cpp | 2 +- .../range.chunk/range.chunk.iter/deref.pass.cpp | 4 ++-- .../range.chunk/range.chunk.iter/increment.pass.cpp | 2 +- 8 files changed, 21 insertions(+), 15 deletions(-) diff --git a/libcxx/test/libcxx/ranges/range.adaptors/range.chunk/no_unique_address.compile.pass.cpp b/libcxx/test/libcxx/ranges/range.adaptors/range.chunk/no_unique_address.compile.pass.cpp index d1793e282d084..f4ffd69f8f519 100644 --- a/libcxx/test/libcxx/ranges/range.adaptors/range.chunk/no_unique_address.compile.pass.cpp +++ b/libcxx/test/libcxx/ranges/range.adaptors/range.chunk/no_unique_address.compile.pass.cpp @@ -26,14 +26,16 @@ struct input_view { cpp20_input_iterator begin() const; sentinel_wrapper> end() const; }; -template <> inline constexpr bool std::ranges::enable_view = true; +template <> +inline constexpr bool std::ranges::enable_view = true; static_assert(std::ranges::input_range && !std::ranges::forward_range); struct forward_view { int* begin() const; int* end() const; }; -template <> inline constexpr bool std::ranges::enable_view = true; +template <> +inline constexpr bool std::ranges::enable_view = true; static_assert(std::ranges::forward_range); using CV1 = std::ranges::chunk_view; @@ -42,7 +44,8 @@ using CV1 = std::ranges::chunk_view; // [[no_unique_address]] range_difference_t<_View> __n_ // size: sizeof(ptrdiff_t) // [[no_unique_address]] range_difference_t<_View> __remainder_ // size: sizeof(ptrdiff_t) // [[no_unique_address]] __non_propagating_cache> __current_ // size: sizeof(__non_propagating_cache>), align: std::ptrdiff_t -static_assert(sizeof(CV1) == /*sizeof(__base_) == 0 + */ sizeof(std::ptrdiff_t) * 2 + sizeof(std::ranges::__non_propagating_cache>)); +static_assert(sizeof(CV1) == /*sizeof(__base_) == 0 + */ sizeof(std::ptrdiff_t) * 2 + + sizeof(std::ranges::__non_propagating_cache>)); using CV2 = std::ranges::chunk_view; // Expected CV2 (with View >= forward) layout: diff --git a/libcxx/test/std/ranges/range.adaptors/range.chunk/adaptor.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.chunk/adaptor.pass.cpp index edd3c77b38e96..c61967ec9da00 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.chunk/adaptor.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.chunk/adaptor.pass.cpp @@ -23,8 +23,8 @@ #include "types.h" constexpr bool test() { - std::array array = {1, 2, 3, 4, 5, 6, 7, 8}; - std::ranges::ref_view> view = array | std::views::all; + std::array array = {1, 2, 3, 4, 5, 6, 7, 8}; + std::ranges::ref_view> view = array | std::views::all; // Test `views::chunk(view, n)` { @@ -60,7 +60,7 @@ constexpr bool test() { // Test `views::chunk | adaptor` { - /*__pipable*/ auto adaptors = std::views::chunk(5) | std::views::join; + /*__pipable*/ auto adaptors = std::views::chunk(5) | std::views::join; std::ranges::input_range auto rejoined = view | adaptors; assert(std::ranges::equal(rejoined, view)); std::ranges::input_range auto const_rejoined = std::as_const(view) | adaptors; diff --git a/libcxx/test/std/ranges/range.adaptors/range.chunk/base.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.chunk/base.pass.cpp index 383b314a5deb0..e3a315a7a39ce 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.chunk/base.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.chunk/base.pass.cpp @@ -22,9 +22,10 @@ #include "test_range.h" constexpr bool test() { - std::array array = {1, 2, 3, 4, 5, 6, 7, 8}; - std::ranges::chunk_view>> chunked = array | std::views::chunk(3); - std::ranges::chunk_view>> const_chunked = std::as_const(array) | std::views::chunk(4); + std::array array = {1, 2, 3, 4, 5, 6, 7, 8}; + std::ranges::chunk_view>> chunked = array | std::views::chunk(3); + std::ranges::chunk_view>> const_chunked = + std::as_const(array) | std::views::chunk(4); // Test `chunk_view.base()` { diff --git a/libcxx/test/std/ranges/range.adaptors/range.chunk/begin.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.chunk/begin.pass.cpp index 02828a8350771..264d62ee420b8 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.chunk/begin.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.chunk/begin.pass.cpp @@ -29,7 +29,8 @@ constexpr bool test() { std::vector vector = {1, 2, 3, 4, 5, 6, 7, 8}; std::ranges::chunk_view>> chunked = vector | std::views::chunk(3); - std::ranges::chunk_view>> const_chunked = std::as_const(vector) | std::views::chunk(3); + std::ranges::chunk_view>> const_chunked = + std::as_const(vector) | std::views::chunk(3); std::ranges::chunk_view> input_chunked = input_span(vector.data(), 8) | std::views::chunk(3); // Test `chunk_view.begin()` when V models only input_range diff --git a/libcxx/test/std/ranges/range.adaptors/range.chunk/end.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.chunk/end.pass.cpp index 20d96ce29fc44..35358e92d639b 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.chunk/end.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.chunk/end.pass.cpp @@ -30,7 +30,8 @@ constexpr bool test() { std::vector vector = {1, 2, 3, 4, 5, 6, 7, 8}; std::ranges::chunk_view>> chunked = vector | std::views::chunk(3); - std::ranges::chunk_view>> const_chunked = std::as_const(vector) | std::views::chunk(3); + std::ranges::chunk_view>> const_chunked = + std::as_const(vector) | std::views::chunk(3); std::ranges::chunk_view> input_chunked = input_span(vector.data(), 8) | std::views::chunk(3); // Test `chunk_view.end()` when V models only input_range diff --git a/libcxx/test/std/ranges/range.adaptors/range.chunk/range.chunk.iter/decrement.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.chunk/range.chunk.iter/decrement.pass.cpp index 20fda6ff26f6b..8ab28e1b04b76 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.chunk/range.chunk.iter/decrement.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.chunk/range.chunk.iter/decrement.pass.cpp @@ -27,7 +27,7 @@ constexpr bool test() { std::vector vector = {1, 2, 3, 4, 5, 6, 7, 8}; - std::ranges::chunk_view>> chunked = vector | std::views::chunk(2); + std::ranges::chunk_view>> chunked = vector | std::views::chunk(2); // Test `constexpr iterator& operator--();` { diff --git a/libcxx/test/std/ranges/range.adaptors/range.chunk/range.chunk.iter/deref.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.chunk/range.chunk.iter/deref.pass.cpp index cd317e601a9a2..bcd85812d94ef 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.chunk/range.chunk.iter/deref.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.chunk/range.chunk.iter/deref.pass.cpp @@ -32,7 +32,7 @@ constexpr bool test() { std::vector vector = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}; std::ranges::chunk_view>> chunked = vector | std::views::chunk(3); - std::ranges::chunk_view> input_chunked = input_span(vector) | std::views::chunk(3); + std::ranges::chunk_view> input_chunked = input_span(vector) | std::views::chunk(3); // Test `constexpr value_type outer_iterator::operator*() const` { @@ -56,7 +56,7 @@ constexpr bool test() { // Test `constexpr value_type iterator::operator*() const` { /*chunk_view::__inner_iterator*/ std::input_iterator auto it = (*input_chunked.begin()).begin(); - std::same_as decltype(auto) v = *it; + std::same_as decltype(auto) v = *it; assert(v == 1); } diff --git a/libcxx/test/std/ranges/range.adaptors/range.chunk/range.chunk.iter/increment.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.chunk/range.chunk.iter/increment.pass.cpp index df99cc03fc831..a6d369d2bc60c 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.chunk/range.chunk.iter/increment.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.chunk/range.chunk.iter/increment.pass.cpp @@ -33,7 +33,7 @@ constexpr bool test() { std::vector vector = {1, 2, 3, 4, 5, 6, 7, 8}; - std::ranges::chunk_view>> chunked = vector | std::views::chunk(2); + std::ranges::chunk_view>> chunked = vector | std::views::chunk(2); std::ranges::chunk_view> input_chunked = input_span(vector) | std::views::chunk(2); // Test `constexpr outer_iterator& operator++();` From fa5dda5df7761ce501af97dc9dd4cdf40c51ccfa Mon Sep 17 00:00:00 2001 From: anonymouspc Date: Thu, 11 Dec 2025 13:58:21 +0800 Subject: [PATCH 32/34] clang-format --- .../test/std/ranges/range.adaptors/range.chunk/begin.pass.cpp | 2 +- .../test/std/ranges/range.adaptors/range.chunk/end.pass.cpp | 2 +- .../range.chunk/range.chunk.iter/compare.pass.cpp | 2 +- .../range.chunk/range.chunk.iter/decrement.pass.cpp | 2 +- .../range.chunk/range.chunk.iter/deref.pass.cpp | 4 ++-- .../range.chunk/range.chunk.iter/increment.pass.cpp | 2 +- 6 files changed, 7 insertions(+), 7 deletions(-) diff --git a/libcxx/test/std/ranges/range.adaptors/range.chunk/begin.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.chunk/begin.pass.cpp index 264d62ee420b8..3cccd7d1bebc6 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.chunk/begin.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.chunk/begin.pass.cpp @@ -27,7 +27,7 @@ #include "types.h" constexpr bool test() { - std::vector vector = {1, 2, 3, 4, 5, 6, 7, 8}; + std::vector vector = {1, 2, 3, 4, 5, 6, 7, 8}; std::ranges::chunk_view>> chunked = vector | std::views::chunk(3); std::ranges::chunk_view>> const_chunked = std::as_const(vector) | std::views::chunk(3); diff --git a/libcxx/test/std/ranges/range.adaptors/range.chunk/end.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.chunk/end.pass.cpp index 35358e92d639b..73eb0d967f6a2 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.chunk/end.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.chunk/end.pass.cpp @@ -28,7 +28,7 @@ #include "types.h" constexpr bool test() { - std::vector vector = {1, 2, 3, 4, 5, 6, 7, 8}; + std::vector vector = {1, 2, 3, 4, 5, 6, 7, 8}; std::ranges::chunk_view>> chunked = vector | std::views::chunk(3); std::ranges::chunk_view>> const_chunked = std::as_const(vector) | std::views::chunk(3); diff --git a/libcxx/test/std/ranges/range.adaptors/range.chunk/range.chunk.iter/compare.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.chunk/range.chunk.iter/compare.pass.cpp index 0ea21267f8548..d86726d958e6e 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.chunk/range.chunk.iter/compare.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.chunk/range.chunk.iter/compare.pass.cpp @@ -42,7 +42,7 @@ #include "../types.h" constexpr bool test() { - std::vector vector = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}; + std::vector vector = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}; std::ranges::chunk_view>> chunked = vector | std::views::chunk(3); std::ranges::chunk_view> input_chunked = input_span(vector) | std::views::chunk(3); diff --git a/libcxx/test/std/ranges/range.adaptors/range.chunk/range.chunk.iter/decrement.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.chunk/range.chunk.iter/decrement.pass.cpp index 8ab28e1b04b76..397b32e73080a 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.chunk/range.chunk.iter/decrement.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.chunk/range.chunk.iter/decrement.pass.cpp @@ -26,7 +26,7 @@ #include "test_range.h" constexpr bool test() { - std::vector vector = {1, 2, 3, 4, 5, 6, 7, 8}; + std::vector vector = {1, 2, 3, 4, 5, 6, 7, 8}; std::ranges::chunk_view>> chunked = vector | std::views::chunk(2); // Test `constexpr iterator& operator--();` diff --git a/libcxx/test/std/ranges/range.adaptors/range.chunk/range.chunk.iter/deref.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.chunk/range.chunk.iter/deref.pass.cpp index bcd85812d94ef..b8772d0fac3d2 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.chunk/range.chunk.iter/deref.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.chunk/range.chunk.iter/deref.pass.cpp @@ -30,7 +30,7 @@ #include "../types.h" constexpr bool test() { - std::vector vector = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}; + std::vector vector = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}; std::ranges::chunk_view>> chunked = vector | std::views::chunk(3); std::ranges::chunk_view> input_chunked = input_span(vector) | std::views::chunk(3); @@ -49,7 +49,7 @@ constexpr bool test() { // Test `constexpr default_sentinel_t outer_iterator::value_type::end() const noexcept` { /*chunk_view::__outer_iterator::value_type*/ std::ranges::input_range auto inner = *input_chunked.begin(); - [[maybe_unused]] std::same_as auto it = inner.end(); + [[maybe_unused]] std::same_as auto it = inner.end(); static_assert(noexcept((inner.end()))); } diff --git a/libcxx/test/std/ranges/range.adaptors/range.chunk/range.chunk.iter/increment.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.chunk/range.chunk.iter/increment.pass.cpp index a6d369d2bc60c..6048aba027ce9 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.chunk/range.chunk.iter/increment.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.chunk/range.chunk.iter/increment.pass.cpp @@ -32,7 +32,7 @@ #include "../types.h" constexpr bool test() { - std::vector vector = {1, 2, 3, 4, 5, 6, 7, 8}; + std::vector vector = {1, 2, 3, 4, 5, 6, 7, 8}; std::ranges::chunk_view>> chunked = vector | std::views::chunk(2); std::ranges::chunk_view> input_chunked = input_span(vector) | std::views::chunk(2); From 93d9a49bd2c7982a36934ef28e47b39ac7a5d2ac Mon Sep 17 00:00:00 2001 From: anonymouspc Date: Thu, 11 Dec 2025 15:54:22 +0800 Subject: [PATCH 33/34] what the hell msvc abi is doing? --- .../range.chunk/no_unique_address.compile.pass.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/libcxx/test/libcxx/ranges/range.adaptors/range.chunk/no_unique_address.compile.pass.cpp b/libcxx/test/libcxx/ranges/range.adaptors/range.chunk/no_unique_address.compile.pass.cpp index f4ffd69f8f519..5b582fed88bfc 100644 --- a/libcxx/test/libcxx/ranges/range.adaptors/range.chunk/no_unique_address.compile.pass.cpp +++ b/libcxx/test/libcxx/ranges/range.adaptors/range.chunk/no_unique_address.compile.pass.cpp @@ -8,8 +8,6 @@ // REQUIRES: std-at-least-c++23 -// XFAIL: msvc - // // This test ensures that we use `[[no_unique_address]]` in `chunk_view`. From a1678f83f68df34d63503c2b5cb73d7f814cde6a Mon Sep 17 00:00:00 2001 From: anonymouspc Date: Thu, 11 Dec 2025 22:31:07 +0800 Subject: [PATCH 34/34] you, msvc --- .../range.chunk/no_unique_address.compile.pass.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/libcxx/test/libcxx/ranges/range.adaptors/range.chunk/no_unique_address.compile.pass.cpp b/libcxx/test/libcxx/ranges/range.adaptors/range.chunk/no_unique_address.compile.pass.cpp index 5b582fed88bfc..14c618c505e70 100644 --- a/libcxx/test/libcxx/ranges/range.adaptors/range.chunk/no_unique_address.compile.pass.cpp +++ b/libcxx/test/libcxx/ranges/range.adaptors/range.chunk/no_unique_address.compile.pass.cpp @@ -42,6 +42,7 @@ using CV1 = std::ranges::chunk_view; // [[no_unique_address]] range_difference_t<_View> __n_ // size: sizeof(ptrdiff_t) // [[no_unique_address]] range_difference_t<_View> __remainder_ // size: sizeof(ptrdiff_t) // [[no_unique_address]] __non_propagating_cache> __current_ // size: sizeof(__non_propagating_cache>), align: std::ptrdiff_t +static_assert(alignof(std::ranges::__non_propagating_cache>) == alignof(std::ptrdiff_t)); static_assert(sizeof(CV1) == /*sizeof(__base_) == 0 + */ sizeof(std::ptrdiff_t) * 2 + sizeof(std::ranges::__non_propagating_cache>));