Jump to page: 1 2
Thread overview
How to test for equality of types?
May 18, 2012
Matthias Walter
May 18, 2012
bearophile
May 18, 2012
Matthias Walter
May 18, 2012
Simen Kjaeraas
May 19, 2012
Matthias Walter
May 19, 2012
Philippe Sigaud
May 19, 2012
Matthias Walter
May 20, 2012
Kenji Hara
May 20, 2012
Kenji Hara
May 21, 2012
Kenji Hara
May 20, 2012
Philippe Sigaud
May 18, 2012
Artur Skawina
May 18, 2012
Hi,

how do I test two types for equality? Suppose I have A and B aliasing some type(s), how do I find out if they are aliases the same thing?

I tried the "is(A == B)" expression, but this does not always work (tell
me if I shall give an example).

On the other hand, according to the spec the IsExpression is not supposed to compare two aliases with each other.

Best regards,

Matthias
May 18, 2012
Matthias Walter:

> I tried the "is(A == B)" expression, but this does not always work (tell me if I shall give an example).

Showing examples is great.

Bye,
bearophile
May 18, 2012
On Fri, 18 May 2012 06:06:45 -0400, Matthias Walter <xammy@xammy.homelinux.net> wrote:

> Hi,
>
> how do I test two types for equality? Suppose I have A and B aliasing
> some type(s), how do I find out if they are aliases the same thing?
>
> I tried the "is(A == B)" expression, but this does not always work (tell
> me if I shall give an example).

I would expect this to work.  What situation does it not (maybe you aren't actually testing for equality there).

It could be a bug...

> On the other hand, according to the spec the IsExpression is not
> supposed to compare two aliases with each other.

where does it say that?

-Steve
May 18, 2012

On 2012-05-18 16:12, Steven Schveighoffer wrote:
> On Fri, 18 May 2012 06:06:45 -0400, Matthias Walter wrote:
>> how do I test two types for equality? Suppose I have A and B aliasing some type(s), how do I find out if they are aliases the same thing?
>>
>> I tried the "is(A == B)" expression, but this does not always work (tell
>> me if I shall give an example).
> 
> I would expect this to work.  What situation does it not (maybe you aren't actually testing for equality there).
> 
> It could be a bug...

=============

struct MyStruct { }

struct Wrapper(Wrap)
{
  Wrap _wrap;

  this(Wrap wrap)
  {
    _wrap = wrap;
  }
}


struct AliasStruct
{
public:
  alias MyStruct Alias;
}


int main(char[][] args)
{
  auto w = Wrapper!(AliasStruct)(AliasStruct.init);
  pragma(msg, is(Wrapper!(AliasStruct).Wrap == AliasStruct) ? "true" :
"false");
  pragma(msg, is(typeof(w._wrap) == AliasStruct) ? "true" : "false");
  pragma(msg, is(typeof(w._wrap).Alias == AliasStruct.Alias) ? "true" :
"false");


  return 0;
}
=============

prints out

false
true
false

during compilation using current git version of dmd. In my application I used the third case, i.e., wanted to find out whether they alias the same thing.

>> On the other hand, according to the spec the IsExpression is not supposed to compare two aliases with each other.
> 
> where does it say that?

Okay, this seems to be my fault. It states different cases for the RHS operator of "is(LHS == RHS)", e.g., "Type == TypeSpecialization", but nothing like "Type == Type". But TypeSpecialization includes Type as well...

Best regards,

Matthias
May 18, 2012
On Fri, 18 May 2012 23:06:00 +0200, Matthias Walter <xammy@xammy.homelinux.net> wrote:

[snip]
> prints out
>
> false

Because Wrapper!(AliasStruct).Wrap does not exist. And _error_ is not
equal to any other type.


> true

Indeed, they are the same.


> false

And here I disagree. This prints true on 2.059. Regression?
May 18, 2012
On 05/18/12 23:06, Matthias Walter wrote:
> =============
> 
> struct MyStruct { }
> 
> struct Wrapper(Wrap)
> {
>   Wrap _wrap;
> 
>   this(Wrap wrap)
>   {
>     _wrap = wrap;
>   }
> }
> 
> 
> struct AliasStruct
> {
> public:
>   alias MyStruct Alias;
> }
> 
> 
> int main(char[][] args)
> {
>   auto w = Wrapper!(AliasStruct)(AliasStruct.init);
>   pragma(msg, is(Wrapper!(AliasStruct).Wrap == AliasStruct) ? "true" :
> "false");
>   pragma(msg, is(typeof(w._wrap) == AliasStruct) ? "true" : "false");
>   pragma(msg, is(typeof(w._wrap).Alias == AliasStruct.Alias) ? "true" :
> "false");
> 
> 
>   return 0;
> }
> =============
> 
> prints out
> 
> false
> true
> false
> 
> during compilation using current git version of dmd. In my application I used the third case, i.e., wanted to find out whether they alias the same thing.

Hmm, my old GDC considers them equal (ie last line is "true"), so it's a recent
change. What does

  pragma(msg, is(w._wrap.Alias == AliasStruct.Alias));
  pragma(msg, typeof(w._wrap).Alias.stringof);
  pragma(msg, AliasStruct.Alias.stringof);

print?

Looks like a bug.

artur
May 19, 2012
On 2012-05-19 09:05, Philippe Sigaud wrote:
> On Fri, May 18, 2012 at 11:51 PM, Simen Kjaeraas <simen.kjaras@gmail.com> wrote:
> 
>> Because Wrapper!(AliasStruct).Wrap does not exist. And _error_ is not
>> equal to any other type.
> 
> Yes. Wrap is included in the complete template name (Wrapper!(Wrap))
> and has no independent existence.
> You _can_ get access to it by exposing it as an alias, as you do in AliasStruct:
> 
> struct Wrapper(Wrap)
> {
>     alias Wrap Wrapped; // cannot call it 'Wrap'
>  ...
> 
> }

Yes, of course you are right. This was my fault - after exposing it via an alias, it prints true.

> (third case)
>>> false
>>
>>
>> And here I disagree. This prints true on 2.059. Regression?
> 
> AFAICT, this should print true.
> 
> And, concerning Artur questio, on 2.059 (Linux):
> 
>  pragma(msg, is(w._wrap.Alias == AliasStruct.Alias));//   -> true
>  pragma(msg, typeof(w._wrap).Alias.stringof); // -> MyStruct
>  pragma(msg, AliasStruct.Alias.stringof); // -> MyStruct

I would open a bug report with the following code which is a bit smaller than my first wrong version:

=====================
module main;

struct MyStruct { }

struct AliasStruct
{
  alias MyStruct Alias;
}

struct Wrapper
{
  AliasStruct aliasStruct;
}

void main()
{
  Wrapper w;

  pragma(msg, typeof(w.aliasStruct).Alias.stringof); // -> "MyStruct"
  pragma(msg, AliasStruct.Alias.stringof); // -> "MyStruct"
  static assert(is(typeof(w.aliasStruct) == AliasStruct)); // -> true
  static assert(is(typeof(w.aliasStruct).Alias == AliasStruct.Alias));
// -> false
}
=====================

Best regards,

Matthias
May 19, 2012
On Sat, May 19, 2012 at 12:23 PM, Matthias Walter <xammy@xammy.homelinux.net> wrote:

> I would open a bug report with the following code which is a bit smaller than my first wrong version:
>
> =====================
(...)
>  pragma(msg, typeof(w.aliasStruct).Alias.stringof); // -> "MyStruct"
>  pragma(msg, AliasStruct.Alias.stringof); // -> "MyStruct"
>  static assert(is(typeof(w.aliasStruct) == AliasStruct)); // -> true
>  static assert(is(typeof(w.aliasStruct).Alias == AliasStruct.Alias));
> // -> false
> }

Seems like a pb concerning whether Alias is a type or a symbol. See A,B,C,D below:

void main()
{
 Wrapper w;

 pragma(msg, typeof(w.aliasStruct).Alias.stringof); // -> "MyStruct"
 pragma(msg, AliasStruct.Alias.stringof); // -> "MyStruct"
 static assert(is(typeof(w.aliasStruct) == AliasStruct)); // -> true
 static assert(is(w.aliasStruct.Alias == AliasStruct.Alias)); // -> true

 alias typeof(w.aliasStruct) A; // -> OK
 //alias typeof(w.aliasStruct).Alias B; // -> NOK
 //alias A.Alias C; // -> NOK
 alias w.aliasStruct.Alias D; // -> OK

 static assert(is(A.Alias == AliasStruct.Alias)); // -> true
 //static assert(is(B == AliasStruct.Alias));
 //static assert(is(C == AliasStruct.Alias));
 static assert(is(D == AliasStruct.Alias)); // -> true
}

I think A is enough for your need, but I don't get why B and C are not
accepted (DMD 2.059, Linux)
May 19, 2012
On 2012-05-19 15:28, Philippe Sigaud wrote:
> On Sat, May 19, 2012 at 12:23 PM, Matthias Walter <xammy@xammy.homelinux.net> wrote:
> 
>> I would open a bug report with the following code which is a bit smaller than my first wrong version:
>>
>> =====================
> (...)
>>  pragma(msg, typeof(w.aliasStruct).Alias.stringof); // -> "MyStruct"
>>  pragma(msg, AliasStruct.Alias.stringof); // -> "MyStruct"
>>  static assert(is(typeof(w.aliasStruct) == AliasStruct)); // -> true
>>  static assert(is(typeof(w.aliasStruct).Alias == AliasStruct.Alias));
>> // -> false
>> }
> 
> Seems like a pb concerning whether Alias is a type or a symbol. See A,B,C,D below:
> 
> void main()
> {
>  Wrapper w;
> 
>  pragma(msg, typeof(w.aliasStruct).Alias.stringof); // -> "MyStruct"
>  pragma(msg, AliasStruct.Alias.stringof); // -> "MyStruct"
>  static assert(is(typeof(w.aliasStruct) == AliasStruct)); // -> true
>  static assert(is(w.aliasStruct.Alias == AliasStruct.Alias)); // -> true
> 
>  alias typeof(w.aliasStruct) A; // -> OK
>  //alias typeof(w.aliasStruct).Alias B; // -> NOK
>  //alias A.Alias C; // -> NOK
>  alias w.aliasStruct.Alias D; // -> OK
> 
>  static assert(is(A.Alias == AliasStruct.Alias)); // -> true
>  //static assert(is(B == AliasStruct.Alias));
>  //static assert(is(C == AliasStruct.Alias));
>  static assert(is(D == AliasStruct.Alias)); // -> true
> }
> 
> I think A is enough for your need, but I don't get why B and C are not
> accepted (DMD 2.059, Linux)
> 

Using the current git version of dmd I realized that C works! Hence, as a workaround it can be used by creating a local alias A and subsequently using A.Alias in the is-expressions. But it seems odd that

"alias typeof(X).A B;" does not work but
"alias typeof(X) Y; alias Y.A B;" does.

Is this considered as a bug?

Best regards,

Matthias
May 20, 2012
> Using the current git version of dmd I realized that C works! Hence, as a workaround it can be used by creating a local alias A and subsequently using A.Alias in the is-expressions. But it seems odd that
>
> "alias typeof(X).A B;" does not work but
> "alias typeof(X) Y; alias Y.A B;" does.
>
> Is this considered as a bug?

I should say so: it's surprising, and limiting for the user.


« First   ‹ Prev
1 2