Expression template

ag0aep6g via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Sat Jul 23 16:55:44 PDT 2016


On 07/23/2016 01:05 PM, Etranger wrote:
> 1- Is there a cleaner way to do it ? I had to use struct because I want
> every thing to happen at compile time and on the stack (without gc). And
> I had to use string mixins because template mixin does not work the way
> I tried to use it ( see the error last line).

To avoid the string mixin, you can let VecExpression take an alias of 
the mixin template (Vec_impl/VecSum_impl) and the list of arguments:

----
struct VecExpression(alias mixinTemplate, mixinArgs ...)
{
   mixin mixinTemplate!mixinArgs;
   VecSum!(typeof(this), VecExpression!RHS) opBinary
     (string op, RHS ...)(ref VecExpression!RHS rhs)
   {
     /* ... */
   }
}
/* ... */
alias Vec(int n) = VecExpression!(Vec_impl, n);
/* ... */
alias VecSum(E1, E2) = VecExpression!(VecSum_impl, E1, E2);
----


Instead of mixing the fields into VecExpression, you could mix opBinary 
into distinct Vec/VecSum structs:

----
mixin template opBinaryMixin()
{
   VecSum!(typeof(this), RHS) opBinary(string op, RHS)(ref RHS rhs)
   {
     static if (op == "+") return typeof(return)(&this, &rhs);
   }
}

struct Vec(int n)
{
   double[n] elems;

   /* ... */

   mixin opBinaryMixin!();
}

struct VecSum(E1, E2)
{
   E1 * e1;
   E2 * e2;

   /* ... */

   mixin opBinaryMixin!();
}
----

A bit of type strictness is lost here, since opBinary accepts anything, 
not just Vec/VecSum. If that strictness is needed, you could check 
specifically for Vec/VecSum, or maybe mix in a little identifier along 
with opBinary and check for that.


You can also try std.typecons.scoped [1] to put classes on the stack. 
That would get around any kind of mixin.


[1] https://dlang.org/phobos/std_typecons.html#.scoped


More information about the Digitalmars-d-learn mailing list