On Sunday, 9 April 2017 at 13:59:14 UTC, Andrei Alexandrescu
wrote:
. The allocator has to be specified as part of the type: this
means the user can choose how to store it in the smart
pointer, which for singletons (e.g. Mallocator) or stateless
allocators means they can take up zero space. If a singleton
(or the default theAllocator), the allocator doesn't need to
be passed in to the constructor, otherwise it does.
Specifying, e.g. Mallocator also means the relevant code can
be marked @nogc.
After extensively studying how C++ allocator framework works, I
got to the notion that making the allocator part of the type is
an antipattern.
Just repeating an older argument of mine which didn't make it
during the std.allocator discussions
(http://forum.dlang.org/post/[email protected]).
Yes, we clearly want type erasure for the Allocator, because
having the Allocator as part of the type tends to push Allocator
choices/forwarding everywhere into the APIs. It also prevents
conversion/copying values with different allocators.
The obvious solution is to use an Allocator interface and/or a
custom deleter function (deleter was needed for attribute correct
destruction with polymorphic RC!Klass, see [¹]).
Now as Chandler Carruth mentions,
https://www.youtube.com/watch?v=fHNmRkzxHWs&t=3950
https://www.youtube.com/watch?v=fHNmRkzxHWs&t=4037
, an interface with dynamic dispatch would prevent optimizing
away redundant allocations.
Allocations are complex enough that I'm not too worried about the
virtual call overhead itself.
I think we might be able to solve this problem in D by making
IAllocator.allocate pure, which tells the compiler that this
function returns a fresh piece of memory without any side-effect,
i.e. enough information to optimize away allocations.
Pure might be too restrictive for some allocators, but maybe this
can be solved with a little type system hack (or at worse a
compiler exemption).
[¹]:
https://github.com/MartinNowak/phobos/commit/8cf0ec29ad65ac2a13bd6917b4ff3da0fdea5ab0#diff-4e008aedb3026d4a84f58323e53bf017R4896