File Coverage

blib/lib/List/Pairwise.pm
Criterion Covered Total %
statement 123 128 96.0
branch 68 74 91.8
condition 12 14 85.7
subroutine 21 22 95.4
pod 1 1 100.0
total 225 239 94.1


line stmt bran cond sub pod time code
1             package List::Pairwise;
2 11     11   291303 use 5.006;
  11         42  
  11         432  
3 11     11   66 use strict;
  11         20  
  11         471  
4 11     11   55 use warnings;
  11         32  
  11         378  
5 11     11   55 use Exporter;
  11         18  
  11         559  
6              
7 11     11   53 use constant USE_LIST_UTIL_VERSION => 0;
  11         18  
  11         2135  
8              
9             our $VERSION = '1.03';
10              
11             our %EXPORT_TAGS = (
12             all => [ qw(
13             mapp grepp firstp lastp
14             map_pairwise grep_pairwise first_pairwise last_pairwise
15             pair
16             ) ],
17             );
18              
19             our @EXPORT_OK = ( @{ $EXPORT_TAGS{all} } );
20              
21             if ($] < 5.019006) {
22             # avoid "Name "main::a" used only once" warnings for $a and $b
23             *import = sub {
24 11     11   63 no strict qw(refs);
  11         22  
  11         355  
25 11     11   173 no warnings qw(once void);
  11         19  
  11         2340  
26             *{caller().'::a'};
27             *{caller().'::b'};
28             goto &Exporter::import
29             }
30             } else {
31             import Exporter 'import'
32             }
33              
34             sub _carp_odd {
35 49     49   8548 [caller(1)]->[3] =~ /([a-z]+)$/;
36 49         6221 warnings::warnif(misc => "Odd number of elements in $1")
37             }
38              
39             sub _mapp (&@) {
40 32     32   20981 my $code = shift;
41 32 100       112 _carp_odd if @_&1;
42              
43             # Localise $a and $b
44             # (borrowed from List-MoreUtils)
45 32         172 my ($caller_a, $caller_b) = do {
46 32         56 my $pkg = caller();
47 11     11   58 no strict 'refs';
  11         19  
  11         680  
48 32         38 \*{$pkg.'::a'}, \*{$pkg.'::b'};
  32         94  
  32         100  
49             };
50 32         169 local(*$caller_a, *$caller_b);
51              
52 11     11   56 no warnings;
  11         16  
  11         10828  
53              
54 32 100       80 if (not @_&1) {
55             # Even number of elements
56             # normal case
57 19 100       53 if (wantarray) {
    100          
58             # list context
59 7         24 map {(*$caller_a, *$caller_b) = \splice(@_, 0, 2); $code->()} (1..@_/2)
  27         99  
  27         60  
60             }
61             elsif (defined wantarray) {
62             # scalar context
63             # count number of returned elements
64 7         7 my $i=0;
65             # force list context with =()= for the count
66 7         41 $i +=()= $code->() while (*$caller_a, *$caller_b) = \splice(@_, 0, 2);
67 7         133 $i
68             }
69             else {
70             # void context
71 5         38 () = $code->() while (*$caller_a, *$caller_b) = \splice(@_, 0, 2);
72             }
73             }
74             else {
75             # Odd number of element
76             # Same code but last element is an alias to undef
77 13 100       40 if (wantarray) {
    100          
78 4 100       16 map {(*$caller_a, *$caller_b) = $_ ? \splice(@_, 0, 2) : \(shift, undef); $code->()} (1..@_/2, 0)
  7         31  
  7         17  
79             }
80             elsif (defined wantarray) {
81 4         8 my $i=0;
82 4 100       43 $i +=()= $code->() while (*$caller_a, *$caller_b) = @_==1 ? \(shift, undef) : \splice(@_, 0, 2);
83 3         73 $i
84             }
85             else {
86 5 100       37 () = $code->() while (*$caller_a, *$caller_b) = @_==1 ? \(shift, undef) : \splice(@_, 0, 2);
87             }
88             }
89             }
90              
91             sub _grepp (&@) {
92 22     22   9934 my $code = shift;
93 22 100       74 _carp_odd if @_&1;
94              
95             # Localise $a and $b
96             # (borrowed from List-MoreUtils)
97 22         140 my ($caller_a, $caller_b) = do {
98 22         35 my $pkg = caller();
99 11     11   168 no strict 'refs';
  11         20  
  11         649  
100 22         24 \*{$pkg.'::a'}, \*{$pkg.'::b'};
  22         61  
  22         69  
101             };
102 22         63 local(*$caller_a, *$caller_b);
103              
104 11     11   55 no warnings;
  11         30  
  11         11379  
105              
106 22 100       53 if (not @_&1) {
107             # Even number of elements
108             # normal case
109 13 100       35 if (wantarray) {
    100          
110             # list context
111 5 100       20 map {(*$caller_a, *$caller_b) = \splice(@_, 0, 2); $code->() ? ($$$caller_a, $$$caller_b) : ()} (1..@_/2)
  21         118  
  21         53  
112             }
113             elsif (defined wantarray) {
114             # scalar context
115             # count number of valid *pairs* (not elements)
116 6         9 my $i=0;
117 6   66     38 $code->() && ++$i while (*$caller_a, *$caller_b) = \splice(@_, 0, 2);
118 6         206 $i
119             # Returning the number of valid pairs is more intuitive than
120             # the number of elements.
121             # We have this equality:
122             # (grepp BLOCK LIST) == 1/2 * scalar(my @a = (grepp BLOCK LIST))
123             }
124             else {
125             # void context
126             # same as mapp, but evaluates $code in scalar context
127 2         19 scalar $code->() while (*$caller_a, *$caller_b) = \splice(@_, 0, 2);
128             }
129             }
130             else {
131             # Odd number of element
132             # Same code but last element is an alias to undef
133 9 100       22 if (wantarray) {
    100          
134 2 100       9 map {(*$caller_a, *$caller_b) = $_ ? \splice(@_, 0, 2) : \(shift, undef); $code->() ? ($$$caller_a, $$$caller_b) : ()} (1..@_/2, 0)
  4 50       23  
  4         12  
135             }
136             elsif (defined wantarray) {
137 2         5 my $i=0;
138 2 100 66     25 $code->() && ++$i while (*$caller_a, *$caller_b) = @_==1 ? \(shift, undef) : \splice(@_, 0, 2);
139 1         37 $i
140             }
141             else {
142 5 100       32 scalar $code->() while (*$caller_a, *$caller_b) = @_==1 ? \(shift, undef) : \splice(@_, 0, 2);
143             }
144             }
145             }
146              
147             sub _firstp (&@) {
148 22     22   10088 my $code = shift;
149 22 100       69 _carp_odd if @_&1;
150              
151             # Localise $a and $b
152             # (borrowed from List-MoreUtils)
153 22         148 my ($caller_a, $caller_b) = do {
154 22         39 my $pkg = caller();
155 11     11   63 no strict 'refs';
  11         20  
  11         676  
156 22         23 \*{$pkg.'::a'}, \*{$pkg.'::b'};
  22         56  
  22         53  
157             };
158 22         58 local(*$caller_a, *$caller_b);
159              
160 11     11   59 no warnings;
  11         30  
  11         3066  
161              
162 22 100       48 if (not @_&1) {
163             # Even number of elements
164             # normal case
165 13 100 100     64 $code->() && return wantarray ? ($$$caller_a, $$$caller_b) : 1 while (*$caller_a, *$caller_b) = \splice(@_, 0, 2);
166             ()
167 5         554 }
168             else {
169             # Odd number of element
170             # Same code but last element is an alias to undef
171 9 100 100     63 $code->() && return wantarray ? ($$$caller_a, $$$caller_b) : 1 while (*$caller_a, *$caller_b) = @_==1 ? \(shift, undef) : (\splice(@_, 0, 2));
    100          
172             ()
173 0         0 }
174             }
175              
176             sub lastp (&@) {
177 22     22 1 10074 my $code = shift;
178 22 100       65 _carp_odd if @_&1;
179              
180             # Localise $a and $b
181             # (borrowed from List-MoreUtils)
182 22         153 my ($caller_a, $caller_b) = do {
183 22         36 my $pkg = caller();
184 11     11   59 no strict 'refs';
  11         16  
  11         670  
185 22         23 \*{$pkg.'::a'}, \*{$pkg.'::b'};
  22         54  
  22         56  
186             };
187 22         62 local(*$caller_a, *$caller_b);
188              
189 11     11   53 no warnings;
  11         18  
  11         6144  
190              
191 22 100       50 if (not @_&1) {
192             # Even number of elements
193             # normal case
194 13 100 100     75 $code->() && return wantarray ? ($$$caller_a, $$$caller_b) : 1 while (*$caller_a, *$caller_b) = @_ ? \splice(@_, -2) : ();
    100          
195             ()
196 5         105 }
197             else {
198             # Odd number of element
199             # Same code but last element is an alias to undef
200 9 50 100     56 $code->() && return wantarray ? ($$$caller_a, $$$caller_b) : 1 while (*$caller_a, *$caller_b) = @_>=2 ? (\splice(@_, 0, 2)) : @_==1 ? \(shift, undef) : ();
    100          
    100          
201             ()
202 0         0 }
203             }
204              
205             sub _pair {
206 20 100   20   8520 _carp_odd if @_&1;
207             return @_
208 20 100       200 ? map [ @_[$_*2, $_*2 + 1] ] => 0 .. ($#_>>1)
    100          
209             : wantarray ? () : 0
210             ;
211             }
212              
213             sub _LU_pair {
214 0 0   0     goto \&List::Util::pairs if wantarray;
215 0 0         _carp_odd if @_&1;
216 0           1+@_>>1
217             }
218              
219             #sub truep (&@) { scalar &grepp(@_) }
220             #sub falsep (&@) { (@_-1)/2 - &grepp(@_) }
221             #sub allp (&@) { (@_-1)/2 == &grepp(@_) }
222             #sub notallp (&@) { (@_-1)/2 > &grepp(@_) }
223             #sub nonep (&@) { !&firstp(@_) }
224             #sub anyp (&@) { scalar &firstp(@_) }
225              
226             # install functions
227              
228             sub mapp (&@);
229             sub grepp (&@);
230             sub firstp (&@);
231             sub pair;
232              
233             if (USE_LIST_UTIL_VERSION && eval {require List::Util;1} && $List::Util::VERSION >= USE_LIST_UTIL_VERSION) {
234             # print "LIST UTIL\n\n";
235             *mapp = \&List::Util::pairmap;
236             *grepp = \&List::Util::pairgrep;
237             *firstp = \&List::Util::pairfirst;
238             *pair = \&_LU_pair;
239             } else {
240             # print "INTERNAL\n\n";
241             *mapp = \&_mapp;
242             *grepp = \&_grepp;
243             *firstp = \&_firstp;
244             *pair = \&_pair;
245             }
246              
247             # install aliases
248              
249             sub map_pairwise (&@);
250             sub grep_pairwise (&@);
251             sub first_pairwise (&@);
252             sub last_pairwise (&@);
253             #sub true_pairwise (&@);
254             #sub false_pairwise (&@);
255             #sub all_pairwise (&@);
256             #sub notall_pairwise (&@);
257             #sub none_pairwise (&@);
258             #sub any_pairwise (&@);
259              
260             *map_pairwise = \&mapp;
261             *grep_pairwise = \&grepp;
262             *first_pairwise = \&firstp;
263             *last_pairwise = \&lastp;
264             #*true_pairwise = \&truep;
265             #*false_pairwise = \&falsep;
266             #*all_pairwise = \&allp;
267             #*notall_pairwise = \¬allp;
268             #*none_pairwise = \&nonep;
269             #*any_pairwise = \&anyp;
270              
271             1