On Sat, 07 Mar 2009 08:15:59 +0300, John Simon <zildjoh...@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; }
}

Reply via email to