www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Scope with owner types

reply Thomas Gregory <charles.gregory940 topper.wku.edu> writes:
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?
Sep 20 2021
parent Kagamin <spam here.lot> writes:
Yes, the `return` attribute is what should do it. You also need 
to compile the code with -dip1000 option.
Sep 23 2021