mirror of
https://github.com/dlang/phobos.git
synced 2025-04-27 21:51:40 +03:00
Fix Issue 22105 - std.container.array.Array.length setter creates values of init-less types
This commit is contained in:
parent
ef9ed4fa19
commit
dc697c8dd8
2 changed files with 55 additions and 8 deletions
|
@ -866,6 +866,9 @@ if (isInputRange!InputRange
|
|||
Initializes all elements of `range` with their `.init` value.
|
||||
Assumes that the elements of the range are uninitialized.
|
||||
|
||||
This function is unavailable if `T` is a `struct` and `T.this()` is annotated
|
||||
with `@disable`.
|
||||
|
||||
Params:
|
||||
range = An
|
||||
$(REF_ALTTEXT input range, isInputRange, std,range,primitives)
|
||||
|
@ -877,7 +880,8 @@ See_Also:
|
|||
$(LREF uninitializedFill)
|
||||
*/
|
||||
void initializeAll(Range)(Range range)
|
||||
if (isInputRange!Range && hasLvalueElements!Range && hasAssignableElements!Range)
|
||||
if (isInputRange!Range && hasLvalueElements!Range && hasAssignableElements!Range
|
||||
&& __traits(compiles, { static ElementType!Range _; }))
|
||||
{
|
||||
import core.stdc.string : memset, memcpy;
|
||||
import std.traits : hasElaborateAssign, isDynamicArray;
|
||||
|
@ -1037,6 +1041,18 @@ if (is(Range == char[]) || is(Range == wchar[]))
|
|||
assert(xs[1].x == 3);
|
||||
}
|
||||
|
||||
// https://issues.dlang.org/show_bug.cgi?id=22105
|
||||
@system unittest
|
||||
{
|
||||
struct NoDefaultCtor
|
||||
{
|
||||
@disable this();
|
||||
}
|
||||
|
||||
NoDefaultCtor[1] array = void;
|
||||
static assert(!__traits(compiles, array[].initializeAll));
|
||||
}
|
||||
|
||||
// move
|
||||
/**
|
||||
Moves `source` into `target`, via a destructive copy when necessary.
|
||||
|
|
|
@ -428,8 +428,6 @@ if (!is(immutable T == immutable bool))
|
|||
|
||||
@property void length(size_t newLength)
|
||||
{
|
||||
import std.algorithm.mutation : initializeAll;
|
||||
|
||||
if (length >= newLength)
|
||||
{
|
||||
// shorten
|
||||
|
@ -440,10 +438,22 @@ if (!is(immutable T == immutable bool))
|
|||
_payload = _payload.ptr[0 .. newLength];
|
||||
return;
|
||||
}
|
||||
immutable startEmplace = length;
|
||||
reserve(newLength);
|
||||
initializeAll(_payload.ptr[startEmplace .. newLength]);
|
||||
_payload = _payload.ptr[0 .. newLength];
|
||||
|
||||
static if (__traits(compiles, { static T _; }))
|
||||
{
|
||||
import std.algorithm.mutation : initializeAll;
|
||||
|
||||
immutable startEmplace = length;
|
||||
reserve(newLength);
|
||||
initializeAll(_payload.ptr[startEmplace .. newLength]);
|
||||
_payload = _payload.ptr[0 .. newLength];
|
||||
}
|
||||
else
|
||||
{
|
||||
assert(0, "Cannot add elements to array because `" ~
|
||||
fullyQualifiedName!T ~ ".this()` is annotated with " ~
|
||||
"`@disable`.");
|
||||
}
|
||||
}
|
||||
|
||||
@property size_t capacity() const
|
||||
|
@ -901,12 +911,16 @@ if (!is(immutable T == immutable bool))
|
|||
/**
|
||||
* Sets the number of elements in the array to `newLength`. If `newLength`
|
||||
* is greater than `length`, the new elements are added to the end of the
|
||||
* array and initialized with `T.init`.
|
||||
* array and initialized with `T.init`. If `T` is a `struct` whose default
|
||||
* constructor is annotated with `@disable`, `newLength` must be lower than
|
||||
* or equal to `length`.
|
||||
*
|
||||
* Complexity:
|
||||
* Guaranteed $(BIGOH abs(length - newLength)) if `capacity >= newLength`.
|
||||
* If `capacity < newLength` the worst case is $(BIGOH newLength).
|
||||
*
|
||||
* Precondition: `__traits(compiles, { static T _; }) || newLength <= length`
|
||||
*
|
||||
* Postcondition: `length == newLength`
|
||||
*/
|
||||
@property void length(size_t newLength)
|
||||
|
@ -1708,6 +1722,23 @@ if (!is(immutable T == immutable bool))
|
|||
assert(equal(a[], [1,2,3,4,5,6,7,8]));
|
||||
}
|
||||
|
||||
// https://issues.dlang.org/show_bug.cgi?id=22105
|
||||
@system unittest
|
||||
{
|
||||
import core.exception : AssertError;
|
||||
import std.exception : assertThrown, assertNotThrown;
|
||||
|
||||
struct NoDefaultCtor
|
||||
{
|
||||
int i;
|
||||
@disable this();
|
||||
this(int j) { i = j; }
|
||||
}
|
||||
|
||||
auto array = Array!NoDefaultCtor([NoDefaultCtor(1), NoDefaultCtor(2)]);
|
||||
assertNotThrown!AssertError(array.length = 1);
|
||||
assertThrown!AssertError(array.length = 5);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Array!bool
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue