// Copyright 2017 The Abseil Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "ceres/internal/fixed_array.h"

#include <cstdio>
#include <cstring>
#include <list>
#include <memory>
#include <numeric>
#include <scoped_allocator>
#include <stdexcept>
#include <string>
#include <vector>

#include "gmock/gmock.h"
#include "gtest/gtest.h"

using ::testing::ElementsAreArray;

namespace {

// CERES_INTERNAL_ARRAYSIZE()
//
// Returns the number of elements in an array as a compile-time constant, which
// can be used in defining new arrays. If you use this macro on a pointer by
// mistake, you will get a compile-time error.
#define CERES_INTERNAL_ARRAYSIZE(array) (sizeof(ArraySizeHelper(array)))

// Note: this internal template function declaration is used by
// CERES_INTERNAL_ARRAYSIZE. The function doesn't need a definition, as we only
// use its type.
template <typename T, size_t N>
auto ArraySizeHelper(const T (&array)[N]) -> char (&)[N];

// Helper routine to determine if a ceres::internal::FixedArray used stack
// allocation.
template <typename ArrayType>
static bool IsOnStack(const ArrayType& a) {
  return a.size() <= ArrayType::inline_elements;
}

class ConstructionTester {
 public:
  ConstructionTester() : self_ptr_(this) { constructions++; }
  ~ConstructionTester() {
    assert(self_ptr_ == this);
    self_ptr_ = nullptr;
    destructions++;
  }

  // These are incremented as elements are constructed and destructed so we can
  // be sure all elements are properly cleaned up.
  static int constructions;
  static int destructions;

  void CheckConstructed() { assert(self_ptr_ == this); }

  void set(int value) { value_ = value; }
  int get() { return value_; }

 private:
  // self_ptr_ should always point to 'this' -- that's how we can be sure the
  // constructor has been called.
  ConstructionTester* self_ptr_;
  int value_{0};
};

int ConstructionTester::constructions = 0;
int ConstructionTester::destructions = 0;

// ThreeInts will initialize its three ints to the value stored in
// ThreeInts::counter. The constructor increments counter so that each object
// in an array of ThreeInts will have different values.
class ThreeInts {
 public:
  ThreeInts() {
    x_ = counter;
    y_ = counter;
    z_ = counter;
    ++counter;
  }

  static int counter;

  int x_, y_, z_;
};

int ThreeInts::counter = 0;

TEST(FixedArrayTest, CopyCtor) {
  ceres::internal::FixedArray<int, 10> on_stack(5);
  std::iota(on_stack.begin(), on_stack.end(), 0);
  ceres::internal::FixedArray<int, 10> stack_copy = on_stack;
  EXPECT_THAT(stack_copy, ElementsAreArray(on_stack));
  EXPECT_TRUE(IsOnStack(stack_copy));

  ceres::internal::FixedArray<int, 10> allocated(15);
  std::iota(allocated.begin(), allocated.end(), 0);
  ceres::internal::FixedArray<int, 10> alloced_copy = allocated;
  EXPECT_THAT(alloced_copy, ElementsAreArray(allocated));
  EXPECT_FALSE(IsOnStack(alloced_copy));
}

TEST(FixedArrayTest, MoveCtor) {
  ceres::internal::FixedArray<std::unique_ptr<int>, 10> on_stack(5);
  for (int i = 0; i < 5; ++i) {
    on_stack[i] = std::make_unique<int>(i);
  }

  ceres::internal::FixedArray<std::unique_ptr<int>, 10> stack_copy =
      std::move(on_stack);
  for (int i = 0; i < 5; ++i) EXPECT_EQ(*(stack_copy[i]), i);
  EXPECT_EQ(stack_copy.size(), on_stack.size());

  ceres::internal::FixedArray<std::unique_ptr<int>, 10> allocated(15);
  for (int i = 0; i < 15; ++i) {
    allocated[i] = std::make_unique<int>(i);
  }

  ceres::internal::FixedArray<std::unique_ptr<int>, 10> alloced_copy =
      std::move(allocated);
  for (int i = 0; i < 15; ++i) EXPECT_EQ(*(alloced_copy[i]), i);
  EXPECT_EQ(allocated.size(), alloced_copy.size());
}

TEST(FixedArrayTest, SmallObjects) {
  // Small object arrays
  {
    // Short arrays should be on the stack
    ceres::internal::FixedArray<int> array(4);
    EXPECT_TRUE(IsOnStack(array));
  }

  {
    // Large arrays should be on the heap
    ceres::internal::FixedArray<int> array(1048576);
    EXPECT_FALSE(IsOnStack(array));
  }

  {
    // Arrays of <= default size should be on the stack
    ceres::internal::FixedArray<int, 100> array(100);
    EXPECT_TRUE(IsOnStack(array));
  }

  {
    // Arrays of > default size should be on the heap
    ceres::internal::FixedArray<int, 100> array(101);
    EXPECT_FALSE(IsOnStack(array));
  }

  {
    // Arrays with different size elements should use approximately
    // same amount of stack space
    ceres::internal::FixedArray<int> array1(0);
    ceres::internal::FixedArray<char> array2(0);
    EXPECT_LE(sizeof(array1), sizeof(array2) + 100);
    EXPECT_LE(sizeof(array2), sizeof(array1) + 100);
  }

  {
    // Ensure that vectors are properly constructed inside a fixed array.
    ceres::internal::FixedArray<std::vector<int>> array(2);
    EXPECT_EQ(0, array[0].size());
    EXPECT_EQ(0, array[1].size());
  }

  {
    // Regardless of ceres::internal::FixedArray implementation, check that a
    // type with a low alignment requirement and a non power-of-two size is
    // initialized correctly.
    ThreeInts::counter = 1;
    ceres::internal::FixedArray<ThreeInts> array(2);
    EXPECT_EQ(1, array[0].x_);
    EXPECT_EQ(1, array[0].y_);
    EXPECT_EQ(1, array[0].z_);
    EXPECT_EQ(2, array[1].x_);
    EXPECT_EQ(2, array[1].y_);
    EXPECT_EQ(2, array[1].z_);
  }
}

TEST(FixedArrayRelationalsTest, EqualArrays) {
  for (int i = 0; i < 10; ++i) {
    ceres::internal::FixedArray<int, 5> a1(i);
    std::iota(a1.begin(), a1.end(), 0);
    ceres::internal::FixedArray<int, 5> a2(a1.begin(), a1.end());

    EXPECT_TRUE(a1 == a2);
    EXPECT_FALSE(a1 != a2);
    EXPECT_TRUE(a2 == a1);
    EXPECT_FALSE(a2 != a1);
    EXPECT_FALSE(a1 < a2);
    EXPECT_FALSE(a1 > a2);
    EXPECT_FALSE(a2 < a1);
    EXPECT_FALSE(a2 > a1);
    EXPECT_TRUE(a1 <= a2);
    EXPECT_TRUE(a1 >= a2);
    EXPECT_TRUE(a2 <= a1);
    EXPECT_TRUE(a2 >= a1);
  }
}

TEST(FixedArrayRelationalsTest, UnequalArrays) {
  for (int i = 1; i < 10; ++i) {
    ceres::internal::FixedArray<int, 5> a1(i);
    std::iota(a1.begin(), a1.end(), 0);
    ceres::internal::FixedArray<int, 5> a2(a1.begin(), a1.end());
    --a2[i / 2];

    EXPECT_FALSE(a1 == a2);
    EXPECT_TRUE(a1 != a2);
    EXPECT_FALSE(a2 == a1);
    EXPECT_TRUE(a2 != a1);
    EXPECT_FALSE(a1 < a2);
    EXPECT_TRUE(a1 > a2);
    EXPECT_TRUE(a2 < a1);
    EXPECT_FALSE(a2 > a1);
    EXPECT_FALSE(a1 <= a2);
    EXPECT_TRUE(a1 >= a2);
    EXPECT_TRUE(a2 <= a1);
    EXPECT_FALSE(a2 >= a1);
  }
}

template <int stack_elements>
static void TestArray(int n) {
  SCOPED_TRACE(n);
  SCOPED_TRACE(stack_elements);
  ConstructionTester::constructions = 0;
  ConstructionTester::destructions = 0;
  {
    ceres::internal::FixedArray<ConstructionTester, stack_elements> array(n);

    EXPECT_THAT(array.size(), n);
    EXPECT_THAT(array.memsize(), sizeof(ConstructionTester) * n);
    EXPECT_THAT(array.begin() + n, array.end());

    // Check that all elements were constructed
    for (int i = 0; i < n; i++) {
      array[i].CheckConstructed();
    }
    // Check that no other elements were constructed
    EXPECT_THAT(ConstructionTester::constructions, n);

    // Test operator[]
    for (int i = 0; i < n; i++) {
      array[i].set(i);
    }
    for (int i = 0; i < n; i++) {
      EXPECT_THAT(array[i].get(), i);
      EXPECT_THAT(array.data()[i].get(), i);
    }

    // Test data()
    for (int i = 0; i < n; i++) {
      array.data()[i].set(i + 1);
    }
    for (int i = 0; i < n; i++) {
      EXPECT_THAT(array[i].get(), i + 1);
      EXPECT_THAT(array.data()[i].get(), i + 1);
    }
  }  // Close scope containing 'array'.

  // Check that all constructed elements were destructed.
  EXPECT_EQ(ConstructionTester::constructions,
            ConstructionTester::destructions);
}

template <int elements_per_inner_array, int inline_elements>
static void TestArrayOfArrays(int n) {
  SCOPED_TRACE(n);
  SCOPED_TRACE(inline_elements);
  SCOPED_TRACE(elements_per_inner_array);
  ConstructionTester::constructions = 0;
  ConstructionTester::destructions = 0;
  {
    using InnerArray = ConstructionTester[elements_per_inner_array];
    // Heap-allocate the FixedArray to avoid blowing the stack frame.
    auto array_ptr = std::unique_ptr<
        ceres::internal::FixedArray<InnerArray, inline_elements>>(
        new ceres::internal::FixedArray<InnerArray, inline_elements>(n));
    auto& array = *array_ptr;

    ASSERT_EQ(array.size(), n);
    ASSERT_EQ(array.memsize(),
              sizeof(ConstructionTester) * elements_per_inner_array * n);
    ASSERT_EQ(array.begin() + n, array.end());

    // Check that all elements were constructed
    for (int i = 0; i < n; i++) {
      for (int j = 0; j < elements_per_inner_array; j++) {
        (array[i])[j].CheckConstructed();
      }
    }
    // Check that no other elements were constructed
    ASSERT_EQ(ConstructionTester::constructions, n * elements_per_inner_array);

    // Test operator[]
    for (int i = 0; i < n; i++) {
      for (int j = 0; j < elements_per_inner_array; j++) {
        (array[i])[j].set(i * elements_per_inner_array + j);
      }
    }
    for (int i = 0; i < n; i++) {
      for (int j = 0; j < elements_per_inner_array; j++) {
        ASSERT_EQ((array[i])[j].get(), i * elements_per_inner_array + j);
        ASSERT_EQ((array.data()[i])[j].get(), i * elements_per_inner_array + j);
      }
    }

    // Test data()
    for (int i = 0; i < n; i++) {
      for (int j = 0; j < elements_per_inner_array; j++) {
        (array.data()[i])[j].set((i + 1) * elements_per_inner_array + j);
      }
    }
    for (int i = 0; i < n; i++) {
      for (int j = 0; j < elements_per_inner_array; j++) {
        ASSERT_EQ((array[i])[j].get(), (i + 1) * elements_per_inner_array + j);
        ASSERT_EQ((array.data()[i])[j].get(),
                  (i + 1) * elements_per_inner_array + j);
      }
    }
  }  // Close scope containing 'array'.

  // Check that all constructed elements were destructed.
  EXPECT_EQ(ConstructionTester::constructions,
            ConstructionTester::destructions);
}

TEST(IteratorConstructorTest, NonInline) {
  int const kInput[] = {2, 3, 5, 7, 11, 13, 17};
  ceres::internal::FixedArray<int, CERES_INTERNAL_ARRAYSIZE(kInput) - 1> const
      fixed(kInput, kInput + CERES_INTERNAL_ARRAYSIZE(kInput));
  ASSERT_EQ(CERES_INTERNAL_ARRAYSIZE(kInput), fixed.size());
  for (size_t i = 0; i < CERES_INTERNAL_ARRAYSIZE(kInput); ++i) {
    ASSERT_EQ(kInput[i], fixed[i]);
  }
}

TEST(IteratorConstructorTest, Inline) {
  int const kInput[] = {2, 3, 5, 7, 11, 13, 17};
  ceres::internal::FixedArray<int, CERES_INTERNAL_ARRAYSIZE(kInput)> const
      fixed(kInput, kInput + CERES_INTERNAL_ARRAYSIZE(kInput));
  ASSERT_EQ(CERES_INTERNAL_ARRAYSIZE(kInput), fixed.size());
  for (size_t i = 0; i < CERES_INTERNAL_ARRAYSIZE(kInput); ++i) {
    ASSERT_EQ(kInput[i], fixed[i]);
  }
}

TEST(IteratorConstructorTest, NonPod) {
  char const* kInput[] = {
      "red", "orange", "yellow", "green", "blue", "indigo", "violet"};
  ceres::internal::FixedArray<std::string> const fixed(
      kInput, kInput + CERES_INTERNAL_ARRAYSIZE(kInput));
  ASSERT_EQ(CERES_INTERNAL_ARRAYSIZE(kInput), fixed.size());
  for (size_t i = 0; i < CERES_INTERNAL_ARRAYSIZE(kInput); ++i) {
    ASSERT_EQ(kInput[i], fixed[i]);
  }
}

TEST(IteratorConstructorTest, FromEmptyVector) {
  std::vector<int> const empty;
  ceres::internal::FixedArray<int> const fixed(empty.begin(), empty.end());
  EXPECT_EQ(0, fixed.size());
  EXPECT_EQ(empty.size(), fixed.size());
}

TEST(IteratorConstructorTest, FromNonEmptyVector) {
  int const kInput[] = {2, 3, 5, 7, 11, 13, 17};
  std::vector<int> const items(kInput,
                               kInput + CERES_INTERNAL_ARRAYSIZE(kInput));
  ceres::internal::FixedArray<int> const fixed(items.begin(), items.end());
  ASSERT_EQ(items.size(), fixed.size());
  for (size_t i = 0; i < items.size(); ++i) {
    ASSERT_EQ(items[i], fixed[i]);
  }
}

TEST(IteratorConstructorTest, FromBidirectionalIteratorRange) {
  int const kInput[] = {2, 3, 5, 7, 11, 13, 17};
  std::list<int> const items(kInput, kInput + CERES_INTERNAL_ARRAYSIZE(kInput));
  ceres::internal::FixedArray<int> const fixed(items.begin(), items.end());
  EXPECT_THAT(fixed, testing::ElementsAreArray(kInput));
}

TEST(InitListConstructorTest, InitListConstruction) {
  ceres::internal::FixedArray<int> fixed = {1, 2, 3};
  EXPECT_THAT(fixed, testing::ElementsAreArray({1, 2, 3}));
}

TEST(FillConstructorTest, NonEmptyArrays) {
  ceres::internal::FixedArray<int> stack_array(4, 1);
  EXPECT_THAT(stack_array, testing::ElementsAreArray({1, 1, 1, 1}));

  ceres::internal::FixedArray<int, 0> heap_array(4, 1);
  EXPECT_THAT(stack_array, testing::ElementsAreArray({1, 1, 1, 1}));
}

TEST(FillConstructorTest, EmptyArray) {
  ceres::internal::FixedArray<int> empty_fill(0, 1);
  ceres::internal::FixedArray<int> empty_size(0);
  EXPECT_EQ(empty_fill, empty_size);
}

TEST(FillConstructorTest, NotTriviallyCopyable) {
  std::string str = "abcd";
  ceres::internal::FixedArray<std::string> strings = {str, str, str, str};

  ceres::internal::FixedArray<std::string> array(4, str);
  EXPECT_EQ(array, strings);
}

TEST(FillConstructorTest, Disambiguation) {
  ceres::internal::FixedArray<size_t> a(1, 2);
  EXPECT_THAT(a, testing::ElementsAre(2));
}

TEST(FixedArrayTest, ManySizedArrays) {
  std::vector<int> sizes;
  for (int i = 1; i < 100; i++) sizes.push_back(i);
  for (int i = 100; i <= 1000; i += 100) sizes.push_back(i);
  for (int n : sizes) {
    TestArray<0>(n);
    TestArray<1>(n);
    TestArray<64>(n);
    TestArray<1000>(n);
  }
}

TEST(FixedArrayTest, ManySizedArraysOfArraysOf1) {
  for (int n = 1; n < 1000; n++) {
    ASSERT_NO_FATAL_FAILURE((TestArrayOfArrays<1, 0>(n)));
    ASSERT_NO_FATAL_FAILURE((TestArrayOfArrays<1, 1>(n)));
    ASSERT_NO_FATAL_FAILURE((TestArrayOfArrays<1, 64>(n)));
    ASSERT_NO_FATAL_FAILURE((TestArrayOfArrays<1, 1000>(n)));
  }
}

TEST(FixedArrayTest, ManySizedArraysOfArraysOf2) {
  for (int n = 1; n < 1000; n++) {
    TestArrayOfArrays<2, 0>(n);
    TestArrayOfArrays<2, 1>(n);
    TestArrayOfArrays<2, 64>(n);
    TestArrayOfArrays<2, 1000>(n);
  }
}

// If value_type is put inside of a struct container,
// we might evoke this error in a hardened build unless data() is carefully
// written, so check on that.
//     error: call to int __builtin___sprintf_chk(etc...)
//     will always overflow destination buffer [-Werror]
TEST(FixedArrayTest, AvoidParanoidDiagnostics) {
  ceres::internal::FixedArray<char, 32> buf(32);
  snprintf(buf.data(), 32, "foo");
}

TEST(FixedArrayTest, TooBigInlinedSpace) {
  struct TooBig {
    char c[1 << 20];
  };  // too big for even one on the stack

  // Simulate the data members of ceres::internal::FixedArray, a pointer and a
  // size_t.
  struct Data {
    std::tuple<size_t, std::allocator<double>> size_alloc_;
    TooBig* p;
  };

  // Make sure TooBig objects are not inlined for 0 or default size.
  static_assert(
      sizeof(ceres::internal::FixedArray<TooBig, 0>) == sizeof(Data),
      "0-sized ceres::internal::FixedArray should have same size as Data.");
  static_assert(
      alignof(ceres::internal::FixedArray<TooBig, 0>) == alignof(Data),
      "0-sized ceres::internal::FixedArray should have same alignment as "
      "Data.");
  static_assert(sizeof(ceres::internal::FixedArray<TooBig>) == sizeof(Data),
                "default-sized ceres::internal::FixedArray should have same "
                "size as Data");
  static_assert(alignof(ceres::internal::FixedArray<TooBig>) == alignof(Data),
                "default-sized ceres::internal::FixedArray should have same "
                "alignment as Data.");
}

// PickyDelete EXPECTs its class-scope deallocation funcs are unused.
struct PickyDelete {
  void operator delete(void* p) {
    EXPECT_TRUE(false) << __FUNCTION__;
    ::operator delete(p);
  }
  void operator delete[](void* p) {
    EXPECT_TRUE(false) << __FUNCTION__;
    ::operator delete[](p);
  }
};

TEST(FixedArrayTest, UsesGlobalAlloc) {
  ceres::internal::FixedArray<PickyDelete, 0> a(5);
}

TEST(FixedArrayTest, Data) {
  static const int kInput[] = {2, 3, 5, 7, 11, 13, 17};
  ceres::internal::FixedArray<int> fa(std::begin(kInput), std::end(kInput));
  EXPECT_EQ(fa.data(), &*fa.begin());
  EXPECT_EQ(fa.data(), &fa[0]);

  const ceres::internal::FixedArray<int>& cfa = fa;
  EXPECT_EQ(cfa.data(), &*cfa.begin());
  EXPECT_EQ(cfa.data(), &cfa[0]);
}

TEST(FixedArrayTest, Empty) {
  ceres::internal::FixedArray<int> empty(0);
  ceres::internal::FixedArray<int> inline_filled(1);
  ceres::internal::FixedArray<int, 0> heap_filled(1);
  EXPECT_TRUE(empty.empty());
  EXPECT_FALSE(inline_filled.empty());
  EXPECT_FALSE(heap_filled.empty());
}

TEST(FixedArrayTest, FrontAndBack) {
  ceres::internal::FixedArray<int, 3 * sizeof(int)> inlined = {1, 2, 3};
  EXPECT_EQ(inlined.front(), 1);
  EXPECT_EQ(inlined.back(), 3);

  ceres::internal::FixedArray<int, 0> allocated = {1, 2, 3};
  EXPECT_EQ(allocated.front(), 1);
  EXPECT_EQ(allocated.back(), 3);

  ceres::internal::FixedArray<int> one_element = {1};
  EXPECT_EQ(one_element.front(), one_element.back());
}

TEST(FixedArrayTest, ReverseIteratorInlined) {
  ceres::internal::FixedArray<int, 5 * sizeof(int)> a = {0, 1, 2, 3, 4};

  int counter = 5;
  for (ceres::internal::FixedArray<int>::reverse_iterator iter = a.rbegin();
       iter != a.rend();
       ++iter) {
    counter--;
    EXPECT_EQ(counter, *iter);
  }
  EXPECT_EQ(counter, 0);

  counter = 5;
  for (ceres::internal::FixedArray<int>::const_reverse_iterator iter =
           a.rbegin();
       iter != a.rend();
       ++iter) {
    counter--;
    EXPECT_EQ(counter, *iter);
  }
  EXPECT_EQ(counter, 0);

  counter = 5;
  for (auto iter = a.crbegin(); iter != a.crend(); ++iter) {
    counter--;
    EXPECT_EQ(counter, *iter);
  }
  EXPECT_EQ(counter, 0);
}

TEST(FixedArrayTest, ReverseIteratorAllocated) {
  ceres::internal::FixedArray<int, 0> a = {0, 1, 2, 3, 4};

  int counter = 5;
  for (ceres::internal::FixedArray<int>::reverse_iterator iter = a.rbegin();
       iter != a.rend();
       ++iter) {
    counter--;
    EXPECT_EQ(counter, *iter);
  }
  EXPECT_EQ(counter, 0);

  counter = 5;
  for (ceres::internal::FixedArray<int>::const_reverse_iterator iter =
           a.rbegin();
       iter != a.rend();
       ++iter) {
    counter--;
    EXPECT_EQ(counter, *iter);
  }
  EXPECT_EQ(counter, 0);

  counter = 5;
  for (auto iter = a.crbegin(); iter != a.crend(); ++iter) {
    counter--;
    EXPECT_EQ(counter, *iter);
  }
  EXPECT_EQ(counter, 0);
}

TEST(FixedArrayTest, Fill) {
  ceres::internal::FixedArray<int, 5 * sizeof(int)> inlined(5);
  int fill_val = 42;
  inlined.fill(fill_val);
  for (int i : inlined) EXPECT_EQ(i, fill_val);

  ceres::internal::FixedArray<int, 0> allocated(5);
  allocated.fill(fill_val);
  for (int i : allocated) EXPECT_EQ(i, fill_val);

  // It doesn't do anything, just make sure this compiles.
  ceres::internal::FixedArray<int> empty(0);
  empty.fill(fill_val);
}

// TODO(johnsoncj): Investigate InlinedStorage default initialization in GCC 4.x
#ifndef __GNUC__
TEST(FixedArrayTest, DefaultCtorDoesNotValueInit) {
  using T = char;
  constexpr auto capacity = 10;
  using FixedArrType = ceres::internal::FixedArray<T, capacity>;
  using FixedArrBuffType =
      typename std::aligned_storage<sizeof(FixedArrType),
                                    alignof(FixedArrType)>::type;
  constexpr auto scrubbed_bits = 0x95;
  constexpr auto length = capacity / 2;

  FixedArrBuffType buff;
  std::memset(std::addressof(buff), scrubbed_bits, sizeof(FixedArrBuffType));

  FixedArrType* arr =
      ::new (static_cast<void*>(std::addressof(buff))) FixedArrType(length);
  EXPECT_THAT(*arr, testing::Each(scrubbed_bits));
  arr->~FixedArrType();
}
#endif  // __GNUC__

// This is a stateful allocator, but the state lives outside of the
// allocator (in whatever test is using the allocator). This is odd
// but helps in tests where the allocator is propagated into nested
// containers - that chain of allocators uses the same state and is
// thus easier to query for aggregate allocation information.
template <typename T>
class CountingAllocator : public std::allocator<T> {
 public:
  using Alloc = std::allocator<T>;
  using size_type = typename Alloc::size_type;

  CountingAllocator() = default;
  explicit CountingAllocator(int64_t* b) : bytes_used_(b) {}
  CountingAllocator(int64_t* b, int64_t* a)
      : bytes_used_(b), instance_count_(a) {}

  template <typename U>
  explicit CountingAllocator(const CountingAllocator<U>& x)
      : Alloc(x),
        bytes_used_(x.bytes_used_),
        instance_count_(x.instance_count_) {}

  T* allocate(size_type n) {
    assert(bytes_used_ != nullptr);
    *bytes_used_ += n * sizeof(T);
    return Alloc::allocate(n);
  }

  void deallocate(T* p, size_type n) {
    Alloc::deallocate(p, n);
    assert(bytes_used_ != nullptr);
    *bytes_used_ -= n * sizeof(T);
  }

  int64_t* bytes_used_{nullptr};
  int64_t* instance_count_{nullptr};
};

TEST(AllocatorSupportTest, CountInlineAllocations) {
  constexpr size_t inlined_size = 4;
  using Alloc = CountingAllocator<int>;
  using AllocFxdArr = ceres::internal::FixedArray<int, inlined_size, Alloc>;

  int64_t allocated = 0;
  int64_t active_instances = 0;

  {
    const int ia[] = {0, 1, 2, 3, 4, 5, 6, 7};

    Alloc alloc(&allocated, &active_instances);

    AllocFxdArr arr(ia, ia + inlined_size, alloc);
    static_cast<void>(arr);
  }

  EXPECT_EQ(allocated, 0);
  EXPECT_EQ(active_instances, 0);
}

TEST(AllocatorSupportTest, CountOutoflineAllocations) {
  constexpr size_t inlined_size = 4;
  using Alloc = CountingAllocator<int>;
  using AllocFxdArr = ceres::internal::FixedArray<int, inlined_size, Alloc>;

  int64_t allocated = 0;
  int64_t active_instances = 0;

  {
    const int ia[] = {0, 1, 2, 3, 4, 5, 6, 7};
    Alloc alloc(&allocated, &active_instances);

    AllocFxdArr arr(ia, ia + CERES_INTERNAL_ARRAYSIZE(ia), alloc);

    EXPECT_EQ(allocated, arr.size() * sizeof(int));
    static_cast<void>(arr);
  }

  EXPECT_EQ(active_instances, 0);
}

TEST(AllocatorSupportTest, CountCopyInlineAllocations) {
  constexpr size_t inlined_size = 4;
  using Alloc = CountingAllocator<int>;
  using AllocFxdArr = ceres::internal::FixedArray<int, inlined_size, Alloc>;

  int64_t allocated1 = 0;
  int64_t allocated2 = 0;
  int64_t active_instances = 0;
  Alloc alloc(&allocated1, &active_instances);
  Alloc alloc2(&allocated2, &active_instances);

  {
    int initial_value = 1;

    AllocFxdArr arr1(inlined_size / 2, initial_value, alloc);

    EXPECT_EQ(allocated1, 0);

    AllocFxdArr arr2(arr1, alloc2);

    EXPECT_EQ(allocated2, 0);
    static_cast<void>(arr1);
    static_cast<void>(arr2);
  }

  EXPECT_EQ(active_instances, 0);
}

TEST(AllocatorSupportTest, CountCopyOutoflineAllocations) {
  constexpr size_t inlined_size = 4;
  using Alloc = CountingAllocator<int>;
  using AllocFxdArr = ceres::internal::FixedArray<int, inlined_size, Alloc>;

  int64_t allocated1 = 0;
  int64_t allocated2 = 0;
  int64_t active_instances = 0;
  Alloc alloc(&allocated1, &active_instances);
  Alloc alloc2(&allocated2, &active_instances);

  {
    int initial_value = 1;

    AllocFxdArr arr1(inlined_size * 2, initial_value, alloc);

    EXPECT_EQ(allocated1, arr1.size() * sizeof(int));

    AllocFxdArr arr2(arr1, alloc2);

    EXPECT_EQ(allocated2, inlined_size * 2 * sizeof(int));
    static_cast<void>(arr1);
    static_cast<void>(arr2);
  }

  EXPECT_EQ(active_instances, 0);
}

TEST(AllocatorSupportTest, SizeValAllocConstructor) {
  using testing::AllOf;
  using testing::Each;
  using testing::SizeIs;

  constexpr size_t inlined_size = 4;
  using Alloc = CountingAllocator<int>;
  using AllocFxdArr = ceres::internal::FixedArray<int, inlined_size, Alloc>;

  {
    auto len = inlined_size / 2;
    auto val = 0;
    int64_t allocated = 0;
    AllocFxdArr arr(len, val, Alloc(&allocated));

    EXPECT_EQ(allocated, 0);
    EXPECT_THAT(arr, AllOf(SizeIs(len), Each(0)));
  }

  {
    auto len = inlined_size * 2;
    auto val = 0;
    int64_t allocated = 0;
    AllocFxdArr arr(len, val, Alloc(&allocated));

    EXPECT_EQ(allocated, len * sizeof(int));
    EXPECT_THAT(arr, AllOf(SizeIs(len), Each(0)));
  }
}

struct EigenStruct {
  Eigen::Vector4d data;
};

static_assert(
    std::is_same<ceres::internal::FixedArrayDefaultAllocator<double>,
                 std::allocator<double>>::value,
    "Double is a trivial type, so std::allocator should be used here.");
static_assert(
    std::is_same<ceres::internal::FixedArrayDefaultAllocator<double*>,
                 std::allocator<double*>>::value,
    "A pointer is a trivial type, so std::allocator should be used here.");
static_assert(
    std::is_same<ceres::internal::FixedArrayDefaultAllocator<Eigen::Matrix4d>,
                 Eigen::aligned_allocator<Eigen::Matrix4d>>::value,
    "An Eigen::Matrix4d needs the Eigen::aligned_allocator for proper "
    "alignment.");
static_assert(
    std::is_same<ceres::internal::FixedArrayDefaultAllocator<EigenStruct>,
                 Eigen::aligned_allocator<EigenStruct>>::value,
    "A struct containing fixed size Eigen types needs Eigen::aligned_allocator "
    "for proper alignment.");

}  // namespace
