silly code doesn't work

thread
Brett 2024-06-04 21:52:43 -04:00
parent 8c79c8dd15
commit 13562d35ff
2 changed files with 143 additions and 5 deletions

View File

@ -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)

View File

@ -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);