On Wednesday, 5 February 2014 at 13:38:08 UTC, dbjdbj wrote:


You can't. Classes are reference types. This just doesn't make sense: x2 = x_; does not create any new objects.

*object_alive* is what I mentioned, not object_create

Yes, but in your implementation you intend to increment both counters in opAssign.

therefore it does "make sense" ...  so  here it is again:

auto x_ = new X() , // created:1 , alive: 1
     x2 = x_      ; // created:1 , alive: 2

I tried (in all of my D innocence) to implement simple but effective counter from C++ side of the "wall" ... using the CRTP idiom ...

You just cannot reliably count references to class objects in D (at least, yet, see the ongoing discussions: http://forum.dlang.org/thread/lcrue7$1ho3$1...@digitalmars.com, http://forum.dlang.org/thread/grngmshdtwqfaftef...@forum.dlang.org).

For non-class objects, there is a library implementation, std.typecons.RefCounted.

With it, you can roll something similar:

import std.stdio;
import std.typecons;

struct Counter(T) if (!is(T == class)) {
    @disable this(this);
    @disable void opAssign(ref Counter);

    private static int objectsCreated_ = 0;
    private T x_;

    this(T x) { x_ = x; ++objectsCreated_; }

    static int getObjectsCreated() { return objectsCreated_; }

    @property ref auto get() inout { return x_; }

    alias get this;
}

auto counter(T,Args...)(ref auto Args args) if (!is(T == class)) {
    return RefCounted!(Counter!T)(T(args));
}

@property auto objectsCreated(O)(ref O o) if (is(O == RefCounted!(Counter!T), T)) {
    return o.getObjectsCreated();
}

@property auto numReferences(O)(ref O o) if (is(O == RefCounted!(Counter!T), T)) {
    return o.refCountedStore.refCount;
}

struct X { int v; }
struct Y { string s; }

void foo(ref const X x) {
    writefln("%s", x.v);
}

void bar(ref const Y y) {
    writefln("%s", y.s);
}

void main()
{
    auto x_ = counter!X, x2 = x_;
writefln("objects created: %s, num references: %s", x_.objectsCreated, x_.numReferences);
    foo(x_);

    auto y_ = counter!Y("hello"), y2 = y_;
    y2.s = "world"; // Modifies y_.s too
writefln("objects created: %s, num references: %s", y_.objectsCreated, y_.numReferences);
    bar(y_);
}


---

Note that e.g. typeof(x_) is actually RefCounted!(Counter!X).

But you cannot do similar for classes, because you cannot guard against escaping references.

Reply via email to