www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Convert array to tupled array easily?

reply Prudence <Pursuit Happyness.All> writes:
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();
}
Sep 14 2015
parent =?UTF-8?Q?Ali_=c3=87ehreli?= <acehreli yahoo.com> writes:
On 09/14/2015 04:23 PM, Prudence wrote:

 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;
After changing that, I methodically dealt with compilation errors. A total of 6 changes were sufficient: $ diff before.d after.d 24c24 < public TValue[][TKey] Store; ---
     public Tuple!(TValue, void*)[][TKey] Store;
36c36 < if (c == Value) ---
             if (c[0] == Value)
39c39 < Store[Key][i] = null; // Set to null to release any references if necessary ---
                     Store[Key][i][1] = null; // Set to null to 
release any references if necessary 58c58 < public static auto New(TKey k, TValue v, ref TValue[][TKey] s) ---
     public static auto New(TKey k, TValue v, ref Tuple!(TValue, 
void*)[][TKey] s) 77c77 < public static TValue[][TKey] Store; ---
     public static Tuple!(TValue, void*)[][TKey] Store;
81c81 < (Store[k]) ~= v; ---
         (Store[k]) ~= tuple(v, cast(void*)null);
Ali
Sep 14 2015