www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - opIndex negative index?

reply cerjones <who what.com> writes:
I have an iterator that steps along a 2D vector path command by 
command and uses opIndex to give access to the points for the 
current command. The issue is that there's a shared point between 
commands, so when the iterator is on a given command, it also 
needs to also allow access to the end point of the previous 
command. Currently the iterator juggles the indexes so that for a 
cubic you use 0,1,2,3, and 0 gives the previous end point. But it 
would simplify a few things if [-1] was for accessing the 
previous end point, so a cubic would allow indexes -1,0,1,2.

I'm a bit unsure if this is reasonable or not.

Thoughts?
Jan 21
next sibling parent reply IGotD- <nise nise.com> writes:
On Thursday, 21 January 2021 at 14:00:28 UTC, cerjones wrote:
 I have an iterator that steps along a 2D vector path command by 
 command and uses opIndex to give access to the points for the 
 current command. The issue is that there's a shared point 
 between commands, so when the iterator is on a given command, 
 it also needs to also allow access to the end point of the 
 previous command. Currently the iterator juggles the indexes so 
 that for a cubic you use 0,1,2,3, and 0 gives the previous end 
 point. But it would simplify a few things if [-1] was for 
 accessing the previous end point, so a cubic would allow 
 indexes -1,0,1,2.

 I'm a bit unsure if this is reasonable or not.

 Thoughts?
Not possible, indexes are of type size_t which is unsigned. If you want negative indexes you need to wrap arrays in your own implementation and offset 0 so that negative indexes can be used.
Jan 21
parent reply cerjones <who what.com> writes:
On Thursday, 21 January 2021 at 14:25:41 UTC, IGotD- wrote:
 On Thursday, 21 January 2021 at 14:00:28 UTC, cerjones wrote:

 Not possible, indexes are of type size_t which is unsigned. If 
 you want negative indexes you need to wrap arrays in your own 
 implementation and offset 0 so that negative indexes can be 
 used.
import std; struct Foo { int opIndex(int idx) { return idx; } } void main() { Foo foo; writeln(foo[-1]); } prints: -1 And just for weirdness... import std; struct Foo { string opIndex(string s) { return s; } } void main() { Foo foo; writeln(foo["ohrealy?"]); } prints: ohreally?
Jan 21
parent reply IGotD- <nise nise.com> writes:
On Thursday, 21 January 2021 at 14:47:38 UTC, cerjones wrote:
 ohreally?
I thought you were talking about the built in arrays.
Jan 21
parent reply IGotD- <nise nise.com> writes:
On Thursday, 21 January 2021 at 15:49:02 UTC, IGotD- wrote:
 On Thursday, 21 January 2021 at 14:47:38 UTC, cerjones wrote:
 ohreally?
I thought you were talking about the built in arrays.
Since you create your own implementation just as you showed you are basically free to do anything. That also includes that you are free to create your own iterator as well.
Jan 21
parent cerjones <who what.com> writes:
On Thursday, 21 January 2021 at 15:55:02 UTC, IGotD- wrote:
 On Thursday, 21 January 2021 at 15:49:02 UTC, IGotD- wrote:
 On Thursday, 21 January 2021 at 14:47:38 UTC, cerjones wrote:
 ohreally?
I thought you were talking about the built in arrays.
Since you create your own implementation just as you showed you are basically free to do anything. That also includes that you are free to create your own iterator as well.
Tbh I was just a bit uneasy about negative indexes from a design point of view, you know when something just doesnt feel right. So anyway I coded it up and decided I didnt like it anyway, just looks weird having doSomthing(path[-1].x, path[-1].y); so im going to stick with it as it is.
Jan 21
prev sibling parent tsbockman <thomas.bockman gmail.com> writes:
On Thursday, 21 January 2021 at 14:00:28 UTC, cerjones wrote:
 I'm a bit unsure if this is reasonable or not.

 Thoughts?
Signed indexes are fine, if there is a principled reason to use them. Just make sure that you are consistent by making `length`, `opDollar`, etc. use signed types, as well. Otherwise, you're laying a trap for users of the API who may accidentally write code with mixed signed-unsigned integer operations. That's a big problem, because mixed signed-unsigned integer operations are done incorrectly by default, often with no warnings, in D and some other C-like languages. Consistently using signed types for lengths and indexes will make the API incompatible with some Phobos (D's `std`) range code, but you should get a compile-time error message. Mixing signed and unsigned, on the other hand, is likely to result in subtly wrong code that compiles without error, but sometimes does the wrong thing.
Jan 21