On Sunday, 18 November 2018 at 17:30:18 UTC, Dennis wrote:
I'm making a fixed point numeric type and want it to work correctly with const. First problem:

```
const q16 a = 6;
a /= 2;          // compiles! despite `a` being const.

Ouch. That's actually kind of nasty.

writeln(a);      // still 6
a.toQ32 /= 2;    // what's actually happening
```

My q16 type has an implicit conversion to q32 (like how int can be converted to long):
```
q32 toQ32() const {
  return q32(...);
}
alias toQ32 this;
```
How do I make it so that a const(q16) will be converted to a const(q32) instead of mutable q32?

Like this:

        // implement separate methods for mutable/const/immutable
        q32 toQ32() {
            return q32(x);
        }

        const(q32) toQ32() const {
            return q32(x);
        }

        immutable(q32) toQ32() immutable {
            return q32(x);
        }

Or like this:

// implement all three in one method, using the `this template` feature
        auto toQ32(this T)() {
            static if (is(T == immutable))
                return immutable(q32)(x);
            else static if (is(T == const))
                return const(q32)(x);
            else
                return q32(x);
        }


Second problem:
```
Q log2(Q)(Q num) if (is(Q : q16) || is(Q : q32)) {
    import std.traits: Unqual;
    Unqual!Q x = num;
    // actual code
}
```
When I call this with a const(q16), Q is resolved to const(q16) so I have to unqualify Q every time. It works, but feels clumsy. Is there an easier way to automatically de-const parameters? We're working with small value types here, it should be simple.

Define different overloads for Q and const Q. Or this:

Q log2(Q)(inout Q num) if (is(Q : q16) || is(Q : q32)) { /* ... */ }

Being able to jam mutable/const/immutable implementation in one function like that should tell you that you shouldn't mutate the argument. Then, the necessity to Unqual will go away on it's own ;)

Reply via email to