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