digitalmars.D - scope as template struct
- Christian Kamm (31/31) Jan 13 2009 With the features of D2 you can get pretty close to implementing scope
- Robert Fraser (4/43) Jan 13 2009 Yes this would be possible. But what's the advantage of doing it this
- Christian Kamm (12/18) Jan 13 2009 For the same reason that std.typecons.Rebindable isn't in the language b...
- Eldar Insafutdinov (2/24) Jan 16 2009 and in this case where would be class allocated? On heap? scope allocate...
- Christian Kamm (7/27) Jan 16 2009 Christian Kamm Wrote:
With the features of D2 you can get pretty close to implementing scope classes as a template struct: private final class PlacementNewClass(T) : T { // forward constructors here! new(uint size, byte[__traits(classInstanceSize, PlacementNewClass)] mem) { return &mem; } delete(void* addr) {} } struct StackClass(T) { // forward constructors here! void construct() { new(memory) PlacementNewClass!(T); } ~this() { T tmp = cast(T)this; delete tmp; } // should be opImplicitCast T opCast() { return cast(T)cast(void*)&memory; } T opDot() { return cast(T)cast(void*)&memory; } byte[__traits(classInstanceSize, PlacementNewClass!(T))] memory; } Instances of StackClass!(C) behave pretty much like scope C, except they are not limited to function local variables. Unless there's a major difference to 'scope' I missed, I think that with the addition of a few generic features it should be possible to move it into a library entirely. In particular, D would need opImplicitCast as well as a way of accessing and forwarding constructors to make this work nicely.
Jan 13 2009
Christian Kamm wrote:With the features of D2 you can get pretty close to implementing scope classes as a template struct: private final class PlacementNewClass(T) : T { // forward constructors here! new(uint size, byte[__traits(classInstanceSize, PlacementNewClass)] mem) { return &mem; } delete(void* addr) {} } struct StackClass(T) { // forward constructors here! void construct() { new(memory) PlacementNewClass!(T); } ~this() { T tmp = cast(T)this; delete tmp; } // should be opImplicitCast T opCast() { return cast(T)cast(void*)&memory; } T opDot() { return cast(T)cast(void*)&memory; } byte[__traits(classInstanceSize, PlacementNewClass!(T))] memory; } Instances of StackClass!(C) behave pretty much like scope C, except they are not limited to function local variables. Unless there's a major difference to 'scope' I missed, I think that with the addition of a few generic features it should be possible to move it into a library entirely. In particular, D would need opImplicitCast as well as a way of accessing and forwarding constructors to make this work nicely.Yes this would be possible. But what's the advantage of doing it this way and is it worth sacrificing syntax sugar and backwards compatibility for? And would this even work right with RAII?
Jan 13 2009
Christian Kamm wrote:Robert Fraser wrote:Unless there's a major difference to 'scope' I missed, I think that with the addition of a few generic features it should be possible to move it into a library entirely.Yes this would be possible. But what's the advantage of doing it this way and is it worth sacrificing syntax sugar and backwards compatibility for? And would this even work right with RAII?For the same reason that std.typecons.Rebindable isn't in the language but in a library: if you can build it out of other features, it's not worth making the language more complicated by adding it explicitly. I agree that there's a fine line where ease of use conflicts with orthogonality, but in this case not much sugar seems to be lost. About RAII: The wrapped classes' constructor and destructor are called just fine at the right time. There is a bug that the destructor will probably segfault if construct() wasn't called, but that should be avoidable either by having a flag set on construction or somehow forcing construction during initialization.
Jan 13 2009
Christian Kamm Wrote:Christian Kamm wrote:and in this case where would be class allocated? On heap? scope allocates classes on the stack afaik.Robert Fraser wrote:Unless there's a major difference to 'scope' I missed, I think that with the addition of a few generic features it should be possible to move it into a library entirely.Yes this would be possible. But what's the advantage of doing it this way and is it worth sacrificing syntax sugar and backwards compatibility for? And would this even work right with RAII?For the same reason that std.typecons.Rebindable isn't in the language but in a library: if you can build it out of other features, it's not worth making the language more complicated by adding it explicitly. I agree that there's a fine line where ease of use conflicts with orthogonality, but in this case not much sugar seems to be lost. About RAII: The wrapped classes' constructor and destructor are called just fine at the right time. There is a bug that the destructor will probably segfault if construct() wasn't called, but that should be avoidable either by having a flag set on construction or somehow forcing construction during initialization.
Jan 16 2009
Christian Kamm wrote:Robert Fraser wrote:Unless there's a major difference to 'scope' I missed, I think that with the addition of a few generic features it should be possible to move it into a library entirely.Christian Kamm Wrote:Yes this would be possible. But what's the advantage of doing it this way and is it worth sacrificing syntax sugar and backwards compatibility for? And would this even work right with RAII?Eldar Insafutdinov wrote:For the same reason that std.typecons.Rebindable isn't in the language but in a library: if you can build it out of other features, it's not worth making the language more complicated by adding it explicitly. I agree that there's a fine line where ease of use conflicts with orthogonality, but in this case not much sugar seems to be lost. About RAII: The wrapped classes' constructor and destructor are called just fine at the right time. There is a bug that the destructor will probably segfault if construct() wasn't called, but that should be avoidable either by having a flag set on construction or somehow forcing construction during initialization.and in this case where would be class allocated? On heap? scope allocates classes on the stack afaik.In the case that construct() isn't called? There'd be stack space reserved for the class, but no object constructed inside. The template I posted doesn't touch the heap at all.
Jan 16 2009