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