important proposal: scope keyword for class members

Denis Koroskin 2korden at gmail.com
Sun Mar 8 18:31:23 PDT 2009


On Sat, 07 Mar 2009 08:15:59 +0300, John Simon <zildjohn01 at gmail.com> wrote:

> I'd like to propose a new use for the 'scope' keyword within an  
> aggregate body.
>
> Members of class type declared with the scope keyword are allocated not  
> as references or pointers, but initialized directly inside the  
> container.  Instead of a default initializer of 'null', it will  
> initialize with the default constructor of the class, or an optional  
> assignment after the declaration. Any 'new [type]' within the assignment  
> will resolve to a simple call to the type's __ctor, instead of a memory  
> allocation.
>
> Example:
>
> class Inner {
>     this() {}
>     this(int x) {}
> }
>
> class Container {
>     Inner i1; // initialized to null
>     scope Inner i2; // allocated within class
>     scope i3 = new Inner(42); // allocated within class
>
>     this() {
>         // implicit i2.__ctor();
>         // i3.__ctor(42) written above, executed here
>         assert(i1 is null);
>         assert(i2 !is null);
>         i1 = new Inner;
>     }
>
>     this(int overloaded) {
>         // i2 and i3 are constructed, same as above
>     }
>
>     ~this() {
>         // implicit i2.__dtor();
>         // implicit i3.__dtor();
>         // i1 is still somewhere in the heap
>     }
> }
>
> IN ENGLISH:
>
> If it's likely that class members will be constructed with and die with  
> the object, why not just allocate them right in the class? Save on heap  
> fragmentation and cache misses.  I was honesetly flabberghasted when I  
> realized there was no way to do this in D, it seems like it should be  
> one of the most basic constructs of a C-derived (or any low-ish level)  
> language.
>
> The programmer knows best where he wants his objects stored. Also, the  
> 'scope' makes sense, and we should mirror the current behavior of the  
> keyword in function bodies.

I belive it could be implemented in a library. Something like this (not tested):

struct Scope(T)
{
    static assert(is(T : class));

    private ubyte[SizeOf!(T)] _data = T.init[];
    private bool _isConstructed = false;

    T value()
    {
        return cast(T)_data.ptr;
    }

    alias this value;

    void construct(Params...)(Params params) // perhaps, could be 'this'
    {
        assert(!_isConstructed);
        value.ctor(params);
        _isConstructed = true;
    }
}

Usage:

class Foo {
    this(int i) { this.i = i; }
    int i;
    void doSomething() { }
}

class Bar
{
    Scope!(Foo) foo;

    this()
    {
        // optional:
        foo.construct(42); // different syntax is also possible
        // same as foo = new Foo(42);

        Foo f = foo; // implicit cast
        foo.doSomething();
        int i = foo.i;       
    }
}




More information about the Digitalmars-d mailing list