Initalizing complex array types or some other problem ;/

2015-09-15 Thread Prudence via Digitalmars-d-learn
How does one initialize a tuple type and are arrays initialized 
by default?



The code below doesn't work. I recently converted to use a tuple 
and that seemed to have broke it and I don't know why, when I 
changed the New function to use a ref, that made it worse cause 
now the array is all ways null. Debugging doesn't help much 
because, for some reason, VD won't show object information inside 
the mixin ObjectStore.



	alias StoreType = Tuple!(TValue, SingleStore!(TKey, 
TValue))[][TKey];

public static StoreType Store;

I thought using the alias would help but it doesn't. Trying to 
init it in the static this doesn't seem to help me, as I can't 
get it to new propertly. e.g., new StoreType(); fails.


Any ideas?






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 Tuple!(TValue, SingleStore!(TKey, TValue))[][TKey] Store;


public auto Remove()
{
import std.algorithm;
if (Value == null || Key == null) return;
int count = 0;
for(int i = 0; i < Store[Key].length; i++)
{
if (Store[Key][i][0] == Value && Store[Key][i][1] == 
this)
{
count++;
Store[Key][i] = tuple(null, null);
	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)];
Store[Key].length = Store[Key].length - count;

Value = null;
Key = null;

}

	public static auto New(TKey k, TValue v, ref Tuple!(TValue, 
SingleStore!(TKey, TValue))[][TKey] s)

{
auto o = new SingleStore!(TKey, TValue)(k, v);  // GC
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 them specifically.

public mixin template ObjectStore(TKey, TValue)
{
	alias StoreType = Tuple!(TValue, SingleStore!(TKey, 
TValue))[][TKey];

public static StoreType Store;

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

alias dg = int delegate(int);

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

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

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

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



getch();
}


Re: Initalizing complex array types or some other problem ;/

2015-09-15 Thread anonymous via Digitalmars-d-learn
On Tuesday 15 September 2015 22:09, Prudence wrote:

> The code below doesn't work.

Please be more specific in how it doesn't work. Mention the error message if 
there is one, or say how the code behaves differently from what you'd 
expect.

Trying to compile the code (after kicking getch out), I get this error:
core.exception.RangeError@test.d(103): Range violation

Line 103 is: writeln(MyStore.Store[k].length);

I can't find where you set Store[k]. Maybe you forgot that or deleted it 
accidentally?

I made a guess and added this line in SingleStore.New:
o.Store[k] ~= tuple(v, o);

It still throws a range error with this. That's because associative arrays 
are a little weird, unfortunately.

An AA is effectively initialized on the first assignment. So (with my 
addition) the first SingleStore.New call initializes the AA. But it only 
initializes o.Store, not the original variable s (i.e. ObjectStore.Store). s 
is left empty.

Possible solutions/workarounds:
* Append to s[k], then assign s to o.Store.
* Initialize ObjectStore.Store in a static constructor:

static this()
{
Store[TKey.init] = [];
Store.remove(TKey.init);
}


Aside: I have no idea what you're doing there, but it looks pretty 
complicated, to the point that I'd guess that it's more complicated than 
necessary.


Re: Initalizing complex array types or some other problem ;/

2015-09-15 Thread Prudence via Digitalmars-d-learn

On Tuesday, 15 September 2015 at 20:54:49 UTC, anonymous wrote:

On Tuesday 15 September 2015 22:09, Prudence wrote:


The code below doesn't work.


Please be more specific in how it doesn't work. Mention the 
error message if there is one, or say how the code behaves 
differently from what you'd expect.


Trying to compile the code (after kicking getch out), I get 
this error:

core.exception.RangeError@test.d(103): Range violation

Line 103 is: writeln(MyStore.Store[k].length);

I can't find where you set Store[k]. Maybe you forgot that or 
deleted it accidentally?


I made a guess and added this line in SingleStore.New:
o.Store[k] ~= tuple(v, o);

It still throws a range error with this. That's because 
associative arrays are a little weird, unfortunately.


An AA is effectively initialized on the first assignment. So 
(with my addition) the first SingleStore.New call initializes 
the AA. But it only initializes o.Store, not the original 
variable s (i.e. ObjectStore.Store). s is left empty.


Possible solutions/workarounds:
* Append to s[k], then assign s to o.Store.
* Initialize ObjectStore.Store in a static constructor:

static this()
{
Store[TKey.init] = [];
Store.remove(TKey.init);
}


Maybe. Seems to work without it. The code below should compile on 
your system and work(and prints 1 2 3 4, 4 3 2 1). The getch is 
required on windows if I want to see the output, so I don't know 
why you even bothered mention replacing it.






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 Tuple!(TValue, SingleStore!(TKey, 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++)
{
if (Store[Key][i][0] == Value && Store[Key][i][1] == 
this)
{
count++;
	Store[Key][i] = tuple(null, 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)];
Store[Key].length = Store[Key].length - count;

Value = null;
Key = null;

}

	public static auto New(TKey k, TValue v, ref Tuple!(TValue, 
SingleStore!(TKey, TValue))[][TKey] s)

{
auto o = new SingleStore!(TKey, TValue)();  // GC
o.Key = k;
o.Value = v;
s[k] ~= tuple(v, o);
o.Store = s;

return o;
}

}


// 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 Tuple!(TValue, SingleStore!(TKey, TValue))[][TKey] 
Store;


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

}

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

public class cMyStore(TKey, TValue)
{
//mixin ObjectStore!(string, dg);
mixin ObjectStore!(string, string); 
}



void main()
{
alias MyStore = cMyStore!(string, string);
auto k = "x";

auto r = &MyStore.Store;

/*
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.Sto

Re: Initalizing complex array types or some other problem ;/

2015-09-15 Thread anonymous via Digitalmars-d-learn
On Wednesday 16 September 2015 03:46, Prudence wrote:

> In any case, Maybe you are not as smart as you think you are if 
> you can't understand it?

kthxbye


Re: Initalizing complex array types or some other problem ;/

2015-09-16 Thread Andrea Fontana via Digitalmars-d-learn

On Wednesday, 16 September 2015 at 01:46:09 UTC, Prudence wrote:
In any case, Maybe you are not as smart as you think you are if 
you can't understand it? Maybe next time you shouldn't assume 
you are the oracle of all knowledge and if you can't understand 
it then it's bad/wrong.


In fact, it's quite simple to understand for anyone with half a 
brain.


Seriously. Don't guess. It's not that complex and it would take 
you 5 mins to understand if you wanted. No reason to try and 
through your ego in it.


"Prudence" seems not to fit well as nickname.