TypeFunction example: filtering types
Stefan Koch
uplink.coder at googlemail.com
Thu Oct 8 10:59:23 UTC 2020
Hi there,
Atlia just wrote of what he thinks first class type should allow
him to do:
https://forum.dlang.org/post/uscehdzicfluyjyspocm@forum.dlang.org
Luckily he does not actually require first class types for this.
type functions do exactly what he wants.
he wrote:
----
import std.algorithm: filter, equal;
type[] types = [int, uint, long, ulong];
auto size4 = types.filter!(a => a.sizeof == 4);
assert(equal(size4, [int, uint]));
---
that of course won't compile because the assert has to be a
static assert.
also the array literal of types is currently unsupported.
and for some reason isInputRange fails to instantiate for
`alias[]`
which means we can't use phobos directly.
So we have to implement phobos filter and phobos equal ourselves.
Similarly `==` is not defined for types right now ... and I don't
see how it makes sense,
given we have the is expression ... which means we have to pass a
predicate to equals.
Other than that, his code runs with type functions right now!
---
alias type = alias;
type[] makeTypeArray(type[] types ...)
{
return types;
}
// has to be written because right now, alias.init is the
errorType;
// which means that is() and __traits(compiles) may fail if
alias.init is used.
auto filter(alias pred, E)(E array) if (is(typeof(E.init[0]) ==
alias))
{
E result;
size_t len;
result.length = array.length;
foreach(e;array)
{
if (pred(e))
{
result[len++] = e;
}
}
return result[0 .. len];
}
bool equal(alias pred, E)(E array1, E array2) if
(is(typeof(E.init[0]) == alias))
{
if (array1.length != array2.length)
return false;
immutable len = array1.length;
foreach(i; 0 .. len)
{
if (!pred(array1[i], array2[i]))
{
return false;
}
}
return true;
}
enum type[] types = makeTypeArray(int, uint, long, ulong);
pragma(msg, makeTypeArray(int, uint, long, ulong).tupleof);
enum type[] size4 = types.filter!((type a) => a.sizeof == 4);
static assert(equal!((type a, type b) => is(a == b)) (size4,
makeTypeArray(int, uint)));
pragma(msg, size4); // unsurprisingly prints [(int), (uint)]
---
Cheers,
Stefan
More information about the Digitalmars-d
mailing list