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

// friend constexpr void iter_swap(const inner-iterator& x, const inner-iterator& y)
//   noexcept(noexcept(ranges::iter_swap(x.i_.<current>, y.i_.<current>)))
//   requires indirectly_swappable<iterator_t<Base>>;

#include <ranges>

#include <cassert>
#include <type_traits>
#include <utility>
#include "../types.h"

namespace adl {

template <bool IsNoexcept = false>
struct MaybeNoexceptIterator {
  using value_type = int;
  using difference_type = std::ptrdiff_t;

  value_type* ptr_ = nullptr;
  int* iter_swap_invocations_ = nullptr;

  constexpr MaybeNoexceptIterator() = default;
  constexpr explicit MaybeNoexceptIterator(int& iter_swaps) : iter_swap_invocations_(&iter_swaps) {}

  value_type& operator*() const { return *ptr_; }

  MaybeNoexceptIterator& operator++() { ++ptr_; return *this; }
  MaybeNoexceptIterator operator++(int) {
    MaybeNoexceptIterator prev = *this;
    ++ptr_;
    return prev;
  }

  MaybeNoexceptIterator& operator--() { --ptr_; return *this; }
  MaybeNoexceptIterator operator--(int) {
    MaybeNoexceptIterator prev = *this;
    --ptr_;
    return prev;
  }

  constexpr friend void iter_swap(MaybeNoexceptIterator a, MaybeNoexceptIterator) noexcept(IsNoexcept) {
    if (a.iter_swap_invocations_) {
      ++(*a.iter_swap_invocations_);
    }
  }

  friend bool operator==(const MaybeNoexceptIterator& lhs, const MaybeNoexceptIterator& rhs) {
    return lhs.ptr_ == rhs.ptr_;
  }
};

template <bool IsNoexcept = false>
struct View : std::ranges::view_base {
  int* iter_swaps = nullptr;

  constexpr View() = default;
  constexpr View(int& iter_swap_invocations) : iter_swaps(&iter_swap_invocations) {
  }

  constexpr adl::MaybeNoexceptIterator<IsNoexcept> begin() {
    return adl::MaybeNoexceptIterator<IsNoexcept>(*iter_swaps);
  }
  constexpr adl::MaybeNoexceptIterator<IsNoexcept> end() {
    return adl::MaybeNoexceptIterator<IsNoexcept>(*iter_swaps);
  }
};

} // namespace adl

constexpr bool test() {
  // Can use `iter_swap` with `inner-iterator`; `View` is a forward range.
  {
    // Non-const iterator.
    {
      SplitViewDiff v("abc def", " ");
      auto segment = *v.begin();

      auto i1 = segment.begin();
      auto i2 = i1++;
      static_assert(std::is_void_v<decltype(iter_swap(i1, i2))>);
      assert(*i1 == 'b');
      assert(*i2 == 'a');

      iter_swap(i1, i2);
      assert(*i1 == 'a');
      assert(*i2 == 'b');
      // Note that `iter_swap` swaps characters in the actual underlying range.
      assert(*v.base().begin() == 'b');
    }

    // Const iterator.
    {
      SplitViewDiff v("abc def", " ");
      auto segment = *v.begin();

      auto i1 = segment.begin();
      const auto i2 = i1++;
      static_assert(std::is_void_v<decltype(iter_swap(i1, i2))>);
      static_assert(std::is_void_v<decltype(iter_swap(i2, i2))>);
      assert(*i1 == 'b');
      assert(*i2 == 'a');

      iter_swap(i1, i2);
      assert(*i1 == 'a');
      assert(*i2 == 'b');
      assert(*v.base().begin() == 'b');
    }
  }

  // Can use `iter_swap` with `inner-iterator`; `View` is an input range.
  {

    // Non-const iterator.
    {
      // Iterators belong to the same view.
      {
        SplitViewInput v("abc def", ' ');
        auto segment = *v.begin();

        auto i1 = segment.begin();
        auto i2 = i1;
        ++i1;
        static_assert(std::is_void_v<decltype(iter_swap(i1, i2))>);
        assert(*i1 == 'b');
        // For an input view, all inner iterators are essentially thin proxies to the same underlying iterator.
        assert(*i2 == 'b');

        iter_swap(i1, i2);
        assert(*i1 == 'b');
        assert(*i2 == 'b');
      }

      // Iterators belong to different views.
      {
        SplitViewInput v1("abc def", ' ');
        auto val1 = *v1.begin();
        SplitViewInput v2 = v1;
        auto val2 = *v2.begin();

        auto i1 = val1.begin();
        auto i2 = val2.begin();
        ++i1;
        assert(*i1 == 'b');
        assert(*i2 == 'a');

        iter_swap(i1, i2);
        assert(*i1 == 'a');
        assert(*i2 == 'b');
      }
    }

    // Const iterator.
    {
      SplitViewInput v("abc def", ' ');
      auto segment = *v.begin();

      const auto i1 = segment.begin();
      const auto i2 = i1;
      static_assert(std::is_void_v<decltype(iter_swap(i1, i2))>);
      assert(*i1 == 'a');
      assert(*i2 == 'a');

      iter_swap(i1, i2);
      assert(*i1 == 'a');
      assert(*i2 == 'a');
    }
  }

  // Ensure the `iter_swap` customization point is being used.
  {
    int iter_swap_invocations = 0;
    adl::View<> input(iter_swap_invocations);
    std::ranges::lazy_split_view<adl::View<>, adl::View<>> v(input, adl::View<>());

    auto segment = *v.begin();
    auto i = segment.begin();
    iter_swap(i, i);
    assert(iter_swap_invocations == 1);
  }

  // Check the `noexcept` specification.
  {
    {
      using ThrowingSplitView = std::ranges::lazy_split_view<adl::View<false>, adl::View<false>>;
      using ThrowingValueType = std::ranges::iterator_t<ThrowingSplitView>::value_type;
      using ThrowingIter = std::ranges::iterator_t<ThrowingValueType>;
      ASSERT_NOT_NOEXCEPT(std::ranges::iter_swap(
          std::declval<adl::MaybeNoexceptIterator<false>>(),
          std::declval<adl::MaybeNoexceptIterator<false>>()));
      ASSERT_NOT_NOEXCEPT(iter_swap(std::declval<ThrowingIter>(), std::declval<ThrowingIter>()));
    }

    {
      using NoexceptSplitView = std::ranges::lazy_split_view<adl::View<true>, adl::View<true>>;
      using NoexceptValueType = std::ranges::iterator_t<NoexceptSplitView>::value_type;
      using NoexceptIter = std::ranges::iterator_t<NoexceptValueType>;
      ASSERT_NOEXCEPT(std::ranges::iter_swap(
          std::declval<adl::MaybeNoexceptIterator<true>>(),
          std::declval<adl::MaybeNoexceptIterator<true>>()));
      ASSERT_NOEXCEPT(iter_swap(std::declval<NoexceptIter>(), std::declval<NoexceptIter>()));
    }
  }

  return true;
}

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

  return 0;
}
