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