From d267a9cc645f1219203bd43e046dc07b4a1fc520 Mon Sep 17 00:00:00 2001 From: Eugen Wissner Date: Thu, 12 Apr 2018 19:35:59 +0200 Subject: [PATCH] Implement SList.popFirstOf Fix #36. Slicing for the SList on top of the existing SRange would be inefficent. There would be two cases: - Range iterates till the end of the list. - Range iterates till some element "end". If both cases are implemented in the same range, this range should check for both conditions (end of the list and "begin == end") instead of only one (end of the list). Introducing a different range is undesirable since all containers have currently only one range. --- source/tanya/container/list.d | 44 +++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/source/tanya/container/list.d b/source/tanya/container/list.d index cb3115f..9a5beb7 100644 --- a/source/tanya/container/list.d +++ b/source/tanya/container/list.d @@ -719,6 +719,50 @@ struct SList(T) assert(l1 == l2); } + /** + * Removes the fron element of the $(D_PARAM range) from the list. + * + * Params: + * range = Range whose front element should be removed. + * + * Returns: $(D_PSYMBOL range) with the first element removed. + * + * Precondition: $(D_INLINECODE !range.empty). + * $(D_PARAM range) is extracted from this list. + */ + Range popFirstOf(Range range) + in + { + assert(!range.empty); + assert(checkRangeBelonging(range)); + } + do + { + auto next = (*range.head).next; + + allocator.dispose(*range.head); + *range.head = next; + + return range; + } + + /// + @nogc nothrow pure @safe unittest + { + auto list = SList!int([5, 234, 30]); + auto range = list[]; + + range.popFront(); + assert(list.popFirstOf(range).front == 30); + + range = list[]; + assert(range.front == 5); + range.popFront; + assert(range.front == 30); + range.popFront; + assert(range.empty); + } + /** * Returns: Range that iterates over all elements of the container, in * forward order.