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:44:53 PDT 2017


On Tue, Aug 01, 2017 at 07:31:41PM -0400, Steven Schveighoffer via Digitalmars-d-learn wrote:
> On 8/1/17 7:15 PM, H. S. Teoh via Digitalmars-d-learn wrote:
> > On Tue, Aug 01, 2017 at 07:09:45PM -0400, Steven Schveighoffer via Digitalmars-d-learn wrote:
> > > 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.
> 
> No, you can't const the Slot, because if the value type is a pointer,
> you can't then cast away the const-ness of it legally.
> 
> There are ways to get it right, it involves templating for mutability.
[...]

Counter-proof:

	struct Slot {
		Slot* next;
		const(string) key;
		const(int) value;
	}
	struct AA {
		Slot*[] slots;
	}
	unittest {
		const(AA) aa;

		static assert(is(typeof(aa.slots[0]) == const(Slot*)));
		const(Slot)* p = aa.slots[0];	// N.B.: legal
		p = p.next;			// N.B.: legal
	}

Note especially the type checked for in the static assert: you cannot
modify any of the Slot pointers in the AA, but you *can* assign them to
mutable (but tail-const) pointers. Therefore you totally can iterate a
const AA without any casts or any breaking of the type system. And
there's no need to template for mutability either.


T

-- 
One Word to write them all, One Access to find them, One Excel to count them all, And thus to Windows bind them. -- Mike Champion


More information about the Digitalmars-d-learn mailing list