June 01, 2023

On 5/31/23 12:08 AM, John Xu wrote:

>

When render vibe.d diet template,

    string[] allMembers = __traits(allMembers, t);

enum allMembers = __traits(allMembers, t);

>

    res.render!("index.dt", t, allMembers)

if I don't want write memberName one by one in diet template:

    table
        - foreach(memberName; allMembers)
            tr
                td #{memberName}
                td #{getTMember!memberName(t)}

Problem: memberName is not known at compile time.

The problem is that you stored the member name list as a runtime variable, and that is not known at compile time. Try the enum.

Or really, just foreach(memberName; __traits(allMembers, t)) right in the diet template.

-Steve

June 02, 2023

On Thursday, 1 June 2023 at 15:38:08 UTC, Steven Schveighoffer wrote:

>

On 5/31/23 12:08 AM, John Xu wrote:

>

When render vibe.d diet template,

    string[] allMembers = __traits(allMembers, t);

enum allMembers = __traits(allMembers, t);

>

    res.render!("index.dt", t, allMembers)

if I don't want write memberName one by one in diet template:

    table
        - foreach(memberName; allMembers)
            tr
                td #{memberName}
                td #{getTMember!memberName(t)}

Problem: memberName is not known at compile time.

The problem is that you stored the member name list as a runtime variable, and that is not known at compile time. Try the enum.

Or really, just foreach(memberName; __traits(allMembers, t)) right in the diet template.

-Steve

Ok, thanks for all you gentlemen's help. I tried following function,
now it works like C/C++/Python way:

string getTMember(T t, string columnName) {
    foreach(member; __traits(allMembers, T)){
        if (member == columnName) {
            return __traits(getMember, mcu, member).to!string;
        }
    }
    return "";
}
June 02, 2023

A correction:

 string getTMember(T t, string columnName) {
     foreach(member; __traits(allMembers, T)){
         if (member == columnName) {
             return __traits(getMember, t, member).to!string;
         }
     }
     return "";
 }
June 02, 2023

On 6/1/23 10:58 PM, John Xu wrote:

>

Ok, thanks for all you gentlemen's help. I tried following function,
now it works like C/C++/Python way:

    string getTMember(T t, string columnName) {
        foreach(member; __traits(allMembers, T)){
            if (member == columnName) {
                return __traits(getMember, mcu, member).to!string;
            }
        }
        return "";
    }

You can use a switch, and the search for the right member name should be more optimized, though it's possible the compiler might recognize your pattern and do this anyway:

string getTMember(T t, string columnName) {
   switch(columnName)
   {
        static foreach(member; __traits(allMembers, T)) {
            case member:
                 return __traits(getMember, t, member).to!string;
        }
        default:
            return "";
   }
}

This is a very common pattern in e.g. serialization libs in D.

-Steve

June 02, 2023

On Tuesday, 30 May 2023 at 15:43:12 UTC, Steven Schveighoffer wrote:

>

On 5/30/23 4:46 AM, John Xu wrote:

>

How to put above enum as a function parameter? Following code wouldn't work:

    string getTMember(T t, enum string memberName) {
        return __traits(getMember, t, memberName);
    }

compile time parameters come before runtime parameters:

string getTMember(string memberName)(T t) {
   return __traits(getMember, t, memberName);
}

// used like
auto v = getTMember!"name"(t);

-Steve

Yeah I did fix it in my message right after

1 2
Next ›   Last »