From fc8133376df75467c780617391a910b29424778e Mon Sep 17 00:00:00 2001 From: Brett Date: Thu, 6 Jun 2024 00:50:44 -0400 Subject: [PATCH] can now call operators using paramater order in allocator --- CMakeLists.txt | 2 +- examples/main.cpp | 42 ++++++++-- include/blt/gp/program.h | 168 ++++++++++++++++++++++++--------------- 3 files changed, 141 insertions(+), 71 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index a5d1e58..766b7a6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,5 +1,5 @@ cmake_minimum_required(VERSION 3.25) -project(blt-gp VERSION 0.0.13) +project(blt-gp VERSION 0.0.14) option(ENABLE_ADDRSAN "Enable the address sanitizer" OFF) option(ENABLE_UBSAN "Enable the ub sanitizer" OFF) diff --git a/examples/main.cpp b/examples/main.cpp index cd0f71e..7d2e0d0 100644 --- a/examples/main.cpp +++ b/examples/main.cpp @@ -312,12 +312,16 @@ int main() alloc.push(50); alloc.push(550.3f); alloc.push(20.1230345); + alloc.push(true); + alloc.push(false); alloc.push(std::string("SillyString")); alloc.push(&"SillyString"); std::cout << std::endl; std::cout << *alloc.pop() << std::endl; std::cout << alloc.pop() << std::endl; + std::cout << alloc.pop() << std::endl; + std::cout << alloc.pop() << std::endl; std::cout << alloc.pop() << std::endl; std::cout << alloc.pop() << std::endl; std::cout << alloc.pop() << std::endl; @@ -331,20 +335,46 @@ int main() alloc.push(large{}); std::cout << std::endl; + std::cout << "Is empty? " << alloc.empty() << std::endl; alloc.pop(); + std::cout << "Is empty? " << alloc.empty() << std::endl; std::cout << alloc.pop() << std::endl; + std::cout << "Is empty? " << alloc.empty() << std::endl; alloc.pop(); + std::cout << "Is empty? " << alloc.empty() << std::endl; alloc.pop(); + std::cout << "Is empty? " << alloc.empty() << std::endl; std::cout << alloc.pop() << std::endl; + std::cout << std::endl; + + std::cout << "Is empty? " << alloc.empty() << " bytes left: " << alloc.bytes_in_head() << std::endl; + std::cout << std::endl; + + alloc.push(silly{2, 5}); + alloc.push(large{}); + alloc.push(super_large{}); + alloc.push(silly{80, 10}); + alloc.push(large{}); + alloc.push(50); + alloc.push(550.3f); + alloc.push(20.1230345); + alloc.push(std::string("SillyString")); + alloc.push(33.22f); + alloc.push(120); + alloc.push(true); + + blt::gp::operation silly_op([](float f, int i, bool b) -> float { + std::cout << "We found values: " << f << " " << i << " " << b << std::endl; + return f + static_cast(i * b); + }); + + std::cout << alloc.run(silly_op) << std::endl; + + std::cout << std::endl; - blt::size_t remaining_bytes = 4096; //auto* pointer = static_cast(head->metadata.offset); //return std::align(alignment, bytes, pointer, remaining_bytes); - blt::gp::operation silly([](float f, int i, bool b) -> float { - return static_cast(f); - }); - float f = 10.5; int i = 412; bool b = true; @@ -353,7 +383,7 @@ int main() blt::span spv{arr}; - std::cout << silly.operator()(spv) << std::endl; + std::cout << silly_op.operator()(spv) << std::endl; std::cout << "Hello World!" << std::endl; } \ No newline at end of file diff --git a/include/blt/gp/program.h b/include/blt/gp/program.h index c243d18..68fb72f 100644 --- a/include/blt/gp/program.h +++ b/include/blt/gp/program.h @@ -29,6 +29,7 @@ #include #include #include +#include namespace blt::gp { @@ -85,6 +86,65 @@ namespace blt::gp std::vector types; }; + template + class operation + { + public: + using function_t = std::function; + + operation(const operation& copy) = default; + + operation(operation&& move) = default; + + template, void>> + explicit operation(const T& functor): func(functor) + {} + + template, void>> + explicit operation(const T& functor) + { + func = [&functor](Args... args) { + return functor(args...); + }; + } + + explicit operation(function_t&& functor): func(std::move(functor)) + {} + + [[nodiscard]] inline Return operator()(Args... args) const + { + return func(args...); + } + + Return operator()(blt::span args) + { + auto pack_sequence = std::make_integer_sequence(); + return function_evaluator(args, pack_sequence); + } + + std::function)> to_functor() + { + return [this](blt::span args) { + return this->operator()(args); + }; + } + + private: + template + static inline T& access_pack_index(blt::span args) + { + return *reinterpret_cast(args[index]); + } + + template + Return function_evaluator(blt::span args, std::integer_sequence) + { + return func(access_pack_index(args)...); + } + + function_t func; + }; + class stack_allocator { constexpr static blt::size_t PAGE_SIZE = 0x1000; @@ -99,17 +159,17 @@ namespace blt::gp void push(T&& value) { auto ptr = allocate_bytes(); - head->metadata.offset = static_cast(ptr) + sizeof(T); + head->metadata.offset = static_cast(ptr) + aligned_size(); new(ptr) T(std::forward(value)); } template T pop() { - constexpr auto TYPE_SIZE = aligned_size(); + constexpr static auto TYPE_SIZE = aligned_size(); if (head == nullptr) throw std::runtime_error("Silly boi the stack is empty!"); - if (head->used_bytes_in_block() < static_cast(sizeof(T))) + if (head->used_bytes_in_block() < static_cast(aligned_size())) throw std::runtime_error((std::string("Mismatched Types! Not enough space left in block! Bytes: ") += std::to_string( head->used_bytes_in_block()) += " Size: " + std::to_string(sizeof(T))).c_str()); T t = *reinterpret_cast(head->metadata.offset - TYPE_SIZE); @@ -126,7 +186,7 @@ namespace blt::gp template T& from(blt::size_t bytes) { - constexpr auto TYPE_SIZE = aligned_size(); + constexpr static auto TYPE_SIZE = aligned_size(); auto remaining_bytes = static_cast(bytes); blt::i64 bytes_into_block = 0; block* blk = head; @@ -145,9 +205,41 @@ namespace blt::gp } if (blk == nullptr) throw std::runtime_error("Some nonsense is going on. This function already smells"); + if (blk->used_bytes_in_block() < static_cast(aligned_size())) + throw std::runtime_error((std::string("Mismatched Types! Not enough space left in block! Bytes: ") += std::to_string( + blk->used_bytes_in_block()) += " Size: " + std::to_string(sizeof(T))).c_str()); return *reinterpret_cast((blk->metadata.offset - bytes_into_block) - TYPE_SIZE); } + template + blt::size_t getByteOffset() + { + blt::size_t offset = 0; + blt::size_t current_index = 0; + ((offset += (current_index++ > index ? aligned_size() : 0)), ...); + return offset; + } + + template + CurrentArgument& getArgument() + { + auto bytes = getByteOffset(); + return from(bytes); + } + + template + Return sequence_to_indices(const operation& function, std::integer_sequence) + { + return function(getArgument()...); + } + + template + Return run(const operation& function) + { + auto seq = std::make_integer_sequence(); + return sequence_to_indices(function, seq); + } + [[nodiscard]] bool empty() const { if (head == nullptr) @@ -157,6 +249,13 @@ namespace blt::gp return head->used_bytes_in_block() == 0; } + [[nodiscard]] blt::ptrdiff_t bytes_in_head() const + { + if (head == nullptr) + return 0; + return head->used_bytes_in_block(); + } + stack_allocator() = default; stack_allocator(const stack_allocator& copy) = delete; @@ -278,72 +377,13 @@ namespace blt::gp template static inline constexpr blt::size_t aligned_size() noexcept { - return (sizeof(T) + (MAX_ALIGNMENT - 1)) & ~(MAX_ALIGNMENT-1); + return (sizeof(T) + (MAX_ALIGNMENT - 1)) & ~(MAX_ALIGNMENT - 1); } private: block* head = nullptr; }; - template - class operation - { - public: - using function_t = std::function; - - operation(const operation& copy) = default; - - operation(operation&& move) = default; - - template, void>> - explicit operation(const T& functor): func(functor) - {} - - template, void>> - explicit operation(const T& functor) - { - func = [&functor](Args... args) { - return functor(args...); - }; - } - - explicit operation(function_t&& functor): func(std::move(functor)) - {} - - inline Return operator()(Args... args) - { - return func(args...); - } - - Return operator()(blt::span args) - { - auto pack_sequence = std::make_integer_sequence(); - return function_evaluator(args, pack_sequence); - } - - std::function)> to_functor() - { - return [this](blt::span args) { - return this->operator()(args); - }; - } - - private: - template - static inline T& access_pack_index(blt::span args) - { - return *reinterpret_cast(args[index]); - } - - template - Return function_evaluator(blt::span args, std::integer_sequence) - { - return func(access_pack_index(args)...); - } - - function_t func; - }; - }