On Thursday, 3 January 2013 at 00:08:12 UTC, Peter Summerland
wrote:
On Wednesday, 2 January 2013 at 03:52:21 UTC, bearophile wrote:
Era Scarecrow:
Well I see that you have opIndexUnary twice; According to the
manual you wouldn't need as it would rewrite the code so you
only need it once;
And as you have seen if you remove the useles opIndexRight the
program keeps compiling with no errors and keeps asserting at
run-time:
struct Foo {
int x;
alias this = x;
}
class Bar {
Foo[] data;
this() {
data.length = 10;
}
Foo opIndex(uint i) {
return data[i];
}
void opIndexUnary(string op)(uint i) if (op == "++") {
data[i]++;
}
}
void main() {
auto barfoo = new Bar;
++barfoo[3];
assert(barfoo.data[3] == 1);
barfoo[3]++;
assert(barfoo.data[3] == 2);
}
Bye,
bearophile
I am really just guessing, but it appears that whatever the
post increment op gets rewritten as takes either a reference to
or a copy of what is being incremented and it involves opIndex,
not opIndexUnary as suggested by TDPL p. 378 and p. 369.
That's a (old) bug. If opIndexUnary is present, then that should
be called. However, currently, the compiler doesn't "see" it when
it sees "a[i]++".
http://d.puremagic.com/issues/show_bug.cgi?id=5044
"++a[i]" works correctly (AFAIK). If you want to test opUnary, DO
NOT toy around with the post increment index version. Just stick
to simple unary:
"++a" and "a++"
If opIndex is changed to return ref Foo, everything works. (I
had change alias this = x to alias x this - 2.60 64 bit). Here
is code that shows when opIndexUnary and opIndex is called and
when the assertion fails for version(B) - with ref and
version(A) without ref.
As soon as opIndex returns a ref, then *nothing* of
opIndexSomething becomes necessary (heck, it becomes "counter
necessary"). Same thing for front. If front returns by ref, then
you don't need the "front(T t)" variant.
I don't have TDPL under my eyes right now, but I remember it
explicitly stating that these functions where specifically meant
to emulate access primitives, for functions that can't ref access
to its primitives. In particular, for things like array bool.