On 7/10/18 10:34 AM, Timoses wrote:
How do I create an inout object with template parameters?
Take following code:
import std.stdio;
import std.traits;
struct S
{
int[] arr;
}
interface I
{
inout(I) opIndex(size_t idx) inout;
}
class Test(T) : I
{
// Error: variable
`onlineapp.Test!(inout(int)[]).Test.member` only parameters or stack
based variables can be inout
T member;
this(inout T mem) inout
{
this.member = mem;
}
inout(Test!T) get() inout
{
return new inout Test!(Unqual!(typeof(member)))(member);
}
inout(I) opIndex(size_t idx) inout
{
switch (idx)
static foreach (index, t; T.tupleof)
{
case index:
// Error: template instance
`onlineapp.Test!(inout(int)[])` error instantiating
return new inout
Test!(Unqual!(typeof(this.member.tupleof[index])))
(this.member.tupleof[index]);
default:
return null;
}
}
}
unittest
{
auto s = S([1,2,3]);
auto t = new const Test!S(s);
}
`Unqual` in this case just turns `inout(int[])` into `inout(int)[]`,
which is why it complains. That's a side effect of this example, however
the main question is how one would go about achieving something like
this idiomatically?
I would like to return a new object and that object should have the same
mutability as the one creating it.
You are overthinking :) inout typically is much easier than you expect,
until you need to create temporary structs or types with inout members,
then it becomes problematic.
https://run.dlang.io/is/kosYuC
I had to put in a static if, because your function doesn't work once you
get down to the array type. See the // fixme comment.
-Steve