silly code doesn't work
parent
8c79c8dd15
commit
13562d35ff
|
@ -1,5 +1,5 @@
|
||||||
cmake_minimum_required(VERSION 3.25)
|
cmake_minimum_required(VERSION 3.25)
|
||||||
project(blt-gp VERSION 0.0.8)
|
project(blt-gp VERSION 0.0.9)
|
||||||
|
|
||||||
option(ENABLE_ADDRSAN "Enable the address sanitizer" OFF)
|
option(ENABLE_ADDRSAN "Enable the address sanitizer" OFF)
|
||||||
option(ENABLE_UBSAN "Enable the ub sanitizer" OFF)
|
option(ENABLE_UBSAN "Enable the ub sanitizer" OFF)
|
||||||
|
|
|
@ -16,10 +16,10 @@
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <cstddef>
|
|
||||||
#ifndef BLT_GP_PROGRAM_H
|
#ifndef BLT_GP_PROGRAM_H
|
||||||
#define BLT_GP_PROGRAM_H
|
#define BLT_GP_PROGRAM_H
|
||||||
|
|
||||||
|
#include <cstddef>
|
||||||
#include <blt/gp/fwdecl.h>
|
#include <blt/gp/fwdecl.h>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include <blt/std/ranges.h>
|
#include <blt/std/ranges.h>
|
||||||
|
@ -89,6 +89,99 @@ namespace blt::gp
|
||||||
{
|
{
|
||||||
constexpr static blt::size_t PAGE_SIZE = 0x1000;
|
constexpr static blt::size_t PAGE_SIZE = 0x1000;
|
||||||
public:
|
public:
|
||||||
|
/**
|
||||||
|
* Pushes an instance of an object on to the stack
|
||||||
|
* @tparam T type to push
|
||||||
|
* @param value universal reference to the object to push
|
||||||
|
*/
|
||||||
|
template<typename T>
|
||||||
|
void push(T&& value)
|
||||||
|
{
|
||||||
|
auto ptr = allocate_bytes<T>();
|
||||||
|
head->metadata.offset = ptr + sizeof(T);
|
||||||
|
new(ptr) T(std::forward<T>(value));
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
T pop()
|
||||||
|
{
|
||||||
|
if (head == nullptr)
|
||||||
|
throw std::runtime_error("Silly boi the stack is empty!");
|
||||||
|
if (head->remaining_bytes_in_block() - head->storage_size() < sizeof(T))
|
||||||
|
throw std::runtime_error("Mismatched Types!");
|
||||||
|
T t = *reinterpret_cast<T*>(head->metadata.offset - sizeof(T));
|
||||||
|
head->metadata.offset -= sizeof(T);
|
||||||
|
if (head->used_bytes_in_block() == static_cast<blt::ptrdiff_t>(head->storage_size()))
|
||||||
|
{
|
||||||
|
auto ptr = head;
|
||||||
|
head = head->metadata.prev;
|
||||||
|
delete ptr;
|
||||||
|
}
|
||||||
|
return t;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
T& from(blt::size_t bytes)
|
||||||
|
{
|
||||||
|
auto remaining_bytes = static_cast<blt::i64>(bytes);
|
||||||
|
blt::i64 bytes_into_block = 0;
|
||||||
|
block* blk = head;
|
||||||
|
while (remaining_bytes > 0)
|
||||||
|
{
|
||||||
|
if (blk == nullptr)
|
||||||
|
throw std::runtime_error("Requested size is beyond the scope of this stack!");
|
||||||
|
auto bytes_available = blk->used_bytes_in_block() - remaining_bytes;
|
||||||
|
bytes_into_block = remaining_bytes;
|
||||||
|
if (bytes_available < 0)
|
||||||
|
{
|
||||||
|
remaining_bytes = -bytes_available;
|
||||||
|
blk = head->metadata.prev;
|
||||||
|
} else
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (blk == nullptr)
|
||||||
|
throw std::runtime_error("Some nonsense is going on. This function already smells");
|
||||||
|
return *reinterpret_cast<T*>((blk->metadata.offset - bytes_into_block) - sizeof(T));
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] bool empty() const
|
||||||
|
{
|
||||||
|
if (head == nullptr)
|
||||||
|
return true;
|
||||||
|
if (head->metadata.prev != nullptr)
|
||||||
|
return false;
|
||||||
|
return head->used_bytes_in_block() == static_cast<blt::ptrdiff_t>(head->storage_size());
|
||||||
|
}
|
||||||
|
|
||||||
|
stack_allocator() = default;
|
||||||
|
|
||||||
|
stack_allocator(const stack_allocator& copy) = delete;
|
||||||
|
|
||||||
|
stack_allocator& operator=(const stack_allocator& copy) = delete;
|
||||||
|
|
||||||
|
stack_allocator(stack_allocator&& move) noexcept
|
||||||
|
{
|
||||||
|
head = move.head;
|
||||||
|
move.head = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
stack_allocator& operator=(stack_allocator&& move) noexcept
|
||||||
|
{
|
||||||
|
head = move.head;
|
||||||
|
move.head = nullptr;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
~stack_allocator()
|
||||||
|
{
|
||||||
|
block* current = head;
|
||||||
|
while (current != nullptr)
|
||||||
|
{
|
||||||
|
block* ptr = current;
|
||||||
|
current = current->metadata.prev;
|
||||||
|
delete ptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct block
|
struct block
|
||||||
|
@ -108,17 +201,62 @@ namespace blt::gp
|
||||||
metadata.offset = buffer;
|
metadata.offset = buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]] blt::size_t remainder_after_meta() const
|
[[nodiscard]] blt::ptrdiff_t storage_size() const
|
||||||
{
|
{
|
||||||
return metadata.size - sizeof(typename block::block_metadata_t);
|
return static_cast<blt::ptrdiff_t>(metadata.size - sizeof(typename block::block_metadata_t));
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]] blt::ptrdiff_t remaining_bytes() const
|
[[nodiscard]] blt::ptrdiff_t remaining_bytes_in_block() const
|
||||||
|
{
|
||||||
|
return storage_size() - static_cast<blt::ptrdiff_t>(metadata.offset - buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] blt::ptrdiff_t used_bytes_in_block() const
|
||||||
{
|
{
|
||||||
return static_cast<blt::ptrdiff_t>(metadata.offset - buffer);
|
return static_cast<blt::ptrdiff_t>(metadata.offset - buffer);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
void* allocate_bytes()
|
||||||
|
{
|
||||||
|
auto ptr = get_aligned_pointer(sizeof(T), alignof(T));
|
||||||
|
if (ptr == nullptr)
|
||||||
|
push_block_for<T>();
|
||||||
|
ptr = get_aligned_pointer(sizeof(T), alignof(T));
|
||||||
|
if (ptr == nullptr)
|
||||||
|
throw std::bad_alloc();
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void* get_aligned_pointer(blt::size_t bytes, blt::size_t alignment)
|
||||||
|
{
|
||||||
|
if (head == nullptr)
|
||||||
|
return nullptr;
|
||||||
|
blt::size_t remaining_bytes = head->remaining_bytes_in_block();
|
||||||
|
auto* pointer = static_cast<void*>(head->metadata.offset);
|
||||||
|
return std::align(alignment, bytes, pointer, remaining_bytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
void push_block_for()
|
||||||
|
{
|
||||||
|
push_block(std::max(PAGE_SIZE, to_nearest_page_size(sizeof(T))));
|
||||||
|
}
|
||||||
|
|
||||||
|
void push_block(blt::size_t size)
|
||||||
|
{
|
||||||
|
auto blk = allocate_block(size);
|
||||||
|
if (head == nullptr)
|
||||||
|
{
|
||||||
|
head = blk;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
head->metadata.next = blk;
|
||||||
|
blk->metadata.prev = head;
|
||||||
|
head = blk;
|
||||||
|
}
|
||||||
|
|
||||||
static size_t to_nearest_page_size(blt::size_t bytes)
|
static size_t to_nearest_page_size(blt::size_t bytes)
|
||||||
{
|
{
|
||||||
constexpr static blt::size_t MASK = ~(PAGE_SIZE - 1);
|
constexpr static blt::size_t MASK = ~(PAGE_SIZE - 1);
|
||||||
|
|
Loading…
Reference in New Issue