|
|
|
|
#include "internal_structs.hpp"
|
|
|
|
|
|
|
|
|
|
namespace internal
|
|
|
|
|
{
|
|
|
|
|
// ======================================================================
|
|
|
|
|
// Runtime Node
|
|
|
|
|
// ======================================================================
|
|
|
|
|
runtime_node_t::~runtime_node_t() noexcept
|
|
|
|
|
{
|
|
|
|
|
if (parent) {
|
|
|
|
|
if (parent->left_child.raw() == this) {
|
|
|
|
|
parent->left_child.clear();
|
|
|
|
|
} else if (parent->right_child.raw() == this) {
|
|
|
|
|
parent->right_child.clear();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (left_child) { left_child->parent.clear(); }
|
|
|
|
|
if (right_child) { right_child->parent.clear(); }
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool runtime_node_t::is_operation_node() const noexcept { return node_data.get_ptr() == nullptr; }
|
|
|
|
|
|
|
|
|
|
bool runtime_node_t::is_primitive_node() const noexcept { return !is_operation_node(); }
|
|
|
|
|
|
|
|
|
|
bool runtime_node_t::is_parent_null() const noexcept { return parent; }
|
|
|
|
|
|
|
|
|
|
bool runtime_node_t::is_left_child_null() const noexcept { return left_child; }
|
|
|
|
|
|
|
|
|
|
bool runtime_node_t::is_right_child_null() const noexcept { return right_child; }
|
|
|
|
|
|
|
|
|
|
bool runtime_node_t::set_parent(pointer_wrapper<runtime_node_t> _parent) noexcept
|
|
|
|
|
{
|
|
|
|
|
if (_parent) return false;
|
|
|
|
|
|
|
|
|
|
if (_parent->is_left_child_null())
|
|
|
|
|
_parent->left_child = make_pointer_wrapper(this);
|
|
|
|
|
else if (_parent->is_right_child_null())
|
|
|
|
|
_parent->right_child = make_pointer_wrapper(this);
|
|
|
|
|
else
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool runtime_node_t::remove_parent()
|
|
|
|
|
{
|
|
|
|
|
if (parent) return false;
|
|
|
|
|
|
|
|
|
|
if (parent->left_child.raw() == this) {
|
|
|
|
|
parent->left_child.clear();
|
|
|
|
|
} else if (parent->right_child.raw() == this) {
|
|
|
|
|
parent->right_child.clear();
|
|
|
|
|
} else {
|
|
|
|
|
throw std::logic_error("Illegal parent which does not have a child pointing to this.");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
parent.clear();
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool runtime_node_t::set_left_child(pointer_wrapper<runtime_node_t> child) noexcept
|
|
|
|
|
{
|
|
|
|
|
if (child) return false;
|
|
|
|
|
|
|
|
|
|
if (!is_left_child_null() || !child->is_parent_null()) return false;
|
|
|
|
|
|
|
|
|
|
left_child = child;
|
|
|
|
|
child->parent = make_pointer_wrapper(this);
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool runtime_node_t::set_right_child(pointer_wrapper<runtime_node_t> child) noexcept
|
|
|
|
|
{
|
|
|
|
|
if (child) return false;
|
|
|
|
|
|
|
|
|
|
if (!is_right_child_null() || !child->is_parent_null()) return false;
|
|
|
|
|
|
|
|
|
|
right_child = child;
|
|
|
|
|
child->parent = make_pointer_wrapper(this);
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool runtime_node_t::add_child(pointer_wrapper<runtime_node_t> child) noexcept
|
|
|
|
|
{
|
|
|
|
|
if (child) return false;
|
|
|
|
|
|
|
|
|
|
if (!child->is_parent_null()) return false;
|
|
|
|
|
|
|
|
|
|
if (is_left_child_null())
|
|
|
|
|
left_child = child;
|
|
|
|
|
else if (is_right_child_null())
|
|
|
|
|
right_child = child;
|
|
|
|
|
else
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
child->parent = make_pointer_wrapper(this);
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool runtime_node_t::remove_child(pointer_wrapper<runtime_node_t> child)
|
|
|
|
|
{
|
|
|
|
|
if (child) return false;
|
|
|
|
|
|
|
|
|
|
if (left_child == child) {
|
|
|
|
|
left_child.clear();
|
|
|
|
|
} else if (right_child == child) {
|
|
|
|
|
right_child.clear();
|
|
|
|
|
} else {
|
|
|
|
|
throw std::logic_error("Illegal child which does not have a parent pointing to this.");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
child->parent.clear();
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ======================================================================
|
|
|
|
|
// Node
|
|
|
|
|
// ======================================================================
|
|
|
|
|
node_t::node_t() noexcept
|
|
|
|
|
: operation(3),
|
|
|
|
|
type(63),
|
|
|
|
|
primitive_index(0x00FFFFFF),
|
|
|
|
|
parent_index(0xFFFFFFFF),
|
|
|
|
|
left_child_index(0xFFFFFFFF),
|
|
|
|
|
right_child_index(0xFFFFFFFF)
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
eNodeOperation node_t::get_operation() const noexcept { return static_cast<eNodeOperation>(operation); }
|
|
|
|
|
|
|
|
|
|
void node_t::set_operation(eNodeOperation op) noexcept { operation = static_cast<uint32_t>(op); }
|
|
|
|
|
|
|
|
|
|
bool node_t::is_primitive_node() const noexcept { return type != 63; }
|
|
|
|
|
|
|
|
|
|
bool node_t::is_operation_node() const noexcept { return type == 63; }
|
|
|
|
|
|
|
|
|
|
bool node_t::is_parent_null() const noexcept { return parent_index == 0xFFFFFFFF; }
|
|
|
|
|
|
|
|
|
|
bool node_t::is_left_child_null() const noexcept { return left_child_index == 0xFFFFFFFF; }
|
|
|
|
|
|
|
|
|
|
bool node_t::is_right_child_null() const noexcept { return right_child_index == 0xFFFFFFFF; }
|
|
|
|
|
} // namespace internal
|