| Filename | /home/ss5/perl5/perlbrew/perls/tapper-perl/lib/site_perl/5.16.3/Iterator/Util.pm |
| Statements | Executed 124 statements in 1.44ms |
| Calls | P | F | Exclusive Time |
Inclusive Time |
Subroutine |
|---|---|---|---|---|---|
| 1 | 1 | 1 | 655µs | 749µs | Iterator::Util::BEGIN@20 |
| 1 | 1 | 1 | 644µs | 7.59ms | Iterator::Util::BEGIN@28 |
| 17 | 2 | 1 | 185µs | 4.44ms | Iterator::Util::__ANON__[:52] |
| 4 | 1 | 1 | 57µs | 1.34ms | Iterator::Util::imap |
| 4 | 1 | 1 | 51µs | 216µs | Iterator::Util::iarray |
| 17 | 2 | 1 | 40µs | 2.32ms | Iterator::Util::__ANON__[:158] |
| 1 | 1 | 1 | 12µs | 22µs | Data::DPath::Context::BEGIN@15.4 |
| 1 | 1 | 1 | 9µs | 18µs | Iterator::Util::BEGIN@370 |
| 1 | 1 | 1 | 8µs | 18µs | Iterator::Util::BEGIN@284 |
| 1 | 1 | 1 | 7µs | 10µs | Data::DPath::Context::BEGIN@16.5 |
| 1 | 1 | 1 | 7µs | 40µs | Iterator::Util::BEGIN@21 |
| 1 | 1 | 1 | 7µs | 16µs | Iterator::Util::BEGIN@373 |
| 0 | 0 | 0 | 0s | 0s | Iterator::Util::__ANON__[:114] |
| 0 | 0 | 0 | 0s | 0s | Iterator::Util::__ANON__[:133] |
| 0 | 0 | 0 | 0s | 0s | Iterator::Util::__ANON__[:199] |
| 0 | 0 | 0 | 0s | 0s | Iterator::Util::__ANON__[:241] |
| 0 | 0 | 0 | 0s | 0s | Iterator::Util::__ANON__[:293] |
| 0 | 0 | 0 | 0s | 0s | Iterator::Util::__ANON__[:398] |
| 0 | 0 | 0 | 0s | 0s | Iterator::Util::__ANON__[:399] |
| 0 | 0 | 0 | 0s | 0s | Iterator::Util::__ANON__[:434] |
| 0 | 0 | 0 | 0s | 0s | Iterator::Util::__ANON__[:81] |
| 0 | 0 | 0 | 0s | 0s | Iterator::Util::iappend |
| 0 | 0 | 0 | 0s | 0s | Iterator::Util::igrep |
| 0 | 0 | 0 | 0s | 0s | Iterator::Util::ihead |
| 0 | 0 | 0 | 0s | 0s | Iterator::Util::ilist |
| 0 | 0 | 0 | 0s | 0s | Iterator::Util::ipairwise |
| 0 | 0 | 0 | 0s | 0s | Iterator::Util::irange |
| 0 | 0 | 0 | 0s | 0s | Iterator::Util::iskip |
| 0 | 0 | 0 | 0s | 0s | Iterator::Util::iskip_until |
| 0 | 0 | 0 | 0s | 0s | Iterator::Util::iuniq |
| Line | State ments |
Time on line |
Calls | Time in subs |
Code |
|---|---|---|---|---|---|
| 1 | =for gpg | ||||
| 2 | -----BEGIN PGP SIGNED MESSAGE----- | ||||
| 3 | Hash: SHA1 | ||||
| 4 | |||||
| 5 | =head1 NAME | ||||
| 6 | |||||
| 7 | Iterator::Util - Essential utilities for the Iterator class. | ||||
| 8 | |||||
| 9 | =head1 VERSION | ||||
| 10 | |||||
| 11 | This documentation describes version 0.02 of Iterator::Util, August 23, 2005. | ||||
| 12 | |||||
| 13 | =cut | ||||
| 14 | |||||
| 15 | 2 | 18µs | 2 | 32µs | # spent 22µs (12+10) within Data::DPath::Context::BEGIN@15.4 which was called:
# once (12µs+10µs) by Data::DPath::Context::BEGIN@19 at line 15 # spent 22µs making 1 call to Data::DPath::Context::BEGIN@15.4
# spent 10µs making 1 call to strict::import |
| 16 | 2 | 30µs | 2 | 13µs | # spent 10µs (7+3) within Data::DPath::Context::BEGIN@16.5 which was called:
# once (7µs+3µs) by Data::DPath::Context::BEGIN@19 at line 16 # spent 10µs making 1 call to Data::DPath::Context::BEGIN@16.5
# spent 3µs making 1 call to warnings::import |
| 17 | package Iterator::Util; | ||||
| 18 | 1 | 700ns | our $VERSION = '0.02'; | ||
| 19 | |||||
| 20 | 2 | 74µs | 2 | 804µs | # spent 749µs (655+94) within Iterator::Util::BEGIN@20 which was called:
# once (655µs+94µs) by Data::DPath::Context::BEGIN@19 at line 20 # spent 749µs making 1 call to Iterator::Util::BEGIN@20
# spent 55µs making 1 call to base::import |
| 21 | 2 | 38µs | 2 | 73µs | # spent 40µs (7+33) within Iterator::Util::BEGIN@21 which was called:
# once (7µs+33µs) by Data::DPath::Context::BEGIN@19 at line 21 # spent 40µs making 1 call to Iterator::Util::BEGIN@21
# spent 33µs making 1 call to vars::import |
| 22 | |||||
| 23 | 1 | 3µs | @EXPORT = qw(imap igrep irange ilist iarray ihead iappend | ||
| 24 | ipairwise iskip iskip_until imesh izip iuniq); | ||||
| 25 | |||||
| 26 | 1 | 1µs | @EXPORT_OK = (@EXPORT); | ||
| 27 | |||||
| 28 | 2 | 579µs | 1 | 7.59ms | # spent 7.59ms (644µs+6.94) within Iterator::Util::BEGIN@28 which was called:
# once (644µs+6.94ms) by Data::DPath::Context::BEGIN@19 at line 28 # spent 7.59ms making 1 call to Iterator::Util::BEGIN@28 |
| 29 | |||||
| 30 | # Function name: imap | ||||
| 31 | # Synopsis: $iter = imap {code} $another_iterator; | ||||
| 32 | # Description: Transforms an iterator. | ||||
| 33 | # Created: 07/27/2005 by EJR | ||||
| 34 | # Parameters: code - Transformation code | ||||
| 35 | # $another_iterator - any other iterator. | ||||
| 36 | # Returns: Transformed iterator. | ||||
| 37 | # Exceptions: Iterator::X::Parameter_Error | ||||
| 38 | # Iterator::X::Am_Now_Exhausted | ||||
| 39 | sub imap (&$) | ||||
| 40 | # spent 1.34ms (57µs+1.29) within Iterator::Util::imap which was called 4 times, avg 336µs/call:
# 4 times (57µs+1.29ms) by Data::DPath::Context::_iter at line 411 of Data/DPath/Context.pm, avg 336µs/call | ||||
| 41 | 4 | 4µs | my ($transformation, $iter) = @_; | ||
| 42 | |||||
| 43 | 4 | 22µs | 4 | 6µs | Iterator::X::Parameter_Error->throw(q{Argument to imap must be an Iterator object}) # spent 6µs making 4 calls to UNIVERSAL::isa, avg 2µs/call |
| 44 | unless UNIVERSAL::isa($iter, 'Iterator'); | ||||
| 45 | |||||
| 46 | return Iterator->new( sub | ||||
| 47 | # spent 4.44ms (185µs+4.25) within Iterator::Util::__ANON__[/home/ss5/perl5/perlbrew/perls/tapper-perl/lib/site_perl/5.16.3/Iterator/Util.pm:52] which was called 17 times, avg 261µs/call:
# 13 times (126µs+3.14ms) by Iterator::value at line 227 of Iterator.pm, avg 251µs/call
# 4 times (58µs+1.11ms) by Iterator::_initialize at line 168 of Iterator.pm, avg 293µs/call | ||||
| 48 | 17 | 29µs | 21 | 1.58ms | Iterator::is_done if ($iter->is_exhausted); # spent 1.54ms making 4 calls to Iterator::is_done, avg 386µs/call
# spent 32µs making 17 calls to Iterator::is_exhausted, avg 2µs/call |
| 49 | |||||
| 50 | 13 | 26µs | 13 | 1.07ms | local $_ = $iter->value (); # spent 2.60ms making 13 calls to Iterator::value, avg 200µs/call, recursion: max depth 1, sum of overlapping time 1.52ms |
| 51 | 13 | 58µs | 13 | 79µs | return $transformation-> (); # spent 79µs making 13 calls to Data::DPath::Context::__ANON__[Data/DPath/Context.pm:411], avg 6µs/call |
| 52 | 4 | 34µs | 4 | 1.28ms | }); # spent 1.28ms making 4 calls to Iterator::new, avg 320µs/call |
| 53 | } | ||||
| 54 | |||||
| 55 | |||||
| 56 | # Function name: igrep | ||||
| 57 | # Synopsis: $iter = igrep {code} $another_iterator; | ||||
| 58 | # Description: Filters an iterator. | ||||
| 59 | # Created: 07/27/2005 by EJR | ||||
| 60 | # Parameters: code - Filter condition. | ||||
| 61 | # $another_iterator - any other iterator. | ||||
| 62 | # Returns: Filtered iterator. | ||||
| 63 | # Exceptions: Iterator::X::Parameter_Error | ||||
| 64 | # Iterator::X::Am_Now_Exhausted | ||||
| 65 | sub igrep (&$) | ||||
| 66 | { | ||||
| 67 | my ($test, $iter) = @_; | ||||
| 68 | |||||
| 69 | Iterator::X::Parameter_Error->throw(q{Argument to imap must be an Iterator object}) | ||||
| 70 | unless UNIVERSAL::isa($iter, 'Iterator'); | ||||
| 71 | |||||
| 72 | return Iterator->new(sub | ||||
| 73 | { | ||||
| 74 | while ($iter->isnt_exhausted ()) | ||||
| 75 | { | ||||
| 76 | local $_ = $iter->value (); | ||||
| 77 | return $_ if $test-> (); | ||||
| 78 | } | ||||
| 79 | |||||
| 80 | Iterator::is_done(); | ||||
| 81 | }); | ||||
| 82 | } | ||||
| 83 | |||||
| 84 | |||||
| 85 | # Function name: irange | ||||
| 86 | # Synopsis: $iter = irange ($start, $end, $step); | ||||
| 87 | # Description: Generates an arithmetic sequence of numbers. | ||||
| 88 | # Created: 07/27/2005 by EJR | ||||
| 89 | # Parameters: $start - First value. | ||||
| 90 | # $end - Final value. (may be omitted) | ||||
| 91 | # $step - Increment value. (may be omitted) | ||||
| 92 | # Returns: Sequence iterator | ||||
| 93 | # Exceptions: Iterator::X::Am_Now_Exhausted | ||||
| 94 | # Notes: If the $end value is omitted, iterator is unbounded. | ||||
| 95 | # If $step is omitted, it defaults to 1. | ||||
| 96 | # $step may be negative (or even zero). | ||||
| 97 | sub irange | ||||
| 98 | { | ||||
| 99 | my ($from, $to, $step) = @_; | ||||
| 100 | $step = 1 unless defined $step; | ||||
| 101 | |||||
| 102 | return Iterator->new (sub | ||||
| 103 | { | ||||
| 104 | # Reached limit? | ||||
| 105 | Iterator::is_done | ||||
| 106 | if (defined($to) | ||||
| 107 | && ($step>0 && $from>$to || $step<0 && $from<$to) ); | ||||
| 108 | |||||
| 109 | # This iteration's return value | ||||
| 110 | my $retval = $from; | ||||
| 111 | |||||
| 112 | $from += $step; | ||||
| 113 | return $retval; | ||||
| 114 | }); | ||||
| 115 | } | ||||
| 116 | |||||
| 117 | # Function name: ilist | ||||
| 118 | # Synopsis: $iter = ilist (@list); | ||||
| 119 | # Description: Creates an iterator from a list | ||||
| 120 | # Created: 07/28/2005 by EJR | ||||
| 121 | # Parameters: @list - list of values to iterate over | ||||
| 122 | # Returns: Array (list) iterator | ||||
| 123 | # Exceptions: Iterator::X::Am_Now_Exhausted | ||||
| 124 | # Notes: Makes an internal copy of the list. | ||||
| 125 | sub ilist | ||||
| 126 | { | ||||
| 127 | my @items = @_; | ||||
| 128 | my $index=0; | ||||
| 129 | return Iterator->new( sub | ||||
| 130 | { | ||||
| 131 | Iterator::is_done if ($index >= @items); | ||||
| 132 | return $items[$index++]; | ||||
| 133 | }); | ||||
| 134 | } | ||||
| 135 | |||||
| 136 | # Function name: iarray | ||||
| 137 | # Synopsis: $iter = iarray ($a_ref); | ||||
| 138 | # Description: Creates an iterator from an array reference | ||||
| 139 | # Created: 07/28/2005 by EJR | ||||
| 140 | # Parameters: $a_ref - Reference to array to iterate over | ||||
| 141 | # Returns: Array iterator | ||||
| 142 | # Exceptions: Iterator::X::Parameter_Error | ||||
| 143 | # Iterator::X::Am_Now_Exhausted | ||||
| 144 | # Notes: Does not make an internal copy of the list. | ||||
| 145 | sub iarray ($) | ||||
| 146 | # spent 216µs (51+165) within Iterator::Util::iarray which was called 4 times, avg 54µs/call:
# 4 times (51µs+165µs) by Data::DPath::Context::_iter at line 410 of Data/DPath/Context.pm, avg 54µs/call | ||||
| 147 | 4 | 2µs | my $items = shift; | ||
| 148 | 4 | 1µs | my $index=0; | ||
| 149 | |||||
| 150 | 4 | 3µs | Iterator::X::Parameter_Error->throw-> | ||
| 151 | (q{Argument to iarray must be an array reference}) | ||||
| 152 | if ref $items ne 'ARRAY'; | ||||
| 153 | |||||
| 154 | return Iterator->new( sub | ||||
| 155 | # spent 2.32ms (40µs+2.28) within Iterator::Util::__ANON__[/home/ss5/perl5/perlbrew/perls/tapper-perl/lib/site_perl/5.16.3/Iterator/Util.pm:158] which was called 17 times, avg 137µs/call:
# 13 times (31µs+2.28ms) by Iterator::value at line 227 of Iterator.pm, avg 178µs/call
# 4 times (10µs+0s) by Iterator::_initialize at line 168 of Iterator.pm, avg 2µs/call | ||||
| 156 | 17 | 11µs | 4 | 2.28ms | Iterator::is_done if $index >= @$items; # spent 2.28ms making 4 calls to Iterator::is_done, avg 571µs/call |
| 157 | 13 | 47µs | return $items->[$index++]; | ||
| 158 | 4 | 42µs | 4 | 165µs | }); # spent 165µs making 4 calls to Iterator::new, avg 41µs/call |
| 159 | } | ||||
| 160 | |||||
| 161 | # Function name: ihead | ||||
| 162 | # Synopsis: $iter = ihead ($num, $some_other_iterator); | ||||
| 163 | # Synopsis: @valuse = ihead ($num, $iterator); | ||||
| 164 | # Description: Returns at most $num items from other iterator. | ||||
| 165 | # Created: 07/28/2005 by EJR | ||||
| 166 | # 08/02/2005 EJR: combined with ahead, per Will Coleda | ||||
| 167 | # Parameters: $num - Max number of items to return | ||||
| 168 | # $some_other_iterator - another iterator | ||||
| 169 | # Returns: limited iterator | ||||
| 170 | # Exceptions: Iterator::X::Parameter_Error | ||||
| 171 | # Iterator::X::Am_Now_Exhausted | ||||
| 172 | sub ihead | ||||
| 173 | { | ||||
| 174 | my $num = shift; | ||||
| 175 | my $iter = shift; | ||||
| 176 | |||||
| 177 | Iterator::X::Parameter_Error->throw | ||||
| 178 | (q{Second parameter for ihead must be an Iterator}) | ||||
| 179 | unless UNIVERSAL::isa($iter, 'Iterator'); | ||||
| 180 | |||||
| 181 | # List context? Return the first $num elements. | ||||
| 182 | if (wantarray) | ||||
| 183 | { | ||||
| 184 | my @a; | ||||
| 185 | while ($iter->isnt_exhausted && (!defined($num) || $num-- > 0)) | ||||
| 186 | { | ||||
| 187 | push @a, $iter->value; | ||||
| 188 | } | ||||
| 189 | return @a; | ||||
| 190 | } | ||||
| 191 | |||||
| 192 | # Scalar context: return an iterator to return at most $num elements. | ||||
| 193 | return Iterator->new(sub | ||||
| 194 | { | ||||
| 195 | Iterator::is_done if $num <= 0; | ||||
| 196 | |||||
| 197 | $num--; | ||||
| 198 | return $iter->value; | ||||
| 199 | }); | ||||
| 200 | } | ||||
| 201 | |||||
| 202 | # Function name: iappend | ||||
| 203 | # Synopsis: $iter = iappend (@iterators); | ||||
| 204 | # Description: Joins a bunch of iterators together. | ||||
| 205 | # Created: 07/28/2005 by EJR | ||||
| 206 | # Parameters: @iterators - any number of other iterators | ||||
| 207 | # Returns: A "merged" iterator. | ||||
| 208 | # Exceptions: Iterator::X::Parameter_Error | ||||
| 209 | # Iterator::X::Am_Now_Exhausted | ||||
| 210 | sub iappend | ||||
| 211 | { | ||||
| 212 | my @its = @_; | ||||
| 213 | |||||
| 214 | # Check types | ||||
| 215 | foreach (@its) | ||||
| 216 | { | ||||
| 217 | Iterator::X::Parameter_Error->throw | ||||
| 218 | (q{All parameters for iarray must be Iterators}) | ||||
| 219 | unless UNIVERSAL::isa($_, 'Iterator'); | ||||
| 220 | } | ||||
| 221 | |||||
| 222 | # Passthru, if there's only one. | ||||
| 223 | return $its[0] if @its == 1; | ||||
| 224 | |||||
| 225 | return Iterator->new (sub | ||||
| 226 | { | ||||
| 227 | my $val; | ||||
| 228 | |||||
| 229 | # Any empty iterators at front of list? Remove'em. | ||||
| 230 | while (@its && $its[0]->is_exhausted) | ||||
| 231 | { | ||||
| 232 | shift @its; | ||||
| 233 | } | ||||
| 234 | |||||
| 235 | # No more iterators? Then we're done. | ||||
| 236 | Iterator::is_done | ||||
| 237 | if @its == 0; | ||||
| 238 | |||||
| 239 | # Return the next value of the iterator at the head of the list. | ||||
| 240 | return $its[0]->value; | ||||
| 241 | }); | ||||
| 242 | } | ||||
| 243 | |||||
| 244 | # Function name: ipairwise | ||||
| 245 | # Synopsis: $iter = ipairwise {code} ($iter1, $iter2); | ||||
| 246 | # Description: Applies an operation to pairs of values from iterators. | ||||
| 247 | # Created: 07/28/2005 by EJR | ||||
| 248 | # Parameters: code - transformation, may use $a and $b | ||||
| 249 | # $iter1 - First iterator; "$a" value. | ||||
| 250 | # $iter2 - First iterator; "$b" value. | ||||
| 251 | # Returns: Iterator | ||||
| 252 | # Exceptions: Iterator::X::Parameter_Error | ||||
| 253 | # Iterator::X::Am_Now_Exhausted | ||||
| 254 | sub ipairwise (&$$) | ||||
| 255 | { | ||||
| 256 | my $op = shift; | ||||
| 257 | my $iterA = shift; | ||||
| 258 | my $iterB = shift; | ||||
| 259 | |||||
| 260 | # Check types | ||||
| 261 | for ($iterA, $iterB) | ||||
| 262 | { | ||||
| 263 | Iterator::X::Parameter_Error->throw | ||||
| 264 | (q{Second and third parameters for ipairwise must be Iterators}) | ||||
| 265 | unless UNIVERSAL::isa($_, 'Iterator'); | ||||
| 266 | } | ||||
| 267 | |||||
| 268 | return Iterator->new(sub | ||||
| 269 | { | ||||
| 270 | Iterator::is_done | ||||
| 271 | if $iterA->is_exhausted || $iterB->is_exhausted; | ||||
| 272 | |||||
| 273 | # Localize $a and $b | ||||
| 274 | # My thanks to Benjamin Goldberg for this little bit of evil. | ||||
| 275 | my ($caller_a, $caller_b) = do | ||||
| 276 | { | ||||
| 277 | my $pkg; | ||||
| 278 | my $i = 1; | ||||
| 279 | while (1) | ||||
| 280 | { | ||||
| 281 | $pkg = caller($i++); | ||||
| 282 | last if $pkg ne 'Iterator' && $pkg ne 'Iterator::Util'; | ||||
| 283 | } | ||||
| 284 | 2 | 196µs | 2 | 28µs | # spent 18µs (8+10) within Iterator::Util::BEGIN@284 which was called:
# once (8µs+10µs) by Data::DPath::Context::BEGIN@19 at line 284 # spent 18µs making 1 call to Iterator::Util::BEGIN@284
# spent 10µs making 1 call to strict::unimport |
| 285 | \*{$pkg.'::a'}, \*{$pkg.'::b'}; | ||||
| 286 | }; | ||||
| 287 | |||||
| 288 | # Set caller's $a and $b | ||||
| 289 | local (*$caller_a, *$caller_b) = \($iterA->value, $iterB->value); | ||||
| 290 | |||||
| 291 | # Invoke caller's operation | ||||
| 292 | return $op->(); | ||||
| 293 | }); | ||||
| 294 | } | ||||
| 295 | |||||
| 296 | # Function name: iskip | ||||
| 297 | # Synopsis: $iter = iskip $num, $another_iterator | ||||
| 298 | # Description: Skips the first $num values of another iterator | ||||
| 299 | # Created: 07/28/2005 by EJR | ||||
| 300 | # Parameters: $num - how many values to skip | ||||
| 301 | # $another_iterator - another iterator | ||||
| 302 | # Returns: Sequence iterator | ||||
| 303 | # Exceptions: None | ||||
| 304 | sub iskip | ||||
| 305 | { | ||||
| 306 | my $num = shift; | ||||
| 307 | my $it = shift; | ||||
| 308 | |||||
| 309 | Iterator::X::Parameter_Error->throw | ||||
| 310 | (q{Second parameter for iskip must be an Iterator}) | ||||
| 311 | unless UNIVERSAL::isa($it, 'Iterator'); | ||||
| 312 | |||||
| 313 | # Discard first $num values | ||||
| 314 | $it->value while $it->isnt_exhausted && $num-->0; | ||||
| 315 | |||||
| 316 | return $it; | ||||
| 317 | } | ||||
| 318 | |||||
| 319 | |||||
| 320 | # Function name: iskip_until | ||||
| 321 | # Synopsis: $iter = iskip_until {code}, $another_iterator | ||||
| 322 | # Description: Skips values of another iterator until {code} is true. | ||||
| 323 | # Created: 07/28/2005 by EJR | ||||
| 324 | # Parameters: {code} - Determines when to start returning values | ||||
| 325 | # $another_iterator - another iterator | ||||
| 326 | # Returns: Sequence iterator | ||||
| 327 | # Exceptions: Iterator::X::Am_Now_Exhausted | ||||
| 328 | sub iskip_until (&$) | ||||
| 329 | { | ||||
| 330 | my $code = shift; | ||||
| 331 | my $iter = shift; | ||||
| 332 | my $value; | ||||
| 333 | my $found_it = 0; | ||||
| 334 | |||||
| 335 | Iterator::X::Parameter_Error->throw | ||||
| 336 | (q{Second parameter for iskip_until must be an Iterator}) | ||||
| 337 | unless UNIVERSAL::isa($iter, 'Iterator'); | ||||
| 338 | |||||
| 339 | # Discard first $num values | ||||
| 340 | while ($iter->isnt_exhausted) | ||||
| 341 | { | ||||
| 342 | local $_ = $iter->value; | ||||
| 343 | if ($code->()) | ||||
| 344 | { | ||||
| 345 | $found_it = 1; | ||||
| 346 | $value = $_; | ||||
| 347 | last; | ||||
| 348 | } | ||||
| 349 | } | ||||
| 350 | |||||
| 351 | # Didn't find it? Pity. | ||||
| 352 | Iterator::is_done | ||||
| 353 | unless $found_it; | ||||
| 354 | |||||
| 355 | # Return an iterator with this value, and all remaining values. | ||||
| 356 | return iappend ilist($value), $iter; | ||||
| 357 | } | ||||
| 358 | |||||
| 359 | |||||
| 360 | # Function name: imesh / izip | ||||
| 361 | # Synopsis: $iter = imesh ($iter1, $iter2, ...) | ||||
| 362 | # Description: Merges other iterators together. | ||||
| 363 | # Created: 07/30/2005 by EJR | ||||
| 364 | # Parameters: Any number of other iterators. | ||||
| 365 | # Returns: Sequence iterator | ||||
| 366 | # Exceptions: Iterator::X::Parameter_Error | ||||
| 367 | # Iterator::X::Am_Now_Exhausted | ||||
| 368 | 1 | 700ns | foreach my $sub (qw/imesh izip/) | ||
| 369 | { | ||||
| 370 | 2 | 28µs | 2 | 26µs | # spent 18µs (9+9) within Iterator::Util::BEGIN@370 which was called:
# once (9µs+9µs) by Data::DPath::Context::BEGIN@19 at line 370 # spent 18µs making 1 call to Iterator::Util::BEGIN@370
# spent 9µs making 1 call to strict::unimport |
| 371 | *$sub = sub | ||||
| 372 | { | ||||
| 373 | 2 | 186µs | 2 | 24µs | # spent 16µs (7+9) within Iterator::Util::BEGIN@373 which was called:
# once (7µs+9µs) by Data::DPath::Context::BEGIN@19 at line 373 # spent 16µs making 1 call to Iterator::Util::BEGIN@373
# spent 9µs making 1 call to strict::import |
| 374 | |||||
| 375 | my @iterators = @_; | ||||
| 376 | my $it_index = 0; | ||||
| 377 | |||||
| 378 | foreach my $iter (@iterators) | ||||
| 379 | { | ||||
| 380 | Iterator::X::Parameter_Error->throw( | ||||
| 381 | "Argument to $sub is not an iterator") | ||||
| 382 | unless UNIVERSAL::isa($iter, 'Iterator'); | ||||
| 383 | } | ||||
| 384 | |||||
| 385 | return Iterator->new (sub | ||||
| 386 | { | ||||
| 387 | Iterator::is_done | ||||
| 388 | if $iterators[$it_index]->is_exhausted(); | ||||
| 389 | |||||
| 390 | my $retval = $iterators[$it_index]->value(); | ||||
| 391 | |||||
| 392 | if (++$it_index >= @iterators) | ||||
| 393 | { | ||||
| 394 | $it_index = 0; | ||||
| 395 | } | ||||
| 396 | |||||
| 397 | return $retval; | ||||
| 398 | }); | ||||
| 399 | 2 | 6µs | }; | ||
| 400 | } | ||||
| 401 | |||||
| 402 | # Function name: iuniq | ||||
| 403 | # Synopsis: $iter = iuniq ($another_iterator); | ||||
| 404 | # Description: Removes duplicate entries from an iterator. | ||||
| 405 | # Created: 07/30/2005 by EJR | ||||
| 406 | # Parameters: Another iterator. | ||||
| 407 | # Returns: Sequence iterator | ||||
| 408 | # Exceptions: Iterator::X::Parameter_Error | ||||
| 409 | # Iterator::X::Am_Now_Exhausted | ||||
| 410 | sub iuniq | ||||
| 411 | { | ||||
| 412 | Iterator::X::Parameter_Error->throw ("Too few parameters to iuniq") | ||||
| 413 | if @_ < 1; | ||||
| 414 | Iterator::X::Parameter_Error->throw ("Too many parameters to iuniq") | ||||
| 415 | if @_ > 1; | ||||
| 416 | |||||
| 417 | my $iter = shift; | ||||
| 418 | Iterator::X::Parameter_Error->throw("Argument to iuniq is not an iterator") | ||||
| 419 | unless UNIVERSAL::isa($iter, 'Iterator'); | ||||
| 420 | |||||
| 421 | my %did_see; | ||||
| 422 | return Iterator->new (sub | ||||
| 423 | { | ||||
| 424 | my $value; | ||||
| 425 | while (1) | ||||
| 426 | { | ||||
| 427 | Iterator::is_done | ||||
| 428 | if $iter->is_exhausted; | ||||
| 429 | |||||
| 430 | $value = $iter->value; | ||||
| 431 | last if !$did_see{$value}++; | ||||
| 432 | } | ||||
| 433 | return $value; | ||||
| 434 | }); | ||||
| 435 | } | ||||
| 436 | |||||
| 437 | 1 | 5µs | 1; | ||
| 438 | __END__ |