1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100
|
module traits_getVirtualIndex;
class VirtualIndexBase
{
protected int _foo;
int doubler()
{
return foo * 2;
}
@property int foo() const
{
return _foo;
}
@property void foo(int val)
{
_foo = val;
}
final void finalFunc()
{
}
}
class VirtualIndexDerived : VirtualIndexBase
{
@property override int foo() const
{
return super.foo;
}
@property override void foo(int val)
{
super.foo = val;
}
@property @safe int foo() pure nothrow
{
return _foo * 2;
}
final void otherFinalFunc()
{
}
}
final class VirtualIndexFinal : VirtualIndexDerived
{
@property final override int foo() const
{
return super.foo;
}
@property final override void foo(int val)
{
super.foo = val;
}
@property @safe final override int foo() pure nothrow
{
return super.foo;
}
}
private @property ptrdiff_t getIndex(T, string m, size_t index = 0)()
{
return __traits(getVirtualIndex, __traits(getOverloads, T, m)[index]);
}
void main()
{
ptrdiff_t doublerIndex = getIndex!(VirtualIndexBase, "doubler");
assert(doublerIndex > 0);
ptrdiff_t firstIndex = getIndex!(VirtualIndexBase, "foo", 0);
ptrdiff_t secondIndex = getIndex!(VirtualIndexBase, "foo", 1);
assert(firstIndex > 0 && secondIndex > 0);
// Virtual index is in definition order.
assert(secondIndex == firstIndex + 1);
assert(firstIndex == doublerIndex + 1);
ptrdiff_t finalIndex = getIndex!(VirtualIndexBase, "finalFunc");
assert(finalIndex == -1);
assert(getIndex!(VirtualIndexDerived, "doubler") == doublerIndex);
assert(getIndex!(VirtualIndexDerived, "foo", 0) == firstIndex);
assert(getIndex!(VirtualIndexDerived, "foo", 1) == secondIndex);
assert(getIndex!(VirtualIndexDerived, "finalFunc") == finalIndex);
assert(getIndex!(VirtualIndexDerived, "otherFinalFunc") == -1);
ptrdiff_t newOverloadIndex = getIndex!(VirtualIndexDerived, "foo", 2);
assert(newOverloadIndex == secondIndex + 1);
foreach(i, overload; __traits(getOverloads, VirtualIndexFinal, "foo"))
{
// It should still return the initial virtual index even if overridden to be final.
ptrdiff_t finalOverrideIndex = getIndex!(VirtualIndexFinal, __traits(identifier, overload), i);
ptrdiff_t originalIndex = getIndex!(VirtualIndexDerived, __traits(identifier, overload), i);
assert(finalOverrideIndex == originalIndex);
}
}
|