On Tue, Aug 01, 2017 at 07:09:45PM -0400, Steven Schveighoffer via Digitalmars-d-learn wrote: > On 8/1/17 6:50 PM, H. S. Teoh via Digitalmars-d-learn wrote: [...] > > Actually, there's nothing about the implementation of both > > byKeyValue (the underlying implementation in druntime) and byPair in > > std.array that would preclude them from being used with const AA's. > > The only flaw is that the declaration of byPair doesn't match const > > AA's: > > > > https://issues.dlang.org/show_bug.cgi?id=17711 > > > > Here's the fix: > > > > https://github.com/dlang/phobos/pull/5668 > > It works, because the byKeyValue implementation is so... ugly. > > For instance this: > > return Result(_aaRange(cast(void*)aa)); > > Just throws away all const/mutability. However, the Pair struct inside > restores the correct modifiers. I hope... > > If this were a true implementation without the opaqueness, it would > not work properly. [...]
Actually, a proper implementation would still work, provided you declare your pointer types carefully. Sketch of idea: auto byKeyValue(AA)(AA aa) { struct Result { const(Slot)* current; // N.B.: proper type bool empty() { ... } auto front() { return Pair(*current); } void popFront() { current = current.next; ... } } return Result(aa); } Basically, the type of `current` must be const(Slot)* rather than const(Slot*), which would be the default inferred type. But since it's legal to assign a const pointer to a pointer to const (you can't modify the original pointer, nor what it points to, but it's valid to copy the pointer to a mutable pointer variable, as long as what is pointed to is still const), this actually will work without breaking / bypassing the type system. T -- People tell me that I'm skeptical, but I don't believe them.