opConcatAll?
Nick Treleaven
nick at geany.org
Sat Jul 4 12:37:23 UTC 2020
On Friday, 3 July 2020 at 20:27:10 UTC, Steven Schveighoffer
wrote:
> It would be kind of weird/unfortunate for this to support a + b
> + c, but not a + b - c.
>
> We could still do it all with opBinary, as:
>
> opBinary(string[] ops, Args...)(Args args)
>
> And either enforce precedence by reordering the operations
> (like Petar suggests) into RPN, or give up when precedence
> isn't strictly left-to-right. One can always break up the
> operations into subexpressions and sub-calls to opBinary/opNary.
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)`
Concatenation is commutative, but for other operations brackets
would be handled naturally by the compiler:
`s1 * (s2 + s3)` lowers to:
`s1.opBinary!"*"(s2.opBinaryTemp!"+"(s3))`
The following code would support either 1 concatenation, or 2
concatenations being done at once:
struct S {
int[] data;
struct Expr {
S left, right;
// left ~ right ~ rhs
auto opBinary(string op : "~")(S rhs) {
size_t lhsLen = left.data.len + right.data.len;
auto r = new int[lhsLen + rhs.data.len];
r[0..left.data.len] = left.data;
r[left.data.len..$][0..right.data.len] = right.data;
r[lhsLen..$][0..rhs.data.len] = rhs.data;
return r;
}
}
auto opBinaryTemp(string op : "~")(S rhs) {
return Expr(this, right);
}
// this ~ rhs
auto opBinary(string op : "~")(S rhs) {
return S(data ~ rhs.data);
}
}
Maybe this pattern could be extended to work with
arbitrary-length sequences of concatenation. Perhaps it could
also be extended to work with differing `op` kinds.
Although Expr is essentially an expression template, its use is
controlled and the above code doesn't need `alias this`.
More information about the Digitalmars-d
mailing list