View mode: basic / threaded / horizontal-split · Log in · Help
May 18, 2012
How to test for equality of types?
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
Re: How to test for equality of types?
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
Re: How to test for equality of types?
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
Re: How to test for equality of types?
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
Re: How to test for equality of types?
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
Re: How to test for equality of types?
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
Re: How to test for equality of types?
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
Re: How to test for equality of types?
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
Re: How to test for equality of types?
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
Re: How to test for equality of types?
> 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
Top | Discussion index | About this forum | D home