how to achieve C's Token Pasting (##) Operator to generate variable name in D?
Paul Backus
snarwin at gmail.com
Sun May 31 00:46:09 UTC 2020
On Saturday, 30 May 2020 at 23:39:31 UTC, mw wrote:
>
> Thank you all for the reply.
>
> I hate to write boilerplate code:
>
> class Point {
> private int _x;
> public int x() {return _x;}
> public Point x(int v) {_x=v; return this;}
>
> ...
> // ... y, z
> }
>
>
> this is what I've got:
> $ cat b.d
> --------------------------------------------------------------------------------
> // dmd -unittest -vcg-ast -c b.d
> import std.format;
>
>
> enum RW(string T, string name) =
> format(q{
> private %1$s _%2$s;
> public %1$s %2$s() {return _%2$s;}
> public auto %2$s(%1$s v) {_%2$s = v; return this;}
> }, T, name);
>
>
> class Point {
> mixin(RW!("int", "x"));
> mixin(RW!("double", "y"));
> mixin(RW!("string", "z"));
> }
[...]
> Is there a better way to achieve this? esp. for the type `int`,
> is there any way I don't have to quote it as string?
>
> Thanks.
You can simplify this considerably using a mixin template [1]:
---
mixin template RW(T, string name) {
private T var;
public T get() { return var; }
public typeof(this) set(T val) { var = val; return this; }
mixin("private alias _", name, " = var;");
// two aliases with the same name create an overload set
mixin("public alias ", name, " = get;");
mixin("public alias ", name, " = set;");
}
class Point {
mixin RW!(int, "x");
mixin RW!(int, "y");
// etc.
}
---
You still need string mixins to make the names work, but the rest
can be done without them. Large string mixins tend to be
error-prone and difficult to debug, so it's usually a good idea
to make them as small as you reasonably can [2].
[1] https://dlang.org/spec/template-mixin.html
[2] http://www.arsdnet.net/this-week-in-d/2016-feb-21.html
More information about the Digitalmars-d-learn
mailing list