start adding functions for ref
parent
32a83e725c
commit
db0c7da8e7
|
@ -27,7 +27,7 @@ macro(compile_options target_name)
|
|||
sanitizers(${target_name})
|
||||
endmacro()
|
||||
|
||||
project(blt-gp VERSION 0.3.8)
|
||||
project(blt-gp VERSION 0.3.9)
|
||||
|
||||
include(CTest)
|
||||
|
||||
|
@ -107,17 +107,17 @@ endif ()
|
|||
|
||||
if (${BUILD_GP_TESTS})
|
||||
|
||||
blt_add_project(blt-stack tests/old/stack_tests.cpp test)
|
||||
blt_add_project(blt-eval tests/old/evaluation_tests.cpp test)
|
||||
blt_add_project(blt-order tests/old/order_tests.cpp test)
|
||||
# blt_add_project(blt-stack tests/old/stack_tests.cpp test)
|
||||
# blt_add_project(blt-eval tests/old/evaluation_tests.cpp test)
|
||||
# blt_add_project(blt-order tests/old/order_tests.cpp test)
|
||||
#blt_add_project(blt-destructor tests/destructor_test.cpp test)
|
||||
blt_add_project(blt-gp1 tests/old/gp_test_1.cpp test)
|
||||
blt_add_project(blt-gp2 tests/old/gp_test_2.cpp test)
|
||||
blt_add_project(blt-gp3 tests/old/gp_test_3.cpp test)
|
||||
blt_add_project(blt-gp4 tests/old/gp_test_4.cpp test)
|
||||
blt_add_project(blt-gp5 tests/old/gp_test_5.cpp test)
|
||||
blt_add_project(blt-gp6 tests/old/gp_test_6.cpp test)
|
||||
blt_add_project(blt-gp7 tests/old/gp_test_7.cpp test)
|
||||
# blt_add_project(blt-gp1 tests/old/gp_test_1.cpp test)
|
||||
# blt_add_project(blt-gp2 tests/old/gp_test_2.cpp test)
|
||||
# blt_add_project(blt-gp3 tests/old/gp_test_3.cpp test)
|
||||
# blt_add_project(blt-gp4 tests/old/gp_test_4.cpp test)
|
||||
# blt_add_project(blt-gp5 tests/old/gp_test_5.cpp test)
|
||||
# blt_add_project(blt-gp6 tests/old/gp_test_6.cpp test)
|
||||
# blt_add_project(blt-gp7 tests/old/gp_test_7.cpp test)
|
||||
|
||||
blt_add_project(blt-symbolic-regression tests/symbolic_regression_test.cpp test)
|
||||
|
||||
|
|
|
@ -62,7 +62,7 @@ namespace blt::gp
|
|||
}
|
||||
|
||||
template<typename context = void, typename... NoCtxArgs>
|
||||
void call_destructors_without_first(stack_allocator& read_allocator)
|
||||
void call_destructors_without_first(stack_allocator& read_allocator) const
|
||||
{
|
||||
if constexpr (sizeof...(NoCtxArgs) > 0)
|
||||
{
|
||||
|
@ -71,9 +71,9 @@ namespace blt::gp
|
|||
}
|
||||
|
||||
template<typename Func, typename... ExtraArgs>
|
||||
Return operator()(bool has_context, Func&& func, stack_allocator& read_allocator, ExtraArgs&& ... args)
|
||||
Return operator()(const bool has_context, Func&& func, stack_allocator& read_allocator, ExtraArgs&& ... args)
|
||||
{
|
||||
constexpr auto seq = std::make_integer_sequence<blt::u64, sizeof...(Args)>();
|
||||
constexpr auto seq = std::make_integer_sequence<u64, sizeof...(Args)>();
|
||||
#if BLT_DEBUG_LEVEL > 0
|
||||
try
|
||||
{
|
||||
|
@ -173,16 +173,21 @@ namespace blt::gp
|
|||
return func;
|
||||
}
|
||||
|
||||
inline auto set_ephemeral()
|
||||
auto set_ephemeral()
|
||||
{
|
||||
is_ephemeral_ = true;
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline bool is_ephemeral()
|
||||
bool is_ephemeral() const
|
||||
{
|
||||
return is_ephemeral_;
|
||||
}
|
||||
|
||||
bool return_has_drop() const
|
||||
{
|
||||
return detail::has_func_drop_v<Return>;
|
||||
}
|
||||
|
||||
operator_id id = -1;
|
||||
private:
|
||||
|
|
|
@ -57,6 +57,29 @@
|
|||
|
||||
namespace blt::gp
|
||||
{
|
||||
struct operator_special_flags
|
||||
{
|
||||
explicit operator_special_flags(const bool is_ephemeral = false, const bool has_drop = false): m_ephemeral(is_ephemeral), m_drop(has_drop)
|
||||
{
|
||||
}
|
||||
|
||||
[[nodiscard]] bool is_ephemeral() const
|
||||
{
|
||||
return m_ephemeral;
|
||||
}
|
||||
|
||||
[[nodiscard]] bool has_drop() const
|
||||
{
|
||||
return m_drop;
|
||||
}
|
||||
|
||||
private:
|
||||
bool m_ephemeral : 1;
|
||||
bool m_drop : 1;
|
||||
};
|
||||
|
||||
static_assert(sizeof(operator_special_flags) == 1, "Size of operator flags struct is expected to be 1 byte!");
|
||||
|
||||
struct argc_t
|
||||
{
|
||||
blt::u32 argc = 0;
|
||||
|
@ -90,11 +113,12 @@ namespace blt::gp
|
|||
struct program_operator_storage_t
|
||||
{
|
||||
// indexed from return TYPE ID, returns index of operator
|
||||
blt::expanding_buffer<tracked_vector<operator_id>> terminals;
|
||||
blt::expanding_buffer<tracked_vector<operator_id>> non_terminals;
|
||||
blt::expanding_buffer<tracked_vector<std::pair<operator_id, blt::size_t>>> operators_ordered_terminals;
|
||||
// indexed from OPERATOR ID (operator number)
|
||||
blt::hashset_t<operator_id> ephemeral_leaf_operators;
|
||||
expanding_buffer<tracked_vector<operator_id>> terminals;
|
||||
expanding_buffer<tracked_vector<operator_id>> non_terminals;
|
||||
expanding_buffer<tracked_vector<std::pair<operator_id, size_t>>> operators_ordered_terminals;
|
||||
// indexed from OPERATOR ID (operator number) to a bitfield of flags
|
||||
hashmap_t<operator_id, operator_special_flags> operator_flags;
|
||||
|
||||
tracked_vector<operator_info_t> operators;
|
||||
tracked_vector<operator_metadata_t> operator_metadata;
|
||||
tracked_vector<detail::print_func_t> print_funcs;
|
||||
|
@ -253,7 +277,7 @@ namespace blt::gp
|
|||
out << "[Printing Value on '" << (op.get_name() ? *op.get_name() : "") << "' Not Supported!]";
|
||||
}
|
||||
});
|
||||
storage.destroy_funcs.push_back([](detail::destroy_t type, stack_allocator& alloc)
|
||||
storage.destroy_funcs.push_back([](const detail::destroy_t type, stack_allocator& alloc)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
|
@ -269,8 +293,7 @@ namespace blt::gp
|
|||
}
|
||||
});
|
||||
storage.names.push_back(op.get_name());
|
||||
if (op.is_ephemeral())
|
||||
storage.ephemeral_leaf_operators.insert(operator_id);
|
||||
storage.operator_flags.emplace(operator_id, operator_special_flags{op.is_ephemeral(), op.return_has_drop()});
|
||||
return meta;
|
||||
}
|
||||
|
||||
|
@ -282,8 +305,8 @@ namespace blt::gp
|
|||
types.push_back(storage.system.get_type<T>().id());
|
||||
}
|
||||
}
|
||||
private:
|
||||
|
||||
private:
|
||||
program_operator_storage_t storage;
|
||||
};
|
||||
|
||||
|
@ -691,9 +714,14 @@ namespace blt::gp
|
|||
return current_stats;
|
||||
}
|
||||
|
||||
[[nodiscard]] bool is_operator_ephemeral(operator_id id)
|
||||
[[nodiscard]] bool is_operator_ephemeral(const operator_id id) const
|
||||
{
|
||||
return storage.ephemeral_leaf_operators.contains(static_cast<blt::size_t>(id));
|
||||
return storage.operator_flags.find(static_cast<size_t>(id))->second.is_ephemeral();
|
||||
}
|
||||
|
||||
[[nodiscard]] bool operator_has_drop(const operator_id id) const
|
||||
{
|
||||
return storage.operator_flags.find(static_cast<size_t>(id))->second.has_drop();
|
||||
}
|
||||
|
||||
void set_operations(program_operator_storage_t op)
|
||||
|
|
|
@ -84,7 +84,10 @@ namespace blt::gp
|
|||
public:
|
||||
explicit tree_t(gp_program& program);
|
||||
|
||||
tree_t(const tree_t& copy) = default;
|
||||
tree_t(const tree_t& copy): func(copy.func)
|
||||
{
|
||||
copy_fast(copy);
|
||||
}
|
||||
|
||||
tree_t& operator=(const tree_t& copy)
|
||||
{
|
||||
|
@ -97,14 +100,13 @@ namespace blt::gp
|
|||
/**
|
||||
* This function copies the data from the provided tree, will attempt to reserve and copy in one step.
|
||||
* will avoid reallocation if enough space is already present.
|
||||
*
|
||||
* This function is meant to copy into and replaces data inside the tree.
|
||||
*/
|
||||
void copy_fast(const tree_t& copy)
|
||||
{
|
||||
if (this == ©)
|
||||
return;
|
||||
values.reserve(copy.values.stored());
|
||||
values.reset();
|
||||
values.insert(copy.values);
|
||||
|
||||
operations.reserve(copy.operations.size());
|
||||
|
||||
|
@ -115,6 +117,7 @@ namespace blt::gp
|
|||
{
|
||||
if (op_it->has_drop())
|
||||
{
|
||||
|
||||
}
|
||||
if (copy_it == copy.operations.end())
|
||||
break;
|
||||
|
@ -134,6 +137,10 @@ namespace blt::gp
|
|||
operations.erase(op_it_cpy, operations.end());
|
||||
for (; copy_it != copy.operations.end(); ++copy_it)
|
||||
operations.emplace_back(*copy_it);
|
||||
|
||||
values.reserve(copy.values.stored());
|
||||
values.reset();
|
||||
values.insert(copy.values);
|
||||
}
|
||||
|
||||
tree_t(tree_t&& move) = default;
|
||||
|
|
|
@ -30,108 +30,116 @@
|
|||
|
||||
namespace blt::gp
|
||||
{
|
||||
struct operator_id : integer_type<blt::u64>
|
||||
struct operator_id : integer_type<u64>
|
||||
{
|
||||
using integer_type<blt::u64>::integer_type;
|
||||
using integer_type::integer_type;
|
||||
};
|
||||
|
||||
struct type_id : integer_type<blt::u64>
|
||||
|
||||
struct type_id : integer_type<u64>
|
||||
{
|
||||
using integer_type<blt::u64>::integer_type;
|
||||
using integer_type::integer_type;
|
||||
};
|
||||
|
||||
|
||||
class type
|
||||
{
|
||||
public:
|
||||
type() = default;
|
||||
|
||||
template<typename T>
|
||||
static type make_type(const type_id id)
|
||||
{
|
||||
return type(stack_allocator::aligned_size<T>(), id, blt::type_string<T>());
|
||||
}
|
||||
|
||||
[[nodiscard]] inline blt::size_t size() const
|
||||
{
|
||||
return size_;
|
||||
}
|
||||
|
||||
[[nodiscard]] inline type_id id() const
|
||||
{
|
||||
return id_;
|
||||
}
|
||||
|
||||
[[nodiscard]] inline std::string_view name() const
|
||||
{
|
||||
return name_;
|
||||
}
|
||||
|
||||
private:
|
||||
type(size_t size, type_id id, std::string_view name): size_(size), id_(id), name_(name)
|
||||
{}
|
||||
|
||||
blt::size_t size_{};
|
||||
type_id id_{};
|
||||
std::string name_{};
|
||||
public:
|
||||
type() = default;
|
||||
|
||||
template <typename T>
|
||||
static type make_type(const type_id id)
|
||||
{
|
||||
return type(stack_allocator::aligned_size<T>(), id, blt::type_string<T>(), detail::has_func_drop<T>::value);
|
||||
}
|
||||
|
||||
[[nodiscard]] size_t size() const
|
||||
{
|
||||
return size_;
|
||||
}
|
||||
|
||||
[[nodiscard]] type_id id() const
|
||||
{
|
||||
return id_;
|
||||
}
|
||||
|
||||
[[nodiscard]] std::string_view name() const
|
||||
{
|
||||
return name_;
|
||||
}
|
||||
|
||||
[[nodiscard]] bool has_drop() const
|
||||
{
|
||||
return has_drop_;
|
||||
}
|
||||
private:
|
||||
type(const size_t size, const type_id id, const std::string_view name, const bool has_drop): size_(size), id_(id), name_(name),
|
||||
has_drop_(has_drop)
|
||||
{
|
||||
}
|
||||
|
||||
size_t size_{};
|
||||
type_id id_{};
|
||||
std::string name_{};
|
||||
bool has_drop_ = false;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Is a provider for the set of types possible in a GP program
|
||||
* also provides a set of functions for converting between C++ types and BLT GP types
|
||||
*/
|
||||
class type_provider
|
||||
{
|
||||
public:
|
||||
type_provider() = default;
|
||||
|
||||
template<typename T>
|
||||
inline void register_type()
|
||||
{
|
||||
if (has_type<T>())
|
||||
return;
|
||||
auto t = type::make_type<T>(types.size());
|
||||
types.insert({blt::type_string_raw<T>(), t});
|
||||
types_from_id[t.id()] = t;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline type get_type()
|
||||
{
|
||||
return types[blt::type_string_raw<T>()];
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline bool has_type(){
|
||||
return types.find(blt::type_string_raw<T>()) != types.end();
|
||||
}
|
||||
|
||||
inline type get_type(type_id id)
|
||||
{
|
||||
return types_from_id[id];
|
||||
}
|
||||
|
||||
/**
|
||||
* This function is slow btw
|
||||
* @param engine
|
||||
* @return
|
||||
*/
|
||||
inline type select_type(std::mt19937_64& engine)
|
||||
{
|
||||
std::uniform_int_distribution dist(0ul, types.size() - 1);
|
||||
auto offset = dist(engine);
|
||||
auto itr = types.begin();
|
||||
for ([[maybe_unused]] auto _ : blt::range(0ul, offset))
|
||||
itr = itr++;
|
||||
return itr->second;
|
||||
}
|
||||
|
||||
private:
|
||||
blt::hashmap_t<std::string, type> types;
|
||||
blt::expanding_buffer<type> types_from_id;
|
||||
public:
|
||||
type_provider() = default;
|
||||
|
||||
template <typename T>
|
||||
void register_type()
|
||||
{
|
||||
if (has_type<T>())
|
||||
return;
|
||||
auto t = type::make_type<T>(types.size());
|
||||
types.insert({blt::type_string_raw<T>(), t});
|
||||
types_from_id[t.id()] = t;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
type get_type()
|
||||
{
|
||||
return types[blt::type_string_raw<T>()];
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
bool has_type()
|
||||
{
|
||||
return types.find(blt::type_string_raw<T>()) != types.end();
|
||||
}
|
||||
|
||||
type get_type(type_id id)
|
||||
{
|
||||
return types_from_id[id];
|
||||
}
|
||||
|
||||
/**
|
||||
* This function is slow btw
|
||||
* @param engine
|
||||
* @return
|
||||
*/
|
||||
type select_type(std::mt19937_64& engine)
|
||||
{
|
||||
std::uniform_int_distribution dist(0ul, types.size() - 1);
|
||||
auto offset = dist(engine);
|
||||
auto itr = types.begin();
|
||||
for ([[maybe_unused]] auto _ : blt::range(0ul, offset))
|
||||
itr = itr++;
|
||||
return itr->second;
|
||||
}
|
||||
|
||||
private:
|
||||
hashmap_t<std::string, type> types;
|
||||
expanding_buffer<type> types_from_id;
|
||||
};
|
||||
}
|
||||
|
||||
template<>
|
||||
template <>
|
||||
struct std::hash<blt::gp::operator_id>
|
||||
{
|
||||
std::size_t operator()(const blt::gp::operator_id& s) const noexcept
|
||||
|
@ -140,7 +148,7 @@ struct std::hash<blt::gp::operator_id>
|
|||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
template <>
|
||||
struct std::hash<blt::gp::type_id>
|
||||
{
|
||||
std::size_t operator()(const blt::gp::type_id& s) const noexcept
|
||||
|
|
|
@ -308,6 +308,13 @@ namespace blt::gp
|
|||
auto* f = &program.get_eval_func();
|
||||
if (f != func)
|
||||
func = f;
|
||||
for (const auto& op : operations)
|
||||
{
|
||||
if (op.has_drop())
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
operations.clear();
|
||||
values.reset();
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue