const and immutable objects

Jeremie Pelletier jeremiep at gmail.com
Sun Aug 30 18:28:18 PDT 2009


Graham St Jack Wrote:

> 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);
>     }
> }
> 

I agree that D lacks a mechanism to separate the object from it's reference. Maybe syntax like the following could be used to apply the storage class to the object value, and not the reference value:

class Foo;
void bar(in Foo& foo) {}

It's quite ugly and C-like, but that's the first thing that came to mind. The reference value is unique to the current method and shouldn't share the same storage qualifiers as it's referenced memory.



More information about the Digitalmars-d mailing list