opConcatAll?
Nick Treleaven
nick at geany.org
Sun Jul 5 10:26:05 UTC 2020
On Saturday, 4 July 2020 at 12:37:23 UTC, Nick Treleaven wrote:
> What if the compiler calls opBinaryTemp when it detects an
> expression that would be used in another opBinary call? Given:
>
> S s1, s2, s3;
>
> `s1 ~ s2 ~ s3` would be lowered to:
> `s1.opBinaryTemp!"~"(s2).opBinary!"~"(s3)`
The lowering actually compiles now:
https://github.com/ntrel/stuff/tree/master/optemp
> Maybe this pattern could be extended to work with
> arbitrary-length sequences of concatenation.
From the above link:
struct S {
int[] data;
static struct Expr(T...)
{
T items;
static foreach (E; T)
static assert(is(E == S));
// concat(items) ~ rhs
S opBinary(string op : "~")(S rhs) {
auto len = rhs.data.length;
foreach (s; items)
len += s.data.length;
auto r = new int[len];
size_t i;
foreach (s; items) {
r[i..$][0..s.data.length] = s.data;
i += s.data.length;
}
r[i..$] = rhs.data;
return S(r);
}
auto opBinaryTemp(string op : "~")(S rhs) {
return expr(items, rhs);
}
}
private static expr(T...)(T args) {
return Expr!T(args);
}
auto opBinaryTemp(string op : "~")(S rhs) {
return expr(this, rhs);
}
// this ~ rhs
S opBinary(string op : "~")(S rhs) {
return expr(this) ~ rhs;
}
}
void main()
{
import std.stdio;
auto s1 = S([1,10]);
auto s2 = S([2,22]);
auto s3 = S([3,-3]);
//s1 ~ s2
s1.opBinary!"~"(s2).data.writeln;
//s1 ~ s2 ~ s3
s1.opBinaryTemp!"~"(s2).opBinary!"~"(s3).data.writeln;
//s1 ~ s2 ~ s3 ~ s1
s1.opBinaryTemp!"~"(s2).opBinaryTemp!"~"(s3).opBinary!"~"(s1).data.writeln;
}
More information about the Digitalmars-d
mailing list