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)
and
 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)
and
 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
next sibling 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 parent Philippe Sigaud <philippe.sigaud gmail.com> writes:
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.
Jun 23 2012
prev 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