www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Type functions example printing class hierarchy

reply Stefan Koch <uplink.coder googlemail.com> writes:
Hi there,

In a previous thread I talked about how pattern-matching is 
expressions are a pain to implement for type functions.
So I've taken the liberty to add an additional __trait to get the 
super type
Below is an example of how it might be used to visualize a class 
hierarchy
---
class A {}
class B : A {}
class C : A {}

string class_hierarchy(alias T)
{
     string result;

     alias super_type;
     // for now this is a typefunction-only __trait
     super_type = __traits(getSuperType, T);
     while(is(super_type))
     {
         result ~= T.stringof ~ " -> " ~ super_type.stringof ~ 
"\n";
         T = super_type;
         super_type = __traits(getSuperType, T);
     }

     return result;
}

pragma(msg, "class_hierarchy(A): \n", class_hierarchy(A));
pragma(msg, "class_hierarchy(B): \n", class_hierarchy(B));
pragma(msg, "class_hierarchy(C): \n", class_hierarchy(C));
---

Of which the output is:

class_hierarchy(A):
A -> Object

class_hierarchy(B):
B -> A
A -> Object

class_hierarchy(C):
C -> A
A -> Object

If there any questions about how this works please fire away.

Cheers, Stefan

PS. the addition of __traits(getSuperType) added 90 lines of code.
I think that's a worthwhile treat-off
Aug 21 2020
next sibling parent Stefan Koch <uplink.coder googlemail.com> writes:
On Friday, 21 August 2020 at 16:19:36 UTC, Stefan Koch wrote:
 I think that's a worthwhile treat-off
I meant trade-off ... or maybe trait-off ?
Aug 21 2020
prev sibling next sibling parent Stefan Koch <uplink.coder googlemail.com> writes:
On Friday, 21 August 2020 at 16:19:36 UTC, Stefan Koch wrote:

 class_hierarchy(A):
 A -> Object

 class_hierarchy(B):
 B -> A
 A -> Object

 class_hierarchy(C):
 C -> A
 A -> Object
Also I would have liked to write a template which produces the same output; So I could show it as a comparison. But I could not get it to work, (which is one data-point) So If anyone how is more adapt at using recursive templates than me could provide an implementation, that'd be nice.
Aug 21 2020
prev sibling parent Stefan Koch <uplink.coder googlemail.com> writes:
On Friday, 21 August 2020 at 16:19:36 UTC, Stefan Koch wrote:
 Hi there,

 In a previous thread I talked about how pattern-matching is 
 expressions are a pain to implement for type functions.
 So I've taken the liberty to add an additional __trait to get 
 the super type
 Below is an example of how it might be used to visualize a 
 class hierarchy
 ---
 class A {}
 class B : A {}
 class C : A {}

 string class_hierarchy(alias T)
 {
     string result;

     alias super_type;
     // for now this is a typefunction-only __trait
     super_type = __traits(getSuperType, T);
     while(is(super_type))
     {
         result ~= T.stringof ~ " -> " ~ super_type.stringof ~ 
 "\n";
         T = super_type;
         super_type = __traits(getSuperType, T);
     }

     return result;
 }

 pragma(msg, "class_hierarchy(A): \n", class_hierarchy(A));
 pragma(msg, "class_hierarchy(B): \n", class_hierarchy(B));
 pragma(msg, "class_hierarchy(C): \n", class_hierarchy(C));
 ---

 Of which the output is:

 class_hierarchy(A):
 A -> Object

 class_hierarchy(B):
 B -> A
 A -> Object

 class_hierarchy(C):
 C -> A
 A -> Object

 If there any questions about how this works please fire away.

 Cheers, Stefan

 PS. the addition of __traits(getSuperType) added 90 lines of 
 code.
 I think that's a worthwhile treat-off
Here's the recursive template: template type_h_template(T) { static if (is(T S == super) && S.length) { enum type_h_template = ( T.stringof ~ " -> " ~ S[0].stringof ~ "\n" ~ .type_h_template!(S) ); } else { enum type_h_template = ""; } } Which looks less jarring than I first thought.
Aug 21 2020