[libcxx-commits] [libcxx] f1db578 - [libc++][test] Fix assumptions that `std::array` iterators are pointers (#74430)
via libcxx-commits
libcxx-commits at lists.llvm.org
Tue Dec 5 08:25:46 PST 2023
Author: Stephan T. Lavavej
Date: 2023-12-05T11:25:42-05:00
New Revision: f1db578f0d0f9d83f8b8b88d92ad5397377a74b2
URL: https://github.com/llvm/llvm-project/commit/f1db578f0d0f9d83f8b8b88d92ad5397377a74b2
DIFF: https://github.com/llvm/llvm-project/commit/f1db578f0d0f9d83f8b8b88d92ad5397377a74b2.diff
LOG: [libc++][test] Fix assumptions that `std::array` iterators are pointers (#74430)
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::array`s
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.
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.)
Added:
Modified:
libcxx/test/std/algorithms/alg.modifying.operations/alg.replace/pstl.replace.pass.cpp
libcxx/test/std/algorithms/alg.modifying.operations/alg.replace/pstl.replace_copy.pass.cpp
libcxx/test/std/algorithms/alg.modifying.operations/alg.replace/pstl.replace_copy_if.pass.cpp
libcxx/test/std/algorithms/alg.modifying.operations/alg.replace/pstl.replace_if.pass.cpp
libcxx/test/std/algorithms/alg.sorting/alg.merge/pstl.merge.pass.cpp
libcxx/test/std/algorithms/alg.sorting/alg.three.way/lexicographical_compare_three_way.pass.cpp
libcxx/test/std/algorithms/alg.sorting/alg.three.way/lexicographical_compare_three_way_comp.pass.cpp
libcxx/test/std/containers/from_range_helpers.h
libcxx/test/std/containers/views/views.span/span.cons/iterator_sentinel.pass.cpp
libcxx/test/std/ranges/range.adaptors/range.chunk.by/range.chunk.by.iter/compare.pass.cpp
libcxx/test/std/ranges/range.adaptors/range.chunk.by/range.chunk.by.iter/decrement.pass.cpp
libcxx/test/std/ranges/range.adaptors/range.chunk.by/range.chunk.by.iter/deref.pass.cpp
libcxx/test/std/ranges/range.adaptors/range.chunk.by/range.chunk.by.iter/increment.pass.cpp
Removed:
################################################################################
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..00b40a4e159ac 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,36 @@ 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 +71,12 @@ 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 +84,12 @@ 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 +97,12 @@ 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..9e4f4d3f03450 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,40 @@ 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..ade15ce0b7085 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
@@ -53,15 +53,23 @@ struct Test {
std::array<int, 0> a;
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));
+ std::merge(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));
+ std::merge(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}));
}
@@ -69,8 +77,12 @@ struct Test {
int a[] = {2, 4, 6, 8, 10};
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));
+ std::merge(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..d7cd49987689d 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
@@ -27,8 +27,8 @@
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::same_as<Order> decltype(auto) result = 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..f2f7d538d773f 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
@@ -56,8 +56,8 @@ 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::same_as<Order> decltype(auto) result = 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>::
diff erence_type
diff erence_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..c6c036363d3df 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 = make_chunk_by_view(array.begin(), array.end());
+ ChunkByView view = make_chunk_by_view(array);
ChunkByIterator it = view.begin();
++it;
--it;
- assert(base((*it).begin()) == array.begin());
- assert(base((*it).end()) == array.begin() + 3);
+ assert(base((*it).begin()) == array.data());
+ assert(base((*it).end()) == array.data() + 3);
++it;
++it;
--it;
- assert(base((*it).begin()) == array.begin() + 3);
- assert(base((*it).end()) == array.begin() + 6);
+ assert(base((*it).begin()) == array.data() + 3);
+ assert(base((*it).end()) == array.data() + 6);
++it;
++it;
--it;
- assert(base((*it).begin()) == array.begin() + 6);
- assert(base((*it).end()) == array.begin() + 9);
+ assert(base((*it).begin()) == array.data() + 6);
+ assert(base((*it).end()) == array.data() + 9);
++it;
++it;
--it;
- assert(base((*it).begin()) == array.begin() + 9);
+ assert(base((*it).begin()) == array.data() + 9);
}
// Decrement an iterator multiple times
if constexpr (std::ranges::common_range<Underlying>) {
std::array array{1, 2, 1, 2, 1};
- ChunkByView view = make_chunk_by_view(array.begin(), array.end());
+ ChunkByView view = make_chunk_by_view(array);
ChunkByIterator it = view.end();
--it;
--it;
--it;
- assert(base((*it).begin()) == array.begin());
+ assert(base((*it).begin()) == array.data());
}
// Test with a predicate that takes by non-const reference
if constexpr (!std::to_underlying(Constant)) {
std::array array{1, 2, 3, -3, -2, -1};
- View v{Iterator{array.begin()}, Sentinel{Iterator{array.end()}}};
+ View v{Iterator{array.data()}, Sentinel{Iterator{array.data() + array.size()}}};
auto view = std::views::chunk_by(std::move(v), [](int& x, int& y) { return x <= y; });
auto it = std::ranges::next(view.begin());
- assert(base((*it).begin()) == array.begin() + 3);
+ assert(base((*it).begin()) == array.data() + 3);
--it;
- assert(base((*it).begin()) == array.begin());
+ assert(base((*it).begin()) == array.data());
}
// Test with a predicate that is invocable but not callable (i.e. cannot be called like regular function 'f()')
{
std::array array = {1, 2, 3, -3, -2, -1};
- auto v = View{Iterator{array.begin()}, Sentinel{Iterator{array.end()}}}
- | std::views::transform([](int x) { return IntWrapper{x}; });
+ auto v = View{Iterator{array.data()}, Sentinel{Iterator{array.data() + array.size()}}} |
+ std::views::transform([](int x) { return IntWrapper{x}; });
auto view = std::views::chunk_by(std::move(v), &IntWrapper::lessEqual);
auto it = std::ranges::next(view.begin());
- assert(base((*it).begin().base()) == array.begin() + 3);
+ assert(base((*it).begin().base()) == array.data() + 3);
--it;
- assert(base((*it).begin().base()) == array.begin());
+ assert(base((*it).begin().base()) == array.data());
}
// Make sure we do not make a copy of the predicate when we decrement
if constexpr (std::ranges::common_range<Underlying>) {
bool moved = false, copied = false;
std::array array{1, 2, 1, 3};
- View v{Iterator(array.begin()), Sentinel(Iterator(array.end()))};
+ View v{Iterator(array.data()), Sentinel(Iterator(array.data() + array.size()))};
auto view = std::views::chunk_by(std::move(v), TrackingPred(&moved, &copied));
assert(std::exchange(moved, false));
auto it = view.end();
@@ -164,21 +164,21 @@ constexpr void test() {
// Check post-decrement
{
std::array array{0, 1, 2, -3, -2, -1, -6, -5, -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(result == std::default_sentinel);
- assert(base((*it).begin()) == array.begin() + 6);
+ assert(base((*it).begin()) == array.data() + 6);
result = it--;
- assert(base((*it).begin()) == array.begin() + 3);
- assert(base((*result).begin()) == array.begin() + 6);
+ assert(base((*it).begin()) == array.data() + 3);
+ assert(base((*result).begin()) == array.data() + 6);
result = it--;
- assert(base((*it).begin()) == array.begin());
- assert(base((*result).begin()) == array.begin() + 3);
+ assert(base((*it).begin()) == array.data());
+ assert(base((*result).begin()) == array.data() + 3);
}
}
diff --git a/libcxx/test/std/ranges/range.adaptors/range.chunk.by/range.chunk.by.iter/deref.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.chunk.by/range.chunk.by.iter/deref.pass.cpp
index 3f8c073e7b3b0..8cc9bdac0b1d8 100644
--- a/libcxx/test/std/ranges/range.adaptors/range.chunk.by/range.chunk.by.iter/deref.pass.cpp
+++ b/libcxx/test/std/ranges/range.adaptors/range.chunk.by/range.chunk.by.iter/deref.pass.cpp
@@ -33,7 +33,7 @@ constexpr void test() {
std::array array{0, 1, 2, 3, -1, 0, 1, 2, -2, 3, 4, 5};
std::array expected{std::array{0, 1, 2, 3}, std::array{-1, 0, 1, 2}, std::array{-2, 3, 4, 5}};
- Underlying underlying{Iter{array.begin()}, Sent{Iter{array.end()}}};
+ Underlying underlying{Iter{array.data()}, Sent{Iter{array.data() + array.size()}}};
ChunkByView view{underlying, std::ranges::less_equal{}};
size_t idx = 0;
diff --git a/libcxx/test/std/ranges/range.adaptors/range.chunk.by/range.chunk.by.iter/increment.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.chunk.by/range.chunk.by.iter/increment.pass.cpp
index 454e9e7503a5b..3a9262cb2ad71 100644
--- a/libcxx/test/std/ranges/range.adaptors/range.chunk.by/range.chunk.by.iter/increment.pass.cpp
+++ b/libcxx/test/std/ranges/range.adaptors/range.chunk.by/range.chunk.by.iter/increment.pass.cpp
@@ -39,15 +39,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{}};
};
// Increment the iterator when it won't find another satisfied value after begin()
{
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 = view.begin();
std::same_as<ChunkByIterator&> decltype(auto) result = ++it;
@@ -59,8 +59,8 @@ constexpr void test() {
// Increment the iterator and it finds another value after begin()
{
std::array array{1, 2, 3, -1, -2, -3};
- int const* second_chunk = array.begin() + 3;
- ChunkByView view = make_chunk_by_view(array.begin(), array.end());
+ int const* second_chunk = array.data() + 3;
+ ChunkByView view = make_chunk_by_view(array);
ChunkByIterator it = view.begin();
++it;
@@ -70,26 +70,26 @@ constexpr void test() {
// Increment advances all the way to the end of the range
{
std::array array{1, 2, 3, 4, 1};
- ChunkByView view = make_chunk_by_view(array.begin(), array.end());
+ ChunkByView view = make_chunk_by_view(array);
ChunkByIterator it = view.begin();
++it;
- assert(base((*it).begin()) == array.begin() + 4);
+ assert(base((*it).begin()) == array.data() + 4);
}
// Increment an iterator multiple times
{
std::array array{0, 1, 0, 2, 0, 3, 0, 4};
- ChunkByView view = make_chunk_by_view(array.begin(), array.end());
+ ChunkByView view = make_chunk_by_view(array);
ChunkByIterator it = view.begin();
- assert(base((*it).begin()) == array.begin());
+ assert(base((*it).begin()) == array.data());
++it;
- assert(base((*it).begin()) == array.begin() + 2);
+ assert(base((*it).begin()) == array.data() + 2);
++it;
- assert(base((*it).begin()) == array.begin() + 4);
+ assert(base((*it).begin()) == array.data() + 4);
++it;
- assert(base((*it).begin()) == array.begin() + 6);
+ assert(base((*it).begin()) == array.data() + 6);
++it;
assert(it == std::default_sentinel);
}
@@ -97,26 +97,26 @@ constexpr void test() {
// Test with a predicate that takes by non-const reference
if constexpr (!std::to_underlying(Constant)) {
std::array array{1, 2, 3, -3, -2, -1};
- View v{Iterator{array.begin()}, Sentinel{Iterator{array.end()}}};
+ View v{Iterator{array.data()}, Sentinel{Iterator{array.data() + array.size()}}};
auto view = std::views::chunk_by(std::move(v), [](int& x, int& y) { return x <= y; });
auto it = view.begin();
- assert(base((*it).begin()) == array.begin());
+ assert(base((*it).begin()) == array.data());
++it;
- assert(base((*it).begin()) == array.begin() + 3);
+ assert(base((*it).begin()) == array.data() + 3);
}
// Test with a predicate that is invocable but not callable (i.e. cannot be called like regular function 'f()')
{
std::array array = {1, 2, 3, -3, -2, -1};
- auto v = View{Iterator{array.begin()}, Sentinel{Iterator{array.end()}}}
- | std::views::transform([](int x) { return IntWrapper{x}; });
+ auto v = View{Iterator{array.data()}, Sentinel{Iterator{array.data() + array.size()}}} |
+ std::views::transform([](int x) { return IntWrapper{x}; });
auto view = std::views::chunk_by(std::move(v), &IntWrapper::lessEqual);
auto it = view.begin();
- assert(base((*it).begin().base()) == array.begin());
+ assert(base((*it).begin().base()) == array.data());
++it;
- assert(base((*it).begin().base()) == array.begin() + 3);
+ assert(base((*it).begin().base()) == array.data() + 3);
}
// Make sure we do not make a copy of the predicate when we increment
@@ -124,7 +124,7 @@ constexpr void test() {
{
bool moved = false, copied = false;
std::array array{1, 2, 1, 3};
- View v{Iterator(array.begin()), Sentinel(Iterator(array.end()))};
+ View v{Iterator(array.data()), Sentinel(Iterator(array.data() + array.size()))};
auto view = std::views::chunk_by(std::move(v), TrackingPred(&moved, &copied));
assert(std::exchange(moved, false));
auto it = view.begin();
@@ -137,20 +137,20 @@ constexpr void test() {
// Check post-increment
{
std::array array{0, 1, 2, -3, -2, -1, -6, -5, -4};
- ChunkByView view = make_chunk_by_view(array.begin(), array.end());
+ ChunkByView view = make_chunk_by_view(array);
ChunkByIterator it = view.begin();
std::same_as<ChunkByIterator> decltype(auto) result = it++;
assert(result != it);
- assert(base((*result).begin()) == array.begin());
- assert(base((*it).begin()) == array.begin() + 3);
+ assert(base((*result).begin()) == array.data());
+ assert(base((*it).begin()) == array.data() + 3);
result = it++;
- assert(base((*result).begin()) == array.begin() + 3);
- assert(base((*it).begin()) == array.begin() + 6);
+ assert(base((*result).begin()) == array.data() + 3);
+ assert(base((*it).begin()) == array.data() + 6);
result = it++;
- assert(base((*result).begin()) == array.begin() + 6);
+ assert(base((*result).begin()) == array.data() + 6);
assert(it == std::default_sentinel);
}
}
More information about the libcxx-commits
mailing list