Capture parameter identifier name in a template?

Rémy Mouëza via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Thu Aug 14 04:23:16 PDT 2014


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.



More information about the Digitalmars-d-learn mailing list