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