www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - append uninitialized elements to array

reply realhet <real_het hotmail.com> writes:
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
Jul 30 2018
next sibling parent Steven Schveighoffer <schveiguy gmail.com> writes:
On 7/30/18 1:40 PM, 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.
 
There isn't an official way to do this. The function that extends the array always initializes. It's something that could potentially be an addition to druntime. -Steve
Jul 30 2018
prev sibling parent reply =?UTF-8?Q?Ali_=c3=87ehreli?= <acehreli yahoo.com> writes:
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; } 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
Jul 30 2018
next sibling parent realhet <real_het hotmail.com> writes:
Thank You!
Jul 31 2018
prev sibling parent Steven Schveighoffer <schveiguy gmail.com> writes:
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
Jul 31 2018