File Coverage

blib/lib/DataStructure/DoubleList/Node.pm
Criterion Covered Total %
statement 85 85 100.0
branch 8 8 100.0
condition n/a
subroutine 15 15 100.0
pod 6 7 85.7
total 114 115 99.1


line stmt bran cond sub pod time code
1             # A node of a double linked list.
2              
3             package DataStructure::DoubleList::Node;
4              
5 1     1   7 use strict;
  1         1  
  1         30  
6 1     1   5 use warnings;
  1         2  
  1         23  
7 1     1   7 use utf8;
  1         2  
  1         29  
8 1     1   32 use feature ':5.24';
  1         1  
  1         92  
9 1     1   7 use feature 'signatures';
  1         2  
  1         38  
10 1     1   6 no warnings 'experimental::signatures';
  1         1  
  1         35  
11              
12 1     1   15 use Scalar::Util qw(weaken);
  1         3  
  1         794  
13              
14             =pod
15              
16             =head1 NAME
17              
18             DataStructure::DoubleList::Node
19              
20             =head1 SYNOPSIS
21              
22             A single node (element) in a L.
23              
24             =head1 DESCRIPTION
25              
26             =head2 CONSTRUCTOR
27              
28             You can’t build a node directly. Instead you can call one of the accessors of a
29             L or some of the methods below.
30              
31             Note that a B does not hold a reference on its
32             parent list. So a node becomes invalid when the last reference to its list is
33             deleted as the list itself will be destroyed. But you should also not depend on
34             this behavior as it might be fixed in the future.
35              
36             =cut
37              
38             # The constructor is private and should be called only by this package and its
39             # parent.
40 20     20 0 30 sub new ($class, $list, $prev, $next, $value) {
  20         32  
  20         30  
  20         26  
  20         28  
  20         39  
  20         33  
41 20         72 my $self = bless {
42             list => $list,
43             prev => $prev,
44             next => $next,
45             value => $value,
46             }, $class;
47 20         69 weaken($self->{list});
48 20         47 return $self;
49             }
50              
51             =pod
52              
53             =head2 METHODS
54              
55             All the functions below are class methods that should be called on a
56             B object.
57              
58             =head3 I
59              
60             Returns the value held by this node.
61              
62             =cut
63              
64 122     122 1 1400 sub value ($self) {
  122         161  
  122         156  
65 122         262 return $self->{value};
66             }
67              
68             =pod
69              
70             =head3 I
71              
72             Returns the previous B in this list or B
73             if the current object is the first node in its list.
74              
75             The current node can still be used after that call.
76              
77             =cut
78              
79 1     1 1 3 sub prev ($self) {
  1         2  
  1         2  
80 1         5 return $self->{prev};
81             }
82              
83             =pod
84              
85             =head3 I
86              
87             Returns the next B in this list or B
88             if the current object is the last node in its list.
89              
90             The current node can still be used after that call.
91              
92             =cut
93              
94 119     119 1 603 sub next ($self) {
  119         145  
  119         140  
95 119         283 return $self->{next};
96             }
97              
98             =pod
99              
100             =head3 I
101              
102             Inserts a new node in the list after the current one, with the given value and
103             returns that new node.
104              
105             The current node can still be used after that call.
106              
107             =cut
108              
109 4     4 1 11 sub insert_after ($self, $value) {
  4         7  
  4         8  
  4         4  
110 4         14 my $new_node = new(ref $self, $self->{list}, $self, $self->{next}, $value);
111 4 100       26 if (defined $self->{next}) {
112 2         6 $self->{next}{prev} = $new_node;
113             } else {
114 2         5 $self->{list}{last} = $new_node;
115             }
116 4         8 $self->{next} = $new_node;
117 4         7 $self->{list}{size}++;
118 4         8 return $new_node;
119             }
120              
121              
122             =pod
123              
124             =head3 I
125              
126             Inserts a new node before in the list before the current one, with the given
127             value and returns that new node.
128              
129             The current node can still be used after that call.
130              
131             =cut
132              
133 4     4 1 10 sub insert_before ($self, $value) {
  4         6  
  4         7  
  4         6  
134 4         15 my $new_node = new(ref $self, $self->{list}, $self->{prev}, $self, $value);
135 4 100       12 if (defined $self->{prev}) {
136 2         6 $self->{prev}{next} = $new_node;
137             } else {
138 2         16 $self->{list}{first} = $new_node;
139             }
140 4         7 $self->{prev} = $new_node;
141 4         8 $self->{list}{size}++;
142 4         9 return;
143             }
144              
145              
146             =pod
147              
148             =head3 I
149              
150             Removes the node from the list and returns the value that it help value. The
151             node becomes invalid and can no longer be used.
152              
153             =cut
154              
155 15     15 1 24 sub delete ($self) {
  15         20  
  15         25  
156 15         22 my $value = $self->{value};
157 15         39 $self->_delete();
158 15         60 return $value;
159             }
160              
161             # Removes the current element without returning its value.
162 15     15   20 sub _delete ($self) {
  15         19  
  15         24  
163 15         30 my ($prev, $next) = ($self->{prev}, $self->{next});
164 15 100       31 if (defined $prev) {
165 6         13 $prev->{next} = $next;
166             } else {
167 9         17 $self->{list}{first} = $next;
168             }
169 15 100       29 if (defined $next) {
170 7         9 $next->{prev} = $prev;
171             } else {
172 8         12 $self->{list}{last} = $prev;
173             }
174 15         28 $self->{list}{size}--;
175 15         17 undef %{$self};
  15         37  
176 15         26 return;
177             }
178              
179             1;