brintos

brintos / llvm-project-archived public Read only

0
0
Text · 11.4 KiB · 27babf3 Raw
294 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// UNSUPPORTED: c++03, c++11, c++14, c++1710 11// template <input_iterator I1, sentinel_for<_I1> S1, input_iterator I2, sentinel_for<_I2> S2,12//           class Pred = ranges::equal_to, class Proj1 = identity, class Proj2 = identity>13//   requires indirectly_comparable<I1, I2, Pred, Proj1, Proj2>14// constexpr mismatch_result<_I1, _I2>15// ranges::mismatch()(I1 first1, S1 last1, I2 first2, S2 last2, Pred pred = {}, Proj1 proj1 = {}, Proj2 proj2 = {})16 17// template <input_range R1, input_range R2,18//           class Pred = ranges::equal_to, class Proj1 = identity, class Proj2 = identity>19//   requires indirectly_comparable<iterator_t<R1>, iterator_t<R2>, Pred, Proj1, Proj2>20// constexpr mismatch_result<borrowed_iterator_t<R1>, borrowed_iterator_t<R2>>21// ranges::mismatch(R1&& r1, R2&& r2, Pred pred = {}, Proj1 proj1 = {}, Proj2 proj2 = {})22 23#include <algorithm>24#include <array>25#include <cassert>26#include <functional>27#include <ranges>28 29#include "test_iterators.h"30 31template <class Iter1, class Iter2>32constexpr void test_iterators(Iter1 begin1, Iter1 end1, Iter2 begin2, Iter2 end2, int* expected1, int* expected2) {33  using Expected = std::ranges::mismatch_result<Iter1, Iter2>;34  std::same_as<Expected> auto ret = std::ranges::mismatch(std::move(begin1), sentinel_wrapper<Iter1>(std::move(end1)),35                                                          std::move(begin2), sentinel_wrapper<Iter2>(std::move(end2)));36  assert(base(ret.in1) == expected1);37  assert(base(ret.in2) == expected2);38}39 40template <class Iter1, class Iter2>41constexpr void test_iters() {42  int a[] = {1, 2, 3, 4, 5};43  int b[] = {1, 2, 3, 5, 4};44 45  test_iterators(Iter1(a), Iter1(a + 5), Iter2(b), Iter2(b + 5), a + 3, b + 3);46}47 48constexpr bool test() {49  test_iters<cpp17_input_iterator<int*>, cpp17_input_iterator<int*>>();50  test_iters<cpp17_input_iterator<int*>, cpp20_input_iterator<int*>>();51  test_iters<cpp17_input_iterator<int*>, forward_iterator<int*>>();52  test_iters<cpp17_input_iterator<int*>, bidirectional_iterator<int*>>();53  test_iters<cpp17_input_iterator<int*>, random_access_iterator<int*>>();54  test_iters<cpp17_input_iterator<int*>, contiguous_iterator<int*>>();55  test_iters<cpp17_input_iterator<int*>, int*>();56 57  test_iters<cpp20_input_iterator<int*>, cpp17_input_iterator<int*>>();58  test_iters<cpp20_input_iterator<int*>, cpp20_input_iterator<int*>>();59  test_iters<cpp20_input_iterator<int*>, forward_iterator<int*>>();60  test_iters<cpp20_input_iterator<int*>, bidirectional_iterator<int*>>();61  test_iters<cpp20_input_iterator<int*>, random_access_iterator<int*>>();62  test_iters<cpp20_input_iterator<int*>, contiguous_iterator<int*>>();63  test_iters<cpp20_input_iterator<int*>, int*>();64 65  test_iters<forward_iterator<int*>, cpp17_input_iterator<int*>>();66  test_iters<forward_iterator<int*>, cpp20_input_iterator<int*>>();67  test_iters<forward_iterator<int*>, forward_iterator<int*>>();68  test_iters<forward_iterator<int*>, bidirectional_iterator<int*>>();69  test_iters<forward_iterator<int*>, random_access_iterator<int*>>();70  test_iters<forward_iterator<int*>, contiguous_iterator<int*>>();71  test_iters<forward_iterator<int*>, int*>();72 73  test_iters<bidirectional_iterator<int*>, cpp17_input_iterator<int*>>();74  test_iters<bidirectional_iterator<int*>, cpp20_input_iterator<int*>>();75  test_iters<bidirectional_iterator<int*>, forward_iterator<int*>>();76  test_iters<bidirectional_iterator<int*>, bidirectional_iterator<int*>>();77  test_iters<bidirectional_iterator<int*>, random_access_iterator<int*>>();78  test_iters<bidirectional_iterator<int*>, contiguous_iterator<int*>>();79  test_iters<bidirectional_iterator<int*>, int*>();80 81  test_iters<random_access_iterator<int*>, cpp17_input_iterator<int*>>();82  test_iters<random_access_iterator<int*>, cpp20_input_iterator<int*>>();83  test_iters<random_access_iterator<int*>, forward_iterator<int*>>();84  test_iters<random_access_iterator<int*>, bidirectional_iterator<int*>>();85  test_iters<random_access_iterator<int*>, random_access_iterator<int*>>();86  test_iters<random_access_iterator<int*>, contiguous_iterator<int*>>();87  test_iters<random_access_iterator<int*>, int*>();88 89  test_iters<contiguous_iterator<int*>, cpp17_input_iterator<int*>>();90  test_iters<contiguous_iterator<int*>, cpp20_input_iterator<int*>>();91  test_iters<contiguous_iterator<int*>, forward_iterator<int*>>();92  test_iters<contiguous_iterator<int*>, bidirectional_iterator<int*>>();93  test_iters<contiguous_iterator<int*>, random_access_iterator<int*>>();94  test_iters<contiguous_iterator<int*>, contiguous_iterator<int*>>();95  test_iters<contiguous_iterator<int*>, int*>();96 97  test_iters<int*, cpp17_input_iterator<int*>>();98  test_iters<int*, cpp20_input_iterator<int*>>();99  test_iters<int*, forward_iterator<int*>>();100  test_iters<int*, bidirectional_iterator<int*>>();101  test_iters<int*, random_access_iterator<int*>>();102  test_iters<int*, contiguous_iterator<int*>>();103  test_iters<int*, int*>();104 105  { // test with a range106    std::array<int, 5> a = {1, 2, 3, 4, 5};107    std::array<int, 5> b = {1, 2, 3, 5, 4};108    using Expected = std::ranges::mismatch_result<std::array<int, 5>::iterator, std::array<int, 5>::iterator>;109    std::same_as<Expected> auto ret = std::ranges::mismatch(a, b);110    assert(ret.in1 == a.begin() + 3);111    assert(ret.in2 == b.begin() + 3);112  }113 114  { // test with non-iterator sentinel115    int a[] = {1, 2, 3, 4, 5};116    int b[] = {1, 2, 3, 5, 4};117 118    using Iter = int*;119    using Sentinel = sentinel_wrapper<Iter>;120    using Expected = std::ranges::mismatch_result<Iter, Iter>;121 122    std::same_as<Expected> auto r = std::ranges::mismatch(Iter(a), Sentinel(a + 5), Iter(b), Sentinel(b + 5));123    assert(r.in1 == a + 3);124    assert(r.in2 == b + 3);125  }126 127  { // test with different array sizes128    {129      int a[] = {1, 2, 3};130      int b[] = {1, 2};131      test_iterators(a, a + 3, b, b + 2, a + 2, b + 2);132      using Expected = std::ranges::mismatch_result<int*, int*>;133      std::same_as<Expected> auto ret = std::ranges::mismatch(a, b);134      assert(ret.in1 == a + 2);135      assert(ret.in2 == b + 2);136    }137    {138      int a[] = {1, 2};139      int b[] = {1, 2, 3};140      test_iterators(a, a + 2, b, b + 3, a + 2, b + 2);141      using Expected = std::ranges::mismatch_result<int*, int*>;142      std::same_as<Expected> auto ret = std::ranges::mismatch(a, b);143      assert(ret.in1 == a + 2);144      assert(ret.in2 == b + 2);145    }146  }147 148  { // test with borrowed ranges149    int r1[] = {1, 2, 3, 4, 5};150    int r2[] = {1, 2, 3, 5, 4};151 152    using Expected = std::ranges::mismatch_result<int*, int*>;153    {154      std::same_as<Expected> auto ret = std::ranges::mismatch(r1, std::views::all(r2));155      assert(ret.in1 == r1 + 3);156      assert(ret.in2 == r2 + 3);157    }158    {159      std::same_as<Expected> auto ret = std::ranges::mismatch(std::views::all(r1), r2);160      assert(ret.in1 == r1 + 3);161      assert(ret.in2 == r2 + 3);162    }163    {164      std::same_as<Expected> auto ret = std::ranges::mismatch(std::views::all(r1), std::views::all(r2));165      assert(ret.in1 == r1 + 3);166      assert(ret.in2 == r2 + 3);167    }168  }169 170  { // test structured bindings171    int a[] = {1, 2, 3, 4};172    int b[] = {1, 2, 4, 8, 16};173    auto [ai, bi] = std::ranges::mismatch(a, b);174    assert(ai == a + 2);175    assert(bi == b + 2);176    auto [aj, bj] = std::ranges::mismatch(a, a+4, b, b+5);177    assert(aj == a + 2);178    assert(bj == b + 2);179  }180 181  { // test predicate182    {183      int a[] = {7, 6, 9, 3, 5, 1, 2, 4};184      int b[] = {6, 5, 8, 2, 5, 1, 2, 4};185      auto ret = std::ranges::mismatch(a, a + 8, b, b + 8, std::ranges::greater{});186      assert(ret.in1 == a + 4);187      assert(ret.in2 == b + 4);188      assert(*ret.in1 == 5);189      assert(*ret.in2 == 5);190    }191 192    {193      int a[] = {7, 6, 9, 3, 5, 1, 2, 4};194      int b[] = {6, 5, 8, 2, 5, 1, 2, 4};195      auto ret = std::ranges::mismatch(a, b, std::ranges::greater{});196      assert(ret.in1 == a + 4);197      assert(ret.in2 == b + 4);198      assert(*ret.in1 == 5);199      assert(*ret.in2 == 5);200    }201  }202 203  { // test projection204    {205      int a[] = {7, 6, 9, 3, 5, 1, 2, 4};206      int b[] = {6, 5, 8, 2, 5, 1, 2, 4};207      auto ret = std::ranges::mismatch(a, b,208                                       std::ranges::greater{},209                                       [](int i) { return i == 5 ? +100 : i; },210                                       [](int i) { return i == 5 ? -100 : i; });211      assert(ret.in1 == a + 5);212      assert(ret.in2 == b + 5);213      assert(*ret.in1 == 1);214      assert(*ret.in2 == 1);215    }216    {217      int a[] = {7, 6, 9, 3, 5, 1, 2, 4};218      auto ret = std::ranges::mismatch(a, a,219                                       std::less<double>{},220                                       [](int i) { return i * 1.01; },221                                       [c = 0](int i) mutable { return c++ < 5 ? i * 1.02 : i; });222      assert(ret.in1 == a + 5);223      assert(ret.in2 == a + 5);224      assert(*ret.in1 == 1);225      assert(*ret.in2 == 1);226    }227    {228      int a[] = {7, 6, 9, 3, 5, 1, 2, 4};229      int b[] = {6, 5, 8, 2, 5, 1, 2, 4};230      auto ret = std::ranges::mismatch(a, a + 8, b, b + 8,231                                       std::ranges::greater{},232                                       [](int i) { return i == 5 ? +100 : i; },233                                       [](int i) { return i == 5 ? -100 : i; });234      assert(ret.in1 == a + 5);235      assert(ret.in2 == b + 5);236      assert(*ret.in1 == 1);237      assert(*ret.in2 == 1);238    }239    {240      int a[] = {7, 6, 9, 3, 5, 1, 2, 4};241      auto ret = std::ranges::mismatch(a, a + 8, a, a + 8,242                                       std::less<double>{},243                                       [](int i) { return i * 1.01; },244                                       [c = 0](int i) mutable { return c++ < 5 ? i * 1.02 : i; });245      assert(ret.in1 == a + 5);246      assert(ret.in2 == a + 5);247      assert(*ret.in1 == 1);248      assert(*ret.in2 == 1);249    }250  }251 252  { // test predicate and projection call count253    {254      int pred_count = 0;255      int proj1_count = 0;256      int proj2_count = 0;257      int a[] = {7, 6, 9, 3, 5, 1, 2, 4};258      auto ret = std::ranges::mismatch(a, a,259                                       [&](int lhs, int rhs) { ++pred_count; return lhs == rhs; },260                                       [&](int i) { ++proj1_count; return i; },261                                       [&](int i) { ++proj2_count; return i; });262      assert(ret.in1 == a + 8);263      assert(ret.in2 == a + 8);264      assert(pred_count == 8);265      assert(proj1_count == 8);266      assert(proj2_count == 8);267    }268    {269      int pred_count = 0;270      int proj1_count = 0;271      int proj2_count = 0;272      int a[] = {7, 6, 9, 3, 5, 1, 2, 4};273      auto ret = std::ranges::mismatch(a, a + 8, a, a + 8,274                                       [&](int lhs, int rhs) { ++pred_count; return lhs == rhs; },275                                       [&](int i) { ++proj1_count; return i; },276                                       [&](int i) { ++proj2_count; return i; });277      assert(ret.in1 == a + 8);278      assert(ret.in2 == a + 8);279      assert(pred_count == 8);280      assert(proj1_count == 8);281      assert(proj2_count == 8);282    }283  }284 285  return true;286}287 288int main(int, char**) {289  test();290  static_assert(test());291 292  return 0;293}294