opIndexUnary post in-/decrement how to ?

wjoe invalid at example.com
Thu Jul 15 13:28:19 UTC 2021


On Thursday, 15 July 2021 at 12:09:20 UTC, Tejas wrote:
> [...]
>
> Oh yes, that is what happens. I was trying to be a little 
> concise.
> You are correct, this is what the code will look in the gory 
> details (I believe) :
> ```d
> auto x = (auto e = i.opIndex(1), i.opIndexUnary("++")(1)/*this 
> may or may not expand to what you wrote, not sure what the 
> compiler does, although what you say does sound like the 
> obvious thing to do*/, return e);
> ```
>> I did indeed override opIndex() but since i need to apply a 
>> bit mask and do some shifting I can't return anything by ref.
>
> As I mentioned, maybe the bit manipulation library could 
> help(although they don't seem to be overloading the operators 
> in the first place, thus sidestepping the problem you 
> encountered).

The only way, for me, to explain the error message ```opIndex 
isn't an lvalue and can't be modified.``` for ```i[1]++``` is 
that the compiler rewrites to
```D
(auto e = i.opIndex(1), i.opIndex(1).opUnary!"++"()/*1) note: not 
opIndexUnary*/, return e;)
```
If it were using ```opIndexUnary``` at 1) it would work.

The gist of it
```D
part_int_t!("alpha", 1, "beta", 4, "gamma", 16) a;

struct part_int_t(ARGS...)
{
    int _int;
    mixin(generatePartInt!ARGS);
}

// auto-generated from ARGS
alias typeof_alpha = bool;
enum ulong offset_alpha = 0;
enum ulong mask_alpha = 0xFFFF;
// etc.

//getter
@property const pure nothrow @nogc typeof_alpha alpha() {
    if (_int & signmask_alpha)
       return cast(typeof(return))(((_int & mask_alpha) >> 
offset_alpha) | signpad_alpha);
    else
       return cast(typeof(return))((_int & mask_alpha) >> 
offset_alpha);
}

// setter
// ...

const pure nothrow @nogc auto opIndex(size_t _i) {
   switch (_i) {
     default:
       assert (0, "Out of bounds.");

      // cases are auto generated from ARGS and mixed in like this
      case 0:
         return alpha;

     case 1:
          return beta;

     case 2:
          return gamma;
}}

// OpIndexAssign, etc.

pure nothrow @nogc auto opIndexUnary(string op)(size_t _i) {
   switch (_i) {
     default:
       assert (0, "Out of bounds.");

      // cases are auto generated from ARGS and mixed in like this
      case 0:
         typeof_alpha result;
         auto tmp = prepare_for_op!(op, "alpha");
         mixin(op ~ "tmp");
         result = finalize!(op, "alpha")(tmp);
         return result;

     // ...

}}

// repeat for beta and gamma

```

I'll revisit the bitfields in std.bitmanip but there were 
shortcomings which prompted me to start ```part_int_t```.



More information about the Digitalmars-d-learn mailing list