summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEugen Wissner <belka@caraus.de>2017-07-08 15:51:17 +0200
committerEugen Wissner <belka@caraus.de>2017-07-08 15:51:17 +0200
commit4834b36271f6ab39aa4f0d57f41e1c276ccd9d42 (patch)
tree38b3ac843892c733e11a17a56d3c6560ca6ee253
parent53df12897ba18a461a94d9ebbec2bcdaa6a83c60 (diff)
downloadtanya-4834b36271f6ab39aa4f0d57f41e1c276ccd9d42.tar.gz
Finish DList implementation. Fixes #209
* removeBack * insertAfter * Diverse fixes of insertion logic * Internal moveFront and moveBack functions * Internal makeList function
-rw-r--r--source/tanya/container/list.d73
1 files changed, 48 insertions, 25 deletions
diff --git a/source/tanya/container/list.d b/source/tanya/container/list.d
index 305b557..4800a76 100644
--- a/source/tanya/container/list.d
+++ b/source/tanya/container/list.d
@@ -1307,6 +1307,34 @@ struct DList(T)
return 1;
}
+ // Creates a lsit of linked entries from a range.
+ // Returns count of the elements in the list.
+ private size_t makeList(R)(ref R el, out Entry* head, out Entry* tail) @trusted
+ out (retLength)
+ {
+ assert(retLength == 0 && head is null && tail is null
+ || retLength > 0 && head !is null && tail !is null);
+ }
+ body
+ {
+ size_t retLength;
+
+ if (!el.empty)
+ {
+ head = tail = allocator.make!Entry(el.front);
+ el.popFront();
+ retLength = 1;
+ }
+ foreach (ref e; el)
+ {
+ tail.next = allocator.make!Entry(e);
+ tail.next.prev = tail;
+ tail = tail.next;
+ ++retLength;
+ }
+ return retLength;
+ }
+
/**
* Inserts a new element at the beginning.
*
@@ -1355,39 +1383,25 @@ struct DList(T)
}
/// Ditto.
- size_t insertFront(R)(R el) @trusted
+ size_t insertFront(R)(R el)
if (!isInfinite!R
&& isInputRange!R
&& isImplicitlyConvertible!(ElementType!R, T))
{
- size_t retLength;
- Entry* next, newHead;
+ Entry* begin, end;
+ const inserted = makeList(el, begin, end);
- if (!el.empty)
- {
- next = allocator.make!Entry(el.front);
- newHead = next;
- el.popFront();
- retLength = 1;
- }
- foreach (ref e; el)
- {
- next.next = allocator.make!Entry(e);
- next.next.prev = next;
- next = next.next;
- ++retLength;
- }
if (this.head is null)
{
- this.tail = next;
+ this.tail = end;
}
- if (newHead !is null)
+ if (begin !is null)
{
- next.next = this.head;
- this.head = newHead;
+ end.next = this.head;
+ this.head = begin;
}
- return retLength;
+ return inserted;
}
private @safe @nogc unittest
@@ -1500,11 +1514,20 @@ struct DList(T)
&& isInputRange!R
&& isImplicitlyConvertible!(ElementType!R, T))
{
- size_t inserted;
+ Entry* begin, end;
+ const inserted = makeList(el, begin, end);
- foreach (ref e; el)
+ if (this.tail is null)
+ {
+ this.head = begin;
+ }
+ else
+ {
+ this.tail.next = begin;
+ }
+ if (begin !is null)
{
- inserted += insertBack(e);
+ this.tail = end;
}
return inserted;