My design need friends
Namespace
rswhite4 at googlemail.com
Sat Oct 5 16:13:56 PDT 2013
I have now a solution. A bit dirty but it's the D magic I
expected.
New file:
----
module Core.Friend;
struct Friend {
public:
immutable string friend;
}
----
Drawable looks now like this:
----
module Bar.Drawable;
import Core.Friend;
@Friend("Window") interface Drawable {
protected:
void _render();
package:
final void render() {
this._render();
}
}
----
And window looks like this:
----
class Window {
public:
void draw(Drawable d) {
writeln("Window.draw");
//d.render(); /// Error: interface Bar.Drawable.Drawable member
render is not accessible
Accessor.friendCall!(Window, "render")(d);
}
}
----
As you can see, we have now an 'Accessor':
----
module Bar.Accessor;
import std.stdio;
import std.string : format;
import Core.Friend;
abstract final class Accessor {
public:
static void friendCall(Request, string method, T, Args...)(ref T
obj, Args args) {
auto friend = __traits(getAttributes, T);
static if (friend.length != 0 && is(typeof(friend[0]) ==
Friend)) {
if (friend[0].friend == __traits(identifier, Request)) {
mixin("obj." ~ method ~ "(args);");
} else {
throw new Exception(format("%s is not a friend of %s.",
__traits(identifier, Request), __traits(identifier,
T)));
}
} else {
throw new Exception(format("%s has no friends.",
__traits(identifier, T)));
}
}
}
----
Any further suggestions or improvements?
----
More information about the Digitalmars-d-learn
mailing list