22 * COPYRIGHT: See COPYING in the top level directory
33 * PROJECT: ExtendedSystemObjects
44 * FILE: ExtendedSystemObjects/UnmanagedIntList.cs
5- * PURPOSE: A high-performance List implementation with reduced features. Limited to integer Values.
5+ * PURPOSE: Provides a high-performance list implementation for integer values using unmanaged memory.
6+ * Designed for scenarios requiring manual memory control.
7+ * Not inherently thread-safe.
68 * PROGRAMMER: Peter Geinitz (Wayfarer)
79 */
810
@@ -23,10 +25,17 @@ namespace ExtendedSystemObjects
2325{
2426 /// <inheritdoc cref="IUnmanagedArray" />
2527 /// <summary>
26- /// A high-performance list of integers backed by unmanaged memory.
27- /// Supports fast adding, popping, and random access with minimal overhead.
28- /// Designed for scenarios where manual memory management is needed.
28+ /// Represents a high-performance list of integers backed by unmanaged memory.
29+ /// Offers fast insertion, removal, and random access with minimal overhead.
30+ /// Useful for scenarios requiring fine-grained memory control, such as high-throughput data pipelines,
31+ /// interop with native code, or avoiding garbage collection in performance-critical paths.
32+ ///
33+ /// This class is not thread-safe. Consumers must implement external synchronization if needed.
2934 /// </summary>
35+ /// <remarks>
36+ /// Manual disposal is required via <see cref="Dispose"/> to avoid memory leaks.
37+ /// The internal buffer is allocated using <see cref="Marshal.AllocHGlobal"/> and must be explicitly freed.
38+ /// </remarks>
3039 /// <seealso cref="T:System.IDisposable" />
3140 [ DebuggerDisplay ( "{ToString()}" ) ]
3241 public sealed unsafe class UnmanagedIntList : IUnmanagedArray < int > , IEnumerable < int >
@@ -89,17 +98,19 @@ IEnumerator IEnumerable.GetEnumerator()
8998
9099 /// <inheritdoc />
91100 /// <summary>
92- /// Gets the number of elements contained in the <see cref="UnmanagedIntList" />.
101+ /// Gets the number of elements currently stored in the list <see cref="UnmanagedIntList" />.
93102 /// </summary>
94103 public int Length { get ; private set ; }
95104
96105 /// <inheritdoc />
97106 /// <summary>
98- /// Gets or sets the element at the specified index.
107+ /// Provides direct access to an element at the specified index.
99108 /// </summary>
100- /// <param name="i">The zero-based index of the element to get or set.</param>
101- /// <returns>The element at the specified index.</returns>
102- /// <exception cref="IndexOutOfRangeException">Thrown in debug builds if the index is out of bounds.</exception>
109+ /// <param name="i">Zero-based index of the element.</param>
110+ /// <returns>The value at the specified index.</returns>
111+ /// <exception cref="IndexOutOfRangeException">
112+ /// Thrown in debug builds if the index is out of bounds.
113+ /// </exception>
103114 public int this [ int i ]
104115 {
105116 get
@@ -126,11 +137,11 @@ public int this[int i]
126137
127138 /// <inheritdoc />
128139 /// <summary>
129- /// Removes at .
140+ /// Removes one or more elements starting at the specified index .
130141 /// </summary>
131- /// <param name="index">The index.</param>
132- /// <param name="count">The count we want to remove. Optional .</param>
133- /// <exception cref="System. ArgumentOutOfRangeException">index</exception>
142+ /// <param name="index">The starting index of the element(s) to remove .</param>
143+ /// <param name="count">The number of elements to remove. Default is 1 .</param>
144+ /// <exception cref="ArgumentOutOfRangeException">Thrown if index is invalid in debug mode. </exception>
134145 public void RemoveAt ( int index , int count = 1 )
135146 {
136147#if DEBUG
@@ -302,6 +313,18 @@ public Span<int> AsSpan()
302313 return new Span < int > ( _ptr , Capacity ) ;
303314 }
304315
316+ /// <summary>
317+ /// Returns a span representing a range of elements from the list.
318+ /// </summary>
319+ /// <value>
320+ /// The <see cref="Span{System.Int32}"/>.
321+ /// </value>
322+ /// <param name="range">The range of elements to include in the span.</param>
323+ /// <returns>
324+ /// A <see cref="Span{Int32}" /> over the specified range.
325+ /// </returns>
326+ public Span < int > this [ Range range ] => AsSpan ( ) [ range ] ;
327+
305328 /// <summary>
306329 /// Returns a new UnmanagedIntList that is a sorted copy of the current list.
307330 /// </summary>
@@ -318,6 +341,52 @@ public UnmanagedIntList Sorted()
318341 return copy ;
319342 }
320343
344+ /// <summary>
345+ /// Reduces the internal capacity to match the current number of elements,
346+ /// releasing any unused memory.
347+ /// </summary>
348+ public void TrimExcess ( )
349+ {
350+ if ( Length == Capacity ) return ;
351+
352+ _buffer = UnmanagedMemoryHelper . Reallocate < int > ( _buffer , Length ) ;
353+ _ptr = ( int * ) _buffer ;
354+ Capacity = Length ;
355+ }
356+
357+ /// <summary>
358+ /// Copies the list contents into a new managed array.
359+ /// </summary>
360+ /// <returns>A managed <see cref="int[]"/> containing the current elements.</returns>
361+ public int [ ] ToArray ( )
362+ {
363+ var result = new int [ Length ] ;
364+ CopyTo ( result ) ;
365+ return result ;
366+ }
367+
368+
369+ /// <summary>
370+ /// Copies to Array.
371+ /// </summary>
372+ /// <param name="array">The array.</param>
373+ /// <param name="arrayIndex">Index of the array.</param>
374+ /// <exception cref="System.ArgumentNullException">array</exception>
375+ /// <exception cref="System.ArgumentOutOfRangeException">arrayIndex</exception>
376+ public void CopyTo ( int [ ] array , int arrayIndex = 0 )
377+ {
378+ #if DEBUG
379+ if ( array == null ) throw new ArgumentNullException ( nameof ( array ) ) ;
380+ if ( arrayIndex < 0 || arrayIndex + Length > array . Length )
381+ throw new ArgumentOutOfRangeException ( nameof ( arrayIndex ) ) ;
382+ #endif
383+ for ( int i = 0 ; i < Length ; i ++ )
384+ {
385+ array [ arrayIndex + i ] = _ptr [ i ] ;
386+ }
387+ }
388+
389+
321390 /// <summary>
322391 /// Converts to string.
323392 /// </summary>
@@ -340,10 +409,25 @@ public override string ToString()
340409 return sb . ToString ( ) ;
341410 }
342411
412+ /// <summary>
413+ /// Copies to.
414+ /// </summary>
415+ /// <param name="target">The target.</param>
416+ /// <exception cref="System.ArgumentException">Target span too small</exception>
417+ public void CopyTo ( Span < int > target )
418+ {
419+ #if DEBUG
420+ if ( target . Length < Length )
421+ throw new ArgumentException ( "Target span too small" ) ;
422+ #endif
423+ AsSpan ( ) . Slice ( 0 , Length ) . CopyTo ( target ) ;
424+ }
343425
344426 /// <summary>
345- /// Finalizes an instance of the <see cref="UnmanagedIntList" /> class, releasing unmanaged resources.
427+ /// Releases the unmanaged resources used by the list.
428+ /// After disposal, the instance should not be used.
346429 /// </summary>
430+
347431 ~ UnmanagedIntList ( )
348432 {
349433 Dispose ( false ) ;
0 commit comments