File Coverage

blib/lib/List/BinarySearch/PP.pm
Criterion Covered Total %
statement 53 53 100.0
branch 6 6 100.0
condition n/a
subroutine 9 9 100.0
pod 2 2 100.0
total 70 70 100.0


line stmt bran cond sub pod time code
1             ## no critic (RCS,prototypes)
2              
3             package List::BinarySearch::PP;
4              
5 5     5   15335 use 5.006000;
  5         12  
  5         180  
6              
7 5     5   22 use strict;
  5         5  
  5         129  
8 5     5   19 use warnings;
  5         13  
  5         157  
9 5     5   24 use Carp;
  5         7  
  5         727  
10              
11             require Exporter;
12              
13             our @ISA = qw(Exporter); ## no critic (ISA)
14             our @EXPORT = qw( binsearch binsearch_pos ); ## no critic (export)
15              
16              
17             our $VERSION = '0.25';
18             # $VERSION = eval $VERSION; ## no critic (eval)
19              
20              
21              
22             #---------------------------------------------
23             # Use a callback for comparisons.
24              
25             sub binsearch (&$\@) {
26 32     32 1 16069 my ( $code, $target, $aref ) = @_;
27 32         32 my $min = 0;
28 32         29 my $max = $#{$aref};
  32         47  
29 32         54 my $caller = caller();
30 32         66 while ( $max > $min ) {
31 80         122 my $mid = int( ( $max - $min ) / 2 + $min );
32 5     5   22 no strict 'refs'; ## no critic(strict)
  5         8  
  5         369  
33 80         70 local ( ${"${caller}::a"}, ${"${caller}::b"} )
  80         128  
  80         128  
34             = ( $target, $aref->[$mid] );
35 80 100       131 if ( $code->( $target, $aref->[$mid] ) > 0 ) {
36 38         150 $min = $mid + 1;
37             }
38             else {
39 42         153 $max = $mid;
40             }
41             }
42             {
43 5     5   19 no strict 'refs'; ## no critic(strict)
  5         6  
  5         640  
  32         26  
44 32         30 local ( ${"${caller}::a"}, ${"${caller}::b"} )
  32         41  
  32         44  
45             = ( $target, $aref->[$min] );
46 32 100       48 return $min if $code->( $target, $aref->[$min] ) == 0;
47             }
48 6         36 return; # Undef in scalar context, empty list in list context.
49             }
50              
51              
52             #------------------------------------------------------
53             # Identical to binsearch, but upon match-failure returns best insert
54             # position for $target.
55              
56              
57             sub binsearch_pos (&$\@) {
58 9     9 1 3118 my ( $comp, $target, $aref ) = @_;
59 9         11 my ( $low, $high ) = ( 0, scalar @{$aref} );
  9         15  
60 9         23 my $caller = caller();
61 9         24 while ( $low < $high ) {
62 24         46 my $cur = int( ( $high - $low ) / 2 + $low );
63 5     5   21 no strict 'refs'; ## no critic(strict)
  5         6  
  5         505  
64 24         30 local ( ${"${caller}::a"}, ${"${caller}::b"} )
  24         73  
  24         44  
65             = ( $target, $aref->[$cur] ); # Future use.
66 24 100       59 if ( $comp->( $target, $aref->[$cur] ) > 0 ) {
67 10         45 $low = $cur + 1;
68             }
69             else {
70 14         59 $high = $cur;
71             }
72             }
73 9         31 return $low;
74             }
75              
76              
77             1;
78              
79             __END__