summaryrefslogtreecommitdiff
path: root/source
diff options
context:
space:
mode:
authorEugen Wissner <belka@caraus.de>2017-06-28 08:12:58 +0200
committerEugen Wissner <belka@caraus.de>2017-06-28 08:12:58 +0200
commita6dfb3a19ee98f44750c56ac4d7c9cf5b69965dc (patch)
treec518e836703569c5838440f0bae14d16722d82c1 /source
parent2af0db04bd8a6db63e6988c29e0297b668b5b375 (diff)
downloadtanya-a6dfb3a19ee98f44750c56ac4d7c9cf5b69965dc.tar.gz
Fix DList.opAssign not changing tail
Diffstat (limited to 'source')
-rw-r--r--source/tanya/container/list.d181
1 files changed, 113 insertions, 68 deletions
diff --git a/source/tanya/container/list.d b/source/tanya/container/list.d
index 1d5085d..6b93311 100644
--- a/source/tanya/container/list.d
+++ b/source/tanya/container/list.d
@@ -134,9 +134,9 @@ struct SList(T)
* allocator = Allocator.
*/
this(R)(R init, shared Allocator allocator = defaultAllocator)
- if (!isInfinite!R
- && isInputRange!R
- && isImplicitlyConvertible!(ElementType!R, T))
+ if (!isInfinite!R
+ && isInputRange!R
+ && isImplicitlyConvertible!(ElementType!R, T))
{
this(allocator);
insertFront(init);
@@ -174,6 +174,12 @@ struct SList(T)
assert(l.front == 3);
}
+ private @safe @nogc unittest
+ {
+ auto l = SList!int(0, 0);
+ assert(l.empty);
+ }
+
/// Ditto.
this(const size_t len, shared Allocator allocator = defaultAllocator)
{
@@ -217,14 +223,14 @@ struct SList(T)
* allocator = Allocator.
*/
this(R)(ref R init, shared Allocator allocator = defaultAllocator)
- if (is(Unqual!R == SList))
+ if (is(Unqual!R == SList))
{
this(init[], allocator);
}
/// Ditto.
this(R)(R init, shared Allocator allocator = defaultAllocator) @trusted
- if (is(R == SList))
+ if (is(R == SList))
{
this(allocator);
if (allocator is init.allocator)
@@ -320,7 +326,7 @@ struct SList(T)
}
private size_t moveEntry(R)(ref Entry* head, ref R el) @trusted
- if (isImplicitlyConvertible!(R, T))
+ if (isImplicitlyConvertible!(R, T))
{
auto temp = cast(Entry*) allocator.allocate(Entry.sizeof);
@@ -341,14 +347,14 @@ struct SList(T)
* Returns: The number of elements inserted.
*/
size_t insertFront(R)(R el)
- if (isImplicitlyConvertible!(R, T))
+ if (isImplicitlyConvertible!(R, T))
{
return moveEntry(this.head, el);
}
/// Ditto.
size_t insertFront(R)(ref R el) @trusted
- if (isImplicitlyConvertible!(R, T))
+ if (isImplicitlyConvertible!(R, T))
{
this.head = allocator.make!Entry(el, this.head);
return 1;
@@ -370,9 +376,9 @@ struct SList(T)
/// Ditto.
size_t insertFront(R)(R el) @trusted
- if (!isInfinite!R
- && isInputRange!R
- && isImplicitlyConvertible!(ElementType!R, T))
+ if (!isInfinite!R
+ && isInputRange!R
+ && isImplicitlyConvertible!(ElementType!R, T))
{
size_t retLength;
Entry* next, newHead;
@@ -451,7 +457,7 @@ struct SList(T)
* Precondition: $(D_PARAM r) is extracted from this list.
*/
size_t insertBefore(R)(SRange!T r, R el)
- if (isImplicitlyConvertible!(R, T))
+ if (isImplicitlyConvertible!(R, T))
in
{
assert(checkRangeBelonging(r));
@@ -472,9 +478,9 @@ struct SList(T)
/// Ditto.
size_t insertBefore(R)(SRange!T r, R el)
- if (!isInfinite!R
- && isInputRange!R
- && isImplicitlyConvertible!(ElementType!R, T))
+ if (!isInfinite!R
+ && isInputRange!R
+ && isImplicitlyConvertible!(ElementType!R, T))
in
{
assert(checkRangeBelonging(r));
@@ -610,9 +616,7 @@ struct SList(T)
}
/**
- * Returns the first element and moves to the next one.
- *
- * Returns: The first element.
+ * Removes the front element.
*
* Precondition: $(D_INLINECODE !empty)
*/
@@ -749,33 +753,50 @@ struct SList(T)
* Returns: $(D_KEYWORD this).
*/
ref typeof(this) opAssign(R)(ref R that)
- if (is(Unqual!R == SList))
+ if (is(Unqual!R == SList))
{
return this = that[];
}
/// Ditto.
ref typeof(this) opAssign(R)(R that)
- if (is(R == SList))
+ if (is(R == SList))
{
swap(this.head, that.head);
swap(this.allocator_, that.allocator_);
return this;
}
+ ///
+ @safe @nogc unittest
+ {
+ {
+ auto l1 = SList!int([5, 4, 9]);
+ auto l2 = SList!int([9, 4]);
+ l1 = l2;
+ assert(l1 == l2);
+ }
+ {
+ auto l1 = SList!int([5, 4, 9]);
+ auto l2 = SList!int([9, 4]);
+ l1 = SList!int([9, 4]);
+ assert(l1 == l2);
+ }
+ }
+
/**
* Assigns an input range.
*
* Params:
- * R = Type of the initial range.
- * that = Values to initialize the list with.
+ * R = Type of the initial range.
+ * that = Values to initialize the list with.
*
* Returns: $(D_KEYWORD this).
*/
ref typeof(this) opAssign(R)(R that) @trusted
- if (!isInfinite!R
- && isInputRange!R
- && isImplicitlyConvertible!(ElementType!R, T))
+ if (!isInfinite!R
+ && isInputRange!R
+ && isImplicitlyConvertible!(ElementType!R, T))
{
Entry** next = &this.head;
@@ -805,12 +826,20 @@ struct SList(T)
assert(l1 == l2);
}
+ private @safe @nogc unittest
+ {
+ auto l1 = SList!int();
+ auto l2 = SList!int([9, 4]);
+ l1 = l2[];
+ assert(l1 == l2);
+ }
+
/**
* Assigns a static array.
*
* Params:
* R = Static array size.
- * that = Values to initialize the vector with.
+ * that = Values to initialize the list with.
*
* Returns: $(D_KEYWORD this).
*/
@@ -1020,9 +1049,9 @@ struct DList(T)
* allocator = Allocator.
*/
this(R)(R init, shared Allocator allocator = defaultAllocator)
- if (!isInfinite!R
- && isInputRange!R
- && isImplicitlyConvertible!(ElementType!R, T))
+ if (!isInfinite!R
+ && isInputRange!R
+ && isImplicitlyConvertible!(ElementType!R, T))
{
this(allocator);
insertFront(init);
@@ -1063,6 +1092,12 @@ struct DList(T)
assert(l.back == 3);
}
+ private @safe @nogc unittest
+ {
+ auto l = DList!int(0, 0);
+ assert(l.empty);
+ }
+
/// Ditto.
this(const size_t len, shared Allocator allocator = defaultAllocator)
{
@@ -1106,14 +1141,14 @@ struct DList(T)
* allocator = Allocator.
*/
this(R)(ref R init, shared Allocator allocator = defaultAllocator)
- if (is(Unqual!R == DList))
+ if (is(Unqual!R == DList))
{
this(init[], allocator);
}
/// Ditto.
this(R)(R init, shared Allocator allocator = defaultAllocator) @trusted
- if (is(R == DList))
+ if (is(R == DList))
{
this(allocator);
if (allocator is init.allocator)
@@ -1238,7 +1273,7 @@ struct DList(T)
}
private size_t moveEntry(R)(ref Entry* head, ref R el) @trusted
- if (isImplicitlyConvertible!(R, T))
+ if (isImplicitlyConvertible!(R, T))
{
auto temp = cast(Entry*) allocator.allocate(Entry.sizeof);
@@ -1268,14 +1303,14 @@ struct DList(T)
* Returns: The number of elements inserted.
*/
size_t insertFront(R)(R el)
- if (isImplicitlyConvertible!(R, T))
+ if (isImplicitlyConvertible!(R, T))
{
return moveEntry(this.head, el);
}
/// Ditto.
size_t insertFront(R)(ref R el) @trusted
- if (isImplicitlyConvertible!(R, T))
+ if (isImplicitlyConvertible!(R, T))
{
if (this.tail is null)
{
@@ -1307,9 +1342,9 @@ struct DList(T)
/// Ditto.
size_t insertFront(R)(R el) @trusted
- if (!isInfinite!R
- && isInputRange!R
- && isImplicitlyConvertible!(ElementType!R, T))
+ if (!isInfinite!R
+ && isInputRange!R
+ && isImplicitlyConvertible!(ElementType!R, T))
{
size_t retLength;
Entry* next, newHead;
@@ -1356,16 +1391,20 @@ struct DList(T)
assert(l1.insertFront(8) == 1);
assert(l1.front == 8);
+ assert(l1.back == 8);
assert(l1.insertFront(9) == 1);
assert(l1.front == 9);
+ assert(l1.back == 8);
DList!int l2;
assert(l2.insertFront([25, 30, 15]) == 3);
assert(l2.front == 25);
+ assert(l2.back == 15);
l2.insertFront(l1[]);
assert(l2.length == 5);
assert(l2.front == 9);
+ assert(l2.back == 15);
}
/**
@@ -1378,7 +1417,7 @@ struct DList(T)
* Returns: The number of elements inserted.
*/
size_t insertBack(R)(R el) @trusted
- if (isImplicitlyConvertible!(R, T))
+ if (isImplicitlyConvertible!(R, T))
{
auto temp = cast(Entry*) allocator.allocate(Entry.sizeof);
@@ -1400,7 +1439,7 @@ struct DList(T)
/// Ditto.
size_t insertBack(R)(ref R el) @trusted
- if (isImplicitlyConvertible!(R, T))
+ if (isImplicitlyConvertible!(R, T))
{
if (this.tail is null)
{
@@ -1432,9 +1471,9 @@ struct DList(T)
/// Ditto.
size_t insertBack(R)(R el) @trusted
- if (!isInfinite!R
- && isInputRange!R
- && isImplicitlyConvertible!(ElementType!R, T))
+ if (!isInfinite!R
+ && isInputRange!R
+ && isImplicitlyConvertible!(ElementType!R, T))
{
size_t inserted;
@@ -1496,7 +1535,7 @@ struct DList(T)
* Precondition: $(D_PARAM r) is extracted from this list.
*/
size_t insertBefore(R)(DRange!T r, R el)
- if (isImplicitlyConvertible!(R, T))
+ if (isImplicitlyConvertible!(R, T))
in
{
assert(checkRangeBelonging(r));
@@ -1517,9 +1556,9 @@ struct DList(T)
/// Ditto.
size_t insertBefore(R)(DRange!T r, R el)
- if (!isInfinite!R
- && isInputRange!R
- && isImplicitlyConvertible!(ElementType!R, T))
+ if (!isInfinite!R
+ && isInputRange!R
+ && isImplicitlyConvertible!(ElementType!R, T))
in
{
assert(checkRangeBelonging(r));
@@ -1655,9 +1694,7 @@ struct DList(T)
}
/**
- * Returns the first element and moves to the next one.
- *
- * Returns: The first element.
+ * Removes the front element.
*
* Precondition: $(D_INLINECODE !empty)
*/
@@ -1807,14 +1844,14 @@ struct DList(T)
* Returns: $(D_KEYWORD this).
*/
ref typeof(this) opAssign(R)(ref R that)
- if (is(Unqual!R == DList))
+ if (is(Unqual!R == DList))
{
return this = that[];
}
/// Ditto.
ref typeof(this) opAssign(R)(R that)
- if (is(R == DList))
+ if (is(R == DList))
{
swap(this.head, that.head);
swap(this.tail, that.tail);
@@ -1826,32 +1863,32 @@ struct DList(T)
* Assigns an input range.
*
* Params:
- * R = Type of the initial range.
- * that = Values to initialize the list with.
+ * R = Type of the initial range.
+ * that = Values to initialize the list with.
*
* Returns: $(D_KEYWORD this).
*/
ref typeof(this) opAssign(R)(R that) @trusted
- if (!isInfinite!R
- && isInputRange!R
- && isImplicitlyConvertible!(ElementType!R, T))
+ if (!isInfinite!R
+ && isInputRange!R
+ && isImplicitlyConvertible!(ElementType!R, T))
{
Entry** next = &this.head;
- foreach (ref e; that)
+ while (!that.empty && *next !is null)
{
- if (*next is null)
- {
- *next = allocator.make!Entry(e);
- }
- else
- {
- (*next).content = e;
- }
+ (*next).content = that.front;
next = &(*next).next;
+ that.popFront();
+ }
+ if (that.empty)
+ {
+ remove(DRange!T(*next, this.tail));
+ }
+ else
+ {
+ insertBack(that);
}
- remove(DRange!T(*next, this.tail));
-
return this;
}
@@ -1864,12 +1901,20 @@ struct DList(T)
assert(l1 == l2);
}
+ private @safe @nogc unittest
+ {
+ auto l1 = DList!int();
+ auto l2 = DList!int([9, 4]);
+ l1 = l2[];
+ assert(l1 == l2);
+ }
+
/**
* Assigns a static array.
*
* Params:
* R = Static array size.
- * that = Values to initialize the vector with.
+ * that = Values to initialize the list with.
*
* Returns: $(D_KEYWORD this).
*/