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