how to achieve C's Token Pasting (##) Operator to generate variable name in D?

mw mingwu at gmail.com
Sat May 30 23:39:31 UTC 2020


On Saturday, 30 May 2020 at 22:21:14 UTC, Paul Backus wrote:
> enum f(string x) = "_" ~ x;
>
> int main() {
>   mixin("int ", f!"x", " = 3;");
>   return _x;
> }
>
> This uses a templated [1] manifest constant [2] to generate the 
> variable name at compile time, and a mixin statement [3] to 
> insert the definition of `_x` into the program.
>
> [1] https://dlang.org/spec/template.html#variable-template
> [2] https://dlang.org/spec/enum.html#manifest_constants
> [3] https://dlang.org/spec/statement.html#mixin-statement


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"));
}

$ dmd -unittest -vcg-ast -c b.d
$ head -n 24 b.d.cg
import object;
import std.format;
enum RW(string T, string name) = format("\x0a    private %1$s 
_%2$s;\x0a    public  %1$s  %2$s()        {return _%2$s;}\x0a    
public  auto  %2$s(%1$s v)  {_%2$s = v;  return this;}\x0a  ", T, 
name);
class Point : Object
{
         mixin(RW!("int", "x")
         {
                 enum string RW = ['\x0a', ' ', ' ', ' ', ' ', 
'p', 'r', 'i', 'v', 'a', 't', 'e', ' ', 'i', 'n', 't', ' ', '_', 
'x', ';', '\x0a', ' ', ' ', ' ', ' ', 'p', 'u', 'b', 'l', 'i', 
'c', ' ', ' ', 'i', 'n', 't', ' ', ' ', 'x', '(', ')', ' ', ' ', 
' ', ' ', ' ', ' ', ' ', ' ', '{', 'r', 'e', 't', 'u', 'r', 'n', 
' ', '_', 'x', ';', '}', '\x0a', ' ', ' ', ' ', ' ', 'p', 'u', 
'b', 'l', 'i', 'c', ' ', ' ', 'a', 'u', 't', 'o', ' ', ' ', 'x', 
'(', 'i', 'n', 't', ' ', 'v', ')', ' ', ' ', '{', '_', 'x', ' ', 
'=', ' ', 'v', ';', ' ', ' ', 'r', 'e', 't', 'u', 'r', 'n', ' ', 
't', 'h', 'i', 's', ';', '}', '\x0a', ' ', ' '];

         }
         );
         mixin(RW!("double", "y")
         {
                 enum string RW = ['\x0a', ' ', ' ', ' ', ' ', 
'p', 'r', 'i', 'v', 'a', 't', 'e', ' ', 'd', 'o', 'u', 'b', 'l', 
'e', ' ', '_', 'y', ';', '\x0a', ' ', ' ', ' ', ' ', 'p', 'u', 
'b', 'l', 'i', 'c', ' ', ' ', 'd', 'o', 'u', 'b', 'l', 'e', ' ', 
' ', 'y', '(', ')', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '{', 
'r', 'e', 't', 'u', 'r', 'n', ' ', '_', 'y', ';', '}', '\x0a', ' 
', ' ', ' ', ' ', 'p', 'u', 'b', 'l', 'i', 'c', ' ', ' ', 'a', 
'u', 't', 'o', ' ', ' ', 'y', '(', 'd', 'o', 'u', 'b', 'l', 'e', 
' ', 'v', ')', ' ', ' ', '{', '_', 'y', ' ', '=', ' ', 'v', ';', 
' ', ' ', 'r', 'e', 't', 'u', 'r', 'n', ' ', 't', 'h', 'i', 's', 
';', '}', '\x0a', ' ', ' '];

         }
         );
         mixin(RW!("string", "z")
         {
                 enum string RW = ['\x0a', ' ', ' ', ' ', ' ', 
'p', 'r', 'i', 'v', 'a', 't', 'e', ' ', 's', 't', 'r', 'i', 'n', 
'g', ' ', '_', 'z', ';', '\x0a', ' ', ' ', ' ', ' ', 'p', 'u', 
'b', 'l', 'i', 'c', ' ', ' ', 's', 't', 'r', 'i', 'n', 'g', ' ', 
' ', 'z', '(', ')', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '{', 
'r', 'e', 't', 'u', 'r', 'n', ' ', '_', 'z', ';', '}', '\x0a', ' 
', ' ', ' ', ' ', 'p', 'u', 'b', 'l', 'i', 'c', ' ', ' ', 'a', 
'u', 't', 'o', ' ', ' ', 'z', '(', 's', 't', 'r', 'i', 'n', 'g', 
' ', 'v', ')', ' ', ' ', '{', '_', 'z', ' ', '=', ' ', 'v', ';', 
' ', ' ', 'r', 'e', 't', 'u', 'r', 'n', ' ', 't', 'h', 'i', 's', 
';', '}', '\x0a', ' ', ' '];

         }
         );
}
--------------------------------------------------------------------------------


Am I doing the right thing in D? any improvement you'd suggest?

e.g. I don't quite like have to put the type and var name in the 
quotes as string:

   mixin(RW!("int",     "x"));

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.



More information about the Digitalmars-d-learn mailing list