| |
| Posted by vit in reply to Ali Çehreli | PermalinkReply |
|
vit
Posted in reply to Ali Çehreli
| 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:
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);
}
}
}
|