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.
This commit is contained in:
Eugen Wissner 2018-04-12 19:35:59 +02:00
parent ddb02e41eb
commit d267a9cc64
1 changed files with 44 additions and 0 deletions

View File

@ -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.