append uninitialized elements to array

Steven Schveighoffer schveiguy at gmail.com
Tue Jul 31 12:26:25 UTC 2018


On 7/30/18 5:10 PM, Ali Çehreli wrote:
> On 07/30/2018 10:40 AM, realhet wrote:
>> Hello,
>>
>> I've already found out how to create an array with uninitialized 
>> elements, but what I'm looking for is a way to append 16 uninitialized 
>> ushorts to it and after I will it directly from 2 SSE registers.
>>
>> The approximate array length is known at the start so I could be able 
>> to do this by making an uninitializedArray and then doing the 
>> appending manually, but I wonder if there is a way to do this with 
>> array.reserve().
>>
>> Basically it would be a thing that when this special uninitialized 
>> append is happening and when the reserved array size is big enough, it 
>> only increments the internal array length effectively.
>>
>> Thanks
> 
> Knowing that the length of a slice is its first member:
> 
> void appendUninitialized(T)(ref T[] arr, size_t N = 1) {
>      arr.reserve(arr.length + N);
>      auto length_p = cast(size_t*)(&arr);
>      *length_p += N;

Instead of above 2 lines:

arr = arr.ptr[0 .. arr.length + N];

> }
> 
> unittest {
>      ushort[] arr;
>      arr.appendUninitialized(2);
>      assert(arr.length == 2);
>      arr[0] = 1;
>      arr[1] = 2;
>      assert(arr == [ 1, 2 ]);
> }
> 
> void main() {
>      int[] arr;
>      arr.appendUninitialized(100);
>      import std.stdio : writeln;
>      writeln(arr);
> }
> 
> Ali

While this may work, it's unsafe. reserve reserves the space, but does 
not adjust the allocated length. You have the potential for overwriting 
data if you do this. I wouldn't recommend this method, especially if you 
aren't sure of the source of array. The resulting array is also not 
going to be appendable (it will reallocate on next append, even using 
appendUninitialized).

-Steve


More information about the Digitalmars-d-learn mailing list