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```.

Reply via email to