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); } }