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;
                                }
                        }
                }
        }

Reply via email to