How to move from Unique(someClass) to Unique(someInterface)?

Gregor Mückl gregormueckl at gmx.de
Tue Nov 29 00:06:13 UTC 2022


On Monday, 28 November 2022 at 02:40:28 UTC, Tejas wrote:
> On Sunday, 27 November 2022 at 17:06:31 UTC, vushu wrote:
>> On Saturday, 16 May 2020 at 17:45:56 UTC, Konstantin wrote:
>>> [...]
>>
>> I'm actually also very curious about this issue, since I come 
>> from c++ where this is possible, and it is a very common 
>> functionality for example for dependency inversion and 
>> dependency injection or mocking. It would be very nice to have 
>> this working.
>
> I _think_ it's not working here because `Unique` is a `struct`, 
> so there's no concept of inheritance here, meanwhile that it 
> possible in `C++`

It should be possible to make template structs 
assignable/initializable from a compatible wrapped type with a 
custom constructor and a custom opAssign. There is a bit of 
fiddling with constraints involved to prohibit implicit casting 
of the wrapped type in ways that shouldn't work. See this 
incomplete proof of concept:

```d
interface IFoo { }
class Foo : IFoo { }

struct Unique(T) {
     T value;

     // This should check that T2 is another instantiation of 
Unique instead of this compiles trait
     this(T2)(T2 v) if(!__traits(compiles, this.value = v.value))
     {
         this.value = v;
     }

     this(T2)(Unique!T2 other) if(__traits(compiles, this.value = 
other.value))
     {
         this.value = other.value;
     }

     void opAssign(T2)(Unique!T2 other) {
         value = other.value;
     }
}

void main()
{
     IFoo foo = new Foo();

     Unique!IFoo f = Unique!Foo();
     //Unique!IFoo f2 = Unique!int(); // error: assignment from 
incompaatible type
}
```

The reason why automem.Unique doesn't support this is probably 
hidden within the intended behavior of Unique. Maybe Adam Ruppe 
can shed some light on this.


More information about the Digitalmars-d-learn mailing list