//===----------------------------------------------------------------------===//
//
// 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 SUPPORT_CONTROLLED_ALLOCATORS_HPP
#define SUPPORT_CONTROLLED_ALLOCATORS_HPP

#include <memory>
#include <type_traits>
#include <cstddef>
#include <cstdlib>
#include <cstring>
#include <cstdint>
#include <cassert>
#include "test_macros.h"
#include "type_id.h"

#if TEST_STD_VER < 11
#error This header requires C++11 or greater
#endif

struct AllocController;
    // 'AllocController' is a concrete type that instruments and controls the
    // behavior of test allocators.

template <class T, size_t ID = 0>
class CountingAllocator;
    // 'CountingAllocator' is an basic implementation of the 'Allocator'
    // requirements that use the 'AllocController' interface.

template <class T>
class MinAlignAllocator;
    // 'MinAlignAllocator' is an instrumented test type which implements the
    // 'Allocator' requirements. 'MinAlignAllocator' ensures that it *never*
    // returns a pointer to over-aligned storage. For example
    // 'MinAlignPointer<char>{}.allocate(...)' will never a 2-byte aligned
    // pointer.

template <class T>
class NullAllocator;
    // 'NullAllocator' is an instrumented test type which implements the
    // 'Allocator' requirements except that 'allocator' and 'deallocate' are
    // nops.


#define DISALLOW_COPY(Type) \
  Type(Type const&) = delete; \
  Type& operator=(Type const&) = delete

constexpr std::size_t MaxAlignV = alignof(std::max_align_t);

struct TestException {};

struct AllocController {
    int copy_constructed = 0;
    int move_constructed = 0;

    int alive = 0;
    int alloc_count = 0;
    int dealloc_count = 0;
    int is_equal_count = 0;

    std::size_t alive_size;
    std::size_t allocated_size;
    std::size_t deallocated_size;

    std::size_t last_size = 0;
    std::size_t last_align = 0;
    void * last_pointer = 0;

    std::size_t last_alloc_size = 0;
    std::size_t last_alloc_align = 0;
    void * last_alloc_pointer = nullptr;

    std::size_t last_dealloc_size = 0;
    std::size_t last_dealloc_align = 0;
    void * last_dealloc_pointer = nullptr;

    bool throw_on_alloc = false;

    int construct_called = 0;
    void *last_construct_pointer = nullptr;
    TypeID const* last_construct_alloc = nullptr;
    TypeID const* last_construct_type = nullptr;
    TypeID const* last_construct_args = nullptr;

    int destroy_called = 0;
    void *last_destroy_pointer = nullptr;
    TypeID const* last_destroy_alloc = nullptr;
    TypeID const* last_destroy_type = nullptr;

    AllocController() = default;

    void countAlloc(void* p, size_t s, size_t a) {
        ++alive;
        ++alloc_count;
        alive_size += s;
        allocated_size += s;
        last_pointer = last_alloc_pointer = p;
        last_size = last_alloc_size = s;
        last_align = last_alloc_align = a;
    }

    void countDealloc(void* p, size_t s, size_t a) {
        --alive;
        ++dealloc_count;
        alive_size -= s;
        deallocated_size += s;
        last_pointer = last_dealloc_pointer = p;
        last_size = last_dealloc_size = s;
        last_align = last_dealloc_align = a;
    }

    template <class ...Args, class Alloc, class Tp>
    void countConstruct(Alloc const&, Tp *p) {
      ++construct_called;
      last_construct_pointer = p;
      last_construct_alloc = &makeTypeID<Alloc>();
      last_construct_type = &makeTypeID<Tp>();
      last_construct_args = &makeArgumentID<Args...>();
    }

    template <class Alloc, class Tp>
    void countDestroy(Alloc const&, Tp *p) {
      ++destroy_called;
      last_destroy_alloc = &makeTypeID<Alloc>();
      last_destroy_type = &makeTypeID<Tp>();
      last_destroy_pointer = p;
    }

    void reset() { std::memset(this, 0, sizeof(*this)); }
    void resetConstructDestroy() {
      construct_called = 0;
      last_construct_pointer = nullptr;
      last_construct_alloc = last_construct_args = last_construct_type = nullptr;
      destroy_called = 0;
      last_destroy_alloc = nullptr;
      last_destroy_pointer = nullptr;
    }
public:
    bool checkAlloc(void* p, size_t s, size_t a) const {
        return p == last_alloc_pointer &&
               s == last_alloc_size &&
               a == last_alloc_align;
    }

    bool checkAlloc(void* p, size_t s) const {
        return p == last_alloc_pointer &&
               s == last_alloc_size;
    }

    bool checkAllocAtLeast(void* p, size_t s, size_t a) const {
        return p == last_alloc_pointer &&
               s <= last_alloc_size &&
               a <= last_alloc_align;
    }

    bool checkAllocAtLeast(void* p, size_t s) const {
        return p == last_alloc_pointer &&
               s <= last_alloc_size;
    }

    bool checkDealloc(void* p, size_t s, size_t a) const {
        return p == last_dealloc_pointer &&
               s == last_dealloc_size &&
               a == last_dealloc_align;
    }

    bool checkDealloc(void* p, size_t s) const {
        return p == last_dealloc_pointer &&
               s == last_dealloc_size;
    }

    bool checkDeallocMatchesAlloc() const {
        return last_dealloc_pointer == last_alloc_pointer &&
               last_dealloc_size == last_alloc_size &&
               last_dealloc_align == last_alloc_align;
    }

    template <class ...Args, class Alloc, class Tp>
    bool checkConstruct(Alloc const&, Tp *p) const {
      auto expectAlloc = &makeTypeID<Alloc>();
      auto expectTp = &makeTypeID<Tp>();
      auto expectArgs = &makeArgumentID<Args...>();
      return last_construct_pointer == p &&
          COMPARE_TYPEID(last_construct_alloc, expectAlloc) &&
          COMPARE_TYPEID(last_construct_type, expectTp) &&
          COMPARE_TYPEID(last_construct_args, expectArgs);
    }

    template <class Alloc, class Tp>
    bool checkDestroy(Alloc const&, Tp *p) const {
      return last_destroy_pointer == p &&
          last_destroy_alloc == &makeTypeID<Alloc>() &&
          last_destroy_type == &makeTypeID<Tp>();
    }

    bool checkDestroyMatchesConstruct() const {
      return last_destroy_pointer == last_construct_pointer &&
          last_destroy_type == last_construct_type;
    }

    void countIsEqual() {
        ++is_equal_count;
    }

    bool checkIsEqualCalledEq(int n) const {
        return is_equal_count == n;
    }
private:
  DISALLOW_COPY(AllocController);
};

template <class T, size_t ID>
class CountingAllocator
{
public:
    typedef T value_type;
    typedef T* pointer;

    template <class U>
    struct rebind { using other = CountingAllocator<U, ID>; };

    CountingAllocator() = delete;
    explicit CountingAllocator(AllocController& PP) : P(&PP) {}

    CountingAllocator(CountingAllocator const& other) : P(other.P) {
        P->copy_constructed += 1;
    }

    CountingAllocator(CountingAllocator&& other) : P(other.P) {
        P->move_constructed += 1;
    }

    template <class U>
    CountingAllocator(CountingAllocator<U, ID> const& other) TEST_NOEXCEPT : P(other.P) {
        P->copy_constructed += 1;
    }

    template <class U>
    CountingAllocator(CountingAllocator<U, ID>&& other) TEST_NOEXCEPT : P(other.P) {
        P->move_constructed += 1;
    }

    T* allocate(std::size_t n)
    {
        void* ret = ::operator new(n*sizeof(T));
        P->countAlloc(ret, n*sizeof(T), alignof(T));
        return static_cast<T*>(ret);
    }

    void deallocate(T* p, std::size_t n)
    {
        void* vp = static_cast<void*>(p);
        P->countDealloc(vp, n*sizeof(T), alignof(T));
        ::operator delete(vp);
    }

    template <class U, class ...Args>
    void construct(U *p, Args&&... args) {
      ::new ((void*)p) U(std::forward<Args>(args)...);
      P->countConstruct<Args&&...>(*this, p);
    }

    template <class U>
    void destroy(U* p) {
      p->~U();
      P->countDestroy(*this, p);
    }

    AllocController& getController() const { return *P; }

private:
    template <class Tp, size_t XID> friend class CountingAllocator;
    AllocController *P;
};


template <size_t ID>
class CountingAllocator<void, ID>
{
public:
    typedef void* pointer;
    typedef const void* const_pointer;
    typedef void value_type;

    template <class U>
    struct rebind { using other = CountingAllocator<U, ID>; };

    CountingAllocator() = delete;
    explicit CountingAllocator(AllocController& PP) : P(&PP) {}

    CountingAllocator(CountingAllocator const& other) : P(other.P) {
        P->copy_constructed += 1;
    }

    CountingAllocator(CountingAllocator&& other) : P(other.P) {
        P->move_constructed += 1;
    }

    template <class U>
    CountingAllocator(CountingAllocator<U, ID> const& other) TEST_NOEXCEPT : P(other.P) {
        P->copy_constructed += 1;
    }

    template <class U>
    CountingAllocator(CountingAllocator<U, ID>&& other) TEST_NOEXCEPT : P(other.P) {
        P->move_constructed += 1;
    }

    void construct(...) = delete;
    void destroy(void*) = delete;

    AllocController& getController() const { return *P; }

private:
    template <class Tp, size_t> friend class CountingAllocator;
    AllocController *P;
};

template <class T, class U, size_t ID>
inline bool operator==(CountingAllocator<T, ID> const& x,
                       CountingAllocator<U, ID> const& y) {
    return &x.getController() == &y.getController();
}

template <class T, class U, size_t ID>
inline bool operator!=(CountingAllocator<T, ID> const& x,
                       CountingAllocator<U, ID> const& y) {
    return !(x == y);
}

template <class T>
class MinAlignedAllocator
{
public:
    typedef T value_type;
    typedef T* pointer;

    MinAlignedAllocator() = delete;

    explicit MinAlignedAllocator(AllocController& R) : P(&R) {}

    MinAlignedAllocator(MinAlignedAllocator const& other) : P(other.P) {
        P->copy_constructed += 1;
    }

    MinAlignedAllocator(MinAlignedAllocator&& other) : P(other.P) {
        P->move_constructed += 1;
    }

    template <class U>
    MinAlignedAllocator(MinAlignedAllocator<U> const& other) TEST_NOEXCEPT : P(other.P) {
        P->copy_constructed += 1;
    }

    template <class U>
    MinAlignedAllocator(MinAlignedAllocator<U>&& other) TEST_NOEXCEPT : P(other.P) {
        P->move_constructed += 1;
    }

    T* allocate(std::size_t n) {
        char* aligned_ptr = (char*)::operator new(alloc_size(n*sizeof(T)));
        assert(is_max_aligned(aligned_ptr));

        char* unaligned_ptr = aligned_ptr + alignof(T);
        assert(is_min_aligned(unaligned_ptr));

        P->countAlloc(unaligned_ptr, n * sizeof(T), alignof(T));

        return ((T*)unaligned_ptr);
    }

    void deallocate(T* p, std::size_t n) {
        assert(is_min_aligned(p));

        char* aligned_ptr = ((char*)p) - alignof(T);
        assert(is_max_aligned(aligned_ptr));

        P->countDealloc(p, n*sizeof(T), alignof(T));

        return ::operator delete(static_cast<void*>(aligned_ptr));
    }

    template <class U, class ...Args>
    void construct(U *p, Args&&... args) {
      auto *c = ::new ((void*)p) U(std::forward<Args>(args)...);
      P->countConstruct<Args&&...>(*this, p);
    }

    template <class U>
    void destroy(U* p) {
      p->~U();
      P->countDestroy(*this, p);
    }

    AllocController& getController() const { return *P; }

private:
    static const std::size_t BlockSize = alignof(std::max_align_t);

    static std::size_t alloc_size(std::size_t s) {
        std::size_t bytes = (s + BlockSize - 1) & ~(BlockSize - 1);
        bytes += BlockSize;
        assert(bytes % BlockSize == 0);
        return bytes;
    }

    static bool is_max_aligned(void* p) {
        return reinterpret_cast<std::uintptr_t>(p) % BlockSize == 0;
    }

    static bool is_min_aligned(void* p) {
        if (alignof(T) == BlockSize) {
            return is_max_aligned(p);
        } else {
            return reinterpret_cast<std::uintptr_t>(p) % BlockSize == alignof(T);
        }
    }

    template <class Tp> friend class MinAlignedAllocator;
    mutable AllocController *P;
};


template <class T, class U>
inline bool operator==(MinAlignedAllocator<T> const& x,
                       MinAlignedAllocator<U> const& y) {
    return &x.getController() == &y.getController();
}

template <class T, class U>
inline bool operator!=(MinAlignedAllocator<T> const& x,
                       MinAlignedAllocator<U> const& y) {
    return !(x == y);
}

template <class T>
class NullAllocator
{
public:
    typedef T value_type;
    typedef T* pointer;
    NullAllocator() = delete;
    explicit NullAllocator(AllocController& PP) : P(&PP) {}

    NullAllocator(NullAllocator const& other) : P(other.P) {
        P->copy_constructed += 1;
    }

    NullAllocator(NullAllocator&& other) : P(other.P) {
        P->move_constructed += 1;
    }

    template <class U>
    NullAllocator(NullAllocator<U> const& other) TEST_NOEXCEPT : P(other.P) {
        P->copy_constructed += 1;
    }

    template <class U>
    NullAllocator(NullAllocator<U>&& other) TEST_NOEXCEPT : P(other.P) {
        P->move_constructed += 1;
    }

    T* allocate(std::size_t n)
    {
        P->countAlloc(nullptr, n*sizeof(T), alignof(T));
        return nullptr;
    }

    void deallocate(T* p, std::size_t n)
    {
        void* vp = static_cast<void*>(p);
        P->countDealloc(vp, n*sizeof(T), alignof(T));
    }

    AllocController& getController() const { return *P; }

private:
    template <class Tp> friend class NullAllocator;
    AllocController *P;
};

template <class T, class U>
inline bool operator==(NullAllocator<T> const& x,
                       NullAllocator<U> const& y) {
    return &x.getController() == &y.getController();
}

template <class T, class U>
inline bool operator!=(NullAllocator<T> const& x,
                       NullAllocator<U> const& y) {
    return !(x == y);
}


#endif /* SUPPORT_CONTROLLED_ALLOCATORS_HPP */
