Build interface from abstract class

Simen Kjærås simen.kjaras at
Wed May 30 10:31:27 UTC 2018

On Monday, 28 May 2018 at 20:13:49 UTC, DigitalDesigns wrote:
> I do not think this is a problem in D. Infinite recursion can 
> always be terminated with appropriate means.
> 1. Use attributes. methods in class A should be marked as being 
> for the interface. When added to the interface they will not 
> have the attribute so will not be picked up again.
> 2. Your method of function creation does not pick up attributes 
> and other factors so it is weak.
> Here is my solution that does not solve problem 2:
> [Neat stuff]

Neat, but as you say it doesn't handle attributes or UDAs. The 
use of stringof is also a red flag - the same name can apply to 
different types in different scopes, and aliases may confuse it. 
Here's a version that solves both of those issues:

import std.array : join;
import std.meta : ApplyLeft, staticMap, Filter, Alias;
import std.traits;

enum isPublic(alias overload) = Alias!(__traits(getProtection, 
overload) == "public");

interface InterfaceFromClass(T, alias filter = isPublic)
     static foreach (overload; Filter!(filter, 
staticMap!(ApplyLeft!(MemberFunctionsTuple, T), 
__traits(derivedMembers, T))))
         mixin("@(__traits(getAttributes, overload)) 
"~attributes!overload~" ReturnType!overload 
"~__traits(identifier, overload)~"(Parameters!overload);");

string attributes(alias overload)()
     enum attrs = Filter!(ApplyLeft!(hasFunctionAttributes, 
         "pure", "nothrow", "ref", "@property", "@trusted", 
"@safe", "@nogc", "@system", "const", "immutable", "inout", 
"shared", "return", "scope");
     return [attrs].join(" ");

alias A = InterfaceFromClass!C;

abstract class C : A
     int n;
         @(3) ref int foo(ref int a) { return n; }
         @(19) @safe void bar() { }

// class D : C {}

static assert([__traits(allMembers, A)] == ["foo", "bar"]);
static assert(functionAttributes!( == 
static assert(functionAttributes!( == 
static assert(is(Parameters!( == Parameters!(;
static assert(is(Parameters!( == Parameters!(;

Note the link to issue 18915 (that's your 'string mixin output 
works...' post). I believe if we can fix that, the above should 


More information about the Digitalmars-d-learn mailing list