module mutils.traits; import std.traits; bool isForeachDelegateWithI(DG)() { return is(DG == delegate) && is(ReturnType!DG == int) && Parameters!DG.length == 2 && isIntegral!(Parameters!(DG)[0]); } unittest { assert(isForeachDelegateWithI!(int delegate(int, double))); assert(isForeachDelegateWithI!(int delegate(int, double) @nogc nothrow)); assert(!isForeachDelegateWithI!(int delegate(double, double))); } bool isForeachDelegateWithoutI(DG)() { return is(DG == delegate) && is(ReturnType!DG == int) && Parameters!DG.length == 1; } unittest { assert(isForeachDelegateWithoutI!(int delegate(int))); assert(isForeachDelegateWithoutI!(int delegate(size_t) @nogc nothrow)); assert(!isForeachDelegateWithoutI!(void delegate(int))); } bool isForeachDelegateWithTypes(DG, Types...)() { return is(DG == delegate) && is(ReturnType!DG == int) && is(Parameters!DG == Types); } unittest { assert(isForeachDelegateWithTypes!(int delegate(int, int), int, int)); assert(isForeachDelegateWithTypes!(int delegate(ref int, ref int), int, int)); assert(!isForeachDelegateWithTypes!(int delegate(double), int, int)); } auto assumeNoGC(T)(T t) if (isFunctionPointer!T || isDelegate!T) { enum attrs = functionAttributes!T | FunctionAttribute.nogc; return cast(SetFunctionAttributes!(T, functionLinkage!T, attrs)) t; }