www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - std.traits : Select - could it be better?

reply SrMordred <patric.dexheimer gmail.com> writes:
alias U = Select!( isPointer!T, PointerTarget!T, T );

This don´t compile if T are not a pointer;

so you have to do this:

static if( isPointer!T )
     alias U = PointerTarget!T;
else
     alias U = T;

Shouldnt the 'correct' way of Select to work is ignoring the 
choice that was not taken?

I love the idea of Select, but because of this I almost never use 
it.
Jul 05 2018
next sibling parent Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 7/5/18 2:50 PM, SrMordred wrote:
 alias U = Select!( isPointer!T, PointerTarget!T, T );
 
 This don´t compile if T are not a pointer;
 
 so you have to do this:
 
 static if( isPointer!T )
      alias U = PointerTarget!T;
 else
      alias U = T;
 
 Shouldnt the 'correct' way of Select to work is ignoring the choice that 
 was not taken?
 
 I love the idea of Select, but because of this I almost never use it.
mixin("alias U = " ~ Select!(isPointer!T, "PointerTarget!T", "T") ~ ";"); Ehm this is actually not better :o). Andrei
Jul 05 2018
prev sibling parent reply Steven Schveighoffer <schveiguy yahoo.com> writes:
On 7/5/18 2:50 PM, SrMordred wrote:
 alias U = Select!( isPointer!T, PointerTarget!T, T );
 
 This don´t compile if T are not a pointer;
 
 so you have to do this:
 
 static if( isPointer!T )
      alias U = PointerTarget!T;
 else
      alias U = T;
 
 Shouldnt the 'correct' way of Select to work is ignoring the choice that 
 was not taken?
 
 I love the idea of Select, but because of this I almost never use it.
Hm... only thing I can think of is to do the instantiation within the template itself: template BetterSelect(bool cond, alias temp1, alias temp2, Args...) { import std.meta : Instantiate; static if(cond) alias BetterSelect = Instantiate!(temp1, Args); else alias BetterSelect = Instantiate!(temp2, Args); } alias U = BetterSelect!(isPointer!T, PointerTarget, Alias, T) Of course, this requires you to have templates that take EXACTLY the same parameters. I don't know if this (or something like it) is worth adding to std.traits or std.meta. -Steve
Jul 05 2018
parent reply Steven Schveighoffer <schveiguy yahoo.com> writes:
On 7/5/18 4:27 PM, Steven Schveighoffer wrote:
 template BetterSelect(bool cond, alias temp1, alias temp2, Args...)
 {
     import std.meta : Instantiate;
     static if(cond)
        alias BetterSelect = Instantiate!(temp1, Args);
     else
        alias BetterSelect = Instantiate!(temp2, Args);
 }
ugh, got too cute for my own good :) No need for Instantiate here: alias BetterSelect = temp1!Args; alias BetterSelect = temp2!Args; -Steve
Jul 05 2018
parent reply SrMordred <patric.dexheimer gmail.com> writes:
On Thursday, 5 July 2018 at 20:29:02 UTC, Steven Schveighoffer 
wrote:
 On 7/5/18 4:27 PM, Steven Schveighoffer wrote:
 template BetterSelect(bool cond, alias temp1, alias temp2, 
 Args...)
 {
     import std.meta : Instantiate;
     static if(cond)
        alias BetterSelect = Instantiate!(temp1, Args);
     else
        alias BetterSelect = Instantiate!(temp2, Args);
 }
ugh, got too cute for my own good :) No need for Instantiate here: alias BetterSelect = temp1!Args; alias BetterSelect = temp2!Args; -Steve
I find another solution :) template Try(alias T, Args...) { static if( is( T!Args ) ) alias Try = T!Args; } alias U = Select!( isPointer!T, Try!( PointerTarget, T ), T );
Jul 05 2018
parent Steven Schveighoffer <schveiguy yahoo.com> writes:
On 7/5/18 10:17 PM, SrMordred wrote:
 I find another solution :)
 
 template Try(alias T, Args...)
 {
      static if( is( T!Args ) )
          alias Try = T!Args;
 }
 
 alias U = Select!( isPointer!T, Try!( PointerTarget, T ), T );
 
I like it! -Steve
Jul 06 2018