I'm having a lot of problems with meta when inout gets involved.
There's no std.traits that deal with inout, and I think that's a bit of a hole...
So my situation is, I have X captured by ReturnType!(T.f), and I also have T.
T.f is "inout(RT)[] f() inout { return ...; }"
I run into the situation where X == inout(RT)[]. I can't declare variables of that type, and it all goes wrong.
What I need to do, is transform X into RT[], const(RT)[] or immutable(RT)[] accordingly to T.
First problem, I can't work out how to detect if X is inout, I can't seem to craft an is() expression that works, and there's nothing in std.traits.
After that, I need to perform the substitution, and that's proving to be really tricky...
I think a std template could be created which will transform some type containing inout with the appropriate mutability level taken from some other type...
What I want is:
alias Y = SubstituteInout!(X, T); // copy the mutability of T where 'inout' appears in X
static assert(is(SubstituteInout!(inout(T)[], const(S)) == const(T)[]);
Can anyone suggest how I might write that template? I can't work it out >_<
I revisited this today, and realized it does not handle mixed qualifiers, like inout(const(int)*). As this is a rather big oversight, here's an improved implementation:
template SubstituteInout(FromType, ToType)
{
alias Modifiers(T) = CopyTypeQualifiers!(FromType, T);
alias Next(T) = SubstituteInout!(FromType, T);
static if (is(ToType U == immutable U)) alias SubstituteInout = immutable Next!U;
else static if (is(ToType U == shared inout const U)) alias SubstituteInout = shared const Modifiers!(Next!U);
else static if (is(ToType U == shared inout U)) alias SubstituteInout = shared Modifiers!(Next!U);
else static if (is(ToType U == shared const U)) alias SubstituteInout = shared const Next!U;
else static if (is(ToType U == shared U)) alias SubstituteInout = shared Next!U;
else static if (is(ToType U == inout const U)) alias SubstituteInout = const Modifiers!(Next!U);
else static if (is(ToType U == inout U)) alias SubstituteInout = Modifiers!(Next!U);
else static if (is(ToType U == const U)) alias SubstituteInout = const Next!U;
else static if (is(ToType U == U* )) alias SubstituteInout = Next!U*;
else static if (is(ToType U == U[] )) alias SubstituteInout = Next!U[];
else static if (is(ToType U == U[N], size_t N)) alias SubstituteInout = Next!U[N];
else static if (is(ToType U == U[K], K)) alias SubstituteInout = Next!U[Next!K];
else alias SubstituteInout = ToType;
}
unittest {
static assert(is(SubstituteInout!(const(string), int) == int));
static assert(is(SubstituteInout!(const(string), inout(int)[]) == const(int)[]));
static assert(is(SubstituteInout!(const(string), inout(int)) == const(int)));
static assert(is(SubstituteInout!(const(string), inout(int)*[][3][int]) == const(int)*[][3][int]));
static assert(is(SubstituteInout!(const(string), inout(int)[inout(string)]) == const(int)[const(string)]));
static assert(is(SubstituteInout!(const(int), inout(const(int)*)) == const(int*)));
static assert(is(SubstituteInout!(int, inout(const(int)*)) == const(int)*));
}
Comment #4 by robert.schadek — 2024-12-01T16:22:17Z