digitalmars.D - Suggestion for allocators and D integration for them
- foobar (64/64) Jul 16 2010 Recently Andrei asked for a design for allocators and there was also a d...
- Petr Janda (4/4) Jul 19 2010 I would be interested to see what other think about this.
Recently Andrei asked for a design for allocators and there was also a discussion about removing "delete" and maybe even "new". Here's my design ideas: 1. we define some Allocator interface, e.g. //shamelessly copied from Andrei and put into an interface :) Interface Allocator { T* create(T, Args...)(Args args) if (!is(T == class) && !isDynamicArray!T); T create(T, Args...)(Args args) if (is(T == class) || isDynamicArray!T); void destroy(T)(ref T obj); // add other functions? } The GC will need to implement the interface. 2. we remove placement new. 3. we allow to define a regular (virtual) member-function called "new" that has an argument of type Allocator in its argument list 4. Constructors can become virtual The semantics would be that "new" contains logic for allocation and "this" contains logic for initialization here's an example: interface Pizza { override property double price(); } class MushroomPizza : Pizza { private: int size; public: property double price() { return 5.5; } this(int a) { size = a; } } class DeluxePizza : Pizza { private: int size; public: property double price() { return 7.5; } A this(int a) { size = a; } } class HawaiianPizza : Pizza { // only personal pizzas property double price() { return 12.5; } } // built in the language factory design pattern :) class PizzaFactory { Pizza new(Allocator allocator, string type, int size = 1) { if (type == "Mushroom") return allocator.create! MushroomPizza(size); else if (type == "Deluxe") return allocator.create!DeluxePizza(size); else if (type == "Hawaiian") return allocator.create!HawaiianPizza(); } } we can do a simple trick in order to preserve current syntax to use the above: auto p1 = new(FooAlloc) PizaaFactory("Hawaiian"); Pizza p2 = new PizaaFactory("Deluxe", 4); where the compiler rewrites it to: auto p1 = PizaaFactory.new(FooAlloc, "Hawaiian"); Pizza p2 = PizaaFactory.new(GC, "Deluxe", 4); // defaults to GC for classes D would provide compatible GC Allocator for reference types and a StackAllocator for value types. For example, to allocate a struct on the heap you'd call: auto value = new(GC) Struct(arg1, arg2); we can require empty parens after new to force new default behavior, e.g. // current semantics that the compiler can warn about auto pizza = new HawaiianPizza(4); // new semantics: "new" is called with GC as allocator auto pizza = new() HawaiianPizza(4); What do you think?
Jul 16 2010
I would be interested to see what other think about this. Sounds pretty cool for me! Thanks, Petr
Jul 19 2010