10e3dc1a5SNikolas Klauser //===----------------------------------------------------------------------===//
20e3dc1a5SNikolas Klauser //
30e3dc1a5SNikolas Klauser // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40e3dc1a5SNikolas Klauser // See https://llvm.org/LICENSE.txt for license information.
50e3dc1a5SNikolas Klauser // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60e3dc1a5SNikolas Klauser //
70e3dc1a5SNikolas Klauser //===----------------------------------------------------------------------===//
80e3dc1a5SNikolas Klauser
90e3dc1a5SNikolas Klauser // <algorithm>
100e3dc1a5SNikolas Klauser
110e3dc1a5SNikolas Klauser // UNSUPPORTED: c++03, c++11, c++14, c++17
120e3dc1a5SNikolas Klauser
130e3dc1a5SNikolas Klauser // template<input_iterator I, sentinel_for<I> S, class Proj = identity,
140e3dc1a5SNikolas Klauser // indirect_unary_predicate<projected<I, Proj>> Pred>
150e3dc1a5SNikolas Klauser // constexpr bool ranges::none_of(I first, S last, Pred pred, Proj proj = {});
160e3dc1a5SNikolas Klauser // template<input_range R, class Proj = identity,
170e3dc1a5SNikolas Klauser // indirect_unary_predicate<projected<iterator_t<R>, Proj>> Pred>
180e3dc1a5SNikolas Klauser // constexpr bool ranges::none_of(R&& r, Pred pred, Proj proj = {});
190e3dc1a5SNikolas Klauser
200e3dc1a5SNikolas Klauser #include <algorithm>
210e3dc1a5SNikolas Klauser #include <array>
220e3dc1a5SNikolas Klauser #include <cassert>
230e3dc1a5SNikolas Klauser #include <ranges>
240e3dc1a5SNikolas Klauser
250e3dc1a5SNikolas Klauser #include "almost_satisfies_types.h"
260e3dc1a5SNikolas Klauser #include "test_iterators.h"
270e3dc1a5SNikolas Klauser
280e3dc1a5SNikolas Klauser struct UnaryFunctor {
290e3dc1a5SNikolas Klauser bool operator()(auto&&);
300e3dc1a5SNikolas Klauser };
310e3dc1a5SNikolas Klauser
320e3dc1a5SNikolas Klauser template <class It, class Sent = sentinel_wrapper<It>>
330e3dc1a5SNikolas Klauser concept HasNoneOfIt = requires(It first, Sent last) { std::ranges::none_of(first, last, UnaryFunctor{}); };
340e3dc1a5SNikolas Klauser
350e3dc1a5SNikolas Klauser static_assert(HasNoneOfIt<int*>);
360e3dc1a5SNikolas Klauser static_assert(!HasNoneOfIt<InputIteratorNotDerivedFrom>);
370e3dc1a5SNikolas Klauser static_assert(!HasNoneOfIt<InputIteratorNotIndirectlyReadable>);
380e3dc1a5SNikolas Klauser static_assert(!HasNoneOfIt<InputIteratorNotInputOrOutputIterator>);
390e3dc1a5SNikolas Klauser static_assert(!HasNoneOfIt<int*, SentinelForNotSemiregular>);
400e3dc1a5SNikolas Klauser static_assert(!HasNoneOfIt<int*, SentinelForNotWeaklyEqualityComparableWith>);
410e3dc1a5SNikolas Klauser
420e3dc1a5SNikolas Klauser template <class Func>
430e3dc1a5SNikolas Klauser concept HasNoneOfItFunc = requires(int* ptr) { std::ranges::none_of(ptr, ptr, Func{}); };
440e3dc1a5SNikolas Klauser
450e3dc1a5SNikolas Klauser static_assert(HasNoneOfItFunc<UnaryFunctor>);
460e3dc1a5SNikolas Klauser static_assert(!HasNoneOfItFunc<IndirectUnaryPredicateNotCopyConstructible>);
470e3dc1a5SNikolas Klauser static_assert(!HasNoneOfItFunc<IndirectUnaryPredicateNotPredicate>);
480e3dc1a5SNikolas Klauser
490e3dc1a5SNikolas Klauser template <class Range>
500e3dc1a5SNikolas Klauser concept HasNoneOfR = requires(Range range) { std::ranges::none_of(range, UnaryFunctor{}); };
510e3dc1a5SNikolas Klauser
520e3dc1a5SNikolas Klauser static_assert(HasNoneOfR<std::array<int, 10>>);
530e3dc1a5SNikolas Klauser static_assert(!HasNoneOfR<InputRangeNotDerivedFrom>);
540e3dc1a5SNikolas Klauser static_assert(!HasNoneOfR<InputRangeNotIndirectlyReadable>);
550e3dc1a5SNikolas Klauser static_assert(!HasNoneOfR<InputRangeNotInputOrOutputIterator>);
560e3dc1a5SNikolas Klauser static_assert(!HasNoneOfR<InputRangeNotSentinelSemiregular>);
570e3dc1a5SNikolas Klauser static_assert(!HasNoneOfR<InputRangeNotSentinelEqualityComparableWith>);
580e3dc1a5SNikolas Klauser
590e3dc1a5SNikolas Klauser template <class Func>
600e3dc1a5SNikolas Klauser concept HasNoneOfRFunc = requires(std::array<int, 10> range) { std::ranges::none_of(range, Func{}); };
610e3dc1a5SNikolas Klauser
620e3dc1a5SNikolas Klauser static_assert(HasNoneOfRFunc<UnaryFunctor>);
630e3dc1a5SNikolas Klauser static_assert(!HasNoneOfRFunc<IndirectUnaryPredicateNotCopyConstructible>);
640e3dc1a5SNikolas Klauser static_assert(!HasNoneOfRFunc<IndirectUnaryPredicateNotPredicate>);
650e3dc1a5SNikolas Klauser
660e3dc1a5SNikolas Klauser template <class It, class Sent = It>
test_iterators()670e3dc1a5SNikolas Klauser constexpr void test_iterators() {
680e3dc1a5SNikolas Klauser { // simple test
690e3dc1a5SNikolas Klauser {
700e3dc1a5SNikolas Klauser int a[] = {1, 2, 3, 4};
710e3dc1a5SNikolas Klauser std::same_as<bool> decltype(auto) ret = std::ranges::none_of(It(a), Sent(It(a + 4)), [](int) { return true; });
720e3dc1a5SNikolas Klauser assert(!ret);
730e3dc1a5SNikolas Klauser }
740e3dc1a5SNikolas Klauser {
750e3dc1a5SNikolas Klauser int a[] = {1, 2, 3, 4};
760e3dc1a5SNikolas Klauser auto range = std::ranges::subrange(It(a), Sent(It(a + 4)));
770e3dc1a5SNikolas Klauser std::same_as<bool> decltype(auto) ret = std::ranges::none_of(range, [](int) { return true; });
780e3dc1a5SNikolas Klauser assert(!ret);
790e3dc1a5SNikolas Klauser }
800e3dc1a5SNikolas Klauser }
810e3dc1a5SNikolas Klauser
820e3dc1a5SNikolas Klauser { // check that an empty range works
830e3dc1a5SNikolas Klauser std::array<int, 0> a;
840e3dc1a5SNikolas Klauser assert(std::ranges::none_of(It(a.data()), Sent(It(a.data())), [](int) { return false; }));
850e3dc1a5SNikolas Klauser auto range = std::ranges::subrange(It(a.data()), Sent(It(a.data())));
860e3dc1a5SNikolas Klauser assert(std::ranges::none_of(range, [](int) { return false; }));
870e3dc1a5SNikolas Klauser }
880e3dc1a5SNikolas Klauser
890e3dc1a5SNikolas Klauser { // check that the complexity requirements are met
900e3dc1a5SNikolas Klauser {
910e3dc1a5SNikolas Klauser int predicateCount = 0;
920e3dc1a5SNikolas Klauser int projectionCount = 0;
930e3dc1a5SNikolas Klauser auto pred = [&](int) { ++predicateCount; return false; };
940e3dc1a5SNikolas Klauser auto proj = [&](int i) { ++projectionCount; return i; };
950e3dc1a5SNikolas Klauser std::array a = {9, 7, 5, 3};
96*d05bada5SDuo Wang assert(std::ranges::none_of(It(a.data()), Sent(It(a.data() + a.size())), pred, proj));
970e3dc1a5SNikolas Klauser assert(predicateCount == 4);
980e3dc1a5SNikolas Klauser assert(projectionCount == 4);
990e3dc1a5SNikolas Klauser }
1000e3dc1a5SNikolas Klauser {
1010e3dc1a5SNikolas Klauser int predicateCount = 0;
1020e3dc1a5SNikolas Klauser int projectionCount = 0;
1030e3dc1a5SNikolas Klauser auto pred = [&](int) { ++predicateCount; return false; };
1040e3dc1a5SNikolas Klauser auto proj = [&](int i) { ++projectionCount; return i; };
1050e3dc1a5SNikolas Klauser std::array a = {9, 7, 5, 3};
1060e3dc1a5SNikolas Klauser auto range = std::ranges::subrange(It(a.data()), Sent(It(a.data() + a.size())));
1070e3dc1a5SNikolas Klauser assert(std::ranges::none_of(range, pred, proj));
1080e3dc1a5SNikolas Klauser assert(predicateCount == 4);
1090e3dc1a5SNikolas Klauser assert(projectionCount == 4);
1100e3dc1a5SNikolas Klauser }
1110e3dc1a5SNikolas Klauser }
1120e3dc1a5SNikolas Klauser
1130e3dc1a5SNikolas Klauser { // check that true is returned if no element satisfies the condition
1140e3dc1a5SNikolas Klauser std::array a = {1, 2, 3, 4};
1150e3dc1a5SNikolas Klauser assert(std::ranges::none_of(It(a.data()), Sent(It(a.data() + a.size())), [](int i) { return i > 5; }));
1160e3dc1a5SNikolas Klauser auto range = std::ranges::subrange(It(a.data()), Sent(It(a.data() + a.size())));
1170e3dc1a5SNikolas Klauser assert(std::ranges::none_of(range, [](int i) { return i > 5; }));
1180e3dc1a5SNikolas Klauser }
1190e3dc1a5SNikolas Klauser
1200e3dc1a5SNikolas Klauser { // check that false is returned if all elements satisfy the condition
1210e3dc1a5SNikolas Klauser std::array a = {1, 2, 3, 4};
1220e3dc1a5SNikolas Klauser assert(!std::ranges::none_of(It(a.data()), Sent(It(a.data() + a.size())), [](int i) { return i < 5; }));
1230e3dc1a5SNikolas Klauser auto range = std::ranges::subrange(It(a.data()), Sent(It(a.data() + a.size())));
1240e3dc1a5SNikolas Klauser assert(!std::ranges::none_of(range, [](int i) { return i < 5; }));
1250e3dc1a5SNikolas Klauser }
1260e3dc1a5SNikolas Klauser
1270e3dc1a5SNikolas Klauser { // check that false is returned if ony one elements satisfies the condition
1280e3dc1a5SNikolas Klauser std::array a = {1, 2, 3, 4, 6};
1290e3dc1a5SNikolas Klauser assert(!std::ranges::none_of(It(a.data()), Sent(It(a.data() + a.size())), [](int i) { return i > 5; }));
1300e3dc1a5SNikolas Klauser auto range = std::ranges::subrange(It(a.data()), Sent(It(a.data() + a.size())));
1310e3dc1a5SNikolas Klauser assert(!std::ranges::none_of(range, [](int i) { return i > 5; }));
1320e3dc1a5SNikolas Klauser }
1330e3dc1a5SNikolas Klauser }
1340e3dc1a5SNikolas Klauser
test()1350e3dc1a5SNikolas Klauser constexpr bool test() {
1360e3dc1a5SNikolas Klauser test_iterators<cpp20_input_iterator<int*>, sentinel_wrapper<cpp20_input_iterator<int*>>>();
1370e3dc1a5SNikolas Klauser test_iterators<forward_iterator<int*>>();
1380e3dc1a5SNikolas Klauser test_iterators<bidirectional_iterator<int*>>();
1390e3dc1a5SNikolas Klauser test_iterators<random_access_iterator<int*>>();
1400e3dc1a5SNikolas Klauser test_iterators<contiguous_iterator<int*>>();
1410e3dc1a5SNikolas Klauser test_iterators<int*>();
1420e3dc1a5SNikolas Klauser
1430e3dc1a5SNikolas Klauser { // check that std::invoke is used
1440e3dc1a5SNikolas Klauser struct S { int check; int other; };
1450e3dc1a5SNikolas Klauser S a[] = {{1, 2}, {1, 7}, {1, 3}};
1460e3dc1a5SNikolas Klauser assert(std::ranges::none_of(a, a + 3, [](int i) { return i != 1; }, &S::check));
1470e3dc1a5SNikolas Klauser assert(std::ranges::none_of(a, [](int i) { return i != 1; }, &S::check));
1480e3dc1a5SNikolas Klauser }
1490e3dc1a5SNikolas Klauser
1500e3dc1a5SNikolas Klauser return true;
1510e3dc1a5SNikolas Klauser }
1520e3dc1a5SNikolas Klauser
main(int,char **)1530e3dc1a5SNikolas Klauser int main(int, char**) {
1540e3dc1a5SNikolas Klauser test();
1550e3dc1a5SNikolas Klauser static_assert(test());
1560e3dc1a5SNikolas Klauser
1570e3dc1a5SNikolas Klauser return 0;
1580e3dc1a5SNikolas Klauser }
159