I created the following code that some of you have already seen. It's sort of a multiple value AA array with self tracking.

The problem is, that for some type values, such as delegates, the comparison is is identical. (basically when the delegate is the same)

To solve that problem, I'd like to try and turn the Value into Tuples of the Value and the address of the SingleStore wrapper(which should be unique).

e.g.,
public Tuple!(TValue, void*)[][TKey] Store;

then I'll simply compare the value and address stored with the this(inside single store) instead of just this.

Of course, this requires somewhat of a rewrite of the code(trying it produced all kinds of errors(I tried to fix up all the references and correlated variables but still a mess, specially with D's error codes).

It shouldn't be that much trouble though. Essentially where ever I access the value, I want to instead of use value from the tuple(a single indirection).

Probably not that easy though?



import std.stdio;
import std.concurrency;



extern (C) int getch();
import std.string;
import std.concurrency;
import core.time;
import core.thread;
import std.container.array;
import std.typecons;







public class SingleStore(TKey, TValue)
{
        public TValue Value;
        public TKey Key;        
        public TValue[][TKey] Store;


// Duplicate entries will be removed together as there is no way to distinguish them
        public auto Remove()
        {
                import std.algorithm;
                if (Value == null || Key == null) return;
                int count = 0;
                for(int i = 0; i < Store[Key].length;i++)
                {
                        auto c = Store[Key][i];
                        if (c == Value)
                        {
                                        count++;
Store[Key][i] = null; // Set to null to release any references if necessary swap(Store[Key][i], Store[Key][max(0, Store[Key].length - count)]);
                                        i = i - 1;
                        }


                }
                if (count == 1 && Store[Key].length == 1)
                {
                        Store[Key] = null;
                        Store.remove(Key);
                } else
                        Store[Key] = 
Store[Key][0..max(0,Store[Key].length-count)];

                Value = null;
                Key = null;

        }

        public static auto New(TKey k, TValue v, ref TValue[][TKey] s)
        {
                auto o = new SingleStore!(TKey, TValue)(k, v);  
                o.Store = s;
                return o;
        }

        private this(TKey k, TValue v)
        {
                Key = k;
                Value = v;
        }
}


// Creates a static Associative Array that stores multiple values per key. The object returned by New can then be used to remove the key/value without having to remember specifically them.
public mixin template ObjectStore(TKey, TValue)
{
// The object store. It is static. Mixin the template into it's different types to create different types of stores. All objects of that type are then in the same store.
        public static TValue[][TKey] Store;

        public static auto New(TKey k, TValue v)
        {
                (Store[k]) ~= v;
                auto o = SingleStore!(TKey, TValue).New(k, v, Store);
                return o;
        }

        public string ToString()
        {
                return "asdf";
        }


}

alias dg = int delegate(int);
//alias dg = string;

class MyStore
{
        mixin ObjectStore!(string, dg);
        //mixin ObjectStore!(string, string);
        
}

void main()
{

        auto k = "x";

        
        dg d1 = (int x) { return x; };
        dg d2 = (int x) { return x; };
        dg d3 = d1;
        dg d4 = (int x) { return 3*x; };
        
/*
        dg d1 = "a1";
        dg d2 = "a2";
        dg d3 = "a3";
        dg d4 = "a4";
        */

        
        auto s = MyStore.New(k, d1);
        writeln(MyStore.Store[k].length);
        auto s1 = MyStore.New(k, d2);
        writeln(MyStore.Store[k].length);
        auto s2 = MyStore.New(k, d3);
        writeln(MyStore.Store[k].length);
        auto s3 = MyStore.New(k, d4);
        writeln(MyStore.Store[k].length);       
        
        //auto x = MyStore.Store[k][0](3);
        //writeln("-" ~ x);

        s1.Remove();
        writeln(MyStore.Store[k].length);
        s2.Remove();
        writeln(MyStore.Store[k].length);
        s.Remove();
        writeln(MyStore.Store[k].length);
        s3.Remove();
        


        getch();
}

Reply via email to