www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - parameter type tuple or alias for std.traits templates ?

reply Guillaume Chatelet <chatelet.guillaume gmail.com> writes:
While reading the source code of std.traits I came across a bunch of
variadic templates enforcing the length of their parameter type tuple to
be of 1.

Is there any semantic difference between
 template ReturnType(func...) if (func.length == 1 && isCallable!func)

 template ReturnType(alias func) if (isCallable!func)

If not, is there any reason why this syntax is used ? Guillaume -- The list of templates from std.traits ( https://github.com/D-Programming-Language/phobos/blob/master/std/traits.d ) matching this pattern : template ReturnType(func...) if (func.length == 1 && isCallable!func) template ParameterTypeTuple(func...) if (func.length == 1 && isCallable!func) template ParameterStorageClassTuple(func...) if (func.length == 1 && isCallable!func) template functionAttributes(func...) if (func.length == 1 && isCallable!func) template functionLinkage(func...) if (func.length == 1 && isCallable!func) template variadicFunctionStyle(func...) if (func.length == 1 && isCallable!func) template FunctionTypeOf(func...) if (func.length == 1 && isCallable!func) template isFunctionPointer(T...) if (T.length == 1) template isDelegate(T...) if(T.length == 1) template isSomeFunction(T...) if (T.length == 1) template isCallable(T...) if (T.length == 1) template isAbstractFunction(method...) if (method.length == 1) template mangledName(sth...) if (sth.length == 1)
Jun 22 2012
parent reply Timon Gehr <timon.gehr gmx.ch> writes:
On 06/22/2012 11:50 PM, Guillaume Chatelet wrote:
 While reading the source code of std.traits I came across a bunch of
 variadic templates enforcing the length of their parameter type tuple to
 be of 1.

 Is there any semantic difference between
 template ReturnType(func...) if (func.length == 1&&  isCallable!func)

 template ReturnType(alias func) if (isCallable!func)


Yes there is, but I have argued that this is a bug in the past. With DMD, the (func...) accepts built-in types, while the (alias func) does not.
 If not, is there any reason why this syntax is used ?

 Guillaume
 --

Jun 22 2012
next sibling parent Guillaume Chatelet <chatelet.guillaume gmail.com> writes:
On 06/23/12 01:05, Timon Gehr wrote:
 
 Yes there is, but I have argued that this is a bug in the past. With
 DMD, the (func...) accepts built-in types, while the (alias func) does
 not.

Ok got it, the following won't compile I agree. template isInt(alias T) { enum bool isInt = is(T==int); } void main(){ static assert(isInt!int); } So I understand the following functions have to go the variadic way because you want an answer at compile time and not a compiler error template isFunctionPointer(T...) template isDelegate(T...) template isSomeFunction(T...) template isCallable(T...) template isAbstractFunction(method...) template mangledName(sth...) Nevertheless the following templates are all requiring 'func.length == 1 && isCallable!func' template ReturnType(func...) template ParameterTypeTuple(func...) template ParameterStorageClassTuple(func...) template functionAttributes(func...) template functionLinkage(func...) template variadicFunctionStyle(func...) template FunctionTypeOf(func...) So they won't instantiate if you pass a built-in type anyway. Using an 'alias' instead of a 'func...' would make it clear that : * you can't pass a built-in type in * the template is requiring exactly one argument As a user, I find it odd that ReturnType takes a TypeTuple rather than an alias. 'func...' basically means 'I will accept a tuple of functions' which is then restricted in the if clause to the case where func.length==1. -- Guillaume
Jun 23 2012
prev sibling next sibling parent reply Jacob Carlborg <doob me.com> writes:
On 2012-06-23 01:05, Timon Gehr wrote:

 Yes there is, but I have argued that this is a bug in the past. With
 DMD, the (func...) accepts built-in types, while the (alias func) does
 not.

Would it be possible to overload? Something like this: template Foo (T) {} template Foo (alias a) {} -- /Jacob Carlborg
Jun 23 2012
parent Timon Gehr <timon.gehr gmx.ch> writes:
On 06/23/2012 12:52 PM, Jacob Carlborg wrote:
 On 2012-06-23 01:05, Timon Gehr wrote:

 Yes there is, but I have argued that this is a bug in the past. With
 DMD, the (func...) accepts built-in types, while the (alias func) does
 not.

Would it be possible to overload? Something like this: template Foo (T) {} template Foo (alias a) {}

alias should just accept built in types.
Jun 23 2012
prev sibling next sibling parent Guillaume Chatelet <chatelet.guillaume gmail.com> writes:
I'm reposting this because I'm not sure it made it to the NG ( it
doesn't show up in the web interface )

On 06/23/12 01:05, Timon Gehr wrote:
 Yes there is, but I have argued that this is a bug in the past. With
 DMD, the (func...) accepts built-in types, while the (alias func) does
 not.

Ok got it, the following won't compile I agree. template isInt(alias T) { enum bool isInt = is(T==int); } void main(){ static assert(isInt!int); } So I understand the following functions have to go the variadic way because you want an answer at compile time and not a compiler error template isFunctionPointer(T...) template isDelegate(T...) template isSomeFunction(T...) template isCallable(T...) template isAbstractFunction(method...) template mangledName(sth...) Nevertheless the following templates are all requiring 'func.length == 1 && isCallable!func' template ReturnType(func...) template ParameterTypeTuple(func...) template ParameterStorageClassTuple(func...) template functionAttributes(func...) template functionLinkage(func...) template variadicFunctionStyle(func...) template FunctionTypeOf(func...) So they won't instantiate if you pass a built-in type anyway. Using an 'alias' instead of a 'func...' would make it clear that : * you can't pass a built-in type in * the template is requiring exactly one argument As a user, I find it odd that ReturnType takes a TypeTuple rather than an alias. 'func...' basically means 'I will accept a tuple of functions' which is then restricted in the if clause to the case where func.length==1. -- Guillaume
Jun 23 2012
prev sibling parent Philippe Sigaud <philippe.sigaud gmail.com> writes:
--20cf30334ecb521d0304c331ee9f
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

Le 23 juin 2012 12:53, "Jacob Carlborg" <doob me.com> a =C3=A9crit :
 On 2012-06-23 01:05, Timon Gehr wrote:

 Yes there is, but I have argued that this is a bug in the past. With
 DMD, the (func...) accepts built-in types, while the (alias func) does
 not.

Would it be possible to overload? Something like this: template Foo (T) {} template Foo (alias a) {}

I think it is. IIRC, I did something like this. But then the trouble is with user-defined types: they are both a type and a symbol, so they may fire both templates. --20cf30334ecb521d0304c331ee9f Content-Type: text/html; charset=UTF-8 Content-Transfer-Encoding: quoted-printable <p><br> Le 23 juin 2012 12:53, &quot;Jacob Carlborg&quot; &lt;<a href=3D"mailto:doo= b me.com">doob me.com</a>&gt; a =C3=A9crit=C2=A0:<br> &gt;<br> &gt; On 2012-06-23 01:05, Timon Gehr wrote:<br> &gt;<br> &gt;&gt; Yes there is, but I have argued that this is a bug in the past. Wi= th<br> &gt;&gt; DMD, the (func...) accepts built-in types, while the (alias func) = does<br> &gt;&gt; not.<br> &gt;<br> &gt;<br> &gt; Would it be possible to overload? Something like this:<br> &gt;<br> &gt; template Foo (T) {}<br> &gt;<br> &gt; template Foo (alias a) {}</p> <p>I think it is. IIRC, I did something like this.</p> <p>But then the trouble is with user-defined types: they are both a type an= d a symbol, so they may fire both templates.<br> </p> --20cf30334ecb521d0304c331ee9f--
Jun 23 2012