On Tuesday, 27 November 2012 at 14:05:37 UTC, Joseph Rushton Wakeling wrote:
On 11/27/2012 01:16 PM, Joseph Rushton Wakeling wrote:
... so the real issue here seems to be that there's no canonical way (that I can find) to idup an _associative_ array.

I'm using a custom gdup that recursively copies fields and requires no support from nested structs. If a dup is provided by a struct it will be called. No guarantees, but have a look. https://github.com/patefacio/d-help/blob/master/d-help/opmix/mix.d

The following runs:

--------------------------
import std.stdio;
import std.typecons;
import std.conv;
import std.exception;
import opmix.mix;

alias Tuple!(uint, "id") Link;

struct Node
{
  uint id;
  Link[] links;

  void addLink(uint l)
  {
    links ~= Link(l);
  }

  immutable(Node) idup() pure const @property
  {
    auto linkCopy = to!(Link[])(links);
    immutable ilinks = assumeUnique(linkCopy);
    return immutable(Node)(id, ilinks);
  }
}


struct Network
{
  Node[uint] nodes;

  immutable(Network) idup() pure const @property
  {
    auto nodeCopy = nodes.gdup;
    immutable imnodes = assumeUnique(nodeCopy);
    return immutable(Network)(imnodes);
  }

  void add(uint i, uint j)
  {
    if((i in nodes) is null)
      nodes[i] = Node(i);
    if((j in nodes) is null)
      nodes[j] = Node(j);

    nodes[i].addLink(j);
    nodes[j].addLink(i);
  }

  void print()
  {
    foreach(k; nodes.keys)
      {
        write("[", k, "]");
        foreach(l; nodes[k].links)
          write(" ", l.id);
        writeln();
      }
    writeln();
  }
}

unittest {
  auto n1 = Node(1);

  n1.addLink(5);
  n1.addLink(6);
  writeln(n1.links);

  immutable n2 = n1.idup;
  writeln(n2.links);

  Network net1;
  net1.add(1,2);
  immutable Network net2 = net1.idup;
  writeln(net1);
  writeln(net2);
}

Reply via email to