www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Compare types with `static if` in template function.

reply "vladde" <v vladde.net> writes:
I want to have a template function where I can throw in some 
stuff in the parameters, then run foreach+static ifs and check 
what type the current is. From my project clayers[1], I've taken 
out some parts. (Note the current code does not compile.)
This is what I have so far:


struct XY {size_t x, y;}
alias fg = colorize.fg; //[2]
[...]
void changeSlot(C...)(XY xy, C changes){
     foreach(c; changes){
         static if(is(typeof(c) == dchar) || is(typeof(c) == char))
         {
             slots[xy.y][xy.x].character = c;
         }
         else if(is(typeof(c) == fg))
         {
             slots[xy.y][xy.x].fg = C;
         }
     }
}
[...]
changeSlot(XY(10, 15), fg.red);


For this demonstation I've chosen to only check for `char` and 
`fg`, but it's intended to check for multiple different types. 
(See [1])

Now when I try to compile, I get "Error: more than one argument 
for construction of int" for checking against fg. HOWEVER, the 
code functions properly when checking the type for characters. 
 From what I understand, my thinking works, but checking with `fg` 
is causing some crux-flux. `fg` is created from a template, 
please take a look at [2].

What am I doing wrong when I check for the type of `fg`?

TL;DR: Is there a way to check the type of `fg` with an static if?

[1] = 
https://github.com/vladdeSV/clayers/blob/change-slot/source/clayers.d#L323
[2] = 
https://github.com/yamadapc/d-colorize/blob/master/source/colorize/colors.d#L37
Jul 29 2015
parent reply =?UTF-8?B?QWxpIMOHZWhyZWxp?= <acehreli yahoo.com> writes:
On 07/29/2015 10:48 AM, vladde wrote:

          static if(is(typeof(c) == dchar) || is(typeof(c) == char))
          {
              slots[xy.y][xy.x].character = c;
          }
          else if(is(typeof(c) == fg))
I don't know whether it is the reason here but you fell for one of the D traps. :( Most definitely, you want an 'else static if' there. Otherwise, for the fg case, what ends up in your code to be compiled is this: if(is(typeof(c) == fg)) Ali
Jul 29 2015
parent reply "vladde" <v vladde.net> writes:
On Wednesday, 29 July 2015 at 17:52:45 UTC, Ali Çehreli wrote:
 On 07/29/2015 10:48 AM, vladde wrote:

          static if(is(typeof(c) == dchar) || is(typeof(c) ==
char))
          {
              slots[xy.y][xy.x].character = c;
          }
          else if(is(typeof(c) == fg))
I don't know whether it is the reason here but you fell for one of the D traps. :( Most definitely, you want an 'else static if' there. Otherwise, for the fg case, what ends up in your code to be compiled is this: if(is(typeof(c) == fg)) Ali
Apparently, if I only check for a character the code compiles without the need of static if. if(is(typeof(c) == dchar) || is(typeof(c) == char)){ slots[xy.y][xy.x].character = c; } //Compiles and works as expected
Jul 29 2015
parent reply "vladde" <v vladde.net> writes:
On Wednesday, 29 July 2015 at 18:04:48 UTC, vladde wrote:
 Apparently, if I only check for a character the code compiles 
 without the need of static if.

 if(is(typeof(c) == dchar) || is(typeof(c) == char)){ 
 slots[xy.y][xy.x].character = c; } //Compiles and works as 
 expected
And changing all if statements to static if still does not compile.
Jul 29 2015
parent reply =?UTF-8?B?QWxpIMOHZWhyZWxp?= <acehreli yahoo.com> writes:
On 07/29/2015 11:08 AM, vladde wrote:
 On Wednesday, 29 July 2015 at 18:04:48 UTC, vladde wrote:
 Apparently, if I only check for a character the code compiles without
 the need of static if.

 if(is(typeof(c) == dchar) || is(typeof(c) == char)){
 slots[xy.y][xy.x].character = c; } //Compiles and works as expected
And changing all if statements to static if still does not compile.
The error may be the capital C in the else branch. (?) Can you provide complete code please? The following compiles with dmd 2.067: struct XY {size_t x, y;} private template color_type(int offset) { static enum type : int { init = 39 + offset, black = 30 + offset, red = 31 + offset, green = 32 + offset, yellow = 33 + offset, blue = 34 + offset, magenta = 35 + offset, cyan = 36 + offset, white = 37 + offset, light_black = 90 + offset, light_red = 91 + offset, light_green = 92 + offset, light_yellow = 93 + offset, light_blue = 94 + offset, light_magenta = 95 + offset, light_cyan = 96 + offset, light_white = 97 + offset } } alias color_type!0 .type fg; // alias fg = colorize.fg; //[2] void changeSlot(C...)(XY xy, C changes){ foreach(c; changes){ static if(is(typeof(c) == dchar) || is(typeof(c) == char)) { // slots[xy.y][xy.x].character = c; } else if(is(typeof(c) == fg)) { // slots[xy.y][xy.x].fg = C; } } } void main() { changeSlot(XY(10, 15), fg.red); } Ali
Jul 29 2015
parent reply "vladde" <v vladde.net> writes:
On Wednesday, 29 July 2015 at 18:14:11 UTC, Ali Çehreli wrote:
         else if(is(typeof(c) == fg))
         {
             // slots[xy.y][xy.x].fg = C;
         }
The error occurs when the commented line is run. The full code can be viewed at https://github.com/vladdeSV/clayers/blob/change-slot/source/clayers.d
Jul 29 2015
parent reply =?UTF-8?B?QWxpIMOHZWhyZWxp?= <acehreli yahoo.com> writes:
On 07/29/2015 11:54 AM, vladde wrote:
 On Wednesday, 29 July 2015 at 18:14:11 UTC, Ali Çehreli wrote:
         else if(is(typeof(c) == fg))
         {
             // slots[xy.y][xy.x].fg = C;
         }
The error occurs when the commented line is run. The full code can be viewed at https://github.com/vladdeSV/clayers/blob/change-slot/source/clayers.d
You seem to be using type names instead of member names: static if(is(typeof(c) == dchar) || is(typeof(c) == char)) { slots[xy.y][xy.x].character = c; } else if(is(typeof(c) == fg)) { slots[xy.y][xy.x].fg = c; Should be ... color = c; } else if(is(typeof(c) == bg)) { slots[xy.y][xy.x].bg = c; ... background = c; } else if(is(typeof(c) == md)) { slots[xy.y][xy.x].md = c; ... mode = c; } Ali
Jul 29 2015
parent "Vladde Nordholm" <v vladde.net> writes:
On Wednesday, 29 July 2015 at 22:40:08 UTC, Ali Çehreli wrote:
 You seem to be using type names instead of member names:

             static if(is(typeof(c) == dchar) || is(typeof(c) == 
 char))
             {
                 slots[xy.y][xy.x].character = c;
             }
             else if(is(typeof(c) == fg))
             {
                 slots[xy.y][xy.x].fg = c;

 Should be

 ... color = c;

             }
             else if(is(typeof(c) == bg))
             {
                 slots[xy.y][xy.x].bg = c;

 ... background = c;

             }
             else if(is(typeof(c) == md))
             {
                 slots[xy.y][xy.x].md = c;

 ... mode = c;

             }

 Ali
Thank you! This was a mistake on my end. Really glad you spotted it, saved me quite some headaches!
Jul 30 2015