TypeFunction example: ImplictConvTargets
Stefan Koch
uplink.coder at googlemail.com
Tue Oct 6 10:22:44 UTC 2020
On Tuesday, 6 October 2020 at 01:12:01 UTC, Walter Bright wrote:
> On 10/5/2020 2:20 PM, Stefan Koch wrote:
>> Now post it with all transitive dependencies.
>
> I'm not sure how transitive dependencies applies here. A
> illuminating test case would be helpful.
Okay let me show you the transitive dependencies of the "3 liner"
suggested by Andrei and executed by Paul Backus.
--- phobos dependencies ---
template ApplyLeft(alias Template, args...)
{
alias ApplyLeft(right...) = SmartAlias!(Template!(args,
right));
}
private template SmartAlias(T...)
{
static if (T.length == 1)
{
alias SmartAlias = Alias!T;
}
else
{
alias SmartAlias = T;
}
}
alias Alias(alias a) = a;
alias Alias(T) = T;
template Filter(alias pred, TList...)
{
static if (TList.length < filterExpandFactor)
{
mixin(FilterShortCode[TList.length]);
}
else
{
template MaybeNothing(Q...)
{
static if (pred!(Q[0]))
alias MaybeNothing = AliasSeq!(Q[0]);
else
alias MaybeNothing = Nothing;
}
alias Filter = staticMap!(MaybeNothing, TList);
}
}
private enum staticMapExpandFactor = 150;
private string generateCases()
{
string[staticMapExpandFactor] chunks;
chunks[0] = q{};
static foreach (enum i; 0 .. staticMapExpandFactor - 1)
chunks[i + 1] = chunks[i] ~ `F!(Args[` ~ i.stringof ~
`]),`;
string ret = `AliasSeq!(`;
foreach (chunk; chunks)
ret ~= `q{alias staticMap = AliasSeq!(` ~ chunk ~
`);},`;
return ret ~ `)`;
}
private alias staticMapBasicCases =
AliasSeq!(mixin(generateCases()));
template staticMap(alias F, Args...)
{
static if (Args.length < staticMapExpandFactor)
mixin(staticMapBasicCases[Args.length]);
else
alias staticMap = AliasSeq!(staticMap!(F, Args[0
.. $ / 2]),
staticMap!(F, Args[$ / 2 .. $]));
}
private alias FilterShortCode = AliasSeq!(
q{
alias Filter = Nothing;
},
q{
static if (pred!(TList[0]))
alias Filter = AliasSeq!(TList[0]);
else
alias Filter = Nothing;
},
q{
static if (pred!(TList[0]))
{
static if (pred!(TList[1]))
alias Filter = AliasSeq!(TList[0], TList[1]);
else
alias Filter = AliasSeq!(TList[0]);
}
else
{
static if (pred!(TList[1]))
alias Filter = AliasSeq!(TList[1]);
else
alias Filter = Nothing;
}
},
q{
static if (pred!(TList[0]))
{
static if (pred!(TList[1]))
{
static if (pred!(TList[2]))
alias Filter = AliasSeq!(TList[0], TList[1],
TList[2]);
else
alias Filter = AliasSeq!(TList[0], TList[1]);
}
else
{
static if (pred!(TList[2]))
alias Filter = AliasSeq!(TList[0], TList[2]);
else
alias Filter = AliasSeq!(TList[0]);
}
}
else
{
static if (pred!(TList[1]))
{
static if (pred!(TList[2]))
alias Filter = AliasSeq!(TList[1], TList[2]);
else
alias Filter = AliasSeq!(TList[1]);
}
else
{
static if (pred!(TList[2]))
alias Filter = AliasSeq!(TList[2]);
else
alias Filter = Nothing;
}
}
},
q{
static if (pred!(TList[0]))
{
static if (pred!(TList[1]))
{
static if (pred!(TList[2]))
{
static if (pred!(TList[3]))
alias Filter = AliasSeq!(TList[0],
TList[1], TList[2], TList[3]);
else
alias Filter = AliasSeq!(TList[0],
TList[1], TList[2]);
}
else
{
static if (pred!(TList[3]))
alias Filter = AliasSeq!(TList[0],
TList[1], TList[3]);
else
alias Filter = AliasSeq!(TList[0],
TList[1]);
}
}
else
{
static if (pred!(TList[2]))
{
static if (pred!(TList[3]))
alias Filter = AliasSeq!(TList[0],
TList[2], TList[3]);
else
alias Filter = AliasSeq!(TList[0],
TList[2]);
}
else
{
static if (pred!(TList[3]))
alias Filter = AliasSeq!(TList[0],
TList[3]);
else
alias Filter = AliasSeq!(TList[0]);
}
}
}
else
{
static if (pred!(TList[1]))
{
static if (pred!(TList[2]))
{
static if (pred!(TList[3]))
alias Filter = AliasSeq!(TList[1],
TList[2], TList[3]);
else
alias Filter = AliasSeq!(TList[1],
TList[2]);
}
else
{
static if (pred!(TList[3]))
alias Filter = AliasSeq!(TList[1],
TList[3]);
else
alias Filter = AliasSeq!(TList[1]);
}
}
else
{
static if (pred!(TList[2]))
{
static if (pred!(TList[3]))
alias Filter = AliasSeq!(TList[2],
TList[3]);
else
alias Filter = AliasSeq!(TList[2]);
}
else
{
static if (pred!(TList[3]))
alias Filter = AliasSeq!(TList[3]);
else
alias Filter = Nothing;
}
}
}
}
);
private enum filterExpandFactor = FilterShortCode.length;
package alias Nothing = AliasSeq!(); // yes, this really does
speed up compilation!
---
--- actual 3 liner ---
alias Numerics = AliasSeq!(byte, ubyte, short, ushort, int,
uint, long,
ulong, float, double, real, char, wchar, dchar);
enum convertsTo(T, U) = is(T : U);
alias ImplicitConversionTargets(T) =
Filter!(ApplyLeft!(convertsTo, T), Numerics);
pragma(msg, ImplicitConversionTargets!uint);
---
I would consider this illuminating in a way.
More information about the Digitalmars-d
mailing list