digitalmars.D.learn - Allocating a class within another class during object init w/o passing
- David Zhang (32/32) Dec 15 2016 Hello,
- visitor (31/32) Dec 15 2016 would something like this be a solution ?
- ag0aep6g (40/47) Dec 15 2016 Add a fixed-size array with an appropiate size to the class, and use
- David Zhang (6/6) Dec 15 2016 Thank you for your responses. Visitor, I don't want any reference
- ag0aep6g (8/10) Dec 15 2016 Depends on SomeClass. The array's size is just the value of
- David Zhang (3/14) Dec 15 2016 So the size of Foo would be the size of SomeClass plus members?
- ag0aep6g (22/24) Dec 15 2016 With these definitions:
- David Zhang (4/6) Dec 16 2016 I though all classes were aligned to sizeof(size_t) boundaries?
- ag0aep6g (6/10) Dec 16 2016 I guess? I really don't have much of a clue here.
Hello, It is my understanding that a class can have a struct as one of its members, and it will be allocated in-line with the rest of the class' members. My question is this; how might I be able to do this with another class? I want to be able to allocate Foo using std.experimental.allocator without having to pass in a reference to the actual allocator. Thanks. eg: class SomeClass {} class Foo { this(IAllocator alloc) { sc = alloc.make!SomeClass; this.alloc = alloc } ~this() { alloc.dispose(sc); } size_t something; SomeClass sc; IAllocator alloc } auto foo = alloc.make!Foo(alloc); vs. struct SomeStruct {} class Foo { this() { ss = SomeStruct (...); } size_t something; SomeStruct ss; } auto foo = alloc.make!Foo;
Dec 15 2016
On Thursday, 15 December 2016 at 17:44:23 UTC, David Zhang wrote:would something like this be a solution ? import std.stdio; import std.experimental.allocator; class SomeClass { int someint = 42; static SomeClass opCall(int a) { auto inst = theAllocator.make!SomeClass; inst.someint += a; return inst; } void destruct() { theAllocator.dispose(this); } } class Foo { this() { sc = SomeClass(7); sc.someint -= 42; } ~this() { sc.destruct(); } size_t something; SomeClass sc; } void main(string[] args) { auto foo = theAllocator.make!Foo; assert(foo.sc.someint == 7); theAllocator.dispose(foo); }
Dec 15 2016
On 12/15/2016 06:44 PM, David Zhang wrote:It is my understanding that a class can have a struct as one of its members, and it will be allocated in-line with the rest of the class' members.Yup.My question is this; how might I be able to do this with another class? I want to be able to allocate Foo using std.experimental.allocator without having to pass in a reference to the actual allocator.Add a fixed-size array with an appropiate size to the class, and use std.conv.emplace to construct the object there: ---- class SomeClass {} class Foo { this() { import std.conv: emplace; sc = emplace!SomeClass(scStorage); } SomeClass sc; void[__traits(classInstanceSize, SomeClass)] scStorage; } void main() { import std.experimental.allocator: make; import std.experimental.allocator.mallocator: Mallocator; auto foo = Mallocator.instance.make!Foo; } ---- I haven't considered alignment here. I'm not sure if you have to. The GC will collect the sc object along with the parent Foo. Be cautious of that when you allow public access to sc. You can also replace the sc field with a method that creates the class reference on the fly (it's just a cast): ---- class Foo { this() { import std.conv: emplace; emplace!SomeClass(scStorage); } property SomeClass sc() { return cast(SomeClass) scStorage.ptr; } void[__traits(classInstanceSize, SomeClass)] scStorage; } ----
Dec 15 2016
Thank you for your responses. Visitor, I don't want any reference to an allocator within the class if I can avoid it. ag0aep6g, thanks! That's what I was looking for. However, it leaves me with another question, how much (if any) space would the static array require from the class? It's not a strict necessity for me, but I'm curious.
Dec 15 2016
On 12/15/2016 09:51 PM, David Zhang wrote:However, it leaves me with another question, how much (if any) space would the static array require from the class?Depends on SomeClass. The array's size is just the value of __traits(classInstanceSize, SomeClass). There's no overhead. You can print such stuff at compile time with pragma(msg, ...): ---- pragma(msg, __traits(classInstanceSize, SomeClass)); pragma(msg, Foo.scStorage.sizeof); /* same */ ----
Dec 15 2016
On Thursday, 15 December 2016 at 21:08:51 UTC, ag0aep6g wrote:On 12/15/2016 09:51 PM, David Zhang wrote:So the size of Foo would be the size of SomeClass plus members? ie. Is the size of the array stored too?However, it leaves me with another question, how much (if any) space would the static array require from the class?Depends on SomeClass. The array's size is just the value of __traits(classInstanceSize, SomeClass). There's no overhead. You can print such stuff at compile time with pragma(msg, ...): ---- pragma(msg, __traits(classInstanceSize, SomeClass)); pragma(msg, Foo.scStorage.sizeof); /* same */ ----
Dec 15 2016
On Thursday, 15 December 2016 at 21:37:34 UTC, David Zhang wrote:So the size of Foo would be the size of SomeClass plus members? ie. Is the size of the array stored too?With these definitions: ---- class SomeClass {} class Foo { this() { import std.conv: emplace; emplace!SomeClass(scStorage); } property SomeClass sc() { return cast(SomeClass) scStorage.ptr; } void[__traits(classInstanceSize, SomeClass)] scStorage; } ---- the "instance size" of Foo is the size of a) Foo's hidden/implicit fields which all classes have, plus b) the size of scStorage which is Foo's only explicit field. The size of scStorage is the instance size of SomeClass (just the implicit fields here). The size/length of scStorage is known at compile-time. It's not stored in Foo.
Dec 15 2016
I haven't considered alignment here. I'm not sure if you have to.I though all classes were aligned to sizeof(size_t) boundaries? Wouldn't it then just be align(sizeof(size_t)) byte[__traits(classInstanceSize, SomeClass)] scStorage;
Dec 16 2016
On Friday, 16 December 2016 at 18:25:42 UTC, David Zhang wrote:I though all classes were aligned to sizeof(size_t) boundaries?I don't know.Wouldn't it then just be align(sizeof(size_t)) byte[__traits(classInstanceSize, SomeClass)] scStorage;I guess? I really don't have much of a clue here. Looking around a bit, I found std.traits.classInstanceAlignment which seems fitting. http://dlang.org/phobos/std_traits.html#classInstanceAlignment
Dec 16 2016