Optional type - how to correctly reset a wrapped immutable T

aliak something at something.com
Tue Mar 27 06:16:07 UTC 2018


On Sunday, 25 March 2018 at 23:00:11 UTC, Simen Kjærås wrote:
> On Sunday, 25 March 2018 at 21:26:57 UTC, aliak wrote:
>> struct Optional(T) {
>>   Unqual!T value;
>>   opAssign(T t) {
>>     value = cast(Unqual!T)(t);
>>   }
>> }
>
> Consider this case:
>
> Optional!(immutable int) a = some(3);
> immutable int* p = &a.value;
> a = some(5);

Ahh, bugger.

> As for the problems you've had with inout, I wrote this 
> template a few years back:

This template seems to substitute type qualifiers from the 
FromType to any inout qualifiers in the ToType yes? I'm not sure 
how I'd use this actually. I would like to support the inout 
usecase when a user does

Optional!(inout int) a = 3; // for e.g.

I guess for that template I'd need to have some extra information 
that tells me what to substitute inout with yeah?

> Of course, if Optional offers no way to get a reference to the 
> wrapped value (say, if a.value is an @property function that 
> doesn't return ref T), then using Unqual internally is safe*.

This thought crossed my mind as well, value should be private 
anyway, and there's an unwrap function that provides a pointer to 
the value if it exists, so I wouldn't know how to get around that 
(return a dynamic array with one or no element that contains a 
copy and only if it's immutable, else return a pointer? erm ... 
O_o ) and then I was thinking compiler optimizations may throw in 
wrench in that if I did find a way around.

> unittest {
>     immutable a = Foo(new int(3));
>     assert(*a.p == 3); // Passes
>     Optional!(immutable(Foo)) b;
>     b = a;
>     assert(*a.p == 3); // Fails
> }
>
> There actually is a workaround for this, using destroy() and 
> move() instead of assignment. I'm unsure if there are other 
> corner cases to consider.

I'm curious what the move/destroy workaround would be?

Cheers,
- Ali





More information about the Digitalmars-d-learn mailing list