// This file is part of Eigen, a lightweight C++ template library
// for linear algebra.
//
// Copyright (C) 2018-2019 Gael Guennebaud <gael.guennebaud@inria.fr>
//
// This Source Code Form is subject to the terms of the Mozilla
// Public License v. 2.0. If a copy of the MPL was not distributed
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.

// Include <ranges> before main.h because main.h redefines min/max as
// error macros, which conflicts with std::ranges internals.
#if __cplusplus >= 202002L
#include <ranges>
#include <concepts>
#endif

#include "main.h"
#include <iterator>
#include <numeric>

#if __cplusplus >= 202002L && defined(__cpp_lib_ranges) && __cpp_lib_ranges >= 201911L
#define EIGEN_TEST_CXX20_RANGES 1
#endif

template <class Iterator>
std::reverse_iterator<Iterator> make_reverse_iterator(Iterator i) {
  return std::reverse_iterator<Iterator>(i);
}

using std::is_sorted;

template <typename XprType>
bool is_pointer_based_stl_iterator(const internal::pointer_based_stl_iterator<XprType>&) {
  return true;
}

template <typename XprType>
bool is_generic_randaccess_stl_iterator(const internal::generic_randaccess_stl_iterator<XprType>&) {
  return true;
}

template <typename Iter>
bool is_default_constructible_and_assignable(const Iter& it) {
  VERIFY(std::is_default_constructible<Iter>::value);
  VERIFY(std::is_nothrow_default_constructible<Iter>::value);
  Iter it2;
  it2 = it;
  return (it == it2);
}

template <typename Xpr>
void check_begin_end_for_loop(Xpr xpr) {
  const Xpr& cxpr(xpr);
  Index i = 0;

  i = 0;
  for (typename Xpr::iterator it = xpr.begin(); it != xpr.end(); ++it) {
    VERIFY_IS_EQUAL(*it, xpr[i++]);
  }

  i = 0;
  for (typename Xpr::const_iterator it = xpr.cbegin(); it != xpr.cend(); ++it) {
    VERIFY_IS_EQUAL(*it, xpr[i++]);
  }

  i = 0;
  for (typename Xpr::const_iterator it = cxpr.begin(); it != cxpr.end(); ++it) {
    VERIFY_IS_EQUAL(*it, xpr[i++]);
  }

  i = 0;
  for (typename Xpr::const_iterator it = xpr.begin(); it != xpr.end(); ++it) {
    VERIFY_IS_EQUAL(*it, xpr[i++]);
  }

  {
    // simple API check
    typename Xpr::const_iterator cit = xpr.begin();
    cit = xpr.cbegin();

    auto tmp1 = xpr.begin();
    VERIFY(tmp1 == xpr.begin());
    auto tmp2 = xpr.cbegin();
    VERIFY(tmp2 == xpr.cbegin());
  }

  VERIFY(xpr.end() - xpr.begin() == xpr.size());
  VERIFY(xpr.cend() - xpr.begin() == xpr.size());
  VERIFY(xpr.end() - xpr.cbegin() == xpr.size());
  VERIFY(xpr.cend() - xpr.cbegin() == xpr.size());

  if (xpr.size() > 0) {
    VERIFY(xpr.begin() != xpr.end());
    VERIFY(xpr.begin() < xpr.end());
    VERIFY(xpr.begin() <= xpr.end());
    VERIFY(!(xpr.begin() == xpr.end()));
    VERIFY(!(xpr.begin() > xpr.end()));
    VERIFY(!(xpr.begin() >= xpr.end()));

    VERIFY(xpr.cbegin() != xpr.end());
    VERIFY(xpr.cbegin() < xpr.end());
    VERIFY(xpr.cbegin() <= xpr.end());
    VERIFY(!(xpr.cbegin() == xpr.end()));
    VERIFY(!(xpr.cbegin() > xpr.end()));
    VERIFY(!(xpr.cbegin() >= xpr.end()));

    VERIFY(xpr.begin() != xpr.cend());
    VERIFY(xpr.begin() < xpr.cend());
    VERIFY(xpr.begin() <= xpr.cend());
    VERIFY(!(xpr.begin() == xpr.cend()));
    VERIFY(!(xpr.begin() > xpr.cend()));
    VERIFY(!(xpr.begin() >= xpr.cend()));
  }
}

template <typename Scalar, int Rows, int Cols>
void test_stl_iterators(int rows = Rows, int cols = Cols) {
  typedef Matrix<Scalar, Rows, 1> VectorType;
  typedef Matrix<Scalar, 1, Cols> RowVectorType;
  typedef Matrix<Scalar, Rows, Cols, ColMajor> ColMatrixType;
  typedef Matrix<Scalar, Rows, Cols, RowMajor> RowMatrixType;
  VectorType v = VectorType::Random(rows);
  const VectorType& cv(v);
  ColMatrixType A = ColMatrixType::Random(rows, cols);
  const ColMatrixType& cA(A);
  RowMatrixType B = RowMatrixType::Random(rows, cols);
  using Eigen::placeholders::last;

  Index i, j;

  // Verify that iterators are default constructible (See bug #1900)
  {
    VERIFY(is_default_constructible_and_assignable(v.begin()));
    VERIFY(is_default_constructible_and_assignable(v.end()));
    VERIFY(is_default_constructible_and_assignable(cv.begin()));
    VERIFY(is_default_constructible_and_assignable(cv.end()));

    VERIFY(is_default_constructible_and_assignable(A.row(0).begin()));
    VERIFY(is_default_constructible_and_assignable(A.row(0).end()));
    VERIFY(is_default_constructible_and_assignable(cA.row(0).begin()));
    VERIFY(is_default_constructible_and_assignable(cA.row(0).end()));

    VERIFY(is_default_constructible_and_assignable(B.row(0).begin()));
    VERIFY(is_default_constructible_and_assignable(B.row(0).end()));
  }

  // Check we got a fast pointer-based iterator when expected
  {
    VERIFY(is_pointer_based_stl_iterator(v.begin()));
    VERIFY(is_pointer_based_stl_iterator(v.end()));
    VERIFY(is_pointer_based_stl_iterator(cv.begin()));
    VERIFY(is_pointer_based_stl_iterator(cv.end()));

    j = internal::random<Index>(0, A.cols() - 1);
    VERIFY(is_pointer_based_stl_iterator(A.col(j).begin()));
    VERIFY(is_pointer_based_stl_iterator(A.col(j).end()));
    VERIFY(is_pointer_based_stl_iterator(cA.col(j).begin()));
    VERIFY(is_pointer_based_stl_iterator(cA.col(j).end()));

    i = internal::random<Index>(0, A.rows() - 1);
    VERIFY(is_pointer_based_stl_iterator(A.row(i).begin()));
    VERIFY(is_pointer_based_stl_iterator(A.row(i).end()));
    VERIFY(is_pointer_based_stl_iterator(cA.row(i).begin()));
    VERIFY(is_pointer_based_stl_iterator(cA.row(i).end()));

    VERIFY(is_pointer_based_stl_iterator(A.reshaped().begin()));
    VERIFY(is_pointer_based_stl_iterator(A.reshaped().end()));
    VERIFY(is_pointer_based_stl_iterator(cA.reshaped().begin()));
    VERIFY(is_pointer_based_stl_iterator(cA.reshaped().end()));

    VERIFY(is_pointer_based_stl_iterator(B.template reshaped<AutoOrder>().begin()));
    VERIFY(is_pointer_based_stl_iterator(B.template reshaped<AutoOrder>().end()));

    VERIFY(is_generic_randaccess_stl_iterator(A.template reshaped<RowMajor>().begin()));
    VERIFY(is_generic_randaccess_stl_iterator(A.template reshaped<RowMajor>().end()));
  }

  {
    check_begin_end_for_loop(v);
    check_begin_end_for_loop(A.col(internal::random<Index>(0, A.cols() - 1)));
    check_begin_end_for_loop(A.row(internal::random<Index>(0, A.rows() - 1)));
    check_begin_end_for_loop(v + v);
  }

  // check swappable
  {
    using std::swap;
    // pointer-based
    {
      VectorType v_copy = v;
      auto a = v.begin();
      auto b = v.end() - 1;
      swap(a, b);
      VERIFY_IS_EQUAL(v, v_copy);
      VERIFY_IS_EQUAL(*b, *v.begin());
      VERIFY_IS_EQUAL(*b, v(0));
      VERIFY_IS_EQUAL(*a, v.end()[-1]);
      VERIFY_IS_EQUAL(*a, v(last));
    }

    // generic
    {
      RowMatrixType B_copy = B;
      auto Br = B.reshaped();
      auto a = Br.begin();
      auto b = Br.end() - 1;
      swap(a, b);
      VERIFY_IS_EQUAL(B, B_copy);
      VERIFY_IS_EQUAL(*b, *Br.begin());
      VERIFY_IS_EQUAL(*b, Br(0));
      VERIFY_IS_EQUAL(*a, Br.end()[-1]);
      VERIFY_IS_EQUAL(*a, Br(last));
    }
  }

  // check non-const iterator with for-range loops
  {
    i = 0;
    for (auto x : v) {
      VERIFY_IS_EQUAL(x, v[i++]);
    }

    j = internal::random<Index>(0, A.cols() - 1);
    i = 0;
    for (auto x : A.col(j)) {
      VERIFY_IS_EQUAL(x, A(i++, j));
    }

    i = 0;
    for (auto x : (v + A.col(j))) {
      VERIFY_IS_APPROX(x, v(i) + A(i, j));
      ++i;
    }

    j = 0;
    i = internal::random<Index>(0, A.rows() - 1);
    for (auto x : A.row(i)) {
      VERIFY_IS_EQUAL(x, A(i, j++));
    }

    i = 0;
    for (auto x : A.reshaped()) {
      VERIFY_IS_EQUAL(x, A(i++));
    }
  }

  // same for const_iterator
  {
    i = 0;
    for (auto x : cv) {
      VERIFY_IS_EQUAL(x, v[i++]);
    }

    i = 0;
    for (auto x : cA.reshaped()) {
      VERIFY_IS_EQUAL(x, A(i++));
    }

    j = 0;
    i = internal::random<Index>(0, A.rows() - 1);
    for (auto x : cA.row(i)) {
      VERIFY_IS_EQUAL(x, A(i, j++));
    }
  }

  // check reshaped() on row-major
  {
    i = 0;
    Matrix<Scalar, Dynamic, Dynamic, ColMajor> Bc = B;
    for (auto x : B.reshaped()) {
      VERIFY_IS_EQUAL(x, Bc(i++));
    }
  }

  // check write access
  {
    VectorType w(v.size());
    i = 0;
    for (auto& x : w) {
      x = v(i++);
    }
    VERIFY_IS_EQUAL(v, w);
  }

  // check for dangling pointers
  {
    // no dangling because pointer-based
    {
      j = internal::random<Index>(0, A.cols() - 1);
      auto it = A.col(j).begin();
      for (i = 0; i < rows; ++i) {
        VERIFY_IS_EQUAL(it[i], A(i, j));
      }
    }

    // no dangling because pointer-based
    {
      i = internal::random<Index>(0, A.rows() - 1);
      auto it = A.row(i).begin();
      for (j = 0; j < cols; ++j) {
        VERIFY_IS_EQUAL(it[j], A(i, j));
      }
    }

    {
      j = internal::random<Index>(0, A.cols() - 1);
      // this would produce a dangling pointer:
      // auto it = (A+2*A).col(j).begin();
      // we need to name the temporary expression:
      auto tmp = (A + 2 * A).col(j);
      auto it = tmp.begin();
      for (i = 0; i < rows; ++i) {
        VERIFY_IS_APPROX(it[i], 3 * A(i, j));
      }
    }
  }

  {
    // check basic for loop on vector-wise iterators
    j = 0;
    for (auto it = A.colwise().cbegin(); it != A.colwise().cend(); ++it, ++j) {
      VERIFY_IS_APPROX(it->coeff(0), A(0, j));
      VERIFY_IS_APPROX((*it).coeff(0), A(0, j));
    }
    j = 0;
    for (auto it = A.colwise().begin(); it != A.colwise().end(); ++it, ++j) {
      (*it).coeffRef(0) = (*it).coeff(0);  // compilation check
      it->coeffRef(0) = it->coeff(0);      // compilation check
      VERIFY_IS_APPROX(it->coeff(0), A(0, j));
      VERIFY_IS_APPROX((*it).coeff(0), A(0, j));
    }

    // check valuetype gives us a copy
    j = 0;
    for (auto it = A.colwise().cbegin(); it != A.colwise().cend(); ++it, ++j) {
      typename decltype(it)::value_type tmp = *it;
      VERIFY_IS_NOT_EQUAL(tmp.data(), it->data());
      VERIFY_IS_APPROX(tmp, A.col(j));
    }
  }

  if (rows >= 3) {
    VERIFY_IS_EQUAL((v.begin() + rows / 2)[1], v(rows / 2 + 1));

    VERIFY_IS_EQUAL((A.rowwise().begin() + rows / 2)[1], A.row(rows / 2 + 1));
  }

  if (cols >= 3) {
    VERIFY_IS_EQUAL((A.colwise().begin() + cols / 2)[1], A.col(cols / 2 + 1));
  }

  // check std::sort
  {
    // first check that is_sorted returns false when required
    if (rows >= 2) {
      v(1) = v(0) - Scalar(1);
      VERIFY(!is_sorted(std::begin(v), std::end(v)));
    }

    // on a vector
    {
      std::sort(v.begin(), v.end());
      VERIFY(is_sorted(v.begin(), v.end()));
      VERIFY(!::is_sorted(make_reverse_iterator(v.end()), make_reverse_iterator(v.begin())));
    }

    // on a column of a column-major matrix -> pointer-based iterator and default increment
    {
      j = internal::random<Index>(0, A.cols() - 1);
      // std::sort(begin(A.col(j)),end(A.col(j))); // does not compile because this returns const iterators
      typename ColMatrixType::ColXpr Acol = A.col(j);
      std::sort(Acol.begin(), Acol.end());
      VERIFY(is_sorted(Acol.cbegin(), Acol.cend()));
      A.setRandom();

      std::sort(A.col(j).begin(), A.col(j).end());
      VERIFY(is_sorted(A.col(j).cbegin(), A.col(j).cend()));
      A.setRandom();
    }

    // on a row of a rowmajor matrix -> pointer-based iterator and runtime increment
    {
      i = internal::random<Index>(0, A.rows() - 1);
      typename ColMatrixType::RowXpr Arow = A.row(i);
      VERIFY_IS_EQUAL(std::distance(Arow.begin(), Arow.end()), cols);
      std::sort(Arow.begin(), Arow.end());
      VERIFY(is_sorted(Arow.cbegin(), Arow.cend()));
      A.setRandom();

      std::sort(A.row(i).begin(), A.row(i).end());
      VERIFY(is_sorted(A.row(i).cbegin(), A.row(i).cend()));
      A.setRandom();
    }

    // with a generic iterator
    {
      Reshaped<RowMatrixType, RowMatrixType::SizeAtCompileTime, 1> B1 = B.reshaped();
      std::sort(B1.begin(), B1.end());
      VERIFY(is_sorted(B1.cbegin(), B1.cend()));
      B.setRandom();

      // assertion because nested expressions are different
      // std::sort(B.reshaped().begin(),B.reshaped().end());
      // VERIFY(is_sorted(B.reshaped().cbegin(),B.reshaped().cend()));
      // B.setRandom();
    }
  }

  // check with partial_sum
  {
    j = internal::random<Index>(0, A.cols() - 1);
    typename ColMatrixType::ColXpr Acol = A.col(j);
    std::partial_sum(Acol.begin(), Acol.end(), v.begin());
    VERIFY_IS_APPROX(v(seq(1, last)), v(seq(0, last - 1)) + Acol(seq(1, last)));

    // inplace
    std::partial_sum(Acol.begin(), Acol.end(), Acol.begin());
    VERIFY_IS_APPROX(v, Acol);
  }

  // stress random access as required by std::nth_element
  if (rows >= 3) {
    v.setRandom();
    VectorType v1 = v;
    std::sort(v1.begin(), v1.end());
    std::nth_element(v.begin(), v.begin() + rows / 2, v.end());
    VERIFY_IS_APPROX(v1(rows / 2), v(rows / 2));

    v.setRandom();
    v1 = v;
    std::sort(v1.begin() + rows / 2, v1.end());
    std::nth_element(v.begin() + rows / 2, v.begin() + rows / 4, v.end());
    VERIFY_IS_APPROX(v1(rows / 4), v(rows / 4));
  }

  // check rows/cols iterators with range-for loops
  {
    j = 0;
    for (auto c : A.colwise()) {
      VERIFY_IS_APPROX(c.sum(), A.col(j).sum());
      ++j;
    }
    j = 0;
    for (auto c : B.colwise()) {
      VERIFY_IS_APPROX(c.sum(), B.col(j).sum());
      ++j;
    }

    j = 0;
    for (auto c : B.colwise()) {
      i = 0;
      for (auto& x : c) {
        VERIFY_IS_EQUAL(x, B(i, j));
        x = A(i, j);
        ++i;
      }
      ++j;
    }
    VERIFY_IS_APPROX(A, B);
    B.setRandom();

    i = 0;
    for (auto r : A.rowwise()) {
      VERIFY_IS_APPROX(r.sum(), A.row(i).sum());
      ++i;
    }
    i = 0;
    for (auto r : B.rowwise()) {
      VERIFY_IS_APPROX(r.sum(), B.row(i).sum());
      ++i;
    }
  }

  // check rows/cols iterators with STL algorithms
  {
    RowVectorType row = RowVectorType::Random(cols);
    VectorType col = VectorType::Random(rows);
    // Prevent overflows for integer types.
    if (Eigen::NumTraits<Scalar>::IsInteger) {
      Scalar kMaxVal = Scalar(1000);
      row.array() = row.array() - kMaxVal * (row.array() / kMaxVal);
      col.array() = col.array() - kMaxVal * (col.array() / kMaxVal);
    }
    A.rowwise() = row;
    VERIFY(std::all_of(A.rowwise().begin(), A.rowwise().end(), [&row](typename ColMatrixType::RowXpr x) {
      return internal::isApprox(x.squaredNorm(), row.squaredNorm());
    }));
    VERIFY(std::all_of(A.rowwise().rbegin(), A.rowwise().rend(), [&row](typename ColMatrixType::RowXpr x) {
      return internal::isApprox(x.squaredNorm(), row.squaredNorm());
    }));

    A.colwise() = col;
    VERIFY(std::all_of(A.colwise().begin(), A.colwise().end(), [&col](typename ColMatrixType::ColXpr x) {
      return internal::isApprox(x.squaredNorm(), col.squaredNorm());
    }));
    VERIFY(std::all_of(A.colwise().rbegin(), A.colwise().rend(), [&col](typename ColMatrixType::ColXpr x) {
      return internal::isApprox(x.squaredNorm(), col.squaredNorm());
    }));
    VERIFY(std::all_of(A.colwise().cbegin(), A.colwise().cend(), [&col](typename ColMatrixType::ConstColXpr x) {
      return internal::isApprox(x.squaredNorm(), col.squaredNorm());
    }));
    VERIFY(std::all_of(A.colwise().crbegin(), A.colwise().crend(), [&col](typename ColMatrixType::ConstColXpr x) {
      return internal::isApprox(x.squaredNorm(), col.squaredNorm());
    }));

    i = internal::random<Index>(0, A.rows() - 1);
    A.setRandom();
    A.row(i).setZero();
    VERIFY_IS_EQUAL(
        std::find_if(A.rowwise().begin(), A.rowwise().end(),
                     [](typename ColMatrixType::RowXpr x) { return numext::is_exactly_zero(x.squaredNorm()); }) -
            A.rowwise().begin(),
        i);
    VERIFY_IS_EQUAL(
        std::find_if(A.rowwise().rbegin(), A.rowwise().rend(),
                     [](typename ColMatrixType::RowXpr x) { return numext::is_exactly_zero(x.squaredNorm()); }) -
            A.rowwise().rbegin(),
        (A.rows() - 1) - i);

    j = internal::random<Index>(0, A.cols() - 1);
    A.setRandom();
    A.col(j).setZero();
    VERIFY_IS_EQUAL(
        std::find_if(A.colwise().begin(), A.colwise().end(),
                     [](typename ColMatrixType::ColXpr x) { return numext::is_exactly_zero(x.squaredNorm()); }) -
            A.colwise().begin(),
        j);
    VERIFY_IS_EQUAL(
        std::find_if(A.colwise().rbegin(), A.colwise().rend(),
                     [](typename ColMatrixType::ColXpr x) { return numext::is_exactly_zero(x.squaredNorm()); }) -
            A.colwise().rbegin(),
        (A.cols() - 1) - j);
  }

  {
    using VecOp = VectorwiseOp<ArrayXXi, 0>;
    STATIC_CHECK((internal::is_same<VecOp::const_iterator, decltype(std::declval<const VecOp&>().cbegin())>::value));
    STATIC_CHECK((internal::is_same<VecOp::const_iterator, decltype(std::declval<const VecOp&>().cend())>::value));
    STATIC_CHECK(
        (internal::is_same<VecOp::const_iterator, decltype(std::cbegin(std::declval<const VecOp&>()))>::value));
    STATIC_CHECK((internal::is_same<VecOp::const_iterator, decltype(std::cend(std::declval<const VecOp&>()))>::value));
  }
}

// When the compiler sees expression IsContainerTest<C>(0), if C is an
// STL-style container class, the first overload of IsContainerTest
// will be viable (since both C::iterator* and C::const_iterator* are
// valid types and NULL can be implicitly converted to them).  It will
// be picked over the second overload as 'int' is a perfect match for
// the type of argument 0.  If C::iterator or C::const_iterator is not
// a valid type, the first overload is not viable, and the second
// overload will be picked.
template <class C, class Iterator = decltype(::std::declval<const C&>().begin()),
          class = decltype(::std::declval<const C&>().end()), class = decltype(++::std::declval<Iterator&>()),
          class = decltype(*::std::declval<Iterator>()), class = typename C::const_iterator>
bool IsContainerType(int /* dummy */) {
  return true;
}

template <class C>
bool IsContainerType(long /* dummy */) {
  return false;
}

template <typename Scalar, int Rows, int Cols>
void test_stl_container_detection(int rows = Rows, int cols = Cols) {
  typedef Matrix<Scalar, Rows, 1> VectorType;
  typedef Matrix<Scalar, Rows, Cols, ColMajor> ColMatrixType;
  typedef Matrix<Scalar, Rows, Cols, RowMajor> RowMatrixType;

  ColMatrixType A = ColMatrixType::Random(rows, cols);
  RowMatrixType B = RowMatrixType::Random(rows, cols);

  Index i = 1;

  using ColMatrixColType = decltype(A.col(i));
  using ColMatrixRowType = decltype(A.row(i));
  using RowMatrixColType = decltype(B.col(i));
  using RowMatrixRowType = decltype(B.row(i));

  // Vector and matrix col/row are valid Stl-style container.
  VERIFY_IS_EQUAL(IsContainerType<VectorType>(0), true);
  VERIFY_IS_EQUAL(IsContainerType<ColMatrixColType>(0), true);
  VERIFY_IS_EQUAL(IsContainerType<ColMatrixRowType>(0), true);
  VERIFY_IS_EQUAL(IsContainerType<RowMatrixColType>(0), true);
  VERIFY_IS_EQUAL(IsContainerType<RowMatrixRowType>(0), true);

  // But the matrix itself is not a valid Stl-style container.
  VERIFY_IS_EQUAL(IsContainerType<ColMatrixType>(0), rows == 1 || cols == 1);
  VERIFY_IS_EQUAL(IsContainerType<RowMatrixType>(0), rows == 1 || cols == 1);
}

#ifdef EIGEN_TEST_CXX20_RANGES
template <typename Scalar, int Rows, int Cols>
void test_cxx20_ranges(int rows = Rows, int cols = Cols) {
  typedef Matrix<Scalar, Rows, 1> VectorType;
  typedef Matrix<Scalar, Dynamic, 1> DynVectorType;
  typedef Matrix<Scalar, Rows, Cols, ColMajor> ColMatrixType;

  // Vectors with unit stride satisfy contiguous_range.
  static_assert(std::contiguous_iterator<typename VectorType::iterator>);
  static_assert(std::contiguous_iterator<typename VectorType::const_iterator>);
  static_assert(std::ranges::contiguous_range<VectorType>);
  static_assert(std::ranges::contiguous_range<const VectorType>);

  // Dynamic vectors too.
  static_assert(std::contiguous_iterator<typename DynVectorType::iterator>);
  static_assert(std::ranges::contiguous_range<DynVectorType>);
  static_assert(std::ranges::contiguous_range<const DynVectorType>);

  // Sized range.
  static_assert(std::ranges::sized_range<VectorType>);
  static_assert(std::ranges::sized_range<DynVectorType>);

  // Runtime checks with std::ranges algorithms.
  VectorType v = VectorType::Random(rows);
  auto it = std::ranges::find(v, v(0));
  VERIFY(it == v.begin());

  // ranges::data returns the same pointer as data().
  VERIFY(std::ranges::data(v) == v.data());
  VERIFY(static_cast<Index>(std::ranges::size(v)) == v.size());

  // Column expression of a column-major matrix is contiguous.
  ColMatrixType A = ColMatrixType::Random(rows, cols);
  auto col = A.col(0);
  VERIFY(std::ranges::data(col) == col.data());
  auto col_it = std::ranges::find(col, col(0));
  VERIFY(col_it == col.begin());
}
#endif

EIGEN_DECLARE_TEST(stl_iterators) {
  for (int i = 0; i < g_repeat; i++) {
    CALL_SUBTEST_1((test_stl_iterators<double, 2, 3>()));
    CALL_SUBTEST_1((test_stl_iterators<float, 7, 5>()));
    CALL_SUBTEST_1(
        (test_stl_iterators<int, Dynamic, Dynamic>(internal::random<int>(5, 10), internal::random<int>(5, 10))));
    CALL_SUBTEST_1(
        (test_stl_iterators<int, Dynamic, Dynamic>(internal::random<int>(10, 200), internal::random<int>(10, 200))));
  }

  CALL_SUBTEST_1((test_stl_container_detection<float, 1, 1>()));
  CALL_SUBTEST_1((test_stl_container_detection<float, 5, 5>()));

#ifdef EIGEN_TEST_CXX20_RANGES
  CALL_SUBTEST_1((test_cxx20_ranges<double, 4, 3>()));
  CALL_SUBTEST_1(
      (test_cxx20_ranges<float, Dynamic, Dynamic>(internal::random<int>(5, 10), internal::random<int>(5, 10))));
#endif
}
