brintos

brintos / llvm-project-archived public Read only

0
0
Text · 6.0 KiB · 33f5838 Raw
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