Implicit conversions for AA keys

H. S. Teoh hsteoh at quickfur.ath.cx
Fri Mar 23 17:20:24 PDT 2012


On Fri, Mar 23, 2012 at 10:53:10PM +0100, Timon Gehr wrote:
> On 03/23/2012 10:07 PM, Timon Gehr wrote:
> >
> >I see. An alternative solution (one that does not make AAs depend on
> >Phobos and is more slick) would be to use the const qualified key type
> >for lookup (that is what const is for) and to have immutable keys for
> >stores. For types that define .idup, there would be another overload of
> >opIndexAssign that can take a const qualified key.
> 
> Proof of concept:
[...]

Hmm. I decided that perhaps the full-fledged std.conv.to is a bit of an
overkill, so I revised the AA code to compromise between needing
std.conv.to and still deliver what Andrei wants.

Basically, I have a template that defines AA key compatibility, where
compatibility means that given an AA with key type Key and a key k of
type K, k is considered compatible if:

- k==K.init is valid (i.e. they can be compared);
- (At least) one of the following holds:
   - is(immutable(K) == immutable(Key))
   - is(typeof(k.idup) == Key)
   - Key is a static array of length N, and k[0..N] is valid.
   - is(K : Key)

For the first case (is(immutable(K)==immutable(Key)), which means K and
Key have the "same representation") and the second case (K.idup yields
Key), we can basically assume that K.toHash() is consistent with
Key.toHash(). When creating a new entry, we just assign K to Key, or
K.idup to Key as necessary.

For the third case, we can just slice the input array when comparing or
assigning to a new entry (this will throw an Error if the input array
has the wrong length). I decided to be permissive and compute the hash
on the entire array, if the length doesn't match it will fail anyway, so
it's OK to lookup an array of mismatching length in an AA with static
array keys, as long as you don't try to store the key into it.

Lastly, if is(K : Key) holds but none of the others do, then convert the
key before computing the hash:

	Key key = k;	// implicit conversion
	return key.toHash();

This ensures the int->double conversion works correctly. Creating a new
entry can just use straight assignment, due to the implicit conversion.

I've added these changes on github in a branch:

	https://github.com/quickfur/New-AA-implementation/tree/keyconv

Andrei, please try it out and see if it works on the cases you have in
mind. :-)


T

-- 
Try to keep an open mind, but not so open your brain falls out. -- theboz


More information about the Digitalmars-d mailing list