[libcxx-commits] [libcxx] faf7261 - [libc++] Bring std::{any, all, none}_of tests up to current standards (#209266)
via libcxx-commits
libcxx-commits at lists.llvm.org
Mon Jul 20 06:38:10 PDT 2026
Author: Louis Dionne
Date: 2026-07-20T09:38:04-04:00
New Revision: faf7261308da236627ae8f813d17d6e1ef1e9d68
URL: https://github.com/llvm/llvm-project/commit/faf7261308da236627ae8f813d17d6e1ef1e9d68
DIFF: https://github.com/llvm/llvm-project/commit/faf7261308da236627ae8f813d17d6e1ef1e9d68.diff
LOG: [libc++] Bring std::{any,all,none}_of tests up to current standards (#209266)
The tests for these algorithms were minimal, didn't test all iterator
categories, and the constexpr coverage didn't follow our current
practice. This patch brings all three tests (which are very similar) up
to our current standards.
Assisted by Claude
Added:
Modified:
libcxx/test/std/algorithms/alg.nonmodifying/alg.all_of/all_of.pass.cpp
libcxx/test/std/algorithms/alg.nonmodifying/alg.any_of/any_of.pass.cpp
libcxx/test/std/algorithms/alg.nonmodifying/alg.none_of/none_of.pass.cpp
Removed:
################################################################################
diff --git a/libcxx/test/std/algorithms/alg.nonmodifying/alg.all_of/all_of.pass.cpp b/libcxx/test/std/algorithms/alg.nonmodifying/alg.all_of/all_of.pass.cpp
index f9377fb10277f..acbdeda0f82e6 100644
--- a/libcxx/test/std/algorithms/alg.nonmodifying/alg.all_of/all_of.pass.cpp
+++ b/libcxx/test/std/algorithms/alg.nonmodifying/alg.all_of/all_of.pass.cpp
@@ -9,55 +9,90 @@
// <algorithm>
// template <class InputIterator, class Predicate>
-// constexpr bool // constexpr after C++17
-// all_of(InputIterator first, InputIterator last, Predicate pred);
+// constexpr bool all_of(InputIterator first, InputIterator last, Predicate pred); // constexpr since C++20
#include <algorithm>
#include <cassert>
-#include <iterator>
#include "test_macros.h"
#include "test_iterators.h"
+#include "type_algorithms.h"
-struct test1
-{
- TEST_CONSTEXPR bool operator()(const int& i) const
- {
- return i % 2 == 0;
- }
+struct is_odd {
+ TEST_CONSTEXPR bool operator()(const int& i) const { return i % 2 != 0; }
+};
+
+struct counting_predicate {
+ int* times_applied;
+ bool result;
+ TEST_CONSTEXPR counting_predicate(int* counter, bool r) : times_applied(counter), result(r) {}
+ TEST_CONSTEXPR_CXX14 bool operator()(int) const {
+ ++*times_applied;
+ return result;
+ }
};
-#if TEST_STD_VER > 17
-TEST_CONSTEXPR bool test_constexpr() {
- int ia[] = {2, 4, 6, 8};
- int ib[] = {2, 4, 5, 8};
- return std::all_of(std::begin(ia), std::end(ia), test1())
- && !std::all_of(std::begin(ib), std::end(ib), test1())
- ;
+struct Test {
+ template <class Iter>
+ TEST_CONSTEXPR_CXX20 void operator()() {
+ { // an empty range vacuously satisfies the predicate
+ int a[] = {2, 4, 6, 8};
+ // The return type is always `bool`, regardless of the iterator category.
+ ASSERT_SAME_TYPE(bool, decltype(std::all_of(Iter(a), Iter(a), is_odd())));
+ assert(std::all_of(Iter(a), Iter(a), is_odd()));
+ }
+
+ { // every element satisfies the predicate
+ int a[] = {1, 3, 5, 7};
+ assert(std::all_of(Iter(a), Iter(a + 4), is_odd()));
+ }
+
+ { // no element satisfies the predicate
+ int a[] = {2, 4, 6, 8};
+ assert(!std::all_of(Iter(a), Iter(a + 4), is_odd()));
+ }
+
+ { // the only non-satisfying element is the first one
+ int a[] = {2, 1, 3, 5};
+ assert(!std::all_of(Iter(a), Iter(a + 4), is_odd()));
}
-#endif
-int main(int, char**)
-{
- {
- int ia[] = {2, 4, 6, 8};
- const unsigned sa = sizeof(ia)/sizeof(ia[0]);
- assert(std::all_of(cpp17_input_iterator<const int*>(ia),
- cpp17_input_iterator<const int*>(ia + sa), test1()) == true);
- assert(std::all_of(cpp17_input_iterator<const int*>(ia),
- cpp17_input_iterator<const int*>(ia), test1()) == true);
+ { // the only non-satisfying element is in the middle
+ int a[] = {1, 3, 4, 5};
+ assert(!std::all_of(Iter(a), Iter(a + 4), is_odd()));
}
- {
- const int ia[] = {2, 4, 5, 8};
- const unsigned sa = sizeof(ia)/sizeof(ia[0]);
- assert(std::all_of(cpp17_input_iterator<const int*>(ia),
- cpp17_input_iterator<const int*>(ia + sa), test1()) == false);
- assert(std::all_of(cpp17_input_iterator<const int*>(ia),
- cpp17_input_iterator<const int*>(ia), test1()) == true);
+
+ { // the only non-satisfying element is the last one
+ int a[] = {1, 3, 5, 8};
+ assert(!std::all_of(Iter(a), Iter(a + 4), is_odd()));
}
-#if TEST_STD_VER > 17
- static_assert(test_constexpr());
+ { // a single-element range, satisfying and not satisfying the predicate
+ int satisfies = 1;
+ int not_satisfies = 2;
+ assert(std::all_of(Iter(&satisfies), Iter(&satisfies + 1), is_odd()));
+ assert(!std::all_of(Iter(¬_satisfies), Iter(¬_satisfies + 1), is_odd()));
+ }
+ }
+};
+
+TEST_CONSTEXPR_CXX20 bool test() {
+ types::for_each(types::cpp17_input_iterator_list<int*>(), Test());
+
+ { // the predicate is applied at most `last - first` times (complexity requirement)
+ int a[] = {1, 2, 3, 4, 5};
+ int applied = 0;
+ assert(std::all_of(a, a + 5, counting_predicate(&applied, true)));
+ assert(applied == 5);
+ }
+
+ return true;
+}
+
+int main(int, char**) {
+ test();
+#if TEST_STD_VER >= 20
+ static_assert(test());
#endif
return 0;
diff --git a/libcxx/test/std/algorithms/alg.nonmodifying/alg.any_of/any_of.pass.cpp b/libcxx/test/std/algorithms/alg.nonmodifying/alg.any_of/any_of.pass.cpp
index c0b659304db8b..6eb815d4bf652 100644
--- a/libcxx/test/std/algorithms/alg.nonmodifying/alg.any_of/any_of.pass.cpp
+++ b/libcxx/test/std/algorithms/alg.nonmodifying/alg.any_of/any_of.pass.cpp
@@ -9,63 +9,90 @@
// <algorithm>
// template <class InputIterator, class Predicate>
-// constexpr bool // constexpr after C++17
-// any_of(InputIterator first, InputIterator last, Predicate pred);
+// constexpr bool any_of(InputIterator first, InputIterator last, Predicate pred); // constexpr since C++20
#include <algorithm>
#include <cassert>
-#include <iterator>
#include "test_macros.h"
#include "test_iterators.h"
+#include "type_algorithms.h"
-struct test1
-{
- TEST_CONSTEXPR bool operator()(const int& i) const
- {
- return i % 2 == 0;
- }
+struct is_odd {
+ TEST_CONSTEXPR bool operator()(const int& i) const { return i % 2 != 0; }
+};
+
+struct counting_predicate {
+ int* times_applied;
+ bool result;
+ TEST_CONSTEXPR counting_predicate(int* counter, bool r) : times_applied(counter), result(r) {}
+ TEST_CONSTEXPR_CXX14 bool operator()(int) const {
+ ++*times_applied;
+ return result;
+ }
};
-#if TEST_STD_VER > 17
-TEST_CONSTEXPR bool test_constexpr() {
- int ia[] = {2, 4, 6, 8};
- int ib[] = {1, 3, 5, 7};
- return std::any_of(std::begin(ia), std::end(ia), test1())
- && !std::any_of(std::begin(ib), std::end(ib), test1())
- ;
+struct Test {
+ template <class Iter>
+ TEST_CONSTEXPR_CXX20 void operator()() {
+ { // an empty range never contains a matching element
+ int a[] = {1, 2, 3, 4};
+ // The return type is always `bool`, regardless of the iterator category.
+ ASSERT_SAME_TYPE(bool, decltype(std::any_of(Iter(a), Iter(a), is_odd())));
+ assert(!std::any_of(Iter(a), Iter(a), is_odd()));
}
-#endif
-int main(int, char**)
-{
- {
- int ia[] = {2, 4, 6, 8};
- const unsigned sa = sizeof(ia)/sizeof(ia[0]);
- assert(std::any_of(cpp17_input_iterator<const int*>(ia),
- cpp17_input_iterator<const int*>(ia + sa), test1()) == true);
- assert(std::any_of(cpp17_input_iterator<const int*>(ia),
- cpp17_input_iterator<const int*>(ia), test1()) == false);
+ { // no element matches the predicate
+ int a[] = {2, 4, 6, 8};
+ assert(!std::any_of(Iter(a), Iter(a + 4), is_odd()));
}
- {
- const int ia[] = {2, 4, 5, 8};
- const unsigned sa = sizeof(ia)/sizeof(ia[0]);
- assert(std::any_of(cpp17_input_iterator<const int*>(ia),
- cpp17_input_iterator<const int*>(ia + sa), test1()) == true);
- assert(std::any_of(cpp17_input_iterator<const int*>(ia),
- cpp17_input_iterator<const int*>(ia), test1()) == false);
+
+ { // every element matches the predicate
+ int a[] = {1, 3, 5, 7};
+ assert(std::any_of(Iter(a), Iter(a + 4), is_odd()));
}
- {
- const int ia[] = {1, 3, 5, 7};
- const unsigned sa = sizeof(ia)/sizeof(ia[0]);
- assert(std::any_of(cpp17_input_iterator<const int*>(ia),
- cpp17_input_iterator<const int*>(ia + sa), test1()) == false);
- assert(std::any_of(cpp17_input_iterator<const int*>(ia),
- cpp17_input_iterator<const int*>(ia), test1()) == false);
+
+ { // the only matching element is the first one
+ int a[] = {1, 2, 4, 6};
+ assert(std::any_of(Iter(a), Iter(a + 4), is_odd()));
+ }
+
+ { // the only matching element is in the middle
+ int a[] = {2, 4, 5, 8};
+ assert(std::any_of(Iter(a), Iter(a + 4), is_odd()));
}
-#if TEST_STD_VER > 17
- static_assert(test_constexpr());
+ { // the only matching element is the last one
+ int a[] = {2, 4, 6, 7};
+ assert(std::any_of(Iter(a), Iter(a + 4), is_odd()));
+ }
+
+ { // a single-element range, with and without a match
+ int match = 1;
+ int no_match = 2;
+ assert(std::any_of(Iter(&match), Iter(&match + 1), is_odd()));
+ assert(!std::any_of(Iter(&no_match), Iter(&no_match + 1), is_odd()));
+ }
+ }
+};
+
+TEST_CONSTEXPR_CXX20 bool test() {
+ types::for_each(types::cpp17_input_iterator_list<int*>(), Test());
+
+ { // the predicate is applied at most `last - first` times (complexity requirement)
+ int a[] = {1, 2, 3, 4, 5};
+ int applied = 0;
+ assert(!std::any_of(a, a + 5, counting_predicate(&applied, false)));
+ assert(applied == 5);
+ }
+
+ return true;
+}
+
+int main(int, char**) {
+ test();
+#if TEST_STD_VER >= 20
+ static_assert(test());
#endif
return 0;
diff --git a/libcxx/test/std/algorithms/alg.nonmodifying/alg.none_of/none_of.pass.cpp b/libcxx/test/std/algorithms/alg.nonmodifying/alg.none_of/none_of.pass.cpp
index 8d63ecb6c17a5..4a1c5c5bd5c4d 100644
--- a/libcxx/test/std/algorithms/alg.nonmodifying/alg.none_of/none_of.pass.cpp
+++ b/libcxx/test/std/algorithms/alg.nonmodifying/alg.none_of/none_of.pass.cpp
@@ -9,63 +9,90 @@
// <algorithm>
// template <class InputIterator, class Predicate>
-// bool
-// none_of(InputIterator first, InputIterator last, Predicate pred);
+// constexpr bool none_of(InputIterator first, InputIterator last, Predicate pred); // constexpr since C++20
#include <algorithm>
#include <cassert>
-#include <iterator>
#include "test_macros.h"
#include "test_iterators.h"
+#include "type_algorithms.h"
-struct test1
-{
- TEST_CONSTEXPR bool operator()(const int& i) const
- {
- return i % 2 == 0;
- }
+struct is_odd {
+ TEST_CONSTEXPR bool operator()(const int& i) const { return i % 2 != 0; }
+};
+
+struct counting_predicate {
+ int* times_applied;
+ bool result;
+ TEST_CONSTEXPR counting_predicate(int* counter, bool r) : times_applied(counter), result(r) {}
+ TEST_CONSTEXPR_CXX14 bool operator()(int) const {
+ ++*times_applied;
+ return result;
+ }
};
-#if TEST_STD_VER > 17
-TEST_CONSTEXPR bool test_constexpr() {
- int ia[] = {1, 3, 6, 7};
- int ib[] = {1, 3, 5, 7};
- return !std::none_of(std::begin(ia), std::end(ia), test1())
- && std::none_of(std::begin(ib), std::end(ib), test1())
- ;
+struct Test {
+ template <class Iter>
+ TEST_CONSTEXPR_CXX20 void operator()() {
+ { // an empty range vacuously satisfies none_of
+ int a[] = {1, 3, 5, 7};
+ // The return type is always `bool`, regardless of the iterator category.
+ ASSERT_SAME_TYPE(bool, decltype(std::none_of(Iter(a), Iter(a), is_odd())));
+ assert(std::none_of(Iter(a), Iter(a), is_odd()));
}
-#endif
-int main(int, char**)
-{
- {
- int ia[] = {2, 4, 6, 8};
- const unsigned sa = sizeof(ia)/sizeof(ia[0]);
- assert(std::none_of(cpp17_input_iterator<const int*>(ia),
- cpp17_input_iterator<const int*>(ia + sa), test1()) == false);
- assert(std::none_of(cpp17_input_iterator<const int*>(ia),
- cpp17_input_iterator<const int*>(ia), test1()) == true);
+ { // no element satisfies the predicate
+ int a[] = {2, 4, 6, 8};
+ assert(std::none_of(Iter(a), Iter(a + 4), is_odd()));
}
- {
- const int ia[] = {2, 4, 5, 8};
- const unsigned sa = sizeof(ia)/sizeof(ia[0]);
- assert(std::none_of(cpp17_input_iterator<const int*>(ia),
- cpp17_input_iterator<const int*>(ia + sa), test1()) == false);
- assert(std::none_of(cpp17_input_iterator<const int*>(ia),
- cpp17_input_iterator<const int*>(ia), test1()) == true);
+
+ { // every element satisfies the predicate
+ int a[] = {1, 3, 5, 7};
+ assert(!std::none_of(Iter(a), Iter(a + 4), is_odd()));
}
- {
- const int ia[] = {1, 3, 5, 7};
- const unsigned sa = sizeof(ia)/sizeof(ia[0]);
- assert(std::none_of(cpp17_input_iterator<const int*>(ia),
- cpp17_input_iterator<const int*>(ia + sa), test1()) == true);
- assert(std::none_of(cpp17_input_iterator<const int*>(ia),
- cpp17_input_iterator<const int*>(ia), test1()) == true);
+
+ { // the only satisfying element is the first one
+ int a[] = {1, 2, 4, 6};
+ assert(!std::none_of(Iter(a), Iter(a + 4), is_odd()));
+ }
+
+ { // the only satisfying element is in the middle
+ int a[] = {2, 4, 5, 8};
+ assert(!std::none_of(Iter(a), Iter(a + 4), is_odd()));
}
-#if TEST_STD_VER > 17
- static_assert(test_constexpr());
+ { // the only satisfying element is the last one
+ int a[] = {2, 4, 6, 7};
+ assert(!std::none_of(Iter(a), Iter(a + 4), is_odd()));
+ }
+
+ { // a single-element range, satisfying and not satisfying the predicate
+ int satisfies = 1;
+ int not_satisfies = 2;
+ assert(!std::none_of(Iter(&satisfies), Iter(&satisfies + 1), is_odd()));
+ assert(std::none_of(Iter(¬_satisfies), Iter(¬_satisfies + 1), is_odd()));
+ }
+ }
+};
+
+TEST_CONSTEXPR_CXX20 bool test() {
+ types::for_each(types::cpp17_input_iterator_list<int*>(), Test());
+
+ { // the predicate is applied at most `last - first` times (complexity requirement)
+ int a[] = {1, 2, 3, 4, 5};
+ int applied = 0;
+ assert(std::none_of(a, a + 5, counting_predicate(&applied, false)));
+ assert(applied == 5);
+ }
+
+ return true;
+}
+
+int main(int, char**) {
+ test();
+#if TEST_STD_VER >= 20
+ static_assert(test());
#endif
return 0;
More information about the libcxx-commits
mailing list