Jump to page: 1 2 3
Thread overview
opIndexUnary post in-/decrement how to ?
Jul 14, 2021
wjoe
Jul 14, 2021
Tejas
Jul 14, 2021
wjoe
Jul 14, 2021
Tejas
Jul 14, 2021
vit
Jul 14, 2021
Tejas
Jul 14, 2021
vit
Jul 14, 2021
wjoe
Jul 14, 2021
vit
Jul 14, 2021
vit
Jul 14, 2021
Tejas
Jul 14, 2021
Tejas
Jul 14, 2021
Tejas
Jul 14, 2021
wjoe
Jul 14, 2021
Mike Parker
Jul 14, 2021
wjoe
Jul 14, 2021
Tejas
Jul 14, 2021
Ali Çehreli
Jul 14, 2021
Tejas
Jul 14, 2021
Ali Çehreli
Jul 14, 2021
wjoe
Jul 15, 2021
Tejas
Jul 15, 2021
wjoe
Jul 15, 2021
Tejas
Jul 15, 2021
wjoe
Jul 15, 2021
Tejas
Jul 15, 2021
wjoe
Jul 15, 2021
Tejas
Jul 16, 2021
wjoe
Jul 14, 2021
Tejas
July 14, 2021

I'm want to do something like this

part_int_t!(1,2,3) i;

auto x = -i[0];
--i[1]; // 1
i[1]++; // 2

I think the operator I need to overload would be opIndexUnary which I did.
(1) compiles.
(2) doesn't - the compiler complains that i.opIndex isn't an lvalue and can't be modified.
The language spec says that Post in- and decrement are rewritten but something's fishy.
What's going on behind the scene and how can I make it work?

July 14, 2021

On Wednesday, 14 July 2021 at 10:07:38 UTC, wjoe wrote:

>

I'm want to do something like this

part_int_t!(1,2,3) i;

auto x = -i[0];
--i[1]; // 1
i[1]++; // 2

I think the operator I need to overload would be opIndexUnary which I did.
(1) compiles.
(2) doesn't - the compiler complains that i.opIndex isn't an lvalue and can't be modified.
The language spec says that Post in- and decrement are rewritten but something's fishy.
What's going on behind the scene and how can I make it work?

Please check the language spec here:

https://dlang.org/spec/operatoroverloading.html#postincrement_postdecrement_operators

You can't directly overload the postincrement operator.

You need to rewrite it like:

{auto a = i[1] , ++i[1] , a} //note the , not the ;

Sorry I can't provide something even more concrete.

July 14, 2021

On Wednesday, 14 July 2021 at 11:31:36 UTC, Tejas wrote:

>

{auto a = i[1] , ++i[1] , a} //note the , not the ;

Sorry I can't provide something even more concrete.

Yes I saw that, and I suppose it would work just fine if it were rewritten to just ++i[1].
What I'm struggling to understand is the {auto a = i[1], ... ,a} part. I can't parse that. What's up with the assignment and the comma stuff ?

July 14, 2021

On Wednesday, 14 July 2021 at 12:35:07 UTC, wjoe wrote:

>

On Wednesday, 14 July 2021 at 11:31:36 UTC, Tejas wrote:

>

{auto a = i[1] , ++i[1] , a} //note the , not the ;

Sorry I can't provide something even more concrete.

Yes I saw that, and I suppose it would work just fine if it were rewritten to just ++i[1].
What I'm struggling to understand is the {auto a = i[1], ... ,a} part. I can't parse that. What's up with the assignment and the comma stuff ?

I think it's a bug, because the following works:


import   std.stdio;

struct abc{
    int[100] a;
    int opIndex(int index){
        return a[index];
    }
    int opIndexUnary(string s)(int index)
        if(s == "++"){
        return ++a[index];
        }
    int[] opUnary(string s)() if (s == "++"){
        return a[] += 1;
    }
}

void main (){
    abc s;
    int[100] a;
    int temp;
    writeln (a[20]++);

    writeln(a[20]);

    writeln(++s[20]);

    writeln(s[20]);

    //writeln(s[0]++);// doesn't work for some reason

    writeln(s[0]);

    writeln(s++);//but this works!!

    writeln(s);
}

July 14, 2021

On Wednesday, 14 July 2021 at 11:31:36 UTC, Tejas wrote:

>

On Wednesday, 14 July 2021 at 10:07:38 UTC, wjoe wrote:

>

I'm want to do something like this

part_int_t!(1,2,3) i;

auto x = -i[0];
--i[1]; // 1
i[1]++; // 2

I think the operator I need to overload would be opIndexUnary which I did.
(1) compiles.
(2) doesn't - the compiler complains that i.opIndex isn't an lvalue and can't be modified.
The language spec says that Post in- and decrement are rewritten but something's fishy.
What's going on behind the scene and how can I make it work?

Please check the language spec here:

https://dlang.org/spec/operatoroverloading.html#postincrement_postdecrement_operators

You can't directly overload the postincrement operator.

You need to rewrite it like:

{auto a = i[1] , ++i[1] , a} //note the , not the ;

Sorry I can't provide something even more concrete.

Ignore this, I wanted to say that this is what the compiler rewrites it to when you write i[1]++

There is no way to explicitly overload the post increment operator because of this.

July 14, 2021

On Wednesday, 14 July 2021 at 12:49:58 UTC, Tejas wrote:

>

On Wednesday, 14 July 2021 at 12:35:07 UTC, wjoe wrote:

>

On Wednesday, 14 July 2021 at 11:31:36 UTC, Tejas wrote:

>

{auto a = i[1] , ++i[1] , a} //note the , not the ;

Sorry I can't provide something even more concrete.

Yes I saw that, and I suppose it would work just fine if it were rewritten to just ++i[1].
What I'm struggling to understand is the {auto a = i[1], ... ,a} part. I can't parse that. What's up with the assignment and the comma stuff ?

I think it's a bug, because the following works:


import   std.stdio;

struct abc{
    int[100] a;
    int opIndex(int index){
        return a[index];
    }
    int opIndexUnary(string s)(int index)
        if(s == "++"){
        return ++a[index];
        }
    int[] opUnary(string s)() if (s == "++"){
        return a[] += 1;
    }
}

void main (){
    abc s;
    int[100] a;
    int temp;
    writeln (a[20]++);

    writeln(a[20]);

    writeln(++s[20]);

    writeln(s[20]);

    //writeln(s[0]++);// doesn't work for some reason

    writeln(s[0]);

    writeln(s++);//but this works!!

    writeln(s);
}

From doc: https://dlang.org/spec/operatoroverloading.html
Postincrement e++ and Postdecrement e-- Operators
These are not directly overloadable, but instead are rewritten in terms of the ++e and --e prefix operators:

Postfix Operator Rewrites
op rewrite
e-- (auto t = e, --e, t)
e++ (auto t = e, ++e, t)

Rewriting part doesn't work with operator overloading.

July 14, 2021

On Wednesday, 14 July 2021 at 13:09:56 UTC, vit wrote:

>

On Wednesday, 14 July 2021 at 12:49:58 UTC, Tejas wrote:

>

On Wednesday, 14 July 2021 at 12:35:07 UTC, wjoe wrote:

>

On Wednesday, 14 July 2021 at 11:31:36 UTC, Tejas wrote:

>

{auto a = i[1] , ++i[1] , a} //note the , not the ;

Sorry I can't provide something even more concrete.

Yes I saw that, and I suppose it would work just fine if it were rewritten to just ++i[1].
What I'm struggling to understand is the {auto a = i[1], ... ,a} part. I can't parse that. What's up with the assignment and the comma stuff ?

I think it's a bug, because the following works:


import   std.stdio;

struct abc{
    int[100] a;
    int opIndex(int index){
        return a[index];
    }
    int opIndexUnary(string s)(int index)
        if(s == "++"){
        return ++a[index];
        }
    int[] opUnary(string s)() if (s == "++"){
        return a[] += 1;
    }
}

void main (){
    abc s;
    int[100] a;
    int temp;
    writeln (a[20]++);

    writeln(a[20]);

    writeln(++s[20]);

    writeln(s[20]);

    //writeln(s[0]++);// doesn't work for some reason

    writeln(s[0]);

    writeln(s++);//but this works!!

    writeln(s);
}

From doc: https://dlang.org/spec/operatoroverloading.html
Postincrement e++ and Postdecrement e-- Operators
These are not directly overloadable, but instead are rewritten in terms of the ++e and --e prefix operators:

Postfix Operator Rewrites
op rewrite
e-- (auto t = e, --e, t)
e++ (auto t = e, ++e, t)

Rewriting part doesn't work with operator overloading.

If the rewriting part doesn't work with overloading then why aren't we allowed to explicitly overload post-increment/decrement operators?

How else will the OP solve their problem?

It must rewrite, otherwise it's impossible (I think).

July 14, 2021

On Wednesday, 14 July 2021 at 13:16:49 UTC, Tejas wrote:

>

On Wednesday, 14 July 2021 at 13:09:56 UTC, vit wrote:

>

On Wednesday, 14 July 2021 at 12:49:58 UTC, Tejas wrote:

>

[...]

From doc: https://dlang.org/spec/operatoroverloading.html
Postincrement e++ and Postdecrement e-- Operators
These are not directly overloadable, but instead are rewritten in terms of the ++e and --e prefix operators:

Postfix Operator Rewrites
op rewrite
e-- (auto t = e, --e, t)
e++ (auto t = e, ++e, t)

Rewriting part doesn't work with operator overloading.

If the rewriting part doesn't work with overloading then why aren't we allowed to explicitly overload post-increment/decrement operators?

How else will the OP solve their problem?

It must rewrite, otherwise it's impossible (I think).

This work:

import   std.stdio;

struct abc{
    int[100] a;

    ref int opIndex(int index)return{
        return a[index];
    }
}

void main (){
    abc s;
    s[0]++;
    ++s[0];
}

July 14, 2021

On Wednesday, 14 July 2021 at 12:49:58 UTC, Tejas wrote:

>

I think it's a bug, because the following works:


import   std.stdio;

struct abc{
    int[100] a;
    int opIndex(int index){
        return a[index];
    }
    int opIndexUnary(string s)(int index)
        if(s == "++"){
        return ++a[index];
        }
    int[] opUnary(string s)() if (s == "++"){
        return a[] += 1;
    }
}

void main (){
    abc s;
    int[100] a;
    int temp;
    writeln (a[20]++);

    writeln(a[20]);

    writeln(++s[20]);

    writeln(s[20]);

    //writeln(s[0]++);// doesn't work for some reason

    writeln(s[0]);

    writeln(s++);//but this works!!

    writeln(s);
}

writeln(++s[0]); // should work
writeln(s++); // this calls opUnary if I'm not mistaken
July 14, 2021

On Wednesday, 14 July 2021 at 12:35:07 UTC, wjoe wrote:

>

On Wednesday, 14 July 2021 at 11:31:36 UTC, Tejas wrote:

>

{auto a = i[1] , ++i[1] , a} //note the , not the ;

Sorry I can't provide something even more concrete.

Yes I saw that, and I suppose it would work just fine if it were rewritten to just ++i[1].
What I'm struggling to understand is the {auto a = i[1], ... ,a} part. I can't parse that. What's up with the assignment and the comma stuff ?

It's how the contract of post-inc/dec work---pre-inc/dec return the modified value, post-inc/dec return the original value.

int i = 1;
assert(++i == 2);
int j = 1;
assert(j++ == 1);

The rewrite of the compiler is done in such a way that the result of the expression is the original value. That's what the commas are for.

So you can parse that rewrite example as it if were a function, with each expression separated by a comma, and the final expression the result:

```d
int postInc(ref int j)
{
    auto a = j;
    ++j;
    return a;
}

It doesn't actually create a function, but this demonstrates the effect.

So that's why you don't have to worry about postfix/prefix for these. The compiler handles that behind the scenes. All you need to worry about is returning the incremented value.

« First   ‹ Prev
1 2 3