My design need friends

Namespace rswhite4 at googlemail.com
Sat Oct 5 16:59:22 PDT 2013


Even better as mixin template:

Accessor:
----
module Core.Accessor;

import std.stdio;
import std.string : format;

import Core.Friend;

mixin template Accessor(T) {
public:
	void friendCall(string method, Request, Args...)(ref const 
Request caller, Args args) {
		auto friends = __traits(getAttributes, T);

		static if (friends.length != 0 && is(typeof(friends[0]) == 
Friend)) {
			foreach (ref const Friend friend; friends) {
				if (friend.friend == __traits(identifier, Request)) {
					mixin("return this." ~ method ~ "(args);");
				}
			}

			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)));
		}
	}
}
----

Drawable:
----
@Friend("Window") interface Drawable {
protected:
	void _render();

package:
	final void render() {
		this._render();
	}

public:
	mixin Accessor!Drawable;
}
----

And Window:
----
class Window {
public:
	void draw(Drawable d) {
		writeln("Window.draw");

		//d.render(); /// Error: interface Bar.Drawable.Drawable member 
render is not accessible
		d.friendCall!("render")(this);
	}
}
----

Perhaps something should be added to std.typecons.


More information about the Digitalmars-d-learn mailing list