summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source/tanya/container/entry.d45
-rw-r--r--source/tanya/container/list.d83
-rw-r--r--source/tanya/container/package.d1
-rw-r--r--source/tanya/container/queue.d205
-rw-r--r--source/tanya/crypto/bit.d (renamed from source/tanya/container/bit.d)2
-rw-r--r--source/tanya/crypto/des.d2
-rw-r--r--source/tanya/crypto/package.d10
-rw-r--r--source/tanya/memory/allocator.d21
8 files changed, 248 insertions, 121 deletions
diff --git a/source/tanya/container/entry.d b/source/tanya/container/entry.d
new file mode 100644
index 0000000..ce267a0
--- /dev/null
+++ b/source/tanya/container/entry.d
@@ -0,0 +1,45 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+/*
+ * Internal package used by containers that rely on entries/nodes.
+ *
+ * Copyright: Eugene Wissner 2016.
+ * License: $(LINK2 https://www.mozilla.org/en-US/MPL/2.0/,
+ * Mozilla Public License, v. 2.0).
+ * Authors: $(LINK2 mailto:info@caraus.de, Eugene Wissner)
+ */
+module tanya.container.entry;
+
+version (unittest)
+{
+ package struct ConstEqualsStruct
+ {
+ int opEquals(typeof(this) that) const
+ {
+ return true;
+ }
+ }
+
+ package struct MutableEqualsStruct
+ {
+ int opEquals(typeof(this) that)
+ {
+ return true;
+ }
+ }
+
+ package struct NoEqualsStruct
+ {
+ }
+}
+
+package struct Entry(T)
+{
+ /// Item content.
+ T content;
+
+ /// Next item.
+ Entry* next;
+}
diff --git a/source/tanya/container/list.d b/source/tanya/container/list.d
index 0ce7e4f..d0691ee 100644
--- a/source/tanya/container/list.d
+++ b/source/tanya/container/list.d
@@ -10,29 +10,18 @@
*/
module tanya.container.list;
+import tanya.container.entry;
import tanya.memory;
/**
- * Singly linked list.
+ * Singly-linked list.
*
* Params:
* T = Content type.
*/
-class SList(T)
+struct SList(T)
{
/**
- * Creates a new $(D_PSYMBOL SList).
- *
- * Params:
- * allocator = The allocator should be used for the element
- * allocations.
- */
- this(shared Allocator allocator = defaultAllocator)
- {
- this.allocator = allocator;
- }
-
- /**
* Removes all elements from the list.
*/
~this()
@@ -41,7 +30,7 @@ class SList(T)
}
/**
- * Remove all contents from the $(D_PSYMBOL SList).
+ * Removes all contents from the list.
*/
void clear()
{
@@ -54,14 +43,12 @@ class SList(T)
///
unittest
{
- auto l = make!(SList!int)(defaultAllocator);
+ SList!int l;
l.insertFront(8);
l.insertFront(5);
l.clear();
assert(l.empty);
-
- dispose(defaultAllocator, l);
}
/**
@@ -83,9 +70,9 @@ class SList(T)
* Params:
* x = New element.
*/
- void insertFront(T x)
+ void insertFront(ref T x)
{
- Entry* temp = make!Entry(allocator);
+ auto temp = allocator.make!(Entry!T);
temp.content = x;
temp.next = first.next;
@@ -93,25 +80,29 @@ class SList(T)
}
/// Ditto.
+ void insertFront(T x)
+ {
+ insertFront(x);
+ }
+
+ /// Ditto.
alias insert = insertFront;
///
unittest
{
- auto l = make!(SList!int)(defaultAllocator);
+ SList!int l;
l.insertFront(8);
assert(l.front == 8);
l.insertFront(9);
assert(l.front == 9);
-
- dispose(defaultAllocator, l);
}
/**
* Returns: $(D_KEYWORD true) if the list is empty.
*/
- @property bool empty() inout const
+ @property bool empty() const
{
return first.next is null;
}
@@ -121,7 +112,7 @@ class SList(T)
*
* Returns: The first element.
*/
- T popFront()
+ void popFront()
in
{
assert(!empty);
@@ -129,26 +120,21 @@ class SList(T)
body
{
auto n = first.next.next;
- auto content = first.next.content;
- dispose(allocator, first.next);
+ allocator.dispose(first.next);
first.next = n;
-
- return content;
}
///
unittest
{
- auto l = make!(SList!int)(defaultAllocator);
+ SList!int l;
l.insertFront(8);
l.insertFront(9);
assert(l.front == 9);
l.popFront();
assert(l.front == 8);
-
- dispose(defaultAllocator, l);
}
/**
@@ -179,7 +165,7 @@ class SList(T)
///
unittest
{
- auto l = make!(SList!int)(defaultAllocator);
+ SList!int l;
l.insertFront(8);
l.insertFront(5);
@@ -188,8 +174,6 @@ class SList(T)
assert(l.removeFront(2) == 2);
assert(l.removeFront(3) == 1);
assert(l.removeFront(3) == 0);
-
- dispose(defaultAllocator, l);
}
/**
@@ -235,7 +219,7 @@ class SList(T)
///
unittest
{
- auto l = make!(SList!int)(defaultAllocator);
+ SList!int l;
l.insertFront(5);
l.insertFront(4);
@@ -246,32 +230,18 @@ class SList(T)
assert(i != 1 || e == 4);
assert(i != 2 || e == 5);
}
- dispose(defaultAllocator, l);
- }
-
- /**
- * List entry.
- */
- protected struct Entry
- {
- /// List item content.
- T content;
-
- /// Next list item.
- Entry* next;
}
/// 0th element of the list.
- protected Entry first;
+ private Entry!T first;
- /// Allocator.
- protected shared Allocator allocator;
+ mixin DefaultAllocator;
}
///
unittest
{
- auto l = make!(SList!int)(defaultAllocator);
+ SList!int l;
size_t i;
l.insertFront(5);
@@ -285,8 +255,6 @@ unittest
++i;
}
assert(i == 3);
-
- dispose(defaultAllocator, l);
}
private unittest
@@ -294,8 +262,5 @@ private unittest
interface Stuff
{
}
-
- auto l = make!(SList!Stuff)(defaultAllocator);
-
- dispose(defaultAllocator, l);
+ static assert(is(SList!Stuff));
}
diff --git a/source/tanya/container/package.d b/source/tanya/container/package.d
index e1a5205..eba95a7 100644
--- a/source/tanya/container/package.d
+++ b/source/tanya/container/package.d
@@ -10,7 +10,6 @@
*/
module tanya.container;
-public import tanya.container.bit;
public import tanya.container.buffer;
public import tanya.container.list;
public import tanya.container.vector;
diff --git a/source/tanya/container/queue.d b/source/tanya/container/queue.d
index 960254b..6470044 100644
--- a/source/tanya/container/queue.d
+++ b/source/tanya/container/queue.d
@@ -6,14 +6,16 @@
* 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.
@@ -21,18 +23,6 @@ import tanya.memory;
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.
*/
~this()
@@ -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;
@@ -106,26 +224,30 @@ 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);
diff --git a/source/tanya/container/bit.d b/source/tanya/crypto/bit.d
index 88c563f..8610577 100644
--- a/source/tanya/container/bit.d
+++ b/source/tanya/crypto/bit.d
@@ -8,7 +8,7 @@
* Mozilla Public License, v. 2.0).
* Authors: $(LINK2 mailto:belka@caraus.de, Eugene Wissner)
*/
-module tanya.container.bit;
+module tanya.crypto.bit;
/**
* Wrapper that allows bit manipulation on $(D_KEYWORD ubyte[]) array.
diff --git a/source/tanya/crypto/des.d b/source/tanya/crypto/des.d
index a67ba6f..8154056 100644
--- a/source/tanya/crypto/des.d
+++ b/source/tanya/crypto/des.d
@@ -10,7 +10,7 @@
*/
module tanya.crypto.des;
-import tanya.container.bit;
+import tanya.crypto.bit;
import tanya.crypto.symmetric;
/// Initial permutation table.
diff --git a/source/tanya/crypto/package.d b/source/tanya/crypto/package.d
index 314d0f1..37cb3c7 100644
--- a/source/tanya/crypto/package.d
+++ b/source/tanya/crypto/package.d
@@ -10,9 +10,7 @@
*/
module tanya.crypto;
-public
-{
- import tanya.crypto.des;
- import tanya.crypto.mode;
- import tanya.crypto.symmetric;
-}
+public import tanya.crypto.bit;
+public import tanya.crypto.des;
+public import tanya.crypto.mode;
+public import tanya.crypto.symmetric;
diff --git a/source/tanya/memory/allocator.d b/source/tanya/memory/allocator.d
index c9b7386..4da32c8 100644
--- a/source/tanya/memory/allocator.d
+++ b/source/tanya/memory/allocator.d
@@ -54,9 +54,10 @@ interface Allocator
/**
* The mixin generates common methods for classes and structs using
- * allocators. It provides a protected member and a read-only property,
- * that checks if an allocator was already set and sets it to the default
- * one, if not (useful for structs which don't have a default constructor).
+ * allocators. It provides a protected member, constructor and a read-only
+ * property, that checks if an allocator was already set and sets it to the
+ * default one, if not (useful for structs which don't have a default
+ * constructor).
*/
mixin template DefaultAllocator()
{
@@ -64,6 +65,20 @@ mixin template DefaultAllocator()
protected shared Allocator allocator_;
/**
+ * Params:
+ * allocator = The allocator should be used.
+ */
+ this(shared Allocator allocator)
+ in
+ {
+ assert(allocator !is null);
+ }
+ body
+ {
+ this.allocator_ = allocator;
+ }
+
+ /**
* This property checks if the allocator was set in the constructor
* and sets it to the default one, if not.
*