Implement opApply for the Queue
This commit is contained in:
parent
c53d319337
commit
1123d01e6c
@ -111,7 +111,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
|
@property bool empty() inout const
|
||||||
{
|
{
|
||||||
return first.next is null;
|
return first.next is null;
|
||||||
}
|
}
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
* Copyright: Eugene Wissner 2016.
|
* Copyright: Eugene Wissner 2016.
|
||||||
* License: $(LINK2 https://www.mozilla.org/en-US/MPL/2.0/,
|
* License: $(LINK2 https://www.mozilla.org/en-US/MPL/2.0/,
|
||||||
* Mozilla Public License, v. 2.0).
|
* Mozilla Public License, v. 2.0).
|
||||||
* Authors: $(LINK2 mailto:info@caraus.de, Eugene Wissner)
|
* Authors: $(LINK2 mailto:belka@caraus.de, Eugene Wissner)
|
||||||
*/
|
*/
|
||||||
module tanya.container.queue;
|
module tanya.container.queue;
|
||||||
|
|
||||||
@ -37,19 +37,38 @@ class Queue(T)
|
|||||||
*/
|
*/
|
||||||
~this()
|
~this()
|
||||||
{
|
{
|
||||||
foreach (e; this)
|
clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes all elements from the queue.
|
||||||
|
*/
|
||||||
|
void clear()
|
||||||
|
{
|
||||||
|
while (!empty)
|
||||||
{
|
{
|
||||||
static if (isFinalizable!T)
|
popFront();
|
||||||
{
|
|
||||||
dispose(allocator, e);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
unittest
|
||||||
|
{
|
||||||
|
auto q = theAllocator.make!(Queue!int);
|
||||||
|
|
||||||
|
assert(q.empty);
|
||||||
|
q.insertBack(8);
|
||||||
|
q.insertBack(9);
|
||||||
|
q.clear();
|
||||||
|
assert(q.empty);
|
||||||
|
|
||||||
|
theAllocator.dispose(q);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns: First element.
|
* Returns: First element.
|
||||||
*/
|
*/
|
||||||
@property ref T front()
|
@property ref inout(T) front() inout
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
assert(!empty);
|
assert(!empty);
|
||||||
@ -64,10 +83,8 @@ class Queue(T)
|
|||||||
*
|
*
|
||||||
* Params:
|
* Params:
|
||||||
* x = New element.
|
* x = New element.
|
||||||
*
|
|
||||||
* Returns: $(D_KEYWORD this).
|
|
||||||
*/
|
*/
|
||||||
typeof(this) insertBack(T x)
|
void insertBack(T x)
|
||||||
{
|
{
|
||||||
Entry* temp = make!Entry(allocator);
|
Entry* temp = make!Entry(allocator);
|
||||||
|
|
||||||
@ -82,52 +99,21 @@ class Queue(T)
|
|||||||
rear.next = temp;
|
rear.next = temp;
|
||||||
rear = rear.next;
|
rear = rear.next;
|
||||||
}
|
}
|
||||||
|
|
||||||
return this;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Ditto.
|
||||||
alias insert = insertBack;
|
alias insert = insertBack;
|
||||||
|
|
||||||
///
|
///
|
||||||
unittest
|
unittest
|
||||||
{
|
{
|
||||||
auto q = make!(Queue!int)(theAllocator);
|
auto q = make!(Queue!int)(theAllocator);
|
||||||
int[2] values = [8, 9];
|
|
||||||
|
|
||||||
q.insertBack(values[0]);
|
|
||||||
assert(q.front is values[0]);
|
|
||||||
q.insertBack(values[1]);
|
|
||||||
assert(q.front is values[0]);
|
|
||||||
|
|
||||||
dispose(theAllocator, q);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Inserts a new element.
|
|
||||||
*
|
|
||||||
* Params:
|
|
||||||
* x = New element.
|
|
||||||
*
|
|
||||||
* Returns: $(D_KEYWORD this).
|
|
||||||
*/
|
|
||||||
typeof(this) opOpAssign(string Op)(ref T x)
|
|
||||||
if (Op == "~")
|
|
||||||
{
|
|
||||||
return insertBack(x);
|
|
||||||
}
|
|
||||||
|
|
||||||
///
|
|
||||||
unittest
|
|
||||||
{
|
|
||||||
auto q = make!(Queue!int)(theAllocator);
|
|
||||||
int value = 5;
|
|
||||||
|
|
||||||
assert(q.empty);
|
assert(q.empty);
|
||||||
|
q.insertBack(8);
|
||||||
q ~= value;
|
assert(q.front == 8);
|
||||||
|
q.insertBack(9);
|
||||||
assert(q.front == value);
|
assert(q.front == 8);
|
||||||
assert(!q.empty);
|
|
||||||
|
|
||||||
dispose(theAllocator, q);
|
dispose(theAllocator, q);
|
||||||
}
|
}
|
||||||
@ -135,7 +121,7 @@ class Queue(T)
|
|||||||
/**
|
/**
|
||||||
* Returns: $(D_KEYWORD true) if the queue is empty.
|
* Returns: $(D_KEYWORD true) if the queue is empty.
|
||||||
*/
|
*/
|
||||||
@property bool empty() const @safe pure nothrow
|
@property bool empty() inout const
|
||||||
{
|
{
|
||||||
return first.next is null;
|
return first.next is null;
|
||||||
}
|
}
|
||||||
@ -154,11 +140,9 @@ class Queue(T)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Move position to the next element.
|
* Move the position to the next element.
|
||||||
*
|
|
||||||
* Returns: $(D_KEYWORD this).
|
|
||||||
*/
|
*/
|
||||||
typeof(this) popFront()
|
void popFront()
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
assert(!empty);
|
assert(!empty);
|
||||||
@ -169,21 +153,91 @@ class Queue(T)
|
|||||||
|
|
||||||
dispose(allocator, first.next);
|
dispose(allocator, first.next);
|
||||||
first.next = n;
|
first.next = n;
|
||||||
|
|
||||||
return this;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
unittest
|
unittest
|
||||||
{
|
{
|
||||||
auto q = make!(Queue!int)(theAllocator);
|
auto q = make!(Queue!int)(theAllocator);
|
||||||
int[2] values = [8, 9];
|
|
||||||
|
|
||||||
q.insertBack(values[0]);
|
q.insertBack(8);
|
||||||
q.insertBack(values[1]);
|
q.insertBack(9);
|
||||||
assert(q.front is values[0]);
|
assert(q.front == 8);
|
||||||
q.popFront();
|
q.popFront();
|
||||||
assert(q.front is values[1]);
|
assert(q.front == 9);
|
||||||
|
|
||||||
|
dispose(theAllocator, q);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* $(D_KEYWORD foreach) iteration.
|
||||||
|
*
|
||||||
|
* Params:
|
||||||
|
* dg = $(D_KEYWORD foreach) body.
|
||||||
|
*/
|
||||||
|
int opApply(scope int delegate(ref size_t i, ref T) dg)
|
||||||
|
{
|
||||||
|
int result;
|
||||||
|
|
||||||
|
for (size_t i = 0; !empty; ++i)
|
||||||
|
{
|
||||||
|
if ((result = dg(i, front)) != 0)
|
||||||
|
{
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
popFront();
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Ditto.
|
||||||
|
int opApply(scope int delegate(ref T) dg)
|
||||||
|
{
|
||||||
|
int result;
|
||||||
|
|
||||||
|
while (!empty)
|
||||||
|
{
|
||||||
|
if ((result = dg(front)) != 0)
|
||||||
|
{
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
popFront();
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
unittest
|
||||||
|
{
|
||||||
|
auto q = theAllocator.make!(Queue!int);
|
||||||
|
|
||||||
|
size_t j;
|
||||||
|
q.insertBack(5);
|
||||||
|
q.insertBack(4);
|
||||||
|
q.insertBack(9);
|
||||||
|
foreach (i, e; q)
|
||||||
|
{
|
||||||
|
assert(i != 2 || e == 9);
|
||||||
|
assert(i != 1 || e == 4);
|
||||||
|
assert(i != 0 || e == 5);
|
||||||
|
++j;
|
||||||
|
}
|
||||||
|
assert(j == 3);
|
||||||
|
assert(q.empty);
|
||||||
|
|
||||||
|
j = 0;
|
||||||
|
q.insertBack(5);
|
||||||
|
q.insertBack(4);
|
||||||
|
q.insertBack(9);
|
||||||
|
foreach (e; q)
|
||||||
|
{
|
||||||
|
assert(j != 2 || e == 9);
|
||||||
|
assert(j != 1 || e == 4);
|
||||||
|
assert(j != 0 || e == 5);
|
||||||
|
++j;
|
||||||
|
}
|
||||||
|
assert(j == 3);
|
||||||
|
assert(q.empty);
|
||||||
|
|
||||||
dispose(theAllocator, q);
|
dispose(theAllocator, q);
|
||||||
}
|
}
|
||||||
@ -206,13 +260,33 @@ class Queue(T)
|
|||||||
/// The last element of the list.
|
/// The last element of the list.
|
||||||
protected Entry* rear;
|
protected Entry* rear;
|
||||||
|
|
||||||
private IAllocator allocator;
|
/// The allocator.
|
||||||
|
protected IAllocator allocator;
|
||||||
}
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
unittest
|
unittest
|
||||||
{
|
{
|
||||||
auto q = make!(Queue!int)(theAllocator);
|
auto q = theAllocator.make!(Queue!int);
|
||||||
|
|
||||||
dispose(theAllocator, q);
|
q.insertBack(5);
|
||||||
|
assert(!q.empty);
|
||||||
|
|
||||||
|
q.insertBack(4);
|
||||||
|
assert(q.front == 5);
|
||||||
|
|
||||||
|
q.insertBack(9);
|
||||||
|
assert(q.front == 5);
|
||||||
|
|
||||||
|
q.popFront();
|
||||||
|
assert(q.front == 4);
|
||||||
|
|
||||||
|
foreach (i, ref e; q)
|
||||||
|
{
|
||||||
|
assert(i != 0 || e == 4);
|
||||||
|
assert(i != 1 || e == 9);
|
||||||
|
}
|
||||||
|
assert(q.empty);
|
||||||
|
|
||||||
|
theAllocator.dispose(q);
|
||||||
}
|
}
|
||||||
|
@ -55,12 +55,12 @@ class Vector(T)
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@property bool empty() const
|
@property bool empty() inout const
|
||||||
{
|
{
|
||||||
return start >= end;
|
return start >= end;
|
||||||
}
|
}
|
||||||
|
|
||||||
@property size_t length() const
|
@property size_t length() inout const
|
||||||
{
|
{
|
||||||
return end - start;
|
return end - start;
|
||||||
}
|
}
|
||||||
@ -261,13 +261,13 @@ class Vector(T)
|
|||||||
/**
|
/**
|
||||||
* Returns: Vector length.
|
* Returns: Vector length.
|
||||||
*/
|
*/
|
||||||
@property size_t length() const
|
@property size_t length() inout const
|
||||||
{
|
{
|
||||||
return vector.length;
|
return vector.length;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Ditto.
|
/// Ditto.
|
||||||
size_t opDollar() const
|
size_t opDollar() inout const
|
||||||
{
|
{
|
||||||
return length;
|
return length;
|
||||||
}
|
}
|
||||||
@ -301,7 +301,7 @@ class Vector(T)
|
|||||||
/**
|
/**
|
||||||
* Returns: $(D_KEYWORD true) if the vector is empty.
|
* Returns: $(D_KEYWORD true) if the vector is empty.
|
||||||
*/
|
*/
|
||||||
@property bool empty() const
|
@property bool empty() inout const
|
||||||
{
|
{
|
||||||
return vector.length == 0;
|
return vector.length == 0;
|
||||||
}
|
}
|
||||||
@ -776,4 +776,6 @@ unittest
|
|||||||
assert(v.front == 5);
|
assert(v.front == 5);
|
||||||
assert(v[1] == 15);
|
assert(v[1] == 15);
|
||||||
assert(v.back == 8);
|
assert(v.back == 8);
|
||||||
|
|
||||||
|
theAllocator.dispose(v);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user