www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Capture parameter identifier name in a template?

reply "Maxime Chevalier-Boisvert" <maximechevalierb gmail.com> writes:
In my JavaScript VM, I have a function whose purpose is to expose 
D/host constants to the JavaScript runtime code running inside 
the VM. This makes for somewhat redundant code, as follows:

vm.defRTConst("OBJ_MIN_CAP"w, OBJ_MIN_CAP);
vm.defRTConst("PROTO_SLOT_IDX"w, PROTO_SLOT_IDX);
vm.defRTConst("FPTR_SLOT_IDX"w, FPTR_SLOT_IDX);
vm.defRTConst("ATTR_CONFIGURABLE"w  , ATTR_CONFIGURABLE);
vm.defRTConst("ATTR_WRITABLE"w      , ATTR_WRITABLE);
vm.defRTConst("ATTR_ENUMERABLE"w    , ATTR_ENUMERABLE);
vm.defRTConst("ATTR_DELETED"w       , ATTR_DELETED);
vm.defRTConst("ATTR_GETSET"w        , ATTR_GETSET);
vm.defRTConst("ATTR_DEFAULT"w       , ATTR_DEFAULT);

I'm just wondering if there's a way to template defRTConst so 
that the name of an identifier I'm passing (e.g.: ATTR_DEFAULT) 
can be captured by the template, making it so that I don't also 
need to pass the name as a string. I expect the answer to be no, 
but maybe someone with more knowledge of D template magic knows 
better.
Aug 12 2014
next sibling parent ketmar via Digitalmars-d-learn <digitalmars-d-learn puremagic.com> writes:
On Tue, 12 Aug 2014 17:36:40 +0000
Maxime Chevalier-Boisvert via Digitalmars-d-learn
<digitalmars-d-learn puremagic.com> wrote:

 I'm just wondering if there's a way to template defRTConst so=20
 that the name of an identifier I'm passing (e.g.: ATTR_DEFAULT)
seems that this is the work for mixins.
Aug 12 2014
prev sibling next sibling parent "H. S. Teoh via Digitalmars-d-learn" <digitalmars-d-learn puremagic.com> writes:
On Tue, Aug 12, 2014 at 05:36:40PM +0000, Maxime Chevalier-Boisvert via
Digitalmars-d-learn wrote:
 In my JavaScript VM, I have a function whose purpose is to expose
 D/host constants to the JavaScript runtime code running inside the VM.
 This makes for somewhat redundant code, as follows:
 
 vm.defRTConst("OBJ_MIN_CAP"w, OBJ_MIN_CAP);
 vm.defRTConst("PROTO_SLOT_IDX"w, PROTO_SLOT_IDX);
 vm.defRTConst("FPTR_SLOT_IDX"w, FPTR_SLOT_IDX);
 vm.defRTConst("ATTR_CONFIGURABLE"w  , ATTR_CONFIGURABLE);
 vm.defRTConst("ATTR_WRITABLE"w      , ATTR_WRITABLE);
 vm.defRTConst("ATTR_ENUMERABLE"w    , ATTR_ENUMERABLE);
 vm.defRTConst("ATTR_DELETED"w       , ATTR_DELETED);
 vm.defRTConst("ATTR_GETSET"w        , ATTR_GETSET);
 vm.defRTConst("ATTR_DEFAULT"w       , ATTR_DEFAULT);
 
 I'm just wondering if there's a way to template defRTConst so that the
 name of an identifier I'm passing (e.g.: ATTR_DEFAULT) can be captured
 by the template, making it so that I don't also need to pass the name
 as a string.  I expect the answer to be no, but maybe someone with
 more knowledge of D template magic knows better.
I know it's possible to get function (runtime) parameter names using __traits(), but I'm not sure if that can be done for compile-time parameters. See: std.traits.ParameterIdentifierTuple. T -- It said to install Windows 2000 or better, so I installed Linux instead.
Aug 12 2014
prev sibling next sibling parent "Dicebot" <public dicebot.lv> writes:
On Tuesday, 12 August 2014 at 17:36:41 UTC, Maxime 
Chevalier-Boisvert wrote:
 In my JavaScript VM, I have a function whose purpose is to 
 expose D/host constants to the JavaScript runtime code running 
 inside the VM. This makes for somewhat redundant code, as 
 follows:

 vm.defRTConst("OBJ_MIN_CAP"w, OBJ_MIN_CAP);
 vm.defRTConst("PROTO_SLOT_IDX"w, PROTO_SLOT_IDX);
 vm.defRTConst("FPTR_SLOT_IDX"w, FPTR_SLOT_IDX);
 vm.defRTConst("ATTR_CONFIGURABLE"w  , ATTR_CONFIGURABLE);
 vm.defRTConst("ATTR_WRITABLE"w      , ATTR_WRITABLE);
 vm.defRTConst("ATTR_ENUMERABLE"w    , ATTR_ENUMERABLE);
 vm.defRTConst("ATTR_DELETED"w       , ATTR_DELETED);
 vm.defRTConst("ATTR_GETSET"w        , ATTR_GETSET);
 vm.defRTConst("ATTR_DEFAULT"w       , ATTR_DEFAULT);

 I'm just wondering if there's a way to template defRTConst so 
 that the name of an identifier I'm passing (e.g.: ATTR_DEFAULT) 
 can be captured by the template, making it so that I don't also 
 need to pass the name as a string. I expect the answer to be 
 no, but maybe someone with more knowledge of D template magic 
 knows better.
Something like this? enum ATTRS { ATTR_GETSET, ATTR_ENUMERABLE, ATTR_CONFIGURABLE } void foo(ATTRS attr) { import std.conv; foo_impl(attr, to!string(attr)); } void foo_impl(ATTRS attr, string name) { import std.stdio; writefln("name = %s, attr = %d", name, attr); } void main() { foo(ATTRS.ATTR_GETSET); }
Aug 12 2014
prev sibling parent reply =?UTF-8?B?UsOpbXkgTW91w6t6YQ==?= <remy.moueza gmail.com> writes:
Using __traits (identifier, ...) and a template alias seems to work for me:

import std.stdio;

/// Two kinds of enums:

/// A named enum.
enum VmParams {
     OBJ_MIN_CAP,
     PROTO_SLOT_IDX,
     FPTR_SLOT_IDX,
}

/// An anonymous one.
enum {
     ATTR_CONFIGURABLE = 3,
     ATTR_WRITABLE,
     ATTR_ENUMERABLE,
     ATTR_DELETED,
     ATTR_GETSET,
     ATTR_DEFAULT
}

/// A dummy Vm class for example purpose.
class Vm {
     /// Stores values.
     int [string] table;

     /// The "classic" runtime const API.
     void defRTConst (string id, int val) {
         table [id] = val;
     }

     /// Using an alias with the identifier trait.
     void rtConst (alias p) () {
         table [__traits (identifier, p)] = p;
     }

     /// Initializes our .table member.
     this () {
         /// Using the allMembers traits we can process all the members 
of a
         /// named enum.
         foreach (member; __traits (allMembers, VmParams)) {
             int value = mixin ("VmParams." ~ member);
             this.defRTConst (member, value);
         }

         /// Without duplicating the name and its value.
         rtConst!ATTR_CONFIGURABLE;
         rtConst!ATTR_WRITABLE;
         rtConst!ATTR_ENUMERABLE;
         rtConst!ATTR_DELETED;
         rtConst!ATTR_GETSET;
         rtConst!ATTR_DEFAULT;

         /* rtConst won't work with local variables:
         //  auto foo = ATTR_DEFAULT;
         //  rtConst!foo;
         The code above raises a compiler error:
             Error: template instance rtConst!(foo) cannot use local 
'foo' as parameter to non-global template rtConst(alias p)()
         */
     }
}

void main ()  {
     Vm vm = new Vm;
     vm.table.writeln;

     /// output:
     /// ["OBJ_MIN_CAP":0, "ATTR_WRITABLE":4, "ATTR_ENUMERABLE":5, 
"ATTR_GETSET":7, "PROTO_SLOT_IDX":1, "FPTR_SLOT_IDX":2, 
"ATTR_CONFIGURABLE":3, "ATTR_DELETED":6, "ATTR_DEFAULT":8]
}


On 08/12/2014 07:36 PM, Maxime Chevalier-Boisvert wrote:
 In my JavaScript VM, I have a function whose purpose is to expose D/host
 constants to the JavaScript runtime code running inside the VM. This
 makes for somewhat redundant code, as follows:

 vm.defRTConst("OBJ_MIN_CAP"w, OBJ_MIN_CAP);
 vm.defRTConst("PROTO_SLOT_IDX"w, PROTO_SLOT_IDX);
 vm.defRTConst("FPTR_SLOT_IDX"w, FPTR_SLOT_IDX);
 vm.defRTConst("ATTR_CONFIGURABLE"w  , ATTR_CONFIGURABLE);
 vm.defRTConst("ATTR_WRITABLE"w      , ATTR_WRITABLE);
 vm.defRTConst("ATTR_ENUMERABLE"w    , ATTR_ENUMERABLE);
 vm.defRTConst("ATTR_DELETED"w       , ATTR_DELETED);
 vm.defRTConst("ATTR_GETSET"w        , ATTR_GETSET);
 vm.defRTConst("ATTR_DEFAULT"w       , ATTR_DEFAULT);

 I'm just wondering if there's a way to template defRTConst so that the
 name of an identifier I'm passing (e.g.: ATTR_DEFAULT) can be captured
 by the template, making it so that I don't also need to pass the name as
 a string. I expect the answer to be no, but maybe someone with more
 knowledge of D template magic knows better.
Aug 14 2014
parent =?UTF-8?B?UsOpbXkgTW91w6t6YQ==?= <remy.moueza gmail.com> writes:
I have just checked it and yes, it works with a constant that is not an 
enum: `const int FOO` defined in the module namespace or `static int 
BAR` defined in the dummy Vm class.

On 08/14/2014 02:08 PM, Maxime Chevalier-Boisvert wrote:
 Thanks. Does it also work with a constant that's not an enum, e.g.: 
const int FOO?
 On 08/14/2014 01:23 PM, Rémy Mouëza wrote:
 Using __traits (identifier, ...) and a template alias seems to work 
for me:
 import std.stdio;

 /// Two kinds of enums:

 /// A named enum.
 enum VmParams {
      OBJ_MIN_CAP,
      PROTO_SLOT_IDX,
      FPTR_SLOT_IDX,
 }

 /// An anonymous one.
 enum {
      ATTR_CONFIGURABLE = 3,
      ATTR_WRITABLE,
      ATTR_ENUMERABLE,
      ATTR_DELETED,
      ATTR_GETSET,
      ATTR_DEFAULT
 }

 /// A dummy Vm class for example purpose.
 class Vm {
      /// Stores values.
      int [string] table;

      /// The "classic" runtime const API.
      void defRTConst (string id, int val) {
          table [id] = val;
      }

      /// Using an alias with the identifier trait.
      void rtConst (alias p) () {
          table [__traits (identifier, p)] = p;
      }

      /// Initializes our .table member.
      this () {
          /// Using the allMembers traits we can process all the members
 of a
          /// named enum.
          foreach (member; __traits (allMembers, VmParams)) {
              int value = mixin ("VmParams." ~ member);
              this.defRTConst (member, value);
          }

          /// Without duplicating the name and its value.
          rtConst!ATTR_CONFIGURABLE;
          rtConst!ATTR_WRITABLE;
          rtConst!ATTR_ENUMERABLE;
          rtConst!ATTR_DELETED;
          rtConst!ATTR_GETSET;
          rtConst!ATTR_DEFAULT;

          /* rtConst won't work with local variables:
          //  auto foo = ATTR_DEFAULT;
          //  rtConst!foo;
          The code above raises a compiler error:
              Error: template instance rtConst!(foo) cannot use local
 'foo' as parameter to non-global template rtConst(alias p)()
          */
      }
 }

 void main ()  {
      Vm vm = new Vm;
      vm.table.writeln;

      /// output:
      /// ["OBJ_MIN_CAP":0, "ATTR_WRITABLE":4, "ATTR_ENUMERABLE":5,
 "ATTR_GETSET":7, "PROTO_SLOT_IDX":1, "FPTR_SLOT_IDX":2,
 "ATTR_CONFIGURABLE":3, "ATTR_DELETED":6, "ATTR_DEFAULT":8]
 }


 On 08/12/2014 07:36 PM, Maxime Chevalier-Boisvert wrote:
 In my JavaScript VM, I have a function whose purpose is to expose 
D/host
 constants to the JavaScript runtime code running inside the VM. This
 makes for somewhat redundant code, as follows:

 vm.defRTConst("OBJ_MIN_CAP"w, OBJ_MIN_CAP);
 vm.defRTConst("PROTO_SLOT_IDX"w, PROTO_SLOT_IDX);
 vm.defRTConst("FPTR_SLOT_IDX"w, FPTR_SLOT_IDX);
 vm.defRTConst("ATTR_CONFIGURABLE"w  , ATTR_CONFIGURABLE);
 vm.defRTConst("ATTR_WRITABLE"w      , ATTR_WRITABLE);
 vm.defRTConst("ATTR_ENUMERABLE"w    , ATTR_ENUMERABLE);
 vm.defRTConst("ATTR_DELETED"w       , ATTR_DELETED);
 vm.defRTConst("ATTR_GETSET"w        , ATTR_GETSET);
 vm.defRTConst("ATTR_DEFAULT"w       , ATTR_DEFAULT);

 I'm just wondering if there's a way to template defRTConst so that the
 name of an identifier I'm passing (e.g.: ATTR_DEFAULT) can be captured
 by the template, making it so that I don't also need to pass the 
name as
 a string. I expect the answer to be no, but maybe someone with more
 knowledge of D template magic knows better.
Aug 14 2014