NAME

LinkedList::Single - singly linked list manager.

SYNOPSIS

# generate the list with one value from @_ per node
# in a single pass.

my $listh   = LinkedList::Single->new( @one_datum_per_node );

# generate an empty list.

my $listh   = LinkedList::Single->new;

# each node can have multiple data values.

$listh->push( @multiple_data_in_a_single_node );

# extract the data from the current node.

my @data    = $listh->data;

# save and restore a node position

my $curr    = $listh->node;

# do something and restore the node.

$list->node( $curr );

# note the lack of "pop", it is simply too
# expensive with singly linked lists. for 
# a stack use unsift and shift; for a que
# use push and shift (or seriously consider
# using arrays, which are a helluva lot more
# effective for the purpose).


$list->push( @node_data );

my @node_data   = $list->shift; # array of values
my $node_data   = $list->shift; # arrayref

# these manipulate the head node directly
# and to not modify the current list.

$listh->unshift( @new_head_node_data );

my @data    = $listh->shift;

# sequences of pushes are effecient for adding
# longer lists.

my $wcurve  = LinkedList::Single->new;

while( my $base = substr $dna, 0, 1, '' )
{
    ...

    $wcurve->push( $r, $a, ++$z );
}

# reset to the start-of-list.

$wcurve->head;

# hide extra data in the head node.

$wcurve->set_meta( $z, $species );

# extra data can come back as a list
# or arrayref.

my ( $size )    = $wcurve->get_meta;


# walk down the list examining each item until 
# the tail is reached.
#
# unlike Perl's each there is no internal
# mechanism for re-setting the current node,
# if you don't call head $listh->each returns
# immediatley. 

$listh->head;

while( my @data = $listh->each )
{
    # play with the data
}

# duplicate a list handler, reset it to the 
# start-of-list.

if( $some_test )
{
    # $altlist starts out with the same node 
    # as $listh, call to next does not affect
    # $listh.

    my $altlist = $listh->clone;

    my @data    = $altlist->next->data;

    ...
}


# for those do-it-yourselfers in the crowd:

my $node    = $listh->head_ref;

while( @$node )
{
    # advance the node and extract the data
    # in one step.

    ( $node, @data )    = @$node;

    # process @data...
}

# if you prefer OO...
# $listh->each returns each value in order then
# returns false. one catch: in a list context
# this will return equally false for an empty
# node as the end-of-list.
#
# in a scalar context each returns false for the
# end-of-list and an empty arrayref for a node.

$listh->head;

while( my $data = $listh->each )
{
    # deal with @$data
}

# if you *know* the nodes are never empty

while( my @data = $listh->each )
{
    # deal with @data
}

# note that $listh->next->data may be empty
# even if there are mode nodes due to a node
# having no data.

$listh->add( @new_data );

my @old_data    = $listh->cut;

# $listh->head->cut is slower version of shift.

DESCRIPTION

Singly-linked list managed via ref-to-scalar.

Nodes on the list are ref-to-next followed by arbitrary -- and possibly empty -- user data:

my $node    = [ $next, @user_data ].

The list handler can reference the list contents via double-dollar. For example, walking the list uses:

$$listh = $$list->[0]

this allows $listh to be blessed and use inside- out data structures while the nodes are un-blessed.

AUTHOR

Steven Lembark <lembark@wrkhors.com>

COPYRIGHT

Copyright (C) 2009, 2010 Steven Lembark.

LICENSE

This code can be used under the same terms as Perl-5.10.1 itself.