Comment #0 by pro.mathias.lang — 2015-02-17T12:22:47Z
Currently they are 5 "kinds" of emplace:
0) pure nothrow @safe T* emplace(T)(T* chunk);
1) T* emplace(T, Args...)(T* chunk, auto ref Args args)
if (!is(T == struct) && Args.length == 1);
2) T* emplace(T, Args...)(T* chunk, auto ref Args args)
if (is(T == struct));
3) T emplace(T, Args...)(void[] chunk, auto ref Args args)
if (is(T == class));
4) T* emplace(T, Args...)(void[] chunk, auto ref Args args)
if (!is(T == class));
"Kind" 0, 1, 2 and 4 are documented as working on "non-class type". However, except for 4, their signature doesn't reflect that, so they are pretty easy to misuse, leading to unrelated error message (E.g: /usr/include/dlang/dmd/std/conv.d(3839): Error: static assert "Condition cannot be emplaced from a Mutex."). (Condition and Mutex in their respective modules in core.sync).
That left us with only kind 3 to emplace classes, which means that a generic approach to a memory allocator should use the void[] approach for it's allocations.
Now, since it's a memory allocator, you want to have it nothrow, but kind 3 calls testEmplaceChunk, which itself check for the size and throw on error.
So far, it looks to me like calling emplace for a class with a void[] that's too small is a programmer error, as he failed to create to correct size / validate the arguments, and so it should be an in contract in emplace, rather than a private function that throw exception.
Will try to submit something when I get a bit of time.