const and immutable objects

Graham St Jack graham.stjack at internode.on.net
Sun Aug 30 15:31:33 PDT 2009


I have been trying (again) to start using const and immutable objects in 
a project, and found I kept getting stuck with the need to change the 
value of object references, which isn't allowed. I don't quite follow the 
arguments that mean that this has to be the case, but I'm prepared to 
accept them.

After some experimenting with Andrei's Rebindable template, I still 
couldn't get past the problems. For a start, the get method is private so 
I couldn't test for null.

In the end I cooked up the following, which is a very simple workaround 
that just lets me assign to a const or immutable object reference. It 
works just fine, and can be used in templates like containers without 
forcing the container to care about what it is containing.

Comments?

//
// Assign dest to src, using brute-force methods as necessary if T
// is an immutable or const object.
//
// The intent is to avoid needing routine nasty tricks in
// application code, especially in template code which should be
// spared the complication of handling this very annoying
// restriction on objects. Use of this template function doesn't
// let you change the object itself, just the reference to it - so
// all should be well.
//
void forcefulAssign(T)(ref T dest, T src) {
    static if (!is(T X == const(U), U) &&  !is(T X == invariant(U), U)) {
        // T is not const or immutable - just assign normally
        dest = src;
    }
    else static if (is(T : Object)) {
        // T is a const or immutable object - use brute force
        U * ptr = cast(U *) &dest;
        *ptr = cast(U) src;
    }
    else {
        // T is some other const or immutable type - not assignable
        static assert(false, "cannot assign to " ~ T.stringof);
    }
}

// assign the default initializer to something
void forcefulInitialize(T)(ref T dest) {
    static if (!is(T X == const(U), U) &&  !is(T X == invariant(U), U)) {
        // T is not const or immutable - just initialise normally
        dest = T.init;
    }
    else static if (is(T : Object)) {
        // T is a const or immutable object - use brute force
        U * ptr = cast(U *) &dest;
        *ptr = U.init;
    }
    else {
        // T is some other const or immutable type - not assignable
        static assert(false, "cannot assign to " ~ T.stringof);
    }
}




More information about the Digitalmars-d mailing list