diff options
| author | Eugen Wissner <belka@caraus.de> | 2017-07-08 15:51:17 +0200 |
|---|---|---|
| committer | Eugen Wissner <belka@caraus.de> | 2017-07-08 15:51:17 +0200 |
| commit | 4834b36271f6ab39aa4f0d57f41e1c276ccd9d42 (patch) | |
| tree | 38b3ac843892c733e11a17a56d3c6560ca6ee253 | |
| parent | 53df12897ba18a461a94d9ebbec2bcdaa6a83c60 (diff) | |
| download | tanya-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.d | 73 |
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; |
