BIg semantic issues with SList & DList

monarch_dodra monarchdodra at gmail.com
Thu Sep 13 12:42:24 PDT 2012


On Thursday, 13 September 2012 at 19:37:41 UTC, monarch_dodra 
wrote:
> On Wednesday, 12 September 2012 at 17:24:57 UTC, monarch_dodra
> wrote:
>> [SNIP]
> [SNIP]

I'll just copy paste here the 3 headers which contain examples, 
to give a quicker idea of what I went for:

111 CHAIN IMPLEMENTATION 111
/**
    Implements a doubly-linked list.

    $(D DList) uses neither reference nor value semantics. They 
can be seen as
    several different handles into an external chain of nodes. 
Several different
    $(D DList)s can all reference different points in a same chain.

    $(D DList.Range) is, for all intents and purposes, a DList 
with range
    semantics. The $(D DList.Range) has a view directly into the 
chain itself.
    It is not tied to its parent $(D DList), and may be used to 
operate on
    other lists (that point to the same chain).

    The ONLY operation that can invalidate a $(D DList) or $(D 
DList.Range), but
    which will invalidate BOTH, is the $(D remove) operation, if 
the cut Range
    overlaps with the boundaries of another DList or DList.Range.

    Example:
----
auto a = DList!int([3, 4]); //Create a new chain
auto b = a; //Point to the same chain
// (3 - 4)
assert(a[].equal([3, 4]));
assert(b[].equal([3, 4]));

b.stableInsertFront(1); //insert before of b
b.stableInsertBack(5);  //insert after of b
// (2 - (3 - 4) - 5)
assert(a[].equal([3, 4])); //a is not changed
assert(b[].equal([1, 3, 4, 5])); // but a is

a.stableInsertFront(2); //insert in front of a, this will insert 
"inside" the chain
// (1 - (2 - 3 - 4) - 5)
assert(a[].equal([2, 3, 4])); //a is modified
assert(b[].equal([1, 2, 3, 4, 5])); //and so is b;

a.remove(a[]); //remove all the elements of a;
// (1 - 5)
assert(a[].empty); //a is empty
assert(b[].equal([1, 5])); //b has lost some of its elements;

a.insert(2); //insert in a. This will create a new chain
// (2)
// (1 - 5)
assert(a[].equal([2])); //a is empty
assert(b[].equal([1, 5])); //b has lost some of its elements;
----
  */

222 HYBRID REFERENCE IMPLEMENATION 222
/**
    Implements a doubly-linked list.

    $(D DList) use reference semantics. They give a view into a 
bidirectional
    chain of nodes.

    $(D DList.Range) can be used to have $(D BidirectionalRange) 
view of the
    chain of nodes. $(D DList.Ranges) are almost never 
invalidated, but they
    may have access to nodes that are past the end of original $(D 
DList)'s,
    if that $(D DList) was shortened.

    Example:
----
auto a = DList!int([1, 2, 3]); //Create a new DList
auto b = a; //A reference to that DList
auto r = a[]; //A range view of the list

a.removeFront();
a.removeBack();
assert(a[].equal([2])); // both a and b have been affected
assert(b[].equal([2])); // both a and b have been affected
assert(r.equal([1, 2, 3])); //But the range remains unchanged

a.insertFront(1);
assert(a[].equal([1, 2])); // both a and b have been affected
assert(b[].equal([1, 2])); // both a and b have been affected
assert(r.equal([1, 1, 2, 3])); //But so has the range

auto c = a; //Create a third reference
a.clear();  //Detaches from the chain
assert(a[].empty); //a is now empty
assert(b[].equal([1, 2])); //But a and b are unchanged
assert(c[].equal([1, 2])); //But a and b are unchanged
assert(r.equal([1, 1, 2, 3]));

b.remove(b[]); //Do a hard removal of the actual elements
assert(b[].empty); //b is empty of course
assert(c[].empty); //but so is c
assert(r.equal([1, 3])); //and the range has lost an element: It 
was removed from the chain

b.insert(1); //Insert an element into b
assert(a[].empty); //a remains unchanged
assert(b[].equal([1])); //b has the new element
assert(c[].equal([1])); //and so does c
assert(r.equal([1, 3])); //r points to the old chain, so does not 
see this new element
----
  */

333 CLASSIC IMPLEMENTATION 333
/**
    Implements a doubly-linked list.

    $(D DList) use reference semantics.

    $(D DList.Range) may be used to have a $(D BidirectionalRange) 
view into
    the DList.

    Example:
----
auto a = DList!int([1, 2, 3]); //Create a new DList
auto b = a; //A reference to that DList

a.removeFront();
a.removeBack();
assert(a[].equal([2])); // both a and b have been affected
assert(b[].equal([2])); // both a and b have been affected

a.insertFront(1);
assert(a[].equal([1, 2])); // both a and b have been affected
assert(b[].equal([1, 2])); // both a and b have been affected

auto c = a; //Create a third reference
a.clear();  //Detaches from the chain
assert(a[].empty); //a is now empty
assert(b[].equal([1, 2])); //But a and b are unchanged
assert(c[].equal([1, 2])); //But a and b are unchanged

b.remove(b[]); //Do a hard removal of the actual elements
assert(b[].empty); //b is empty of course
assert(c[].empty); //but so is c

b.insert(1); //Insert an element into b
assert(a[].empty); //a remains unchanged
assert(b[].equal([1])); //b has the new element
assert(c[].equal([1])); //and so does c
----
  */
/*
There is not much to show here actually: Ranges are *immediatly* 
invalidated, and attempt to use an invalid range will assert 
pretty quickly.
  */


More information about the Digitalmars-d mailing list