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/ubithltzbtdypaegn...@forum.dlang.org).

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,


, 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

Reply via email to