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