159 lines · cpp
1//===----------------------------------------------------------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9// <algorithm>10 11// UNSUPPORTED: c++03, c++11, c++14, c++1712 13// template<input_iterator I, sentinel_for<I> S, class Proj = identity,14// indirect_unary_predicate<projected<I, Proj>> Pred>15// constexpr bool ranges::all_of(I first, S last, Pred pred, Proj proj = {});16// template<input_range R, class Proj = identity,17// indirect_unary_predicate<projected<iterator_t<R>, Proj>> Pred>18// constexpr bool ranges::all_of(R&& r, Pred pred, Proj proj = {});19 20#include <algorithm>21#include <array>22#include <cassert>23#include <ranges>24 25#include "almost_satisfies_types.h"26#include "test_iterators.h"27 28struct UnaryFunctor {29 bool operator()(auto&&);30};31 32template <class It, class Sent = sentinel_wrapper<It>>33concept HasAllOfIt = requires(It first, Sent last) { std::ranges::all_of(first, last, UnaryFunctor{}); };34 35static_assert(HasAllOfIt<int*>);36static_assert(!HasAllOfIt<InputIteratorNotDerivedFrom>);37static_assert(!HasAllOfIt<InputIteratorNotIndirectlyReadable>);38static_assert(!HasAllOfIt<InputIteratorNotInputOrOutputIterator>);39static_assert(!HasAllOfIt<int*, SentinelForNotSemiregular>);40static_assert(!HasAllOfIt<int*, SentinelForNotWeaklyEqualityComparableWith>);41 42template <class Func>43concept HasAllOfItFunc = requires(int* ptr) { std::ranges::all_of(ptr, ptr, Func{}); };44 45static_assert(HasAllOfItFunc<UnaryFunctor>);46static_assert(!HasAllOfItFunc<IndirectUnaryPredicateNotCopyConstructible>);47static_assert(!HasAllOfItFunc<IndirectUnaryPredicateNotPredicate>);48 49template <class Range>50concept HasAllOfR = requires(Range range) { std::ranges::all_of(range, UnaryFunctor{}); };51 52static_assert(HasAllOfR<std::array<int, 10>>);53static_assert(!HasAllOfR<InputRangeNotDerivedFrom>);54static_assert(!HasAllOfR<InputRangeNotIndirectlyReadable>);55static_assert(!HasAllOfR<InputRangeNotInputOrOutputIterator>);56static_assert(!HasAllOfR<InputRangeNotSentinelSemiregular>);57static_assert(!HasAllOfR<InputRangeNotSentinelEqualityComparableWith>);58 59template <class Func>60concept HasAllOfRFunc = requires(std::array<int, 10> range) { std::ranges::all_of(range, Func{}); };61 62static_assert(HasAllOfRFunc<UnaryFunctor>);63static_assert(!HasAllOfRFunc<IndirectUnaryPredicateNotCopyConstructible>);64static_assert(!HasAllOfRFunc<IndirectUnaryPredicateNotPredicate>);65 66template <class It, class Sent = It>67constexpr void test_iterators() {68 { // simple test69 {70 int a[] = {1, 2, 3, 4};71 std::same_as<bool> decltype(auto) ret = std::ranges::all_of(It(a), Sent(It(a + 4)), [](int) { return true; });72 assert(ret);73 }74 {75 int a[] = {1, 2, 3, 4};76 auto range = std::ranges::subrange(It(a), Sent(It(a + 4)));77 std::same_as<bool> decltype(auto) ret = std::ranges::all_of(range, [](int) { return true; });78 assert(ret);79 }80 }81 82 { // check that an empty range works83 std::array<int, 0> a;84 assert(std::ranges::all_of(It(a.data()), Sent(It(a.data())), [](int) { return false; }));85 auto range = std::ranges::subrange(It(a.data()), Sent(It(a.data())));86 assert(std::ranges::all_of(range, [](int) { return false; }));87 }88 89 { // check that the complexity requirements are met90 {91 int predicateCount = 0;92 int projectionCount = 0;93 auto pred = [&](int) { ++predicateCount; return true; };94 auto proj = [&](int i) { ++projectionCount; return i; };95 std::array a = {9, 7, 5, 3};96 assert(std::ranges::all_of(It(a.data()), Sent(It(a.data() + a.size())), pred, proj));97 assert(predicateCount == 4);98 assert(projectionCount == 4);99 }100 {101 int predicateCount = 0;102 int projectionCount = 0;103 auto pred = [&](int) { ++predicateCount; return true; };104 auto proj = [&](int i) { ++projectionCount; return i; };105 std::array a = {9, 7, 5, 3};106 auto range = std::ranges::subrange(It(a.data()), Sent(It(a.data() + a.size())));107 assert(std::ranges::all_of(range, pred, proj));108 assert(predicateCount == 4);109 assert(projectionCount == 4);110 }111 }112 113 { // check that false is returned if no element satisfies the condition114 std::array a = {1, 2, 3, 4};115 assert(!std::ranges::all_of(It(a.data()), Sent(It(a.data() + a.size())), [](int i) { return i > 5; }));116 auto range = std::ranges::subrange(It(a.data()), Sent(It(a.data() + a.size())));117 assert(!std::ranges::all_of(range, [](int i) { return i > 5; }));118 }119 120 { // check that true is returned if all elements satisfy the condition121 std::array a = {1, 2, 3, 4};122 assert(std::ranges::all_of(It(a.data()), Sent(It(a.data() + a.size())), [](int i) { return i < 5; }));123 auto range = std::ranges::subrange(It(a.data()), Sent(It(a.data() + a.size())));124 assert(std::ranges::all_of(range, [](int i) { return i < 5; }));125 }126 127 { // check that false is returned if ony one elements satisfies the condition128 std::array a = {1, 2, 3, 4, 6};129 assert(!std::ranges::all_of(It(a.data()), Sent(It(a.data() + a.size())), [](int i) { return i > 5; }));130 auto range = std::ranges::subrange(It(a.data()), Sent(It(a.data() + a.size())));131 assert(!std::ranges::all_of(range, [](int i) { return i > 5; }));132 }133}134 135constexpr bool test() {136 test_iterators<cpp20_input_iterator<int*>, sentinel_wrapper<cpp20_input_iterator<int*>>>();137 test_iterators<forward_iterator<int*>>();138 test_iterators<bidirectional_iterator<int*>>();139 test_iterators<random_access_iterator<int*>>();140 test_iterators<contiguous_iterator<int*>>();141 test_iterators<int*>();142 143 { // check that std::invoke is used144 struct S { int check; int other; };145 S a[] = {{1, 2}, {1, 7}, {1, 3}};146 assert(std::ranges::all_of(a, a + 3, [](int i) { return i == 1; }, &S::check));147 assert(std::ranges::all_of(a, [](int i) { return i == 1; }, &S::check));148 }149 150 return true;151}152 153int main(int, char**) {154 test();155 static_assert(test());156 157 return 0;158}159