Vector: allow insert multiple items in insertBack

This commit is contained in:
Eugen Wissner 2017-01-02 12:47:41 +01:00
parent b3f4ea572e
commit 48e355b87f
3 changed files with 47 additions and 63 deletions

View File

@ -16,7 +16,7 @@ version (unittest)
{
package struct ConstEqualsStruct
{
int opEquals(typeof(this) that) const
int opEquals(typeof(this) that) const @nogc
{
return true;
}
@ -24,7 +24,7 @@ version (unittest)
package struct MutableEqualsStruct
{
int opEquals(typeof(this) that)
int opEquals(typeof(this) that) @nogc
{
return true;
}

View File

@ -21,25 +21,13 @@ import tanya.memory;
version (unittest)
{
import tanya.container.entry;
struct SWithDtor
{
bool opEquals(ref SWithDtor that)
{
return true;
}
~this() @nogc
{
}
}
struct SConstEquals
{
bool opEquals(in ref SConstEquals that) const
{
return true;
}
}
}
// Defines the container's primary range.
@ -324,12 +312,6 @@ struct Vector(T)
insertBack(init);
}
private unittest
{
// Implicitly convertible works.
auto v = Vector!int(IL(cast(short) 1, cast(short) 2));
}
/**
* Creates a new $(D_PSYMBOL Vector).
*
@ -415,11 +397,6 @@ struct Vector(T)
capacity_ = length_ = 0;
}
private unittest
{
auto v = Vector!SWithDtor(); // Destructor can destroy empty vectors.
}
/**
* Copies the vector.
*/
@ -638,22 +615,25 @@ struct Vector(T)
* Inserts the $(D_PARAM el) into the vector.
*
* Params:
* R = Parameter type (single value or range).
* el = Value should be inserted.
* R = Parameter type (single values or a range).
* el = Values should be inserted.
*
* Returns: The number of elements inserted.
*/
size_t insertBack(R)(auto ref R el) @trusted
if (isImplicitlyConvertible!(R, T))
size_t insertBack(R...)(auto ref R el) @trusted
if (isImplicitlyConvertible!(R[0], T))
{
reserve(length_ + 1);
reserve(length_ + el.length);
if (capacity_ <= length_)
{
onOutOfMemoryError();
}
emplace(vector + length_, el);
++length_;
return 1;
foreach (i; el)
{
emplace(vector + length_, i);
++length_;
}
return el.length;
}
/// Ditto.
@ -883,21 +863,6 @@ struct Vector(T)
assert(v1 == v2);
}
private unittest
{
auto v1 = Vector!SConstEquals();
auto v2 = Vector!SConstEquals();
assert(v1 == v2);
auto v3 = const Vector!SConstEquals();
auto v4 = const Vector!SConstEquals();
assert(v3 == v4);
auto v7 = Vector!SWithDtor();
auto v8 = Vector!SWithDtor();
assert(v7 == v8);
}
/**
* $(D_KEYWORD foreach) iteration.
*
@ -1237,16 +1202,7 @@ unittest
assert(r.front == v.front);
}
private @nogc unittest
{
// Test the destructor can be called at the end of the scope.
auto a = Vector!A();
// Test that structs can be members of the vector.
static assert(is(typeof(Vector!SWithDtor())));
}
private @nogc unittest
@nogc unittest
{
const v1 = Vector!int();
const Vector!int v2;
@ -1254,7 +1210,7 @@ private @nogc unittest
static assert(is(PointerTarget!(typeof(v3.vector)) == const(int)));
}
private @nogc unittest
@nogc unittest
{
// Test that const vectors return usable ranges.
auto v = const Vector!int(IL(1, 2, 4));
@ -1275,7 +1231,7 @@ private @nogc unittest
static assert(is(typeof(r2[])));
}
private @nogc unittest
@nogc unittest
{
Vector!int v1;
const Vector!int v2;
@ -1286,4 +1242,32 @@ private @nogc unittest
assert(r1.length == 0);
assert(r2.empty);
assert(r1 == r2);
v1.insertBack(1, 2, 4);
}
@nogc unittest
{
auto v1 = Vector!ConstEqualsStruct();
auto v2 = Vector!ConstEqualsStruct();
assert(v1 == v2);
auto v3 = const Vector!ConstEqualsStruct();
auto v4 = const Vector!ConstEqualsStruct();
assert(v3 == v4);
auto v7 = Vector!MutableEqualsStruct();
auto v8 = Vector!MutableEqualsStruct();
assert(v7 == v8);
}
@nogc unittest
{
// Implicitly convertible works.
auto v = Vector!int(IL(cast(short) 1, cast(short) 2));
}
@nogc unittest
{
auto v = Vector!SWithDtor(); // Destructor can destroy empty vectors.
}

View File

@ -303,7 +303,7 @@ unittest
version (unittest)
{
class A
private class A
{
uint *destroyed;
@ -318,7 +318,7 @@ version (unittest)
}
}
struct B
private struct B
{
int prop;
@disable this();