// This file is part of Eigen, a lightweight C++ template library
// for linear algebra.
//
// Copyright (C) 2013 Hauke Heibel <hauke.heibel@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"
#include "AnnoyingScalar.h"
#include "SafeScalar.h"

#include <Eigen/Core>

using DenseStorageD3x3 = Eigen::DenseStorage<double, 3, 3, 3, 3>;
static_assert(std::is_trivially_move_constructible<DenseStorageD3x3>::value,
              "DenseStorage not trivially_move_constructible");
static_assert(std::is_trivially_move_assignable<DenseStorageD3x3>::value, "DenseStorage not trivially_move_assignable");
#if !defined(EIGEN_DENSE_STORAGE_CTOR_PLUGIN)
static_assert(std::is_trivially_copy_constructible<DenseStorageD3x3>::value,
              "DenseStorage not trivially_copy_constructible");
static_assert(std::is_trivially_copy_assignable<DenseStorageD3x3>::value, "DenseStorage not trivially_copy_assignable");
static_assert(std::is_trivially_copyable<DenseStorageD3x3>::value, "DenseStorage not trivially_copyable");
#endif

template <typename T, int Size, int Rows, int Cols>
void dense_storage_copy(int rows, int cols) {
  typedef DenseStorage<T, Size, Rows, Cols, 0> DenseStorageType;

  const int size = rows * cols;
  DenseStorageType reference(size, rows, cols);
  T* raw_reference = reference.data();
  for (int i = 0; i < size; ++i) raw_reference[i] = static_cast<T>(i);

  DenseStorageType copied_reference(reference);
  const T* raw_copied_reference = copied_reference.data();
  for (int i = 0; i < size; ++i) VERIFY_IS_EQUAL(raw_reference[i], raw_copied_reference[i]);
}

template <typename T, int Size, int Rows, int Cols>
void dense_storage_assignment(int rows, int cols) {
  typedef DenseStorage<T, Size, Rows, Cols, 0> DenseStorageType;

  const int size = rows * cols;
  DenseStorageType reference(size, rows, cols);
  T* raw_reference = reference.data();
  for (int i = 0; i < size; ++i) raw_reference[i] = static_cast<T>(i);

  DenseStorageType copied_reference;
  copied_reference = reference;
  const T* raw_copied_reference = copied_reference.data();
  for (int i = 0; i < size; ++i) VERIFY_IS_EQUAL(raw_reference[i], raw_copied_reference[i]);
}

template <typename T, int Size, int Rows, int Cols>
void dense_storage_swap(int rows0, int cols0, int rows1, int cols1) {
  typedef DenseStorage<T, Size, Rows, Cols, 0> DenseStorageType;

  const int size0 = rows0 * cols0;
  DenseStorageType a(size0, rows0, cols0);
  for (int i = 0; i < size0; ++i) {
    a.data()[i] = static_cast<T>(i);
  }

  const int size1 = rows1 * cols1;
  DenseStorageType b(size1, rows1, cols1);
  for (int i = 0; i < size1; ++i) {
    b.data()[i] = static_cast<T>(-i);
  }

  a.swap(b);

  for (int i = 0; i < size0; ++i) {
    VERIFY_IS_EQUAL(b.data()[i], static_cast<T>(i));
  }

  for (int i = 0; i < size1; ++i) {
    VERIFY_IS_EQUAL(a.data()[i], static_cast<T>(-i));
  }
}

template <typename T, int Size, std::size_t Alignment>
void dense_storage_alignment() {
  struct alignas(Alignment) Empty1 {};
  VERIFY_IS_EQUAL(std::alignment_of<Empty1>::value, Alignment);

  struct EIGEN_ALIGN_TO_BOUNDARY(Alignment) Empty2 {};
  VERIFY_IS_EQUAL(std::alignment_of<Empty2>::value, Alignment);

  struct Nested1 {
    EIGEN_ALIGN_TO_BOUNDARY(Alignment) T data[Size];
  };
  VERIFY_IS_EQUAL(std::alignment_of<Nested1>::value, Alignment);

  VERIFY_IS_EQUAL((std::alignment_of<internal::plain_array<T, Size, AutoAlign, Alignment> >::value), Alignment);

  const std::size_t default_alignment = internal::compute_default_alignment<T, Size>::value;
  if (default_alignment > 0) {
    VERIFY_IS_EQUAL((std::alignment_of<DenseStorage<T, Size, 1, 1, AutoAlign> >::value), default_alignment);
    VERIFY_IS_EQUAL((std::alignment_of<Matrix<T, Size, 1, AutoAlign> >::value), default_alignment);
    struct Nested2 {
      Matrix<T, Size, 1, AutoAlign> mat;
    };
    VERIFY_IS_EQUAL(std::alignment_of<Nested2>::value, default_alignment);
  }
}

template <typename T>
void dense_storage_tests() {
  // Dynamic Storage.
  dense_storage_copy<T, Dynamic, Dynamic, Dynamic>(4, 3);
  dense_storage_copy<T, Dynamic, Dynamic, 3>(4, 3);
  dense_storage_copy<T, Dynamic, 4, Dynamic>(4, 3);
  // Fixed Storage.
  dense_storage_copy<T, 12, 4, 3>(4, 3);
  dense_storage_copy<T, 12, Dynamic, Dynamic>(4, 3);
  dense_storage_copy<T, 12, 4, Dynamic>(4, 3);
  dense_storage_copy<T, 12, Dynamic, 3>(4, 3);
  // Fixed Storage with Uninitialized Elements.
  dense_storage_copy<T, 18, Dynamic, Dynamic>(4, 3);
  dense_storage_copy<T, 18, 4, Dynamic>(4, 3);
  dense_storage_copy<T, 18, Dynamic, 3>(4, 3);

  // Dynamic Storage.
  dense_storage_assignment<T, Dynamic, Dynamic, Dynamic>(4, 3);
  dense_storage_assignment<T, Dynamic, Dynamic, 3>(4, 3);
  dense_storage_assignment<T, Dynamic, 4, Dynamic>(4, 3);
  // Fixed Storage.
  dense_storage_assignment<T, 12, 4, 3>(4, 3);
  dense_storage_assignment<T, 12, Dynamic, Dynamic>(4, 3);
  dense_storage_assignment<T, 12, 4, Dynamic>(4, 3);
  dense_storage_assignment<T, 12, Dynamic, 3>(4, 3);
  // Fixed Storage with Uninitialized Elements.
  dense_storage_assignment<T, 18, Dynamic, Dynamic>(4, 3);
  dense_storage_assignment<T, 18, 4, Dynamic>(4, 3);
  dense_storage_assignment<T, 18, Dynamic, 3>(4, 3);

  // Dynamic Storage.
  dense_storage_swap<T, Dynamic, Dynamic, Dynamic>(4, 3, 4, 3);
  dense_storage_swap<T, Dynamic, Dynamic, Dynamic>(4, 3, 2, 1);
  dense_storage_swap<T, Dynamic, Dynamic, Dynamic>(2, 1, 4, 3);
  dense_storage_swap<T, Dynamic, Dynamic, 3>(4, 3, 4, 3);
  dense_storage_swap<T, Dynamic, Dynamic, 3>(4, 3, 2, 3);
  dense_storage_swap<T, Dynamic, Dynamic, 3>(2, 3, 4, 3);
  dense_storage_swap<T, Dynamic, 4, Dynamic>(4, 3, 4, 3);
  dense_storage_swap<T, Dynamic, 4, Dynamic>(4, 3, 4, 1);
  dense_storage_swap<T, Dynamic, 4, Dynamic>(4, 1, 4, 3);
  // Fixed Storage.
  dense_storage_swap<T, 12, 4, 3>(4, 3, 4, 3);
  dense_storage_swap<T, 12, Dynamic, Dynamic>(4, 3, 4, 3);
  dense_storage_swap<T, 12, Dynamic, Dynamic>(4, 3, 2, 1);
  dense_storage_swap<T, 12, Dynamic, Dynamic>(2, 1, 4, 3);
  dense_storage_swap<T, 12, 4, Dynamic>(4, 3, 4, 3);
  dense_storage_swap<T, 12, 4, Dynamic>(4, 3, 4, 1);
  dense_storage_swap<T, 12, 4, Dynamic>(4, 1, 4, 3);
  dense_storage_swap<T, 12, Dynamic, 3>(4, 3, 4, 3);
  dense_storage_swap<T, 12, Dynamic, 3>(4, 3, 2, 3);
  dense_storage_swap<T, 12, Dynamic, 3>(2, 3, 4, 3);
  // Fixed Storage with Uninitialized Elements.
  dense_storage_swap<T, 18, Dynamic, Dynamic>(4, 3, 4, 3);
  dense_storage_swap<T, 18, Dynamic, Dynamic>(4, 3, 2, 1);
  dense_storage_swap<T, 18, Dynamic, Dynamic>(2, 1, 4, 3);
  dense_storage_swap<T, 18, 4, Dynamic>(4, 3, 4, 3);
  dense_storage_swap<T, 18, 4, Dynamic>(4, 3, 4, 1);
  dense_storage_swap<T, 18, 4, Dynamic>(4, 1, 4, 3);
  dense_storage_swap<T, 18, Dynamic, 3>(4, 3, 4, 3);
  dense_storage_swap<T, 18, Dynamic, 3>(4, 3, 2, 3);
  dense_storage_swap<T, 18, Dynamic, 3>(2, 3, 4, 3);

  dense_storage_alignment<T, 16, 8>();
  dense_storage_alignment<T, 16, 16>();
  dense_storage_alignment<T, 16, 32>();
  dense_storage_alignment<T, 16, 64>();
}

EIGEN_DECLARE_TEST(dense_storage) {
  dense_storage_tests<int>();
  dense_storage_tests<float>();
  dense_storage_tests<SafeScalar<float> >();
  dense_storage_tests<AnnoyingScalar>();
}
