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

Reply via email to