forward tuple arg to local variable + dtor

vit vit at vit.vit
Sat Jan 22 18:00:58 UTC 2022


On Saturday, 22 January 2022 at 17:23:12 UTC, Ali Çehreli wrote:
> On 1/22/22 07:17, vit wrote:
>
> > Why local variable of type tuple call destructors immediately
> after
> > initialization?
>
> I don't even understand where the local variable comes from. If 
> you want a pair of Foo objects, I would use std.typeconst.Tuple.
>
> Otherwise I would use AliasSeq as I understand it like the 
> following:
>
>         alias tup = AliasSeq!(Foo, Foo);
>
>         static foreach(Type; tup) {{
>           Type x;
>           writeln("check(", x.i, "): ", cast(void*)&x);
>         }}
>
> So, to me, AliasSeq!(Foo, Foo) is just a pair of types. I 
> instantiate an object for each type individually and use it 
> inside.
>
> Ali

I want implement something like this:

```d
import std.stdio : writeln;
import std.meta : AliasSeq, staticMap;
import core.memory : pureMalloc, pureFree;
import core.lifetime : emplace, forward;


     void main()@safe{
         auto rc1 = RcPtr!int.make(1);	//ref counted pointer

         long result = 0;

         //apply can be @safe
         apply!((ref int a, ref long b){
             rc1 = null;	//apply has copy of rc1, a is not 
dangling reference
         	result = a + b;

         })(rc1, RcPtr!long.make(2));

         assert(result == 3);
     }

     //@safe access to data of multiple ref counted objects:
     public auto apply(alias fn, Args...)(scope auto ref Args 
args){
     	Args params = forward!args;	//copy lvalue and move rvalue 
args

     	@property auto ref elm(alias param)()@trusted{
     		return param.get();
     	}

     	return fn(staticMap!(elm, params));

     }

     //simple implementation of ref counted pointer
     struct RcPtr(T){

     	private Payload* payload;

         private this(Payload* payload)@safe{
             this.payload = payload;
         }

         //copy ctor
         public this(ref typeof(this) rhs){
         	this.payload = rhs.payload;
             if(payload)
                 payload.count += 1;
         }

         //make data
         public static auto make(Args...)(auto ref Args args){
             Payload* payload = ()@trusted{
                 return cast(Payload*)pureMalloc(Payload.sizeof);
             }();
             emplace(payload, forward!args);
         	return RcPtr(payload);	
         }

         public ~this(){
             this.opAssign(null);
         }

         //release payload
         void opAssign(typeof(null) nil){
             if(payload){
             	payload.count -= 1;
                 if(payload.count == 0){
                     destroy(*payload);
                     ()@trusted{
                     	pureFree(payload);
                     }();
                     payload = null;
                 }
             }
         }

         //
         ref T get()@system{
         	assert(payload);
             return payload.data;
         }

         private struct Payload{
             int count = 1;
             T data;

             this(Args...)(auto ref Args args){
                 data = T(forward!args);
             }
         }
     }



```


More information about the Digitalmars-d-learn mailing list