// This file is part of Eigen, a lightweight C++ template library
// for linear algebra.
//
// Copyright (C) 2008 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 "main.h"

#if EIGEN_MAX_ALIGN_BYTES > 0
#define ALIGNMENT EIGEN_MAX_ALIGN_BYTES
#else
#define ALIGNMENT 1
#endif

typedef Matrix<float, 16, 1> Vector16f;
typedef Matrix<float, 8, 1> Vector8f;

void check_handmade_aligned_malloc() {
  // Hand-make alignment needs at least sizeof(void*) to store the offset.
  constexpr int alignment = (std::max<int>)(EIGEN_DEFAULT_ALIGN_BYTES, sizeof(void *));

  for (int i = 1; i < 1000; i++) {
    char *p = (char *)internal::handmade_aligned_malloc(i, alignment);
    VERIFY(std::uintptr_t(p) % ALIGNMENT == 0);
    // if the buffer is wrongly allocated this will give a bad write --> check with valgrind
    for (int j = 0; j < i; j++) p[j] = 0;
    internal::handmade_aligned_free(p);
  }
}

void check_aligned_malloc() {
  for (int i = ALIGNMENT; i < 1000; i++) {
    char *p = (char *)internal::aligned_malloc(i);
    VERIFY(std::uintptr_t(p) % ALIGNMENT == 0);
    // if the buffer is wrongly allocated this will give a bad write --> check with valgrind
    for (int j = 0; j < i; j++) p[j] = 0;
    internal::aligned_free(p);
  }
}

void check_aligned_new() {
  for (int i = ALIGNMENT; i < 1000; i++) {
    float *p = internal::aligned_new<float>(i);
    VERIFY(std::uintptr_t(p) % ALIGNMENT == 0);
    // if the buffer is wrongly allocated this will give a bad write --> check with valgrind
    for (int j = 0; j < i; j++) p[j] = 0;
    internal::aligned_delete(p, i);
  }
}

void check_aligned_stack_alloc() {
  for (int i = ALIGNMENT; i < 400; i++) {
    ei_declare_aligned_stack_constructed_variable(float, p, i, 0);
    VERIFY(std::uintptr_t(p) % ALIGNMENT == 0);
    // if the buffer is wrongly allocated this will give a bad write --> check with valgrind
    for (int j = 0; j < i; j++) p[j] = 0;
  }
}

// test compilation with both a struct and a class...
struct MyStruct {
  EIGEN_MAKE_ALIGNED_OPERATOR_NEW
  char dummychar;
  Vector16f avec;
};

class MyClassA {
 public:
  EIGEN_MAKE_ALIGNED_OPERATOR_NEW
  char dummychar;
  Vector16f avec;
};

template <typename T>
void check_dynaligned() {
  // TODO have to be updated once we support multiple alignment values
  if (T::SizeAtCompileTime % ALIGNMENT == 0) {
    T *obj = new T;
    VERIFY(T::NeedsToAlign == 1);
    VERIFY(std::uintptr_t(obj) % ALIGNMENT == 0);
    delete obj;
  }
}

template <typename T>
void check_custom_new_delete() {
  {
    T *t = new T;
    delete t;
  }

  {
    std::size_t N = internal::random<std::size_t>(1, 10);
    T *t = new T[N];
    delete[] t;
  }

#if EIGEN_MAX_ALIGN_BYTES > 0 && (!EIGEN_HAS_CXX17_OVERALIGN)
  {
    T *t = static_cast<T *>((T::operator new)(sizeof(T)));
    (T::operator delete)(t, sizeof(T));
  }

  {
    T *t = static_cast<T *>((T::operator new)(sizeof(T)));
    (T::operator delete)(t);
  }
#endif
}

EIGEN_DECLARE_TEST(dynalloc) {
  // low level dynamic memory allocation
  CALL_SUBTEST(check_handmade_aligned_malloc());
  CALL_SUBTEST(check_aligned_malloc());
  CALL_SUBTEST(check_aligned_new());
  CALL_SUBTEST(check_aligned_stack_alloc());

  for (int i = 0; i < g_repeat * 100; ++i) {
    CALL_SUBTEST(check_custom_new_delete<Vector4f>());
    CALL_SUBTEST(check_custom_new_delete<Vector2f>());
    CALL_SUBTEST(check_custom_new_delete<Matrix4f>());
    CALL_SUBTEST(check_custom_new_delete<MatrixXi>());
  }

// check static allocation, who knows ?
#if EIGEN_MAX_STATIC_ALIGN_BYTES
  for (int i = 0; i < g_repeat * 100; ++i) {
    CALL_SUBTEST(check_dynaligned<Vector4f>());
    CALL_SUBTEST(check_dynaligned<Vector2d>());
    CALL_SUBTEST(check_dynaligned<Matrix4f>());
    CALL_SUBTEST(check_dynaligned<Vector4d>());
    CALL_SUBTEST(check_dynaligned<Vector4i>());
    CALL_SUBTEST(check_dynaligned<Vector8f>());
    CALL_SUBTEST(check_dynaligned<Vector16f>());
  }

  {
    MyStruct foo0;
    VERIFY(std::uintptr_t(foo0.avec.data()) % ALIGNMENT == 0);
    MyClassA fooA;
    VERIFY(std::uintptr_t(fooA.avec.data()) % ALIGNMENT == 0);
  }

  // dynamic allocation, single object
  for (int i = 0; i < g_repeat * 100; ++i) {
    MyStruct *foo0 = new MyStruct();
    VERIFY(std::uintptr_t(foo0->avec.data()) % ALIGNMENT == 0);
    MyClassA *fooA = new MyClassA();
    VERIFY(std::uintptr_t(fooA->avec.data()) % ALIGNMENT == 0);
    delete foo0;
    delete fooA;
  }

  // dynamic allocation, array
  const int N = 10;
  for (int i = 0; i < g_repeat * 100; ++i) {
    MyStruct *foo0 = new MyStruct[N];
    VERIFY(std::uintptr_t(foo0->avec.data()) % ALIGNMENT == 0);
    MyClassA *fooA = new MyClassA[N];
    VERIFY(std::uintptr_t(fooA->avec.data()) % ALIGNMENT == 0);
    delete[] foo0;
    delete[] fooA;
  }
#endif
}
