File Coverage

blib/lib/List/BinarySearch/PP.pm
Criterion Covered Total %
statement 51 51 100.0
branch 6 6 100.0
condition n/a
subroutine 9 9 100.0
pod 2 2 100.0
total 68 68 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   15936 use 5.006000;
  5         12  
  5         173  
6              
7 5     5   21 use strict;
  5         6  
  5         138  
8 5     5   19 use warnings;
  5         11  
  5         145  
9 5     5   20 use Carp;
  5         6  
  5         802  
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.24';
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 12519 my ( $code, $target, $aref ) = @_;
27 32         66 my $min = 0;
28 32         31 my $max = $#{$aref};
  32         45  
29 32         66 while ( $max > $min ) {
30 80         109 my $mid = int( ( $min + $max ) / 2 );
31 5     5   27 no strict 'refs'; ## no critic(strict)
  5         6  
  5         425  
32 80         72 local ( ${caller() . '::a'}, ${caller() . '::b'} )
  80         155  
  80         121  
33             = ( $target, $aref->[$mid] );
34 80 100       129 if ( $code->( $target, $aref->[$mid] ) > 0 ) {
35 38         139 $min = $mid + 1;
36             }
37             else {
38 42         146 $max = $mid;
39             }
40             }
41             {
42 5     5   24 no strict 'refs'; ## no critic(strict)
  5         5  
  5         755  
  32         24  
43 32         26 local ( ${caller() . '::a'}, ${caller() . '::b'} )
  32         50  
  32         44  
44             = ( $target, $aref->[$min] );
45 32 100       48 return $min if $code->( $target, $aref->[$min] ) == 0;
46             }
47 6         32 return; # Undef in scalar context, empty list in list context.
48             }
49              
50              
51             #------------------------------------------------------
52             # Identical to binsearch, but upon match-failure returns best insert
53             # position for $target.
54              
55              
56             sub binsearch_pos (&$\@) {
57 9     9 1 2800 my ( $comp, $target, $aref ) = @_;
58 9         13 my ( $low, $high ) = ( 0, scalar @{$aref} );
  9         16  
59 9         29 while ( $low < $high ) {
60 24         38 my $cur = int( ( $low + $high ) / 2 );
61 5     5   26 no strict 'refs'; ## no critic(strict)
  5         6  
  5         496  
62 24         30 local ( ${ caller() . '::a'}, ${ caller() . '::b'} )
  24         60  
  24         48  
63             = ( $target, $aref->[$cur] ); # Future use.
64 24 100       64 if ( $comp->( $target, $aref->[$cur] ) > 0 ) {
65 10         44 $low = $cur + 1;
66             }
67             else {
68 14         73 $high = $cur;
69             }
70             }
71 9         30 return $low;
72             }
73              
74              
75             1;
76              
77             __END__