Vector.insertBack: Accept by value and by ref

This commit is contained in:
Eugen Wissner 2017-01-20 05:40:28 +01:00
parent 5fa9bd7b49
commit 1450a6adfe

View File

@ -169,14 +169,14 @@ struct Vector(T)
* to generate a list. * to generate a list.
* allocator = Allocator. * allocator = Allocator.
*/ */
this(size_t R)(auto in ref T[R] init, shared Allocator allocator = defaultAllocator) this(size_t R)(in T[R] init, shared Allocator allocator = defaultAllocator)
{ {
this(allocator); this(allocator);
insertBack(init[]); insertBack(init);
} }
/// Ditto. /// Ditto.
this(R)(auto in ref R init, shared Allocator allocator = defaultAllocator) this(R)(R init, shared Allocator allocator = defaultAllocator)
if (!isInfinite!R if (!isInfinite!R
&& isInputRange!R && isInputRange!R
&& isImplicitlyConvertible!(ElementType!R, T)) && isImplicitlyConvertible!(ElementType!R, T))
@ -198,17 +198,20 @@ struct Vector(T)
* If $(D_PARAM init) is passed by reference, it will be copied. * If $(D_PARAM init) is passed by reference, it will be copied.
* *
* Params: * Params:
* R = Vector type.
* init = Source vector. * init = Source vector.
* allocator = Allocator. * allocator = Allocator.
*/ */
this(ref Vector init, shared Allocator allocator = defaultAllocator) this(R)(ref R init, shared Allocator allocator = defaultAllocator)
if (is(Unqual!R == Vector))
{ {
this(allocator); this(allocator);
insertBack(init[]); insertBack(init[]);
} }
/// Ditto. /// Ditto.
this(Vector init, shared Allocator allocator = defaultAllocator) @trusted this(R)(R init, shared Allocator allocator = defaultAllocator) @trusted
if (is(R == Vector))
{ {
this(allocator); this(allocator);
if (allocator is init.allocator) if (allocator is init.allocator)
@ -251,6 +254,19 @@ struct Vector(T)
assert(v3.capacity == 3); assert(v3.capacity == 3);
} }
unittest // const constructor tests
{
auto v1 = const Vector!int([1, 2, 3]);
auto v2 = Vector!int(v1);
assert(v1.vector !is v2.vector);
assert(v1 == v2);
auto v3 = const Vector!int(Vector!int([1, 2, 3]));
assert(v1 == v3);
assert(v3.length == 3);
assert(v3.capacity == 3);
}
/** /**
* Creates a new $(D_PSYMBOL Vector). * Creates a new $(D_PSYMBOL Vector).
* *
@ -627,25 +643,29 @@ struct Vector(T)
* Inserts the $(D_PARAM el) into the vector. * Inserts the $(D_PARAM el) into the vector.
* *
* Params: * Params:
* R = Parameter type (single values or a range). * R = Parameter type (single value, range or static array).
* el = Values should be inserted. * el = Values should be inserted.
* *
* Returns: The number of elements inserted. * Returns: The number of elements inserted.
*/ */
size_t insertBack(R...)(auto ref R el) @trusted size_t insertBack(R)(auto ref R el) @trusted
if (allSatisfy!(ApplyRight!(isImplicitlyConvertible, T), R)) if (isImplicitlyConvertible!(R, T))
{ {
reserve(length_ + el.length); reserve(length_ + 1);
foreach (i; el) static if (__traits(isRef, el))
{ {
emplace(vector + length_, i); emplace(vector + length_, el);
++length_;
} }
return el.length; else
{
moveEmplace(el, *(vector + length_));
}
++length_;
return 1;
} }
/// Ditto. /// Ditto.
size_t insertBack(R)(R el) @trusted size_t insertBack(R)(R el)
if (!isInfinite!R if (!isInfinite!R
&& isInputRange!R && isInputRange!R
&& isImplicitlyConvertible!(ElementType!R, T)) && isImplicitlyConvertible!(ElementType!R, T))
@ -657,12 +677,22 @@ struct Vector(T)
size_t retLength; size_t retLength;
foreach (e; el) foreach (e; el)
{ {
insertBack(e); retLength += insertBack(e);
++retLength;
} }
return retLength; return retLength;
} }
/// Ditto.
size_t insertBack(size_t R)(in T[R] el)
{
reserve(length_ + el.length);
foreach (e; el)
{
insertBack(e);
}
return el.length;
}
/// Ditto. /// Ditto.
alias insert = insertBack; alias insert = insertBack;
@ -1304,7 +1334,7 @@ unittest
assert(r2.empty); assert(r2.empty);
assert(r1 == r2); assert(r1 == r2);
v1.insertBack(1, 2, 4); v1.insertBack([1, 2, 4]);
assert(v1[] == v1); assert(v1[] == v1);
assert(v2[] == v2); assert(v2[] == v2);
assert(v2[] != v1); assert(v2[] != v1);