Skip to content

Instantly share code, notes, and snippets.

@TimToady
Created February 15, 2013 21:22
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save TimToady/4963642 to your computer and use it in GitHub Desktop.
Save TimToady/4963642 to your computer and use it in GitHub Desktop.
role DLL_Element[::T] {
has ::?CLASS $.prev is rw;
has ::?CLASS $.next is rw;
has T $.payload handles *;
method pre-insert(T $payload) {
die "Can't insert before beginning" unless $!prev;
my $elem = ::?CLASS.new(:$payload);
$!prev.next = $elem;
$elem.prev = $!prev;
$elem.next = self;
$!prev = $elem;
$elem;
}
method post-insert(T $payload) {
die "Can't insert after end" unless $!next;
my $elem = ::?CLASS.new(:$payload);
$!next.prev = $elem;
$elem.next = $!next;
$elem.prev = self;
$!next = $elem;
$elem;
}
method delete {
die "Can't delete a sentinel" unless $!prev and $!next;
$!next.prev = $!prev;
$!prev.next = $!next; # conveniently returns next element
}
method sentinels {
my $first = ::?CLASS.new();
my $last = ::?CLASS.new();
$first.next = $last;
$last.prev = $first;
:$first,:$last;
}
}
role DLL[::T] {
my class DLLE does DLL_Element[T] {}
has DLLE $.first;
has DLLE $.last;
has $.elemtype = DLLE;
method new { self.bless(*, |DLLE.sentinels) }
method list {
gather loop (my $elem = $!first.next;
$elem.next;
$elem = $elem.next)
{
take $elem
}
}
}
class DLL_Int does DLL[Int] {}
my $list = DLL_Int.new;
$list.first.post-insert(1);
$list.last.pre-insert(42);
for $list.list { .say }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment