Thread overview
Compare types with `static if` in template function.
Jul 29, 2015
vladde
Jul 29, 2015
Ali Çehreli
Jul 29, 2015
vladde
Jul 29, 2015
vladde
Jul 29, 2015
Ali Çehreli
Jul 29, 2015
vladde
Jul 29, 2015
Ali Çehreli
Jul 30, 2015
Vladde Nordholm
July 29, 2015
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
July 29, 2015
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

July 29, 2015
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
July 29, 2015
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.
July 29, 2015
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

July 29, 2015
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

July 29, 2015
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

July 30, 2015
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!