www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - C'tors from templates

reply dsimcha <dsimcha yahoo.com> writes:
Is there a way to run a class's c'tor on a block of memory from a template
function?  For example:

C newClass(C, CtorArgs...)(CtorArgs args) {
    // Allocate, initialize.
    // Want to call the c'tor that takes type CtorArgs.
}
Oct 31 2009
next sibling parent reply Robert Clipsham <robert octarineparrot.com> writes:
dsimcha wrote:
 Is there a way to run a class's c'tor on a block of memory from a template
 function?  For example:
 
 C newClass(C, CtorArgs...)(CtorArgs args) {
     // Allocate, initialize.
     // Want to call the c'tor that takes type CtorArgs.
 }

---- C newClass(C, CtorArgs...)(CtorArgs args) { return new C(args); } class Foo{ this(int a, string b) { /* do something */ } } auto foo = newClass!(Foo)(1, "bar"); ---- That seems to work here... or are you meaning you already have a block of memory allocated and want to turn it into an instance of the class? In which case something like: ---- C newClass(C, CtorArgs...)(CtorArgs args) { void* mem; // Allocate/initialize etc, store in inst of type C // Stolen/adapted from Object.d: if( inst.classinfo.flags & 8 && inst.classinfo.defaultConstructor ) { C delegate(CtorArgs) ctor; ctor.ptr = cast(void*)inst; ctor.funcptr = cast(C function(CtorArgs)) inst.classinfo.defaultConstructor; return ctor(args); } return null; } ---- Should work (untested).
Oct 31 2009
parent reply dsimcha <dsimcha yahoo.com> writes:
== Quote from Robert Clipsham (robert octarineparrot.com)'s article
 dsimcha wrote:
 Is there a way to run a class's c'tor on a block of memory from a template
 function?  For example:

 C newClass(C, CtorArgs...)(CtorArgs args) {
     // Allocate, initialize.
     // Want to call the c'tor that takes type CtorArgs.
 }

C newClass(C, CtorArgs...)(CtorArgs args) { return new C(args); } class Foo{ this(int a, string b) { /* do something */ } } auto foo = newClass!(Foo)(1, "bar"); ---- That seems to work here... or are you meaning you already have a block of memory allocated and want to turn it into an instance of the class? In which case something like: ---- C newClass(C, CtorArgs...)(CtorArgs args) { void* mem; // Allocate/initialize etc, store in inst of type C // Stolen/adapted from Object.d: if( inst.classinfo.flags & 8 && inst.classinfo.defaultConstructor ) { C delegate(CtorArgs) ctor; ctor.ptr = cast(void*)inst; ctor.funcptr = cast(C function(CtorArgs)) inst.classinfo.defaultConstructor; return ctor(args); } return null; } ---- Should work (untested).

I meant the latter, but not just for the default constructor, for any constructor.
Oct 31 2009
parent Robert Clipsham <robert octarineparrot.com> writes:
dsimcha wrote:
 == Quote from Robert Clipsham (robert octarineparrot.com)'s article
 dsimcha wrote:
 Is there a way to run a class's c'tor on a block of memory from a template
 function?  For example:

 C newClass(C, CtorArgs...)(CtorArgs args) {
     // Allocate, initialize.
     // Want to call the c'tor that takes type CtorArgs.
 }

C newClass(C, CtorArgs...)(CtorArgs args) { return new C(args); } class Foo{ this(int a, string b) { /* do something */ } } auto foo = newClass!(Foo)(1, "bar"); ---- That seems to work here... or are you meaning you already have a block of memory allocated and want to turn it into an instance of the class? In which case something like: ---- C newClass(C, CtorArgs...)(CtorArgs args) { void* mem; // Allocate/initialize etc, store in inst of type C // Stolen/adapted from Object.d: if( inst.classinfo.flags & 8 && inst.classinfo.defaultConstructor ) { C delegate(CtorArgs) ctor; ctor.ptr = cast(void*)inst; ctor.funcptr = cast(C function(CtorArgs)) inst.classinfo.defaultConstructor; return ctor(args); } return null; } ---- Should work (untested).

I meant the latter, but not just for the default constructor, for any constructor.

I'm not sure that it's possible to access ctors other than the default one, I can't seem to find any mention of them in the abi or object.d, you might have better luck if you search yourself though, I only had a quick skim. If not it might be worth a feature request?
Oct 31 2009
prev sibling next sibling parent reply grauzone <none example.net> writes:
dsimcha wrote:
 Is there a way to run a class's c'tor on a block of memory from a template
 function?  For example:
 
 C newClass(C, CtorArgs...)(CtorArgs args) {
     // Allocate, initialize.
     // Want to call the c'tor that takes type CtorArgs.
 }

Deeply hidden on the Digitalmars homepage, it hints _ctor() and shows how to correctly construct an object (if you're using dmd): http://www.digitalmars.com/techtips/class_objects.html
Oct 31 2009
parent reply dsimcha <dsimcha yahoo.com> writes:
== Quote from grauzone (none example.net)'s article
 dsimcha wrote:
 Is there a way to run a class's c'tor on a block of memory from a template
 function?  For example:

 C newClass(C, CtorArgs...)(CtorArgs args) {
     // Allocate, initialize.
     // Want to call the c'tor that takes type CtorArgs.
 }

how to correctly construct an object (if you're using dmd): http://www.digitalmars.com/techtips/class_objects.html

Yeah, I had thought of this, but apparently it doesn't work anymore. This is called excessive encapsulation--making things so opaque that, when someone really knows what they're doing and has a good reason to mess around with the internals, they still can't. I'll file an enhancement requesting that this be put back.
Oct 31 2009
parent reply dsimcha <dsimcha yahoo.com> writes:
== Quote from dsimcha (dsimcha yahoo.com)'s article
 == Quote from grauzone (none example.net)'s article
 dsimcha wrote:
 Is there a way to run a class's c'tor on a block of memory from a template
 function?  For example:

 C newClass(C, CtorArgs...)(CtorArgs args) {
     // Allocate, initialize.
     // Want to call the c'tor that takes type CtorArgs.
 }

how to correctly construct an object (if you're using dmd): http://www.digitalmars.com/techtips/class_objects.html

called excessive encapsulation--making things so opaque that, when someone really knows what they're doing and has a good reason to mess around with the internals, they still can't. I'll file an enhancement requesting that this be put back.

Never mind, I realized I was doing two things wrong: 1. It changed from _ctor to __ctor. 2. The class needs to define a c'tor If it doesn't, then there's no default __ctor() that takes no args. However, this is easy to check for in a static if statement.
Oct 31 2009
parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
dsimcha wrote:
 == Quote from dsimcha (dsimcha yahoo.com)'s article
 == Quote from grauzone (none example.net)'s article
 dsimcha wrote:
 Is there a way to run a class's c'tor on a block of memory from a template
 function?  For example:

 C newClass(C, CtorArgs...)(CtorArgs args) {
     // Allocate, initialize.
     // Want to call the c'tor that takes type CtorArgs.
 }

how to correctly construct an object (if you're using dmd): http://www.digitalmars.com/techtips/class_objects.html

called excessive encapsulation--making things so opaque that, when someone really knows what they're doing and has a good reason to mess around with the internals, they still can't. I'll file an enhancement requesting that this be put back.

Never mind, I realized I was doing two things wrong: 1. It changed from _ctor to __ctor. 2. The class needs to define a c'tor If it doesn't, then there's no default __ctor() that takes no args. However, this is easy to check for in a static if statement.

Walter and I talked a few times about the necessity of providing useful functions a la C++'s placement new in Phobos. std.algorithm offers swap and move, but we need some more. Please advise. Andrei
Oct 31 2009
parent dsimcha <dsimcha yahoo.com> writes:
== Quote from Andrei Alexandrescu (SeeWebsiteForEmail erdani.org)'s article
 dsimcha wrote:
 == Quote from dsimcha (dsimcha yahoo.com)'s article
 == Quote from grauzone (none example.net)'s article
 dsimcha wrote:
 Is there a way to run a class's c'tor on a block of memory from a template
 function?  For example:

 C newClass(C, CtorArgs...)(CtorArgs args) {
     // Allocate, initialize.
     // Want to call the c'tor that takes type CtorArgs.
 }

how to correctly construct an object (if you're using dmd): http://www.digitalmars.com/techtips/class_objects.html

called excessive encapsulation--making things so opaque that, when someone really knows what they're doing and has a good reason to mess around with the internals, they still can't. I'll file an enhancement requesting that this be put back.

Never mind, I realized I was doing two things wrong: 1. It changed from _ctor to __ctor. 2. The class needs to define a c'tor If it doesn't, then there's no default __ctor() that takes no args. However, this is easy to check for in a static if statement.

functions a la C++'s placement new in Phobos. std.algorithm offers swap and move, but we need some more. Please advise. Andrei

Basically, I've got the back end stuff for precise heap scanning (the GC implementation itself) working. I've got the front end stuff (the templates to generate the pointer offset information at compile time) working. I still need the middle end (getting the pointer offset information into the GC for anything other than a direct call to GC.malloc). Right now, the functions that get called when you use the new keyword don't have access to compile time type info, and runtime type info is too crippled to generate pointer offset info from (which is part of why I'm doing it at compile time in the first place). I figured I should at least have a prototype of this functionality before I submit the patch b/c otherwise it's not that practically useful. The problem was that how to run the constructor on a block of memory isn't well-documented, so it took a while for me to figure out. Ideally, allocating class instances and arrays in a way that provides the GC with the information necessary for precise scanning of said objects would be the default, but this won't happen without modification of the compiler. Until then, I just wanted there to be an easy, if non-default, way to do this.
Oct 31 2009
prev sibling parent reply Robert Clipsham <robert octarineparrot.com> writes:
dsimcha wrote:
 Is there a way to run a class's c'tor on a block of memory from a template
 function?  For example:
 
 C newClass(C, CtorArgs...)(CtorArgs args) {
     // Allocate, initialize.
     // Want to call the c'tor that takes type CtorArgs.
 }

After reading the ticket you made, I was wondering if what you were looking for was: http://www.digitalmars.com/d/1.0/class.html#allocators http://www.digitalmars.com/d/1.0/class.html#deallocators This allows you to use a custom allocator/deallocator and not worry about calling the correct ctor/dtor. If you want to change it for all classes, have a look at the _d_allocclass (or _d_newclass depending on your compiler/runtime) function in the runtime. If you change this you will need to recompile the runtime and it won't work for anyone else unless they use your modified runtime.
Oct 31 2009
parent dsimcha <dsimcha yahoo.com> writes:
== Quote from Robert Clipsham (robert octarineparrot.com)'s article
 dsimcha wrote:
 Is there a way to run a class's c'tor on a block of memory from a template
 function?  For example:

 C newClass(C, CtorArgs...)(CtorArgs args) {
     // Allocate, initialize.
     // Want to call the c'tor that takes type CtorArgs.
 }

looking for was: http://www.digitalmars.com/d/1.0/class.html#allocators http://www.digitalmars.com/d/1.0/class.html#deallocators This allows you to use a custom allocator/deallocator and not worry about calling the correct ctor/dtor. If you want to change it for all classes, have a look at the _d_allocclass (or _d_newclass depending on your compiler/runtime) function in the runtime. If you change this you will need to recompile the runtime and it won't work for anyone else unless they use your modified runtime.

Yes, but... Unless I hack the compiler, only *runtime* type info gets passed to this function. I need *compile time* type info so it can be passed to templates to generate/get the bit mask for the type for my precise heap scanning scheme.
Oct 31 2009