}
sub has_descendent {
- my $self = shift;
- my $child = shift;
- die "Assertion failed: $child" unless eval {$child};
- my $there = 0;
- $self->recurse_down(sub { $there = 1 if $_[0] == $child });
-
- return $there;
-}
-
-sub children {
- my $self = shift;
- my @children;
- my $visitor = $self->{child};
- while ($visitor) {
- push @children, $visitor;
- $visitor = $visitor->{next};
- }
- \@children;
-}
-
-sub set_children {
- my ($self, $children) = @_;
- my $walk = $self->{child} = shift @$children;
- do {
- $walk = $walk->{next} = shift @$children;
- } while ($walk);
-}
-
-# non-recursive version of recurse_down to avoid stack depth warnings
-sub recurse_down {
- my ($self, $callback) = @_;
+ my ($self, $child) = @_;
my %seen;
my @q = ($self);
while (my $cont = shift @q) {
$seen{$cont} = 1;
- $callback->($cont);
+
+ return 1 if $cont == $child;
if (my $next = $cont->{next}) {
if ($seen{$next}) {
}
}
}
+ 0;
+}
+
+sub children {
+ my $self = shift;
+ my @children;
+ my $visitor = $self->{child};
+ while ($visitor) {
+ push @children, $visitor;
+ $visitor = $visitor->{next};
+ }
+ \@children;
+}
+
+sub set_children {
+ my ($self, $children) = @_;
+ my $walk = $self->{child} = shift @$children;
+ do {
+ $walk = $walk->{next} = shift @$children;
+ } while ($walk);
}
sub order_children {