digitalmars.D.learn - Insert array into an AA
- nrgyzer (13/13) Aug 16 2011 Hi everyone,
- Steven Schveighoffer (13/25) Aug 16 2011 It's inadvisable to do this, unless you plan on manually deleting the
- Robert Clipsham (26/39) Aug 16 2011 Is there any particular reason you're using ubyte[][2][hash_t] there? To...
- nrgyzer (39/82) Aug 18 2011 Ok, that works - thx.
- Steven Schveighoffer (17/104) Aug 19 2011 If two instances return the same hash value (as is easily possible, but ...
- nrgyzer (56/176) Aug 19 2011 Artikel
Hi everyone, I've the following: private static ubyte[][2][hash_t] classInstances; this() { classInstances[toHash()] = new ubyte[2]; // does not work } I want insert every class instance into the hashmap. Every class instance should be contained in the map after the constructor was called. When I compile my code, I get "Error: cannot implicitly convert expression (new ubyte[](2u)) of type ubyte[] to ubyte[][]" which is logical. But is there any way to insert every instance into the array and define the array/map for this entry? Thanks in advance!
Aug 16 2011
On Tue, 16 Aug 2011 15:17:33 -0400, nrgyzer <nrgyzer gmail.com> wrote:Hi everyone, I've the following: private static ubyte[][2][hash_t] classInstances; this() { classInstances[toHash()] = new ubyte[2]; // does not work } I want insert every class instance into the hashmap. Every class instance should be contained in the map after the constructor was called. When I compile my code, I get "Error: cannot implicitly convert expression (new ubyte[](2u)) of type ubyte[] to ubyte[][]" which is logical. But is there any way to insert every instance into the array and define the array/map for this entry?It's inadvisable to do this, unless you plan on manually deleting the instances. The reason is because the hash will maintain a pointer to every class instance, which means the GC will never collect them. Also, it's hard to know why you selected that type, but changing classInstances to ubyte[][hash_t] should work. Also, you don't need hash_t, you should be able to do ubyte[][Object] classInstances. then add like: classInstances[this] = new ubyte[2]; The call to toHash is implicit. -Steve
Aug 16 2011
On 16/08/2011 20:17, nrgyzer wrote:Hi everyone, I've the following: private static ubyte[][2][hash_t] classInstances; this() { classInstances[toHash()] = new ubyte[2]; // does not work } I want insert every class instance into the hashmap. Every class instance should be contained in the map after the constructor was called. When I compile my code, I get "Error: cannot implicitly convert expression (new ubyte[](2u)) of type ubyte[] to ubyte[][]" which is logical. But is there any way to insert every instance into the array and define the array/map for this entry? Thanks in advance!Is there any particular reason you're using ubyte[][2][hash_t] there? To keep a reference to each instance simply use: ---- class MyClass { static MyClass[] classInstances; this() { classInstances ~= this; } } ---- If you in fact want to have a hashmap indexed by the instances with values of type ubyte[][2], you can do this: ---- class MyClass { static ubyte[][2][MyClass] classInstances; this() { classInstances[this] = new ubyte[][2]; } } ---- The problem in your original code is that you were using = new ubyte[2] rather than = new ubyte[][2]. Hope this helps. -- Robert http://octarineparrot.com/
Aug 16 2011
== Auszug aus Robert Clipsham (robert octarineparrot.com)'s ArtikelOn 16/08/2011 20:17, nrgyzer wrote:Ok, that works - thx. Steve: I'll delete the entries from the map, but what's about overriding the toHash()-function and return a simply int value? I also need this map-structure for further steps in my application. I's possible to change it to ubyte[][hash_t] classInstancesOne; // or ubyte[][MyClass] ubyte[][hash_t] classInstancesTwo; // or ubyte[][MyClass] but I thought one map for the same sense is better. Btw: I've two classes where one inherits: class MyClassOne { protected { static __gshared { uint counter; uint[MyClassOne] fixedData; } uint otherData; this(uint d) { otherData = d; } } this() { fixedData[this] = ++counter; } property ref { uint myPropOne() { return fixedData[this]; } uint myPropTwo() { return otherData; } } } class MyClassTwo : MyClassOne { shared(MyClassOne) supInstance; this(uint d, MyClassOne mco) { super(d); supInstance = mco; } override ref alias supInstance.myPropOne myPropOne; } When I create an instance of MyClassOne and call myPropOne on it, I get "1". When I'm using this instance to create an instance of MyClassTwo and call myPropOne, I get "0". Is there anything I'm doing wrong? What I'm trying to do is: One super-class which contains some fixed data (not inheritable) and some data which are different for each class.Hi everyone, I've the following: private static ubyte[][2][hash_t] classInstances; this() { classInstances[toHash()] = new ubyte[2]; // does not work } I want insert every class instance into the hashmap. Every class instance should be contained in the map after the constructor was called. When I compile my code, I get "Error: cannot implicitly convert expression (new ubyte[](2u)) of type ubyte[] to ubyte[][]" which is logical. But is there any way to insert every instance into the array and define the array/map for this entry? Thanks in advance!Is there any particular reason you're using ubyte[][2][hash_t] there? To keep a reference to each instance simply use: ---- class MyClass { static MyClass[] classInstances; this() { classInstances ~= this; } } ---- If you in fact want to have a hashmap indexed by the instances with values of type ubyte[][2], you can do this: ---- class MyClass { static ubyte[][2][MyClass] classInstances; this() { classInstances[this] = new ubyte[][2]; } } ---- The problem in your original code is that you were using = new ubyte[2] rather than = new ubyte[][2]. Hope this helps.
Aug 18 2011
On Thu, 18 Aug 2011 06:47:32 -0400, nrgyzer <nrgyzer gmail.com> wrote:== Auszug aus Robert Clipsham (robert octarineparrot.com)'s ArtikelIf two instances return the same hash value (as is easily possible, but maybe not for your context), then a collision occurs. Then opCmp is used to determine if they are actually identical. If you use hash_t as your key, then only one object is stored in the map, the other is simply overwritten.On 16/08/2011 20:17, nrgyzer wrote:Ok, that works - thx. Steve: I'll delete the entries from the map, but what's about overriding the toHash()-function and return a simply int value?Hi everyone, I've the following: private static ubyte[][2][hash_t] classInstances; this() { classInstances[toHash()] = new ubyte[2]; // does not work } I want insert every class instance into the hashmap. Every class instance should be contained in the map after the constructor was called. When I compile my code, I get "Error: cannot implicitly convert expression (new ubyte[](2u)) of type ubyte[] to ubyte[][]" which is logical. But is there any way to insert every instance into the array and define the array/map for this entry? Thanks in advance!Is there any particular reason you're using ubyte[][2][hash_t] there? To keep a reference to each instance simply use: ---- class MyClass { static MyClass[] classInstances; this() { classInstances ~= this; } } ---- If you in fact want to have a hashmap indexed by the instances with values of type ubyte[][2], you can do this: ---- class MyClass { static ubyte[][2][MyClass] classInstances; this() { classInstances[this] = new ubyte[][2]; } } ---- The problem in your original code is that you were using = new ubyte[2] rather than = new ubyte[][2]. Hope this helps.I also need this map-structure for further steps in my application. I's possible to change it to ubyte[][hash_t] classInstancesOne; // or ubyte[][MyClass] ubyte[][hash_t] classInstancesTwo; // or ubyte[][MyClass] but I thought one map for the same sense is better.ubyte[][Object] should work for all class types.Btw: I've two classes where one inherits: class MyClassOne { protected { static __gshared { uint counter; uint[MyClassOne] fixedData; } uint otherData; this(uint d) { otherData = d; } } this() { fixedData[this] = ++counter; } property ref { uint myPropOne() { return fixedData[this]; } uint myPropTwo() { return otherData; } } } class MyClassTwo : MyClassOne { shared(MyClassOne) supInstance; this(uint d, MyClassOne mco) { super(d); supInstance = mco; } override ref alias supInstance.myPropOne myPropOne; } When I create an instance of MyClassOne and call myPropOne on it, I get "1". When I'm using this instance to create an instance of MyClassTwo and call myPropOne, I get "0". Is there anything I'm doing wrong?That crazy override ref alias line, I have no idea what you're doing there. For sure, override ref is not needed. I'm surprised all of this compiles.What I'm trying to do is: One super-class which contains some fixed data (not inheritable) and some data which are different for each class.Note that protected does not prevent MyClassTwo from changing it. Also note that even though you've only created one instance of MyClassOne, every MyClassTwo instance is a MyClassOne (and calls MyClassOne's constructor). I think you have applied the wrong techniques to solving your design. Without knowing further your design/context, I can't really help. -Steve
Aug 19 2011
== Auszug aus Steven Schveighoffer (schveiguy yahoo.com)'s ArtikelOn Thu, 18 Aug 2011 06:47:32 -0400, nrgyzer <nrgyzer gmail.com>wrote:Artikel== Auszug aus Robert Clipsham (robert octarineparrot.com)'sclassOn 16/08/2011 20:17, nrgyzer wrote:Hi everyone, I've the following: private static ubyte[][2][hash_t] classInstances; this() { classInstances[toHash()] = new ubyte[2]; // does not work } I want insert every class instance into the hashmap. Everywasinstance should be contained in the map after the constructor[]"called. When I compile my code, I get "Error: cannot implicitly convert expression (new ubyte[](2u)) of type ubyte[] to ubyte[]instance intowhich is logical. But is there any way to insert everythere? Tothe array and define the array/map for this entry? Thanks in advance!Is there any particular reason you're using ubyte[][2][hash_t]withkeep a reference to each instance simply use: ---- class MyClass { static MyClass[] classInstances; this() { classInstances ~= this; } } ---- If you in fact want to have a hashmap indexed by the instancesubyte[2]values of type ubyte[][2], you can do this: ---- class MyClass { static ubyte[][2][MyClass] classInstances; this() { classInstances[this] = new ubyte[][2]; } } ---- The problem in your original code is that you were using = newbutIf two instances return the same hash value (as is easily possible,rather than = new ubyte[][2]. Hope this helps.Ok, that works - thx. Steve: I'll delete the entries from the map, but what's about overriding the toHash()-function and return a simply int value?maybe not for your context), then a collision occurs. Then opCmpis usedto determine if they are actually identical. If you use hash_t as your key, then only one object is stored inthe map,the other is simply overwritten.application. I'sI also need this map-structure for further steps in myI getpossible to change it to ubyte[][hash_t] classInstancesOne; // or ubyte[][MyClass] ubyte[][hash_t] classInstancesTwo; // or ubyte[][MyClass] but I thought one map for the same sense is better.ubyte[][Object] should work for all class types.Btw: I've two classes where one inherits: class MyClassOne { protected { static __gshared { uint counter; uint[MyClassOne] fixedData; } uint otherData; this(uint d) { otherData = d; } } this() { fixedData[this] = ++counter; } property ref { uint myPropOne() { return fixedData[this]; } uint myPropTwo() { return otherData; } } } class MyClassTwo : MyClassOne { shared(MyClassOne) supInstance; this(uint d, MyClassOne mco) { super(d); supInstance = mco; } override ref alias supInstance.myPropOne myPropOne; } When I create an instance of MyClassOne and call myPropOne on it,doing"1". When I'm using this instance to create an instance of MyClassTwo and call myPropOne, I get "0". Is there anything I'mfixed datawrong?That crazy override ref alias line, I have no idea what you're doing there. For sure, override ref is not needed. I'm surprised all of this compiles.What I'm trying to do is: One super-class which contains someMyClassOne,(not inheritable) and some data which are different for each class.Note that protected does not prevent MyClassTwo from changing it. Also note that even though you've only created one instance ofevery MyClassTwo instance is a MyClassOne (and calls MyClassOne's constructor). I think you have applied the wrong techniques tosolvingyour design. Without knowing further your design/context, I can'treallyhelp. -SteveI'm working on a game where the player can build different buildings. There are some general building-structures which defines the costs to build it and some other things, but the name of each building can be modified by the player. So, each building can have it's own name, but the costs to build are always the same for each building. To prevent the redefinition of all the property-methods, I want redirect the properties of a simple building-property to it's building structure. For example: class BuildingShell { private float[BuildingShell] pCostsToBuild; protected { string pName; this(string name) { pName = name; } } this(string name, float costs) { pName = name; pCostsToBuild[this] = costs; } property { ref float costsToBuild() { return pCostsToBuild[this]; } string name() { return pName; } } } class Building : BuildingShell { shared(BuildingShell) pShell; this(BuldingShell bs, string name) { super(name); pShell = cast(shared) bs; } override property pShell.costsToBuild costsToBuild; } All instances of BuildingShell will be loaded from a stream, so I need the ref-keyword in the properties. Because of multi-threading I also need a shared BuildingShell in the Building-class.
Aug 19 2011