// This file is part of Eigen, a lightweight C++ template library
// for linear algebra.
//
// Copyright (C) 2009 Benoit Jacob <jacob.benoit.1@gmail.com>
//
// 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 "main.h"

template <typename T>
struct other_matrix_type {
  typedef int type;
};

template <typename Scalar_, int Rows_, int Cols_, int Options_, int MaxRows_, int MaxCols_>
struct other_matrix_type<Matrix<Scalar_, Rows_, Cols_, Options_, MaxRows_, MaxCols_> > {
  typedef Matrix<Scalar_, Rows_, Cols_, Options_ ^ RowMajor, MaxRows_, MaxCols_> type;
};

template <typename MatrixType>
std::enable_if_t<(MatrixType::RowsAtCompileTime == 1 || MatrixType::RowsAtCompileTime == Dynamic), void> check_row_swap(
    MatrixType& m1) {
  if (m1.rows() != 1) {
    // test assertion on mismatching size -- matrix case
    VERIFY_RAISES_ASSERT(m1.swap(m1.row(0)));
    // test assertion on mismatching size -- xpr case
    VERIFY_RAISES_ASSERT(m1.row(0).swap(m1));
  }
}

template <typename MatrixType>
std::enable_if_t<!(MatrixType::RowsAtCompileTime == 1 || MatrixType::RowsAtCompileTime == Dynamic), void>
check_row_swap(MatrixType& /* unused */) {}

template <typename MatrixType>
void swap(const MatrixType& m) {
  typedef typename other_matrix_type<MatrixType>::type OtherMatrixType;
  typedef typename MatrixType::Scalar Scalar;

  eigen_assert((!internal::is_same<MatrixType, OtherMatrixType>::value));
  Index rows = m.rows();
  Index cols = m.cols();

  // construct 3 matrix guaranteed to be distinct
  MatrixType m1 = MatrixType::Random(rows, cols);
  MatrixType m2 = MatrixType::Random(rows, cols) + Scalar(100) * MatrixType::Identity(rows, cols);
  OtherMatrixType m3 = OtherMatrixType::Random(rows, cols) + Scalar(200) * OtherMatrixType::Identity(rows, cols);

  MatrixType m1_copy = m1;
  MatrixType m2_copy = m2;
  OtherMatrixType m3_copy = m3;

  // test swapping 2 matrices of same type
  Scalar *d1 = m1.data(), *d2 = m2.data();
  m1.swap(m2);
  VERIFY_IS_APPROX(m1, m2_copy);
  VERIFY_IS_APPROX(m2, m1_copy);
  if (MatrixType::SizeAtCompileTime == Dynamic) {
    VERIFY(m1.data() == d2);
    VERIFY(m2.data() == d1);
  }
  m1 = m1_copy;
  m2 = m2_copy;

  // test swapping 2 matrices of different types
  m1.swap(m3);
  VERIFY_IS_APPROX(m1, m3_copy);
  VERIFY_IS_APPROX(m3, m1_copy);
  m1 = m1_copy;
  m3 = m3_copy;

  // test swapping matrix with expression
  m1.swap(m2.block(0, 0, rows, cols));
  VERIFY_IS_APPROX(m1, m2_copy);
  VERIFY_IS_APPROX(m2, m1_copy);
  m1 = m1_copy;
  m2 = m2_copy;

  // test swapping two expressions of different types
  m1.transpose().swap(m3.transpose());
  VERIFY_IS_APPROX(m1, m3_copy);
  VERIFY_IS_APPROX(m3, m1_copy);
  m1 = m1_copy;
  m3 = m3_copy;

  check_row_swap(m1);
}

EIGEN_DECLARE_TEST(swap) {
  int s = internal::random<int>(1, EIGEN_TEST_MAX_SIZE);
  CALL_SUBTEST_1(swap(Matrix3f()));      // fixed size, no vectorization
  CALL_SUBTEST_2(swap(Matrix4d()));      // fixed size, possible vectorization
  CALL_SUBTEST_3(swap(MatrixXd(s, s)));  // dyn size, no vectorization
  CALL_SUBTEST_4(swap(MatrixXf(s, s)));  // dyn size, possible vectorization
  TEST_SET_BUT_UNUSED_VARIABLE(s)
}
