Skip to content

[libcxx][test] std::array::iterator are not pointers by C++ standard #70729

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 4 commits into from
Nov 12, 2023

Conversation

wdunicornpro
Copy link
Contributor

@wdunicornpro wdunicornpro commented Oct 30, 2023

This is to modify a list of libcxx tests written under the assumption that iterators for std::array, std::string_view, and std::string are pointers. The motivation for this PR is to make the tests more universal and potentially being used to test other C++ standard library implementations, for example microsoft/STL.

I can confirm that this patch makes a number of tests compatible with microsoft STL:
Failed : 204 (2.12%) -> Failed : 136 (1.42%)
, and does not break any tests on libcxx.

This is not a complete list of such incompatibilities, but I am hoping this will start a discussion about whether we are open to accepting such changes.

@wdunicornpro wdunicornpro requested a review from a team as a code owner October 30, 2023 21:34
@llvmbot llvmbot added the libc++ libc++ C++ Standard Library. Not GNU libstdc++. Not libc++abi. label Oct 30, 2023
@llvmbot
Copy link
Member

llvmbot commented Oct 30, 2023

@llvm/pr-subscribers-libcxx

Author: Duo Wang (wdunicornpro)

Changes

This is to modify a list of libcxx tests written under the assumption that iterators for std::array, std::string_view, and std::string are pointers. The motivation for this PR is to make the tests more universal and potentially being used to test other C++ standard library implementations, for example microsoft/STL.

I can confirm that this patch makes a number of tests compatible with microsoft STL:
Failed : 204 (2.12%) -> Failed : 136 (1.42%)
, and does not break any tests on libcxx.

This is not a complete list of such incompatibilities, but I am hoping this will start a discussion about whether we are open to accept such changes.


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

40 Files Affected:

  • (modified) libcxx/test/std/algorithms/alg.modifying.operations/alg.copy/ranges.copy.pass.cpp (+2-2)
  • (modified) libcxx/test/std/algorithms/alg.modifying.operations/alg.copy/ranges.copy_backward.pass.cpp (+2-2)
  • (modified) libcxx/test/std/algorithms/alg.modifying.operations/alg.copy/ranges.copy_n.pass.cpp (+2-2)
  • (modified) libcxx/test/std/algorithms/alg.modifying.operations/alg.fill/ranges.fill.pass.cpp (+2-2)
  • (modified) libcxx/test/std/algorithms/alg.modifying.operations/alg.move/ranges.move.pass.cpp (+2-2)
  • (modified) libcxx/test/std/algorithms/alg.modifying.operations/alg.move/ranges.move_backward.pass.cpp (+2-2)
  • (modified) libcxx/test/std/algorithms/alg.modifying.operations/alg.partitions/ranges_partition_copy.pass.cpp (+2-2)
  • (modified) libcxx/test/std/algorithms/alg.modifying.operations/alg.random.sample/ranges_sample.pass.cpp (+2-2)
  • (modified) libcxx/test/std/algorithms/alg.modifying.operations/alg.remove/ranges.remove.pass.cpp (+2-2)
  • (modified) libcxx/test/std/algorithms/alg.modifying.operations/alg.remove/ranges.remove_if.pass.cpp (+1-1)
  • (modified) libcxx/test/std/algorithms/alg.modifying.operations/alg.swap/ranges.swap_ranges.pass.cpp (+3-3)
  • (modified) libcxx/test/std/algorithms/alg.modifying.operations/alg.unique/ranges_unique_copy.pass.cpp (+2-2)
  • (modified) libcxx/test/std/algorithms/alg.nonmodifying/alg.all_of/ranges.all_of.pass.cpp (+1-1)
  • (modified) libcxx/test/std/algorithms/alg.nonmodifying/alg.any_of/ranges.any_of.pass.cpp (+1-1)
  • (modified) libcxx/test/std/algorithms/alg.nonmodifying/alg.none_of/ranges.none_of.pass.cpp (+1-1)
  • (modified) libcxx/test/std/algorithms/alg.nonmodifying/mismatch/ranges_mismatch.pass.cpp (+1-1)
  • (modified) libcxx/test/std/algorithms/alg.sorting/alg.heap.operations/make.heap/ranges_make_heap.pass.cpp (+9-2)
  • (modified) libcxx/test/std/algorithms/alg.sorting/alg.heap.operations/pop.heap/ranges_pop_heap.pass.cpp (+12-4)
  • (modified) libcxx/test/std/algorithms/alg.sorting/alg.heap.operations/push.heap/ranges_push_heap.pass.cpp (+9-2)
  • (modified) libcxx/test/std/algorithms/alg.sorting/alg.heap.operations/sort.heap/ranges_sort_heap.pass.cpp (+11-4)
  • (modified) libcxx/test/std/algorithms/alg.sorting/alg.merge/ranges_merge.pass.cpp (+10-10)
  • (modified) libcxx/test/std/algorithms/alg.sorting/alg.nth.element/ranges_nth_element.pass.cpp (+1-1)
  • (modified) libcxx/test/std/algorithms/alg.sorting/alg.set.operations/set.difference/ranges_set_difference.pass.cpp (+10-10)
  • (modified) libcxx/test/std/algorithms/alg.sorting/alg.set.operations/set.intersection/ranges_set_intersection.pass.cpp (+10-10)
  • (modified) libcxx/test/std/algorithms/alg.sorting/alg.set.operations/set.symmetric.difference/ranges_set_symmetric_difference.pass.cpp (+6-6)
  • (modified) libcxx/test/std/algorithms/alg.sorting/alg.set.operations/set.union/ranges_set_union.pass.cpp (+6-6)
  • (modified) libcxx/test/std/algorithms/ranges_robust_against_dangling.pass.cpp (+40-37)
  • (modified) libcxx/test/std/ranges/range.adaptors/range.filter/iterator/arrow.pass.cpp (+3-3)
  • (modified) libcxx/test/std/ranges/range.adaptors/range.filter/iterator/base.pass.cpp (+5-5)
  • (modified) libcxx/test/std/ranges/range.adaptors/range.filter/iterator/compare.pass.cpp (+2-2)
  • (modified) libcxx/test/std/ranges/range.adaptors/range.filter/iterator/ctor.parent_iter.pass.cpp (+2-2)
  • (modified) libcxx/test/std/ranges/range.adaptors/range.filter/iterator/decrement.pass.cpp (+18-18)
  • (modified) libcxx/test/std/ranges/range.adaptors/range.filter/iterator/deref.pass.cpp (+3-3)
  • (modified) libcxx/test/std/ranges/range.adaptors/range.filter/iterator/increment.pass.cpp (+31-31)
  • (modified) libcxx/test/std/ranges/range.adaptors/range.filter/iterator/iter_move.pass.cpp (+2-2)
  • (modified) libcxx/test/std/ranges/range.adaptors/range.filter/iterator/iter_swap.pass.cpp (+1-1)
  • (modified) libcxx/test/std/ranges/range.adaptors/range.filter/sentinel/base.pass.cpp (+2-2)
  • (modified) libcxx/test/std/ranges/range.adaptors/range.filter/sentinel/compare.pass.cpp (+2-2)
  • (modified) libcxx/test/std/ranges/range.adaptors/range.filter/sentinel/ctor.parent.pass.cpp (+1-1)
  • (modified) libcxx/test/std/ranges/range.adaptors/range.lazy.split/types.h (+8-8)
diff --git a/libcxx/test/std/algorithms/alg.modifying.operations/alg.copy/ranges.copy.pass.cpp b/libcxx/test/std/algorithms/alg.modifying.operations/alg.copy/ranges.copy.pass.cpp
index bc9c2788293cd48..2dd7350b1c35cf8 100644
--- a/libcxx/test/std/algorithms/alg.modifying.operations/alg.copy/ranges.copy.pass.cpp
+++ b/libcxx/test/std/algorithms/alg.modifying.operations/alg.copy/ranges.copy.pass.cpp
@@ -128,8 +128,8 @@ constexpr bool test() {
   { // check that an iterator is returned with a borrowing range
     std::array in{1, 2, 3, 4};
     std::array<int, 4> out;
-    std::same_as<std::ranges::in_out_result<int*, int*>> auto ret = std::ranges::copy(std::views::all(in), out.data());
-    assert(ret.in == in.data() + 4);
+    std::same_as<std::ranges::in_out_result<std::array<int, 4>::iterator, int*>> auto ret = std::ranges::copy(std::views::all(in), out.data());
+    assert(ret.in == in.end());
     assert(ret.out == out.data() + 4);
     assert(in == out);
   }
diff --git a/libcxx/test/std/algorithms/alg.modifying.operations/alg.copy/ranges.copy_backward.pass.cpp b/libcxx/test/std/algorithms/alg.modifying.operations/alg.copy/ranges.copy_backward.pass.cpp
index 184008c3e2fd0ff..feca8fd3be858bb 100644
--- a/libcxx/test/std/algorithms/alg.modifying.operations/alg.copy/ranges.copy_backward.pass.cpp
+++ b/libcxx/test/std/algorithms/alg.modifying.operations/alg.copy/ranges.copy_backward.pass.cpp
@@ -247,9 +247,9 @@ constexpr bool test() {
   { // check that an iterator is returned with a borrowing range
     std::array in {1, 2, 3, 4};
     std::array<int, 4> out;
-    std::same_as<std::ranges::in_out_result<int*, int*>> auto ret =
+    std::same_as<std::ranges::in_out_result<std::array<int, 4>::iterator, int*>> auto ret =
         std::ranges::copy_backward(std::views::all(in), out.data() + out.size());
-    assert(ret.in == in.data() + in.size());
+    assert(ret.in == in.end());
     assert(ret.out == out.data());
     assert(in == out);
   }
diff --git a/libcxx/test/std/algorithms/alg.modifying.operations/alg.copy/ranges.copy_n.pass.cpp b/libcxx/test/std/algorithms/alg.modifying.operations/alg.copy/ranges.copy_n.pass.cpp
index 237d1ef115090c0..d2a2b7c4888308f 100644
--- a/libcxx/test/std/algorithms/alg.modifying.operations/alg.copy/ranges.copy_n.pass.cpp
+++ b/libcxx/test/std/algorithms/alg.modifying.operations/alg.copy/ranges.copy_n.pass.cpp
@@ -53,7 +53,7 @@ constexpr void test_iterators() {
   { // check that an empty range works
     std::array<int, 0> in;
     std::array<int, 0> out;
-    auto ret = std::ranges::copy_n(In(in.data()), in.size(), Out(out.begin()));
+    auto ret = std::ranges::copy_n(In(in.data()), in.size(), Out(out.data()));
     assert(base(ret.in) == in.data());
     assert(base(ret.out) == out.data());
   }
@@ -103,7 +103,7 @@ constexpr bool test() {
     };
     std::array<CopyOnce, 4> in {};
     std::array<CopyOnce, 4> out {};
-    auto ret = std::ranges::copy_n(in.data(), in.size(), out.begin());
+    auto ret = std::ranges::copy_n(in.begin(), in.size(), out.begin());
     assert(ret.in == in.end());
     assert(ret.out == out.end());
     assert(std::all_of(out.begin(), out.end(), [](const auto& e) { return e.copied; }));
diff --git a/libcxx/test/std/algorithms/alg.modifying.operations/alg.fill/ranges.fill.pass.cpp b/libcxx/test/std/algorithms/alg.modifying.operations/alg.fill/ranges.fill.pass.cpp
index 0697f4fc57d671f..1be5a1bb284aaae 100644
--- a/libcxx/test/std/algorithms/alg.modifying.operations/alg.fill/ranges.fill.pass.cpp
+++ b/libcxx/test/std/algorithms/alg.modifying.operations/alg.fill/ranges.fill.pass.cpp
@@ -120,13 +120,13 @@ constexpr bool test() {
     {
       std::array<std::string, 10> a;
       auto ret = std::ranges::fill(a.begin(), a.end(), "long long string so no SSO");
-      assert(ret == a.data() + a.size());
+      assert(ret == a.begin() + a.size());
       assert(std::all_of(a.begin(), a.end(), [](auto& s) { return s == "long long string so no SSO"; }));
     }
     {
       std::array<std::string, 10> a;
       auto ret = std::ranges::fill(a, "long long string so no SSO");
-      assert(ret == a.data() + a.size());
+      assert(ret == a.begin() + a.size());
       assert(std::all_of(a.begin(), a.end(), [](auto& s) { return s == "long long string so no SSO"; }));
     }
   }
diff --git a/libcxx/test/std/algorithms/alg.modifying.operations/alg.move/ranges.move.pass.cpp b/libcxx/test/std/algorithms/alg.modifying.operations/alg.move/ranges.move.pass.cpp
index aeff581c46cb517..a0d1473360a14e8 100644
--- a/libcxx/test/std/algorithms/alg.modifying.operations/alg.move/ranges.move.pass.cpp
+++ b/libcxx/test/std/algorithms/alg.modifying.operations/alg.move/ranges.move.pass.cpp
@@ -275,9 +275,9 @@ constexpr bool test() {
   { // check that an iterator is returned with a borrowing range
     std::array in {1, 2, 3, 4};
     std::array<int, 4> out;
-    std::same_as<std::ranges::in_out_result<int*, int*>> decltype(auto) ret =
+    std::same_as<std::ranges::in_out_result<std::array<int, 4>::iterator, int*>> decltype(auto) ret =
         std::ranges::move(std::views::all(in), out.data());
-    assert(ret.in == in.data() + 4);
+    assert(ret.in == in.end());
     assert(ret.out == out.data() + 4);
     assert(in == out);
   }
diff --git a/libcxx/test/std/algorithms/alg.modifying.operations/alg.move/ranges.move_backward.pass.cpp b/libcxx/test/std/algorithms/alg.modifying.operations/alg.move/ranges.move_backward.pass.cpp
index 9219cbb1dd84d1f..47cf178636ad130 100644
--- a/libcxx/test/std/algorithms/alg.modifying.operations/alg.move/ranges.move_backward.pass.cpp
+++ b/libcxx/test/std/algorithms/alg.modifying.operations/alg.move/ranges.move_backward.pass.cpp
@@ -261,9 +261,9 @@ constexpr bool test() {
   { // check that an iterator is returned with a borrowing range
     std::array in {1, 2, 3, 4};
     std::array<int, 4> out;
-    std::same_as<std::ranges::in_out_result<int*, int*>> auto ret =
+    std::same_as<std::ranges::in_out_result<std::array<int, 4>::iterator, int*>> auto ret =
         std::ranges::move_backward(std::views::all(in), out.data() + out.size());
-    assert(ret.in == in.data() + in.size());
+    assert(ret.in == in.end());
     assert(ret.out == out.data());
     assert(in == out);
   }
diff --git a/libcxx/test/std/algorithms/alg.modifying.operations/alg.partitions/ranges_partition_copy.pass.cpp b/libcxx/test/std/algorithms/alg.modifying.operations/alg.partitions/ranges_partition_copy.pass.cpp
index 7b5b80dd8aaf819..af9a72da71a9985 100644
--- a/libcxx/test/std/algorithms/alg.modifying.operations/alg.partitions/ranges_partition_copy.pass.cpp
+++ b/libcxx/test/std/algorithms/alg.modifying.operations/alg.partitions/ranges_partition_copy.pass.cpp
@@ -132,7 +132,7 @@ constexpr void test_one(std::array<int, N1> input, Pred pred, std::array<int, N2
     std::array<int, N3> out2;
 
     std::same_as<ResultT> decltype(auto) result = std::ranges::partition_copy(
-        Iter(begin), Sent(Iter(end)), OutIter1(out1.begin()), OutIter2(out2.begin()), pred);
+        Iter(begin), Sent(Iter(end)), OutIter1(out1.data()), OutIter2(out2.data()), pred);
 
     assert(base(result.in) == input.data() + input.size());
     assert(base(result.out1) == out1.data() + expected_true.size());
@@ -148,7 +148,7 @@ constexpr void test_one(std::array<int, N1> input, Pred pred, std::array<int, N2
     std::array<int, N3> out2;
 
     std::same_as<ResultT> decltype(auto) result = std::ranges::partition_copy(
-        range, OutIter1(out1.begin()), OutIter2(out2.begin()), pred);
+        range, OutIter1(out1.data()), OutIter2(out2.data()), pred);
 
     assert(base(result.in) == input.data() + input.size());
     assert(base(result.out1) == out1.data() + expected_true.size());
diff --git a/libcxx/test/std/algorithms/alg.modifying.operations/alg.random.sample/ranges_sample.pass.cpp b/libcxx/test/std/algorithms/alg.modifying.operations/alg.random.sample/ranges_sample.pass.cpp
index 69db960ff362f6b..a5178cb2eee132b 100644
--- a/libcxx/test/std/algorithms/alg.modifying.operations/alg.random.sample/ranges_sample.pass.cpp
+++ b/libcxx/test/std/algorithms/alg.modifying.operations/alg.random.sample/ranges_sample.pass.cpp
@@ -164,7 +164,7 @@ void test_one(std::array<int, N> in, std::size_t n, Gen gen) {
     auto begin = Iter(in.data());
     auto end = Sent(Iter(in.data() + in.size()));
     std::array<int, N> output;
-    auto out = Out(output.begin());
+    auto out = Out(output.data());
 
     std::same_as<Out> decltype(auto) result = std::ranges::sample(
         std::move(begin), std::move(end), std::move(out), n, gen);
@@ -177,7 +177,7 @@ void test_one(std::array<int, N> in, std::size_t n, Gen gen) {
     auto begin = Iter(in.data());
     auto end = Sent(Iter(in.data() + in.size()));
     std::array<int, N> output;
-    auto out = Out(output.begin());
+    auto out = Out(output.data());
 
     std::same_as<Out> decltype(auto) result = std::ranges::sample(std::ranges::subrange(
         std::move(begin), std::move(end)), std::move(out), n, gen);
diff --git a/libcxx/test/std/algorithms/alg.modifying.operations/alg.remove/ranges.remove.pass.cpp b/libcxx/test/std/algorithms/alg.modifying.operations/alg.remove/ranges.remove.pass.cpp
index 7836dede7342ae9..7778fe8ce7cfdd0 100644
--- a/libcxx/test/std/algorithms/alg.modifying.operations/alg.remove/ranges.remove.pass.cpp
+++ b/libcxx/test/std/algorithms/alg.modifying.operations/alg.remove/ranges.remove.pass.cpp
@@ -65,7 +65,7 @@ constexpr void test(Data<N, M> d) {
 
     assert(base(ret.begin()) == input.data() + M);
     assert(base(ret.end()) == input.data() + N);
-    assert(std::ranges::equal(input.begin(), base(ret.begin()), d.expected.begin(), d.expected.end()));
+    assert(std::ranges::equal(input.data(), base(ret.begin()), d.expected.begin(), d.expected.end()));
   }
 
   { // range overload
@@ -76,7 +76,7 @@ constexpr void test(Data<N, M> d) {
 
     assert(base(ret.begin()) == input.data() + M);
     assert(base(ret.end()) == input.data() + N);
-    assert(std::ranges::equal(base(input.begin()), base(ret.begin()), d.expected.begin(), d.expected.end()));
+    assert(std::ranges::equal(input.data(), base(ret.begin()), d.expected.begin(), d.expected.end()));
   }
 }
 
diff --git a/libcxx/test/std/algorithms/alg.modifying.operations/alg.remove/ranges.remove_if.pass.cpp b/libcxx/test/std/algorithms/alg.modifying.operations/alg.remove/ranges.remove_if.pass.cpp
index 1db4f171b91072b..39f82a813333fcf 100644
--- a/libcxx/test/std/algorithms/alg.modifying.operations/alg.remove/ranges.remove_if.pass.cpp
+++ b/libcxx/test/std/algorithms/alg.modifying.operations/alg.remove/ranges.remove_if.pass.cpp
@@ -85,7 +85,7 @@ constexpr void test(Data<N, M> d) {
 
     assert(base(ret.begin()) == input.data() + M);
     assert(base(ret.end()) == input.data() + N);
-    assert(std::ranges::equal(base(input.begin()), base(ret.begin()), d.expected.begin(), d.expected.end()));
+    assert(std::ranges::equal(input.data(), base(ret.begin()), d.expected.begin(), d.expected.end()));
   }
 }
 
diff --git a/libcxx/test/std/algorithms/alg.modifying.operations/alg.swap/ranges.swap_ranges.pass.cpp b/libcxx/test/std/algorithms/alg.modifying.operations/alg.swap/ranges.swap_ranges.pass.cpp
index 4895ef59fc4eb00..a8d69b2832b4626 100644
--- a/libcxx/test/std/algorithms/alg.modifying.operations/alg.swap/ranges.swap_ranges.pass.cpp
+++ b/libcxx/test/std/algorithms/alg.modifying.operations/alg.swap/ranges.swap_ranges.pass.cpp
@@ -65,7 +65,7 @@ constexpr void test_range() {
   std::array r2 = {4, 5, 6};
 
 
-  std::same_as<std::ranges::in_in_result<int*, int*>> auto r = std::ranges::swap_ranges(r1, r2);
+  std::same_as<std::ranges::in_in_result<std::array<int, 3>::iterator, std::array<int, 3>::iterator>> auto r = std::ranges::swap_ranges(r1, r2);
   assert(r.in1 == r1.end());
   assert(r.in2 == r2.end());
 
@@ -146,7 +146,7 @@ constexpr void test_iterators() {
 
 constexpr void test_rval_range() {
   {
-    using Expected = std::ranges::swap_ranges_result<int*, std::ranges::dangling>;
+    using Expected = std::ranges::swap_ranges_result<std::array<int, 3>::iterator, std::ranges::dangling>;
     std::array<int, 3> r = {1, 2, 3};
     std::same_as<Expected> auto a = std::ranges::swap_ranges(r, std::array{4, 5, 6});
     assert((r == std::array{4, 5, 6}));
@@ -154,7 +154,7 @@ constexpr void test_rval_range() {
   }
   {
     std::array<int, 3> r = {1, 2, 3};
-    using Expected = std::ranges::swap_ranges_result<std::ranges::dangling, int*>;
+    using Expected = std::ranges::swap_ranges_result<std::ranges::dangling, std::array<int, 3>::iterator>;
     std::same_as<Expected> auto b = std::ranges::swap_ranges(std::array{4, 5, 6}, r);
     assert((r == std::array{4, 5, 6}));
     assert(b.in2 == r.begin() + 3);
diff --git a/libcxx/test/std/algorithms/alg.modifying.operations/alg.unique/ranges_unique_copy.pass.cpp b/libcxx/test/std/algorithms/alg.modifying.operations/alg.unique/ranges_unique_copy.pass.cpp
index 801385cf691ad13..b84600b92c2b291 100644
--- a/libcxx/test/std/algorithms/alg.modifying.operations/alg.unique/ranges_unique_copy.pass.cpp
+++ b/libcxx/test/std/algorithms/alg.modifying.operations/alg.unique/ranges_unique_copy.pass.cpp
@@ -186,7 +186,7 @@ constexpr void testUniqueCopyImpl(std::array<int, N1> in, std::array<int, N2> ex
   {
     std::array<int, N2> out;
     std::same_as<std::ranges::unique_copy_result<InIter, OutIter>> decltype(auto) result =
-        std::ranges::unique_copy(InIter{in.data()}, Sent{InIter{in.data() + in.size()}}, OutIter{out.begin()});
+        std::ranges::unique_copy(InIter{in.data()}, Sent{InIter{in.data() + in.size()}}, OutIter{out.data()});
     assert(std::ranges::equal(out, expected));
     assert(base(result.in) == in.data() + in.size());
     assert(base(result.out) == out.data() + out.size());
@@ -197,7 +197,7 @@ constexpr void testUniqueCopyImpl(std::array<int, N1> in, std::array<int, N2> ex
     std::array<int, N2> out;
     std::ranges::subrange r{InIter{in.data()}, Sent{InIter{in.data() + in.size()}}};
     std::same_as<std::ranges::unique_copy_result<InIter, OutIter>> decltype(auto) result =
-        std::ranges::unique_copy(r, OutIter{out.begin()});
+        std::ranges::unique_copy(r, OutIter{out.data()});
     assert(std::ranges::equal(out, expected));
     assert(base(result.in) == in.data() + in.size());
     assert(base(result.out) == out.data() + out.size());
diff --git a/libcxx/test/std/algorithms/alg.nonmodifying/alg.all_of/ranges.all_of.pass.cpp b/libcxx/test/std/algorithms/alg.nonmodifying/alg.all_of/ranges.all_of.pass.cpp
index 3118ad7b1d475a7..33f583800ad2170 100644
--- a/libcxx/test/std/algorithms/alg.nonmodifying/alg.all_of/ranges.all_of.pass.cpp
+++ b/libcxx/test/std/algorithms/alg.nonmodifying/alg.all_of/ranges.all_of.pass.cpp
@@ -93,7 +93,7 @@ constexpr void test_iterators() {
       auto pred = [&](int) { ++predicateCount; return true; };
       auto proj = [&](int i) { ++projectionCount; return i; };
       std::array a = {9, 7, 5, 3};
-      assert(std::ranges::all_of(It(a.begin()), Sent(It(a.end())), pred, proj));
+      assert(std::ranges::all_of(It(a.data()), Sent(It(a.data() + a.size())), pred, proj));
       assert(predicateCount == 4);
       assert(projectionCount == 4);
     }
diff --git a/libcxx/test/std/algorithms/alg.nonmodifying/alg.any_of/ranges.any_of.pass.cpp b/libcxx/test/std/algorithms/alg.nonmodifying/alg.any_of/ranges.any_of.pass.cpp
index 3dbac4bbc4a546a..312f89f54cd723f 100644
--- a/libcxx/test/std/algorithms/alg.nonmodifying/alg.any_of/ranges.any_of.pass.cpp
+++ b/libcxx/test/std/algorithms/alg.nonmodifying/alg.any_of/ranges.any_of.pass.cpp
@@ -93,7 +93,7 @@ constexpr void test_iterators() {
       auto pred = [&](int) { ++predicateCount; return false; };
       auto proj = [&](int i) { ++projectionCount; return i; };
       std::array a = {9, 7, 5, 3};
-      assert(!std::ranges::any_of(It(a.begin()), Sent(It(a.end())), pred, proj));
+      assert(!std::ranges::any_of(It(a.data()), Sent(It(a.data() + a.size())), pred, proj));
       assert(predicateCount == 4);
       assert(projectionCount == 4);
     }
diff --git a/libcxx/test/std/algorithms/alg.nonmodifying/alg.none_of/ranges.none_of.pass.cpp b/libcxx/test/std/algorithms/alg.nonmodifying/alg.none_of/ranges.none_of.pass.cpp
index cae29c3733b8876..dc9cfa39cbd6808 100644
--- a/libcxx/test/std/algorithms/alg.nonmodifying/alg.none_of/ranges.none_of.pass.cpp
+++ b/libcxx/test/std/algorithms/alg.nonmodifying/alg.none_of/ranges.none_of.pass.cpp
@@ -93,7 +93,7 @@ constexpr void test_iterators() {
       auto pred = [&](int) { ++predicateCount; return false; };
       auto proj = [&](int i) { ++projectionCount; return i; };
       std::array a = {9, 7, 5, 3};
-      assert(std::ranges::none_of(It(a.begin()), Sent(It(a.end())), pred, proj));
+      assert(std::ranges::none_of(It(a.data()), Sent(It(a.data() + a.size())), pred, proj));
       assert(predicateCount == 4);
       assert(projectionCount == 4);
     }
diff --git a/libcxx/test/std/algorithms/alg.nonmodifying/mismatch/ranges_mismatch.pass.cpp b/libcxx/test/std/algorithms/alg.nonmodifying/mismatch/ranges_mismatch.pass.cpp
index 3f4ef7760c9f58e..27babf3ee58744f 100644
--- a/libcxx/test/std/algorithms/alg.nonmodifying/mismatch/ranges_mismatch.pass.cpp
+++ b/libcxx/test/std/algorithms/alg.nonmodifying/mismatch/ranges_mismatch.pass.cpp
@@ -105,7 +105,7 @@ constexpr bool test() {
   { // test with a range
     std::array<int, 5> a = {1, 2, 3, 4, 5};
     std::array<int, 5> b = {1, 2, 3, 5, 4};
-    using Expected = std::ranges::mismatch_result<int*, int*>;
+    using Expected = std::ranges::mismatch_result<std::array<int, 5>::iterator, std::array<int, 5>::iterator>;
     std::same_as<Expected> auto ret = std::ranges::mismatch(a, b);
     assert(ret.in1 == a.begin() + 3);
     assert(ret.in2 == b.begin() + 3);
diff --git a/libcxx/test/std/algorithms/alg.sorting/alg.heap.operations/make.heap/ranges_make_heap.pass.cpp b/libcxx/test/std/algorithms/alg.sorting/alg.heap.operations/make.heap/ranges_make_heap.pass.cpp
index 5d8086df450abb8..77be3660ac436f3 100644
--- a/libcxx/test/std/algorithms/alg.sorting/alg.heap.operations/make.heap/ranges_make_heap.pass.cpp
+++ b/libcxx/test/std/algorithms/alg.sorting/alg.heap.operations/make.heap/ranges_make_heap.pass.cpp
@@ -60,6 +60,13 @@ static_assert(!HasMakeHeapR<UncheckedRange<const int*>>); // Doesn't satisfy `so
 
 template <std::size_t N, class T, class Iter>
 constexpr void verify_heap(const std::array<T, N>& heapified, Iter last, std::array<T, N> expected) {
+  assert(heapified == expected);
+  assert(last == heapified.end());
+  assert(std::is_heap(heapified.begin(), heapified.end()));
+}
+
+template <std::size_t N, class T, class Iter>
+constexpr void verify_heap_iterator(const std::array<T, N>& heapified, Iter last, std::array<T, N> expected) {
   assert(heapified == expected);
   assert(base(last) == heapified.data() + heapified.size());
   assert(std::is_heap(heapified.begin(), heapified.end()));
@@ -73,7 +80,7 @@ constexpr void test_one(const std::array<int, N> input, std::array<int, N> expec
     auto e = Sent(Iter(heapified.data() + heapified.size()));
 
     std::same_as<Iter> decltype(auto) last = std::ranges::make_heap(b, e);
-    verify_heap(heapified, last, expected);
+    verify_heap_iterator(heapified, last, expected);
   }
 
   { // (range) overload.
@@ -83,7 +90,7 @@ constexpr void test_one(const std::array<int, N> input, std::array<int, N> expec
     auto range = std::ranges::subrange(b, e);
 
     std::same_as<Iter> decltype(auto) last = std::ranges::make_heap(range);
-    verify_heap(heapified, last, expected);
+    verify_heap_iterator(heapified, last, expected);
   }
 }
 
diff --git a/libcxx/test/std/algorithms/alg.sorting/alg.heap.operations/pop.heap/ranges_pop_heap.pass.cpp b/libcxx/test/std/algorithms/alg.sorting/alg.heap.operations/pop.heap/ranges_pop_heap.pass.cpp
index e190586fef813bb..de22a40d1cd7a96 100644
--- a/libcxx/test/std/algorithms/alg.sorting/alg.heap.operations/pop.heap/ranges_pop_heap.pass.cpp
+++ b/libcxx/test/std/algorithms/alg.sorting/alg.heap.operations/pop.heap/ranges_pop_heap.pass.cpp
@@ -60,6 +60,14 @@ static_assert(!HasPopHeapR<UncheckedRange<const int*>>); // Doesn't satisfy `sor
 
 template <std::size_t N, class T, class Iter>
 constexpr void verify_heap(const std::array<T, N>& heapified, Iter last, std::array<T, N> expected) {
+  assert(heapified == expected);
+  assert(la...
[truncated]

@github-actions
Copy link

github-actions bot commented Oct 30, 2023

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

Copy link
Contributor

@philnik777 philnik777 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We actually try to make the tests under test/std strictly conforming code, so this doesn't need any discussion. We're just not perfect (far from it) at spotting implementation-specific assumptions. Thanks for fixing these cases!

There are a few minor things. The rest looks pretty good.

@@ -60,6 +60,13 @@ static_assert(!HasMakeHeapR<UncheckedRange<const int*>>); // Doesn't satisfy `so

template <std::size_t N, class T, class Iter>
constexpr void verify_heap(const std::array<T, N>& heapified, Iter last, std::array<T, N> expected) {
assert(heapified == expected);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks wrong to me. We should keep the iterator and range overload tests equivalent. Same for a few cases below.

Copy link
Contributor Author

@wdunicornpro wdunicornpro Oct 31, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I made some efforts trying to unify those two sets of tests, but since contiguous_iterator is only designed to hold pointers (as is suggested here: test_iterators.h#L344), I couldn't find an easy way to do that. I ended up deleting that static assertion and made some changes to contiguous_iterator.
Those changes did not break any ranges tests, but since we use this class quite extensively, I would like your opinion on whether those changes make sense to the rest of the test suite.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think we should remove that static assertion. I'm also not sure what the problem was you were trying to solve with that change. I you need a range you can just do std::ranges::subrange(Iter(array.data()), Sent(array.data() + array.size())).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For last in verify_heap, we get contiguous_iterator<int*> in some cases and std::array::iterator in some other cases, and we later on want to compare it with heapified.end(). Since there isn't a strictly conforming way to cast std::array::iterator to pointers (correct me if I'm wrong), the two solutions I was to either allow contiguous_iterator to contain std::array::iterator, or to check equality in different ways, as illustrated in e69008d.

In hindsight, the naming in e69008d could be misleading. If the general idea of it looks good to you, I can refine it as below:

template <std::size_t N, class T>
constexpr void verify_last(const std::array<T, N>& heapified, T *last) {
  assert(last == heapified.data() + heapified.size());
}

template <std::size_t N, class T>
constexpr void verify_last(const std::array<T, N>& heapified, const typename std::array<T, N>::iterator& last) {
  assert(last == heapified.end());
}

template <std::size_t N, class T, class Iter>
constexpr void verify_heap(const std::array<T, N>& heapified, Iter last, const std::array<T, N>& expected) {
  assert(heapified == expected);
  verify_last(heapified, base(last));
  assert(std::is_heap(heapified.begin(), heapified.end()));
}

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can use std::to_address, but I think we should instead simply remove the uses of array::iterator, since we care about the algorithm and not the container.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree that we should use pointers as much as possible for these tests. In practice, this might require a bigger rewriting of the tests. For now, I have updated verify_heap so that we are eventually checking equality of pointers.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@philnik777 Do the new changes look good to you?

@ldionne
Copy link
Member

ldionne commented Oct 31, 2023

Thanks for the patch! I second @philnik777 here, this needs no discussion, this is a pure improvement and we already strive to do that but it's just hard to spot with a single implementation. I'll let @philnik777 review this in detail and merge once satisfied.

@wdunicornpro wdunicornpro force-pushed the libcxx/test/fix_std_array_iterator branch 2 times, most recently from 06d99ab to 5eb391e Compare November 1, 2023 18:16
@wdunicornpro wdunicornpro force-pushed the libcxx/test/fix_std_array_iterator branch from 5eb391e to 4724f60 Compare November 1, 2023 21:13
Copy link
Contributor

@philnik777 philnik777 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry that it took me so long. I'm fine with this, but it would be nice to clean this up further.

Anyways, this is definitely a step in the right direction. Thanks again for working on this. LGTM.

@philnik777 philnik777 merged commit d05bada into llvm:main Nov 12, 2023
@wdunicornpro wdunicornpro deleted the libcxx/test/fix_std_array_iterator branch November 14, 2023 23:23
zahiraam pushed a commit to zahiraam/llvm-project that referenced this pull request Nov 20, 2023
…lvm#70729)

This is to modify a list of libcxx tests written under the assumption
that iterators for std::array, std::string_view, and std::string are
pointers. The motivation for this PR is to make the tests more universal
and potentially being used to test other C++ standard library
implementations, for example
[microsoft/STL](https://github.com/microsoft/STL).

I can confirm that this patch makes a number of tests compatible with
microsoft STL:
`Failed :  204 (2.12%)`  ->  `Failed :  136 (1.42%)`
, and does not break any tests on `libcxx`.

This is not a complete list of such incompatibilities, but I am hoping
this will start a discussion about whether we are open to accepting such
changes.
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.

4 participants