Introduction to traits (and __traits)

H. S. Teoh hsteoh at quickfur.ath.cx
Fri Aug 30 15:10:26 PDT 2013


On Fri, Aug 30, 2013 at 11:51:37PM +0200, bearophile wrote:
> Joseph Rushton Wakeling:
> 
> >    static if (!__traits(hasMember, G, "directed") ||
> >               !__traits(hasMember, G, "edge") ||
> >               !__traits(hasMember, G, "edgeCount") ||
> >               !__traits(hasMember, G, "vertexCount") ||
> >               !__traits(hasMember, G, "isEdge") ||
> >               !__traits(hasMember, G, "edgeID") ||
> >               !__traits(hasMember, G, "addEdge") ||
> >               !__traits(hasMember, G, "degreeIn") ||
> >               !__traits(hasMember, G, "degreeOut") ||
> >               !__traits(hasMember, G, "incidentEdgesIn") ||
> >               !__traits(hasMember, G, "incidentEdgesOut") ||
> >               !__traits(hasMember, G, "neighboursIn") ||
> >               !__traits(hasMember, G, "neighboursOut"))
> 
> Perhaps can shorten that code writing a hasMembers helper (and I
> suggest to keep those names sorted):
[...]

Here's a first stab at a possible implementation:

	/* Warning: untested code */

	import std.typetuple : allSatisfy;

	template isString(T) {
		// There may already be something in Phobos that does
		// this, but I'm too lazy to look.
		enum isString = is(T == string);
	}

	template hasMembers(alias T, Members...)
		if (allSatisfy!isString(Members))
	{
		// Template recursion + exprTuple slicing FTW :)
		enum hasMembers = __traits(hasMember, T, Members[0]) &&
			hasMembers!(T, Members[1..$]);
	}

	void myFunc(G)(G graph)
	{
		static if (hasMembers!(G, "directed", "edge", /* ... */))
		{
			...
		}
	}


T

-- 
Computers shouldn't beep through the keyhole.


More information about the Digitalmars-d-learn mailing list