clear()
Andrei Alexandrescu
SeeWebsiteForEmail at erdani.org
Fri Oct 9 09:40:43 PDT 2009
I'm talking with Sean and Walter about taking the first step towards
eliminating delete: defining function clear() that clears the state of
an object. Let me know of what you think.
One problem I encountered is that I can't distinguish between a default
constructor that doesn't need to exist, and one that was disabled
because of other constructors. Consider:
class A {}
class B { this(int) {} }
You can evaluate "new A" but not "new B". So it's legit to create
objects of type A all default-initialized. But the pointer to
constructor stored in A.classinfo is null, same as B.
Any ideas?
Andrei
===============================
void clear(T)(T obj) if (is(T == class))
{
auto defaultCtor =
cast(void function(Object)) obj.classinfo.defaultConstructor;
enforce(defaultCtor);
immutable size = obj.classinfo.init.length;
static if (is(typeof(obj.__dtor())))
{
obj.__dtor();
}
auto buf = (cast(void*) obj)[0 .. size];
buf[] = obj.classinfo.init;
defaultCtor(obj);
}
unittest
{
{
class A { string s = "A"; this() {} }
auto a = new A;
a.s = "asd";
clear(a);
assert(a.s == "A");
}
{
static bool destroyed = false;
class B {
string s = "B";
this() {}
~this() {
destroyed = true;
}
}
auto a = new B;
a.s = "asd";
clear(a);
assert(destroyed);
assert(a.s == "B");
}
{
class C {
string s;
this() {
s = "C";
}
}
auto a = new C;
a.s = "asd";
clear(a);
assert(a.s == "C");
}
}
void clear(T)(ref T obj) if (is(T == struct))
{
static if (is(typeof(obj.__dtor())))
{
obj.__dtor();
}
auto buf = (cast(void*) &obj)[0 .. T.sizeof];
auto init = (cast(void*) &T.init)[0 .. T.sizeof];
buf[] = init[];
}
unittest
{
{
struct A { string s = "A"; }
A a;
a.s = "asd";
clear(a);
assert(a.s == "A");
}
{
static bool destroyed = false;
struct B
{
string s = "B";
~this()
{
destroyed = true;
}
}
B a;
a.s = "asd";
clear(a);
assert(destroyed);
assert(a.s == "B");
}
}
void clear(T : U[n], U, size_t n)(/*ref*/ T obj)
{
obj = T.init;
}
unittest
{
int[2] a;
a[0] = 1;
a[1] = 2;
clear(a);
assert(a == [ 0, 0 ]);
}
void clear(T)(ref T obj)
if (!is(T == struct) && !is(T == class) && !isStaticArray!T)
{
obj = T.init;
}
unittest
{
{
int a = 42;
clear(a);
assert(a == 0);
}
{
float a = 42;
clear(a);
assert(isnan(a));
}
}
More information about the Digitalmars-d
mailing list