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);
}



Reply via email to