www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Unmanaged drop in replacemet for [] and length -= 1

reply Joerg Joergonson <JJoergonson gmail.com> writes:
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
next sibling parent Joerg Joergonson <JJoergonson gmail.com> writes:
Also, how to handle foreach(i, x; w) (use index + value)?
Jun 18 2016
prev sibling next sibling parent reply Jonathan M Davis via Digitalmars-d-learn writes:
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
parent reply Joerg Joergonson <JJoergonson gmail.com> writes:
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:
 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
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.
Jun 19 2016
parent Jonathan M Davis via Digitalmars-d-learn writes:
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
prev sibling parent reply Steven Schveighoffer <schveiguy yahoo.com> writes:
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
parent Joerg Joergonson <JJoergonson gmail.com> writes:
On Monday, 20 June 2016 at 16:27:29 UTC, Steven Schveighoffer 
wrote:
 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
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).
Jun 20 2016