File Coverage

blib/lib/App/Sets/Operations.pm
Criterion Covered Total %
statement 50 51 98.0
branch 12 12 100.0
condition 12 16 75.0
subroutine 11 11 100.0
pod 0 3 0.0
total 85 93 91.4


line stmt bran cond sub pod time code
1             package App::Sets::Operations;
2             $App::Sets::Operations::VERSION = '0.978';
3              
4              
5 3     3   24 use strict;
  3         6  
  3         98  
6 3     3   17 use warnings;
  3         5  
  3         88  
7              
8             # ABSTRACT: set operations in Perl
9              
10 3     3   15 use English qw( -no_match_vars );
  3         6  
  3         33  
11 3     3   1290 use 5.010;
  3         11  
12 3     3   20 use App::Sets::Iterator;
  3         5  
  3         1426  
13              
14             sub intersect {
15 20     20 0 105 my ($l, $r) = @_;
16 20         66 my ($lh, $rh);
17             return App::Sets::Iterator->new(
18             sub {
19 160     160   233 while ('necessary') {
20 280   100     1045 $lh //= $l->drop() // last;
      100        
21 240   50     779 $rh //= $r->drop() // last;
      66        
22 240 100       548 if ($lh eq $rh) {
    100          
23 120         181 my $retval = $lh;
24 120         218 $lh = $rh = undef;
25 120         293 return $retval;
26             }
27             elsif ($lh gt $rh) {
28 40         80 $rh = undef;
29             }
30             else {
31 80         113 $lh = undef;
32             }
33             } ## end while ('necessary')
34 40         91 return undef;
35             }
36 20         311 );
37             } ## end sub intersect
38              
39             sub union {
40 28     28 0 119 my ($l, $r) = @_;
41 28         124 my ($lh, $rh);
42             return App::Sets::Iterator->new(
43             sub {
44 420   66 420   823 while (defined($lh = $l->head()) && defined($rh = $r->head())) {
45 336 100       909 if ($lh eq $rh) {
    100          
46 168         430 $r->drop();
47 168         370 return $l->drop();
48             }
49             elsif ($lh lt $rh) {
50 112         288 return $l->drop();
51             }
52             else {
53 56         189 return $r->drop();
54             }
55             } ## end while (defined($lh = $l->head...
56 84         235 while (defined($lh = $l->drop())) {
57 0         0 return $lh;
58             }
59 84         240 while (defined($rh = $r->drop())) {
60 28         80 return $rh;
61             }
62 56         120 return undef;
63             }
64 28         484 );
65             } ## end sub union
66              
67             sub minus {
68 16     16 0 54 my ($l, $r) = @_;
69 16         43 my ($lh, $rh);
70             return App::Sets::Iterator->new(
71             sub {
72 96   66 96   224 while (defined($lh = $l->head()) && defined($rh = $r->head())) {
73 192 100       448 if ($lh eq $rh) { # shared, drop both
    100          
74 96         216 $r->drop();
75 96         163 $l->drop();
76             }
77             elsif ($lh lt $rh) { # only in left, OK!
78 64         125 return $l->drop();
79             }
80             else { # only in right, go on
81 32         96 $r->drop();
82             }
83             } ## end while (defined($lh = $l->head...
84 32         90 return $l->drop();
85             }
86 16         221 );
87             } ## end sub minus
88              
89             1;
90              
91             __END__