mirror of
https://github.com/dlang/phobos.git
synced 2025-04-28 22:21:09 +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.
|
Initializes all elements of `range` with their `.init` value.
|
||||||
Assumes that the elements of the range are uninitialized.
|
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:
|
Params:
|
||||||
range = An
|
range = An
|
||||||
$(REF_ALTTEXT input range, isInputRange, std,range,primitives)
|
$(REF_ALTTEXT input range, isInputRange, std,range,primitives)
|
||||||
|
@ -877,7 +880,8 @@ See_Also:
|
||||||
$(LREF uninitializedFill)
|
$(LREF uninitializedFill)
|
||||||
*/
|
*/
|
||||||
void initializeAll(Range)(Range range)
|
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 core.stdc.string : memset, memcpy;
|
||||||
import std.traits : hasElaborateAssign, isDynamicArray;
|
import std.traits : hasElaborateAssign, isDynamicArray;
|
||||||
|
@ -1037,6 +1041,18 @@ if (is(Range == char[]) || is(Range == wchar[]))
|
||||||
assert(xs[1].x == 3);
|
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
|
// move
|
||||||
/**
|
/**
|
||||||
Moves `source` into `target`, via a destructive copy when necessary.
|
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)
|
@property void length(size_t newLength)
|
||||||
{
|
{
|
||||||
import std.algorithm.mutation : initializeAll;
|
|
||||||
|
|
||||||
if (length >= newLength)
|
if (length >= newLength)
|
||||||
{
|
{
|
||||||
// shorten
|
// shorten
|
||||||
|
@ -440,10 +438,22 @@ if (!is(immutable T == immutable bool))
|
||||||
_payload = _payload.ptr[0 .. newLength];
|
_payload = _payload.ptr[0 .. newLength];
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
immutable startEmplace = length;
|
|
||||||
reserve(newLength);
|
static if (__traits(compiles, { static T _; }))
|
||||||
initializeAll(_payload.ptr[startEmplace .. newLength]);
|
{
|
||||||
_payload = _payload.ptr[0 .. newLength];
|
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
|
@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`
|
* 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
|
* 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:
|
* Complexity:
|
||||||
* Guaranteed $(BIGOH abs(length - newLength)) if `capacity >= newLength`.
|
* Guaranteed $(BIGOH abs(length - newLength)) if `capacity >= newLength`.
|
||||||
* If `capacity < newLength` the worst case is $(BIGOH newLength).
|
* If `capacity < newLength` the worst case is $(BIGOH newLength).
|
||||||
*
|
*
|
||||||
|
* Precondition: `__traits(compiles, { static T _; }) || newLength <= length`
|
||||||
|
*
|
||||||
* Postcondition: `length == newLength`
|
* Postcondition: `length == newLength`
|
||||||
*/
|
*/
|
||||||
@property void length(size_t 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]));
|
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
|
// Array!bool
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue