www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - How to test for equality of types?

reply Matthias Walter <xammy xammy.homelinux.net> writes:
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
next sibling parent "bearophile" <bearophileHUGS lycos.com> writes:
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
prev sibling next sibling parent reply "Steven Schveighoffer" <schveiguy yahoo.com> writes:
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
parent Artur Skawina <art.08.09 gmail.com> writes:
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 18 2012
prev sibling next sibling parent Matthias Walter <xammy xammy.homelinux.net> writes:
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
prev sibling next sibling parent "Simen Kjaeraas" <simen.kjaras gmail.com> writes:
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
prev sibling next sibling parent Matthias Walter <xammy xammy.homelinux.net> writes:
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
prev sibling next sibling parent Philippe Sigaud <philippe.sigaud gmail.com> writes:
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:

 =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D

 =C2=A0pragma(msg, typeof(w.aliasStruct).Alias.stringof); // -> "MyStruct"
 =C2=A0pragma(msg, AliasStruct.Alias.stringof); // -> "MyStruct"
 =C2=A0static assert(is(typeof(w.aliasStruct) =3D=3D AliasStruct)); // -> =

 =C2=A0static assert(is(typeof(w.aliasStruct).Alias =3D=3D AliasStruct.Ali=

 // -> 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) =3D=3D AliasStruct)); // -> true static assert(is(w.aliasStruct.Alias =3D=3D AliasStruct.Alias)); // -> tru= e 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 =3D=3D AliasStruct.Alias)); // -> true //static assert(is(B =3D=3D AliasStruct.Alias)); //static assert(is(C =3D=3D AliasStruct.Alias)); static assert(is(D =3D=3D 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
prev sibling next sibling parent Matthias Walter <xammy xammy.homelinux.net> writes:
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 19 2012
prev sibling next sibling parent Philippe Sigaud <philippe.sigaud gmail.com> writes:
--20cf300faf5516c06604c0718189
Content-Type: text/plain; charset=UTF-8

 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. --20cf300faf5516c06604c0718189 Content-Type: text/html; charset=UTF-8 <p>&gt; Using the current git version of dmd I realized that C works! Hence, as<br> &gt; a workaround it can be used by creating a local alias A and subsequently<br> &gt; using A.Alias in the is-expressions. But it seems odd that<br> &gt;<br> &gt; &quot;alias typeof(X).A B;&quot; does not work but<br> &gt; &quot;alias typeof(X) Y; alias Y.A B;&quot; does.<br> &gt;<br> &gt; Is this considered as a bug?</p> <p>I should say so: it&#39;s surprising, and limiting for the user.</p> --20cf300faf5516c06604c0718189--
May 19 2012
prev sibling next sibling parent "Kenji Hara" <k.hara.pg gmail.com> writes:
On Saturday, 19 May 2012 at 18:17:16 UTC, Matthias Walter wrote:
 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

It seems to me that is a regression by fixing bug 6475. Now I'm trying to fix them.
May 19 2012
prev sibling next sibling parent "Kenji Hara" <k.hara.pg gmail.com> writes:
On Sunday, 20 May 2012 at 06:57:20 UTC, Kenji Hara wrote:
 On Saturday, 19 May 2012 at 18:17:16 UTC, Matthias Walter wrote:
 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

It seems to me that is a regression by fixing bug 6475. Now I'm trying to fix them.

I've filed the bug in bugzilla: http://d.puremagic.com/issues/show_bug.cgi?id=8123 And posted a pull request to fix it: https://github.com/D-Programming-Language/dmd/pull/957 Thanks. Kenji Hara
May 20 2012
prev sibling parent "Kenji Hara" <k.hara.pg gmail.com> writes:
On Sunday, 20 May 2012 at 06:57:20 UTC, Kenji Hara wrote:
 On Saturday, 19 May 2012 at 18:17:16 UTC, Matthias Walter wrote:
 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

It seems to me that is a regression by fixing bug 6475. Now I'm trying to fix them.

Fixed in git head: https://github.com/D-Programming-Language/dmd/commit/76543ef60f3b871612ddc0c87999859f427ba6f9
May 20 2012