On 10/11/2016 10:28 AM, TheFlyingFiddle wrote:
On Tuesday, 11 October 2016 at 15:46:20 UTC, orip wrote:
On Tuesday, 11 October 2016 at 13:06:37 UTC, pineapple wrote:
Rewrite `return chain(ints[0..5], ints[8..$]);` as `return ints[0..5]
~ ints[8..$];`
The `chain` function doesn't return an array, it returns a
lazily-evaluated sequence of an entirely different type from `int[]`.
Of course it does! I would like the function to return an "input range
of int", no matter which one specifically. Is this possible?
It is, but you will have to use an interface / class to achieve this
behavior (or use some sort of polymorphic struct). Something like this
will do the trick:
import std.range;
import std.stdio;
interface IInputRange(T)
{
bool empty();
T front();
void popFront();
}
final class InputRange(Range) if(isInputRange!Range)
: IInputRange!(ElementType!Range)
{
Range r;
this(Range r)
{
this.r = r;
}
bool empty() { return r.empty; }
ElementType!Range front() { return r.front; }
void popFront() { r.popFront; }
}
auto inputRange(Range)(Range r)
{
return new InputRange!Range(r);
}
IInputRange!int foo(int[] ints)
{
import std.range;
if(ints.length > 10) {
return inputRange(chain(ints[0 .. 5], ints[8 .. $]));
} else {
return inputRange(ints);
}
}
void main()
{
auto ir = foo([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]);
auto ir2 = foo([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
writeln(ir);
writeln(ir2);
}
Those interfaces already exist in Phobos: :)
https://dlang.org/phobos/std_range_interfaces.html
auto foo(int[] ints) {
import std.range;
if (ints.length > 10) {
return
cast(RandomAccessFinite!int)inputRangeObject(chain(ints[0..5], ints[8..$]));
} else {
return cast(RandomAccessFinite!int)inputRangeObject(ints);
}
}
void main() {
import std.stdio;
import std.range;
import std.algorithm;
writeln(foo([1, 2, 3]));
writeln(foo(iota(20).array));
}
Ali