Skip to content

Commit

Permalink
Fix Issue 15720 - iota(long.max, long.min, step) does not work properly
Browse files Browse the repository at this point in the history
  • Loading branch information
andralex committed May 16, 2017
1 parent e872190 commit f410f1c
Showing 1 changed file with 45 additions and 40 deletions.
85 changes: 45 additions & 40 deletions std/range/package.d
Expand Up @@ -5217,54 +5217,53 @@ auto sequence(alias fun, State...)(State args)

// iota
/**
Construct a range of values that span the given starting and stopping
values.
Params:
begin = The starting value.
end = The value that serves as the stopping criterion. This value is not
included in the range.
step = The value to add to the current value at each iteration.
Creates a range of values that span the given starting and stopping values.
Returns:
A range that goes through the numbers $(D begin), $(D begin + step),
$(D begin + 2 * step), $(D ...), up to and excluding $(D end).
Params:
begin = The starting value.
end = The value that serves as the stopping criterion. This value is not
included in the range.
step = The value to add to the current value at each iteration.
The two-argument overloads have $(D step = 1). If $(D begin < end && step <
0) or $(D begin > end && step > 0) or $(D begin == end), then an empty range
is returned. If $(D step == 0) then $(D begin == end) is an error.
Returns:
A range that goes through the numbers $(D begin), $(D begin + step), $(D begin +
2 * step), $(D ...), up to and excluding $(D end).
For built-in types, the range returned is a random access range. For
user-defined types that support $(D ++), the range is an input
range.
The two-argument overloads have $(D step = 1). If $(D begin < end && step < 0)
or $(D begin > end && step > 0) or $(D begin == end), then an empty range is
returned. If $(D step == 0) then $(D begin == end) is an error.
Example:
---
void main()
{
import std.stdio;
For built-in types, the range returned is a random access range. For
user-defined types that support $(D ++), the range is an input range.
Example:
---
void main()
{
import std.stdio;
// The following groups all produce the same output of:
// 0 1 2 3 4
// The following groups all produce the same output of:
// 0 1 2 3 4
foreach (i; 0 .. 5)
writef("%s ", i);
writeln();
foreach (i; 0 .. 5)
writef("%s ", i);
writeln();
import std.range : iota;
foreach (i; iota(0, 5))
writef("%s ", i);
writeln();
import std.range : iota;
foreach (i; iota(0, 5)) // alternatively: iota(5)
writef("%s ", i);
writeln();
writefln("%(%s %|%)", iota(0, 5));
writefln("%(%s %|%)", iota(0, 5));
import std.algorithm.iteration : map;
import std.algorithm.mutation : copy;
import std.format;
iota(0, 5).map!(i => format("%s ", i)).copy(stdout.lockingTextWriter());
writeln();
}
---
import std.algorithm.iteration : map;
import std.algorithm.mutation : copy;
import std.format;
iota(0, 5).map!(i => format("%s ", i)).copy(stdout.lockingTextWriter());
writeln();
}
---
*/
auto iota(B, E, S)(B begin, E end, S step)
if ((isIntegral!(CommonType!(B, E)) || isPointer!(CommonType!(B, E)))
Expand Down Expand Up @@ -5354,9 +5353,9 @@ if ((isIntegral!(CommonType!(B, E)) || isPointer!(CommonType!(B, E)))
@property size_t length() const
{
if (step > 0)
return 1 + cast(size_t) ((last - current) / step);
return 1 + cast(size_t) (unsigned(last - current) / step);
if (step < 0)
return 1 + cast(size_t) ((current - last) / -step);
return 1 + cast(size_t) (unsigned(current - last) / -step);
return 0;
}

Expand Down Expand Up @@ -5553,6 +5552,12 @@ nothrow @nogc @safe unittest
auto t1 = iota(0, 10, 2);
auto t2 = iota(1, 1, 0);
//float overloads use std.conv.to so can't be @nogc or nothrow
alias ssize_t = Unsigned!size_t;
assert(iota(ssize_t.max, 0, -1).length == ssize_t.max);
assert(iota(ssize_t.max, ssize_t.min, -1).length == size_t.max);
assert(iota(ssize_t.max, ssize_t.min, -2).length == 1 + size_t.max / 2);
assert(iota(ssize_t.min, ssize_t.max, 2).length == 1 + size_t.max / 2);
assert(iota(ssize_t.max, ssize_t.min, -3).length == size_t.max / 3);
}

debug @system unittest
Expand Down

0 comments on commit f410f1c

Please sign in to comment.