Type functions with std.algorithm
Stefan Koch
uplink.coder at googlemail.com
Sun Oct 11 13:49:20 UTC 2020
On Sunday, 11 October 2020 at 10:19:56 UTC, Stefan Koch wrote:
> On Sunday, 11 October 2020 at 06:22:26 UTC, Petar Kirov
> [ZombineDev] wrote:
>>
>> Is there an issue with `std.array.array`, or you just prefer
>> manually converting the range to an array? Btw, dmd can
>> evaluate ranges at compile-time (e.g. in static foreach), so
>> .tupleof could potentially also do that (convert both ranges
>> and arrays of types to a tuples).
>
> Indeed there is an issue with std.array.array.
>
> ...
I found out what happens.
This is funky, so fasten your seatbelts :)
Here is the reproducible case:
---
@property ref inout(T) front(T)(return scope inout(T)[] a) @safe
pure nothrow @nogc
// if (!isAutodecodableString!(T[]) && !is(T[] == void[]))
commented out to avoid deps
{
assert(a.length, "Attempting to fetch the front of an empty
array of " ~ T.stringof);
return a[0];
}
template ElementType(R)
{
pragma(msg, "R: ", R, ", R.init: ", R.init, ",
typeof(R.init.front): ", typeof(R.init.front) );
static if (is(typeof(R.init.front.init) T))
alias ElementType = T;
else
alias ElementType = void;
}
pragma(msg, is(ElementType!(__type[]) == void));
pragma(msg, is(ElementType!(int[]) == void));
---
Which prints:
R: __type[], R.init: null, typeof(R.init.front): __type
true
R: int[], R.init: null, typeof(R.init.front): int
false
That tells us that the front wrapper works correctly.
range __type[] correctly returns a __type;
so R.init.front is a variable of type __type
which makes R.init.front.init be the type __emptyType.
the bug is that because __emptyType is a type
typeof(__emptyType) returns void, which is consistent with how
the language has treated types before type functions (they didn't
have a type).
So all I have to do is to teach that the type of any type is
__type.
And then everything will work!
More information about the Digitalmars-d
mailing list