Add length and opCmp to the Queue
This commit is contained in:
@ -6,32 +6,22 @@
|
||||
* Copyright: Eugene Wissner 2016.
|
||||
* License: $(LINK2 https://www.mozilla.org/en-US/MPL/2.0/,
|
||||
* Mozilla Public License, v. 2.0).
|
||||
* Authors: $(LINK2 mailto:belka@caraus.de, Eugene Wissner)
|
||||
* Authors: $(LINK2 mailto:info@caraus.de, Eugene Wissner)
|
||||
*/
|
||||
module tanya.container.queue;
|
||||
|
||||
import tanya.container.entry;
|
||||
import std.traits;
|
||||
import tanya.memory;
|
||||
|
||||
/**
|
||||
* Queue.
|
||||
* FIFO queue.
|
||||
*
|
||||
* Params:
|
||||
* T = Content type.
|
||||
*/
|
||||
struct Queue(T)
|
||||
{
|
||||
/**
|
||||
* Creates a new $(D_PSYMBOL Queue).
|
||||
*
|
||||
* Params:
|
||||
* allocator = The allocator should be used for the element
|
||||
* allocations.
|
||||
*/
|
||||
this(shared Allocator allocator)
|
||||
{
|
||||
this.allocator = allocator;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes all elements from the queue.
|
||||
*/
|
||||
@ -54,15 +44,147 @@ struct Queue(T)
|
||||
///
|
||||
unittest
|
||||
{
|
||||
auto q = defaultAllocator.make!(Queue!int);
|
||||
Queue!int q;
|
||||
|
||||
assert(q.empty);
|
||||
q.insertBack(8);
|
||||
q.insertBack(9);
|
||||
q.clear();
|
||||
assert(q.empty);
|
||||
}
|
||||
|
||||
defaultAllocator.dispose(q);
|
||||
/**
|
||||
* Returns how many elements are in the queue. It iterates through the queue
|
||||
* to count the elements.
|
||||
*
|
||||
* Returns: How many elements are in the queue.
|
||||
*/
|
||||
size_t length() const
|
||||
{
|
||||
size_t len;
|
||||
for (const(Entry!T)* i = first.next; i !is null; i = i.next)
|
||||
{
|
||||
++len;
|
||||
}
|
||||
return len;
|
||||
}
|
||||
|
||||
///
|
||||
unittest
|
||||
{
|
||||
Queue!int q;
|
||||
|
||||
assert(q.length == 0);
|
||||
q.insertBack(5);
|
||||
assert(q.length == 1);
|
||||
q.insertBack(4);
|
||||
assert(q.length == 2);
|
||||
q.insertBack(9);
|
||||
assert(q.length == 3);
|
||||
|
||||
q.popFront();
|
||||
assert(q.length == 2);
|
||||
q.popFront();
|
||||
assert(q.length == 1);
|
||||
q.popFront();
|
||||
assert(q.length == 0);
|
||||
}
|
||||
|
||||
version (D_Ddoc)
|
||||
{
|
||||
/**
|
||||
* Compares two queues. Checks if all elements of the both queues are equal.
|
||||
*
|
||||
* Returns: Whether $(D_KEYWORD this) and $(D_PARAM that) are equal.
|
||||
*/
|
||||
int opEquals(ref typeof(this) that);
|
||||
|
||||
/// Ditto.
|
||||
int opEquals(typeof(this) that);
|
||||
}
|
||||
else static if (!hasMember!(T, "opEquals")
|
||||
|| (functionAttributes!(T.opEquals) & FunctionAttribute.const_))
|
||||
{
|
||||
bool opEquals(in ref typeof(this) that) const
|
||||
{
|
||||
const(Entry!T)* i = first.next;
|
||||
const(Entry!T)* j = that.first.next;
|
||||
while (i !is null && j !is null)
|
||||
{
|
||||
if (i.content != j.content)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
i = i.next;
|
||||
j = j.next;
|
||||
}
|
||||
return i is null && j is null;
|
||||
}
|
||||
|
||||
/// Ditto.
|
||||
bool opEquals(in typeof(this) that) const
|
||||
{
|
||||
return opEquals(that);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/**
|
||||
* Compares two queues. Checks if all elements of the both queues are equal.
|
||||
*
|
||||
* Returns: How many elements are in the queue.
|
||||
*/
|
||||
bool opEquals(ref typeof(this) that)
|
||||
{
|
||||
Entry!T* i = first.next;
|
||||
Entry!T* j = that.first.next;
|
||||
while (i !is null && j !is null)
|
||||
{
|
||||
if (i.content != j.content)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
i = i.next;
|
||||
j = j.next;
|
||||
}
|
||||
return i is null && j is null;
|
||||
}
|
||||
|
||||
/// Ditto.
|
||||
bool opEquals(typeof(this) that)
|
||||
{
|
||||
return opEquals(that);
|
||||
}
|
||||
}
|
||||
|
||||
///
|
||||
unittest
|
||||
{
|
||||
Queue!int q1, q2;
|
||||
|
||||
q1.insertBack(5);
|
||||
q1.insertBack(4);
|
||||
q2.insertBack(5);
|
||||
assert(q1 != q2);
|
||||
q2.insertBack(4);
|
||||
assert(q1 == q2);
|
||||
|
||||
q2.popFront();
|
||||
assert(q1 != q2);
|
||||
|
||||
q1.popFront();
|
||||
assert(q1 == q2);
|
||||
|
||||
q1.popFront();
|
||||
q2.popFront();
|
||||
assert(q1 == q2);
|
||||
}
|
||||
|
||||
private unittest
|
||||
{
|
||||
static assert(is(Queue!ConstEqualsStruct));
|
||||
static assert(is(Queue!MutableEqualsStruct));
|
||||
static assert(is(Queue!NoEqualsStruct));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -84,13 +206,9 @@ struct Queue(T)
|
||||
* Params:
|
||||
* x = New element.
|
||||
*/
|
||||
void insertBack(T x)
|
||||
void insertBack(ref T x)
|
||||
{
|
||||
if (allocator is null)
|
||||
{
|
||||
allocator = defaultAllocator;
|
||||
}
|
||||
Entry* temp = make!Entry(allocator);
|
||||
auto temp = allocator.make!(Entry!T);
|
||||
|
||||
temp.content = x;
|
||||
|
||||
@ -105,27 +223,31 @@ struct Queue(T)
|
||||
}
|
||||
}
|
||||
|
||||
/// Ditto.
|
||||
void insertBack(T x)
|
||||
{
|
||||
insertBack(x);
|
||||
}
|
||||
|
||||
/// Ditto.
|
||||
alias insert = insertBack;
|
||||
|
||||
///
|
||||
unittest
|
||||
{
|
||||
auto q = make!(Queue!int)(defaultAllocator);
|
||||
Queue!int q;
|
||||
|
||||
assert(q.empty);
|
||||
q.insertBack(8);
|
||||
assert(q.front == 8);
|
||||
q.insertBack(9);
|
||||
assert(q.front == 8);
|
||||
|
||||
dispose(defaultAllocator, q);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns: $(D_KEYWORD true) if the queue is empty.
|
||||
*/
|
||||
@property bool empty() inout const pure nothrow @safe
|
||||
@property bool empty() const
|
||||
{
|
||||
return first.next is null;
|
||||
}
|
||||
@ -133,14 +255,12 @@ struct Queue(T)
|
||||
///
|
||||
unittest
|
||||
{
|
||||
auto q = make!(Queue!int)(defaultAllocator);
|
||||
Queue!int q;
|
||||
int value = 7;
|
||||
|
||||
assert(q.empty);
|
||||
q.insertBack(value);
|
||||
assert(!q.empty);
|
||||
|
||||
dispose(defaultAllocator, q);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -163,15 +283,13 @@ struct Queue(T)
|
||||
///
|
||||
unittest
|
||||
{
|
||||
auto q = make!(Queue!int)(defaultAllocator);
|
||||
Queue!int q;
|
||||
|
||||
q.insertBack(8);
|
||||
q.insertBack(9);
|
||||
assert(q.front == 8);
|
||||
q.popFront();
|
||||
assert(q.front == 9);
|
||||
|
||||
dispose(defaultAllocator, q);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -215,7 +333,7 @@ struct Queue(T)
|
||||
///
|
||||
unittest
|
||||
{
|
||||
auto q = Queue!int(defaultAllocator);
|
||||
Queue!int q;
|
||||
|
||||
size_t j;
|
||||
q.insertBack(5);
|
||||
@ -246,32 +364,19 @@ struct Queue(T)
|
||||
assert(q.empty);
|
||||
}
|
||||
|
||||
/**
|
||||
* Queue entry.
|
||||
*/
|
||||
protected struct Entry
|
||||
{
|
||||
/// Queue item content.
|
||||
T content;
|
||||
|
||||
/// Next list item.
|
||||
Entry* next;
|
||||
}
|
||||
|
||||
/// The first element of the list.
|
||||
protected Entry first;
|
||||
private Entry!T first;
|
||||
|
||||
/// The last element of the list.
|
||||
protected Entry* rear;
|
||||
private Entry!T* rear;
|
||||
|
||||
/// The allocator.
|
||||
protected shared Allocator allocator;
|
||||
mixin DefaultAllocator;
|
||||
}
|
||||
|
||||
///
|
||||
unittest
|
||||
{
|
||||
auto q = Queue!int(defaultAllocator);
|
||||
Queue!int q;
|
||||
|
||||
q.insertBack(5);
|
||||
assert(!q.empty);
|
||||
|
Reference in New Issue
Block a user