//===----------------------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

// <algorithm>

// UNSUPPORTED: c++03, c++11, c++14, c++17

// template<forward_iterator I, sentinel_for<I> S, class Proj = identity,
//          indirect_binary_predicate<projected<I, Proj>,
//                                    projected<I, Proj>> Pred = ranges::equal_to>
//   constexpr I ranges::adjacent_find(I first, S last, Pred pred = {}, Proj proj = {});
// template<forward_range R, class Proj = identity,
//          indirect_binary_predicate<projected<iterator_t<R>, Proj>,
//                                    projected<iterator_t<R>, Proj>> Pred = ranges::equal_to>
//   constexpr borrowed_iterator_t<R> ranges::adjacent_find(R&& r, Pred pred = {}, Proj proj = {});

#include <algorithm>
#include <array>
#include <cassert>
#include <cstddef>
#include <ranges>

#include "almost_satisfies_types.h"
#include "boolean_testable.h"
#include "test_iterators.h"

template <class Iter, class Sent = Iter>
concept HasAdjacentFindIt = requires (Iter iter, Sent sent) { std::ranges::adjacent_find(iter, sent); };

struct NotComparable {};

static_assert(HasAdjacentFindIt<int*>);
static_assert(!HasAdjacentFindIt<ForwardIteratorNotDerivedFrom>);
static_assert(!HasAdjacentFindIt<ForwardIteratorNotIncrementable>);
static_assert(!HasAdjacentFindIt<int*, SentinelForNotSemiregular>);
static_assert(!HasAdjacentFindIt<int*, SentinelForNotWeaklyEqualityComparableWith>);
static_assert(!HasAdjacentFindIt<NotComparable*>);

template <class Range>
concept HasAdjacentFindR = requires (Range range) { std::ranges::adjacent_find(range); };

static_assert(HasAdjacentFindR<UncheckedRange<int*>>);
static_assert(!HasAdjacentFindR<ForwardRangeNotDerivedFrom>);
static_assert(!HasAdjacentFindR<ForwardRangeNotIncrementable>);
static_assert(!HasAdjacentFindR<ForwardRangeNotSentinelSemiregular>);
static_assert(!HasAdjacentFindR<ForwardRangeNotSentinelEqualityComparableWith>);
static_assert(!HasAdjacentFindR<UncheckedRange<NotComparable>>);

template <size_t N>
struct Data {
  std::array<int, N> input;
  int expected;
};

template <class Iter, class Sent, size_t N>
constexpr void test(Data<N> d) {
  {
    std::same_as<Iter> decltype(auto) ret =
        std::ranges::adjacent_find(Iter(d.input.data()), Sent(Iter(d.input.data() + d.input.size())));
    assert(base(ret) == d.input.data() + d.expected);
  }
  {
    auto range = std::ranges::subrange(Iter(d.input.data()), Sent(Iter(d.input.data() + d.input.size())));
    std::same_as<Iter> decltype(auto) ret = std::ranges::adjacent_find(range);
    assert(base(ret) == d.input.data() + d.expected);
  }
}

template <class Iter, class Sent = Iter>
constexpr void test_iterators() {
  // simple test
  test<Iter, Sent, 4>({.input = {1, 2, 2, 4}, .expected = 1});
  // last is returned with no match
  test<Iter, Sent, 4>({.input = {1, 2, 3, 4}, .expected = 4});
  // first elements match
  test<Iter, Sent, 4>({.input = {1, 1, 3, 4}, .expected = 0});
  // the first match is returned
  test<Iter, Sent, 7>({.input = {1, 1, 3, 4, 4, 4, 4}, .expected = 0});
  // two element range works
  test<Iter, Sent, 2>({.input = {3, 3}, .expected = 0});
  // single element range works
  test<Iter, Sent, 1>({.input = {1}, .expected = 1});
  // empty range works
  test<Iter, Sent, 0>({.input = {}, .expected = 0});
}

constexpr bool test() {
  test_iterators<forward_iterator<int*>, sentinel_wrapper<forward_iterator<int*>>>();
  test_iterators<forward_iterator<int*>>();
  test_iterators<bidirectional_iterator<int*>>();
  test_iterators<random_access_iterator<int*>>();
  test_iterators<contiguous_iterator<int*>>();
  test_iterators<int*>();
  test_iterators<const int*>();

  { // check that ranges::dangling is returned
    [[maybe_unused]] std::same_as<std::ranges::dangling> decltype(auto) ret =
        std::ranges::adjacent_find(std::array{1, 2, 3, 4});
  }

  { // check that the complexity requirements are met with no match
    {
      int predicateCount = 0;
      auto pred = [&](int, int) { ++predicateCount; return false; };
      auto projectionCount = 0;
      auto proj = [&](int i) { ++projectionCount; return i; };
      int a[] = {1, 2, 3, 4, 5};
      auto ret = std::ranges::adjacent_find(a, a + 5, pred, proj);
      assert(ret == a + 5);
      assert(predicateCount == 4);
      assert(projectionCount == 8);
    }
    {
      int predicateCount = 0;
      auto pred = [&](int, int) { ++predicateCount; return false; };
      auto projectionCount = 0;
      auto proj = [&](int i) { ++projectionCount; return i; };
      int a[] = {1, 2, 3, 4, 5};
      auto ret = std::ranges::adjacent_find(a, pred, proj);
      assert(ret == a + 5);
      assert(predicateCount == 4);
      assert(projectionCount == 8);
    }
  }

  { // check that the complexity requirements are met with a match
    {
      int predicateCount = 0;
      auto pred = [&](int i, int j) { ++predicateCount; return i == j; };
      auto projectionCount = 0;
      auto proj = [&](int i) { ++projectionCount; return i; };
      int a[] = {1, 2, 4, 4, 5};
      auto ret = std::ranges::adjacent_find(a, a + 5, pred, proj);
      assert(ret == a + 2);
      assert(predicateCount == 3);
      assert(projectionCount == 6);
    }
    {
      int predicateCount = 0;
      auto pred = [&](int i, int j) { ++predicateCount; return i == j; };
      auto projectionCount = 0;
      auto proj = [&](int i) { ++projectionCount; return i; };
      int a[] = {1, 2, 4, 4, 5};
      auto ret = std::ranges::adjacent_find(a, pred, proj);
      assert(ret == a + 2);
      assert(predicateCount == 3);
      assert(projectionCount == 6);
    }
  }

  { // check that std::invoke is used
    struct S {
      constexpr S(int i_) : i(i_) {}
      constexpr bool compare(const S& j) const { return j.i == i; }
      constexpr const S& identity() const { return *this; }
      int i;
    };
    {
      S a[] = {1, 2, 3, 4};
      auto ret = std::ranges::adjacent_find(std::begin(a), std::end(a), &S::compare, &S::identity);
      assert(ret == a + 4);
    }
    {
      S a[] = {1, 2, 3, 4};
      auto ret = std::ranges::adjacent_find(a, &S::compare, &S::identity);
      assert(ret == a + 4);
    }
  }

  { // check that the implicit conversion to bool works
    {
      int a[] = {1, 2, 2, 4};
      auto ret = std::ranges::adjacent_find(a, a + 4, [](int i, int j) { return BooleanTestable{i == j}; });
      assert(ret == a + 1);
    }
    {
      int a[] = {1, 2, 2, 4};
      auto ret = std::ranges::adjacent_find(a, [](int i, int j) { return BooleanTestable{i == j}; });
      assert(ret == a + 1);
    }
  }

  return true;
}

int main(int, char**) {
  test();
  static_assert(test());

  return 0;
}
