can now call operators using paramater order in allocator
parent
4d731b074d
commit
fc8133376d
|
@ -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)
|
||||
|
|
|
@ -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<decltype(&"SillString")>() << std::endl;
|
||||
std::cout << alloc.pop<std::string>() << std::endl;
|
||||
std::cout << alloc.pop<bool>() << std::endl;
|
||||
std::cout << alloc.pop<bool>() << std::endl;
|
||||
std::cout << alloc.pop<double>() << std::endl;
|
||||
std::cout << alloc.pop<float>() << std::endl;
|
||||
std::cout << alloc.pop<int>() << 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<large>();
|
||||
std::cout << "Is empty? " << alloc.empty() << std::endl;
|
||||
std::cout << alloc.pop<silly>() << std::endl;
|
||||
std::cout << "Is empty? " << alloc.empty() << std::endl;
|
||||
alloc.pop<super_large>();
|
||||
std::cout << "Is empty? " << alloc.empty() << std::endl;
|
||||
alloc.pop<large>();
|
||||
std::cout << "Is empty? " << alloc.empty() << std::endl;
|
||||
std::cout << alloc.pop<silly>() << 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<float, float, int, bool> silly_op([](float f, int i, bool b) -> float {
|
||||
std::cout << "We found values: " << f << " " << i << " " << b << std::endl;
|
||||
return f + static_cast<float>(i * b);
|
||||
});
|
||||
|
||||
std::cout << alloc.run(silly_op) << std::endl;
|
||||
|
||||
std::cout << std::endl;
|
||||
|
||||
blt::size_t remaining_bytes = 4096;
|
||||
//auto* pointer = static_cast<void*>(head->metadata.offset);
|
||||
//return std::align(alignment, bytes, pointer, remaining_bytes);
|
||||
|
||||
blt::gp::operation<float, float, int, bool> silly([](float f, int i, bool b) -> float {
|
||||
return static_cast<float>(f);
|
||||
});
|
||||
|
||||
float f = 10.5;
|
||||
int i = 412;
|
||||
bool b = true;
|
||||
|
@ -353,7 +383,7 @@ int main()
|
|||
|
||||
blt::span<void*, 3> spv{arr};
|
||||
|
||||
std::cout << silly.operator()(spv) << std::endl;
|
||||
std::cout << silly_op.operator()(spv) << std::endl;
|
||||
|
||||
std::cout << "Hello World!" << std::endl;
|
||||
}
|
|
@ -29,6 +29,7 @@
|
|||
#include <string_view>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <iostream>
|
||||
|
||||
namespace blt::gp
|
||||
{
|
||||
|
@ -85,6 +86,65 @@ namespace blt::gp
|
|||
std::vector<type> types;
|
||||
};
|
||||
|
||||
template<typename Return, typename... Args>
|
||||
class operation
|
||||
{
|
||||
public:
|
||||
using function_t = std::function<Return(Args...)>;
|
||||
|
||||
operation(const operation& copy) = default;
|
||||
|
||||
operation(operation&& move) = default;
|
||||
|
||||
template<typename T, std::enable_if_t<std::is_same_v<T, function_t>, void>>
|
||||
explicit operation(const T& functor): func(functor)
|
||||
{}
|
||||
|
||||
template<typename T, std::enable_if_t<!std::is_same_v<T, function_t>, 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<void*> args)
|
||||
{
|
||||
auto pack_sequence = std::make_integer_sequence<blt::u64, sizeof...(Args)>();
|
||||
return function_evaluator(args, pack_sequence);
|
||||
}
|
||||
|
||||
std::function<Return(blt::span<void*>)> to_functor()
|
||||
{
|
||||
return [this](blt::span<void*> args) {
|
||||
return this->operator()(args);
|
||||
};
|
||||
}
|
||||
|
||||
private:
|
||||
template<typename T, blt::size_t index>
|
||||
static inline T& access_pack_index(blt::span<void*> args)
|
||||
{
|
||||
return *reinterpret_cast<T*>(args[index]);
|
||||
}
|
||||
|
||||
template<typename T, T... indexes>
|
||||
Return function_evaluator(blt::span<void*> args, std::integer_sequence<T, indexes...>)
|
||||
{
|
||||
return func(access_pack_index<Args, indexes>(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<T>();
|
||||
head->metadata.offset = static_cast<blt::u8*>(ptr) + sizeof(T);
|
||||
head->metadata.offset = static_cast<blt::u8*>(ptr) + aligned_size<T>();
|
||||
new(ptr) T(std::forward<T>(value));
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
T pop()
|
||||
{
|
||||
constexpr auto TYPE_SIZE = aligned_size<T>();
|
||||
constexpr static auto TYPE_SIZE = aligned_size<T>();
|
||||
if (head == nullptr)
|
||||
throw std::runtime_error("Silly boi the stack is empty!");
|
||||
if (head->used_bytes_in_block() < static_cast<blt::ptrdiff_t>(sizeof(T)))
|
||||
if (head->used_bytes_in_block() < static_cast<blt::ptrdiff_t>(aligned_size<T>()))
|
||||
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<T*>(head->metadata.offset - TYPE_SIZE);
|
||||
|
@ -126,7 +186,7 @@ namespace blt::gp
|
|||
template<typename T>
|
||||
T& from(blt::size_t bytes)
|
||||
{
|
||||
constexpr auto TYPE_SIZE = aligned_size<T>();
|
||||
constexpr static auto TYPE_SIZE = aligned_size<T>();
|
||||
auto remaining_bytes = static_cast<blt::i64>(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<blt::ptrdiff_t>(aligned_size<T>()))
|
||||
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<T*>((blk->metadata.offset - bytes_into_block) - TYPE_SIZE);
|
||||
}
|
||||
|
||||
template<blt::u64 index, typename... Args>
|
||||
blt::size_t getByteOffset()
|
||||
{
|
||||
blt::size_t offset = 0;
|
||||
blt::size_t current_index = 0;
|
||||
((offset += (current_index++ > index ? aligned_size<Args>() : 0)), ...);
|
||||
return offset;
|
||||
}
|
||||
|
||||
template<typename CurrentArgument, blt::u64 index, typename... Args>
|
||||
CurrentArgument& getArgument()
|
||||
{
|
||||
auto bytes = getByteOffset<index, Args...>();
|
||||
return from<CurrentArgument>(bytes);
|
||||
}
|
||||
|
||||
template<typename Return, typename... Args, blt::u64... indices>
|
||||
Return sequence_to_indices(const operation<Return, Args...>& function, std::integer_sequence<blt::u64, indices...>)
|
||||
{
|
||||
return function(getArgument<Args, indices, Args...>()...);
|
||||
}
|
||||
|
||||
template<typename Return, typename... Args>
|
||||
Return run(const operation<Return, Args...>& function)
|
||||
{
|
||||
auto seq = std::make_integer_sequence<blt::u64, sizeof...(Args)>();
|
||||
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;
|
||||
|
@ -285,65 +384,6 @@ namespace blt::gp
|
|||
block* head = nullptr;
|
||||
};
|
||||
|
||||
template<typename Return, typename... Args>
|
||||
class operation
|
||||
{
|
||||
public:
|
||||
using function_t = std::function<Return(Args...)>;
|
||||
|
||||
operation(const operation& copy) = default;
|
||||
|
||||
operation(operation&& move) = default;
|
||||
|
||||
template<typename T, std::enable_if_t<std::is_same_v<T, function_t>, void>>
|
||||
explicit operation(const T& functor): func(functor)
|
||||
{}
|
||||
|
||||
template<typename T, std::enable_if_t<!std::is_same_v<T, function_t>, 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<void*> args)
|
||||
{
|
||||
auto pack_sequence = std::make_integer_sequence<blt::u64, sizeof...(Args)>();
|
||||
return function_evaluator(args, pack_sequence);
|
||||
}
|
||||
|
||||
std::function<Return(blt::span<void*>)> to_functor()
|
||||
{
|
||||
return [this](blt::span<void*> args) {
|
||||
return this->operator()(args);
|
||||
};
|
||||
}
|
||||
|
||||
private:
|
||||
template<typename T, blt::size_t index>
|
||||
static inline T& access_pack_index(blt::span<void*> args)
|
||||
{
|
||||
return *reinterpret_cast<T*>(args[index]);
|
||||
}
|
||||
|
||||
template<typename T, T... indexes>
|
||||
Return function_evaluator(blt::span<void*> args, std::integer_sequence<T, indexes...>)
|
||||
{
|
||||
return func(access_pack_index<Args, indexes>(args)...);
|
||||
}
|
||||
|
||||
function_t func;
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue