Thread overview
Passing struct and struct[] into a template
Jul 22, 2015
Taylor Gronka
Jul 22, 2015
Timon Gehr
Jul 22, 2015
Taylor Gronka
Jul 22, 2015
Jonathan M Davis
Jul 23, 2015
Gary Willoughby
July 22, 2015
Hi,

I have a template function, and I want it to do something if the input variable is a list of structs, and something else if the input is a struct.

1) What's the best way to test this? I suppose I can call __traits(identifier, results) and look at the last two characters.
2) If `T` is a list of structs, how can I initialize a new struct so that I can append to `T`?

This is sort of how it might be done in python. I haven't implemented question 2 yet since I'm not sure how atm:

template Uks(T) {
    T query(string q) {
        T result;
        try {
            ulong test = result.length; // won't compile for non-list structs
            // append to a struct list
            T.subtype newResult; // is there a function like this?
            result ~= newResult;
        } catch {
            // assign the struct members directly
        }
        return result;
    }
}

I would like to call it like either of the following, depending on if I want 1 result or X results:
auto res = Uks!(U_Struct).query("email");
auto res = Uks!(U_Struct[]).query("email");

I'd be happy to hear better design methods.

Thanks
July 22, 2015
On 07/22/2015 06:29 AM, Taylor Gronka wrote:
> Hi,
>
> I have a template function, and I want it to do something if the input
> variable is a list of structs, and something else if the input is a struct.
>
> 1) What's the best way to test this? I suppose I can call
> __traits(identifier, results) and look at the last two characters.
> 2) If `T` is a list of structs, how can I initialize a new struct so
> that I can append to `T`?
>
> This is sort of how it might be done in python. I haven't implemented
> question 2 yet since I'm not sure how atm:
>
> template Uks(T) {
>      T query(string q) {
>          T result;
>          try {
>              ulong test = result.length; // won't compile for non-list
> structs
>              // append to a struct list
>              T.subtype newResult; // is there a function like this?
>              result ~= newResult;
>          } catch {
>              // assign the struct members directly
>          }
>          return result;
>      }
> }
>
> I would like to call it like either of the following, depending on if I
> want 1 result or X results:
> auto res = Uks!(U_Struct).query("email");
> auto res = Uks!(U_Struct[]).query("email");
>
> I'd be happy to hear better design methods.
>
> Thanks

template Uks(T){
    T query(string q){
        T result;
        static if(is(T==S[],S)){
            ulong test=result.length;
            // append
            S newResult;
            result~=newResult;
        }else{
            // assign
        }
        return result;
    }
}

void main(){
    struct U_Struct{}
    auto res1=Uks!(U_Struct).query("email");
    auto res2=Uks!(U_Struct[]).query("email");
}

July 22, 2015
On Wednesday, 22 July 2015 at 05:02:59 UTC, Timon Gehr wrote:
> template Uks(T){
>     T query(string q){
>         T result;
>         static if(is(T==S[],S)){
>             ulong test=result.length;
>             // append
>             S newResult;
>             result~=newResult;
>         }else{
>             // assign
>         }
>         return result;
>     }
> }
>
> void main(){
>     struct U_Struct{}
>     auto res1=Uks!(U_Struct).query("email");
>     auto res2=Uks!(U_Struct[]).query("email");
> }

Oh that's phenomenal. Thanks!

For reference, the is() function can accept template parameters. More here, under isExpression
http://dlang.org/expression.html
July 22, 2015
On Wednesday, July 22, 2015 04:29:23 Taylor Gronka via Digitalmars-d-learn wrote:
> I have a template function, and I want it to do something if the input variable is a list of structs, and something else if the input is a struct.

If you want a template to be different for different types, then overload it via template constraints. e.g.

auto query(T)(string s)
    if(isDynamicArray!T)
{
}

auto query(T)(string s)
    if(!isDynamicArray!T)
{
}

You can use static if internally instead if the difference in code between the two is small, though in most cases, unless the types are very similar, it's cleaner to use a template constraint.

- Jonathan M Davis

July 23, 2015
On Wednesday, 22 July 2015 at 04:29:26 UTC, Taylor Gronka wrote:
> Hi,
>
> I have a template function, and I want it to do something if the input variable is a list of structs, and something else if the input is a struct.
>
> [...]

Take a look at this thread, the poster had the same question:
http://forum.dlang.org/thread/djxzatqdwplocaazmvsc@forum.dlang.org