Initalizing complex array types or some other problem ;/
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 ;/
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 ;/
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 ;/
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 ;/
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.