Skip to content

Instantly share code, notes, and snippets.

@GilesBathgate
Last active April 20, 2018 13:26
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save GilesBathgate/8409b5889ebb7b1302627c50f342a28b to your computer and use it in GitHub Desktop.
Save GilesBathgate/8409b5889ebb7b1302627c50f342a28b to your computer and use it in GitHub Desktop.
extern (C) void* _aaGetX(void** paa, const TypeInfo_AssociativeArray ti, in size_t valuesize, in void* pkey, out bool found) pure nothrow;
V* slot(K, V)(ref V[K] aa, K key, out bool found)
{
return cast(V*) _aaGetX(cast(void**)&aa, typeid(V[K]), V.sizeof, &key, found);
}
void update(K, V, C, U)(ref V[K] aa, K key, C create, U update)
if (is(C : V delegate()) || is(C : V function()) && (is(U : V delegate(ref V)) || is(U : V function(ref V))))
{
bool found = true;
auto p = cast(V*) _aaGetX(cast(void**)&aa, typeid(V[K]), V.sizeof, &key, found);
if (!found)
*p = create();
else
*p = update(*p);
}
void test1()
{
class C
{
}
C[string] aa;
C orig = new C;
aa["foo"] = orig;
C newer;
C older;
bool found;
auto p = aa.slot("foo", found);
if(!found)
{
newer = new C;
*p = newer;
} else {
older = *p;
newer = new C;
*p = newer;
}
assert(older is orig);
assert(newer is aa["foo"]);
}
void test2()
{
class C
{
}
C[string] aa;
C orig = new C;
aa["foo"] = orig;
C newer;
C older;
aa.update("foo",
{
newer = new C;
return newer;
}, (C c) {
older = c;
newer = new C;
return newer;
});
assert(older is orig);
assert(newer is aa["foo"]);
}
void main()
{
import std.datetime.stopwatch, std.stdio;
auto r1 = benchmark!test1(100_000);
writeln("test1 ", r1);
auto r2 = benchmark!test2(100_000);
writeln("test2 ", r2);
getchar();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment