Reference to an object disregarding mutation - what's the trick?

Steve Teale steve.teale at britseyeview.com
Tue May 29 08:02:25 PDT 2007


BCS Wrote:

> Reply to Steve,
> 
> > OK, so I'm in a typical tree situation:
> > 
> > int n = node.parent.nodelist.length;
> > node.parent.nodelist.length = n+1;
> > // p.s. why can't I say node.parent.nodelist.length++ - doesn't
> > work
> > // other fluff with node.parent.nodelist
> > node.parent.nodelist[n] = x;
> > For brevity I want to be able to say:
> > Node[] t = node.parent.nodelist;
> > int n = t.length;
> > t.length = n+1;
> > .....
> > But as soon as I modify t it becomes a separate object.
> > 
> > OK, I can use with, but how do I get the semantics I'd get with a
> > plain old pointer to the object?
> > 
> 
> you may be running into the issue that changing an array length can cause 
> it to reallocate. I'd have to see more implementation to give you more useful 
> information.
> 
> 

OK, here's the full story.

// This is the original, and works
Node node = findnode(a);  // sets findex to found node
if (node == null)
   return false;
Node newnode = clone_node(node);
int n = node.parent.nodelist.length;
node.parent.nodelist.length = n+1;
if (findex == n-1 || findex == -1)
{
   node.parent.nodelist[n] = newnode;
}
else
{
   for (int i = n; i > findex; i--)
      node.parent.nodelist[i] = node.parent.nodelist[i-1];
   node.parent.nodelist[findex] = newnode;
}

// But its a pain to type and read.  What I wanted to do was
// simplify it.  My choices appear to be:

// This works
Node* pnl = &node.parent.nodelist[0];
if (findex == n-1 || findex == -1)
{
   pnl[n] = newnode;
}
else
{
   for (int i = n; i > findex; i--)
      pnl[i] = pnl[i-1];
   pnl[findex] = newnode;
}

OR

// This works
with (node.parent)
{
   int n = nodelist.length;
   nodelist.length = n+1;
   if (findex == n-1 || findex == -1)
   {
      nodelist[n] = newnode;
   }
   else
   {
      for (int i = n; i > findex; i--)
         nodelist[i] = nodelist[i-1];
      nodelist[findex] = newnode;
   }
}

OR

// This won't compile - it compiles with in, out, and lazy
void insertNode(ref Node[] nl, Node nn)
{
   int n = nl.length;
   nl.length = n+1;
   if (findex == n-1 || findex == -1)
   {
      nl[n] = newnode;
   }
   else
   {
      for (int i = n; i > findex; i--)
         nl[i] = nl[i-1];
      nl[findex] = newnode;
   }
}
insertNode(node.parent.nodelist, newnode);

OR

// Aliasing would be nice, but does not work in this context
alias node.parent.nodelist pnl;
int n = pnl.length;
pnl.length = n+1;
if (this.findex == n-1)
{
   pnl[n] = newnode;
}
else
{
   for (int i = n; i > findex; i--)
      pnl[i] = pnl[i-1];
   pnl[findex] = newnode;
}

The version with the Node* is the tightest, but I don't reaaly find any of the approaches satisfying.



More information about the Digitalmars-d mailing list