[Issue 1826] TransitiveBaseTypeTuple skips interfaces implemented by base types
d-bugmail at puremagic.com
d-bugmail at puremagic.com
Sat Feb 9 09:08:09 PST 2008
http://d.puremagic.com/issues/show_bug.cgi?id=1826
andrei at metalanguage.com changed:
What |Removed |Added
----------------------------------------------------------------------------
AssignedTo|bugzilla at digitalmars.com |andrei at metalanguage.com
------- Comment #1 from andrei at metalanguage.com 2008-02-09 11:08 -------
That was pretty silly of me; thanks for the report. I fixed the bug by adding
InterfacesTuple!(T) to return all interfaces directly or indirectly inherited
by T (without duplicates), and by using that in TransitiveBaseTypesTuple!(T).
In case you are in a hurry, I paste the two templates (the new one and the
modified one) below.
/**
* Get a $(D_PARAM TypeTuple) of $(I all) interfaces directly or
* indirectly inherited by this class or interface. Interfaces do not
* repeat if multiply implemented. $(D_PARAM InterfacesTuple!(Object))
* yields the empty type tuple.
*
* Example:
* ---
* import std.traits, std.typetuple, std.stdio;
* interface I1 { }
* interface I2 { }
* class A : I1, I2 { }
* class B : A, I1 { }
* class C : B { }
*
* void main()
* {
* alias InterfacesTuple!(C) TL;
* writeln(typeid(TL)); // prints: (I1, I2)
* }
* ---
*/
template InterfacesTuple(T)
{
static if (is(T == Object))
{
alias TypeTuple!() InterfacesTuple;
}
static if (is(BaseTypeTuple!(T)[0] == Object))
{
alias TypeTuple!(BaseTypeTuple!(T)[1 .. $]) InterfacesTuple;
}
else
{
alias NoDuplicates!(
TypeTuple!(BaseTypeTuple!(T)[1 .. $], // direct interfaces
InterfacesTuple!(BaseTypeTuple!(T)[0])))
InterfacesTuple;
}
}
unittest
{
{
// doc example
interface I1 { }
interface I2 { }
class A : I1, I2 { }
class B : A, I1 { }
class C : B { }
alias InterfacesTuple!(C) TL;
assert(is(TL[0] == I1) && is(TL[1] == I2));
}
interface I1 {}
interface I2 {}
class B1 : I1, I2 {}
class B2 : B1, I1 {}
class B3 : B2, I2 {}
alias InterfacesTuple!(B3) TL;
//
assert(TL.length == 2);
assert(is (TL[0] == I2));
assert(is (TL[1] == I1));
}
/**
* Get a $(D_PARAM TypeTuple) of $(I all) base classes of $(D_PARAM
* T), in decreasing order, followed by $(D_PARAM T)'s
* interfaces. $(D_PARAM TransitiveBaseTypeTuple!(Object)) yields the
* empty type tuple.
*
* Example:
* ---
* import std.traits, std.typetuple, std.stdio;
* interface I { }
* class A { }
* class B : A, I { }
* class C : B { }
*
* void main()
* {
* alias TransitiveBaseTypeTuple!(C) TL;
* writeln(typeid(TL)); // prints: (B,A,Object,I)
* }
* ---
*/
template TransitiveBaseTypeTuple(T)
{
static if (is(T == Object))
alias TypeTuple!() TransitiveBaseTypeTuple;
else
alias TypeTuple!(BaseClassesTuple!(T),
InterfacesTuple!(T))
TransitiveBaseTypeTuple;
}
unittest
{
interface I1 {}
interface I2 {}
class B1 {}
class B2 : B1, I1, I2 {}
class B3 : B2, I1 {}
alias TransitiveBaseTypeTuple!(B3) TL;
assert(TL.length == 5);
assert(is (TL[0] == B2));
assert(is (TL[1] == B1));
assert(is (TL[2] == Object));
assert(is (TL[3] == I1));
assert(is (TL[4] == I2));
assert(TransitiveBaseTypeTuple!(Object).length == 0);
}
--
More information about the Digitalmars-d-bugs
mailing list