From Code to Community: Sponsoring The Perl and Raku Conference 2025 Learn more

class TestCase::Util::Node : public {
use Cloner;
use Array;
# Fields
has parent_node : public TestCase::Util::Node;
has next_sibling : public TestCase::Util::Node;
has previous_sibling : public TestCase::Util::Node;
has first_child : public TestCase::Util::Node;
has last_child : public TestCase::Util::Node;
# Private Class Methods
private static method copy_object_with_proto : object[] ($array : object[], $proto : object[], $cloner : Cloner = undef, $offset : int = 0, $length : int = -1) {
unless ($array) {
die "The array \$array must be defined.";
}
unless ($offset >= 0) {
die "The offset \$offset must be greater than or equal to 0.";
}
my $array_length = @$array;
if ($length < 0) {
$length = $array_length - $offset;
}
unless ($offset + $length <= $array_length) {
die "\$offset + \$length must be less than or equal to the length of \$array.";
}
unless ($proto) {
$proto = $array;
}
my $new_array = Array->new_proto($proto, $length);
if ($cloner) {
for (my $i = 0; $i < $length; $i++) {
$new_array->[$i] = $cloner->($array->[$offset + $i]);
}
}
else {
Array->memcpy_object_address($new_array, 0, $array, $offset, $length);
}
return $new_array;
}
private static method copy_object_address_with_proto : object[] ($array : object[], $proto : object[], $offset : int = 0, $length : int = -1) {
return &copy_object_with_proto($array, $proto, undef, $offset, $length);
}
static method new : TestCase::Util::Node ($child_nodes : TestCase::Util::Node[] = undef) {
my $self = new TestCase::Util::Node;
$self->init($child_nodes);
return $self;
}
protected method init : void ($child_nodes : TestCase::Util::Node[] = undef) {
if ($child_nodes) {
unless ($child_nodes is_type TestCase::Util::Node[]) {
$child_nodes = (TestCase::Util::Node[])&copy_object_address_with_proto($child_nodes, new TestCase::Util::Node[0]);
}
}
else {
$child_nodes = new TestCase::Util::Node[0];
}
# Tree
if ($child_nodes) {
my $child_nodes_length = @$child_nodes;
if ($child_nodes_length > 0) {
$self->{first_child} = $child_nodes->[0];
$self->{last_child} = $child_nodes->[$child_nodes_length - 1];
for (my $i = 0; $i < $child_nodes_length; $i++) {
my $child_node = $child_nodes->[$i];
if ($i + 1 < $child_nodes_length) {
my $next_sibling_node = $child_nodes->[$i + 1];
$child_node->{next_sibling} = $next_sibling_node;
}
if ($i - 1 >= 0) {
my $previous_sibling_node = $child_nodes->[$i - 1];
$child_node->{previous_sibling} = $previous_sibling_node;
weaken $child_node->{previous_sibling};
}
$child_node->{parent_node} = $self;
weaken $child_node->{parent_node};
}
}
}
}
}