I have made an owner type that wraps malloc'd pointers with custom destroy functions from a C library and utilizes RefCounted
for safety. I would like to be able to use the owner type Memory
implicitly as its underlying pointer type via alias this
.
struct Memory(T, alias destroy)
if(!isPointer!T && isSomeFunction!destroy)
{
@safe:
/// Pointer Wrapper
struct Ptr
{
/// data pointer
T * ptr;
/// no copying this as that could result
/// in premature destruction
@disable this(this);
/// destroy
~this() @trusted
{
/// if destroy function return is void
/// just destroy
/// else if int
/// destroy then check return value
/// else don't compile
static if(is(ReturnType!destroy == void))
destroy(this.ptr);
else static if(is(ReturnType!destroy == int))
{
auto success = destroy(this.ptr);
if(!success) hts_log_error(__FUNCTION__,"Couldn't destroy "~T.stringof~" * data using function "~destroy.stringof);
}else{
static assert(0, "Memory doesn't recognize destroy function return type");
}
}
}
/// reference counted Ptr
RefCounted!(Ptr, RefCountedAutoInitialize.yes) rcPtr;
/// get underlying data pointer
/// copied from RefCounted implementation
@property nothrow pure @nogc
ref inout(T*) getPtr() inout return
{
return rcPtr.refCountedPayload.ptr;
}
/// allow Memory to be used as
/// underlying ptr type
alias getPtr this;
/// ctor from raw pointer
this(T * rawPtr) @trusted
{
auto wrapped = Ptr(rawPtr);
move(wrapped,this.rcPtr.refCountedPayload);
}
}
With alias this
I can use auto rc = Memory!(ctype, ctype_destroy)(ctype_init());
(where ctype_destroy
and ctype_init
are C bindings) and then ctype * ptr = rc;
. This is great since I can pass rc
directly to c functions that accept ctype *
. But how do I either: ensure rc
stays in scope or have compile-time protection against escaping ptr
past the lifetime of rc
. Is this possible with either scope
or @live
? Could I add attributes to the C bindings to help with this?