Make opApply delegate scoped for SList

This commit is contained in:
Eugen Wissner 2016-12-01 20:03:21 +01:00
parent edd3ec4b32
commit a4aa5bcb2e
1 changed files with 56 additions and 124 deletions

View File

@ -30,28 +30,45 @@ class SList(T)
this(IAllocator allocator = theAllocator) this(IAllocator allocator = theAllocator)
{ {
this.allocator = allocator; this.allocator = allocator;
reset();
} }
/** /**
* Removes all elements from the list. * Removes all elements from the list.
*/ */
~this() ~this()
{
clear();
}
/**
* Remove all contents from the $(D_PSYMBOL SList).
*/
void clear()
{ {
while (!empty) while (!empty)
{ {
static if (isFinalizable!T)
{
dispose(allocator, front);
}
popFront(); popFront();
} }
} }
///
unittest
{
auto l = make!(SList!int)(theAllocator);
int[2] values = [8, 5];
l.front = values[0];
l.front = values[1];
l.clear();
assert(l.empty);
dispose(theAllocator, l);
}
/** /**
* Returns: First element. * Returns: First element.
*/ */
@property ref T front() @property ref inout(T) front() inout
in in
{ {
assert(!empty); assert(!empty);
@ -124,7 +141,7 @@ class SList(T)
/** /**
* Returns: $(D_KEYWORD true) if the list is empty. * Returns: $(D_KEYWORD true) if the list is empty.
*/ */
@property bool empty() const @safe pure nothrow @property bool empty() const
{ {
return first.next is null; return first.next is null;
} }
@ -166,28 +183,29 @@ class SList(T)
} }
/** /**
* Returns the current item from the list and removes from the list. * Removes $(D_PARAM howMany) elements from the list.
*
* Unlike $(D_PSYMBOL popFront()), this method doesn't fail, if it could not
* remove $(D_PARAM howMany) elements. Instead, if $(D_PARAM howMany) is
* greater than the list length, all elements are removed.
* *
* Params: * Params:
* x = The item should be removed. * howMany = How many elements should be removed.
* *
* Returns: Removed item. * Returns: The number of elements removed.
*/ */
T remove() size_t removeFront(in size_t howMany = 1)
in
{ {
assert(!empty); size_t i;
for (; i < howMany && !empty; ++i)
{
popFront();
}
return i;
} }
body
{
auto temp = position.next.next;
auto content = position.next.content;
dispose(allocator, position.next); /// Ditto.
position.next = temp; alias remove = removeFront;
return content;
}
/// ///
unittest unittest
@ -197,39 +215,11 @@ class SList(T)
l.front = values[0]; l.front = values[0];
l.front = values[1]; l.front = values[1];
assert(l.remove() == 5);
l.front = values[2]; l.front = values[2];
assert(l.remove() == 4); assert(l.removeFront(0) == 0);
assert(l.remove() == 8); assert(l.removeFront(2) == 2);
assert(l.empty); assert(l.removeFront(3) == 1);
assert(l.removeFront(3) == 0);
dispose(theAllocator, l);
}
/**
* Resets the current position.
*
* Returns: $(D_KEYWORD this).
*/
typeof(this) reset()
{
position = &first;
return this;
}
///
unittest
{
auto l = make!(SList!int)(theAllocator);
int[2] values = [8, 5];
l.current = values[0];
l.current = values[1];
assert(l.current == 5);
l.advance();
assert(l.current == 8);
l.reset();
assert(l.current == 5);
dispose(theAllocator, l); dispose(theAllocator, l);
} }
@ -240,22 +230,20 @@ class SList(T)
* Params: * Params:
* dg = $(D_KEYWORD foreach) body. * dg = $(D_KEYWORD foreach) body.
*/ */
int opApply(int delegate(ref size_t i, ref T) dg) int opApply(scope int delegate(ref size_t i, ref T) dg)
{ {
int result; int result;
size_t i; size_t i;
for (position = first.next; position; position = position.next, ++i) for (auto pos = first.next; pos; pos = pos.next, ++i)
{ {
result = dg(i, position.content); result = dg(i, pos.content);
if (result != 0) if (result != 0)
{ {
return result; return result;
} }
} }
reset();
return result; return result;
} }
@ -279,21 +267,19 @@ class SList(T)
} }
/// Ditto. /// Ditto.
int opApply(int delegate(ref T) dg) int opApply(scope int delegate(ref T) dg)
{ {
int result; int result;
for (position = first.next; position; position = position.next) for (auto pos = first.next; pos; pos = pos.next)
{ {
result = dg(position.content); result = dg(pos.content);
if (result != 0) if (result != 0)
{ {
return result; return result;
} }
} }
reset();
return result; return result;
} }
@ -318,58 +304,6 @@ class SList(T)
dispose(theAllocator, l); dispose(theAllocator, l);
} }
/**
* Returns: $(D_KEYWORD true) if the current position is the end position.
*/
@property bool end() const
{
return empty || position.next.next is null;
}
/**
* Moves to the next element and returns it.
*
* Returns: The element on the next position.
*/
T advance()
in
{
assert(!end);
}
body
{
position = position.next;
return position.content;
}
/**
* Returns: Element on the current position.
*/
@property ref T current()
in
{
assert(!empty);
}
body
{
return position.next.content;
}
/**
* Inserts a new element at the current position.
*
* Params:
* x = New element.
*/
@property void current(T x)
{
Entry* temp = make!Entry(allocator);
temp.content = x;
temp.next = position.next;
position.next = temp;
}
/** /**
* List entry. * List entry.
*/ */
@ -385,19 +319,17 @@ class SList(T)
/// 0th element of the list. /// 0th element of the list.
protected Entry first; protected Entry first;
/// Current position in the list. /// Allocator.
protected Entry* position; protected IAllocator allocator;
private IAllocator allocator;
}
interface Stuff
{
} }
/// ///
unittest unittest
{ {
interface Stuff
{
}
auto l = make!(SList!Stuff)(theAllocator); auto l = make!(SList!Stuff)(theAllocator);
dispose(theAllocator, l); dispose(theAllocator, l);