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