Fix #4
This commit is contained in:
parent
1450a6adfe
commit
a7206cbd02
@ -12,11 +12,11 @@
|
|||||||
*/
|
*/
|
||||||
module tanya.container.entry;
|
module tanya.container.entry;
|
||||||
|
|
||||||
package struct Entry(T)
|
package struct SEntry(T)
|
||||||
{
|
{
|
||||||
/// Item content.
|
/// Item content.
|
||||||
T content;
|
T content;
|
||||||
|
|
||||||
/// Next item.
|
/// Next item.
|
||||||
Entry* next;
|
SEntry* next;
|
||||||
}
|
}
|
||||||
|
@ -72,7 +72,7 @@ struct SList(T)
|
|||||||
*/
|
*/
|
||||||
void insertFront(ref T x)
|
void insertFront(ref T x)
|
||||||
{
|
{
|
||||||
auto temp = allocator.make!(Entry!T);
|
auto temp = allocator.make!(SEntry!T);
|
||||||
|
|
||||||
temp.content = x;
|
temp.content = x;
|
||||||
temp.next = first.next;
|
temp.next = first.next;
|
||||||
@ -233,7 +233,7 @@ struct SList(T)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// 0th element of the list.
|
/// 0th element of the list.
|
||||||
private Entry!T first;
|
private SEntry!T first;
|
||||||
|
|
||||||
mixin DefaultAllocator;
|
mixin DefaultAllocator;
|
||||||
}
|
}
|
||||||
|
@ -44,7 +44,7 @@ struct Queue(T)
|
|||||||
size_t length() const
|
size_t length() const
|
||||||
{
|
{
|
||||||
size_t len;
|
size_t len;
|
||||||
for (const(Entry!T)* i = first; i !is null; i = i.next)
|
for (const(SEntry!T)* i = first; i !is null; i = i.next)
|
||||||
{
|
{
|
||||||
++len;
|
++len;
|
||||||
}
|
}
|
||||||
@ -72,7 +72,7 @@ struct Queue(T)
|
|||||||
assert(q.length == 0);
|
assert(q.length == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void enqueueEntry(ref Entry!T* entry)
|
private void enqueueEntry(ref SEntry!T* entry)
|
||||||
{
|
{
|
||||||
if (empty)
|
if (empty)
|
||||||
{
|
{
|
||||||
@ -85,9 +85,9 @@ struct Queue(T)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private Entry!T* allocateEntry()
|
private SEntry!T* allocateEntry()
|
||||||
{
|
{
|
||||||
auto temp = cast(Entry!T*) allocator.allocate(Entry!T.sizeof);
|
auto temp = cast(SEntry!T*) allocator.allocate(SEntry!T.sizeof);
|
||||||
if (temp is null)
|
if (temp is null)
|
||||||
{
|
{
|
||||||
onOutOfMemoryError();
|
onOutOfMemoryError();
|
||||||
@ -107,7 +107,7 @@ struct Queue(T)
|
|||||||
{
|
{
|
||||||
auto temp = allocateEntry();
|
auto temp = allocateEntry();
|
||||||
|
|
||||||
*temp = Entry!T.init;
|
*temp = SEntry!T.init;
|
||||||
temp.content = x;
|
temp.content = x;
|
||||||
|
|
||||||
enqueueEntry(temp);
|
enqueueEntry(temp);
|
||||||
@ -256,8 +256,8 @@ struct Queue(T)
|
|||||||
assert(q.empty);
|
assert(q.empty);
|
||||||
}
|
}
|
||||||
|
|
||||||
private Entry!T* first;
|
private SEntry!T* first;
|
||||||
private Entry!T* rear;
|
private SEntry!T* rear;
|
||||||
|
|
||||||
mixin DefaultAllocator;
|
mixin DefaultAllocator;
|
||||||
}
|
}
|
||||||
|
@ -169,10 +169,10 @@ struct Vector(T)
|
|||||||
* to generate a list.
|
* to generate a list.
|
||||||
* allocator = Allocator.
|
* allocator = Allocator.
|
||||||
*/
|
*/
|
||||||
this(size_t R)(in T[R] init, shared Allocator allocator = defaultAllocator)
|
this(size_t R)(T[R] init, shared Allocator allocator = defaultAllocator)
|
||||||
{
|
{
|
||||||
this(allocator);
|
this(allocator);
|
||||||
insertBack(init);
|
insertBack!(T[])(init[]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Ditto.
|
/// Ditto.
|
||||||
@ -229,12 +229,7 @@ struct Vector(T)
|
|||||||
{
|
{
|
||||||
// Move each element.
|
// Move each element.
|
||||||
reserve(init.length);
|
reserve(init.length);
|
||||||
|
moveEmplaceAll(init.vector[0 .. init.length_], vector[0 .. init.length_]);
|
||||||
const T* end = vector + init.length;
|
|
||||||
for (T* src = init.vector, dest = vector; dest != end; ++src, ++dest)
|
|
||||||
{
|
|
||||||
moveEmplace(*src, *dest);
|
|
||||||
}
|
|
||||||
length_ = init.length;
|
length_ = init.length;
|
||||||
// Destructor of init should destroy it here.
|
// Destructor of init should destroy it here.
|
||||||
}
|
}
|
||||||
@ -335,21 +330,21 @@ struct Vector(T)
|
|||||||
/**
|
/**
|
||||||
* Destroys this $(D_PSYMBOL Vector).
|
* Destroys this $(D_PSYMBOL Vector).
|
||||||
*/
|
*/
|
||||||
~this()
|
~this() @trusted
|
||||||
{
|
{
|
||||||
length = 0;
|
clear();
|
||||||
shrink(0);
|
allocator.deallocate(vector[0 .. capacity_]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Copies the vector.
|
* Copies the vector.
|
||||||
*/
|
*/
|
||||||
this(this) @trusted
|
this(this)
|
||||||
{
|
{
|
||||||
auto buf = vector;
|
auto buf = opIndex();
|
||||||
immutable oldLen = length_;
|
|
||||||
length_ = capacity_ = 0;
|
length_ = capacity_ = 0;
|
||||||
insertBack(buf[0 .. oldLen]);
|
vector = null;
|
||||||
|
insertBack(buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -357,7 +352,7 @@ struct Vector(T)
|
|||||||
*/
|
*/
|
||||||
void clear()
|
void clear()
|
||||||
{
|
{
|
||||||
length_ = 0;
|
length = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
@ -399,11 +394,11 @@ struct Vector(T)
|
|||||||
*/
|
*/
|
||||||
@property void length(in size_t len) @trusted
|
@property void length(in size_t len) @trusted
|
||||||
{
|
{
|
||||||
if (len == length_)
|
if (len == length)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else if (len > length_)
|
else if (len > length)
|
||||||
{
|
{
|
||||||
reserve(len);
|
reserve(len);
|
||||||
initializeAll(vector[length_ .. len]);
|
initializeAll(vector[length_ .. len]);
|
||||||
@ -597,70 +592,71 @@ struct Vector(T)
|
|||||||
Range!T remove(Range!T r) @trusted
|
Range!T remove(Range!T r) @trusted
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
assert(r.begin >= vector && r.end <= vector + length_);
|
assert(r.begin >= vector);
|
||||||
|
assert(r.end <= vector + length_);
|
||||||
}
|
}
|
||||||
body
|
body
|
||||||
{
|
{
|
||||||
const T* end = vector + length_;
|
auto end = vector + length_;
|
||||||
T* a = r.begin;
|
moveAll(Range!T(r.end, end), Range!T(r.begin, end));
|
||||||
for (T* b = r.end; b != end; ++a, ++b)
|
length = length - r.length;
|
||||||
{
|
|
||||||
*a = *b;
|
|
||||||
}
|
|
||||||
for (; a != end; ++a)
|
|
||||||
{
|
|
||||||
static if (hasElaborateDestructor!T)
|
|
||||||
{
|
|
||||||
destroy(*a);
|
|
||||||
}
|
|
||||||
--length_;
|
|
||||||
}
|
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
unittest
|
@safe @nogc unittest
|
||||||
{
|
{
|
||||||
auto v = Vector!int([5, 18, 17, 2, 4, 6, 1]);
|
auto v = Vector!int([5, 18, 17, 2, 4, 6, 1]);
|
||||||
|
|
||||||
v.remove(v[1..3]);
|
assert(v.remove(v[1 .. 3]).length == 2);
|
||||||
assert(v == Vector!int([5, 2, 4, 6, 1]));
|
assert(v[0] == 5 && v[1] == 2 && v[2] == 4 && v[3] == 6 && v[4] == 1);
|
||||||
|
assert(v.length == 5);
|
||||||
|
|
||||||
v.remove(v[4..4]);
|
assert(v.remove(v[4 .. 4]).length == 0);
|
||||||
assert(v == Vector!int([5, 2, 4, 6, 1]));
|
assert(v[0] == 5 && v[1] == 2 && v[2] == 4 && v[3] == 6 && v[4] == 1);
|
||||||
|
assert(v.length == 5);
|
||||||
|
|
||||||
v.remove(v[4..5]);
|
assert(v.remove(v[4 .. 5]).length == 1);
|
||||||
assert(v == Vector!int([5, 2, 4, 6]));
|
assert(v[0] == 5 && v[1] == 2 && v[2] == 4 && v[3] == 6);
|
||||||
|
assert(v.length == 4);
|
||||||
|
|
||||||
v.remove(v[]);
|
assert(v.remove(v[]).length == 4);
|
||||||
assert(v.empty);
|
assert(v.empty);
|
||||||
|
|
||||||
v.remove(v[]);
|
assert(v.remove(v[]).length == 0);
|
||||||
assert(v.empty);
|
assert(v.empty);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void moveBack(R)(ref R el) @trusted
|
||||||
|
if (isImplicitlyConvertible!(R, T))
|
||||||
|
{
|
||||||
|
reserve(length + 1);
|
||||||
|
moveEmplace(el, *(vector + length_));
|
||||||
|
++length_;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Inserts the $(D_PARAM el) into the vector.
|
* Inserts the $(D_PARAM el) into the vector.
|
||||||
*
|
*
|
||||||
* Params:
|
* Params:
|
||||||
* R = Parameter type (single value, range or static array).
|
* R = Type of the inserted value(s) (single value, range or static array).
|
||||||
* el = Values should be inserted.
|
* el = Value(s) 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 (isImplicitlyConvertible!(R, T))
|
if (isImplicitlyConvertible!(R, T))
|
||||||
{
|
{
|
||||||
reserve(length_ + 1);
|
|
||||||
static if (__traits(isRef, el))
|
static if (__traits(isRef, el))
|
||||||
{
|
{
|
||||||
|
reserve(length + 1);
|
||||||
emplace(vector + length_, el);
|
emplace(vector + length_, el);
|
||||||
|
++length_;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
moveEmplace(el, *(vector + length_));
|
moveBack(el);
|
||||||
}
|
}
|
||||||
++length_;
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -672,7 +668,7 @@ struct Vector(T)
|
|||||||
{
|
{
|
||||||
static if (hasLength!R)
|
static if (hasLength!R)
|
||||||
{
|
{
|
||||||
reserve(length_ + el.length);
|
reserve(length + el.length);
|
||||||
}
|
}
|
||||||
size_t retLength;
|
size_t retLength;
|
||||||
foreach (e; el)
|
foreach (e; el)
|
||||||
@ -683,14 +679,9 @@ struct Vector(T)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Ditto.
|
/// Ditto.
|
||||||
size_t insertBack(size_t R)(in T[R] el)
|
size_t insertBack(size_t R)(T[R] el)
|
||||||
{
|
{
|
||||||
reserve(length_ + el.length);
|
return insertBack!(T[])(el[]);
|
||||||
foreach (e; el)
|
|
||||||
{
|
|
||||||
insertBack(e);
|
|
||||||
}
|
|
||||||
return el.length;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Ditto.
|
/// Ditto.
|
||||||
@ -731,13 +722,191 @@ struct Vector(T)
|
|||||||
assert(v1.capacity == 4);
|
assert(v1.capacity == 4);
|
||||||
assert(v1[0] == 5 && v1[1] == 6 && v1[2] == 4 && v1[3] == 2);
|
assert(v1[0] == 5 && v1[1] == 6 && v1[2] == 4 && v1[3] == 2);
|
||||||
|
|
||||||
auto v2 = Vector!int([34, 234]);
|
assert(v1.insertBack([34, 234]) == 2);
|
||||||
assert(v1.insertBack(v2[]) == 2);
|
|
||||||
assert(v1.length == 6);
|
assert(v1.length == 6);
|
||||||
assert(v1.capacity == 6);
|
assert(v1.capacity == 6);
|
||||||
assert(v1[4] == 34 && v1[5] == 234);
|
assert(v1[4] == 34 && v1[5] == 234);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Inserts $(D_PARAM el) before or after $(D_PARAM r).
|
||||||
|
*
|
||||||
|
* Params:
|
||||||
|
* R = Type of the inserted value(s) (single value, range or static array).
|
||||||
|
* r = Range originally obtained from this vector.
|
||||||
|
* el = Value(s) should be inserted.
|
||||||
|
*
|
||||||
|
* Returns: The number of elements inserted.
|
||||||
|
*/
|
||||||
|
size_t insertAfter(R)(Range!T r, R el)
|
||||||
|
if (!isInfinite!R
|
||||||
|
&& isInputRange!R
|
||||||
|
&& isImplicitlyConvertible!(ElementType!R, T))
|
||||||
|
in
|
||||||
|
{
|
||||||
|
assert(r.begin >= vector);
|
||||||
|
assert(r.end <= vector + length_);
|
||||||
|
}
|
||||||
|
body
|
||||||
|
{
|
||||||
|
immutable oldLen = length;
|
||||||
|
immutable offset = r.end - vector;
|
||||||
|
immutable inserted = insertBack(el);
|
||||||
|
bringToFront(vector[offset .. oldLen], vector[oldLen .. length]);
|
||||||
|
return inserted;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Ditto.
|
||||||
|
size_t insertAfter(size_t R)(Range!T r, T[R] el)
|
||||||
|
{
|
||||||
|
return insertAfter!(T[])(r, el[]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Ditto.
|
||||||
|
size_t insertAfter(R)(Range!T r, auto ref R el)
|
||||||
|
if (isImplicitlyConvertible!(R, T))
|
||||||
|
in
|
||||||
|
{
|
||||||
|
assert(r.begin >= vector);
|
||||||
|
assert(r.end <= vector + length_);
|
||||||
|
}
|
||||||
|
body
|
||||||
|
{
|
||||||
|
immutable oldLen = length;
|
||||||
|
immutable offset = r.end - vector;
|
||||||
|
|
||||||
|
static if (__traits(isRef, el))
|
||||||
|
{
|
||||||
|
insertBack(el);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
moveBack(el);
|
||||||
|
}
|
||||||
|
bringToFront(vector[offset .. oldLen], vector[oldLen .. length_]);
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Ditto.
|
||||||
|
size_t insertBefore(R)(Range!T r, R el)
|
||||||
|
if (!isInfinite!R
|
||||||
|
&& isInputRange!R
|
||||||
|
&& isImplicitlyConvertible!(ElementType!R, T))
|
||||||
|
in
|
||||||
|
{
|
||||||
|
assert(r.begin >= vector);
|
||||||
|
assert(r.end <= vector + length_);
|
||||||
|
}
|
||||||
|
body
|
||||||
|
{
|
||||||
|
return insertAfter(Range!T(vector, r.begin), el);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Ditto.
|
||||||
|
size_t insertBefore(size_t R)(Range!T r, T[R] el)
|
||||||
|
{
|
||||||
|
return insertBefore!(T[])(r, el[]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Ditto.
|
||||||
|
size_t insertBefore(R)(Range!T r, auto ref R el)
|
||||||
|
if (isImplicitlyConvertible!(R, T))
|
||||||
|
in
|
||||||
|
{
|
||||||
|
assert(r.begin >= vector);
|
||||||
|
assert(r.end <= vector + length_);
|
||||||
|
}
|
||||||
|
body
|
||||||
|
{
|
||||||
|
immutable oldLen = length;
|
||||||
|
immutable offset = r.begin - vector;
|
||||||
|
|
||||||
|
static if (__traits(isRef, el))
|
||||||
|
{
|
||||||
|
insertBack(el);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
moveBack(el);
|
||||||
|
}
|
||||||
|
bringToFront(vector[offset .. oldLen], vector[oldLen .. length_]);
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
unittest
|
||||||
|
{
|
||||||
|
Vector!int v1;
|
||||||
|
v1.insertAfter(v1[], [2, 8]);
|
||||||
|
assert(v1[0] == 2);
|
||||||
|
assert(v1[1] == 8);
|
||||||
|
assert(v1.length == 2);
|
||||||
|
|
||||||
|
v1.insertAfter(v1[], [1, 2]);
|
||||||
|
assert(v1[0] == 2);
|
||||||
|
assert(v1[1] == 8);
|
||||||
|
assert(v1[2] == 1);
|
||||||
|
assert(v1[3] == 2);
|
||||||
|
assert(v1.length == 4);
|
||||||
|
|
||||||
|
v1.insertAfter(v1[0 .. 0], [1, 2]);
|
||||||
|
assert(v1[0] == 1);
|
||||||
|
assert(v1[1] == 2);
|
||||||
|
assert(v1[2] == 2);
|
||||||
|
assert(v1[3] == 8);
|
||||||
|
assert(v1[4] == 1);
|
||||||
|
assert(v1[5] == 2);
|
||||||
|
assert(v1.length == 6);
|
||||||
|
|
||||||
|
v1.insertAfter(v1[0 .. 4], 9);
|
||||||
|
assert(v1[0] == 1);
|
||||||
|
assert(v1[1] == 2);
|
||||||
|
assert(v1[2] == 2);
|
||||||
|
assert(v1[3] == 8);
|
||||||
|
assert(v1[4] == 9);
|
||||||
|
assert(v1[5] == 1);
|
||||||
|
assert(v1[6] == 2);
|
||||||
|
assert(v1.length == 7);
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
unittest
|
||||||
|
{
|
||||||
|
Vector!int v1;
|
||||||
|
v1.insertBefore(v1[], [2, 8]);
|
||||||
|
assert(v1[0] == 2);
|
||||||
|
assert(v1[1] == 8);
|
||||||
|
assert(v1.length == 2);
|
||||||
|
|
||||||
|
v1.insertBefore(v1[], [1, 2]);
|
||||||
|
assert(v1[0] == 1);
|
||||||
|
assert(v1[1] == 2);
|
||||||
|
assert(v1[2] == 2);
|
||||||
|
assert(v1[3] == 8);
|
||||||
|
assert(v1.length == 4);
|
||||||
|
|
||||||
|
v1.insertBefore(v1[0 .. 1], [1, 2]);
|
||||||
|
assert(v1[0] == 1);
|
||||||
|
assert(v1[1] == 2);
|
||||||
|
assert(v1[2] == 1);
|
||||||
|
assert(v1[3] == 2);
|
||||||
|
assert(v1[4] == 2);
|
||||||
|
assert(v1[5] == 8);
|
||||||
|
assert(v1.length == 6);
|
||||||
|
|
||||||
|
v1.insertBefore(v1[2 .. $], 9);
|
||||||
|
assert(v1[0] == 1);
|
||||||
|
assert(v1[1] == 2);
|
||||||
|
assert(v1[2] == 9);
|
||||||
|
assert(v1[3] == 1);
|
||||||
|
assert(v1[4] == 2);
|
||||||
|
assert(v1[5] == 2);
|
||||||
|
assert(v1[6] == 8);
|
||||||
|
assert(v1.length == 7);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Assigns a value to the element with the index $(D_PARAM pos).
|
* Assigns a value to the element with the index $(D_PARAM pos).
|
||||||
*
|
*
|
||||||
@ -841,13 +1010,13 @@ struct Vector(T)
|
|||||||
* Returns: Random access range that iterates over elements of the vector, in
|
* Returns: Random access range that iterates over elements of the vector, in
|
||||||
* forward order.
|
* forward order.
|
||||||
*/
|
*/
|
||||||
Range!T opIndex()
|
Range!T opIndex() @trusted
|
||||||
{
|
{
|
||||||
return typeof(return)(vector, vector + length_);
|
return typeof(return)(vector, vector + length_);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Ditto.
|
/// Ditto.
|
||||||
Range!(const T) opIndex() const
|
Range!(const T) opIndex() const @trusted
|
||||||
{
|
{
|
||||||
return typeof(return)(vector, vector + length_);
|
return typeof(return)(vector, vector + length_);
|
||||||
}
|
}
|
||||||
@ -874,15 +1043,15 @@ struct Vector(T)
|
|||||||
* Returns: $(D_KEYWORD true) if the vectors are equal, $(D_KEYWORD false)
|
* Returns: $(D_KEYWORD true) if the vectors are equal, $(D_KEYWORD false)
|
||||||
* otherwise.
|
* otherwise.
|
||||||
*/
|
*/
|
||||||
bool opEquals()(auto ref typeof(this) v)
|
bool opEquals()(auto ref typeof(this) v) @trusted
|
||||||
{
|
{
|
||||||
return equal(opIndex(), v[]);
|
return equal(vector[0 .. length_], v.vector[0 .. v.length_]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Ditto.
|
/// Ditto.
|
||||||
bool opEquals()(in auto ref typeof(this) v) const
|
bool opEquals()(in auto ref typeof(this) v) const @trusted
|
||||||
{
|
{
|
||||||
return equal(opIndex(), v[]);
|
return equal(vector[0 .. length_], v.vector[0 .. length_]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Ditto.
|
/// Ditto.
|
||||||
@ -1185,8 +1354,9 @@ struct Vector(T)
|
|||||||
* Precondition: $(D_INLINECODE i <= j && j <= length
|
* Precondition: $(D_INLINECODE i <= j && j <= length
|
||||||
* && value.length == j - i)
|
* && value.length == j - i)
|
||||||
*/
|
*/
|
||||||
Range!T opSliceAssign(R)(R value, in size_t i, in size_t j)
|
Range!T opSliceAssign(R)(R value, in size_t i, in size_t j) @trusted
|
||||||
if (!isInfinite!R && isInputRange!R
|
if (!isInfinite!R
|
||||||
|
&& isInputRange!R
|
||||||
&& isImplicitlyConvertible!(ElementType!R, T))
|
&& isImplicitlyConvertible!(ElementType!R, T))
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
@ -1196,7 +1366,7 @@ struct Vector(T)
|
|||||||
}
|
}
|
||||||
body
|
body
|
||||||
{
|
{
|
||||||
copy(value, opSlice(i, j));
|
copy(value, vector[i .. j]);
|
||||||
return opSlice(i, j);
|
return opSlice(i, j);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1207,7 +1377,7 @@ struct Vector(T)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Ditto.
|
/// Ditto.
|
||||||
Range!T opSliceAssign(ref T value, in size_t i, in size_t j)
|
Range!T opSliceAssign(ref T value, in size_t i, in size_t j) @trusted
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
assert(i <= j);
|
assert(i <= j);
|
||||||
@ -1215,7 +1385,7 @@ struct Vector(T)
|
|||||||
}
|
}
|
||||||
body
|
body
|
||||||
{
|
{
|
||||||
fill(opSlice(i, j), value);
|
fill(vector[i .. j], value);
|
||||||
return opSlice(i, j);
|
return opSlice(i, j);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1392,3 +1562,12 @@ unittest
|
|||||||
}
|
}
|
||||||
auto v = Vector!SWithDtor(); // Destructor can destroy empty vectors.
|
auto v = Vector!SWithDtor(); // Destructor can destroy empty vectors.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unittest
|
||||||
|
{
|
||||||
|
class A
|
||||||
|
{
|
||||||
|
}
|
||||||
|
A a1, a2;
|
||||||
|
auto v1 = Vector!A([a1, a2]);
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user