Skip to content

[libc++][test] Fix assumptions that std::array iterators are pointers #74430

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 7 commits into from
Dec 5, 2023

Conversation

StephanTLavavej
Copy link
Member

Found while running libc++'s tests with MSVC's STL, where std::array iterators are never pointers.

Most of these changes are reasonably self-explanatory (the std::arrays are right there, and the sometimes-slightly-wrapped raw pointer types are a short distance away). A couple of changes are less obvious:


In libcxx/test/std/containers/from_range_helpers.h, wrap_input() is called with Iter types that are constructible from raw pointers. It's also sometimes called with an array as the input, so the first overload was implicitly assuming that array iterators are pointers. We can fix this assumption by providing a dedicated overload for array, just like the one for vector immediately below. Finally, from_range_helpers.h should explicitly include both <array> and <vector>, even though they were apparently being dragged in already.


In libcxx/test/std/containers/views/views.span/span.cons/iterator_sentinel.pass.cpp, fix throw_operator_minus. The error was pretty complicated, caused by the concepts machinery noticing that value_type and element_type were inconsistent. In the template instantiation context, you can see the critical detail that throw_operator_minus<std::_Array_iterator> is being formed.

Click to expand error:
D:\GitHub\STL\llvm-project\libcxx\test\std\containers\views\views.span\span.cons\iterator_sentinel.pass.cpp(128,8): error: no matching constructor for initialization of 'std::span<int>'
        (std::span<int>{throw_operator_minus{a.begin()}, throw_operator_minus{a.end()}}));
        ^             ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
D:\GitHub\STL\llvm-project\libcxx\test\support\assert_macros.h(129,27): note: expanded from macro 'TEST_VALIDATE_EXCEPTION'
        static_cast<void>(EXPR);                                                                                       \
                            ^~~~
D:\GitHub\STL\out\x64\out\inc\span(328,51): note: candidate constructor template not viable: no known conversion from 'throw_operator_minus<_Array_iterator<int, 1>>' (aka 'throw_operator_minus<std::_Array_iterator<int, 1>>') to 'size_type' (aka 'unsigned long long') for 2nd argument
    constexpr explicit(_Extent != dynamic_extent) span(_It _First, size_type _Count) noexcept // strengthened
                                                    ^
D:\GitHub\STL\out\x64\out\inc\span(339,51): note: candidate template ignored: constraints not satisfied [with _It = throw_operator_minus<_Array_iterator<int, 1>>, _Sentinel = throw_operator_minus<_Array_iterator<int, 1>>]
    constexpr explicit(_Extent != dynamic_extent) span(_It _First, _Sentinel _Last)
                                                    ^
D:\GitHub\STL\out\x64\out\inc\span(338,15): note: because '_Span_compatible_iterator<throw_operator_minus<std::_Array_iterator<int, 1> >, element_type>' evaluated to false
    template <_Span_compatible_iterator<element_type> _It, _Span_compatible_sentinel<_It> _Sentinel>
                ^
D:\GitHub\STL\out\x64\out\inc\span(243,37): note: because 'throw_operator_minus<std::_Array_iterator<int, 1>>' does not satisfy 'contiguous_iterator'
concept _Span_compatible_iterator = contiguous_iterator<_It>
                                    ^
D:\GitHub\STL\out\x64\out\inc\xutility(815,31): note: because 'throw_operator_minus<std::_Array_iterator<int, 1>>' does not satisfy 'random_access_iterator'
concept contiguous_iterator = random_access_iterator<_It>
                                ^
D:\GitHub\STL\out\x64\out\inc\xutility(803,34): note: because 'throw_operator_minus<std::_Array_iterator<int, 1>>' does not satisfy 'bidirectional_iterator'
concept random_access_iterator = bidirectional_iterator<_It>
                                    ^
D:\GitHub\STL\out\x64\out\inc\xutility(796,34): note: because 'throw_operator_minus<std::_Array_iterator<int, 1>>' does not satisfy 'forward_iterator'
concept bidirectional_iterator = forward_iterator<_It> && derived_from<_Iter_concept<_It>, bidirectional_iterator_tag>
                                    ^
D:\GitHub\STL\out\x64\out\inc\xutility(792,28): note: because 'throw_operator_minus<std::_Array_iterator<int, 1>>' does not satisfy 'input_iterator'
concept forward_iterator = input_iterator<_It> && derived_from<_Iter_concept<_It>, forward_iterator_tag>
                            ^
D:\GitHub\STL\out\x64\out\inc\xutility(781,59): note: because 'throw_operator_minus<std::_Array_iterator<int, 1>>' does not satisfy 'indirectly_readable'
concept input_iterator = input_or_output_iterator<_It> && indirectly_readable<_It>
                                                            ^
D:\GitHub\STL\out\x64\out\inc\xutility(694,31): note: because 'remove_cvref_t<throw_operator_minus<_Array_iterator<int, 1>>>' (aka 'throw_operator_minus<std::_Array_iterator<int, 1>>') does not satisfy '_Indirectly_readable_impl'
concept indirectly_readable = _Indirectly_readable_impl<remove_cvref_t<_It>>;
                                ^
D:\GitHub\STL\out\x64\out\inc\__msvc_iter_core.hpp(163,1): note: because 'typename iter_value_t<_It>' would be invalid: no type named 'value_type' in 'std::indirectly_readable_traits<throw_operator_minus<std::_Array_iterator<int, 1>>>'
using iter_value_t = conditional_t<_Is_from_primary<iterator_traits<remove_cvref_t<_Ty>>>,
^
D:\GitHub\STL\out\x64\out\inc\span(353,15): note: candidate constructor template not viable: requires single argument '_Arr', but 2 arguments were provided
    constexpr span(type_identity_t<element_type> (&_Arr)[_Size]) noexcept : _Mybase(_Arr, _Size) {}
                ^
D:\GitHub\STL\out\x64\out\inc\span(358,15): note: candidate constructor template not viable: requires single argument '_Arr', but 2 arguments were provided
    constexpr span(array<_OtherTy, _Size>& _Arr) noexcept : _Mybase(_Arr.data(), _Size) {}
                ^
D:\GitHub\STL\out\x64\out\inc\span(363,15): note: candidate constructor template not viable: requires single argument '_Arr', but 2 arguments were provided
    constexpr span(const array<_OtherTy, _Size>& _Arr) noexcept : _Mybase(_Arr.data(), _Size) {}
                ^
D:\GitHub\STL\out\x64\out\inc\span(366,51): note: candidate constructor template not viable: requires single argument '_Range', but 2 arguments were provided
    constexpr explicit(_Extent != dynamic_extent) span(_Rng&& _Range)
                                                    ^
D:\GitHub\STL\out\x64\out\inc\span(380,5): note: candidate constructor template not viable: requires single argument '_Other', but 2 arguments were provided
    span(const span<_OtherTy, _OtherExtent>& _Other) noexcept
    ^
D:\GitHub\STL\out\x64\out\inc\span(297,7): note: candidate constructor (the implicit copy constructor) not viable: requires 1 argument, but 2 were provided
class span : private _Span_extent_type<_Ty, _Extent> {
        ^
D:\GitHub\STL\out\x64\out\inc\span(297,7): note: candidate constructor (the implicit move constructor) not viable: requires 1 argument, but 2 were provided
D:\GitHub\STL\out\x64\out\inc\span(325,15): note: candidate constructor not viable: requires 0 arguments, but 2 were provided
    constexpr span() noexcept requires (_Extent == 0 || _Extent == dynamic_extent) = default;
                ^

Fortunately, the fix is extremely simple. To produce element_type (which retains any cv-qualification, unlike value_type), we shouldn't attempt to remove_pointer with the iterator type It. Instead, we've already obtained the reference type, so we can remove_reference_t. (This is modern code, where we have access to the alias templates, so I saw no reason to use the older verbose form.)

…rs are pointers.

The error was pretty complicated, caused by the concepts machinery noticing that value_type and element_type were inconsistent:

D:\GitHub\STL\llvm-project\libcxx\test\std\containers\views\views.span\span.cons\iterator_sentinel.pass.cpp(128,8): error: no matching constructor for initialization of 'std::span<int>'
      (std::span<int>{throw_operator_minus{a.begin()}, throw_operator_minus{a.end()}}));
       ^             ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
D:\GitHub\STL\llvm-project\libcxx\test\support\assert_macros.h(129,27): note: expanded from macro 'TEST_VALIDATE_EXCEPTION'
        static_cast<void>(EXPR);                                                                                       \
                          ^~~~
D:\GitHub\STL\out\x64\out\inc\span(328,51): note: candidate constructor template not viable: no known conversion from 'throw_operator_minus<_Array_iterator<int, 1>>' (aka 'throw_operator_minus<std::_Array_iterator<int, 1>>') to 'size_type' (aka 'unsigned long long') for 2nd argument
    constexpr explicit(_Extent != dynamic_extent) span(_It _First, size_type _Count) noexcept // strengthened
                                                  ^
D:\GitHub\STL\out\x64\out\inc\span(339,51): note: candidate template ignored: constraints not satisfied [with _It = throw_operator_minus<_Array_iterator<int, 1>>, _Sentinel = throw_operator_minus<_Array_iterator<int, 1>>]
    constexpr explicit(_Extent != dynamic_extent) span(_It _First, _Sentinel _Last)
                                                  ^
D:\GitHub\STL\out\x64\out\inc\span(338,15): note: because '_Span_compatible_iterator<throw_operator_minus<std::_Array_iterator<int, 1> >, element_type>' evaluated to false
    template <_Span_compatible_iterator<element_type> _It, _Span_compatible_sentinel<_It> _Sentinel>
              ^
D:\GitHub\STL\out\x64\out\inc\span(243,37): note: because 'throw_operator_minus<std::_Array_iterator<int, 1>>' does not satisfy 'contiguous_iterator'
concept _Span_compatible_iterator = contiguous_iterator<_It>
                                    ^
D:\GitHub\STL\out\x64\out\inc\xutility(815,31): note: because 'throw_operator_minus<std::_Array_iterator<int, 1>>' does not satisfy 'random_access_iterator'
concept contiguous_iterator = random_access_iterator<_It>
                              ^
D:\GitHub\STL\out\x64\out\inc\xutility(803,34): note: because 'throw_operator_minus<std::_Array_iterator<int, 1>>' does not satisfy 'bidirectional_iterator'
concept random_access_iterator = bidirectional_iterator<_It>
                                 ^
D:\GitHub\STL\out\x64\out\inc\xutility(796,34): note: because 'throw_operator_minus<std::_Array_iterator<int, 1>>' does not satisfy 'forward_iterator'
concept bidirectional_iterator = forward_iterator<_It> && derived_from<_Iter_concept<_It>, bidirectional_iterator_tag>
                                 ^
D:\GitHub\STL\out\x64\out\inc\xutility(792,28): note: because 'throw_operator_minus<std::_Array_iterator<int, 1>>' does not satisfy 'input_iterator'
concept forward_iterator = input_iterator<_It> && derived_from<_Iter_concept<_It>, forward_iterator_tag>
                           ^
D:\GitHub\STL\out\x64\out\inc\xutility(781,59): note: because 'throw_operator_minus<std::_Array_iterator<int, 1>>' does not satisfy 'indirectly_readable'
concept input_iterator = input_or_output_iterator<_It> && indirectly_readable<_It>
                                                          ^
D:\GitHub\STL\out\x64\out\inc\xutility(694,31): note: because 'remove_cvref_t<throw_operator_minus<_Array_iterator<int, 1>>>' (aka 'throw_operator_minus<std::_Array_iterator<int, 1>>') does not satisfy '_Indirectly_readable_impl'
concept indirectly_readable = _Indirectly_readable_impl<remove_cvref_t<_It>>;
                              ^
D:\GitHub\STL\out\x64\out\inc\__msvc_iter_core.hpp(163,1): note: because 'typename iter_value_t<_It>' would be invalid: no type named 'value_type' in 'std::indirectly_readable_traits<throw_operator_minus<std::_Array_iterator<int, 1>>>'
using iter_value_t = conditional_t<_Is_from_primary<iterator_traits<remove_cvref_t<_Ty>>>,
^
D:\GitHub\STL\out\x64\out\inc\span(353,15): note: candidate constructor template not viable: requires single argument '_Arr', but 2 arguments were provided
    constexpr span(type_identity_t<element_type> (&_Arr)[_Size]) noexcept : _Mybase(_Arr, _Size) {}
              ^
D:\GitHub\STL\out\x64\out\inc\span(358,15): note: candidate constructor template not viable: requires single argument '_Arr', but 2 arguments were provided
    constexpr span(array<_OtherTy, _Size>& _Arr) noexcept : _Mybase(_Arr.data(), _Size) {}
              ^
D:\GitHub\STL\out\x64\out\inc\span(363,15): note: candidate constructor template not viable: requires single argument '_Arr', but 2 arguments were provided
    constexpr span(const array<_OtherTy, _Size>& _Arr) noexcept : _Mybase(_Arr.data(), _Size) {}
              ^
D:\GitHub\STL\out\x64\out\inc\span(366,51): note: candidate constructor template not viable: requires single argument '_Range', but 2 arguments were provided
    constexpr explicit(_Extent != dynamic_extent) span(_Rng&& _Range)
                                                  ^
D:\GitHub\STL\out\x64\out\inc\span(380,5): note: candidate constructor template not viable: requires single argument '_Other', but 2 arguments were provided
    span(const span<_OtherTy, _OtherExtent>& _Other) noexcept
    ^
D:\GitHub\STL\out\x64\out\inc\span(297,7): note: candidate constructor (the implicit copy constructor) not viable: requires 1 argument, but 2 were provided
class span : private _Span_extent_type<_Ty, _Extent> {
      ^
D:\GitHub\STL\out\x64\out\inc\span(297,7): note: candidate constructor (the implicit move constructor) not viable: requires 1 argument, but 2 were provided
D:\GitHub\STL\out\x64\out\inc\span(325,15): note: candidate constructor not viable: requires 0 arguments, but 2 were provided
    constexpr span() noexcept requires (_Extent == 0 || _Extent == dynamic_extent) = default;
              ^
wrap_input() is called with Iter types that are constructible from raw pointers. It's also sometimes called with an `array` as the `input`, so the first overload was implicitly assuming that array iterators are pointers.

We can fix this assumption by providing a dedicated overload for `array`, just like the one for `vector` immediately below.

Finally, from_range_helpers.h should explicitly include both `<array>` and `<vector>`, even though they were apparently being dragged in already.
This is called immediately below with arrays and pointer types.
@StephanTLavavej StephanTLavavej requested a review from a team as a code owner December 5, 2023 07:59
@llvmbot llvmbot added the libc++ libc++ C++ Standard Library. Not GNU libstdc++. Not libc++abi. label Dec 5, 2023
@llvmbot
Copy link
Member

llvmbot commented Dec 5, 2023

@llvm/pr-subscribers-libcxx

Author: Stephan T. Lavavej (StephanTLavavej)

Changes

Found while running libc++'s tests with MSVC's STL, where std::array iterators are never pointers.

Most of these changes are reasonably self-explanatory (the std::arrays are right there, and the sometimes-slightly-wrapped raw pointer types are a short distance away). A couple of changes are less obvious:


In libcxx/test/std/containers/from_range_helpers.h, wrap_input() is called with Iter types that are constructible from raw pointers. It's also sometimes called with an array as the input, so the first overload was implicitly assuming that array iterators are pointers. We can fix this assumption by providing a dedicated overload for array, just like the one for vector immediately below. Finally, from_range_helpers.h should explicitly include both &lt;array&gt; and &lt;vector&gt;, even though they were apparently being dragged in already.


In libcxx/test/std/containers/views/views.span/span.cons/iterator_sentinel.pass.cpp, fix throw_operator_minus. The error was pretty complicated, caused by the concepts machinery noticing that value_type and element_type were inconsistent. In the template instantiation context, you can see the critical detail that throw_operator_minus&lt;std::_Array_iterator&gt; is being formed.

<details><summary>Click to expand error:</summary>

D:\GitHub\STL\llvm-project\libcxx\test\std\containers\views\views.span\span.cons\iterator_sentinel.pass.cpp(128,8): error: no matching constructor for initialization of 'std::span&lt;int&gt;'
        (std::span&lt;int&gt;{throw_operator_minus{a.begin()}, throw_operator_minus{a.end()}}));
        ^             ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
D:\GitHub\STL\llvm-project\libcxx\test\support\assert_macros.h(129,27): note: expanded from macro 'TEST_VALIDATE_EXCEPTION'
        static_cast&lt;void&gt;(EXPR);                                                                                       \
                            ^~~~
D:\GitHub\STL\out\x64\out\inc\span(328,51): note: candidate constructor template not viable: no known conversion from 'throw_operator_minus&lt;_Array_iterator&lt;int, 1&gt;&gt;' (aka 'throw_operator_minus&lt;std::_Array_iterator&lt;int, 1&gt;&gt;') to 'size_type' (aka 'unsigned long long') for 2nd argument
    constexpr explicit(_Extent != dynamic_extent) span(_It _First, size_type _Count) noexcept // strengthened
                                                    ^
D:\GitHub\STL\out\x64\out\inc\span(339,51): note: candidate template ignored: constraints not satisfied [with _It = throw_operator_minus&lt;_Array_iterator&lt;int, 1&gt;&gt;, _Sentinel = throw_operator_minus&lt;_Array_iterator&lt;int, 1&gt;&gt;]
    constexpr explicit(_Extent != dynamic_extent) span(_It _First, _Sentinel _Last)
                                                    ^
D:\GitHub\STL\out\x64\out\inc\span(338,15): note: because '_Span_compatible_iterator&lt;throw_operator_minus&lt;std::_Array_iterator&lt;int, 1&gt; &gt;, element_type&gt;' evaluated to false
    template &lt;_Span_compatible_iterator&lt;element_type&gt; _It, _Span_compatible_sentinel&lt;_It&gt; _Sentinel&gt;
                ^
D:\GitHub\STL\out\x64\out\inc\span(243,37): note: because 'throw_operator_minus&lt;std::_Array_iterator&lt;int, 1&gt;&gt;' does not satisfy 'contiguous_iterator'
concept _Span_compatible_iterator = contiguous_iterator&lt;_It&gt;
                                    ^
D:\GitHub\STL\out\x64\out\inc\xutility(815,31): note: because 'throw_operator_minus&lt;std::_Array_iterator&lt;int, 1&gt;&gt;' does not satisfy 'random_access_iterator'
concept contiguous_iterator = random_access_iterator&lt;_It&gt;
                                ^
D:\GitHub\STL\out\x64\out\inc\xutility(803,34): note: because 'throw_operator_minus&lt;std::_Array_iterator&lt;int, 1&gt;&gt;' does not satisfy 'bidirectional_iterator'
concept random_access_iterator = bidirectional_iterator&lt;_It&gt;
                                    ^
D:\GitHub\STL\out\x64\out\inc\xutility(796,34): note: because 'throw_operator_minus&lt;std::_Array_iterator&lt;int, 1&gt;&gt;' does not satisfy 'forward_iterator'
concept bidirectional_iterator = forward_iterator&lt;_It&gt; &amp;&amp; derived_from&lt;_Iter_concept&lt;_It&gt;, bidirectional_iterator_tag&gt;
                                    ^
D:\GitHub\STL\out\x64\out\inc\xutility(792,28): note: because 'throw_operator_minus&lt;std::_Array_iterator&lt;int, 1&gt;&gt;' does not satisfy 'input_iterator'
concept forward_iterator = input_iterator&lt;_It&gt; &amp;&amp; derived_from&lt;_Iter_concept&lt;_It&gt;, forward_iterator_tag&gt;
                            ^
D:\GitHub\STL\out\x64\out\inc\xutility(781,59): note: because 'throw_operator_minus&lt;std::_Array_iterator&lt;int, 1&gt;&gt;' does not satisfy 'indirectly_readable'
concept input_iterator = input_or_output_iterator&lt;_It&gt; &amp;&amp; indirectly_readable&lt;_It&gt;
                                                            ^
D:\GitHub\STL\out\x64\out\inc\xutility(694,31): note: because 'remove_cvref_t&lt;throw_operator_minus&lt;_Array_iterator&lt;int, 1&gt;&gt;&gt;' (aka 'throw_operator_minus&lt;std::_Array_iterator&lt;int, 1&gt;&gt;') does not satisfy '_Indirectly_readable_impl'
concept indirectly_readable = _Indirectly_readable_impl&lt;remove_cvref_t&lt;_It&gt;&gt;;
                                ^
D:\GitHub\STL\out\x64\out\inc\__msvc_iter_core.hpp(163,1): note: because 'typename iter_value_t&lt;_It&gt;' would be invalid: no type named 'value_type' in 'std::indirectly_readable_traits&lt;throw_operator_minus&lt;std::_Array_iterator&lt;int, 1&gt;&gt;&gt;'
using iter_value_t = conditional_t&lt;_Is_from_primary&lt;iterator_traits&lt;remove_cvref_t&lt;_Ty&gt;&gt;&gt;,
^
D:\GitHub\STL\out\x64\out\inc\span(353,15): note: candidate constructor template not viable: requires single argument '_Arr', but 2 arguments were provided
    constexpr span(type_identity_t&lt;element_type&gt; (&amp;_Arr)[_Size]) noexcept : _Mybase(_Arr, _Size) {}
                ^
D:\GitHub\STL\out\x64\out\inc\span(358,15): note: candidate constructor template not viable: requires single argument '_Arr', but 2 arguments were provided
    constexpr span(array&lt;_OtherTy, _Size&gt;&amp; _Arr) noexcept : _Mybase(_Arr.data(), _Size) {}
                ^
D:\GitHub\STL\out\x64\out\inc\span(363,15): note: candidate constructor template not viable: requires single argument '_Arr', but 2 arguments were provided
    constexpr span(const array&lt;_OtherTy, _Size&gt;&amp; _Arr) noexcept : _Mybase(_Arr.data(), _Size) {}
                ^
D:\GitHub\STL\out\x64\out\inc\span(366,51): note: candidate constructor template not viable: requires single argument '_Range', but 2 arguments were provided
    constexpr explicit(_Extent != dynamic_extent) span(_Rng&amp;&amp; _Range)
                                                    ^
D:\GitHub\STL\out\x64\out\inc\span(380,5): note: candidate constructor template not viable: requires single argument '_Other', but 2 arguments were provided
    span(const span&lt;_OtherTy, _OtherExtent&gt;&amp; _Other) noexcept
    ^
D:\GitHub\STL\out\x64\out\inc\span(297,7): note: candidate constructor (the implicit copy constructor) not viable: requires 1 argument, but 2 were provided
class span : private _Span_extent_type&lt;_Ty, _Extent&gt; {
        ^
D:\GitHub\STL\out\x64\out\inc\span(297,7): note: candidate constructor (the implicit move constructor) not viable: requires 1 argument, but 2 were provided
D:\GitHub\STL\out\x64\out\inc\span(325,15): note: candidate constructor not viable: requires 0 arguments, but 2 were provided
    constexpr span() noexcept requires (_Extent == 0 || _Extent == dynamic_extent) = default;
                ^

</details>

Fortunately, the fix is extremely simple. To produce element_type (which retains any cv-qualification, unlike value_type), we shouldn't attempt to remove_pointer with the iterator type It. Instead, we've already obtained the reference type, so we can remove_reference_t. (This is modern code, where we have access to the alias templates, so I saw no reason to use the older verbose form.)


Patch is 31.17 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/74430.diff

13 Files Affected:

  • (modified) libcxx/test/std/algorithms/alg.modifying.operations/alg.replace/pstl.replace.pass.cpp (+6-6)
  • (modified) libcxx/test/std/algorithms/alg.modifying.operations/alg.replace/pstl.replace_copy.pass.cpp (+6-6)
  • (modified) libcxx/test/std/algorithms/alg.modifying.operations/alg.replace/pstl.replace_copy_if.pass.cpp (+6-6)
  • (modified) libcxx/test/std/algorithms/alg.modifying.operations/alg.replace/pstl.replace_if.pass.cpp (+6-6)
  • (modified) libcxx/test/std/algorithms/alg.sorting/alg.merge/pstl.merge.pass.cpp (+3-3)
  • (modified) libcxx/test/std/algorithms/alg.sorting/alg.three.way/lexicographical_compare_three_way.pass.cpp (+1-1)
  • (modified) libcxx/test/std/algorithms/alg.sorting/alg.three.way/lexicographical_compare_three_way_comp.pass.cpp (+1-1)
  • (modified) libcxx/test/std/containers/from_range_helpers.h (+9)
  • (modified) libcxx/test/std/containers/views/views.span/span.cons/iterator_sentinel.pass.cpp (+1-1)
  • (modified) libcxx/test/std/ranges/range.adaptors/range.chunk.by/range.chunk.by.iter/compare.pass.cpp (+6-6)
  • (modified) libcxx/test/std/ranges/range.adaptors/range.chunk.by/range.chunk.by.iter/decrement.pass.cpp (+30-30)
  • (modified) libcxx/test/std/ranges/range.adaptors/range.chunk.by/range.chunk.by.iter/deref.pass.cpp (+1-1)
  • (modified) libcxx/test/std/ranges/range.adaptors/range.chunk.by/range.chunk.by.iter/increment.pass.cpp (+25-25)
diff --git a/libcxx/test/std/algorithms/alg.modifying.operations/alg.replace/pstl.replace.pass.cpp b/libcxx/test/std/algorithms/alg.modifying.operations/alg.replace/pstl.replace.pass.cpp
index 751d6b74b0128..833d5b0f6b2bf 100644
--- a/libcxx/test/std/algorithms/alg.modifying.operations/alg.replace/pstl.replace.pass.cpp
+++ b/libcxx/test/std/algorithms/alg.modifying.operations/alg.replace/pstl.replace.pass.cpp
@@ -29,35 +29,35 @@ struct Test {
   void operator()(ExecutionPolicy&& policy) {
     { // simple test
       std::array a = {1, 2, 3, 4, 5, 6, 7, 8};
-      std::replace(policy, Iter(std::begin(a)), Iter(std::end(a)), 3, 6);
+      std::replace(policy, Iter(std::data(a)), Iter(std::data(a) + std::size(a)), 3, 6);
       assert((a == std::array{1, 2, 6, 4, 5, 6, 7, 8}));
     }
 
     { // empty range works
       std::array<int, 0> a = {};
-      std::replace(policy, Iter(std::begin(a)), Iter(std::end(a)), 3, 6);
+      std::replace(policy, Iter(std::data(a)), Iter(std::data(a) + std::size(a)), 3, 6);
     }
 
     { // non-empty range without a match works
       std::array a = {1, 2};
-      std::replace(policy, Iter(std::begin(a)), Iter(std::end(a)), 3, 6);
+      std::replace(policy, Iter(std::data(a)), Iter(std::data(a) + std::size(a)), 3, 6);
     }
 
     { // single element range works
       std::array a = {3};
-      std::replace(policy, Iter(std::begin(a)), Iter(std::end(a)), 3, 6);
+      std::replace(policy, Iter(std::data(a)), Iter(std::data(a) + std::size(a)), 3, 6);
       assert((a == std::array{6}));
     }
 
     { // two element range works
       std::array a = {3, 4};
-      std::replace(policy, Iter(std::begin(a)), Iter(std::end(a)), 3, 6);
+      std::replace(policy, Iter(std::data(a)), Iter(std::data(a) + std::size(a)), 3, 6);
       assert((a == std::array{6, 4}));
     }
 
     { // multiple matching elements work
       std::array a = {1, 2, 3, 4, 3, 3, 5, 6, 3};
-      std::replace(policy, Iter(std::begin(a)), Iter(std::end(a)), 3, 9);
+      std::replace(policy, Iter(std::data(a)), Iter(std::data(a) + std::size(a)), 3, 9);
       assert((a == std::array{1, 2, 9, 4, 9, 9, 5, 6, 9}));
     }
 
diff --git a/libcxx/test/std/algorithms/alg.modifying.operations/alg.replace/pstl.replace_copy.pass.cpp b/libcxx/test/std/algorithms/alg.modifying.operations/alg.replace/pstl.replace_copy.pass.cpp
index f24bedabebccd..18d4446f5d2a9 100644
--- a/libcxx/test/std/algorithms/alg.modifying.operations/alg.replace/pstl.replace_copy.pass.cpp
+++ b/libcxx/test/std/algorithms/alg.modifying.operations/alg.replace/pstl.replace_copy.pass.cpp
@@ -32,40 +32,40 @@ struct Test {
     { // simple test
       std::array a = {1, 2, 3, 4, 5, 6, 7, 8};
       std::array<int, a.size()> out;
-      std::replace_copy(policy, Iter(std::begin(a)), Iter(std::end(a)), Iter(std::begin(out)), 3, 6);
+      std::replace_copy(policy, Iter(std::data(a)), Iter(std::data(a) + std::size(a)), Iter(std::data(out)), 3, 6);
       assert((out == std::array{1, 2, 6, 4, 5, 6, 7, 8}));
     }
 
     { // empty range works
       std::array<int, 0> a = {};
-      std::replace_copy(policy, Iter(std::begin(a)), Iter(std::end(a)), Iter(std::begin(a)), 3, 6);
+      std::replace_copy(policy, Iter(std::data(a)), Iter(std::data(a) + std::size(a)), Iter(std::data(a)), 3, 6);
     }
 
     { // non-empty range without a match works
       std::array a = {1, 2};
       std::array<int, a.size()> out;
-      std::replace_copy(policy, Iter(std::begin(a)), Iter(std::end(a)), Iter(out.data()), 3, 6);
+      std::replace_copy(policy, Iter(std::data(a)), Iter(std::data(a) + std::size(a)), Iter(out.data()), 3, 6);
       assert((out == std::array{1, 2}));
     }
 
     { // single element range works
       std::array a = {3};
       std::array<int, a.size()> out;
-      std::replace_copy(policy, Iter(std::begin(a)), Iter(std::end(a)), Iter(std::begin(out)), 3, 6);
+      std::replace_copy(policy, Iter(std::data(a)), Iter(std::data(a) + std::size(a)), Iter(std::data(out)), 3, 6);
       assert((out == std::array{6}));
     }
 
     { // two element range works
       std::array a = {3, 4};
       std::array<int, a.size()> out;
-      std::replace_copy(policy, Iter(std::begin(a)), Iter(std::end(a)), Iter(std::begin(out)), 3, 6);
+      std::replace_copy(policy, Iter(std::data(a)), Iter(std::data(a) + std::size(a)), Iter(std::data(out)), 3, 6);
       assert((out == std::array{6, 4}));
     }
 
     { // multiple matching elements work
       std::array a = {1, 2, 3, 4, 3, 3, 5, 6, 3};
       std::array<int, a.size()> out;
-      std::replace_copy(policy, Iter(std::begin(a)), Iter(std::end(a)), Iter(std::begin(out)), 3, 9);
+      std::replace_copy(policy, Iter(std::data(a)), Iter(std::data(a) + std::size(a)), Iter(std::data(out)), 3, 9);
       assert((out == std::array{1, 2, 9, 4, 9, 9, 5, 6, 9}));
     }
 
diff --git a/libcxx/test/std/algorithms/alg.modifying.operations/alg.replace/pstl.replace_copy_if.pass.cpp b/libcxx/test/std/algorithms/alg.modifying.operations/alg.replace/pstl.replace_copy_if.pass.cpp
index f7c746f382d11..89ea1652eb896 100644
--- a/libcxx/test/std/algorithms/alg.modifying.operations/alg.replace/pstl.replace_copy_if.pass.cpp
+++ b/libcxx/test/std/algorithms/alg.modifying.operations/alg.replace/pstl.replace_copy_if.pass.cpp
@@ -34,21 +34,21 @@ struct Test {
       std::array a = {1, 2, 3, 4, 5, 6, 7, 8};
       std::array<int, a.size()> out;
       std::replace_copy_if(
-          policy, Iter(std::begin(a)), Iter(std::end(a)), Iter(std::begin(out)), [](int i) { return i == 3; }, 6);
+          policy, Iter(std::data(a)), Iter(std::data(a) + std::size(a)), Iter(std::data(out)), [](int i) { return i == 3; }, 6);
       assert((out == std::array{1, 2, 6, 4, 5, 6, 7, 8}));
     }
 
     { // empty range works
       std::array<int, 0> a = {};
       std::replace_copy_if(
-          policy, Iter(std::begin(a)), Iter(std::end(a)), Iter(std::begin(a)), [](int i) { return i == 3; }, 6);
+          policy, Iter(std::data(a)), Iter(std::data(a) + std::size(a)), Iter(std::data(a)), [](int i) { return i == 3; }, 6);
     }
 
     { // non-empty range without a match works
       std::array a = {1, 2};
       std::array<int, a.size()> out;
       std::replace_copy_if(
-          policy, Iter(std::begin(a)), Iter(std::end(a)), Iter(out.data()), [](int i) { return i == 3; }, 6);
+          policy, Iter(std::data(a)), Iter(std::data(a) + std::size(a)), Iter(out.data()), [](int i) { return i == 3; }, 6);
       assert((out == std::array{1, 2}));
     }
 
@@ -56,7 +56,7 @@ struct Test {
       std::array a = {3};
       std::array<int, a.size()> out;
       std::replace_copy_if(
-          policy, Iter(std::begin(a)), Iter(std::end(a)), Iter(std::begin(out)), [](int i) { return i == 3; }, 6);
+          policy, Iter(std::data(a)), Iter(std::data(a) + std::size(a)), Iter(std::data(out)), [](int i) { return i == 3; }, 6);
       assert((out == std::array{6}));
     }
 
@@ -64,7 +64,7 @@ struct Test {
       std::array a = {3, 4};
       std::array<int, a.size()> out;
       std::replace_copy_if(
-          policy, Iter(std::begin(a)), Iter(std::end(a)), Iter(std::begin(out)), [](int i) { return i == 3; }, 6);
+          policy, Iter(std::data(a)), Iter(std::data(a) + std::size(a)), Iter(std::data(out)), [](int i) { return i == 3; }, 6);
       assert((out == std::array{6, 4}));
     }
 
@@ -72,7 +72,7 @@ struct Test {
       std::array a = {1, 2, 3, 4, 3, 3, 5, 6, 3};
       std::array<int, a.size()> out;
       std::replace_copy_if(
-          policy, Iter(std::begin(a)), Iter(std::end(a)), Iter(std::begin(out)), [](int i) { return i == 3; }, 9);
+          policy, Iter(std::data(a)), Iter(std::data(a) + std::size(a)), Iter(std::data(out)), [](int i) { return i == 3; }, 9);
       assert((out == std::array{1, 2, 9, 4, 9, 9, 5, 6, 9}));
     }
 
diff --git a/libcxx/test/std/algorithms/alg.modifying.operations/alg.replace/pstl.replace_if.pass.cpp b/libcxx/test/std/algorithms/alg.modifying.operations/alg.replace/pstl.replace_if.pass.cpp
index 3ffc1c021bb9c..99ea5e230835f 100644
--- a/libcxx/test/std/algorithms/alg.modifying.operations/alg.replace/pstl.replace_if.pass.cpp
+++ b/libcxx/test/std/algorithms/alg.modifying.operations/alg.replace/pstl.replace_if.pass.cpp
@@ -30,38 +30,38 @@ struct Test {
     { // simple test
       std::array a = {1, 2, 3, 4, 5, 6, 7, 8};
       std::replace_if(
-          policy, Iter(std::begin(a)), Iter(std::end(a)), [](int i) { return i == 3 || i == 7; }, 6);
+          policy, Iter(std::data(a)), Iter(std::data(a) + std::size(a)), [](int i) { return i == 3 || i == 7; }, 6);
       assert((a == std::array{1, 2, 6, 4, 5, 6, 6, 8}));
     }
 
     { // empty range works
       std::array<int, 0> a = {};
       std::replace_if(
-          policy, Iter(std::begin(a)), Iter(std::end(a)), [](int) { return false; }, 6);
+          policy, Iter(std::data(a)), Iter(std::data(a) + std::size(a)), [](int) { return false; }, 6);
     }
 
     { // non-empty range without a match works
       std::array a = {1, 2};
-      std::replace_if(policy, Iter(std::begin(a)), Iter(std::end(a)), [](int) { return false; }, 6);
+      std::replace_if(policy, Iter(std::data(a)), Iter(std::data(a) + std::size(a)), [](int) { return false; }, 6);
     }
 
     { // single element range works
       std::array a = {3};
       std::replace_if(
-          policy, Iter(std::begin(a)), Iter(std::end(a)), [](int i) { return i == 3; }, 6);
+          policy, Iter(std::data(a)), Iter(std::data(a) + std::size(a)), [](int i) { return i == 3; }, 6);
       assert((a == std::array{6}));
     }
 
     { // two element range works
       std::array a = {3, 4};
       std::replace_if(
-          policy, Iter(std::begin(a)), Iter(std::end(a)), [](int i) { return i == 3; }, 6);
+          policy, Iter(std::data(a)), Iter(std::data(a) + std::size(a)), [](int i) { return i == 3; }, 6);
       assert((a == std::array{6, 4}));
     }
 
     { // multiple matching elements work
       std::array a = {1, 2, 3, 4, 3, 3, 5, 6, 3};
-      std::replace_if(policy, Iter(std::begin(a)), Iter(std::end(a)), [](int i) { return i == 3; }, 9);
+      std::replace_if(policy, Iter(std::data(a)), Iter(std::data(a) + std::size(a)), [](int i) { return i == 3; }, 9);
       assert((a == std::array{1, 2, 9, 4, 9, 9, 5, 6, 9}));
     }
 
diff --git a/libcxx/test/std/algorithms/alg.sorting/alg.merge/pstl.merge.pass.cpp b/libcxx/test/std/algorithms/alg.sorting/alg.merge/pstl.merge.pass.cpp
index 1feadfb377a68..c685bff8f4e9b 100644
--- a/libcxx/test/std/algorithms/alg.sorting/alg.merge/pstl.merge.pass.cpp
+++ b/libcxx/test/std/algorithms/alg.sorting/alg.merge/pstl.merge.pass.cpp
@@ -54,14 +54,14 @@ struct Test {
       std::array<int, 0> b;
       std::array<int, std::size(a) + std::size(b)> out;
       std::merge(
-          policy, Iter1(std::begin(a)), Iter1(std::end(a)), Iter2(std::begin(b)), Iter2(std::end(b)), std::begin(out));
+          policy, Iter1(std::data(a)), Iter1(std::data(a) + std::size(a)), Iter2(std::data(b)), Iter2(std::data(b) + std::size(b)), std::begin(out));
     }
     { // check that it works with the first range being empty
       std::array<int, 0> a;
       int b[] = {2, 4, 6, 8, 10};
       std::array<int, std::size(a) + std::size(b)> out;
       std::merge(
-          policy, Iter1(std::begin(a)), Iter1(std::end(a)), Iter2(std::begin(b)), Iter2(std::end(b)), std::begin(out));
+          policy, Iter1(std::data(a)), Iter1(std::data(a) + std::size(a)), Iter2(std::begin(b)), Iter2(std::end(b)), std::begin(out));
       assert((out == std::array{2, 4, 6, 8, 10}));
     }
 
@@ -70,7 +70,7 @@ struct Test {
       std::array<int, 0> b;
       std::array<int, std::size(a) + std::size(b)> out;
       std::merge(
-          policy, Iter1(std::begin(a)), Iter1(std::end(a)), Iter2(std::begin(b)), Iter2(std::end(b)), std::begin(out));
+          policy, Iter1(std::begin(a)), Iter1(std::end(a)), Iter2(std::data(b)), Iter2(std::data(b) + std::size(b)), std::begin(out));
       assert((out == std::array{2, 4, 6, 8, 10}));
     }
 
diff --git a/libcxx/test/std/algorithms/alg.sorting/alg.three.way/lexicographical_compare_three_way.pass.cpp b/libcxx/test/std/algorithms/alg.sorting/alg.three.way/lexicographical_compare_three_way.pass.cpp
index 0bd1d74529530..17db46edfb218 100644
--- a/libcxx/test/std/algorithms/alg.sorting/alg.three.way/lexicographical_compare_three_way.pass.cpp
+++ b/libcxx/test/std/algorithms/alg.sorting/alg.three.way/lexicographical_compare_three_way.pass.cpp
@@ -28,7 +28,7 @@
 template <typename Iter1, typename Iter2, typename C1, typename C2, typename Order>
 constexpr void test_lexicographical_compare(C1 a, C2 b, Order expected) {
   std::same_as<Order> decltype(auto) result =
-      std::lexicographical_compare_three_way(Iter1{a.begin()}, Iter1{a.end()}, Iter2{b.begin()}, Iter2{b.end()});
+      std::lexicographical_compare_three_way(Iter1{a.data()}, Iter1{a.data() + a.size()}, Iter2{b.data()}, Iter2{b.data() + b.size()});
   assert(expected == result);
 }
 
diff --git a/libcxx/test/std/algorithms/alg.sorting/alg.three.way/lexicographical_compare_three_way_comp.pass.cpp b/libcxx/test/std/algorithms/alg.sorting/alg.three.way/lexicographical_compare_three_way_comp.pass.cpp
index d3c2814d642a7..1f8b18737ada8 100644
--- a/libcxx/test/std/algorithms/alg.sorting/alg.three.way/lexicographical_compare_three_way_comp.pass.cpp
+++ b/libcxx/test/std/algorithms/alg.sorting/alg.three.way/lexicographical_compare_three_way_comp.pass.cpp
@@ -57,7 +57,7 @@ static_assert(has_lexicographical_compare<decltype(compare_int_result)>);
 template <typename Iter1, typename Iter2, typename C1, typename C2, typename Order, typename Comparator>
 constexpr void test_lexicographical_compare(C1 a, C2 b, Comparator comp, Order expected) {
   std::same_as<Order> decltype(auto) result =
-      std::lexicographical_compare_three_way(Iter1{a.begin()}, Iter1{a.end()}, Iter2{b.begin()}, Iter2{b.end()}, comp);
+      std::lexicographical_compare_three_way(Iter1{a.data()}, Iter1{a.data() + a.size()}, Iter2{b.data()}, Iter2{b.data() + b.size()}, comp);
   assert(expected == result);
 }
 
diff --git a/libcxx/test/std/containers/from_range_helpers.h b/libcxx/test/std/containers/from_range_helpers.h
index 7fff99da1e15e..e17ea247618bc 100644
--- a/libcxx/test/std/containers/from_range_helpers.h
+++ b/libcxx/test/std/containers/from_range_helpers.h
@@ -9,9 +9,11 @@
 #ifndef SUPPORT_FROM_RANGE_HELPERS_H
 #define SUPPORT_FROM_RANGE_HELPERS_H
 
+#include <array>
 #include <cstddef>
 #include <iterator>
 #include <type_traits>
+#include <vector>
 
 #include "min_allocator.h"
 #include "test_allocator.h"
@@ -34,6 +36,13 @@ constexpr auto wrap_input(Range&& input) {
   return std::ranges::subrange(std::move(b), std::move(e));
 }
 
+template <class Iter, class Sent, class T, std::size_t N>
+constexpr auto wrap_input(std::array<T, N>& input) {
+  auto b = Iter(input.data());
+  auto e = Sent(Iter(input.data() + input.size()));
+  return std::ranges::subrange(std::move(b), std::move(e));
+}
+
 template <class Iter, class Sent, class T>
 constexpr auto wrap_input(std::vector<T>& input) {
   auto b = Iter(input.data());
diff --git a/libcxx/test/std/containers/views/views.span/span.cons/iterator_sentinel.pass.cpp b/libcxx/test/std/containers/views/views.span/span.cons/iterator_sentinel.pass.cpp
index 4e1db3df5b83b..73b13ccc34cf8 100644
--- a/libcxx/test/std/containers/views/views.span/span.cons/iterator_sentinel.pass.cpp
+++ b/libcxx/test/std/containers/views/views.span/span.cons/iterator_sentinel.pass.cpp
@@ -71,7 +71,7 @@ class throw_operator_minus {
   typedef typename std::iterator_traits<It>::difference_type difference_type;
   typedef It pointer;
   typedef typename std::iterator_traits<It>::reference reference;
-  typedef typename std::remove_pointer<It>::type element_type;
+  typedef std::remove_reference_t<reference> element_type;
 
   throw_operator_minus() : it_() {}
   explicit throw_operator_minus(It it) : it_(it) {}
diff --git a/libcxx/test/std/ranges/range.adaptors/range.chunk.by/range.chunk.by.iter/compare.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.chunk.by/range.chunk.by.iter/compare.pass.cpp
index 38b6346e0061f..a3a51c79ccd12 100644
--- a/libcxx/test/std/ranges/range.adaptors/range.chunk.by/range.chunk.by.iter/compare.pass.cpp
+++ b/libcxx/test/std/ranges/range.adaptors/range.chunk.by/range.chunk.by.iter/compare.pass.cpp
@@ -31,15 +31,15 @@ constexpr void test() {
   using ChunkByView     = std::ranges::chunk_by_view<Underlying, std::ranges::less_equal>;
   using ChunkByIterator = std::ranges::iterator_t<ChunkByView>;
 
-  auto make_chunk_by_view = [](auto begin, auto end) {
-    View view{Iterator(begin), Sentinel(Iterator(end))};
+  auto make_chunk_by_view = [](auto& arr) {
+    View view{Iterator(arr.data()), Sentinel(Iterator(arr.data() + arr.size()))};
     return ChunkByView(std::move(view), std::ranges::less_equal{});
   };
 
   // Test operator==
   {
     std::array array{0, 1, 2};
-    ChunkByView view  = make_chunk_by_view(array.begin(), array.end());
+    ChunkByView view  = make_chunk_by_view(array);
     ChunkByIterator i = view.begin();
     ChunkByIterator j = view.begin();
 
@@ -52,7 +52,7 @@ constexpr void test() {
   // Test synthesized operator!=
   {
     std::array array{0, 1, 2};
-    ChunkByView view  = make_chunk_by_view(array.begin(), array.end());
+    ChunkByView view  = make_chunk_by_view(array);
     ChunkByIterator i = view.begin();
     ChunkByIterator j = view.begin();
 
@@ -65,7 +65,7 @@ constexpr void test() {
   // Test operator== with std::default_sentinel_t
   {
     std::array array{0, 1, 2};
-    ChunkByView view  = make_chunk_by_view(array.begin(), array.end());
+    ChunkByView view  = make_chunk_by_view(array);
     ChunkByIterator i = view.begin();
 
     std::same_as<bool> decltype(auto) result = (i == std::default_sentinel);
@@ -77,7 +77,7 @@ constexpr void test() {
   // Test synthesized operator!= with std::default_sentinel_t
   {
     std::array array{0, 1, 2};
-    ChunkByView view  = make_chunk_by_view(array.begin(), array.end());
+    ChunkByView view  = make_chunk_by_view(array);
     ChunkByIterator i = view.begin();
 
     std::same_as<bool> decltype(auto) result = (i != std::default_sentinel);
diff --git a/libcxx/test/std/ranges/range.adaptors/range.chunk.by/range.chunk.by.iter/decrement.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.chunk.by/range.chunk.by.iter/decrement.pass.cpp
index 167f3f753bfae..a331c794c8815 100644
--- a/libcxx/test/std/ranges/range.adaptors/range.chunk.by/range.chunk.by.iter/decrement.pass.cpp
+++ b/libcxx/test/std/ranges/range.adaptors/range.chunk.by/range.chunk.by.iter/decrement.pass.cpp
@@ -51,107 +51,107 @@ constexpr void test() {
   static_assert(HasPostDecrement<ChunkByIterator>);
   static_assert(HasPreDecrement<ChunkByIterator>);
 
-  auto make_chunk_by_view = [](auto begin, auto end) {
-    View view{Iterator{begin}, Sentinel{Iterator{end}}};
+  auto make_chunk_by_view = [](auto& arr) {
+    View view{Iterator{arr.data()}, Sentinel{Iterator{arr.data() + arr.size()}}};
     return ChunkByView{std::move(view), std::ranges::less_equal{}};
   };
 
   // Test with a single chunk
   {
     std::array array{0, 1, 2, 3, 4};
-    ChunkByView view   = make_chunk_by_view(array.begin(), array.end());
+    ChunkByView view   = make_chunk_by_view(array);
     ChunkByIterator it = std::ranges::next(view.begin(), view.end());
 
     std::same_as<ChunkByIterator&> decltype(auto) result = --it;
     assert(&result == &it);
-    assert(base((*result).begin()) == array.begin());
+    assert(base((*result).begin()) == array.data());
   }
 
   // Test with two chunks
   {
     std::array array{0, 1, 2, 0, 1, 2};
-    ChunkByView view   = make_chunk_by_view(array.begin(), array.end());
+    ChunkByView view   = make_chunk_by_view(array);
     ChunkByIterator it = std::ranges::next(view.begin(), view.end());
 
     std::same_as<ChunkByIterator&> decltype(auto) result = --it;
     assert(&result == &it);
-    assert(base((*result).begin()) == array.begin() + 3);
+    assert(base((*result).begin()) == array.data() + 3);
 
     --it;
-    assert(base((*result).begin()) == array.begin());
+    assert(base((*result).begin()) == array.data());
   }
 
   // Test going forward and then backward on the same iterator
   {
     std::array array{7, 8, 9, 4, 5, 6, 1, 2, 3, 0};
-    ChunkByView view   ...
[truncated]

Copy link

github-actions bot commented Dec 5, 2023

✅ With the latest revision this PR passed the C/C++ code formatter.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
libc++ libc++ C++ Standard Library. Not GNU libstdc++. Not libc++abi.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants