On Friday, 16 May 2014 at 16:58:38 UTC, Rainer Schuetze wrote:
On 14.05.2014 12:56, "Marc Schütz" <schue...@gmx.net>" wrote:
On Tuesday, 13 May 2014 at 19:50:52 UTC, Rainer Schuetze wrote:
class C { C next; }
shared(C) list;
C newC()
{
return new C; // allocated on the local heap?
Yes, because it doesn't say "new shared(C)".
}
void prependToList(C c)
{
synchronized(list)
{
C lst = cast(C) list;
c.next = lst; // anything special happening here?
list = cast(shared(C)) c; // and here?
The casts are a problem. You're basically lying to the
compiler, so this
cannot work. Instead, it should be something like:
auto newC() {
return new isolated(C);
}
void prependToList(isolated(C) c) {
synchronized(list) {
// transfer to shared heap
// afterwards, c is no longer usable ("consumed")
shared(C) tmp = c.makeShared();
tmp.next = list;
list = tmp;
}
}
Sorry for the late reply.
I currently don't know of a feasible way to replace casting
away "shared" if you want to do more than just "tmp.next =
list;", for example call "bool check(C c);" on tmp or list? I
can't implement this with a shared object, because any
operations on "shared" tend to not exist (ok, maybe I could for
this very simple example, so consider C contains a container to
operate on). Also, the object is already locked, I should not
have to do it again in a function if it only accepts a shared C.
How can I prepend something to the list that is not isolated? I
guess I cannot, as it might create references to same object
both shared and unshared.
My gut feeling tells me that this ownership handling through
the type system might work, but it is very restrictive and does
not really contribute to the first goal of D listed on the
front page: "convenience".
I haven't thought it through completely, of course, but I believe
it doesn't have to be inconvenient. Maybe there is a nice
solution. I already have something in mind, but I have to think
it over first.