mirror of
https://github.com/xomboverlord/ldc.git
synced 2026-04-18 01:39:03 +02:00
Make "aa[key]" use the same runtime call as "key in aa". The runtime calls
these were using were different, but with equivalent definitions.
With `ldc -O3`, the following functions now all compile to the exact same code:
{{{
int[int] y;
void foo(int x) {
if (x in y) {
auto z = x in y;
sink(*z);
}
}
void bar(int x) {
if (x in y) {
sink(y[x]);
}
}
void baz(int x) {
if (auto p = x in y) {
sink(*p);
}
}
}}}
This commit is contained in:
@@ -292,43 +292,7 @@ Lret:
|
||||
/*************************************************
|
||||
* Get pointer to value in associative array indexed by key.
|
||||
* Returns null if it is not already there.
|
||||
*/
|
||||
|
||||
void* _aaGetRvalue(AA aa, TypeInfo keyti, size_t valuesize, void *pkey)
|
||||
{
|
||||
//printf("_aaGetRvalue(valuesize = %u)\n", valuesize);
|
||||
if (!aa)
|
||||
return null;
|
||||
|
||||
//auto pkey = cast(void *)(&valuesize + 1);
|
||||
auto keysize = aligntsize(keyti.tsize());
|
||||
auto len = aa.b.length;
|
||||
|
||||
if (len)
|
||||
{
|
||||
auto key_hash = keyti.getHash(pkey);
|
||||
//printf("hash = %d\n", key_hash);
|
||||
size_t i = key_hash % len;
|
||||
auto e = aa.b[i];
|
||||
while (e !is null)
|
||||
{
|
||||
if (key_hash == e.hash)
|
||||
{
|
||||
auto c = keyti.compare(pkey, e + 1);
|
||||
if (c == 0)
|
||||
return cast(void *)(e + 1) + keysize;
|
||||
e = (c < 0) ? e.left : e.right;
|
||||
}
|
||||
else
|
||||
e = (key_hash < e.hash) ? e.left : e.right;
|
||||
}
|
||||
}
|
||||
return null; // not found, caller will throw exception
|
||||
}
|
||||
|
||||
|
||||
/*************************************************
|
||||
* Determine if key is in aa.
|
||||
* Used for both "aa[key]" and "key in aa"
|
||||
* Returns:
|
||||
* null not in aa
|
||||
* !=null in aa, return pointer to value
|
||||
|
||||
Reference in New Issue
Block a user