My design need friends

Namespace rswhite4 at googlemail.com
Sun Oct 6 02:24:48 PDT 2013


This is also nice.
My final construct now looks like this:

Friend:
----
module Core.Friend;

struct Friend {
public:
	immutable string FriendClass;
	immutable string FriendMethod;

	this(string friendClass, string friendMethod = null) {
		this.FriendClass = friendClass;
		this.FriendMethod = friendMethod;
	}
}
----

Accessor:
----
module Core.Accessor;

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

import Core.Friend;

class FriendException : Exception {
public:
	this(string msg, string file = __FILE__, size_t line = __LINE__, 
Throwable next = null) {
		super(msg, file, line, next);
	}
}

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

		immutable string ReqStr = __traits(identifier, Request);
		immutable string Tstr = __traits(identifier, T);

		static if (friends.length != 0 && is(typeof(friends[0]) == 
Friend)) {
			foreach (ref const Friend friend; friends) {
				if (friend.FriendClass == ReqStr) {
					if (friend.FriendMethod.length != 0 && method != 
friend.FriendMethod) {
						throw new FriendException(format("%s is a friend of %s but 
no friend of method %s.%s.",
														ReqStr, Tstr, Tstr, method));
					}

					mixin("return this." ~ method ~ "(args);");
				}
			}

			throw new FriendException(format("%s is not a friend of %s.", 
ReqStr, Tstr));
		} else {
			throw new FriendException(format("%s has no friends.", Tstr));
		}
	}
}
----

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

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

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

I'm in favor that something like that is really added to 
std.typecons.
And I should write a blog post about your and my solution. :)


More information about the Digitalmars-d-learn mailing list