//===----------------------------------------------------------------------===//
//
// 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, c++20

// constexpr auto end()
// constexpr auto end() const

#include <array>
#include <cassert>
#include <ranges>

#include "test_iterators.h"

struct DefaultConstructibleView : std::ranges::view_base {
  int* begin() const;
  int* end() const;
};

struct CVCallView : std::ranges::view_base {
  mutable bool const_called = false;
  mutable int i[1];
  constexpr int* begin() {
    const_called = false;
    return i;
  }

  constexpr int* begin() const {
    const_called = true;
    return i;
  }

  constexpr int* end() {
    const_called = false;
    return i + 1;
  }

  constexpr int* end() const {
    const_called = true;
    return i + 1;
  }
};

struct NonConstCommonRange : std::ranges::view_base {
  int* begin();
  int* end();

  int* begin() const;
  sentinel_wrapper<int*> end() const;
};

struct NonConstView : std::ranges::view_base {
  int* begin();
  int* end();
};

template <class T>
concept HasEnd = requires(T t) { t.end(); };

static_assert(HasEnd<std::ranges::as_rvalue_view<DefaultConstructibleView>>);
static_assert(HasEnd<const std::ranges::as_rvalue_view<DefaultConstructibleView>>);
static_assert(HasEnd<std::ranges::as_rvalue_view<NonConstView>>);
static_assert(!HasEnd<const std::ranges::as_rvalue_view<NonConstView>>);

static_assert(std::is_same_v<decltype(std::declval<std::ranges::as_rvalue_view<DefaultConstructibleView>>().end()),
                             std::move_iterator<int*>>);
static_assert(std::is_same_v<decltype(std::declval<const std::ranges::as_rvalue_view<NonConstCommonRange>>().end()),
                             std::move_sentinel<sentinel_wrapper<int*>>>);

template <class Iter, class Sent, bool is_common>
constexpr void test_range() {
  using Expected = std::conditional_t<is_common, std::move_iterator<Sent>, std::move_sentinel<Sent>>;
  int a[]        = {1, 2};
  std::ranges::subrange range(Iter(std::begin(a)), Sent(Iter(std::end(a))));
  std::ranges::as_rvalue_view view(std::move(range));
  std::same_as<Expected> decltype(auto) iter = view.end();
  assert(base(base(iter.base())) == std::end(a));
}

template <class Iter, class Sent>
class WrapRange {
  Iter iter_;
  Sent sent_;

public:
  constexpr WrapRange(Iter iter, Sent sent) : iter_(std::move(iter)), sent_(std::move(sent)) {}

  constexpr Iter begin() const { return iter_; }
  constexpr Sent end() const { return sent_; }
};

template <class Iter, class Sent>
WrapRange(Iter, Sent) -> WrapRange<Iter, Sent>;

template <class Iter, class Sent, bool is_common>
constexpr void test_const_range() {
  using Expected = std::conditional_t<is_common, std::move_iterator<Sent>, std::move_sentinel<Sent>>;
  int a[]        = {1, 2};
  auto range = WrapRange{Iter(a), Sent(Iter(a + 2))};
  const std::ranges::as_rvalue_view view(std::move(range));
  std::same_as<Expected> decltype(auto) iter = view.end();
  assert(base(base(iter.base())) == std::end(a));
}

struct move_iterator_view : std::ranges::view_base {
  constexpr std::move_iterator<int*> begin() const { return {}; }
  constexpr std::move_iterator<int*> end() const { return {}; }
};

constexpr bool test() {
  test_range<cpp17_input_iterator<int*>, sentinel_wrapper<cpp17_input_iterator<int*>>, false>();
  test_range<cpp17_input_iterator<int*>, sized_sentinel<cpp17_input_iterator<int*>>, false>();
  test_range<cpp20_input_iterator<int*>, sentinel_wrapper<cpp20_input_iterator<int*>>, false>();
  test_range<cpp20_input_iterator<int*>, sized_sentinel<cpp20_input_iterator<int*>>, false>();

  types::for_each(types::forward_iterator_list<int*>{}, []<class Iter> {
    test_range<Iter, Iter, true>();
    test_range<Iter, sentinel_wrapper<Iter>, false>();
    test_range<Iter, sized_sentinel<Iter>, false>();
  });

  {
    std::ranges::as_rvalue_view view(CVCallView{});
    (void)view.end();
    assert(view.base().const_called);
  }

  { // check that with a std::move_iterator begin() doesn't return move_iterator<move_iterator<T>>
    std::ranges::as_rvalue_view view{move_iterator_view{}};
    std::same_as<std::move_iterator<int*>> decltype(auto) it = view.end();
    assert(it == std::move_iterator<int*>{});
  }

  return true;
}

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

// gcc cannot have mutable member in constant expression
#if !defined(TEST_COMPILER_GCC)
  static_assert(test());
#endif

  return 0;
}
