Implement opApply for the Queue
This commit is contained in:
		@@ -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);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user