Splitting this from the colour thread(https://forum.dlang.org/thread/mailman.961.1475765646.2994.digitalmar...@puremagic.com?page=1).

So currently D does not have a way to express batch operations that work seamlessly with normal ranges.

Manu suggested to use the array operation syntax. I suggest something along the lines of the following, forwarding any operations to the static array.

struct InBatchesOfN(size_t N,R) if( N!=0 && isInputRange!R
&& hasLength!R)
{
    R r;
    static struct Batch
    {
        ElementType!(R)[N] elements;
        auto get() { return elements[]; }
        alias get this;
Batch opBinary(string op)(Batch rhs) if(hasOperator!(ElementType!(R),op))
        {
            Batch b;
foreach(i; iota(N)) mixin("b.elements[i] = elememts[i] "~op~" rhs.elements[i]");
            return b;
        }
        //repeat for opUnary,opOpAssign,opDispatch etc...
    }
    Batch batch;
    this(R _r)
    {
// could have overloads where undefined elements == ElementType!(R).init
        assert(_r.length % N ==0);
        r = _r;
        foreach( i; iota(N))
        {
            batch[i] = r.front;
            r.popFront;
        }
    }
    bool empty() { return r.empty; }
    auto front() { return batch; }
    void popFront()
    {
        foreach(i; iota(N))
        {
            batch.elements[i] = r.front;
            r.popFront;
        }
    }
}

auto inBatchesOf(size_t N,R)(R r)
{
    return InBatchesOfN(r);
}

Thoughts?

Reply via email to