You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
138 lines
3.7 KiB
138 lines
3.7 KiB
/*
|
|
Author: xerox
|
|
Date: 4/23/2020
|
|
|
|
example:
|
|
std::vector<int, going_internal::no_alloc<int, 30>> test;
|
|
test.reserve(30);
|
|
*/
|
|
|
|
#pragma once
|
|
#include <memory>
|
|
|
|
#define HEAP_SIZE 0x2000
|
|
|
|
// taken from:
|
|
// https://github.com/charles-salvia/charles/blob/master/stack_allocator.hpp
|
|
template <class T, std::size_t heap_size = sizeof(T) * 10, class Allocator = std::allocator<T>>
|
|
class no_alloc
|
|
{
|
|
public:
|
|
|
|
typedef typename std::allocator_traits<Allocator>::value_type value_type;
|
|
typedef typename std::allocator_traits<Allocator>::pointer pointer;
|
|
typedef typename std::allocator_traits<Allocator>::const_pointer const_pointer;
|
|
typedef typename Allocator::reference reference;
|
|
typedef typename Allocator::const_reference const_reference;
|
|
typedef typename std::allocator_traits<Allocator>::size_type size_type;
|
|
typedef typename std::allocator_traits<Allocator>::difference_type difference_type;
|
|
typedef typename std::allocator_traits<Allocator>::const_void_pointer const_void_pointer;
|
|
typedef Allocator allocator_type;
|
|
|
|
public:
|
|
explicit no_alloc(const allocator_type& alloc = allocator_type())
|
|
: m_allocator(alloc), m_begin(this->heap), m_end(this->heap + heap_size),
|
|
m_stack_pointer(this->heap)
|
|
{ }
|
|
|
|
template <class U>
|
|
no_alloc(const no_alloc<U, heap_size, Allocator>& other)
|
|
: m_allocator(other.m_allocator), m_begin(other.m_begin), m_end(other.m_end),
|
|
m_stack_pointer(other.m_stack_pointer)
|
|
{ }
|
|
|
|
constexpr static size_type capacity()
|
|
{
|
|
return heap_size;
|
|
}
|
|
|
|
pointer allocate(size_type n, const_void_pointer hint = const_void_pointer())
|
|
{
|
|
pointer result = m_stack_pointer;
|
|
m_stack_pointer += n;
|
|
return result;
|
|
}
|
|
|
|
void deallocate(pointer p, size_type n)
|
|
{
|
|
m_stack_pointer -= n;
|
|
}
|
|
|
|
size_type max_size() const noexcept
|
|
{
|
|
return m_allocator.max_size();
|
|
}
|
|
|
|
template <class U, class... Args>
|
|
void construct(U* p, Args&&... args)
|
|
{
|
|
m_allocator.construct(p, std::forward<Args>(args)...);
|
|
}
|
|
|
|
template <class U>
|
|
void destroy(U* p)
|
|
{
|
|
m_allocator.destroy(p);
|
|
}
|
|
|
|
pointer address(reference x) const noexcept
|
|
{
|
|
if (pointer_to_internal_buffer(std::addressof(x)))
|
|
{
|
|
return std::addressof(x);
|
|
}
|
|
|
|
return m_allocator.address(x);
|
|
}
|
|
|
|
const_pointer address(const_reference x) const noexcept
|
|
{
|
|
if (pointer_to_internal_buffer(std::addressof(x)))
|
|
{
|
|
return std::addressof(x);
|
|
}
|
|
|
|
return m_allocator.address(x);
|
|
}
|
|
|
|
template <class U>
|
|
struct rebind { typedef no_alloc<U, heap_size, allocator_type> other; };
|
|
|
|
pointer buffer() const noexcept
|
|
{
|
|
return m_begin;
|
|
}
|
|
|
|
private:
|
|
|
|
bool pointer_to_internal_buffer(const_pointer p) const
|
|
{
|
|
return (!(std::less<const_pointer>()(p, m_begin)) && (std::less<const_pointer>()(p, m_end)));
|
|
}
|
|
|
|
allocator_type m_allocator;
|
|
pointer m_begin;
|
|
pointer m_end;
|
|
pointer m_stack_pointer;
|
|
T heap[heap_size];
|
|
};
|
|
|
|
template <class T1, std::size_t heap_size, class Allocator, class T2>
|
|
static bool operator == (const no_alloc<T1, heap_size, Allocator>& lhs,
|
|
const no_alloc<T2, heap_size, Allocator>& rhs) noexcept
|
|
{
|
|
return lhs.buffer() == rhs.buffer();
|
|
}
|
|
|
|
template <class T1, std::size_t heap_size, class Allocator, class T2>
|
|
static bool operator != (const no_alloc<T1, heap_size, Allocator>& lhs,
|
|
const no_alloc<T2, heap_size, Allocator>& rhs) noexcept
|
|
{
|
|
return !(lhs == rhs);
|
|
}
|
|
|
|
inline no_alloc<std::uint8_t, HEAP_SIZE> heap;
|
|
void* operator new(std::size_t size);
|
|
void operator delete(void* ptr, unsigned __int64);
|
|
void* malloc(std::size_t size);
|
|
void free(void*, std::size_t size); |