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