Skip to content

Commit a6678cf

Browse files
author
LoneWandererProductions
committed
Improve my unmanagedIntList
1 parent b1216d6 commit a6678cf

3 files changed

Lines changed: 38 additions & 23 deletions

File tree

189 Bytes
Loading
48 Bytes
Loading

ExtendedSystemObjects/UnmanagedIntList.cs

Lines changed: 38 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -164,10 +164,16 @@ public void RemoveAt(int index, int count = 1)
164164
}
165165
#endif
166166

167-
if (index + count < Length)
167+
int moveCount = Length - (index + count);
168+
if (moveCount > 0)
168169
{
169-
// Shift elements left by 'count' to fill the gap
170-
UnmanagedMemoryHelper.ShiftLeft(_ptr, index, count, Length);
170+
// Source: Elements after the deleted range
171+
ReadOnlySpan<int> source = new ReadOnlySpan<int>(_ptr + index + count, moveCount);
172+
// Destination: The start of the deleted range
173+
Span<int> destination = new Span<int>(_ptr + index, moveCount);
174+
175+
// This is a high-speed memmove equivalent
176+
source.CopyTo(destination);
171177
}
172178

173179
Length -= count;
@@ -237,10 +243,14 @@ public bool Remove(int value)
237243
/// <returns>A new <see cref="UnmanagedIntList" /> instance with the same values.</returns>
238244
public UnmanagedIntList Clone()
239245
{
246+
// Create the new list with enough capacity
240247
var clone = new UnmanagedIntList(Length);
241-
for (var i = 0; i < Length; i++)
248+
249+
if (Length > 0)
242250
{
243-
clone._ptr[i] = _ptr[i];
251+
// Source: Our current valid data (via the fixed AsSpan)
252+
// Destination: A new span wrapping the clone's raw pointer
253+
AsSpan().CopyTo(new Span<int>(clone._ptr, Length));
244254
}
245255

246256
clone.Length = Length;
@@ -348,33 +358,38 @@ public void InsertAt(int index, int value, int count = 1)
348358
throw new ArgumentOutOfRangeException(nameof(index));
349359
}
350360
#endif
351-
if (count <= 0)
352-
{
353-
return;
354-
}
361+
if (count <= 0) return;
355362

356363
EnsureCapacity(Length + count);
357364

358-
// Shift elements to the right
359-
UnmanagedMemoryHelper.ShiftRight(_ptr, index, count, Length, Capacity);
360-
361-
// Fill with value
362-
for (var i = 0; i < count; i++)
365+
int moveCount = Length - index;
366+
if (moveCount > 0)
363367
{
364-
_ptr[index + i] = value;
368+
// Source: Elements from index to the end
369+
ReadOnlySpan<int> source = new ReadOnlySpan<int>(_ptr + index, moveCount);
370+
// Destination: The new position after the gap
371+
Span<int> destination = new Span<int>(_ptr + index + count, moveCount);
372+
373+
source.CopyTo(destination);
365374
}
366375

376+
// High-performance fill
377+
new Span<int>(_ptr + index, count).Fill(value);
378+
367379
Length += count;
368380
}
369381

370382
/// <summary>
371-
/// Returns a span over the valid elements of the list.
372-
/// Allows fast, safe access to the underlying data.
383+
/// Returns a span over the valid elements of the list.
384+
/// Allows fast, safe access to the underlying data.
373385
/// </summary>
374-
/// <returns>A <see cref="Span{Int32}" /> representing the list's contents.</returns>
386+
/// <returns>A <see cref="Span{Int32}" /> representing the list's valid contents.</returns>
387+
[MethodImpl(MethodImplOptions.AggressiveInlining)]
375388
public Span<int> AsSpan()
376389
{
377-
return new Span<int>(_ptr, Capacity);
390+
// Fix: Use 'Length' instead of 'Capacity'
391+
// to prevent access to uninitialized memory.
392+
return new Span<int>(_ptr, Length);
378393
}
379394

380395
/// <summary>
@@ -384,12 +399,12 @@ public Span<int> AsSpan()
384399
public UnmanagedIntList Sorted()
385400
{
386401
var copy = new UnmanagedIntList(Length);
387-
for (var i = 0; i < Length; i++)
402+
if (Length > 0)
388403
{
389-
copy.Add(_ptr[i]);
404+
AsSpan().CopyTo(new Span<int>(copy._ptr, Length));
405+
copy.Length = Length; // Set length before sorting so AsSpan() works
406+
copy.Sort();
390407
}
391-
392-
copy.Sort(); // Uses internal AsSpan().Sort()
393408
return copy;
394409
}
395410

0 commit comments

Comments
 (0)