Thanks, I think I get it. const and postblit don't mix. Copy
ctors don't yet exist but are the hoped for solution to inability
to copy const instances. Copy ctor proposal/solution has not yet
been written up in the newsgroups or details discussed beyond
Andrei and Walter, but have been and maybe still are being worked.
I wish I knew more about the copy ctor proposal.
Here is the issue that haunts me: Say it is January 15 and we
have:
module goo;
struct Goo {
int x = 42;
}
module foo;
struct Foo {
char[] c;
Goo goo;
this(ref const(Foo) other) {
c = other.dup;
goo = other;
}
}
February comes around and developers of Goo want to introduce a
new private member *int[int] ageToWeight*. Now foo won't compile,
because Goo does not also have a copy constructor and went from
value semantics to reference semantics in the change. This seems
very fragile - but maybe that is not the proposal. I guess I was
just hoping copying of const can be taken out of the struct's
hands entirely. Contrast that situation with the state on
February with a proper global dup. There is no copy ctor problem,
no postblit issue. Using something other than the copy ctor and
postblit to do the copy of the const has greatly reduced effort.
This code below does work right now the way you would expect. I'm
not saying it is a panacea - I've only tried it out a bit, but
you have to admit a global dup like function that could copy
*any* const you throw at it might put this entire issue to rest
without the need for any change. Mine could do not that; I'm
specifically avoiding classes. But I don't know what inherent
limitation would prevent it. Even if you were concerned with some
type T that had its own low level memory management, you could
still have it provide it's own dup with a proper const qualifier,
which gdup could call in preference to a recursive call to gdup.
You mention that possibly postblits will go away. That is
discomforting.
In terms of priority, where does this fall?
Thanks
Dan
-----------------------------------------
import std.stdio;
import std.traits;
import opmix.mix;
struct Goo {
private int[int] ageToWeight;
int x = 42;
}
struct Foo {
char[] c;
Goo goo;
}
void main() {
Foo foo = { ['a'], Goo([15:123, 30:180, 45:195]) };
auto copy = foo.gdup;
// No sharing of c and ageToWeight copied
assert(copy.c.ptr != foo.c.ptr &&
copy.goo.ageToWeight == foo.goo.ageToWeight);
// No sharing of ageToWeight
copy.goo.ageToWeight[70] = 178;
assert(copy.goo.ageToWeight != foo.goo.ageToWeight);
writeln(foo.gdup);
}
-------------------------------------------
Thanks,
Dan