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   17059 use 5.006000;
  5         12  
  5         188  
6              
7 5     5   24 use strict;
  5         3  
  5         125  
8 5     5   19 use warnings;
  5         13  
  5         158  
9 5     5   26 use Carp;
  5         6  
  5         791  
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.23';
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 15316 my ( $code, $target, $aref ) = @_;
27 32         37 my $min = 0;
28 32         21 my $max = $#{$aref};
  32         45  
29 32         66 while ( $max > $min ) {
30 80         108 my $mid = int( ( $min + $max ) / 2 );
31 5     5   23 no strict 'refs'; ## no critic(strict)
  5         5  
  5         329  
32 80         66 local ( ${caller() . '::a'}, ${caller() . '::b'} )
  80         158  
  80         126  
33             = ( $target, $aref->[$mid] );
34 80 100       129 if ( $code->( $target, $aref->[$mid] ) > 0 ) {
35 38         135 $min = $mid + 1;
36             }
37             else {
38 42         140 $max = $mid;
39             }
40             }
41             {
42 5     5   19 no strict 'refs'; ## no critic(strict)
  5         8  
  5         631  
  32         25  
43 32         31 local ( ${caller() . '::a'}, ${caller() . '::b'} )
  32         42  
  32         42  
44             = ( $target, $aref->[$min] );
45 32 100       50 return $min if $code->( $target, $aref->[$min] ) == 0;
46             }
47 6         36 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 3641 my ( $comp, $target, $aref ) = @_;
58 9         11 my ( $low, $high ) = ( 0, scalar @{$aref} );
  9         53  
59 9         27 while ( $low < $high ) {
60 24         37 my $cur = int( ( $low + $high ) / 2 );
61 5     5   22 no strict 'refs'; ## no critic(strict)
  5         5  
  5         404  
62 24         25 local ( ${ caller() . '::a'}, ${ caller() . '::b'} )
  24         51  
  24         47  
63             = ( $target, $aref->[$cur] ); # Future use.
64 24 100       52 if ( $comp->( $target, $aref->[$cur] ) > 0 ) {
65 10         37 $low = $cur + 1;
66             }
67             else {
68 14         56 $high = $cur;
69             }
70             }
71 9         26 return $low;
72             }
73              
74              
75             1;
76              
77             __END__