diff --git a/CMakeLists.txt b/CMakeLists.txt index 0270901..e6ba3e8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,5 +1,5 @@ cmake_minimum_required(VERSION 3.25) -project(lilfbtf5 VERSION 0.1.36) +project(lilfbtf5 VERSION 0.1.37) option(ENABLE_ADDRSAN "Enable the address sanitizer" OFF) option(ENABLE_UBSAN "Enable the ub sanitizer" OFF) diff --git a/include/lilfbtf/fwddecl.h b/include/lilfbtf/fwddecl.h index a23600d..f9cccc7 100644 --- a/include/lilfbtf/fwddecl.h +++ b/include/lilfbtf/fwddecl.h @@ -20,23 +20,13 @@ #define LILFBTF5_FWDDECL_H #include +#include #include #include "blt/std/ranges.h" #include namespace fb { - namespace detail - { - class node_t; - - struct fitness_results - { - double fitness; - blt::size_t hits; - }; - } - class func_t; class tree_t; @@ -47,11 +37,32 @@ namespace fb class gp_population_t; + namespace detail + { + class node_t; + + struct fitness_results + { + double fitness; + blt::size_t hits; + }; + + struct func_t_arguments + { + // reference to ourselves + func_t& self; + // list of arguments to use + blt::span arguments; + // any extra information that the tree evaluator wants to provide to us, in the case of an image GP this is going to be the X and Y coords + blt::unsafe::buffer_any_t extra_args; + }; + } + // no way we are going to have more than 4billion types or functions. using type_id = blt::u32; using function_id = blt::u32; using arg_c_t = blt::size_t; - using func_t_call_t = std::function)>; + using func_t_call_t = std::function; using func_t_init_t = std::function; using fitness_eval_func_t = std::function; using function_name = const std::string&; diff --git a/tests/src/main.cpp b/tests/src/main.cpp index 447b894..563dd0e 100644 --- a/tests/src/main.cpp +++ b/tests/src/main.cpp @@ -18,61 +18,98 @@ struct data char c; }; -const fb::func_t_call_t add_f = [](fb::func_t& us, blt::span args) { - us.setValue(args[0]->value().any_cast() + args[1]->value().any_cast()); +struct pixel +{ + blt::size_t x, y; }; -const fb::func_t_call_t sub_f = [](fb::func_t& us, blt::span args) { - us.setValue(args[0]->value().any_cast() - args[1]->value().any_cast()); + +const blt::size_t image_width = 128, image_height = 128; + +struct pixelator_t +{ + private: + blt::size_t width, height; + blt::size_t x = 0, y = 0; + public: + pixelator_t(blt::size_t width, blt::size_t height): width(width), height(height) + {} + + pixel next() + { + if (x > width) + { + x = 0; + y++; + } + return {x++, y}; + } + + [[nodiscard]] inline blt::size_t curX() const + { + return x; + } + + [[nodiscard]] inline blt::size_t curY() const + { + return y; + } +} pixelator{image_width, image_height}; + +const fb::func_t_call_t add_f = [](const fb::detail::func_t_arguments& args) { + args.self.setValue(args.arguments[0]->value().any_cast() + args.arguments[1]->value().any_cast()); }; -const fb::func_t_call_t mul_f = [](fb::func_t& us, blt::span args) { - us.setValue(args[0]->value().any_cast() * args[1]->value().any_cast()); +const fb::func_t_call_t sub_f = [](const fb::detail::func_t_arguments& args) { + args.self.setValue(args.arguments[0]->value().any_cast() - args.arguments[1]->value().any_cast()); }; -const fb::func_t_call_t div_f = [](fb::func_t& us, blt::span args) { - auto dim = args[1]->value().any_cast(); +const fb::func_t_call_t mul_f = [](const fb::detail::func_t_arguments& args) { + args.self.setValue(args.arguments[0]->value().any_cast() * args.arguments[1]->value().any_cast()); +}; +const fb::func_t_call_t div_f = [](const fb::detail::func_t_arguments& args) { + auto dim = args.arguments[1]->value().any_cast(); if (dim == 0) - us.setValue(0); + args.self.setValue(0); else - us.setValue(args[0]->value().any_cast() + dim); + args.self.setValue(args.arguments[0]->value().any_cast() + dim); }; -const fb::func_t_call_t empty_f = [](fb::func_t&, blt::span) {}; -const fb::func_t_init_t value_init_f = [](fb::func_t& us){ - us.setValue(fb::random_value()); +const fb::func_t_call_t empty_f = [](const fb::detail::func_t_arguments&) {}; +const fb::func_t_init_t value_init_f = [](fb::func_t& self) { + self.setValue(fb::random_value()); }; -const fb::func_t_init_t bool_init_f = [](fb::func_t& us){ - us.setValue(fb::choice()); +const fb::func_t_init_t bool_init_f = [](fb::func_t& self) { + self.setValue(fb::choice()); }; -const fb::func_t_call_t if_f = [](fb::func_t& us, blt::span args) { - if (args[0]->value().any_cast()) - us.setValue(args[1]->value().any_cast()); +const fb::func_t_call_t if_f = [](const fb::detail::func_t_arguments& args) { + if (args.arguments[0]->value().any_cast()) + args.self.setValue(args.arguments[1]->value().any_cast()); else - us.setValue(args[2]->value().any_cast()); + args.self.setValue(args.arguments[2]->value().any_cast()); }; -const fb::func_t_call_t equals_b_f = [](fb::func_t& us, blt::span args) { - us.setValue(args[0]->value().any_cast() == args[1]->value().any_cast()); +const fb::func_t_call_t equals_b_f = [](const fb::detail::func_t_arguments& args) { + args.self.setValue(args.arguments[0]->value().any_cast() == args.arguments[1]->value().any_cast()); }; -const fb::func_t_call_t equals_n_f = [](fb::func_t& us, blt::span args) { - us.setValue(args[0]->value().any_cast() == args[1]->value().any_cast()); +const fb::func_t_call_t equals_n_f = [](const fb::detail::func_t_arguments& args) { + args.self.setValue(args.arguments[0]->value().any_cast() == args.arguments[1]->value().any_cast()); }; -const fb::func_t_call_t less_f = [](fb::func_t& us, blt::span args) { - us.setValue(args[0]->value().any_cast() < args[1]->value().any_cast()); +const fb::func_t_call_t less_f = [](const fb::detail::func_t_arguments& args) { + args.self.setValue(args.arguments[0]->value().any_cast() < args.arguments[1]->value().any_cast()); }; -const fb::func_t_call_t greater_f = [](fb::func_t& us, blt::span args) { - us.setValue(args[0]->value().any_cast() > args[1]->value().any_cast()); +const fb::func_t_call_t greater_f = [](const fb::detail::func_t_arguments& args) { + args.self.setValue(args.arguments[0]->value().any_cast() > args.arguments[1]->value().any_cast()); }; -const fb::func_t_call_t not_f = [](fb::func_t& us, blt::span args) { us.setValue(!args[0]->value().any_cast()); }; -const fb::func_t_call_t and_b_f = [](fb::func_t& us, blt::span args) { - us.setValue(args[0]->value().any_cast() && args[1]->value().any_cast()); +const fb::func_t_call_t not_f = [](const fb::detail::func_t_arguments& args) { args.self.setValue(!args.arguments[0]->value().any_cast()); }; +const fb::func_t_call_t and_b_f = [](const fb::detail::func_t_arguments& args) { + args.self.setValue(args.arguments[0]->value().any_cast() && args.arguments[1]->value().any_cast()); }; -const fb::func_t_call_t or_b_f = [](fb::func_t& us, blt::span args) { - us.setValue(args[0]->value().any_cast() || args[1]->value().any_cast()); +const fb::func_t_call_t or_b_f = [](const fb::detail::func_t_arguments& args) { + args.self.setValue(args.arguments[0]->value().any_cast() || args.arguments[1]->value().any_cast()); }; -const fb::func_t_call_t and_n_f = [](fb::func_t& us, blt::span args) { - us.setValue(args[0]->value().any_cast() & args[1]->value().any_cast()); +const fb::func_t_call_t and_n_f = [](const fb::detail::func_t_arguments& args) { + args.self.setValue(args.arguments[0]->value().any_cast() & args.arguments[1]->value().any_cast()); }; -const fb::func_t_call_t or_n_f = [](fb::func_t& us, blt::span args) { - us.setValue(args[0]->value().any_cast() | args[1]->value().any_cast()); +const fb::func_t_call_t or_n_f = [](const fb::detail::func_t_arguments& args) { + args.self.setValue(args.arguments[0]->value().any_cast() | args.arguments[1]->value().any_cast()); }; int main(int argc, const char** argv)