why won't byPair work with a const AA?

H. S. Teoh via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Tue Aug 1 16:15:12 PDT 2017


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.


More information about the Digitalmars-d-learn mailing list