import std.stdio;
import std.c.stdlib;
T o_new(T, U...)(U args) if (is(T == class))
{
size_t sz = __traits(classInstanceSize, T);
void[] mem = calloc(sz, byte.sizeof)[0 .. sz];
if (mem.length < sz) return null;
auto ret = cast(T) mem.ptr;
(cast(byte[]) mem)[0 .. sz] = typeid(T).init[];
static if (is(typeof(ret.__ctor(args))))
ret.__ctor(args);
else
{
static assert(
args.length == 0 && !is(typeof(&T.__ctor)),
"No ctor with arguments " ~ U.stringof ~
" present for an object of type " ~ T.stringof
);
}
return ret;
}
void o_delete(T)(T val) if (is(T == class))
{
static if (is(typeof(val.__dtor())))
val.__dtor();
free(cast(void*) val);
}
class Foo
{
void bah() { writeln("foo"); }
~this()
{
writeln("dtor");
}
}
void main()
{
Foo x = o_new!Foo();
x.bah();
o_delete(x);
}
aW1wb3J0IHN0ZC5zdGRpbzsKaW1wb3J0IHN0ZC5jLnN0ZGxpYjsKClQgb19uZXcoVCwgVS4uLikoVSBhcmdzKSBpZiAoaXMoVCA9PSBjbGFzcykpCnsKICAgIHNpemVfdCBzeiAgPSBfX3RyYWl0cyhjbGFzc0luc3RhbmNlU2l6ZSwgVCk7CiAgICB2b2lkW10gbWVtID0gY2FsbG9jKHN6LCBieXRlLnNpemVvZilbMCAuLiBzel07CgogICAgaWYgKG1lbS5sZW5ndGggPCBzeikgcmV0dXJuIG51bGw7CgogICAgYXV0byByZXQgPSBjYXN0KFQpIG1lbS5wdHI7CiAgICAoY2FzdChieXRlW10pIG1lbSlbMCAuLiBzel0gPSB0eXBlaWQoVCkuaW5pdFtdOwoKICAgIHN0YXRpYyBpZiAoaXModHlwZW9mKHJldC5fX2N0b3IoYXJncykpKSkKICAgICAgICByZXQuX19jdG9yKGFyZ3MpOwogICAgZWxzZQogICAgewogICAgICAgIHN0YXRpYyBhc3NlcnQoCiAgICAgICAgICAgIGFyZ3MubGVuZ3RoID09IDAgJiYgIWlzKHR5cGVvZigmVC5fX2N0b3IpKSwKICAgICAgICAgICAgIk5vIGN0b3Igd2l0aCBhcmd1bWVudHMgIiB+IFUuc3RyaW5nb2YgfgogICAgICAgICAgICAiIHByZXNlbnQgZm9yIGFuIG9iamVjdCBvZiB0eXBlICIgfiBULnN0cmluZ29mCiAgICAgICAgKTsKICAgIH0KCiAgICByZXR1cm4gcmV0Owp9Cgp2b2lkIG9fZGVsZXRlKFQpKFQgdmFsKSBpZiAoaXMoVCA9PSBjbGFzcykpCnsKICAgIHN0YXRpYyBpZiAoaXModHlwZW9mKHZhbC5fX2R0b3IoKSkpKQogICAgICAgIHZhbC5fX2R0b3IoKTsKCiAgICBmcmVlKGNhc3Qodm9pZCopIHZhbCk7Cn0KCmNsYXNzIEZvbwp7CiAgICB2b2lkIGJhaCgpIHsgd3JpdGVsbigiZm9vIik7IH0KCiAgICB+dGhpcygpCiAgICB7CiAgICAgICAgd3JpdGVsbigiZHRvciIpOwogICAgfQp9Cgp2b2lkIG1haW4oKQp7CiAgICBGb28geCA9IG9fbmV3IUZvbygpOwogICAgeC5iYWgoKTsKCiAgICBvX2RlbGV0ZSh4KTsKfQo=