Fix Vector.insertAfter/Before an empty range
This commit is contained in:
parent
9b953198fa
commit
b1d2b9bd9e
@ -22,22 +22,42 @@ import std.meta;
|
||||
import std.traits;
|
||||
import tanya.memory;
|
||||
|
||||
// Defines the container's primary range.
|
||||
private struct Range(E)
|
||||
/**
|
||||
* Random-access range for the $(D_PSYMBOL Vector).
|
||||
*
|
||||
* Params:
|
||||
* E = Element type.
|
||||
*/
|
||||
struct Range(E)
|
||||
{
|
||||
private E* begin, end;
|
||||
private alias ContainerType = CopyConstness!(E, Vector!(Unqual!E));
|
||||
private ContainerType* vector;
|
||||
|
||||
invariant
|
||||
{
|
||||
assert(begin <= end);
|
||||
assert(this.begin <= this.end);
|
||||
assert(this.vector !is null);
|
||||
assert(this.begin >= this.vector.data);
|
||||
assert(this.end <= this.vector.data + this.vector.length);
|
||||
}
|
||||
|
||||
private this(E* begin, E* end)
|
||||
private this(ref ContainerType vector, E* begin, E* end) @trusted
|
||||
in
|
||||
{
|
||||
assert(begin <= end);
|
||||
assert(begin >= vector.data);
|
||||
assert(end <= vector.data + vector.length);
|
||||
}
|
||||
body
|
||||
{
|
||||
this.vector = &vector;
|
||||
this.begin = begin;
|
||||
this.end = end;
|
||||
}
|
||||
|
||||
@disable this();
|
||||
|
||||
@property Range save()
|
||||
{
|
||||
return this;
|
||||
@ -45,12 +65,12 @@ private struct Range(E)
|
||||
|
||||
@property bool empty() const
|
||||
{
|
||||
return begin == end;
|
||||
return this.begin == this.end;
|
||||
}
|
||||
|
||||
@property size_t length() const
|
||||
{
|
||||
return end - begin;
|
||||
return this.end - this.begin;
|
||||
}
|
||||
|
||||
alias opDollar = length;
|
||||
@ -62,7 +82,7 @@ private struct Range(E)
|
||||
}
|
||||
body
|
||||
{
|
||||
return *begin;
|
||||
return *this.begin;
|
||||
}
|
||||
|
||||
@property ref inout(E) back() inout @trusted
|
||||
@ -72,7 +92,7 @@ private struct Range(E)
|
||||
}
|
||||
body
|
||||
{
|
||||
return *(end - 1);
|
||||
return *(this.end - 1);
|
||||
}
|
||||
|
||||
void popFront() @trusted
|
||||
@ -82,7 +102,7 @@ private struct Range(E)
|
||||
}
|
||||
body
|
||||
{
|
||||
++begin;
|
||||
++this.begin;
|
||||
}
|
||||
|
||||
void popBack() @trusted
|
||||
@ -92,7 +112,7 @@ private struct Range(E)
|
||||
}
|
||||
body
|
||||
{
|
||||
--end;
|
||||
--this.end;
|
||||
}
|
||||
|
||||
ref inout(E) opIndex(const size_t i) inout @trusted
|
||||
@ -102,17 +122,17 @@ private struct Range(E)
|
||||
}
|
||||
body
|
||||
{
|
||||
return *(begin + i);
|
||||
return *(this.begin + i);
|
||||
}
|
||||
|
||||
Range opIndex()
|
||||
{
|
||||
return typeof(return)(begin, end);
|
||||
return typeof(return)(*this.vector, this.begin, this.end);
|
||||
}
|
||||
|
||||
Range!(const E) opIndex() const
|
||||
{
|
||||
return typeof(return)(begin, end);
|
||||
return typeof(return)(*this.vector, this.begin, this.end);
|
||||
}
|
||||
|
||||
Range opSlice(const size_t i, const size_t j) @trusted
|
||||
@ -123,7 +143,7 @@ private struct Range(E)
|
||||
}
|
||||
body
|
||||
{
|
||||
return typeof(return)(begin + i, begin + j);
|
||||
return typeof(return)(*this.vector, this.begin + i, this.begin + j);
|
||||
}
|
||||
|
||||
Range!(const E) opSlice(const size_t i, const size_t j) const @trusted
|
||||
@ -134,12 +154,12 @@ private struct Range(E)
|
||||
}
|
||||
body
|
||||
{
|
||||
return typeof(return)(begin + i, begin + j);
|
||||
return typeof(return)(*this.vector, this.begin + i, this.begin + j);
|
||||
}
|
||||
|
||||
inout(E[]) get() inout @trusted
|
||||
{
|
||||
return begin[0 .. length];
|
||||
return this.begin[0 .. length];
|
||||
}
|
||||
}
|
||||
|
||||
@ -152,13 +172,13 @@ private struct Range(E)
|
||||
struct Vector(T)
|
||||
{
|
||||
private size_t length_;
|
||||
private T* vector;
|
||||
private T* data;
|
||||
private size_t capacity_;
|
||||
|
||||
invariant
|
||||
{
|
||||
assert(length_ <= capacity_);
|
||||
assert(capacity_ == 0 || vector !is null);
|
||||
assert(this.length_ <= this.capacity_);
|
||||
assert(this.capacity_ == 0 || this.data !is null);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -224,20 +244,20 @@ struct Vector(T)
|
||||
if (allocator is init.allocator)
|
||||
{
|
||||
// Just steal all references and the allocator.
|
||||
vector = init.vector;
|
||||
length_ = init.length_;
|
||||
capacity_ = init.capacity_;
|
||||
this.data = init.data;
|
||||
this.length_ = init.length_;
|
||||
this.capacity_ = init.capacity_;
|
||||
|
||||
// Reset the source vector, so it can't destroy the moved storage.
|
||||
init.length_ = init.capacity_ = 0;
|
||||
init.vector = null;
|
||||
init.data = null;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Move each element.
|
||||
reserve(init.length);
|
||||
moveEmplaceAll(init.vector[0 .. init.length_], vector[0 .. init.length_]);
|
||||
length_ = init.length;
|
||||
reserve(init.length_);
|
||||
moveEmplaceAll(init.data[0 .. init.length_], this.data[0 .. init.length_]);
|
||||
this.length_ = init.length_;
|
||||
// Destructor of init should destroy it here.
|
||||
}
|
||||
}
|
||||
@ -247,7 +267,6 @@ struct Vector(T)
|
||||
{
|
||||
auto v1 = Vector!int([1, 2, 3]);
|
||||
auto v2 = Vector!int(v1);
|
||||
assert(v1.vector !is v2.vector);
|
||||
assert(v1 == v2);
|
||||
|
||||
auto v3 = Vector!int(Vector!int([1, 2, 3]));
|
||||
@ -260,7 +279,7 @@ struct Vector(T)
|
||||
{
|
||||
auto v1 = const Vector!int([1, 2, 3]);
|
||||
auto v2 = Vector!int(v1);
|
||||
assert(v1.vector !is v2.vector);
|
||||
assert(v1.data !is v2.data);
|
||||
assert(v1 == v2);
|
||||
|
||||
auto v3 = const Vector!int(Vector!int([1, 2, 3]));
|
||||
@ -281,7 +300,7 @@ struct Vector(T)
|
||||
{
|
||||
this(allocator);
|
||||
reserve(len);
|
||||
uninitializedFill(vector[0 .. len], init);
|
||||
uninitializedFill(this.data[0 .. len], init);
|
||||
length_ = len;
|
||||
}
|
||||
|
||||
@ -334,7 +353,7 @@ struct Vector(T)
|
||||
~this() @trusted
|
||||
{
|
||||
clear();
|
||||
allocator.deallocate(vector[0 .. capacity_]);
|
||||
allocator.deallocate(this.data[0 .. capacity]);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -342,9 +361,9 @@ struct Vector(T)
|
||||
*/
|
||||
this(this)
|
||||
{
|
||||
auto buf = opIndex();
|
||||
length_ = capacity_ = 0;
|
||||
vector = null;
|
||||
auto buf = this.data[0 .. this.length_];
|
||||
this.length_ = capacity_ = 0;
|
||||
this.data = null;
|
||||
insertBack(buf);
|
||||
}
|
||||
|
||||
@ -409,14 +428,14 @@ struct Vector(T)
|
||||
else if (len > length)
|
||||
{
|
||||
reserve(len);
|
||||
initializeAll(vector[length_ .. len]);
|
||||
initializeAll(this.data[length_ .. len]);
|
||||
}
|
||||
else
|
||||
{
|
||||
static if (hasElaborateDestructor!T)
|
||||
{
|
||||
const T* end = vector + length_ - 1;
|
||||
for (T* e = vector + len; e != end; ++e)
|
||||
const T* end = this.data + length_ - 1;
|
||||
for (T* e = this.data + len; e != end; ++e)
|
||||
{
|
||||
destroy(*e);
|
||||
}
|
||||
@ -467,7 +486,7 @@ struct Vector(T)
|
||||
immutable byteSize = mulu(size, T.sizeof, overflow);
|
||||
assert(!overflow);
|
||||
|
||||
void[] buf = vector[0 .. capacity_];
|
||||
void[] buf = this.data[0 .. this.capacity_];
|
||||
if (!allocator.reallocateInPlace(buf, byteSize))
|
||||
{
|
||||
buf = allocator.allocate(byteSize);
|
||||
@ -479,8 +498,8 @@ struct Vector(T)
|
||||
{
|
||||
allocator.deallocate(buf);
|
||||
}
|
||||
const T* end = vector + length_;
|
||||
for (T* src = vector, dest = cast(T*) buf; src != end; ++src, ++dest)
|
||||
const T* end = this.data + this.length_;
|
||||
for (T* src = this.data, dest = cast(T*) buf; src != end; ++src, ++dest)
|
||||
{
|
||||
moveEmplace(*src, *dest);
|
||||
static if (hasElaborateDestructor!T)
|
||||
@ -488,10 +507,10 @@ struct Vector(T)
|
||||
destroy(*src);
|
||||
}
|
||||
}
|
||||
allocator.deallocate(vector[0 .. capacity_]);
|
||||
vector = cast(T*) buf;
|
||||
allocator.deallocate(this.data[0 .. this.capacity_]);
|
||||
this.data = cast(T*) buf;
|
||||
}
|
||||
capacity_ = size;
|
||||
this.capacity_ = size;
|
||||
}
|
||||
|
||||
///
|
||||
@ -517,15 +536,15 @@ struct Vector(T)
|
||||
*/
|
||||
void shrink(const size_t size) @trusted
|
||||
{
|
||||
if (capacity_ <= size)
|
||||
if (capacity <= size)
|
||||
{
|
||||
return;
|
||||
}
|
||||
immutable n = max(length, size);
|
||||
void[] buf = vector[0 .. capacity_];
|
||||
void[] buf = this.data[0 .. this.capacity_];
|
||||
if (allocator.reallocateInPlace(buf, n * T.sizeof))
|
||||
{
|
||||
capacity_ = n;
|
||||
this.capacity_ = n;
|
||||
}
|
||||
}
|
||||
|
||||
@ -556,7 +575,7 @@ struct Vector(T)
|
||||
*
|
||||
* Returns: The number of elements removed
|
||||
*
|
||||
* Precondition: $(D_INLINECODE !empty)
|
||||
* Precondition: $(D_INLINECODE !empty).
|
||||
*/
|
||||
void removeBack()
|
||||
in
|
||||
@ -611,22 +630,24 @@ struct Vector(T)
|
||||
* Params:
|
||||
* r = Range originally obtained from this vector.
|
||||
*
|
||||
* Returns: Elements in $(D_PARAM r) after removing.
|
||||
* Returns: A range spanning the remaining elements in the array that
|
||||
* initially were right after $(D_PARAM r).
|
||||
*
|
||||
* Precondition: $(D_PARAM r) refers to a region of $(D_KEYWORD this).
|
||||
*/
|
||||
Range!T remove(Range!T r) @trusted
|
||||
in
|
||||
{
|
||||
assert(r.begin >= vector);
|
||||
assert(r.end <= vector + length_);
|
||||
assert(r.vector is &this);
|
||||
assert(r.begin >= this.data);
|
||||
assert(r.end <= this.data + length);
|
||||
}
|
||||
body
|
||||
{
|
||||
auto end = vector + length_;
|
||||
moveAll(Range!T(r.end, end), Range!T(r.begin, end));
|
||||
auto end = this.data + this.length;
|
||||
moveAll(Range!T(this, r.end, end), Range!T(this, r.begin, end));
|
||||
length = length - r.length;
|
||||
return r;
|
||||
return Range!T(this, r.begin, this.data + length);
|
||||
}
|
||||
|
||||
///
|
||||
@ -634,31 +655,28 @@ struct Vector(T)
|
||||
{
|
||||
auto v = Vector!int([5, 18, 17, 2, 4, 6, 1]);
|
||||
|
||||
assert(v.remove(v[1 .. 3]).length == 2);
|
||||
assert(v.remove(v[1 .. 3]).length == 4);
|
||||
assert(v[0] == 5 && v[1] == 2 && v[2] == 4 && v[3] == 6 && v[4] == 1);
|
||||
assert(v.length == 5);
|
||||
|
||||
assert(v.remove(v[4 .. 4]).length == 0);
|
||||
assert(v.remove(v[4 .. 4]).length == 1);
|
||||
assert(v[0] == 5 && v[1] == 2 && v[2] == 4 && v[3] == 6 && v[4] == 1);
|
||||
assert(v.length == 5);
|
||||
|
||||
assert(v.remove(v[4 .. 5]).length == 1);
|
||||
assert(v.remove(v[4 .. 5]).length == 0);
|
||||
assert(v[0] == 5 && v[1] == 2 && v[2] == 4 && v[3] == 6);
|
||||
assert(v.length == 4);
|
||||
|
||||
assert(v.remove(v[]).length == 4);
|
||||
assert(v.empty);
|
||||
|
||||
assert(v.remove(v[]).length == 0);
|
||||
assert(v.empty);
|
||||
|
||||
}
|
||||
|
||||
private void moveBack(R)(ref R el) @trusted
|
||||
if (isImplicitlyConvertible!(R, T))
|
||||
{
|
||||
reserve(length + 1);
|
||||
moveEmplace(el, *(vector + length_));
|
||||
++length_;
|
||||
reserve(this.length + 1);
|
||||
moveEmplace(el, *(this.data + this.length_));
|
||||
++this.length_;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -675,9 +693,9 @@ struct Vector(T)
|
||||
{
|
||||
static if (__traits(isRef, el))
|
||||
{
|
||||
reserve(length + 1);
|
||||
emplace(vector + length_, el);
|
||||
++length_;
|
||||
reserve(this.length_ + 1);
|
||||
emplace(this.data + this.length_, el);
|
||||
++this.length_;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -763,6 +781,8 @@ struct Vector(T)
|
||||
* el = Value(s) should be inserted.
|
||||
*
|
||||
* Returns: The number of elements inserted.
|
||||
*
|
||||
* Precondition: $(D_PARAM r) refers to a region of $(D_KEYWORD this).
|
||||
*/
|
||||
size_t insertAfter(R)(Range!T r, R el)
|
||||
if (!isInfinite!R
|
||||
@ -770,20 +790,28 @@ struct Vector(T)
|
||||
&& isImplicitlyConvertible!(ElementType!R, T))
|
||||
in
|
||||
{
|
||||
assert(r.begin >= vector);
|
||||
assert(r.end <= vector + length_);
|
||||
assert(r.vector is &this);
|
||||
assert(r.begin >= this.data);
|
||||
assert(r.end <= this.data + length);
|
||||
}
|
||||
body
|
||||
{
|
||||
immutable oldLen = length;
|
||||
immutable offset = r.end - vector;
|
||||
immutable offset = r.end - this.data;
|
||||
immutable inserted = insertBack(el);
|
||||
bringToFront(vector[offset .. oldLen], vector[oldLen .. length]);
|
||||
bringToFront(this.data[offset .. oldLen], this.data[oldLen .. length]);
|
||||
return inserted;
|
||||
}
|
||||
|
||||
/// Ditto.
|
||||
size_t insertAfter(size_t R)(Range!T r, T[R] el)
|
||||
in
|
||||
{
|
||||
assert(r.vector is &this);
|
||||
assert(r.begin >= this.data);
|
||||
assert(r.end <= this.data + length);
|
||||
}
|
||||
body
|
||||
{
|
||||
return insertAfter!(T[])(r, el[]);
|
||||
}
|
||||
@ -793,13 +821,14 @@ struct Vector(T)
|
||||
if (isImplicitlyConvertible!(R, T))
|
||||
in
|
||||
{
|
||||
assert(r.begin >= vector);
|
||||
assert(r.end <= vector + length_);
|
||||
assert(r.vector is &this);
|
||||
assert(r.begin >= this.data);
|
||||
assert(r.end <= this.data + length);
|
||||
}
|
||||
body
|
||||
{
|
||||
immutable oldLen = length;
|
||||
immutable offset = r.end - vector;
|
||||
immutable offset = r.end - this.data;
|
||||
|
||||
static if (__traits(isRef, el))
|
||||
{
|
||||
@ -809,7 +838,7 @@ struct Vector(T)
|
||||
{
|
||||
moveBack(el);
|
||||
}
|
||||
bringToFront(vector[offset .. oldLen], vector[oldLen .. length_]);
|
||||
bringToFront(this.data[offset .. oldLen], this.data[oldLen .. length]);
|
||||
|
||||
return 1;
|
||||
}
|
||||
@ -821,16 +850,24 @@ struct Vector(T)
|
||||
&& isImplicitlyConvertible!(ElementType!R, T))
|
||||
in
|
||||
{
|
||||
assert(r.begin >= vector);
|
||||
assert(r.end <= vector + length_);
|
||||
assert(r.vector is &this);
|
||||
assert(r.begin >= this.data);
|
||||
assert(r.end <= this.data + length);
|
||||
}
|
||||
body
|
||||
{
|
||||
return insertAfter(Range!T(vector, r.begin), el);
|
||||
return insertAfter(Range!T(this, this.data, r.begin), el);
|
||||
}
|
||||
|
||||
/// Ditto.
|
||||
size_t insertBefore(size_t R)(Range!T r, T[R] el)
|
||||
in
|
||||
{
|
||||
assert(r.vector is &this);
|
||||
assert(r.begin >= this.data);
|
||||
assert(r.end <= this.data + length);
|
||||
}
|
||||
body
|
||||
{
|
||||
return insertBefore!(T[])(r, el[]);
|
||||
}
|
||||
@ -840,13 +877,14 @@ struct Vector(T)
|
||||
if (isImplicitlyConvertible!(R, T))
|
||||
in
|
||||
{
|
||||
assert(r.begin >= vector);
|
||||
assert(r.end <= vector + length_);
|
||||
assert(r.vector is &this);
|
||||
assert(r.begin >= this.data);
|
||||
assert(r.end <= this.data + length);
|
||||
}
|
||||
body
|
||||
{
|
||||
immutable oldLen = length;
|
||||
immutable offset = r.begin - vector;
|
||||
immutable offset = r.begin - this.data;
|
||||
|
||||
static if (__traits(isRef, el))
|
||||
{
|
||||
@ -856,7 +894,7 @@ struct Vector(T)
|
||||
{
|
||||
moveBack(el);
|
||||
}
|
||||
bringToFront(vector[offset .. oldLen], vector[oldLen .. length_]);
|
||||
bringToFront(this.data[offset .. oldLen], this.data[oldLen .. length]);
|
||||
|
||||
return 1;
|
||||
}
|
||||
@ -942,7 +980,7 @@ struct Vector(T)
|
||||
*
|
||||
* Returns: Assigned value.
|
||||
*
|
||||
* Precondition: $(D_INLINECODE length > pos)
|
||||
* Precondition: $(D_INLINECODE length > pos).
|
||||
*/
|
||||
ref T opIndexAssign(ref T value, const size_t pos)
|
||||
{
|
||||
@ -983,7 +1021,7 @@ struct Vector(T)
|
||||
*
|
||||
* Returns: Assigned value.
|
||||
*
|
||||
* Precondition: $(D_INLINECODE length == value.length)
|
||||
* Precondition: $(D_INLINECODE length == value.length).
|
||||
*/
|
||||
Range!T opIndexAssign(R)(R value)
|
||||
if (!isInfinite!R && isInputRange!R
|
||||
@ -1020,7 +1058,7 @@ struct Vector(T)
|
||||
*
|
||||
* Returns: The value at a specified index.
|
||||
*
|
||||
* Precondition: $(D_INLINECODE length > pos)
|
||||
* Precondition: $(D_INLINECODE length > pos).
|
||||
*/
|
||||
ref inout(T) opIndex(const size_t pos) inout @trusted
|
||||
in
|
||||
@ -1029,7 +1067,7 @@ struct Vector(T)
|
||||
}
|
||||
body
|
||||
{
|
||||
return *(vector + pos);
|
||||
return *(this.data + pos);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1038,13 +1076,13 @@ struct Vector(T)
|
||||
*/
|
||||
Range!T opIndex() @trusted
|
||||
{
|
||||
return typeof(return)(vector, vector + length_);
|
||||
return typeof(return)(this, this.data, this.data + length);
|
||||
}
|
||||
|
||||
/// Ditto.
|
||||
Range!(const T) opIndex() const @trusted
|
||||
{
|
||||
return typeof(return)(vector, vector + length_);
|
||||
return typeof(return)(this, this.data, this.data + length);
|
||||
}
|
||||
|
||||
///
|
||||
@ -1071,13 +1109,13 @@ struct Vector(T)
|
||||
*/
|
||||
bool opEquals()(auto ref typeof(this) that) @trusted
|
||||
{
|
||||
return equal(vector[0 .. length_], that.vector[0 .. that.length_]);
|
||||
return equal(this.data[0 .. length], that.data[0 .. that.length]);
|
||||
}
|
||||
|
||||
/// Ditto.
|
||||
bool opEquals()(const auto ref typeof(this) that) const @trusted
|
||||
{
|
||||
return equal(vector[0 .. length_], that.vector[0 .. that.length_]);
|
||||
return equal(this.data[0 .. length], that.data[0 .. that.length]);
|
||||
}
|
||||
|
||||
/// Ditto.
|
||||
@ -1132,8 +1170,8 @@ struct Vector(T)
|
||||
*/
|
||||
int opApply(scope int delegate(ref T) @nogc dg)
|
||||
{
|
||||
T* end = vector + length_ - 1;
|
||||
for (T* begin = vector; begin != end; ++begin)
|
||||
T* end = this.data + length - 1;
|
||||
for (T* begin = this.data; begin != end; ++begin)
|
||||
{
|
||||
int result = dg(*begin);
|
||||
if (result != 0)
|
||||
@ -1150,7 +1188,7 @@ struct Vector(T)
|
||||
for (size_t i = 0; i < length; ++i)
|
||||
{
|
||||
assert(i < length);
|
||||
int result = dg(i, *(vector + i));
|
||||
int result = dg(i, *(this.data + i));
|
||||
|
||||
if (result != 0)
|
||||
{
|
||||
@ -1163,7 +1201,7 @@ struct Vector(T)
|
||||
/// Ditto.
|
||||
int opApplyReverse(scope int delegate(ref T) dg)
|
||||
{
|
||||
for (T* end = vector + length - 1; vector != end; --end)
|
||||
for (T* end = this.data + length - 1; this.data != end; --end)
|
||||
{
|
||||
int result = dg(*end);
|
||||
if (result != 0)
|
||||
@ -1184,7 +1222,7 @@ struct Vector(T)
|
||||
{
|
||||
--i;
|
||||
assert(i < length);
|
||||
int result = dg(i, *(vector + i));
|
||||
int result = dg(i, *(this.data + i));
|
||||
|
||||
if (result != 0)
|
||||
{
|
||||
@ -1239,7 +1277,7 @@ struct Vector(T)
|
||||
/**
|
||||
* Returns: The first element.
|
||||
*
|
||||
* Precondition: $(D_INLINECODE !empty)
|
||||
* Precondition: $(D_INLINECODE !empty).
|
||||
*/
|
||||
@property ref inout(T) front() inout
|
||||
in
|
||||
@ -1248,7 +1286,7 @@ struct Vector(T)
|
||||
}
|
||||
body
|
||||
{
|
||||
return *vector;
|
||||
return *this.data;
|
||||
}
|
||||
|
||||
///
|
||||
@ -1266,7 +1304,7 @@ struct Vector(T)
|
||||
/**
|
||||
* Returns: The last element.
|
||||
*
|
||||
* Precondition: $(D_INLINECODE !empty)
|
||||
* Precondition: $(D_INLINECODE !empty).
|
||||
*/
|
||||
@property ref inout(T) back() inout @trusted
|
||||
in
|
||||
@ -1275,7 +1313,7 @@ struct Vector(T)
|
||||
}
|
||||
body
|
||||
{
|
||||
return *(vector + length_ - 1);
|
||||
return *(this.data + length - 1);
|
||||
}
|
||||
|
||||
///
|
||||
@ -1298,7 +1336,7 @@ struct Vector(T)
|
||||
* Returns: A range that iterates over elements of the container from
|
||||
* index $(D_PARAM i) up to (excluding) index $(D_PARAM j).
|
||||
*
|
||||
* Precondition: $(D_INLINECODE i <= j && j <= length)
|
||||
* Precondition: $(D_INLINECODE i <= j && j <= length).
|
||||
*/
|
||||
Range!T opSlice(const size_t i, const size_t j) @trusted
|
||||
in
|
||||
@ -1308,7 +1346,7 @@ struct Vector(T)
|
||||
}
|
||||
body
|
||||
{
|
||||
return typeof(return)(vector + i, vector + j);
|
||||
return typeof(return)(this, this.data + i, this.data + j);
|
||||
}
|
||||
|
||||
/// Ditto.
|
||||
@ -1320,7 +1358,7 @@ struct Vector(T)
|
||||
}
|
||||
body
|
||||
{
|
||||
return typeof(return)(vector + i, vector + j);
|
||||
return typeof(return)(this, this.data + i, this.data + j);
|
||||
}
|
||||
|
||||
///
|
||||
@ -1394,7 +1432,7 @@ struct Vector(T)
|
||||
}
|
||||
body
|
||||
{
|
||||
copy(value, vector[i .. j]);
|
||||
copy(value, this.data[i .. j]);
|
||||
return opSlice(i, j);
|
||||
}
|
||||
|
||||
@ -1413,7 +1451,7 @@ struct Vector(T)
|
||||
}
|
||||
body
|
||||
{
|
||||
fill(vector[i .. j], value);
|
||||
fill(this.data[i .. j], value);
|
||||
return opSlice(i, j);
|
||||
}
|
||||
|
||||
@ -1454,7 +1492,7 @@ struct Vector(T)
|
||||
*/
|
||||
inout(T[]) get() inout @trusted
|
||||
{
|
||||
return vector[0 .. length];
|
||||
return this.data[0 .. length];
|
||||
}
|
||||
|
||||
///
|
||||
@ -1498,7 +1536,7 @@ struct Vector(T)
|
||||
ref typeof(this) opAssign(R)(R that) @trusted
|
||||
if (is(R == Vector))
|
||||
{
|
||||
swap(this.vector, that.vector);
|
||||
swap(this.data, that.data);
|
||||
swap(this.length_, that.length_);
|
||||
swap(this.capacity_, that.capacity_);
|
||||
swap(this.allocator_, that.allocator_);
|
||||
@ -1519,7 +1557,7 @@ struct Vector(T)
|
||||
&& isInputRange!R
|
||||
&& isImplicitlyConvertible!(ElementType!R, T))
|
||||
{
|
||||
this.length = 0;
|
||||
length = 0;
|
||||
insertBack(that);
|
||||
return this;
|
||||
}
|
||||
@ -1596,7 +1634,7 @@ unittest
|
||||
const v1 = Vector!int();
|
||||
const Vector!int v2;
|
||||
const v3 = Vector!int([1, 5, 8]);
|
||||
static assert(is(PointerTarget!(typeof(v3.vector)) == const(int)));
|
||||
static assert(is(PointerTarget!(typeof(v3.data)) == const(int)));
|
||||
}
|
||||
|
||||
@nogc unittest
|
||||
|
Loading…
Reference in New Issue
Block a user