When I initially created my allocators proposal, I figured wrongly that the community would be most interested in seeing a few examples of allocators and that a more formal specification of the allocator interface wasn't terribly important yet. I was wrong, so I got off my butt and wrote a more formal specification. I also made a few other important changes to my allocators proposal:

1. DynamicAllocator allows a struct or class that conforms to the structural allocator interface to be turned into a runtime interface with virtual functions, etc. The reason for this trick instead of just making Allocator a "virtual" interface is to allow scoped allocators, allocators with value semantics, allocators with reference counting, etc. and only live within the constraints of the virtual function world when absolutely necessary. One examples of where the virtual function world is a severe constraint is the templated functions create, newArray, uninitializedArray and array. These were simply left out of the DynamicAllocator. Another is the ugliness and unsafety of using the DynamicAllocator interface with RegionAllocator, as RegionAllocator's scoped semantics create a severe impedance mismatch.

2. I added create(T) for creating new class and struct instances on an allocator.

3. I cleaned up the documentation of RegionAllocator according to Andrei's suggestions. I double-checked and freeIsChecked, etc. are enums. DDoc just doesn't reflect this.

4.  Various fixes for small bugs pointed out by the community.

5. Noted that finalizers/destructors are never automatically called when RegionAllocator-allocated memory gets freed, because the bookkeeping burden of this would be unacceptable and it would prevent O(1) freeing. RegionAllocator is such an unsafe performance hack anyhow that I see very little wrong with "buyer beware" here. Besides, most use cases for it (at least most of mine) are allocating temporary arrays of primitives and containers would use the lower-level DynamicAllocator interface. YMMV.

6. I did **not** change the documentation of the relationship between RegionAllocatorStack and RegionAllocator because I just don't see a good way to do it. I'm open to suggestions.

7.  std.regionallocator -> std.allocators.region, etc.

8. The high-level, templated allocator functions now have a default implementation in terms of lower-level allocator functionality, provided by the TypedAllocatorMixin mixin in std.allocators.allocator. The idea is that an allocator may have better ways of accomplishing this stuff, but this mixin is usually a reasonable default and will avoid code duplication across allocators. I'm leery of including it in the DynamicAllocator interface, though, because for some allocators it's just plain wrong. For example, the default array() implementation just plain wouldn't work with RegionAllocator for huge ranges.

Code:

https://github.com/dsimcha/TempAlloc/tree/master/std/allocators

Docs:
http://cis.jhu.edu/~dsimcha/d/phobos/std_allocators_allocator.html
http://cis.jhu.edu/~dsimcha/d/phobos/std_allocators_gc.html
http://cis.jhu.edu/~dsimcha/d/phobos/std_allocators_region.html

Reply via email to