[libcxx-commits] [libcxx] [libc++][test] Augment ranges::{fill, fill_n, find} with missing tests (PR #121209)

via libcxx-commits libcxx-commits at lists.llvm.org
Sat Dec 28 05:30:31 PST 2024


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-libcxx

Author: Peng Liu (winner245)

<details>
<summary>Changes</summary>

libc++ currently has very limited test coverage for `std::ranges{fill, fill_n, find}` with `vector<bool>::iterator` optimizations. Specifically, the existing tests for `std::ranges::fill` only covers cases of 1 - 2 bytes, which is merely 1/8 to 1/4 of the `__storage_type` word size. This renders the tests insufficient to validate functionality for whole words, with or without partial words (which necessitates at least 8 bytes of data). Morover, no tests were provided for `ranges::{find, fill_n}` with `vector<bool>::iterator` optimizations. This PR fills in the gap. 

---

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


7 Files Affected:

- (modified) libcxx/test/std/algorithms/alg.modifying.operations/alg.fill/fill.pass.cpp (+11-42) 
- (modified) libcxx/test/std/algorithms/alg.modifying.operations/alg.fill/fill_n.pass.cpp (+100-106) 
- (modified) libcxx/test/std/algorithms/alg.modifying.operations/alg.fill/ranges.fill.pass.cpp (+21-5) 
- (modified) libcxx/test/std/algorithms/alg.modifying.operations/alg.fill/ranges.fill_n.pass.cpp (+17-1) 
- (modified) libcxx/test/std/algorithms/alg.nonmodifying/alg.count/ranges.count.pass.cpp (+46-33) 
- (modified) libcxx/test/std/algorithms/alg.nonmodifying/alg.find/find.pass.cpp (+16) 
- (modified) libcxx/test/std/algorithms/alg.nonmodifying/alg.find/ranges.find.pass.cpp (+41-18) 


``````````diff
diff --git a/libcxx/test/std/algorithms/alg.modifying.operations/alg.fill/fill.pass.cpp b/libcxx/test/std/algorithms/alg.modifying.operations/alg.fill/fill.pass.cpp
index 619dc7242a3660..4f7abae374d502 100644
--- a/libcxx/test/std/algorithms/alg.modifying.operations/alg.fill/fill.pass.cpp
+++ b/libcxx/test/std/algorithms/alg.modifying.operations/alg.fill/fill.pass.cpp
@@ -49,50 +49,19 @@ struct Test {
 TEST_CONSTEXPR_CXX20 bool test() {
   types::for_each(types::forward_iterator_list<char*>(), Test<char>());
   types::for_each(types::forward_iterator_list<int*>(), Test<int>());
-  {   // test vector<bool>::iterator optimization
-    { // simple case
-      std::vector<bool> in(4, false);
-      std::vector<bool> expected(4, true);
-      std::fill(in.begin(), in.end(), true);
-      assert(in == expected);
-    }
-    { // partial byte in the front is not filled
-      std::vector<bool> in(8, false);
-      std::vector<bool> expected(8, true);
-      expected[0] = false;
-      expected[1] = false;
-      std::fill(in.begin() + 2, in.end(), true);
-      assert(in == expected);
-    }
-    { // partial byte in the back is not filled
-      std::vector<bool> in(8, false);
-      std::vector<bool> expected(8, true);
-      expected[6] = false;
-      expected[7] = false;
-      std::fill(in.begin(), in.end() - 2, true);
-      assert(in == expected);
-    }
-    { // partial byte in the front and back is not filled
-      std::vector<bool> in(16, false);
-      std::vector<bool> expected(16, true);
-      expected[0]  = false;
-      expected[1]  = false;
-      expected[14] = false;
-      expected[15] = false;
-      std::fill(in.begin() + 2, in.end() - 2, true);
-      assert(in == expected);
-    }
-    { // only a few bits of a byte are set
-      std::vector<bool> in(8, false);
-      std::vector<bool> expected(8, true);
-      expected[0] = false;
-      expected[1] = false;
-      expected[6] = false;
-      expected[7] = false;
-      std::fill(in.begin() + 2, in.end() - 2, true);
-      assert(in == expected);
+
+  { // Test vector<bool>::iterator optimization
+    for (std::size_t N = 8; N <= 256; N *= 2) {
+      // Test with both full and partial bytes
+      for (std::size_t offset = 0; offset <= 4; offset += 4) {
+        std::vector<bool> in(N + 2 * offset);
+        std::vector<bool> expected(N, true);
+        std::fill(in.begin() + offset, in.end() - offset, true);
+        assert(std::equal(in.begin() + offset, in.end() - offset, expected.begin()));
+      }
     }
   }
+
   return true;
 }
 
diff --git a/libcxx/test/std/algorithms/alg.modifying.operations/alg.fill/fill_n.pass.cpp b/libcxx/test/std/algorithms/alg.modifying.operations/alg.fill/fill_n.pass.cpp
index 7d6770de702bf3..be9ecf22b4c252 100644
--- a/libcxx/test/std/algorithms/alg.modifying.operations/alg.fill/fill_n.pass.cpp
+++ b/libcxx/test/std/algorithms/alg.modifying.operations/alg.fill/fill_n.pass.cpp
@@ -15,6 +15,7 @@
 
 #include <algorithm>
 #include <cassert>
+#include <vector>
 
 #include "test_macros.h"
 #include "test_iterators.h"
@@ -22,152 +23,145 @@
 
 #if TEST_STD_VER > 17
 TEST_CONSTEXPR bool test_constexpr() {
-    const std::size_t N = 5;
-    int ib[] = {0, 0, 0, 0, 0, 0}; // one bigger than N
-
-    auto it = std::fill_n(std::begin(ib), N, 5);
-    return it == (std::begin(ib) + N)
-        && std::all_of(std::begin(ib), it, [](int a) {return a == 5; })
-        && *it == 0 // don't overwrite the last value in the output array
-        ;
-    }
+  const std::size_t N = 5;
+  int ib[]            = {0, 0, 0, 0, 0, 0}; // one bigger than N
+
+  auto it = std::fill_n(std::begin(ib), N, 5);
+  return it == (std::begin(ib) + N) && std::all_of(std::begin(ib), it, [](int a) { return a == 5; }) &&
+       *it == 0 // don't overwrite the last value in the output array
+      ;
+}
 #endif
 
 typedef UserDefinedIntegral<unsigned> UDI;
 
 template <class Iter>
-void
-test_char()
-{
-    char a[4] = {};
-    Iter it = std::fill_n(Iter(a), UDI(4), char(1));
-    assert(base(it) == a + 4);
-    assert(a[0] == 1);
-    assert(a[1] == 1);
-    assert(a[2] == 1);
-    assert(a[3] == 1);
+void test_char() {
+  char a[4] = {};
+  Iter it   = std::fill_n(Iter(a), UDI(4), char(1));
+  assert(base(it) == a + 4);
+  assert(a[0] == 1);
+  assert(a[1] == 1);
+  assert(a[2] == 1);
+  assert(a[3] == 1);
 }
 
 template <class Iter>
-void
-test_int()
-{
-    int a[4] = {};
-    Iter it = std::fill_n(Iter(a), UDI(4), 1);
-    assert(base(it) == a + 4);
-    assert(a[0] == 1);
-    assert(a[1] == 1);
-    assert(a[2] == 1);
-    assert(a[3] == 1);
+void test_int() {
+  int a[4] = {};
+  Iter it  = std::fill_n(Iter(a), UDI(4), 1);
+  assert(base(it) == a + 4);
+  assert(a[0] == 1);
+  assert(a[1] == 1);
+  assert(a[2] == 1);
+  assert(a[3] == 1);
 }
 
-void
-test_int_array()
-{
-    int a[4] = {};
-    assert(std::fill_n(a, UDI(4), static_cast<char>(1)) == a + 4);
-    assert(a[0] == 1);
-    assert(a[1] == 1);
-    assert(a[2] == 1);
-    assert(a[3] == 1);
+void test_int_array() {
+  int a[4] = {};
+  assert(std::fill_n(a, UDI(4), static_cast<char>(1)) == a + 4);
+  assert(a[0] == 1);
+  assert(a[1] == 1);
+  assert(a[2] == 1);
+  assert(a[3] == 1);
 }
 
 struct source {
-    source() : i(0) { }
+  source() : i(0) {}
 
-    operator int() const { return i++; }
-    mutable int i;
+  operator int() const { return i++; }
+  mutable int i;
 };
 
-void
-test_int_array_struct_source()
-{
-    int a[4] = {};
-    assert(std::fill_n(a, UDI(4), source()) == a + 4);
-    assert(a[0] == 0);
-    assert(a[1] == 1);
-    assert(a[2] == 2);
-    assert(a[3] == 3);
+void test_int_array_struct_source() {
+  int a[4] = {};
+  assert(std::fill_n(a, UDI(4), source()) == a + 4);
+  assert(a[0] == 0);
+  assert(a[1] == 1);
+  assert(a[2] == 2);
+  assert(a[3] == 3);
 }
 
 struct test1 {
-    test1() : c(0) { }
-    test1(char xc) : c(xc + 1) { }
-    char c;
+  test1() : c(0) {}
+  test1(char xc) : c(xc + 1) {}
+  char c;
 };
 
-void
-test_struct_array()
-{
-    test1 test1a[4] = {};
-    assert(std::fill_n(test1a, UDI(4), static_cast<char>(10)) == test1a + 4);
-    assert(test1a[0].c == 11);
-    assert(test1a[1].c == 11);
-    assert(test1a[2].c == 11);
-    assert(test1a[3].c == 11);
+void test_struct_array() {
+  test1 test1a[4] = {};
+  assert(std::fill_n(test1a, UDI(4), static_cast<char>(10)) == test1a + 4);
+  assert(test1a[0].c == 11);
+  assert(test1a[1].c == 11);
+  assert(test1a[2].c == 11);
+  assert(test1a[3].c == 11);
 }
 
-class A
-{
-    char a_;
+class A {
+  char a_;
+
 public:
-    A() {}
-    explicit A(char a) : a_(a) {}
-    operator unsigned char() const {return 'b';}
+  A() {}
+  explicit A(char a) : a_(a) {}
+  operator unsigned char() const { return 'b'; }
 
-    friend bool operator==(const A& x, const A& y)
-        {return x.a_ == y.a_;}
+  friend bool operator==(const A& x, const A& y) { return x.a_ == y.a_; }
 };
 
-void
-test5()
-{
-    A a[3];
-    assert(std::fill_n(&a[0], UDI(3), A('a')) == a+3);
-    assert(a[0] == A('a'));
-    assert(a[1] == A('a'));
-    assert(a[2] == A('a'));
+void test5() {
+  A a[3];
+  assert(std::fill_n(&a[0], UDI(3), A('a')) == a + 3);
+  assert(a[0] == A('a'));
+  assert(a[1] == A('a'));
+  assert(a[2] == A('a'));
 }
 
-struct Storage
-{
-  union
-  {
+struct Storage {
+  union {
     unsigned char a;
     unsigned char b;
   };
 };
 
-void test6()
-{
+void test6() {
   Storage foo[5];
   std::fill_n(&foo[0], UDI(5), Storage());
 }
 
-
-int main(int, char**)
-{
-    test_char<cpp17_output_iterator<char*> >();
-    test_char<forward_iterator<char*> >();
-    test_char<bidirectional_iterator<char*> >();
-    test_char<random_access_iterator<char*> >();
-    test_char<char*>();
-
-    test_int<cpp17_output_iterator<int*> >();
-    test_int<forward_iterator<int*> >();
-    test_int<bidirectional_iterator<int*> >();
-    test_int<random_access_iterator<int*> >();
-    test_int<int*>();
-
-    test_int_array();
-    test_int_array_struct_source();
-    test_struct_array();
-
-    test5();
-    test6();
+int main(int, char**) {
+  test_char<cpp17_output_iterator<char*> >();
+  test_char<forward_iterator<char*> >();
+  test_char<bidirectional_iterator<char*> >();
+  test_char<random_access_iterator<char*> >();
+  test_char<char*>();
+
+  test_int<cpp17_output_iterator<int*> >();
+  test_int<forward_iterator<int*> >();
+  test_int<bidirectional_iterator<int*> >();
+  test_int<random_access_iterator<int*> >();
+  test_int<int*>();
+
+  test_int_array();
+  test_int_array_struct_source();
+  test_struct_array();
+
+  test5();
+  test6();
+
+  { // Test vector<bool>::iterator optimization
+    for (std::size_t N = 8; N <= 256; N *= 2) {
+      // Test with both full and partial bytes
+      for (std::size_t offset = 0; offset <= 4; offset += 4) {
+        std::vector<bool> in(N + 2 * offset);
+        std::vector<bool> expected(N, true);
+        std::fill_n(in.begin() + offset, N + offset, true);
+        assert(std::equal(in.begin() + offset, in.end() - offset, expected.begin()));
+      }
+    }
+  }
 
 #if TEST_STD_VER > 17
-    static_assert(test_constexpr());
+  static_assert(test_constexpr());
 #endif
 
   return 0;
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 5dc375e0e8dc0d..58804bb90b5241 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
@@ -20,9 +20,11 @@
 #include <cassert>
 #include <ranges>
 #include <string>
+#include <vector>
 
 #include "almost_satisfies_types.h"
 #include "test_iterators.h"
+#include "test_macros.h"
 
 template <class Iter, class Sent = sentinel_wrapper<Iter>>
 concept HasFillIt = requires(Iter iter, Sent sent) { std::ranges::fill(iter, sent, int{}); };
@@ -53,7 +55,7 @@ constexpr void test_iterators() {
     }
     {
       int a[3];
-      auto range = std::ranges::subrange(It(a), Sent(It(a + 3)));
+      auto range                = std::ranges::subrange(It(a), Sent(It(a + 3)));
       std::same_as<It> auto ret = std::ranges::fill(range, 1);
       assert(std::all_of(a, a + 3, [](int i) { return i == 1; }));
       assert(base(ret) == a + 3);
@@ -69,7 +71,7 @@ constexpr void test_iterators() {
     {
       std::array<int, 0> a;
       auto range = std::ranges::subrange(It(a.data()), Sent(It(a.data())));
-      auto ret = std::ranges::fill(range, 1);
+      auto ret   = std::ranges::fill(range, 1);
       assert(base(ret) == a.data());
     }
   }
@@ -94,19 +96,19 @@ constexpr bool test() {
     };
     {
       S a[5];
-      std::ranges::fill(a, a + 5, S {true});
+      std::ranges::fill(a, a + 5, S{true});
       assert(std::all_of(a, a + 5, [](S& s) { return s.copied; }));
     }
     {
       S a[5];
-      std::ranges::fill(a, S {true});
+      std::ranges::fill(a, S{true});
       assert(std::all_of(a, a + 5, [](S& s) { return s.copied; }));
     }
   }
 
   { // check that std::ranges::dangling is returned
     [[maybe_unused]] std::same_as<std::ranges::dangling> decltype(auto) ret =
-        std::ranges::fill(std::array<int, 10> {}, 1);
+        std::ranges::fill(std::array<int, 10>{}, 1);
   }
 
   { // check that std::ranges::dangling isn't returned with a borrowing range
@@ -131,6 +133,20 @@ constexpr bool test() {
     }
   }
 
+#if TEST_STD_VER >= 23
+  { // Test vector<bool>::iterator optimization
+    for (std::size_t N = 8; N <= 256; N *= 2) {
+      // Test with both full and partial bytes
+      for (std::size_t offset : {0, 4}) {
+        std::vector<bool> in(N + 2 * offset);
+        std::vector<bool> expected(N, true);
+        std::ranges::fill(std::ranges::begin(in) + offset, std::ranges::end(in) - offset, true);
+        assert(std::equal(in.begin() + offset, in.end() - offset, expected.begin()));
+      }
+    }
+  }
+#endif
+
   return true;
 }
 
diff --git a/libcxx/test/std/algorithms/alg.modifying.operations/alg.fill/ranges.fill_n.pass.cpp b/libcxx/test/std/algorithms/alg.modifying.operations/alg.fill/ranges.fill_n.pass.cpp
index 10ff385d474281..945960681d8e5d 100644
--- a/libcxx/test/std/algorithms/alg.modifying.operations/alg.fill/ranges.fill_n.pass.cpp
+++ b/libcxx/test/std/algorithms/alg.modifying.operations/alg.fill/ranges.fill_n.pass.cpp
@@ -18,9 +18,11 @@
 #include <cassert>
 #include <ranges>
 #include <string>
+#include <vector>
 
 #include "almost_satisfies_types.h"
 #include "test_iterators.h"
+#include "test_macros.h"
 
 template <class Iter>
 concept HasFillN = requires(Iter iter) { std::ranges::fill_n(iter, int{}, int{}); };
@@ -68,7 +70,7 @@ constexpr bool test() {
     };
 
     S a[5];
-    std::ranges::fill_n(a, 5, S {});
+    std::ranges::fill_n(a, 5, S{});
     assert(std::all_of(a, a + 5, [](S& s) { return s.copied; }));
   }
 
@@ -79,6 +81,20 @@ constexpr bool test() {
     assert(std::all_of(a.begin(), a.end(), [](auto& s) { return s == "long long string so no SSO"; }));
   }
 
+#if TEST_STD_VER >= 23
+  { // Test vector<bool>::iterator optimization
+    for (std::size_t N = 8; N <= 256; N *= 2) {
+      // Test with both full and partial bytes
+      for (std::size_t offset : {0, 4}) {
+        std::vector<bool> in(N + 2 * offset);
+        std::vector<bool> expected(N, true);
+        std::ranges::fill_n(std::ranges::begin(in) + offset, N, true);
+        assert(std::equal(in.begin() + offset, in.end() - offset, expected.begin()));
+      }
+    }
+  }
+#endif
+
   return true;
 }
 
diff --git a/libcxx/test/std/algorithms/alg.nonmodifying/alg.count/ranges.count.pass.cpp b/libcxx/test/std/algorithms/alg.nonmodifying/alg.count/ranges.count.pass.cpp
index 6030bed47ec6a7..877b6fa34e5bcb 100644
--- a/libcxx/test/std/algorithms/alg.nonmodifying/alg.count/ranges.count.pass.cpp
+++ b/libcxx/test/std/algorithms/alg.nonmodifying/alg.count/ranges.count.pass.cpp
@@ -67,13 +67,13 @@ constexpr void test_iterators() {
   {
     // simple test
     {
-      int a[] = {1, 2, 3, 4};
+      int a[]                               = {1, 2, 3, 4};
       std::same_as<std::ptrdiff_t> auto ret = std::ranges::count(It(a), Sent(It(a + 4)), 3);
       assert(ret == 1);
     }
     {
-      int a[] = {1, 2, 3, 4};
-      auto range = std::ranges::subrange(It(a), Sent(It(a + 4)));
+      int a[]                               = {1, 2, 3, 4};
+      auto range                            = std::ranges::subrange(It(a), Sent(It(a + 4)));
       std::same_as<std::ptrdiff_t> auto ret = std::ranges::count(range, 3);
       assert(ret == 1);
     }
@@ -83,13 +83,13 @@ constexpr void test_iterators() {
     // check that an empty range works
     {
       std::array<int, 0> a = {};
-      auto ret = std::ranges::count(It(a.data()), Sent(It(a.data() + a.size())), 1);
+      auto ret             = std::ranges::count(It(a.data()), Sent(It(a.data() + a.size())), 1);
       assert(ret == 0);
     }
     {
       std::array<int, 0> a = {};
-      auto range = std::ranges::subrange(It(a.data()), Sent(It(a.data() + a.size())));
-      auto ret = std::ranges::count(range, 1);
+      auto range           = std::ranges::subrange(It(a.data()), Sent(It(a.data() + a.size())));
+      auto ret             = std::ranges::count(range, 1);
       assert(ret == 0);
     }
   }
@@ -98,13 +98,13 @@ constexpr void test_iterators() {
     // check that a range with a single element works
     {
       std::array a = {2};
-      auto ret = std::ranges::count(It(a.data()), Sent(It(a.data() + a.size())), 2);
+      auto ret     = std::ranges::count(It(a.data()), Sent(It(a.data() + a.size())), 2);
       assert(ret == 1);
     }
     {
       std::array a = {2};
-      auto range = std::ranges::subrange(It(a.data()), Sent(It(a.data() + a.size())));
-      auto ret = std::ranges::count(range, 2);
+      auto range   = std::ranges::subrange(It(a.data()), Sent(It(a.data() + a.size())));
+      auto ret     = std::ranges::count(range, 2);
       assert(ret == 1);
     }
   }
@@ -113,13 +113,13 @@ constexpr void test_iterators() {
     // check that 0 is returned with no match
     {
       std::array a = {1, 1, 1};
-      auto ret = std::ranges::count(It(a.data()), Sent(It(a.data() + a.size())), 0);
+      auto ret     = std::ranges::count(It(a.data()), Sent(It(a.data() + a.size())), 0);
       assert(ret == 0);
     }
     {
       std::array a = {1, 1, 1};
-      auto range = std::ranges::subrange(It(a.data()), Sent(It(a.data() + a.size())));
-      auto ret = std::ranges::count(range, 0);
+      auto range   = std::ranges::subrange(It(a.data()), Sent(It(a.data() + a.size())));
+      auto ret     = std::ranges::count(range, 0);
       assert(ret == 0);
     }
   }
@@ -128,13 +128,13 @@ constexpr void test_iterators() {
     // check that more than one element is counted
     {
       std::array a = {3, 3, 4, 3, 3};
-      auto ret = std::ranges::count(It(a.data()), Sent(It(a.data() + a.size())), 3);
+      auto ret     = std::ranges::count(It(a.data()), Sent(It(a.data() + a.size())), 3);
       assert(ret == 4);
     }
     {
       std::array a = {3, 3, 4, 3, 3};
-      auto range = std::ranges::subrange(It(a.data()), Sent(It(a.data() + a.size())));
-      auto ret = std::ranges::count(range, 3);
+      auto range   = std::ranges::subrange(It(a.data()), Sent(It(a.data() + a.size())));
+      auto ret     = std::ranges::count(range, 3);
       assert(ret == 4);
     }
   }
@@ -143,13 +143,13 @@ constexpr void test_iterators() {
     // check that all elements are counted
     {
       std::array a = {5, 5, 5, 5};
-      auto ret = std::ranges::count(It(a.data()), Sent(It(a.data() + a.size())), 5);
+      auto ret     = std::ranges::count(It(a.data()), Sent(It(a.data() + a.size())), 5);
       assert(ret == 4);
     }
     {
       std::array a = {5, 5, 5, 5};
-      auto range = std::ranges::subrange(It(a.data()), Sent(It(a.data() + a.size())));
-      auto ret = std::ranges::count(range, 5);
+      auto range   = std::ranges::subrange(It(a.data()), Sent(It(a.data() + a.size())));
+      auto ret     = std::ranges::count(range, 5);
       assert(ret == 4);
     }
   }
@@ -167,12 +167,12 @@ constexpr bool test() {
   {
     // check that projections are used properly and that they are called with the iterator directly
     {
-      int a[] = {1, 2, 3, 4};
+      int a[]  = {1, 2, 3, 4};
       auto ret = std::ranges::count(a, a + 4, a + 3, [](int& i) { return &i; });
       assert(ret == 1);
     }
     {
-      int a[] = {1, 2, 3, 4};
+      int a[]  = {1, 2, 3, 4};
       auto ret = std::ranges::count(a, a + 3, [](int& i) { return &i; });
       assert(ret == 1);
     }
@@ -180,8 +180,10 @@ constexpr bool test() {
 
   {
     // check that std::invoke is used
-    struct S { int i; };
-    S a[] = { S{1}, S{3}, S{2} };
+    struct S {
+      int i;
+    };
+    S a[]                                 = {S{1}, S{3}, S{2}};
     std::same_as<std::ptrdiff_t> auto ret = std::ranges::count(a, 4, &S::i);
     assert(ret == 0);
   }
@@ -189,16 +191,22 @@ constexpr bool test() {
   {
     // count invocations of the projection
     {
-      int a[] = {1, 2, 3, 4};
+      int a[]              = {1, 2, 3, 4};
       int projection_count = 0;
-      auto ret = std::ranges::count(a, a + 4, 2, [&](int i) { ++projection_count; return i; });
+      auto ret             = std::ranges::count(a, a + 4, 2, [&](int i) {
+        ++projection_count;
+        return i;
+      });
       assert(ret == 1);
       assert(projection_count == 4);
     }
     {
-      int a[] = {1, 2, 3, 4};
+      int a[]              = {1, 2, 3, 4};
       int projection_count = 0;
-      auto ret = std::ranges::count(a, 2, [&](int i) { ++projection_count; return i; });
+      auto ret             = std::ranges::count(a, 2, [&](int i) {
+        ++projection_count;
+        return i;
+      });
       assert(ret == 1);
       assert(projection_count == 4);
     }
@@ -208,7 +216,7 @@ constexpr bool test() {
     // check that an immobile type works
     struct NonMovable {
       NonMovable(const NonMovable&) = delete;
-      NonMovable(NonMovable&&) = delete;
+      NonMovable(NonMovable&&)      = delete;
       constexpr NonMovable(int i_) : i(i_) {}
       int i;
 
@@ -216,12 +224,12 @@ constexpr bool test() {
     };
     {
       NonMovable a[] = {9, 8, 4, 3};
-      auto ret = std::ranges::count(a, a + 4, NonMovable(8));
+      auto ret ...
[truncated]

``````````

</details>


https://github.com/llvm/llvm-project/pull/121209


More information about the libcxx-commits mailing list