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);
            }
        }
    }



```

Reply via email to