digitalmars.D.learn - Unmanaged drop in replacemet for [] and length -= 1
- Joerg Joergonson (71/71) Jun 18 2016 I wanted to switch to std.container.Array but it doesn't seem to
- Joerg Joergonson (1/1) Jun 18 2016 Also, how to handle foreach(i, x; w) (use index + value)?
- Jonathan M Davis via Digitalmars-d-learn (13/15) Jun 19 2016 D's dynamic arrays are really quite weird in that they're sort of contai...
- Joerg Joergonson (6/23) Jun 19 2016 Thanks for your 2c... but I think I can handle it. I'm a big boy
- Jonathan M Davis via Digitalmars-d-learn (14/16) Jun 19 2016 That's exactly what happens with a basic input range, and if it doesn't
- Steven Schveighoffer (20/28) Jun 20 2016 length wrapper *struct*:
- Joerg Joergonson (6/42) Jun 20 2016 Thanks, this is what I was thinking I'd have to do. I'm probably
I wanted to switch to std.container.Array but it doesn't seem to mimic [] for some odd ball reason. I threw this class together and it seems to work. The only problem is that I can't do carray.length -= 1; I can't override `-=` because that is on the class. can I override it for length somehow or do I have to create a length wrapper class that has it overridden in it? Or is there a way to do it in cArray? Basically I want to support code that does something like auto x = []; x.length -= 1; and not have to rewrite that to x.length = x.length - 1; public class cArray(T) { Array!T data; public void assumeSafeAppend() { }; public property int length() { return data.length; } public property int length(int len) { for(int i = 0; i < len; i++) data.removeBack(); return data.length; } ref T opIndex(int i) { return data[i]; } property int opDollar(size_t dim : 0)() { return data.length; } this() { data = Array!T(); } int opApply(int delegate(ref T) dg) { int result = 0; for (int i = 0; i < data.length; i++) { result = dg(data[i]); if (result) break; } return result; } int opApplyReverse(int delegate(ref T) dg) { int result = 0; for (int i = 0; i < data.length; i++) { result = dg(data[i]); if (result) break; } return result; } void opOpAssign(string op)(T d) { if (op == "~") { data ~= d; } } bool canFind(T)(T d) { for(int i = 0; i < data.length; i++) { if (data[i] == d) return true; } return false; } }
Jun 18 2016
Also, how to handle foreach(i, x; w) (use index + value)?
Jun 18 2016
On Saturday, June 18, 2016 21:55:31 Joerg Joergonson via Digitalmars-d-learn wrote:I wanted to switch to std.container.Array but it doesn't seem to mimic [] for some odd ball reason.D's dynamic arrays are really quite weird in that they're sort of containers and sort of not. So, pretty much nothing is ever going to act quite like a dynamic array. But when dynamic arrays are used as ranges, their semantics definitely are not that of containers. Having a container which is treated as a range is just begging for trouble, and I would strongly advise against attempting it. When it comes to containers, ranges are intended to be a view into a container, just like an iterator is intended to be a pointer into a container. Neither ranges are iterators are intended to _be_ containers. Treating a container as a range is going to get you weird behavior like foreach removing every element from the container. - Jonathan M Davis
Jun 19 2016
On Sunday, 19 June 2016 at 10:10:54 UTC, Jonathan M Davis wrote:On Saturday, June 18, 2016 21:55:31 Joerg Joergonson via Digitalmars-d-learn wrote:Thanks for your 2c... but I think I can handle it. I'm a big boy and I wear big boy pants and I'm not afraid of a few little scrapes. If foreach removes all/any of the elements of a container then something is broke.I wanted to switch to std.container.Array but it doesn't seem to mimic [] for some odd ball reason.D's dynamic arrays are really quite weird in that they're sort of containers and sort of not. So, pretty much nothing is ever going to act quite like a dynamic array. But when dynamic arrays are used as ranges, their semantics definitely are not that of containers. Having a container which is treated as a range is just begging for trouble, and I would strongly advise against attempting it. When it comes to containers, ranges are intended to be a view into a container, just like an iterator is intended to be a pointer into a container. Neither ranges are iterators are intended to _be_ containers. Treating a container as a range is going to get you weird behavior like foreach removing every element from the container. - Jonathan M Davis
Jun 19 2016
On Sunday, June 19, 2016 15:59:41 Joerg Joergonson via Digitalmars-d-learn wrote:If foreach removes all/any of the elements of a container then something is broke.That's exactly what happens with a basic input range, and if it doesn't happen with a forward range, it's just because copying that range implicitly saves it, which doesn't work in generic code, because it's not the case with all forward ranges. popFront consumes an element from a range, and foreach is popping every element in the range. The same goes for any algorithm which iterates over a range. So, naturally, any container that is treated as a range is going to have its elements removed as it's iterated over. You're certainly free to treat a container as a range if that's what you want to do, but it shows a fundamental misunderstanding of what a range is supposed to be and do, and there are plenty of algorithms that will behave very badly for you if you do that. - Jonathan M Davis
Jun 19 2016
On 6/18/16 5:55 PM, Joerg Joergonson wrote:I wanted to switch to std.container.Array but it doesn't seem to mimic [] for some odd ball reason. I threw this class together and it seems to work. The only problem is that I can't do carray.length -= 1; I can't override `-=` because that is on the class. can I override it for length somehow or do I have to create a length wrapper class that has it overridden in it? Or is there a way to do it in cArray?length wrapper *struct*: struct AdjustableLength { cArray t; auto get() { return t.data.length; } opOpAssign(string s: "+", Addend)(Addend x) { //... your code here that does += using t t.data.length = get() + x; } alias get this; } property auto length() { return AdjustableLength(this); } D does not have any direct support for modification of properties. It has been talked about, but has never been implemented. -Steve
Jun 20 2016
On Monday, 20 June 2016 at 16:27:29 UTC, Steven Schveighoffer wrote:On 6/18/16 5:55 PM, Joerg Joergonson wrote:Thanks, this is what I was thinking I'd have to do. I'm probably going to manually manage the array items. I just need simple append and remove but this will still help with the drop in replacement(for my cases).I wanted to switch to std.container.Array but it doesn't seem to mimic [] for some odd ball reason. I threw this class together and it seems to work. The only problem is that I can't do carray.length -= 1; I can't override `-=` because that is on the class. can I override it for length somehow or do I have to create a length wrapper class that has it overridden in it? Or is there a way to do it in cArray?length wrapper *struct*: struct AdjustableLength { cArray t; auto get() { return t.data.length; } opOpAssign(string s: "+", Addend)(Addend x) { //... your code here that does += using t t.data.length = get() + x; } alias get this; } property auto length() { return AdjustableLength(this); } D does not have any direct support for modification of properties. It has been talked about, but has never been implemented. -Steve
Jun 20 2016