Scope with owner types

Thomas Gregory charles.gregory940 at topper.wku.edu
Mon Sep 20 15:44:50 UTC 2021


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?


More information about the Digitalmars-d-learn mailing list