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