Bug 13428 – Add template to perform appropriate substitution for inout when it appears in a type

Status
NEW
Severity
enhancement
Priority
P4
Component
phobos
Product
D
Version
D2
Platform
All
OS
All
Creation time
2014-09-06T07:48:47Z
Last change time
2024-12-01T16:22:17Z
Keywords
industry, pull
Assigned to
No Owner
Creator
Manu
Moved to GitHub: phobos#10082 →

Comments

Comment #0 by turkeyman — 2014-09-06T07:48:47Z
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 >_<
Comment #1 by simen.kjaras — 2017-09-17T01:02:50Z
import std.traits; template SubstituteInout(FromType, ToType) { static if (is(ToType == inout(SubType), SubType)) { alias SubstituteInout = CopyTypeQualifiers!(FromType, SubType); } else static if (is(ToType == SubType*, SubType)) { alias SubstituteInout = SubstituteInout!(FromType, SubType)*; } else static if (is(ToType == SubType[], SubType)) { alias SubstituteInout = SubstituteInout!(FromType, SubType)[]; } else static if (is(ToType == SubType[n], SubType, size_t n)) { alias SubstituteInout = SubstituteInout!(FromType, SubType)[n]; } else static if (is(ToType == SubType[KeyType], SubType, KeyType)) { alias SubstituteInout = SubstituteInout!(FromType, SubType)[SubstituteInout!(FromType, KeyType)]; } 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)])); }
Comment #2 by dlang-bot — 2019-06-10T07:37:52Z
@thewilsonator created dlang/phobos pull request #7062 "Fix issue 13428: add substituteInout" fixing this issue: - Fix issue 13428: add substituteInout https://github.com/dlang/phobos/pull/7062
Comment #3 by simen.kjaras — 2019-08-16T10:50:06Z
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
THIS ISSUE HAS BEEN MOVED TO GITHUB https://github.com/dlang/phobos/issues/10082 DO NOT COMMENT HERE ANYMORE, NOBODY WILL SEE IT, THIS ISSUE HAS BEEN MOVED TO GITHUB