Skip to content

Commit

Permalink
Streamline Range.pick/roll in light of degenerate Ranges
Browse files Browse the repository at this point in the history
Such as NaN..NaN or Inf..0 and stuff like that.  Any Range that cannot
determine its number of elements, will always return Nil for .pick/.roll
or an empty Seq for .pick(N)/.roll(N).  This makes the behaviour consistent
with Ranges that do not contain any elements, such as 0..^0.
  • Loading branch information
lizmat committed Dec 26, 2017
1 parent 893d09f commit 5c22833
Showing 1 changed file with 21 additions and 13 deletions.
34 changes: 21 additions & 13 deletions src/core/Range.pm
Expand Up @@ -500,19 +500,23 @@ my class Range is Cool does Iterable does Positional {
!! self.list.roll(*)
}
else {
Nil xx *
Seq.new(Rakudo::Iterator.Empty)
}
}
multi method roll(Range:D:) {
if $!is-int {
my $elems = $!max - $!excludes-max - $!min - $!excludes-min + 1;
$elems > 0
?? $!min + $!excludes-min + nqp::rand_I(nqp::decont($elems),Int)
!! Nil
}
else {
self.list.roll
}
nqp::if(
$!is-int,
nqp::if(
(my $elems := $!max - $!excludes-max - $!min - $!excludes-min+1) > 0,
$!min + $!excludes-min + nqp::rand_I($elems,Int),
Nil
),
nqp::if(
self.elems,
self.list.roll,
Nil
)
)
}
multi method roll(Int(Cool) $todo) {
if self.elems -> $elems {
Expand Down Expand Up @@ -541,13 +545,17 @@ my class Range is Cool does Iterable does Positional {
!! self.list.roll($todo)
}
else {
Nil xx $todo
Seq.new(Rakudo::Iterator.Empty)
}
}

proto method pick(|) {*}
multi method pick() { self.roll };
multi method pick(Whatever) { self.list.pick(*) };
multi method pick(Whatever) {
self.elems
?? self.list.pick(*)
!! Seq.new(Rakudo::Iterator.Empty)
}
multi method pick(Int(Cool) $todo) {
if self.elems -> $elems {
$!is-int && $elems > 3 * $todo # heuristic for sparse lookup
Expand Down Expand Up @@ -596,7 +604,7 @@ my class Range is Cool does Iterable does Positional {
!! self.list.pick($todo)
}
else {
Nil xx $todo
Seq.new(Rakudo::Iterator.Empty)
}
}

Expand Down

0 comments on commit 5c22833

Please sign in to comment.