//===----------------------------------------------------------------------===//
//
// 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
//
//===----------------------------------------------------------------------===//

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

// <algorithm>
//
// Range algorithms that take predicates should support predicates that return a non-boolean value as long as the
// returned type is implicitly convertible to bool.

#include <algorithm>

#include <array>
#include <concepts>
#include <initializer_list>
#include <iterator>
#include <ranges>

#include "boolean_testable.h"

constexpr auto unary_pred = [](int i) { return BooleanTestable(i > 0); };
static_assert(!std::same_as<decltype(unary_pred(1)), bool>);
static_assert(std::convertible_to<decltype(unary_pred(1)), bool>);

constexpr auto binary_pred = [](int i, int j) { return BooleanTestable(i < j); };
static_assert(!std::same_as<decltype(binary_pred(1, 2)), bool>);
static_assert(std::convertible_to<decltype(binary_pred(1, 2)), bool>);

// Invokes both the (iterator, sentinel, ...) and the (range, ...) overloads of the given niebloid.

// (in, ...)
template <class Func, std::ranges::range Input, class... Args>
constexpr void test(Func&& func, Input& in, Args&&... args) {
  (void)func(in.begin(), in.end(), std::forward<Args>(args)...);
  (void)func(in, std::forward<Args>(args)...);
}

// (in1, in2, ...)
template <class Func, std::ranges::range Input, class... Args>
constexpr void test(Func&& func, Input& in1, Input& in2, Args&&... args) {
  (void)func(in1.begin(), in1.end(), in2.begin(), in2.end(), std::forward<Args>(args)...);
  (void)func(in1, in2, std::forward<Args>(args)...);
}

// (in, mid, ...)
template <class Func, std::ranges::range Input, class... Args>
constexpr void test_mid(Func&& func, Input& in, std::ranges::iterator_t<Input> mid, Args&&... args) {
  (void)func(in.begin(), mid, in.end(), std::forward<Args>(args)...);
  (void)func(in, mid, std::forward<Args>(args)...);
}

constexpr bool test_all() {
  std::array in  = {1, 2, 3};
  std::array in2 = {4, 5, 6};
  auto mid       = in.begin() + 1;

  std::array output = {7, 8, 9, 10, 11, 12};
  auto out          = output.begin();
  auto out2         = output.begin() + 1;

  int x     = 2;
  int count = 1;

  test(std::ranges::any_of, in, unary_pred);
  test(std::ranges::all_of, in, unary_pred);
  test(std::ranges::none_of, in, unary_pred);
  test(std::ranges::find_if, in, unary_pred);
  test(std::ranges::find_if_not, in, unary_pred);
  test(std::ranges::find_first_of, in, in2, binary_pred);
  test(std::ranges::adjacent_find, in, binary_pred);
  test(std::ranges::mismatch, in, in2, binary_pred);
  test(std::ranges::equal, in, in2, binary_pred);
  test(std::ranges::lexicographical_compare, in, in2, binary_pred);
  test(std::ranges::partition_point, in, unary_pred);
  test(std::ranges::lower_bound, in, x, binary_pred);
  test(std::ranges::upper_bound, in, x, binary_pred);
  test(std::ranges::equal_range, in, x, binary_pred);
  test(std::ranges::binary_search, in, x, binary_pred);

  // min
  (void)std::ranges::min(1, 2, binary_pred);
  (void)std::ranges::min(std::initializer_list<int>{1, 2}, binary_pred);
  (void)std::ranges::min(in, binary_pred);
  // max
  (void)std::ranges::max(1, 2, binary_pred);
  (void)std::ranges::max(std::initializer_list<int>{1, 2}, binary_pred);
  (void)std::ranges::max(in, binary_pred);
  // minmax
  (void)std::ranges::minmax(1, 2, binary_pred);
  (void)std::ranges::minmax(std::initializer_list<int>{1, 2}, binary_pred);
  (void)std::ranges::minmax(in, binary_pred);

  test(std::ranges::min_element, in, binary_pred);
  test(std::ranges::max_element, in, binary_pred);
  test(std::ranges::minmax_element, in, binary_pred);
  test(std::ranges::count_if, in, unary_pred);
  test(std::ranges::search, in, in2, binary_pred);
  test(std::ranges::search_n, in, count, x, binary_pred);
  test(std::ranges::find_end, in, in2, binary_pred);
  test(std::ranges::is_partitioned, in, unary_pred);
  test(std::ranges::is_sorted, in, binary_pred);
  test(std::ranges::is_sorted_until, in, binary_pred);
  test(std::ranges::includes, in, in2, binary_pred);
  test(std::ranges::is_heap, in, binary_pred);
  test(std::ranges::is_heap_until, in, binary_pred);
  (void)std::ranges::clamp(2, 1, 3, binary_pred);
  test(std::ranges::is_permutation, in, in2, binary_pred);
  test(std::ranges::copy_if, in, out, unary_pred);
  test(std::ranges::remove_copy_if, in, out, unary_pred);
  test(std::ranges::replace_if, in, unary_pred, x);
  test(std::ranges::replace_copy_if, in, out, unary_pred, x);
  test(std::ranges::unique_copy, in, out, binary_pred);
  test(std::ranges::partition_copy, in, out, out2, unary_pred);
  test(std::ranges::partial_sort_copy, in, in2, binary_pred);
  test(std::ranges::merge, in, in2, out, binary_pred);
  test(std::ranges::set_difference, in, in2, out, binary_pred);
  test(std::ranges::set_intersection, in, in2, out, binary_pred);
  test(std::ranges::set_symmetric_difference, in, in2, out, binary_pred);
  test(std::ranges::set_union, in, in2, out, binary_pred);
  test(std::ranges::remove_if, in, unary_pred);
  test(std::ranges::unique, in, binary_pred);
  test(std::ranges::partition, in, unary_pred);
  if (!std::is_constant_evaluated())
    test(std::ranges::stable_partition, in, unary_pred);
  test(std::ranges::sort, in, binary_pred);
  if (!std::is_constant_evaluated())
    test(std::ranges::stable_sort, in, binary_pred);
  test_mid(std::ranges::partial_sort, in, mid, binary_pred);
  test_mid(std::ranges::nth_element, in, mid, binary_pred);
  if (!std::is_constant_evaluated())
    test_mid(std::ranges::inplace_merge, in, mid, binary_pred);
  test(std::ranges::make_heap, in, binary_pred);
  test(std::ranges::push_heap, in, binary_pred);
  test(std::ranges::pop_heap, in, binary_pred);
  test(std::ranges::sort_heap, in, binary_pred);
  test(std::ranges::prev_permutation, in, binary_pred);
  test(std::ranges::next_permutation, in, binary_pred);

  return true;
}

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

  return 0;
}
