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.

Reply via email to