On 07/04/2017 05:52 PM, Jean-Louis Leroy wrote:
On Wednesday, 5 July 2017 at 00:28:01 UTC, Ali Çehreli wrote:
On 07/04/2017 04:57 PM, Jean-Louis Leroy wrote:
[...]
No time to dig deeper but this is because the two ranges that chain()
receives do not have a common type. (Rather, that type is 'void'):
[...]
I suspect that that is the reason, although I checked in several ways
that I had ClassInfo elements on both sides. Ok, I'll keep looking
tomorrow with a fresh eye...
This is related to TypeInfo.init, which unfortunately is *not* the .init
property in this case. :( Luckily, it will be fixed in 2.075. This is
what object.d has:
class TypeInfo
{
// ...
/**
* Return default initializer. If the type should be initialized
to all
* zeros, an array with a null ptr and a length equal to the type
size will
* be returned. For static arrays, this returns the default
initializer for
* a single element of the array, use `tsize` to get the correct size.
*/
abstract const(void)[] initializer() nothrow pure const @safe @nogc;
/// $(RED Removed.) Please use `initializer` instead.
@disable static const(void)[] init(); // since 2.074
/* Planned for 2.075: Remove init, making way for the init type
property,
fixing issue 12233. */
}
The problem is, ElementType relies on .init, which works on most other
type but not TypeInfo:
template ElementType(R)
{
static if (is(typeof(R.init.front.init) T))
alias ElementType = T;
else
alias ElementType = void;
}
So, unfortunately, most Phobos range functions cannot be used with
TypeInfo as they would invariably touch ElementType. Here is a halfway
workaround that uses each() instead of map(): :/
import std.algorithm;
class C {
}
void main() {
auto k = C.classinfo;
TypeInfo_Class[] arr;
each!(i => arr ~= i.classinfo)(k.interfaces);
arr ~= k.base;
}
Ali