On 09/25/2014 04:08 PM, SlomoTheBrave wrote:
> On Thursday, 25 September 2014 at 22:11:20 UTC, Mathias LANG wrote:
>> I'm a bit puzzled with the following behavior:
>>
>> ----
>> import std.typetuple, std.traits;
>>
>> struct UDAStruct {
>> string identifier;
>> }
>>
>> class MyClass {
>> @(UDAStruct("p1"), UDAStruct("p2"), UDAStruct("P3")) // P3 is a typo
>> void func(int p1, string p2, float p3) {}
>> }
>>
>> unittest {
>> alias Func = MyClass.func;
>> enum ParamNames = ParameterIdentifierTuple!Func;
>> enum ParamAttr = __traits(getAttributes, Func);
>>
>> foreach (attr; ParamAttr) {
>> template CmpName(string PName) {
>> pragma(msg, "Instantiated for: "~PName);
>> enum CmpName = (PName == attr.identifier);
>> }
>> pragma(msg, "Current attr is: "~attr.identifier);
>> static assert(anySatisfy!(CmpName, ParamNames));
The first invocation of that line will instantiate CmpName with
ParamNames, which happens to be a TypeTuple of "p1", "p2", and "p3".
> the output lines order shows there is a problem too:
>
>> Current attr is: p1
>> Instantiated for: p1
>> Instantiated for: p2
>> Instantiated for: p3
Surprisingly, that indicates that anySatisfy did instantiate CmpName
with all three string values, meaning that perhaps we don't have
shortcut behavior for 'bool' eponymous templates.
Copying and instrumenting anySatisfy's implementation:
template myAnySatisfy(alias F, T...)
{
pragma(msg, "myAnySatisfy with "~[ T ]);
static if(T.length == 0)
{
enum myAnySatisfy = false;
pragma(msg, "length == 0 "~myAnySatisfy);
}
else static if (T.length == 1)
{
enum myAnySatisfy = F!(T[0]);
pragma(msg, "length == 1 "~myAnySatisfy);
}
else
{
enum myAnySatisfy =
myAnySatisfy!(F, T[ 0 .. $/2]) ||
myAnySatisfy!(F, T[$/2 .. $ ]);
pragma(msg, "else "~myAnySatisfy);
}
}
When I use myAnySatisfy instead of anySatisfy, I see that I am right:
The last expression above does not stop instantiating after "p1". In
other words, even though myAnySatisfy!(F, T[$/2 .. $ ] is unnecessary
(because the first part of || is already 'true'), it gets instantiated
anyway.
Current attr is: p1
["myAnySatisfy with ", "p1", "p2", "p3"]
["myAnySatisfy with ", "p1"]
Instantiated for: p1
length == 1
["myAnySatisfy with ", "p2", "p3"]
["myAnySatisfy with ", "p2"]
Instantiated for: p2
length == 1
["myAnySatisfy with ", "p3"]
Instantiated for: p3
length == 1
else
else
Current attr is: p2
Current attr is: P3
This looks like an enhancement request.
Ali