I have some questions about "inout" qualifier. I treated this qualifier as duplicated code reducer without using templates. But it is a real part of type system with its own casting rules. Inside an inout function we have special type "inout(T)" with several restrictions. So the first question is: should I keep in mind that my generalized code can meet inout type and how to work with it?

For example, I have problems with the following code that, I suppose, should work.

class A {}

A foo(A x) // works
{
    Rebindable!(typeof(return)) r;
    r = x;
    return r;
}

const(A) foo(const(A) x) // works
{
    Rebindable!(typeof(return)) r;
    r = x;
    return r;
}

immutable(A) foo(immutable(A) x) // works
{
    Rebindable!(typeof(return)) r;
    r = x;
    return r;
}

inout(A) bar(inout(A) x) // compilation error
{
    Rebindable!(typeof(return)) r;
    r = x;
    return r;
}

Rebindable doesn't handle the case of inout type and I don't think that it can do it because it is possible to cast to inout or to keep inout variables only inside the proper inout function. So, I have to make some silly workarounds with castings in this case. The same situation happens in several places in phobos when arguments type is deductible. For example, std.array.replaceInPlace(...), std.array.join(...), etc, can not be used with inout(T) parameters.

The second question: if I want to provide inout function but it fails like in the example above, what is common practice? Just use casting? Or make a templated version and provide hand-writing code for all cases (mutable, const, immutable)? Or something wrong with inout qualifier?

Reply via email to