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

Reply via email to