DList invariant fails.
This commit is contained in:
Eugen Wissner 2017-07-08 05:41:04 +02:00
parent b79657f0d2
commit 4ac890d7d3

View File

@ -1361,6 +1361,7 @@ struct DList(T)
foreach (ref e; el) foreach (ref e; el)
{ {
next.next = allocator.make!Entry(e); next.next = allocator.make!Entry(e);
next.next.prev = next;
next = next.next; next = next.next;
++retLength; ++retLength;
} }
@ -1377,6 +1378,12 @@ struct DList(T)
return retLength; return retLength;
} }
private @safe @nogc unittest
{
auto l1 = DList!int([5, 234]);
assert(l1.head is l1.head.next.prev);
}
/// Ditto. /// Ditto.
size_t insertFront(size_t R)(T[R] el) size_t insertFront(size_t R)(T[R] el)
{ {
@ -1709,7 +1716,7 @@ struct DList(T)
{ {
auto n = this.head.next; auto n = this.head.next;
this.allocator.dispose(this.head); allocator.dispose(this.head);
this.head = n; this.head = n;
if (this.head is null) if (this.head is null)
{ {
@ -1775,7 +1782,7 @@ struct DList(T)
* Params: * Params:
* r = The range to remove. * r = The range to remove.
* *
* Returns: An empty range. * Returns: Range spanning the elements just after $(D_PARAM r).
* *
* Precondition: $(D_PARAM r) is extracted from this list. * Precondition: $(D_PARAM r) is extracted from this list.
*/ */
@ -1786,19 +1793,34 @@ struct DList(T)
} }
body body
{ {
auto outOfScopeList = typeof(this)(allocator); // Save references to the elements before and after the range.
outOfScopeList.head = *r.head; Entry* tailNext, headPrev;
outOfScopeList.tail = r.tail; if (r.tail !is null && r.tail.next !is null)
if (r.tail is null)
{ {
*r.head = null; tailNext = r.tail.next;
} }
else if (*r.head !is null)
{ {
outOfScopeList.tail.next = null; headPrev = (*r.head).prev;
*r.head = r.tail.next;
} }
// Remove the elements.
Entry* e = *r.head;
while (e !is tailNext)
{
auto next = e.next;
allocator.dispose(e);
e = next;
}
// Connect the elements before and after the removed range.
if (tailNext !is null)
{
tailNext.prev = headPrev;
}
*r.head = tailNext;
r.tail = tail;
return r; return r;
} }
@ -1815,6 +1837,22 @@ struct DList(T)
assert(l1 == l2); assert(l1 == l2);
} }
// Issue 260: https://issues.caraus.io/issues/260.
private @safe @nogc unittest
{
auto l1 = DList!int([5, 234, 30, 1]);
auto l2 = DList!int([5, 1]);
auto r = l1[];
r.popFront();
r.popBack();
assert(r.front == 234);
assert(r.back == 30);
assert(!l1.remove(r).empty);
assert(l1 == l2);
}
/** /**
* Returns: Range that iterates over all elements of the container, in * Returns: Range that iterates over all elements of the container, in
* forward order. * forward order.