Thread overview
Could use some help with porting problems
Feb 08, 2012
Roderick Gibson
Feb 08, 2012
bearophile
Feb 08, 2012
Daniel Murphy
Feb 08, 2012
Roderick Gibson
February 08, 2012
So I needed a coherent noise generator and decided to look at libnoise. Noticing it was rather small I decided I would just port it over to d and be done with it, as I expected it would help me understand d a bit better (it has).

My problems all seem to stem from the const qualifier, which is actually rather different between d and c++, and coming from a web programming background is somewhat alien to me.

So my question is 1) How would I declare an array of pointers to const(Class)? That is, how do I declare an array such that the ARRAY is mutable, but the actual objects that it points to are not (ie you could change the pointers in the array, but you cannot change anything in a dereferenced object).

Question 2 is why would this be giving me a "(cast(const(Object)) is not an lvalue)" error when I try to actually set a new source module?

>     void SetSourceMod(int index, ref const(Mod) sourceMod)
>     {
>       assert (m_pSourceMod != null);
>       if (index >= GetSourceModCount () || index < 0) {
>         throw new ExceptionInvalidParam ();
>       }
>       m_pSourceMod[index] = &sourceMod;
>     }
>
>   protected:
>
>     /// An array containing the pointers to each source module required by
>     /// this noise module.
>     const(Mod)*[] m_pSourceMod;

I am typically going to be passing in an object that derives from Mod (this class was named Module in libnoise c++, changed for obvious reasons)

I'm not quite sure I explained clearly enough, so please ask if you need more clarification.

Also if anyone is interested in the port (currently, modules that require no additional modules seem to work fine):
https://bitbucket.org/kniteli/libnoise-d/src

And the original source:
http://libnoise.sourceforge.net/
February 08, 2012
Roderick Gibson:

> So my question is 1) How would I declare an array of pointers to const(Class)? That is, how do I declare an array such that the ARRAY is mutable, but the actual objects that it points to are not (ie you could change the pointers in the array, but you cannot change anything in a dereferenced object).

Currently one way to do it is:

import std.typecons;

class Foo { int x; }

void main() {
    Rebindable!(const(Foo))[] foos;
    foos.length = 5;
    foos[0] = new Foo();
    foos[0] = new Foo(); // OK
    foos[0].x = 5; // Error
}


Bye,
bearophile
February 08, 2012
It seems the problem you've run into is that a class reference cannot be tail-const.

Pointers can be tail-const like this:
const(Data)*
but there is no way currently (there are proposals) to make only the data
and not the reference const.

A workaround is to use Rebindable in std.typecons.

An array of references to const classes becomes:
(Rebindable!const(Class))[]


February 08, 2012
On 2/7/2012 7:58 PM, Daniel Murphy wrote:
> It seems the problem you've run into is that a class reference cannot be
> tail-const.
>
> Pointers can be tail-const like this:
> const(Data)*
> but there is no way currently (there are proposals) to make only the data
> and not the reference const.
>
> A workaround is to use Rebindable in std.typecons.
>
> An array of references to const classes becomes:
> (Rebindable!const(Class))[]
>
>

Thanks, both answers mentioned Rebindable, looks like it may be very useful. I actually did use the const(Class)* solution, which puts the referencing requirement on the caller, but that's not a huge deal.