Skip to content

Commit 888a9d1

Browse files
Add some more stuff
1 parent 340c847 commit 888a9d1

4 files changed

Lines changed: 146 additions & 0 deletions

File tree

CommonExtendedObjectsTests/IntListTests.cs

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,87 @@ public void CapacityResizesCorrectly()
7979
Assert.AreEqual(999, list[999]);
8080
}
8181

82+
#if DEBUG
83+
/// <summary>
84+
/// Indexes the get out of bounds throws.
85+
/// </summary>
86+
[TestMethod]
87+
[ExpectedException(typeof(IndexOutOfRangeException))]
88+
public void IndexGetOutOfBoundsThrows()
89+
{
90+
using var list = new UnmanagedIntList(1);
91+
var _ = list[5];
92+
}
93+
94+
/// <summary>
95+
/// Indexes the set out of bounds throws.
96+
/// </summary>
97+
[TestMethod]
98+
[ExpectedException(typeof(IndexOutOfRangeException))]
99+
public void IndexSetOutOfBoundsThrows()
100+
{
101+
using var list = new UnmanagedIntList(1) {[3] = 99};
102+
}
103+
#endif
104+
105+
/// <summary>
106+
/// Removes at invalid index throws.
107+
/// </summary>
108+
[TestMethod]
109+
[ExpectedException(typeof(ArgumentOutOfRangeException))]
110+
public void RemoveAtInvalidIndexThrows()
111+
{
112+
using var list = new UnmanagedIntList(1) {1};
113+
list.RemoveAt(2);
114+
}
115+
116+
/// <summary>
117+
/// Inserts at adds elements correctly.
118+
/// </summary>
119+
[TestMethod]
120+
public void InsertAtAddsElementsCorrectly()
121+
{
122+
using var list = new UnmanagedIntList(2) {1, 2};
123+
list.InsertAt(1, 99); // Between 1 and 2
124+
125+
Assert.AreEqual(3, list.Length);
126+
Assert.AreEqual(1, list[0]);
127+
Assert.AreEqual(99, list[1]);
128+
Assert.AreEqual(2, list[2]);
129+
}
130+
131+
/// <summary>
132+
/// Inserts at with count adds multiple.
133+
/// </summary>
134+
[TestMethod]
135+
public void InsertAtWithCountAddsMultiple()
136+
{
137+
using var list = new UnmanagedIntList(2) {1, 2};
138+
list.InsertAt(1, 99, 2); // Insert 99 twice at index 1
139+
140+
Assert.AreEqual(4, list.Length);
141+
Assert.AreEqual(1, list[0]);
142+
Assert.AreEqual(99, list[1]);
143+
Assert.AreEqual(99, list[2]);
144+
Assert.AreEqual(2, list[3]);
145+
}
146+
147+
/// <summary>
148+
/// Disposes the state of the frees memory and invalidates.
149+
/// </summary>
150+
[TestMethod]
151+
public void DisposeFreesMemoryAndInvalidatesState()
152+
{
153+
var list = new UnmanagedIntList(2) { 1 };
154+
list.Dispose();
155+
156+
// Post-condition: buffer is cleared, pointers null, Length and Capacity are zero.
157+
// Behavior is undefined after Dispose. No exception is required.
158+
// Test only verifies internal reset, not enforcement.
159+
Assert.AreEqual(0, list.Length);
160+
Assert.AreEqual(0, list.Capacity);
161+
}
162+
82163
/// <summary>
83164
/// Performances the benchmark.
84165
/// </summary>
0 Bytes
Loading
0 Bytes
Loading

ExtendedSystemObjects/Helper/UnmanagedMemoryHelper.cs

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
* PROGRAMMER: Peter Geinitz (Wayfarer)
77
*/
88

9+
// ReSharper disable UnusedMember.Global
10+
911
using System;
1012
using System.Runtime.CompilerServices;
1113
using System.Runtime.InteropServices;
@@ -116,5 +118,68 @@ internal static unsafe void ShiftLeft<T>(T* ptr, int index, int count, int lengt
116118
elementsToShift * sizeof(T),
117119
elementsToShift * sizeof(T));
118120
}
121+
122+
/// <summary>
123+
/// Copies a block of unmanaged memory from source to destination.
124+
/// Similar to memcpy.
125+
/// </summary>
126+
[MethodImpl(MethodImplOptions.AggressiveInlining)]
127+
internal static unsafe void Copy<T>(T* source, T* destination, int count) where T : unmanaged
128+
{
129+
Buffer.MemoryCopy(source, destination, count * sizeof(T), count * sizeof(T));
130+
}
131+
132+
/// <summary>
133+
/// Allocates and clones a block of unmanaged memory from a given source.
134+
/// </summary>
135+
[MethodImpl(MethodImplOptions.AggressiveInlining)]
136+
internal static unsafe IntPtr Clone<T>(T* source, int count) where T : unmanaged
137+
{
138+
var size = sizeof(T) * count;
139+
var dest = Marshal.AllocHGlobal(size);
140+
Buffer.MemoryCopy(source, dest.ToPointer(), size, size);
141+
return dest;
142+
}
143+
144+
/// <summary>
145+
/// Fills a block of unmanaged memory with a given value.
146+
/// Equivalent to memset with a pattern.
147+
/// </summary>
148+
[MethodImpl(MethodImplOptions.AggressiveInlining)]
149+
internal static unsafe void Fill<T>(T* ptr, T value, int count) where T : unmanaged
150+
{
151+
for (int i = 0; i < count; i++)
152+
{
153+
ptr[i] = value;
154+
}
155+
}
156+
157+
/// <summary>
158+
/// Searches for the first occurrence of a value in unmanaged memory.
159+
/// </summary>
160+
[MethodImpl(MethodImplOptions.AggressiveInlining)]
161+
internal static unsafe int IndexOf<T>(T* ptr, T value, int length) where T : unmanaged, IEquatable<T>
162+
{
163+
for (int i = 0; i < length; i++)
164+
{
165+
if (ptr[i].Equals(value))
166+
return i;
167+
}
168+
169+
return -1;
170+
}
171+
172+
/// <summary>
173+
/// Swaps two elements in unmanaged memory.
174+
/// </summary>
175+
[MethodImpl(MethodImplOptions.AggressiveInlining)]
176+
internal static unsafe void Swap<T>(T* ptr, int indexA, int indexB) where T : unmanaged
177+
{
178+
if (indexA == indexB) return;
179+
180+
T temp = ptr[indexA];
181+
ptr[indexA] = ptr[indexB];
182+
ptr[indexB] = temp;
183+
}
119184
}
120185
}

0 commit comments

Comments
 (0)