On 05/27/2013 02:08 PM, Joseph Rushton Wakeling wrote:
> On 05/26/2013 05:59 PM, Ali Çehreli wrote:
>> On 05/26/2013 05:38 AM, Simen Kjaeraas wrote:
>>
>>
>>>      Tuple!(size_t, size_t)[][] data = createData();
>>>      immutable dataImm = assumeUnique(data);
>>>      data = null; // Simply to ensure no mutable references exist.
>>
>> The last line is not needed. assumeUnique already does that. :)
> 
> That's fantastic, thank you both very much.  Does that also work for arbitrary
> data structures (e.g. also associative arrays, complex structs/classes etc.)?
> 
> Related question -- assume that I now want to store that immutable data 
> inside a
> broader storage class, but I want that storage class to be agnostic as to
> whether the data is immutable, const or mutable.

I thought I'd mention the practical solution I eventually came to here, which is
a combination of things learned from this discussion and the subsequent one on
duplicating a multidimensional array.

I first of all had a go at tweaking the templatization of my storage classes, in
line with some of the tricks Ali suggested for the multidimensional duplication
function.  In this case a storage class that had this form (cutting out
extraneous details):

        class SeedSIS(T)
        {
                T[] immune;
                T[] susceptible;
                T[] recover;
                Link!T[][] network;

                this(T[] imm, T[] sus, T[] rec, Link!T[][] net)
                {
                        immune = imm;
                        susceptible = sus;
                        recover = rec;
                        network = net;
                }
        }

... was tweaked to this form:

        class SeedSIS(T, Network : L[][], L)
        {
                T[] immune;
                T[] susceptible;
                T[] recover;
                Network network;

                this(T[] imm, T[] sus, T[] rec, Network net)
                {
                        immune = imm;
                        susceptible = sus;
                        recover = rec;
                        network = net;
                }
        }

... which enabled the network input to be mutable or immutable.  With a bit more
effort, I guess it would be possible to tweak the other inputs to extend that
option to them; it could be useful as a guarantee related to what bits of the
Seed class will change.

However, I found that in practice this reworked design (which involved reworking
lots of templates elsewhere as well) led to slowdown in some crucial bits of the
code.  So, instead I found an alternative solution following Ali's guidance
about using to!()() as a copying device, which was to pass the immutable network
to threads, and then take a mutable local copy via,

        mutableNetwork = to!(Link!T[][])(immutableNetwork);

... which could then be used with the original templates.

Reply via email to