line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
98
|
|
|
98
|
|
3562
|
use 5.006; |
|
98
|
|
|
|
|
338
|
|
2
|
98
|
|
|
98
|
|
574
|
use strict; |
|
98
|
|
|
|
|
182
|
|
|
98
|
|
|
|
|
2239
|
|
3
|
98
|
|
|
98
|
|
507
|
use warnings; |
|
98
|
|
|
|
|
207
|
|
|
98
|
|
|
|
|
63877
|
|
4
|
|
|
|
|
|
|
|
5
|
|
|
|
|
|
|
if ( $] < 5.010000 ) { |
6
|
|
|
|
|
|
|
require UNIVERSAL::DOES; |
7
|
|
|
|
|
|
|
} |
8
|
|
|
|
|
|
|
|
9
|
|
|
|
|
|
|
{ |
10
|
|
|
|
|
|
|
package # hide from PAUSE |
11
|
|
|
|
|
|
|
LINQ::Iterator::_LazyList; |
12
|
|
|
|
|
|
|
|
13
|
|
|
|
|
|
|
my $_throw_caller_error = sub { |
14
|
|
|
|
|
|
|
shift; |
15
|
|
|
|
|
|
|
require LINQ::Exception; |
16
|
|
|
|
|
|
|
'LINQ::Exception::CallerError'->throw( message => @_ ); |
17
|
|
|
|
|
|
|
}; |
18
|
|
|
|
|
|
|
|
19
|
|
|
|
|
|
|
sub __GENERATOR () { 0 } |
20
|
|
|
|
|
|
|
sub __EXHAUSTED () { 1 } |
21
|
|
|
|
|
|
|
sub __VALUES () { 2 } |
22
|
|
|
|
|
|
|
sub __NEXT_SLOT () { 3 } |
23
|
|
|
|
|
|
|
|
24
|
|
|
|
|
|
|
sub TIEARRAY { |
25
|
655
|
|
|
655
|
|
1098
|
my $class = shift; |
26
|
655
|
|
|
|
|
2533
|
bless [ |
27
|
|
|
|
|
|
|
$_[0], |
28
|
|
|
|
|
|
|
!!0, |
29
|
|
|
|
|
|
|
[], |
30
|
|
|
|
|
|
|
], $class; |
31
|
|
|
|
|
|
|
} |
32
|
|
|
|
|
|
|
|
33
|
|
|
|
|
|
|
sub FETCH { |
34
|
1123
|
|
|
1123
|
|
2803
|
my $self = shift; |
35
|
1123
|
|
|
|
|
1615
|
my ( $ix ) = @_; |
36
|
1123
|
|
|
|
|
1470
|
my $cache = $self->[__VALUES]; |
37
|
|
|
|
|
|
|
|
38
|
1123
|
|
|
|
|
2312
|
$self->extend_to( $ix ); |
39
|
|
|
|
|
|
|
|
40
|
1123
|
100
|
|
|
|
4038
|
$ix >= @$cache ? undef : $cache->[$ix]; |
41
|
|
|
|
|
|
|
} |
42
|
|
|
|
|
|
|
|
43
|
|
|
|
|
|
|
sub fetch_ref { |
44
|
1520
|
|
|
1520
|
|
2058
|
my $self = shift; |
45
|
1520
|
|
|
|
|
2282
|
my ( $ix ) = @_; |
46
|
1520
|
|
|
|
|
2078
|
my $cache = $self->[__VALUES]; |
47
|
|
|
|
|
|
|
|
48
|
1520
|
|
|
|
|
3243
|
$self->extend_to( $ix ); |
49
|
|
|
|
|
|
|
|
50
|
1518
|
100
|
|
|
|
3071
|
return if $ix > 0+ $#$cache; |
51
|
1357
|
100
|
|
|
|
2697
|
return if $ix < 0 - @$cache; |
52
|
1355
|
|
|
|
|
2296
|
\( $cache->[$ix] ); |
53
|
|
|
|
|
|
|
} #/ sub fetch_ref |
54
|
|
|
|
|
|
|
|
55
|
|
|
|
|
|
|
sub FETCHSIZE { |
56
|
845
|
|
|
845
|
|
43059
|
my $self = shift; |
57
|
845
|
|
|
|
|
1991
|
$self->extend_to( -1 ); |
58
|
828
|
|
|
|
|
1301
|
scalar @{ $self->[__VALUES] }; |
|
828
|
|
|
|
|
2331
|
|
59
|
|
|
|
|
|
|
} |
60
|
|
|
|
|
|
|
|
61
|
|
|
|
|
|
|
sub current_extension { |
62
|
2
|
|
|
2
|
|
3
|
my $self = shift; |
63
|
2
|
|
|
|
|
3
|
scalar @{ $self->[__VALUES] }; |
|
2
|
|
|
|
|
9
|
|
64
|
|
|
|
|
|
|
} |
65
|
|
|
|
|
|
|
|
66
|
|
|
|
|
|
|
sub is_fully_extended { |
67
|
1
|
|
|
1
|
|
2
|
my $self = shift; |
68
|
1
|
|
|
|
|
4
|
$self->[__EXHAUSTED]; |
69
|
|
|
|
|
|
|
} |
70
|
|
|
|
|
|
|
|
71
|
|
|
|
|
|
|
sub extend_to { |
72
|
3488
|
|
|
3488
|
|
12081
|
require LINQ; |
73
|
|
|
|
|
|
|
|
74
|
3488
|
|
|
|
|
4801
|
my $self = shift; |
75
|
3488
|
|
|
|
|
4807
|
my ( $ix ) = @_; |
76
|
3488
|
|
|
|
|
4660
|
my $cache = $self->[__VALUES]; |
77
|
|
|
|
|
|
|
|
78
|
|
|
|
|
|
|
EXTEND: { |
79
|
3488
|
100
|
|
|
|
4275
|
return if $self->[__EXHAUSTED]; |
|
5668
|
|
|
|
|
10144
|
|
80
|
3876
|
100
|
100
|
|
|
10227
|
return if $ix >= 0 && $ix < @$cache; |
81
|
|
|
|
|
|
|
|
82
|
2644
|
|
|
|
|
4985
|
my @got = $self->[__GENERATOR]->(); |
83
|
2627
|
|
|
|
|
8419
|
my $got; |
84
|
|
|
|
|
|
|
|
85
|
|
|
|
|
|
|
# Crazy optimized loop to find and handle LINQ::END |
86
|
|
|
|
|
|
|
# within @got |
87
|
|
|
|
|
|
|
# uncoverable condition count:1 |
88
|
|
|
|
|
|
|
# uncoverable condition count:5 |
89
|
2627
|
100
|
66
|
|
|
13223
|
push( @$cache, shift @got ) |
|
|
|
100
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
66
|
|
|
|
|
|
|
|
33
|
|
|
|
|
90
|
|
|
|
|
|
|
and ref( $got = $cache->[-1] ) |
91
|
|
|
|
|
|
|
and $got == LINQ::END() |
92
|
|
|
|
|
|
|
and ( $self->[__EXHAUSTED] = !!1 ) |
93
|
|
|
|
|
|
|
and pop( @$cache ) |
94
|
|
|
|
|
|
|
and ( |
95
|
|
|
|
|
|
|
@got |
96
|
|
|
|
|
|
|
? $self->$_throw_caller_error( 'Returned values after LINQ::END' ) |
97
|
|
|
|
|
|
|
: return () |
98
|
|
|
|
|
|
|
) while @got; |
99
|
|
|
|
|
|
|
|
100
|
2180
|
|
|
|
|
3595
|
redo EXTEND; |
101
|
|
|
|
|
|
|
} #/ EXTEND: |
102
|
|
|
|
|
|
|
} #/ sub extend_to |
103
|
|
|
|
|
|
|
} |
104
|
|
|
|
|
|
|
|
105
|
|
|
|
|
|
|
package LINQ::Iterator; |
106
|
|
|
|
|
|
|
|
107
|
|
|
|
|
|
|
our $AUTHORITY = 'cpan:TOBYINK'; |
108
|
|
|
|
|
|
|
our $VERSION = '0.001'; |
109
|
|
|
|
|
|
|
|
110
|
98
|
|
|
98
|
|
28719
|
use Role::Tiny::With (); |
|
98
|
|
|
|
|
304957
|
|
|
98
|
|
|
|
|
2350
|
|
111
|
98
|
|
|
98
|
|
29085
|
use LINQ::Util::Internal (); |
|
98
|
|
|
|
|
255
|
|
|
98
|
|
|
|
|
13682
|
|
112
|
|
|
|
|
|
|
|
113
|
|
|
|
|
|
|
Role::Tiny::With::with( qw( LINQ::Collection ) ); |
114
|
|
|
|
|
|
|
|
115
|
|
|
|
|
|
|
sub new { |
116
|
525
|
|
|
525
|
1
|
10600
|
my $class = shift; |
117
|
525
|
100
|
|
|
|
1325
|
if ( @_ ) { |
118
|
524
|
|
|
|
|
1337
|
tie my ( @arr ), 'LINQ::Iterator::_LazyList', |
119
|
|
|
|
|
|
|
LINQ::Util::Internal::assert_code( @_ ); |
120
|
524
|
|
|
|
|
2930
|
return bless \@arr, $class; |
121
|
|
|
|
|
|
|
} |
122
|
|
|
|
|
|
|
LINQ::Util::Internal::throw( |
123
|
1
|
|
|
|
|
5
|
"CallerError", |
124
|
|
|
|
|
|
|
message => "Expected a coderef" |
125
|
|
|
|
|
|
|
); |
126
|
|
|
|
|
|
|
} #/ sub new |
127
|
|
|
|
|
|
|
|
128
|
|
|
|
|
|
|
sub _guts { |
129
|
431
|
|
|
431
|
|
1938
|
my $self = shift; |
130
|
431
|
|
|
|
|
1593
|
tied( @$self ); |
131
|
|
|
|
|
|
|
} |
132
|
|
|
|
|
|
|
|
133
|
|
|
|
|
|
|
sub to_list { |
134
|
254
|
|
|
254
|
1
|
544
|
my $self = shift; |
135
|
254
|
|
|
|
|
886
|
my @list = @$self; |
136
|
|
|
|
|
|
|
|
137
|
|
|
|
|
|
|
# We must have exhausted the iterator now, |
138
|
|
|
|
|
|
|
# so remove all the magic and act like a |
139
|
|
|
|
|
|
|
# plain old arrayref. |
140
|
|
|
|
|
|
|
# |
141
|
237
|
100
|
|
|
|
831
|
if ( tied( @$self ) ) { |
142
|
98
|
|
|
98
|
|
717
|
no warnings; |
|
98
|
|
|
|
|
216
|
|
|
98
|
|
|
|
|
34176
|
|
143
|
173
|
|
|
|
|
1328
|
untie( @$self ); |
144
|
173
|
|
|
|
|
537
|
@$self = @list; |
145
|
|
|
|
|
|
|
} |
146
|
|
|
|
|
|
|
|
147
|
237
|
|
|
|
|
1726
|
@list; |
148
|
|
|
|
|
|
|
} #/ sub to_list |
149
|
|
|
|
|
|
|
|
150
|
|
|
|
|
|
|
|
151
|
|
|
|
|
|
|
sub to_array { |
152
|
134
|
|
|
134
|
1
|
27529
|
my $self = shift; |
153
|
|
|
|
|
|
|
|
154
|
134
|
100
|
|
|
|
300
|
if ( my $guts = $self->_guts ) { |
155
|
131
|
|
|
|
|
372
|
tie ( my @tied, 'LINQ::Iterator::_LazyList', undef ); |
156
|
131
|
|
|
|
|
309
|
@{ tied( @tied ) } = @$guts; |
|
131
|
|
|
|
|
434
|
|
157
|
131
|
|
|
|
|
986
|
return \@tied; |
158
|
|
|
|
|
|
|
} |
159
|
|
|
|
|
|
|
|
160
|
3
|
|
|
|
|
22
|
$self->LINQ::Collection::to_array( @_ ); |
161
|
|
|
|
|
|
|
} |
162
|
|
|
|
|
|
|
|
163
|
|
|
|
|
|
|
sub element_at { |
164
|
61
|
|
|
61
|
1
|
1368
|
my $self = shift; |
165
|
|
|
|
|
|
|
|
166
|
61
|
100
|
|
|
|
162
|
if ( my $guts = $self->_guts ) { |
167
|
27
|
|
|
|
|
63
|
my $ref = $guts->fetch_ref( @_ ); |
168
|
27
|
100
|
|
|
|
91
|
return $$ref if $ref; |
169
|
4
|
|
|
|
|
1099
|
require LINQ::Exception; |
170
|
4
|
|
|
|
|
21
|
'LINQ::Exception::NotFound'->throw( collection => $self ); |
171
|
|
|
|
|
|
|
} |
172
|
|
|
|
|
|
|
|
173
|
34
|
|
|
|
|
132
|
$self->LINQ::Collection::element_at( @_ ); |
174
|
|
|
|
|
|
|
} #/ sub element_at |
175
|
|
|
|
|
|
|
|
176
|
|
|
|
|
|
|
sub to_iterator { |
177
|
231
|
|
|
231
|
1
|
386
|
my $self = shift; |
178
|
|
|
|
|
|
|
|
179
|
231
|
100
|
|
|
|
490
|
if ( my $guts = $self->_guts ) { |
180
|
229
|
|
|
|
|
377
|
my $idx = 0; |
181
|
229
|
|
|
|
|
380
|
my $done = 0; |
182
|
|
|
|
|
|
|
return sub { |
183
|
1494
|
100
|
|
1494
|
|
2764
|
return if $done; |
184
|
1493
|
|
|
|
|
2995
|
my $val = $guts->fetch_ref( $idx++ ); |
185
|
1491
|
100
|
|
|
|
3926
|
return $$val if $val; |
186
|
159
|
|
|
|
|
285
|
++$done; |
187
|
159
|
|
|
|
|
371
|
return; |
188
|
229
|
|
|
|
|
1154
|
}; |
189
|
|
|
|
|
|
|
} #/ if ( my $guts = $self->...) |
190
|
|
|
|
|
|
|
|
191
|
2
|
|
|
|
|
26
|
$self->LINQ::Collection::to_iterator( @_ ); |
192
|
|
|
|
|
|
|
} #/ sub to_iterator |
193
|
|
|
|
|
|
|
|
194
|
|
|
|
|
|
|
1; |
195
|
|
|
|
|
|
|
|
196
|
|
|
|
|
|
|
__END__ |
197
|
|
|
|
|
|
|
|
198
|
|
|
|
|
|
|
=pod |
199
|
|
|
|
|
|
|
|
200
|
|
|
|
|
|
|
=encoding utf-8 |
201
|
|
|
|
|
|
|
|
202
|
|
|
|
|
|
|
=head1 NAME |
203
|
|
|
|
|
|
|
|
204
|
|
|
|
|
|
|
LINQ::Iterator - a LINQ collection with an iterator backend |
205
|
|
|
|
|
|
|
|
206
|
|
|
|
|
|
|
=head1 SYNOPSIS |
207
|
|
|
|
|
|
|
|
208
|
|
|
|
|
|
|
use LINQ qw( LINQ ); |
209
|
|
|
|
|
|
|
use LINQ::Iterator; |
210
|
|
|
|
|
|
|
|
211
|
|
|
|
|
|
|
my $linq = LINQ( sub { ... } ); |
212
|
|
|
|
|
|
|
|
213
|
|
|
|
|
|
|
# Same: |
214
|
|
|
|
|
|
|
my $linq = 'LINQ::Iterator'->new( sub { ... } ); |
215
|
|
|
|
|
|
|
|
216
|
|
|
|
|
|
|
=head1 METHODS |
217
|
|
|
|
|
|
|
|
218
|
|
|
|
|
|
|
LINQ::Iterator supports all the methods defined in L<LINQ::Collection>. |
219
|
|
|
|
|
|
|
|
220
|
|
|
|
|
|
|
=begin trustme |
221
|
|
|
|
|
|
|
|
222
|
|
|
|
|
|
|
=item new |
223
|
|
|
|
|
|
|
|
224
|
|
|
|
|
|
|
=item element_at |
225
|
|
|
|
|
|
|
|
226
|
|
|
|
|
|
|
=item to_list |
227
|
|
|
|
|
|
|
|
228
|
|
|
|
|
|
|
=item to_array |
229
|
|
|
|
|
|
|
|
230
|
|
|
|
|
|
|
=item to_iterator |
231
|
|
|
|
|
|
|
|
232
|
|
|
|
|
|
|
=end trustme |
233
|
|
|
|
|
|
|
|
234
|
|
|
|
|
|
|
=head1 BUGS |
235
|
|
|
|
|
|
|
|
236
|
|
|
|
|
|
|
Please report any bugs to |
237
|
|
|
|
|
|
|
L<http://rt.cpan.org/Dist/Display.html?Queue=LINQ>. |
238
|
|
|
|
|
|
|
|
239
|
|
|
|
|
|
|
=head1 SEE ALSO |
240
|
|
|
|
|
|
|
|
241
|
|
|
|
|
|
|
L<LINQ>, L<LINQ::Collection>. |
242
|
|
|
|
|
|
|
|
243
|
|
|
|
|
|
|
L<https://en.wikipedia.org/wiki/Language_Integrated_Query> |
244
|
|
|
|
|
|
|
|
245
|
|
|
|
|
|
|
=head1 AUTHOR |
246
|
|
|
|
|
|
|
|
247
|
|
|
|
|
|
|
Toby Inkster E<lt>tobyink@cpan.orgE<gt>. |
248
|
|
|
|
|
|
|
|
249
|
|
|
|
|
|
|
=head1 COPYRIGHT AND LICENCE |
250
|
|
|
|
|
|
|
|
251
|
|
|
|
|
|
|
This software is copyright (c) 2021 by Toby Inkster. |
252
|
|
|
|
|
|
|
|
253
|
|
|
|
|
|
|
This is free software; you can redistribute it and/or modify it under |
254
|
|
|
|
|
|
|
the same terms as the Perl 5 programming language system itself. |
255
|
|
|
|
|
|
|
|
256
|
|
|
|
|
|
|
=head1 DISCLAIMER OF WARRANTIES |
257
|
|
|
|
|
|
|
|
258
|
|
|
|
|
|
|
THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED |
259
|
|
|
|
|
|
|
WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF |
260
|
|
|
|
|
|
|
MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. |