@@ -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