Language Idea #6892: in array ops, enable mixing slices and random access ranges
Simen Kjærås
simen.kjaras at gmail.com
Tue Feb 6 09:02:46 UTC 2018
On Tuesday, 6 February 2018 at 02:14:35 UTC, Meta wrote:
>> What do you think?
>
> It's already possible, with only very slightly worse aesthetics:
>
[Good stuff]
We can do better than that, though:
import std.range, std.array, std.algorithm;
struct Vec(Range)
if (isInputRange!Range)
{
Range rng;
this(Range value)
{
rng = value;
}
static if (!isInfinite!Range)
{
auto get()
{
return rng.array;
}
alias get this;
}
auto getRange(R2)(R2 other)
{
static if (isInputRange!R2)
return other;
else static if (isVec!R2)
return other.rng;
else
return repeat(other);
}
auto opBinary(string op, R2)(R2 rhs)
{
return vec(rng.zip(getRange(rhs)).map!("a[0] "~op~"
a[1]"));
}
auto opBinaryRight(string op, R2)(R2 lhs)
{
return vec(getRange(lhs).zip(rng).map!("a[0] "~op~"
a[1]"));
}
auto opOpAssign(string op, R2)(R2 rhs)
if (isForwardRange!Range)
{
auto rhsR = getRange(rhs);
auto r = rng.save;
foreach (ref e; r)
{
if (rhsR.empty) break;
mixin("e "~op~"= rhsR.front;");
rhsR.popFront();
}
return this;
}
}
auto vec(Range)(Range r)
if (isInputRange!Range)
{
return Vec!Range(r);
}
enum isVec(T) = is(T == Vec!U, U);
unittest
{
import std.stdio;
auto a = [1,2,3,4,5,6,7,8];
auto b = a.length.iota;
auto c = recurrence!("a[n-1] + a[n-2]")(1, 1);
uint[] result = a + b * c.vec;
writeln(result);
result.vec += result;
}
--
Simen
More information about the Digitalmars-d
mailing list