From 4735c6c21bb7ea3c01fa0875b743b9724c78c6d1 Mon Sep 17 00:00:00 2001 From: Brett Laptop Date: Sun, 11 Aug 2024 20:21:53 -0400 Subject: [PATCH] destructors are not possible currently. use a gc if you need them. --- CMakeLists.txt | 2 +- include/blt/gp/operations.h | 42 ++++++++++++++++++++++-------- include/blt/gp/stack.h | 13 +++++----- lib/blt | 2 +- tests/destructor_test.cpp | 52 +++++++++++++++++++++---------------- 5 files changed, 70 insertions(+), 41 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 8e05dc2..62d5355 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,5 +1,5 @@ cmake_minimum_required(VERSION 3.25) -project(blt-gp VERSION 0.0.135) +project(blt-gp VERSION 0.0.136) include(CTest) diff --git a/include/blt/gp/operations.h b/include/blt/gp/operations.h index c2ed5a9..839ba9f 100644 --- a/include/blt/gp/operations.h +++ b/include/blt/gp/operations.h @@ -101,18 +101,30 @@ namespace blt::gp allocator.from>(getByteOffset())...); } + template + void call_destructors_without_first(stack_allocator& read_allocator) + { + if constexpr (sizeof...(NoCtxArgs) > 0) + { + read_allocator.call_destructors...>(); + } + } + template - Return operator()(Func&& func, stack_allocator& read_allocator, ExtraArgs&& ... args) + Return operator()(bool, Func&& func, stack_allocator& read_allocator, ExtraArgs&& ... args) { constexpr auto seq = std::make_integer_sequence(); #if BLT_DEBUG_LEVEL > 0 try { #endif - Return ret = exec_sequence_to_indices(std::forward(func), read_allocator, seq, std::forward(args)...); - read_allocator.call_destructors...>(); - read_allocator.pop_bytes((stack_allocator::aligned_size>() + ...)); - return ret; + Return ret = exec_sequence_to_indices(std::forward(func), read_allocator, seq, std::forward(args)...); + /*if (has_context) + call_destructors_without_first(read_allocator); + else + read_allocator.call_destructors...>();*/ + read_allocator.pop_bytes((stack_allocator::aligned_size>() + ...)); + return ret; #if BLT_DEBUG_LEVEL > 0 } catch (const std::runtime_error& e) { @@ -153,7 +165,7 @@ namespace blt::gp return func(); } else { - return call_with()(func, read_allocator); + return call_with()(false, func, read_allocator); } } @@ -170,7 +182,7 @@ namespace blt::gp return func(ctx_ref); } else { - return call_without_first()(func, read_allocator, ctx_ref); + return call_without_first()(true, func, read_allocator, ctx_ref); } } @@ -214,16 +226,24 @@ namespace blt::gp }; template - operation_t(Lambda) -> operation_t; + operation_t(Lambda) + -> + operation_t; template - operation_t(Return(*)(Args...)) -> operation_t; + operation_t(Return(*) + (Args...)) -> + operation_t; template - operation_t(Lambda, std::optional) -> operation_t; + operation_t(Lambda, std::optional + ) -> + operation_t; template - operation_t(Return(*)(Args...), std::optional) -> operation_t; + operation_t(Return(*) + (Args...), std::optional) -> + operation_t; } #endif //BLT_GP_OPERATIONS_H diff --git a/include/blt/gp/stack.h b/include/blt/gp/stack.h index e7ecefc..e09aade 100644 --- a/include/blt/gp/stack.h +++ b/include/blt/gp/stack.h @@ -205,14 +205,15 @@ namespace blt::gp * @param value universal reference to the object to push */ template - void push(T&& value) + void push(const T& value) { using NO_REF_T = std::remove_cv_t>; static_assert(std::is_trivially_copyable_v && "Type must be bitwise copyable!"); static_assert(alignof(NO_REF_T) <= MAX_ALIGNMENT && "Type must not be greater than the max alignment!"); auto ptr = allocate_bytes(); head->metadata.offset = static_cast(ptr) + aligned_size(); - new(ptr) NO_REF_T(std::forward(value)); + //new(ptr) NO_REF_T(std::forward(value)); + std::memcpy(ptr, &value, sizeof(NO_REF_T)); } template @@ -233,7 +234,7 @@ namespace blt::gp NO_REF_T t = *reinterpret_cast(head->metadata.offset - TYPE_SIZE); // call destructor if constexpr (detail::has_func_drop_v) - reinterpret_cast(head->metadata.offset - TYPE_SIZE)->~NO_REF_T(); + call_drop(0); // move offset back head->metadata.offset -= TYPE_SIZE; // moving back allows us to allocate with other data, if there is room. @@ -348,9 +349,9 @@ namespace blt::gp template void call_destructors() { - blt::size_t offset = 0; - - ((call_drop(offset), offset += stack_allocator::aligned_size>()), ...); + blt::size_t offset = (stack_allocator::aligned_size>() + ...) - + stack_allocator::aligned_size::First>>(); + ((call_drop(offset), offset -= stack_allocator::aligned_size>()), ...); } [[nodiscard]] bool empty() const noexcept diff --git a/lib/blt b/lib/blt index 4327b34..92300bc 160000 --- a/lib/blt +++ b/lib/blt @@ -1 +1 @@ -Subproject commit 4327b34c841fd6d8fb6509757d5cab2717d35457 +Subproject commit 92300bc6a29927f5354d516df76ad40be7fca868 diff --git a/tests/destructor_test.cpp b/tests/destructor_test.cpp index 29fbe70..ee1677d 100644 --- a/tests/destructor_test.cpp +++ b/tests/destructor_test.cpp @@ -43,39 +43,46 @@ //static constexpr long SEED = 41912; static const unsigned long SEED = std::random_device()(); +inline std::atomic_uint64_t last_value = 0; inline std::atomic_uint64_t constructions = 0; inline std::atomic_uint64_t destructions = 0; class move_float { public: - move_float(): f(new float()) - { constructions++; } - - explicit move_float(float f): f(new float(f)) + move_float(): f(new float()), assignment(++last_value) { constructions++; - // BLT_TRACE("Value Constructed"); + BLT_TRACE("Value %ld Default Constructed", assignment); + } + + explicit move_float(float f): f(new float(f)), assignment(++last_value) + { + constructions++; + BLT_TRACE("Value %ld Constructed", assignment); } explicit operator float() const { + BLT_TRACE("Using value %ld", assignment); return *f; } - float get() const + [[nodiscard]] float get() const { + BLT_TRACE("Using value %ld", assignment); return *f; } float operator*() const { + BLT_TRACE("Using value %ld", assignment); return *f; } void drop() // NOLINT { - //BLT_TRACE("Drop Called"); + BLT_TRACE("Drop Called On %ld", assignment); delete f; f = nullptr; destructions++; @@ -83,6 +90,7 @@ class move_float private: float* f = nullptr; + blt::size_t assignment; }; static_assert(std::is_trivially_copyable_v); @@ -90,7 +98,7 @@ static_assert(std::is_trivially_copyable_v); struct context { - move_float x, y; + float x, y; }; std::array fitness_cases; @@ -104,32 +112,32 @@ blt::gp::prog_config_t config = blt::gp::prog_config_t() .set_reproduction_chance(0) .set_max_generations(1) .set_pop_size(1) - .set_thread_count(0); + .set_thread_count(1); blt::gp::type_provider type_system; blt::gp::gp_program program{type_system, SEED, config}; -blt::gp::operation_t add([](const move_float& a, const move_float& b) { return move_float(*a + *b); }, "add"); -blt::gp::operation_t sub([](const move_float& a, const move_float& b) { return move_float(*a - *b); }, "sub"); -blt::gp::operation_t mul([](const move_float& a, const move_float& b) { return move_float(*a * *b); }, "mul"); -blt::gp::operation_t pro_div([](const move_float& a, const move_float& b) { return move_float(*b == 0.0f ? 1.0f : *a / *b); }, "div"); -blt::gp::operation_t op_sin([](const move_float& a) { return move_float(std::sin(*a)); }, "sin"); -blt::gp::operation_t op_cos([](const move_float& a) { return move_float(std::cos(*a)); }, "cos"); -blt::gp::operation_t op_exp([](const move_float& a) { return move_float(std::exp(*a)); }, "exp"); -blt::gp::operation_t op_log([](const move_float& a) { return move_float(*a == 0.0f ? 0.0f : std::log(*a)); }, "log"); +blt::gp::operation_t add([](const move_float& a, const move_float& b) { return move_float(*a + *b); }, "add"); // 0 +blt::gp::operation_t sub([](const move_float& a, const move_float& b) { return move_float(*a - *b); }, "sub"); // 1 +blt::gp::operation_t mul([](const move_float& a, const move_float& b) { return move_float(*a * *b); }, "mul"); // 2 +blt::gp::operation_t pro_div([](const move_float& a, const move_float& b) { return move_float(*b == 0.0f ? 1.0f : *a / *b); }, "div"); // 3 +blt::gp::operation_t op_sin([](const move_float& a) { return move_float(std::sin(*a)); }, "sin"); // 4 +blt::gp::operation_t op_cos([](const move_float& a) { return move_float(std::cos(*a)); }, "cos"); // 5 +blt::gp::operation_t op_exp([](const move_float& a) { return move_float(std::exp(*a)); }, "exp"); // 6 +blt::gp::operation_t op_log([](const move_float& a) { return move_float(*a == 0.0f ? 0.0f : std::log(*a)); }, "log"); // 7 -blt::gp::operation_t lit([]() { +blt::gp::operation_t lit([]() { // 8 return move_float(program.get_random().get_float(-320.0f, 320.0f)); }, "lit"); -blt::gp::operation_t op_x([](const context& context) { - return context.x; +blt::gp::operation_t op_x([](const context& context) { // 9 + return move_float(context.x); }, "x"); constexpr auto fitness_function = [](blt::gp::tree_t& current_tree, blt::gp::fitness_t& fitness, blt::size_t) { constexpr double value_cutoff = 1.e15; for (auto& fitness_case : fitness_cases) { - auto diff = std::abs(*fitness_case.y - *current_tree.get_evaluation_value(&fitness_case)); + auto diff = std::abs(fitness_case.y - *current_tree.get_evaluation_value(&fitness_case)); if (diff < value_cutoff) { fitness.raw_fitness += diff; @@ -159,7 +167,7 @@ int main() constexpr float half_range = range / 2.0; auto x = program.get_random().get_float(-half_range, half_range); auto y = example_function(x); - fitness_case = {move_float(x), move_float(y)}; + fitness_case = {x, y}; } BLT_DEBUG("Setup Types and Operators");