mirror of
https://github.com/dlang/phobos.git
synced 2025-04-29 06:30:28 +03:00
Merge pull request #5294 from byebye/array_length_opt
std.container.Array - do not realloc if enough capacity merged-on-behalf-of: Jack Stouffer <jack@jackstouffer.com>
This commit is contained in:
commit
a7e2f340fa
1 changed files with 55 additions and 11 deletions
|
@ -305,16 +305,24 @@ if (!is(Unqual!T == bool))
|
|||
_payload = _payload.ptr[0 .. newLength];
|
||||
return;
|
||||
}
|
||||
// enlarge
|
||||
immutable startEmplace = length;
|
||||
import core.checkedint : mulu;
|
||||
bool overflow;
|
||||
const nbytes = mulu(newLength, T.sizeof, overflow);
|
||||
if (overflow) assert(0);
|
||||
_payload = (cast(T*) realloc(_payload.ptr,
|
||||
nbytes))[0 .. newLength];
|
||||
if (_capacity < newLength)
|
||||
{
|
||||
// enlarge
|
||||
import core.checkedint : mulu;
|
||||
|
||||
bool overflow;
|
||||
const nbytes = mulu(newLength, T.sizeof, overflow);
|
||||
if (overflow)
|
||||
assert(0);
|
||||
_payload = (cast(T*) realloc(_payload.ptr, nbytes))[0 .. newLength];
|
||||
_capacity = newLength;
|
||||
}
|
||||
else
|
||||
{
|
||||
_payload = _payload.ptr[0 .. newLength];
|
||||
}
|
||||
initializeAll(_payload.ptr[startEmplace .. newLength]);
|
||||
_capacity = newLength;
|
||||
}
|
||||
|
||||
@property size_t capacity() const
|
||||
|
@ -328,7 +336,8 @@ if (!is(Unqual!T == bool))
|
|||
import core.checkedint : mulu;
|
||||
bool overflow;
|
||||
const sz = mulu(elements, T.sizeof, overflow);
|
||||
if (overflow) assert(0);
|
||||
if (overflow)
|
||||
assert(0);
|
||||
static if (hasIndirections!T)
|
||||
{
|
||||
/* Because of the transactional nature of this
|
||||
|
@ -1052,13 +1061,46 @@ if (!is(Unqual!T == bool))
|
|||
|
||||
@system unittest
|
||||
{
|
||||
Array!int a;
|
||||
struct Dumb { int x = 5; }
|
||||
Array!Dumb a;
|
||||
a.length = 10;
|
||||
assert(a.length == 10);
|
||||
assert(a.capacity >= a.length);
|
||||
immutable cap = a.capacity;
|
||||
foreach (ref e; a)
|
||||
e.x = 10;
|
||||
a.length = 5;
|
||||
assert(a.length == 5);
|
||||
assert(a.capacity >= a.length);
|
||||
// do not realloc if length decreases
|
||||
assert(a.capacity == cap);
|
||||
foreach (ref e; a)
|
||||
assert(e.x == 10);
|
||||
|
||||
a.length = 8;
|
||||
assert(a.length == 8);
|
||||
// do not realloc if capacity sufficient
|
||||
assert(a.capacity == cap);
|
||||
assert(Dumb.init.x == 5);
|
||||
foreach (i; 0 .. 5)
|
||||
assert(a[i].x == 10);
|
||||
foreach (i; 5 .. a.length)
|
||||
assert(a[i].x == Dumb.init.x);
|
||||
|
||||
// realloc required, check if values properly copied
|
||||
a[] = Dumb(1);
|
||||
a.length = 20;
|
||||
assert(a.capacity >= 20);
|
||||
foreach (i; 0 .. 8)
|
||||
assert(a[i].x == 1);
|
||||
foreach (i; 8 .. a.length)
|
||||
assert(a[i].x == Dumb.init.x);
|
||||
|
||||
// check if overlapping elements properly initialized
|
||||
a.length = 1;
|
||||
a.length = 20;
|
||||
assert(a[0].x == 1);
|
||||
foreach (e; a[1 .. $])
|
||||
assert(e.x == Dumb.init.x);
|
||||
}
|
||||
|
||||
@system unittest
|
||||
|
@ -1742,6 +1784,8 @@ if (is(Unqual!T == bool))
|
|||
assert(a.capacity == 0);
|
||||
a.reserve(15657);
|
||||
assert(a.capacity >= 15657);
|
||||
a.reserve(100);
|
||||
assert(a.capacity >= 15657);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue