Re: Checking the Return Type of a Template Alias Parameter in assertCTFEable

2014-02-28 Thread Kenji Hara
2014/02/28 23:06 Nordlöw :
>
> I have a solution to Issue 388 at
>
> https://github.com/nordlow/dmd/commits/master
>
> that works nicely for my projects.
>
> This patch however generates a handful of warnings in Phobos unittests.
>
> All of these are IMO fixable except for one which I don't know how to fix
namely the definition of assertCTFEable in exception.d
>
> I need to change this to explicitly capture the return value of the
template alias argument dg when this is non-void. My try so far was to
change
>
> version(unittest) package
> @property void assertCTFEable(alias dg)()
> {
> static assert({ dg(); return true; }());
> dg();
> }
>
> to
>
> version(unittest) package
> @property void assertCTFEable(alias dg)()
> {
> static assert
> ({
> static if (is(typeof(db()) == void)) {
> dg();
> } else {
> auto x = dg();
> }
> return true;
> }());
> static if (is(typeof(db()) == void)) {
> dg();
> } else {
> auto x = dg();
> }
> }
>
> gives the following error when in Phobos make unittest:
>
> std/exception.d(1392): Error: variable
std.exception.assertCTFEable!(function ()
> {
> S[] r = array(repeat((S __ctmp1582 = 0;
>  , __ctmp1582).this(1), 2LU));
> assert(equal(r, [(S __ctmp1591 = 0;
>  , __ctmp1591).this(1), (S __ctmp1592 = 0;
>  , __ctmp1592).this(1)]));
> }
> ).assertCTFEable.__lambda1.x type void is inferred from initializer
(*function ()
> {
> S[] r = array(repeat((S __ctmp1582 = 0;
>  , __ctmp1582).this(1), 2LU));
> assert(equal(r, [(S __ctmp1591 = 0;
>  , __ctmp1591).this(1), (S __ctmp1592 = 0;
>  , __ctmp1592).this(1)]));
> }
> )(), and variables cannot be of type void
> std/exception.d(1392): Error: expression (*function ()
> {
> S[] r = array(repeat((S __ctmp1582 = 0;
>  , __ctmp1582).this(1), 2LU));
> assert(equal(r, [(S __ctmp1591 = 0;
>  , __ctmp1591).this(1), (S __ctmp1592 = 0;
>  , __ctmp1592).this(1)]));
> }
> )() is void and has no value
>
> How can I in a general way check if dg evaluates to void or not?

Maybe:

cast(void)dg();

Kenji Hara


Re: Checking the Return Type of a Template Alias Parameter in assertCTFEable

2014-02-28 Thread Nordlöw

Wonderful!

Now can I request a pull for DMD and Phobos for Issue 3882.

:)


Re: Checking the Return Type of a Template Alias Parameter in assertCTFEable

2014-02-28 Thread John Colvin

On Friday, 28 February 2014 at 16:13:19 UTC, Nordlöw wrote:

On Friday, 28 February 2014 at 15:03:29 UTC, John Colvin wrote:

On Friday, 28 February 2014 at 14:02:35 UTC, Nordlöw wrote:

I have a solution to Issue 388 at

https://github.com/nordlow/dmd/commits/master

that works nicely for my projects.

This patch however generates a handful of warnings in Phobos 
unittests.


All of these are IMO fixable except for one which I don't 
know how to fix namely the definition of assertCTFEable in 
exception.d


I need to change this to explicitly capture the return value 
of the template alias argument dg when this is non-void. My 
try so far was to change


version(unittest) package
@property void assertCTFEable(alias dg)()
{
  static assert({ dg(); return true; }());
  dg();
}

to

version(unittest) package
@property void assertCTFEable(alias dg)()
{
  static assert
  ({
  static if (is(typeof(db()) == void)) {
  dg();
  } else {
  auto x = dg();
  }
  return true;
  }());
  static if (is(typeof(db()) == void)) {
  dg();
  } else {
  auto x = dg();
  }
}

gives the following error when in Phobos make unittest:

std/exception.d(1392): Error: variable 
std.exception.assertCTFEable!(function ()

{
S[] r = array(repeat((S __ctmp1582 = 0;
, __ctmp1582).this(1), 2LU));
assert(equal(r, [(S __ctmp1591 = 0;
, __ctmp1591).this(1), (S __ctmp1592 = 0;
, __ctmp1592).this(1)]));
}
).assertCTFEable.__lambda1.x type void is inferred from 
initializer (*function ()

{
S[] r = array(repeat((S __ctmp1582 = 0;
, __ctmp1582).this(1), 2LU));
assert(equal(r, [(S __ctmp1591 = 0;
, __ctmp1591).this(1), (S __ctmp1592 = 0;
, __ctmp1592).this(1)]));
}
)(), and variables cannot be of type void
std/exception.d(1392): Error: expression (*function ()
{
S[] r = array(repeat((S __ctmp1582 = 0;
, __ctmp1582).this(1), 2LU));
assert(equal(r, [(S __ctmp1591 = 0;
, __ctmp1591).this(1), (S __ctmp1592 = 0;
, __ctmp1592).this(1)]));
}
)() is void and has no value

How can I in a general way check if dg evaluates to void or 
not?


Either use std.traits.ReturnType, or see from it's 
implementation.


I tried


version(unittest) package
@property void assertCTFEable(alias dg)()
{
static assert
({
static if (is(ReturnType!(db()) == void)) {
dg();
} else {
auto x = dg();
}
return true;
}());
static if (is(ReturnType!(db()) == void)) {
dg();
} else {
auto x = dg();
}
}

but this instead fails as

std/exception.d(1392): Error: variable 
std.conv.__unittestL932_18.assertCTFEable!(dg).assertCTFEable.__lambda1.x 
type void is inferred from initializer dg(), and variables 
cannot be of type void
std/exception.d(1392): Error: expression dg() is void and has 
no value
std/exception.d(1402): Error: variable 
std.conv.__unittestL932_18.assertCTFEable!(dg).assertCTFEable.x 
type void is inferred from initializer dg(), and variables 
cannot be of type void
std/exception.d(1402): Error: expression dg() is void and has 
no value
std/conv.d(974): Error: template instance 
std.conv.__unittestL932_18.assertCTFEable!(dg) error 
instantiating
std/exception.d(1392): Error: variable 
std.exception.assertCTFEable!(function ()

{
assert(to(4611686018427387904LU) == "4611686018427387904");
assert(to(4294967296L) == "4294967296");
assert(to(-138L) == "-138");
}
).assertCTFEable.__lambda1.x type void is inferred from 
initializer (*function ()

{
assert(to(4611686018427387904LU) == "4611686018427387904");
assert(to(4294967296L) == "4294967296");
assert(to(-138L) == "-138");
}
)(), and variables cannot be of type void


Should be

version(unittest) package
@property void assertCTFEable(alias dg)()
{
static assert
({
static if (is(ReturnType!dg == void)) {
dg();
} else {
auto x = dg();
}
return true;
}());
static if (is(ReturnType!dg == void)) {
dg();
} else {
auto x = dg();
}
}


Re: Checking the Return Type of a Template Alias Parameter in assertCTFEable

2014-02-28 Thread Nordlöw

On Friday, 28 February 2014 at 15:03:29 UTC, John Colvin wrote:

On Friday, 28 February 2014 at 14:02:35 UTC, Nordlöw wrote:

I have a solution to Issue 388 at

https://github.com/nordlow/dmd/commits/master

that works nicely for my projects.

This patch however generates a handful of warnings in Phobos 
unittests.


All of these are IMO fixable except for one which I don't know 
how to fix namely the definition of assertCTFEable in 
exception.d


I need to change this to explicitly capture the return value 
of the template alias argument dg when this is non-void. My 
try so far was to change


version(unittest) package
@property void assertCTFEable(alias dg)()
{
   static assert({ dg(); return true; }());
   dg();
}

to

version(unittest) package
@property void assertCTFEable(alias dg)()
{
   static assert
   ({
   static if (is(typeof(db()) == void)) {
   dg();
   } else {
   auto x = dg();
   }
   return true;
   }());
   static if (is(typeof(db()) == void)) {
   dg();
   } else {
   auto x = dg();
   }
}

gives the following error when in Phobos make unittest:

std/exception.d(1392): Error: variable 
std.exception.assertCTFEable!(function ()

{
S[] r = array(repeat((S __ctmp1582 = 0;
, __ctmp1582).this(1), 2LU));
assert(equal(r, [(S __ctmp1591 = 0;
, __ctmp1591).this(1), (S __ctmp1592 = 0;
, __ctmp1592).this(1)]));
}
).assertCTFEable.__lambda1.x type void is inferred from 
initializer (*function ()

{
S[] r = array(repeat((S __ctmp1582 = 0;
, __ctmp1582).this(1), 2LU));
assert(equal(r, [(S __ctmp1591 = 0;
, __ctmp1591).this(1), (S __ctmp1592 = 0;
, __ctmp1592).this(1)]));
}
)(), and variables cannot be of type void
std/exception.d(1392): Error: expression (*function ()
{
S[] r = array(repeat((S __ctmp1582 = 0;
, __ctmp1582).this(1), 2LU));
assert(equal(r, [(S __ctmp1591 = 0;
, __ctmp1591).this(1), (S __ctmp1592 = 0;
, __ctmp1592).this(1)]));
}
)() is void and has no value

How can I in a general way check if dg evaluates to void or 
not?


Either use std.traits.ReturnType, or see from it's 
implementation.


I tried


version(unittest) package
@property void assertCTFEable(alias dg)()
{
static assert
({
static if (is(ReturnType!(db()) == void)) {
dg();
} else {
auto x = dg();
}
return true;
}());
static if (is(ReturnType!(db()) == void)) {
dg();
} else {
auto x = dg();
}
}

but this instead fails as

std/exception.d(1392): Error: variable 
std.conv.__unittestL932_18.assertCTFEable!(dg).assertCTFEable.__lambda1.x 
type void is inferred from initializer dg(), and variables cannot 
be of type void
std/exception.d(1392): Error: expression dg() is void and has no 
value
std/exception.d(1402): Error: variable 
std.conv.__unittestL932_18.assertCTFEable!(dg).assertCTFEable.x 
type void is inferred from initializer dg(), and variables cannot 
be of type void
std/exception.d(1402): Error: expression dg() is void and has no 
value
std/conv.d(974): Error: template instance 
std.conv.__unittestL932_18.assertCTFEable!(dg) error instantiating
std/exception.d(1392): Error: variable 
std.exception.assertCTFEable!(function ()

{
assert(to(4611686018427387904LU) == "4611686018427387904");
assert(to(4294967296L) == "4294967296");
assert(to(-138L) == "-138");
}
).assertCTFEable.__lambda1.x type void is inferred from 
initializer (*function ()

{
assert(to(4611686018427387904LU) == "4611686018427387904");
assert(to(4294967296L) == "4294967296");
assert(to(-138L) == "-138");
}
)(), and variables cannot be of type void


Re: Checking the Return Type of a Template Alias Parameter in assertCTFEable

2014-02-28 Thread John Colvin

On Friday, 28 February 2014 at 14:02:35 UTC, Nordlöw wrote:

I have a solution to Issue 388 at

https://github.com/nordlow/dmd/commits/master

that works nicely for my projects.

This patch however generates a handful of warnings in Phobos 
unittests.


All of these are IMO fixable except for one which I don't know 
how to fix namely the definition of assertCTFEable in 
exception.d


I need to change this to explicitly capture the return value of 
the template alias argument dg when this is non-void. My try so 
far was to change


version(unittest) package
@property void assertCTFEable(alias dg)()
{
static assert({ dg(); return true; }());
dg();
}

to

version(unittest) package
@property void assertCTFEable(alias dg)()
{
static assert
({
static if (is(typeof(db()) == void)) {
dg();
} else {
auto x = dg();
}
return true;
}());
static if (is(typeof(db()) == void)) {
dg();
} else {
auto x = dg();
}
}

gives the following error when in Phobos make unittest:

std/exception.d(1392): Error: variable 
std.exception.assertCTFEable!(function ()

{
S[] r = array(repeat((S __ctmp1582 = 0;
 , __ctmp1582).this(1), 2LU));
assert(equal(r, [(S __ctmp1591 = 0;
 , __ctmp1591).this(1), (S __ctmp1592 = 0;
 , __ctmp1592).this(1)]));
}
).assertCTFEable.__lambda1.x type void is inferred from 
initializer (*function ()

{
S[] r = array(repeat((S __ctmp1582 = 0;
 , __ctmp1582).this(1), 2LU));
assert(equal(r, [(S __ctmp1591 = 0;
 , __ctmp1591).this(1), (S __ctmp1592 = 0;
 , __ctmp1592).this(1)]));
}
)(), and variables cannot be of type void
std/exception.d(1392): Error: expression (*function ()
{
S[] r = array(repeat((S __ctmp1582 = 0;
 , __ctmp1582).this(1), 2LU));
assert(equal(r, [(S __ctmp1591 = 0;
 , __ctmp1591).this(1), (S __ctmp1592 = 0;
 , __ctmp1592).this(1)]));
}
)() is void and has no value

How can I in a general way check if dg evaluates to void or not?


Either use std.traits.ReturnType, or see from it's implementation.


Checking the Return Type of a Template Alias Parameter in assertCTFEable

2014-02-28 Thread Nordlöw

I have a solution to Issue 388 at

https://github.com/nordlow/dmd/commits/master

that works nicely for my projects.

This patch however generates a handful of warnings in Phobos 
unittests.


All of these are IMO fixable except for one which I don't know 
how to fix namely the definition of assertCTFEable in exception.d


I need to change this to explicitly capture the return value of 
the template alias argument dg when this is non-void. My try so 
far was to change


version(unittest) package
@property void assertCTFEable(alias dg)()
{
static assert({ dg(); return true; }());
dg();
}

to

version(unittest) package
@property void assertCTFEable(alias dg)()
{
static assert
({
static if (is(typeof(db()) == void)) {
dg();
} else {
auto x = dg();
}
return true;
}());
static if (is(typeof(db()) == void)) {
dg();
} else {
auto x = dg();
}
}

gives the following error when in Phobos make unittest:

std/exception.d(1392): Error: variable 
std.exception.assertCTFEable!(function ()

{
S[] r = array(repeat((S __ctmp1582 = 0;
 , __ctmp1582).this(1), 2LU));
assert(equal(r, [(S __ctmp1591 = 0;
 , __ctmp1591).this(1), (S __ctmp1592 = 0;
 , __ctmp1592).this(1)]));
}
).assertCTFEable.__lambda1.x type void is inferred from 
initializer (*function ()

{
S[] r = array(repeat((S __ctmp1582 = 0;
 , __ctmp1582).this(1), 2LU));
assert(equal(r, [(S __ctmp1591 = 0;
 , __ctmp1591).this(1), (S __ctmp1592 = 0;
 , __ctmp1592).this(1)]));
}
)(), and variables cannot be of type void
std/exception.d(1392): Error: expression (*function ()
{
S[] r = array(repeat((S __ctmp1582 = 0;
 , __ctmp1582).this(1), 2LU));
assert(equal(r, [(S __ctmp1591 = 0;
 , __ctmp1591).this(1), (S __ctmp1592 = 0;
 , __ctmp1592).this(1)]));
}
)() is void and has no value

How can I in a general way check if dg evaluates to void or not?


Re: template alias = parameter

2013-09-17 Thread Luís.Marques

On Tuesday, 17 September 2013 at 12:10:11 UTC, Dicebot wrote:
Any two different alias parameter values mean different 
template instances. Static introspection demands it:


```
auto foo(alias T)()
{
static if (is(typeof(T) : int) && (T == 42))
return true;
else
return false;
}
```


Yes, that's what I was saying (or trying? thanks anyway). The 
problem is that I can't get that and implicit instantiation at 
the same time.


I mean, if void foo(T)(T x) makes T=int when called with foo(42), 
I was hoping that maybe void foo(alias V)(int V) would make V=42. 
But no. Well, it was a long shot, but it was worth the try.


Re: template alias = parameter

2013-09-17 Thread Dicebot

On Tuesday, 17 September 2013 at 11:50:56 UTC, Luís Marques wrote:

On Tuesday, 17 September 2013 at 11:46:07 UTC, Dicebot wrote:
It should not be possible as template instances with same 
template parameter list share same body in code gen.


Well, my long shot idea was to use an alias template parameter, 
that way different values would mean different template 
parameters. But it seems I can't make the alias template 
parameter implicitly match in any way.


Any two different alias parameter values mean different template 
instances. Static introspection demands it:


```
auto foo(alias T)()
{
static if (is(typeof(T) : int) && (T == 42))
return true;
else
return false;
}
```


Re: template alias = parameter

2013-09-17 Thread Luís.Marques

On Tuesday, 17 September 2013 at 11:46:07 UTC, Dicebot wrote:
It should not be possible as template instances with same 
template parameter list share same body in code gen.


Well, my long shot idea was to use an alias template parameter, 
that way different values would mean different template 
parameters. But it seems I can't make the alias template 
parameter implicitly match in any way.


Re: template alias = parameter

2013-09-17 Thread Dicebot

On Tuesday, 17 September 2013 at 11:43:24 UTC, Luís Marques wrote:
These examples came from a set of experiments where I was 
trying to do something which I expected would probably not be 
possible: make a template function generate different code 1) 
without varying the function types, 2) without explicitly 
instantiating the template using "!". (this was for 
compatibility purposes).


It should not be possible as template instances with same 
template parameter list share same body in code gen.


Re: template alias = parameter

2013-09-17 Thread Luís.Marques
Thanks. I think what is weird is that the template parameters are 
allowed to have the same name as the normal parameters, which 
confused my mental model and made me wonder what was even the 
expected behavior.


These examples came from a set of experiments where I was trying 
to do something which I expected would probably not be possible: 
make a template function generate different code 1) without 
varying the function types, 2) without explicitly instantiating 
the template using "!". (this was for compatibility purposes).


Re: template alias = parameter

2013-09-17 Thread Dicebot

On Tuesday, 17 September 2013 at 11:24:10 UTC, Luís Marques wrote:
Could you please comment on the following behaviors? Are all of 
them intended? Are they internally coherent, with respect to 
each

 other?


Looks fine to me.


1)
void foo(alias f)(int f)
{
writeln(f);
}

foo(42);

Error: does not match template


`alias` is never inferred so error is expected. You did not 
provide any template parameters to foo. `void foo(T)(T f)` would 
have worked because `T` can be inferred.



2)
...
foo!(42)(42);

> 42


Explicit template parameter + normal parameter. Name of normal 
parameter shadows alias name (would have expected a warning/error 
here tbh).



3)
...
foo!(7)(42);

> 42


Same as (2).


4)
void foo(alias f)(int g=f)
{
writeln(g);
}

foo(42);

Error: does not match template


Again, you do not provide template parameter, it can't match. 
`foo!(42)()` should have worked here.



5)
void foo(alias f=42)(int g=f)
{
writeln(g);
}

foo();

> 42


Default parameters can be used everywhere so no need to provide 
any parameter explicitly.


template alias = parameter

2013-09-17 Thread Luís.Marques
Could you please comment on the following behaviors? Are all of 
them intended? Are they internally coherent, with respect to each 
 other?


1)
void foo(alias f)(int f)
{
writeln(f);
}

foo(42);

Error: does not match template

2)
...
foo!(42)(42);

> 42

3)
...
foo!(7)(42);

> 42

4)
void foo(alias f)(int g=f)
{
writeln(g);
}

foo(42);

Error: does not match template

5)
void foo(alias f=42)(int g=f)
{
writeln(g);
}

foo();

> 42


Template alias parameter does not accept primitives?

2011-03-05 Thread KennyTM~

template Foo(alias A) {
alias A Foo;
}
Foo!(int) x;

This piece of code will not compile in both D1 and D2 because 'int' 
cannot be matched with 'alias A'. Is this expected? Why is that?



Refs:
 1. http://codepad.org/GQFBdC0T
 2. http://ideone.com/yke0h