Thread overview | |||||||
---|---|---|---|---|---|---|---|
|
March 23, 2012 [Issue 7753] New: Support opIndexCreate as part of index operator overloading in user-defined types | ||||
---|---|---|---|---|
| ||||
http://d.puremagic.com/issues/show_bug.cgi?id=7753 Summary: Support opIndexCreate as part of index operator overloading in user-defined types Product: D Version: D2 Platform: All OS/Version: All Status: NEW Severity: enhancement Priority: P2 Component: DMD AssignedTo: nobody@puremagic.com ReportedBy: hsteoh@quickfur.ath.cx --- Comment #0 from hsteoh@quickfur.ath.cx 2012-03-22 21:18:10 PDT --- Currently, a nested indexing expression such as: a[b][c][d] = 0; for a user-defined type that overloads opIndex* gets translated into: a.opIndex(b).opIndex(c).opIndexAssign(0,d); However, if a[b][c] do not yet exist, this will fail. This works correctly for built-in associative arrays, because the expressions get translated into a series of calls to _aaGetX(), which creates new entries if they don't already exist. But currently, there is no way for a user-defined type to accomplish the same thing. Suggested fix: if the expression as a whole is being assigned to with an assignment operator, then the upper-level indexing calls should be translated into opIndexCreate() instead of just opIndex(): a[b][c][d] = 0; becomes: a.opIndexCreate(b).opIndexCreate(c).opIndexAssign(0,d); If opIndexCreate is not defined, then replace it with opIndex (for backward compatibility). The semantics of opIndexCreate(k) is to return the entry indexed by k if it exists, and if it doesn't, create a new entry with key k and the .init value of the value type, and return the new entry. Preferably, this will apply to any expression that ends with a call to opIndexAssign, opIndexUnary, and opIndexOpAssign. But at the very least, this needs to work when the expression ends with opIndexAssign. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: ------- |
March 23, 2012 [Issue 7753] Support opIndexCreate as part of index operator overloading in user-defined types | ||||
---|---|---|---|---|
| ||||
Posted in reply to hsteoh@quickfur.ath.cx | http://d.puremagic.com/issues/show_bug.cgi?id=7753 Dmitry Olshansky <dmitry.olsh@gmail.com> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |dmitry.olsh@gmail.com --- Comment #1 from Dmitry Olshansky <dmitry.olsh@gmail.com> 2012-03-23 03:28:52 PDT --- It might be a good thing, but ... Why not just return a proxy type upon each indexing? The proxy type will have createIndex that will forward to others in turn. Here a prof of concept I belive it could be generalized and polished. For simplicity sake it's for n-dim arrays: import std.stdio, std.exception; struct Proxy(T) { T* _this; int idx; void opAssign(X)(X value){ debug writeln("Proxy.opAssign"); createIndex(idx) = value; } static if(typeof(*_this).dimension >= 2) { // somewhere io expression ...a[idx][jdx]... is create all, except last one auto opIndex(int jdx){ return proxy(&_this.createIndex(idx), jdx); } //a[idx][jdx] = y; is create if non-existent auto opIndexAssign(X)(X val, int jdx){ //TODO: constraints! debug writeln("Proxy.opIndexAssign"); _this.createIndex(idx).createIndex(jdx) = val; } } @property ref expr(){ debug writeln("Proxy.expr"); return _this.normalIndex(idx); } alias expr this; } auto proxy(T)(T* x, int idx){ return Proxy!(T)(x,idx); } struct M(size_t dim) { static if(dim == 1){ alias int Val; } else{ alias M!(dim-1) Val; } enum dimension = dim; Val[] arr; ref createIndex(int idx){ debug writeln("Created ", typeof(this).stringof); if(arr.length < idx) arr.length = idx+1; return arr[idx]; } ref normalIndex(int idx){ debug writeln("Indexed ", typeof(this).stringof); return arr[idx]; } auto opIndex(int idx){ return Proxy!(M)(&this, idx); } alias arr this; } unittest{ M!(3) d3arr; d3arr[1][2] = [2, 3, 4]; assert(d3arr[1][2][2] == 4); int[] x = d3arr[1][2]; assert(d3arr[1][2].length == 3); assert(d3arr[1][1] == null); //inited //booom used before explicit = assert(collectException!Error(d3arr[2][2][1] + 1 == 1) !is null); } -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: ------- |
March 23, 2012 [Issue 7753] Support opIndexCreate as part of index operator overloading in user-defined types | ||||
---|---|---|---|---|
| ||||
Posted in reply to hsteoh@quickfur.ath.cx | http://d.puremagic.com/issues/show_bug.cgi?id=7753 --- Comment #2 from hsteoh@quickfur.ath.cx 2012-03-23 07:36:46 PDT --- That's a pretty neat idea. Can it be made to work with containers that contain other containers (possibly of a different type)? E.g., a linked list of arrays of AA's? -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: ------- |
March 23, 2012 [Issue 7753] Support opIndexCreate as part of index operator overloading in user-defined types | ||||
---|---|---|---|---|
| ||||
Posted in reply to hsteoh@quickfur.ath.cx | http://d.puremagic.com/issues/show_bug.cgi?id=7753 --- Comment #3 from Dmitry Olshansky <dmitry.olsh@gmail.com> 2012-03-23 08:17:58 PDT --- Well, linked list is, for sure, not indexed so not a problem ;) As for sets I don't see a problem, I can extend this idea to arbitrary set easily. In fact it's even cleaner for sets (maps) then arrays. If you need a headstart I can scratch up a simple version for integer sets. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: ------- |
March 23, 2012 [Issue 7753] Support opIndexCreate as part of index operator overloading in user-defined types | ||||
---|---|---|---|---|
| ||||
Posted in reply to hsteoh@quickfur.ath.cx | http://d.puremagic.com/issues/show_bug.cgi?id=7753 --- Comment #4 from Dmitry Olshansky <dmitry.olsh@gmail.com> 2012-03-23 08:22:00 PDT --- Ahm. So Q was about geterogenious stuff like arrays of sets(maps) or maps of arrays ? I think the 2 mentioned situations cover it all, thus you can parametrize this idea on basis of: a) contigous container, to get item with index X you need to allocted all elements up X. Here X is obviously can be only integer of some sort. b)non-contigous container, to get item with index X you check/create only slot indexed by X. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: ------- |
Copyright © 1999-2021 by the D Language Foundation