Now I'm trying to go in the other way - detecting when a parameter to a function is ref. I know the compiler has this information in the tuple because of stringof:
writef ("%s\n", ParameterTypeTuple! (void function (ref int))); // prints "(ref int)" But that information seems completely lost once you index or slice the tuple. While running a pure function on the stringof works, the compiler's behaving dodgily and I don't like having to trick it into giving me information. Anyone got some goods? The best would be a webpage detailing exactly what you need to do to get anything you need from the compiler. Here's the function I've built: /// Return whether the indexed argument to the function is defined as "ref". /// /// Params: /// I = The zero-based argument index. /// F = The function type. This will be passed to std.traits.ParameterTypeTuple, so anything that works there will work here. pure bool isRefArgument (int I, F) () { const P = ParameterTypeTuple! (F).stringof; static assert (P [0] == '('); for (size_t offset = 1, index = 0; ; index ++, offset ++) { for (int nest = 0; ; offset ++) { if (nest == 0 && index == I && offset + 4 < P.length && P [offset .. offset + 4] == "ref ") return true; else if (P [offset] == ')') { nest --; if (nest < 0) { if (index == I) return false; assert (0, "isRefArgument index is out of range for the function."); } } else if (P [offset] == ']' || P [offset] == '}') nest --; else if (P [offset] == '(' || P [offset] == '[' || P [offset] == '{') nest ++; else if (!nest && P [offset] == ',') { if (index == I) return false; break; } } } }