Capture parameter identifier name in a template?
Rémy Mouëza via Digitalmars-d-learn
digitalmars-d-learn at puremagic.com
Thu Aug 14 05:23:00 PDT 2014
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.
>>
More information about the Digitalmars-d-learn
mailing list