destructors are not possible currently. use a gc if you need them.
parent
e9954f5065
commit
4735c6c21b
|
@ -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)
|
||||
|
||||
|
|
|
@ -101,8 +101,17 @@ namespace blt::gp
|
|||
allocator.from<detail::remove_cv_ref<Args>>(getByteOffset<indices>())...);
|
||||
}
|
||||
|
||||
template<typename context = void, typename... NoCtxArgs>
|
||||
void call_destructors_without_first(stack_allocator& read_allocator)
|
||||
{
|
||||
if constexpr (sizeof...(NoCtxArgs) > 0)
|
||||
{
|
||||
read_allocator.call_destructors<detail::remove_cv_ref<NoCtxArgs>...>();
|
||||
}
|
||||
}
|
||||
|
||||
template<typename Func, typename... ExtraArgs>
|
||||
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<blt::u64, sizeof...(Args)>();
|
||||
#if BLT_DEBUG_LEVEL > 0
|
||||
|
@ -110,7 +119,10 @@ namespace blt::gp
|
|||
{
|
||||
#endif
|
||||
Return ret = exec_sequence_to_indices(std::forward<Func>(func), read_allocator, seq, std::forward<ExtraArgs>(args)...);
|
||||
read_allocator.call_destructors<detail::remove_cv_ref<Args>...>();
|
||||
/*if (has_context)
|
||||
call_destructors_without_first<Args...>(read_allocator);
|
||||
else
|
||||
read_allocator.call_destructors<detail::remove_cv_ref<Args>...>();*/
|
||||
read_allocator.pop_bytes((stack_allocator::aligned_size<detail::remove_cv_ref<Args>>() + ...));
|
||||
return ret;
|
||||
#if BLT_DEBUG_LEVEL > 0
|
||||
|
@ -153,7 +165,7 @@ namespace blt::gp
|
|||
return func();
|
||||
} else
|
||||
{
|
||||
return call_with<Return, Args...>()(func, read_allocator);
|
||||
return call_with<Return, Args...>()(false, func, read_allocator);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -170,7 +182,7 @@ namespace blt::gp
|
|||
return func(ctx_ref);
|
||||
} else
|
||||
{
|
||||
return call_without_first<Return, Args...>()(func, read_allocator, ctx_ref);
|
||||
return call_without_first<Return, Args...>()(true, func, read_allocator, ctx_ref);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -214,16 +226,24 @@ namespace blt::gp
|
|||
};
|
||||
|
||||
template<typename Lambda>
|
||||
operation_t(Lambda) -> operation_t<Lambda, decltype(&Lambda::operator())>;
|
||||
operation_t(Lambda)
|
||||
->
|
||||
operation_t<Lambda, decltype(&Lambda::operator())>;
|
||||
|
||||
template<typename Return, typename... Args>
|
||||
operation_t(Return(*)(Args...)) -> operation_t<Return(*)(Args...), Return(Args...)>;
|
||||
operation_t(Return(*)
|
||||
(Args...)) ->
|
||||
operation_t<Return(*)(Args...), Return(Args...)>;
|
||||
|
||||
template<typename Lambda>
|
||||
operation_t(Lambda, std::optional<std::string_view>) -> operation_t<Lambda, decltype(&Lambda::operator())>;
|
||||
operation_t(Lambda, std::optional<std::string_view>
|
||||
) ->
|
||||
operation_t<Lambda, decltype(&Lambda::operator())>;
|
||||
|
||||
template<typename Return, typename... Args>
|
||||
operation_t(Return(*)(Args...), std::optional<std::string_view>) -> operation_t<Return(*)(Args...), Return(Args...)>;
|
||||
operation_t(Return(*)
|
||||
(Args...), std::optional<std::string_view>) ->
|
||||
operation_t<Return(*)(Args...), Return(Args...)>;
|
||||
}
|
||||
|
||||
#endif //BLT_GP_OPERATIONS_H
|
||||
|
|
|
@ -205,14 +205,15 @@ namespace blt::gp
|
|||
* @param value universal reference to the object to push
|
||||
*/
|
||||
template<typename T>
|
||||
void push(T&& value)
|
||||
void push(const T& value)
|
||||
{
|
||||
using NO_REF_T = std::remove_cv_t<std::remove_reference_t<T>>;
|
||||
static_assert(std::is_trivially_copyable_v<NO_REF_T> && "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<NO_REF_T>();
|
||||
head->metadata.offset = static_cast<blt::u8*>(ptr) + aligned_size<NO_REF_T>();
|
||||
new(ptr) NO_REF_T(std::forward<T>(value));
|
||||
//new(ptr) NO_REF_T(std::forward<T>(value));
|
||||
std::memcpy(ptr, &value, sizeof(NO_REF_T));
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
|
@ -233,7 +234,7 @@ namespace blt::gp
|
|||
NO_REF_T t = *reinterpret_cast<NO_REF_T*>(head->metadata.offset - TYPE_SIZE);
|
||||
// call destructor
|
||||
if constexpr (detail::has_func_drop_v<T>)
|
||||
reinterpret_cast<NO_REF_T*>(head->metadata.offset - TYPE_SIZE)->~NO_REF_T();
|
||||
call_drop<NO_REF_T>(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<typename... Args>
|
||||
void call_destructors()
|
||||
{
|
||||
blt::size_t offset = 0;
|
||||
|
||||
((call_drop<Args>(offset), offset += stack_allocator::aligned_size<NO_REF_T<Args>>()), ...);
|
||||
blt::size_t offset = (stack_allocator::aligned_size<NO_REF_T<Args>>() + ...) -
|
||||
stack_allocator::aligned_size<NO_REF_T<typename blt::meta::arg_helper<Args...>::First>>();
|
||||
((call_drop<Args>(offset), offset -= stack_allocator::aligned_size<NO_REF_T<Args>>()), ...);
|
||||
}
|
||||
|
||||
[[nodiscard]] bool empty() const noexcept
|
||||
|
|
2
lib/blt
2
lib/blt
|
@ -1 +1 @@
|
|||
Subproject commit 4327b34c841fd6d8fb6509757d5cab2717d35457
|
||||
Subproject commit 92300bc6a29927f5354d516df76ad40be7fca868
|
|
@ -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<move_float>);
|
||||
|
@ -90,7 +98,7 @@ static_assert(std::is_trivially_copyable_v<move_float>);
|
|||
|
||||
struct context
|
||||
{
|
||||
move_float x, y;
|
||||
float x, y;
|
||||
};
|
||||
|
||||
std::array<context, 200> 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<move_float>(&fitness_case));
|
||||
auto diff = std::abs(fitness_case.y - *current_tree.get_evaluation_value<move_float>(&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");
|
||||
|
|
Loading…
Reference in New Issue