//===----------------------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#ifndef TEST_ALLOCATOR_H
#define TEST_ALLOCATOR_H

#include <type_traits>
#include <new>
#include <memory>
#include <utility>
#include <cstddef>
#include <cstdlib>
#include <climits>
#include <cassert>

#include "test_macros.h"

template <class Alloc>
TEST_CONSTEXPR_CXX20 inline typename std::allocator_traits<Alloc>::size_type alloc_max_size(Alloc const& a) {
  typedef std::allocator_traits<Alloc> AT;
  return AT::max_size(a);
}

struct test_allocator_statistics {
  int time_to_throw = 0;
  int throw_after = INT_MAX;
  int count = 0;
  int alloc_count = 0;
  int construct_count = 0; // the number of times that ::construct was called
  int destroy_count = 0; // the number of times that ::destroy was called
  int copied = 0;
  int moved = 0;
  int converted = 0;

  TEST_CONSTEXPR_CXX14 void clear() {
    assert(count == 0 && "clearing leaking allocator data?");
    count = 0;
    time_to_throw = 0;
    alloc_count = 0;
    construct_count = 0;
    destroy_count = 0;
    throw_after = INT_MAX;
    clear_ctor_counters();
  }

  TEST_CONSTEXPR_CXX14 void clear_ctor_counters() {
    copied = 0;
    moved = 0;
    converted = 0;
  }
};

struct test_alloc_base {
  TEST_CONSTEXPR static const int destructed_value = -1;
  TEST_CONSTEXPR static const int moved_value = INT_MAX;
};

template <class T>
class test_allocator {
  int data_ = 0; // participates in equality
  int id_ = 0;   // unique identifier, doesn't participate in equality
  test_allocator_statistics* stats_ = nullptr;

  template <class U>
  friend class test_allocator;

public:
  typedef unsigned size_type;
  typedef int difference_type;
  typedef T value_type;
  typedef value_type* pointer;
  typedef const value_type* const_pointer;
  typedef typename std::add_lvalue_reference<value_type>::type reference;
  typedef typename std::add_lvalue_reference<const value_type>::type const_reference;

  template <class U>
  struct rebind {
    typedef test_allocator<U> other;
  };

  TEST_CONSTEXPR test_allocator() TEST_NOEXCEPT = default;

  TEST_CONSTEXPR_CXX14 explicit test_allocator(test_allocator_statistics* stats) TEST_NOEXCEPT : stats_(stats) {
    if (stats_ != nullptr)
      ++stats_->count;
  }

  TEST_CONSTEXPR explicit test_allocator(int data) TEST_NOEXCEPT : data_(data) {}

  TEST_CONSTEXPR_CXX14 explicit test_allocator(int data, test_allocator_statistics* stats) TEST_NOEXCEPT
      : data_(data), stats_(stats) {
    if (stats != nullptr)
      ++stats_->count;
  }

  TEST_CONSTEXPR explicit test_allocator(int data, int id) TEST_NOEXCEPT : data_(data), id_(id) {}

  TEST_CONSTEXPR_CXX14 explicit test_allocator(int data, int id, test_allocator_statistics* stats) TEST_NOEXCEPT
      : data_(data), id_(id), stats_(stats) {
    if (stats_ != nullptr)
      ++stats_->count;
  }

  TEST_CONSTEXPR_CXX14 test_allocator(const test_allocator& a) TEST_NOEXCEPT
    : data_(a.data_), id_(a.id_), stats_(a.stats_) {
    assert(a.data_ != test_alloc_base::destructed_value && a.id_ != test_alloc_base::destructed_value &&
           "copying from destroyed allocator");
    if (stats_ != nullptr) {
      ++stats_->count;
      ++stats_->copied;
    }
  }

  TEST_CONSTEXPR_CXX14 test_allocator(test_allocator&& a) TEST_NOEXCEPT : data_(a.data_), id_(a.id_), stats_(a.stats_) {
    if (stats_ != nullptr) {
      ++stats_->count;
      ++stats_->moved;
    }
    assert(a.data_ != test_alloc_base::destructed_value && a.id_ != test_alloc_base::destructed_value &&
           "moving from destroyed allocator");
    a.data_ = test_alloc_base::moved_value;
    a.id_ = test_alloc_base::moved_value;
  }

  template <class U>
  TEST_CONSTEXPR_CXX14 test_allocator(const test_allocator<U>& a) TEST_NOEXCEPT
      : data_(a.data_), id_(a.id_), stats_(a.stats_) {
    if (stats_ != nullptr) {
      ++stats_->count;
      ++stats_->converted;
    }
  }

  TEST_CONSTEXPR_CXX20 ~test_allocator() TEST_NOEXCEPT {
    assert(data_ != test_alloc_base::destructed_value);
    assert(id_ != test_alloc_base::destructed_value);
    if (stats_ != nullptr)
      --stats_->count;
    data_ = test_alloc_base::destructed_value;
    id_ = test_alloc_base::destructed_value;
  }

  TEST_CONSTEXPR pointer address(reference x) const { return &x; }
  TEST_CONSTEXPR const_pointer address(const_reference x) const { return &x; }

  TEST_CONSTEXPR_CXX14 pointer allocate(size_type n, const void* = nullptr) {
    assert(data_ != test_alloc_base::destructed_value);
    if (stats_ != nullptr) {
      if (stats_->time_to_throw >= stats_->throw_after)
        TEST_THROW(std::bad_alloc());
      ++stats_->time_to_throw;
      ++stats_->alloc_count;
    }
    return std::allocator<value_type>().allocate(n);
  }

  TEST_CONSTEXPR_CXX14 void deallocate(pointer p, size_type s) {
    assert(data_ != test_alloc_base::destructed_value);
    if (stats_ != nullptr)
      --stats_->alloc_count;
    std::allocator<value_type>().deallocate(p, s);
  }

  TEST_CONSTEXPR size_type max_size() const TEST_NOEXCEPT { return UINT_MAX / sizeof(T); }

  template <class U>
  TEST_CONSTEXPR_CXX20 void construct(pointer p, U&& val) {
    if (stats_ != nullptr)
      ++stats_->construct_count;
#if TEST_STD_VER > 17
    std::construct_at(std::to_address(p), std::forward<U>(val));
#else
    ::new (static_cast<void*>(p)) T(std::forward<U>(val));
#endif
  }

  TEST_CONSTEXPR_CXX14 void destroy(pointer p) {
    if (stats_ != nullptr)
      ++stats_->destroy_count;
    p->~T();
  }
  TEST_CONSTEXPR friend bool operator==(const test_allocator& x, const test_allocator& y) { return x.data_ == y.data_; }
  TEST_CONSTEXPR friend bool operator!=(const test_allocator& x, const test_allocator& y) { return !(x == y); }

  TEST_CONSTEXPR int get_data() const { return data_; }
  TEST_CONSTEXPR int get_id() const { return id_; }
};

template <>
class test_allocator<void> {
  int data_ = 0;
  int id_ = 0;
  test_allocator_statistics* stats_ = nullptr;

  template <class U>
  friend class test_allocator;

public:
  typedef unsigned size_type;
  typedef int difference_type;
  typedef void value_type;
  typedef value_type* pointer;
  typedef const value_type* const_pointer;

  template <class U>
  struct rebind {
    typedef test_allocator<U> other;
  };

  TEST_CONSTEXPR test_allocator() TEST_NOEXCEPT = default;

  TEST_CONSTEXPR_CXX14 explicit test_allocator(test_allocator_statistics* stats) TEST_NOEXCEPT : stats_(stats) {}

  TEST_CONSTEXPR explicit test_allocator(int data) TEST_NOEXCEPT : data_(data) {}

  TEST_CONSTEXPR explicit test_allocator(int data, test_allocator_statistics* stats) TEST_NOEXCEPT
      : data_(data), stats_(stats)
  {}

  TEST_CONSTEXPR explicit test_allocator(int data, int id) : data_(data), id_(id) {}

  TEST_CONSTEXPR_CXX14 explicit test_allocator(int data, int id, test_allocator_statistics* stats) TEST_NOEXCEPT
      : data_(data), id_(id), stats_(stats)
  {}

  TEST_CONSTEXPR_CXX14 explicit test_allocator(const test_allocator& a) TEST_NOEXCEPT
      : data_(a.data_), id_(a.id_), stats_(a.stats_)
  {}

  template <class U>
  TEST_CONSTEXPR_CXX14 test_allocator(const test_allocator<U>& a) TEST_NOEXCEPT
      : data_(a.data_), id_(a.id_), stats_(a.stats_)
  {}

  TEST_CONSTEXPR_CXX20 ~test_allocator() TEST_NOEXCEPT {
    data_ = test_alloc_base::destructed_value;
    id_ = test_alloc_base::destructed_value;
  }

  TEST_CONSTEXPR int get_id() const { return id_; }
  TEST_CONSTEXPR int get_data() const { return data_; }

  TEST_CONSTEXPR friend bool operator==(const test_allocator& x, const test_allocator& y) { return x.data_ == y.data_; }
  TEST_CONSTEXPR friend bool operator!=(const test_allocator& x, const test_allocator& y) { return !(x == y); }
};

template <class T>
class other_allocator {
  int data_ = -1;

  template <class U>
  friend class other_allocator;

public:
  typedef T value_type;

  TEST_CONSTEXPR_CXX14 other_allocator() {}
  TEST_CONSTEXPR_CXX14 explicit other_allocator(int i) : data_(i) {}

  template <class U>
  TEST_CONSTEXPR_CXX14 other_allocator(const other_allocator<U>& a) : data_(a.data_) {}

  TEST_CONSTEXPR_CXX20 T* allocate(std::size_t n) { return std::allocator<value_type>().allocate(n); }
  TEST_CONSTEXPR_CXX20 void deallocate(T* p, std::size_t s) { std::allocator<value_type>().deallocate(p, s); }

  TEST_CONSTEXPR_CXX14 other_allocator select_on_container_copy_construction() const { return other_allocator(-2); }

  TEST_CONSTEXPR_CXX14 friend bool operator==(const other_allocator& x, const other_allocator& y) {
    return x.data_ == y.data_;
  }

  TEST_CONSTEXPR_CXX14 friend bool operator!=(const other_allocator& x, const other_allocator& y) { return !(x == y); }

  typedef std::true_type propagate_on_container_copy_assignment;
  typedef std::true_type propagate_on_container_move_assignment;
  typedef std::true_type propagate_on_container_swap;

#if TEST_STD_VER < 11
  std::size_t max_size() const { return UINT_MAX / sizeof(T); }
#endif
};

struct Ctor_Tag {};

template <typename T>
class TaggingAllocator;

struct Tag_X {
  // All constructors must be passed the Tag type.

  // DefaultInsertable into vector<X, TaggingAllocator<X>>,
  TEST_CONSTEXPR Tag_X(Ctor_Tag) {}
  // CopyInsertable into vector<X, TaggingAllocator<X>>,
  TEST_CONSTEXPR Tag_X(Ctor_Tag, const Tag_X&) {}
  // MoveInsertable into vector<X, TaggingAllocator<X>>, and
  TEST_CONSTEXPR Tag_X(Ctor_Tag, Tag_X&&) {}

  // EmplaceConstructible into vector<X, TaggingAllocator<X>> from args.
  template <typename... Args>
  TEST_CONSTEXPR Tag_X(Ctor_Tag, Args&&...) {}

  // not DefaultConstructible, CopyConstructible or MoveConstructible.
  Tag_X() = delete;
  Tag_X(const Tag_X&) = delete;
  Tag_X(Tag_X&&) = delete;

  // CopyAssignable.
  TEST_CONSTEXPR_CXX14 Tag_X& operator=(const Tag_X&) { return *this; };

  // MoveAssignable.
  TEST_CONSTEXPR_CXX14 Tag_X& operator=(Tag_X&&) { return *this; };

private:
  ~Tag_X() = default;
  // Erasable from vector<X, TaggingAllocator<X>>.
  friend class TaggingAllocator<Tag_X>;
};

template <typename T>
class TaggingAllocator {
public:
  using value_type = T;
  TaggingAllocator() = default;

  template <typename U>
  TEST_CONSTEXPR TaggingAllocator(const TaggingAllocator<U>&) {}

  template <typename... Args>
  TEST_CONSTEXPR_CXX20 void construct(Tag_X* p, Args&&... args) {
#if TEST_STD_VER > 17
    std::construct_at(p, Ctor_Tag{}, std::forward<Args>(args)...);
#else
    ::new (static_cast<void*>(p)) Tag_X(Ctor_Tag(), std::forward<Args>(args)...);
#endif
  }

  template <typename U>
  TEST_CONSTEXPR_CXX20 void destroy(U* p) {
    p->~U();
  }

  TEST_CONSTEXPR_CXX20 T* allocate(std::size_t n) { return std::allocator<T>().allocate(n); }
  TEST_CONSTEXPR_CXX20 void deallocate(T* p, std::size_t n) { std::allocator<T>().deallocate(p, n); }
};

template <std::size_t MaxAllocs>
struct limited_alloc_handle {
  std::size_t outstanding_ = 0;
  void* last_alloc_ = nullptr;

  template <class T>
  TEST_CONSTEXPR_CXX20 T* allocate(std::size_t N) {
    if (N + outstanding_ > MaxAllocs)
      TEST_THROW(std::bad_alloc());
    auto alloc = std::allocator<T>().allocate(N);
    last_alloc_ = alloc;
    outstanding_ += N;
    return alloc;
  }

  template <class T>
  TEST_CONSTEXPR_CXX20 void deallocate(T* ptr, std::size_t N) {
    if (ptr == last_alloc_) {
      last_alloc_ = nullptr;
      assert(outstanding_ >= N);
      outstanding_ -= N;
    }
    std::allocator<T>().deallocate(ptr, N);
  }
};

namespace detail {
template <class T>
class thread_unsafe_shared_ptr {
public:
  thread_unsafe_shared_ptr() = default;

  TEST_CONSTEXPR_CXX14 thread_unsafe_shared_ptr(const thread_unsafe_shared_ptr& other) : block(other.block) {
    ++block->ref_count;
  }

  TEST_CONSTEXPR_CXX20 ~thread_unsafe_shared_ptr() {
    --block->ref_count;
    if (block->ref_count != 0)
      return;
    typedef std::allocator_traits<std::allocator<control_block> > allocator_traits;
    std::allocator<control_block> alloc;
    allocator_traits::destroy(alloc, block);
    allocator_traits::deallocate(alloc, block, 1);
  }

  TEST_CONSTEXPR const T& operator*() const { return block->content; }
  TEST_CONSTEXPR const T* operator->() const { return &block->content; }
  TEST_CONSTEXPR_CXX14 T& operator*() { return block->content; }
  TEST_CONSTEXPR_CXX14 T* operator->() { return &block->content; }
  TEST_CONSTEXPR_CXX14 T* get() { return &block->content; }
  TEST_CONSTEXPR const T* get() const { return &block->content; }

private:
  struct control_block {
    template <class... Args>
    TEST_CONSTEXPR control_block(Args... args) : content(std::forward<Args>(args)...) {}
    std::size_t ref_count = 1;
    T content;
  };

  control_block* block = nullptr;

  template <class U, class... Args>
  friend TEST_CONSTEXPR_CXX20 thread_unsafe_shared_ptr<U> make_thread_unsafe_shared(Args...);
};

template <class T, class... Args>
TEST_CONSTEXPR_CXX20 thread_unsafe_shared_ptr<T> make_thread_unsafe_shared(Args... args) {
  typedef typename thread_unsafe_shared_ptr<T>::control_block control_block_type;
  typedef std::allocator_traits<std::allocator<control_block_type> > allocator_traits;

  thread_unsafe_shared_ptr<T> ptr;
  std::allocator<control_block_type> alloc;
  ptr.block = allocator_traits::allocate(alloc, 1);
  allocator_traits::construct(alloc, ptr.block, std::forward<Args>(args)...);

  return ptr;
}
} // namespace detail

template <class T, std::size_t N>
class limited_allocator {
  template <class U, std::size_t UN>
  friend class limited_allocator;
  typedef limited_alloc_handle<N> BuffT;
  detail::thread_unsafe_shared_ptr<BuffT> handle_;

public:
  typedef T value_type;
  typedef value_type* pointer;
  typedef const value_type* const_pointer;
  typedef value_type& reference;
  typedef const value_type& const_reference;
  typedef std::size_t size_type;
  typedef std::ptrdiff_t difference_type;

  template <class U>
  struct rebind {
    typedef limited_allocator<U, N> other;
  };

  TEST_CONSTEXPR_CXX20 limited_allocator() : handle_(detail::make_thread_unsafe_shared<BuffT>()) {}

  limited_allocator(limited_allocator const&) = default;

  template <class U>
  TEST_CONSTEXPR explicit limited_allocator(limited_allocator<U, N> const& other) : handle_(other.handle_) {}

  limited_allocator& operator=(const limited_allocator&) = delete;

  TEST_CONSTEXPR_CXX20 pointer allocate(size_type n) { return handle_->template allocate<T>(n); }
  TEST_CONSTEXPR_CXX20 void deallocate(pointer p, size_type n) { handle_->template deallocate<T>(p, n); }
  TEST_CONSTEXPR size_type max_size() const { return N; }
  TEST_CONSTEXPR BuffT* getHandle() const { return handle_.get(); }
};

template <class T, class U, std::size_t N>
TEST_CONSTEXPR inline bool operator==(limited_allocator<T, N> const& LHS, limited_allocator<U, N> const& RHS) {
  return LHS.getHandle() == RHS.getHandle();
}

template <class T, class U, std::size_t N>
TEST_CONSTEXPR inline bool operator!=(limited_allocator<T, N> const& LHS, limited_allocator<U, N> const& RHS) {
  return !(LHS == RHS);
}

#endif // TEST_ALLOCATOR_H
