1
0
Fork 0
mirror of https://github.com/beefytech/Beef.git synced 2025-06-17 07:44:09 +02:00

Initial checkin

This commit is contained in:
Brian Fiete 2019-08-23 11:56:54 -07:00
parent c74712dad9
commit 078564ac9e
3242 changed files with 1616395 additions and 0 deletions

View file

@ -0,0 +1,651 @@
// This file contains portions of code released by Microsoft under the MIT license as part
// of an open-sourcing initiative in 2014 of the C# core libraries.
// The original source was submitted to https://github.com/Microsoft/referencesource
#if PARANOID
#define VERSION_LIST
#endif
using System;
using System.Runtime;
using System.Diagnostics;
using System.Diagnostics.Contracts;
using System.Threading;
using System.Reflection;
namespace System.Collections.Generic
{
interface IList
{
Variant this[int index]
{
get;
set;
}
}
public class List<T> : IEnumerable<T>, IList
{
private const int_cosize cDefaultCapacity = 4;
const int_cosize SizeFlags = 0x7FFFFFFF;
const int_cosize DynAllocFlag = (int_cosize)0x80000000;
#if BF_ENABLE_REALTIME_LEAK_CHECK
static DbgRawAllocData sRawAllocData;
public static this()
{
sRawAllocData.mMarkFunc = null;
sRawAllocData.mMaxStackTrace = 1;
sRawAllocData.mType = typeof(T);
}
#endif
private T* mItems;
private int_cosize mSize;
private int_cosize mAllocSizeAndFlags;
#if VERSION_LIST
private int32 mVersion;
const String cVersionError = "List changed during enumeration";
#endif
public int AllocSize
{
[Inline]
get
{
return mAllocSizeAndFlags & SizeFlags;
}
}
public bool IsDynAlloc
{
[Inline]
get
{
return (mAllocSizeAndFlags & DynAllocFlag) != 0;
}
}
public this()
{
if (((int)Internal.UnsafeCastToPtr(this) & 0xFFFF) == 0x4BA0)
{
NOP!();
}
}
public this(IEnumerator<T> enumerator)
{
for (var item in enumerator)
Add(item);
}
[AllowAppend]
public this(int capacity)
{
Debug.Assert((uint)capacity <= (uint)SizeFlags);
T* items = append T[capacity]*;
if (capacity > 0)
{
mItems = items;
mAllocSizeAndFlags = (int_cosize)(capacity & SizeFlags);
}
}
/*public this(int capacity)
{
Debug.Assert((uint)capacity <= (uint)SizeFlags);
if (capacity > 0)
{
mItems = Alloc(capacity);
mAllocSizeAndFlags = (int_cosize)(capacity | DynAllocFlag);
}
}*/
public ~this()
{
#if DBG
int typeId = typeof(T).GetTypeId();
if (typeId == sDebugTypeId)
{
Debug.WriteLine("Dealloc {0} {1}", scope Object[] { this, mItems } );
}
#endif
if (IsDynAlloc)
Free(mItems);
}
public T* Ptr
{
get
{
return mItems;
}
}
#if DBG
static int_cosize sDebugTypeId = 470;
static int_cosize sDebugIdx = 0;
#endif
public int Capacity
{
get
{
return mAllocSizeAndFlags & SizeFlags;
}
set
{
Debug.Assert((uint)value <= (uint)SizeFlags);
if (value != AllocSize)
{
if (value > 0)
{
T* newItems = Alloc(value);
#if DBG
int typeId = typeof(T).GetTypeId();
if (typeId == sDebugTypeId)
{
Debug.WriteLine("Alloc {0} {1} {2}", scope Object[] { this, newItems, sDebugIdx } );
sDebugIdx++;
}
#endif
if (mSize > 0)
Internal.MemCpy(newItems, mItems, mSize * strideof(T), alignof(T));
if (IsDynAlloc)
Free(mItems);
mItems = newItems;
mAllocSizeAndFlags = (.)(value | DynAllocFlag);
}
else
{
if (IsDynAlloc)
Free(mItems);
mItems = null;
mAllocSizeAndFlags = 0;
}
}
}
}
public int Count
{
get
{
return mSize;
}
}
public bool IsEmpty
{
get
{
return mSize == 0;
}
}
public ref T this[int index]
{
[Checked]
get
{
Debug.Assert((uint)index < (uint)mSize);
return ref mItems[index];
}
[Checked]
set
{
Debug.Assert((uint)index < (uint)mSize);
mItems[index] = value;
#if VERSION_LIST
mVersion++;
#endif
}
}
public ref T this[int index]
{
[Unchecked, Inline]
get
{
return ref mItems[index];
}
[Unchecked, Inline]
set
{
mItems[index] = value;
#if VERSION_LIST
mVersion++;
#endif
}
}
public ref T Back
{
get
{
Debug.Assert(mSize != 0);
return ref mItems[mSize - 1];
}
}
Variant IList.this[int index]
{
get
{
return [Unbound]Variant.Create(this[index]);
}
set
{
ThrowUnimplemented();
}
}
protected T* Alloc(int size)
{
#if BF_ENABLE_REALTIME_LEAK_CHECK
// We don't want to use the default mark function because it will mark the entire array,
// whereas we have a custom marking routine because we only want to mark up to mSize
return (T*)Internal.Dbg_RawAlloc(size * strideof(T), &sRawAllocData);
#else
return new T[size]*(?);
#endif
}
protected void Free(T* val)
{
delete val;
}
/*protected T[] Alloc(int size)
{
return new:this T[size];
}
protected void Free(Object obj)
{
delete:this obj;
}
protected virtual Object AllocObject(TypeInstance type, int size)
{
return Internal.ObjectAlloc(type, size);
}
protected virtual void FreeObject(Object obj)
{
delete obj;
}*/
/// Adds an item to the back of the list.
public void Add(T item)
{
if (((int)Internal.UnsafeCastToPtr(this) & 0xFFFF) == 0x4BA0)
{
NOP!();
}
if (mSize == AllocSize) EnsureCapacity(mSize + 1);
mItems[mSize++] = item;
#if VERSION_LIST
mVersion++;
#endif
}
/// Returns a pointer to the start of the added uninitialized section
public T* GrowUnitialized(int addSize)
{
if (mSize + addSize > AllocSize) EnsureCapacity(mSize + addSize);
mSize += (int_cosize)addSize;
#if VERSION_LIST
mVersion++;
#endif
if (addSize == 0)
return null;
return &mItems[mSize - addSize];
}
public void Clear()
{
if (mSize > 0)
{
mSize = 0;
}
#if VERSION_LIST
mVersion++;
#endif
}
/*public static void DeleteItemsAndClear<T>(List<T> list) where T : delete
{
foreach (var item in list)
delete item;
list.Clear();
}*/
public bool Contains(T item)
{
if (item == null)
{
for (int i = 0; i < mSize; i++)
if (mItems[i] == null)
return true;
return false;
}
else
{
for (int i = 0; i < mSize; i++)
if (mItems[i] == item)
return true;
return false;
}
}
public void CopyTo(T[] array)
{
CopyTo(array, 0);
}
public void CopyTo(List<T> destList)
{
destList.EnsureCapacity(mSize);
destList.mSize = mSize;
if (mSize > 0)
Internal.MemCpy(destList.mItems, mItems, mSize * strideof(T), alignof(T));
}
public void CopyTo(T[] array, int arrayIndex)
{
// Delegate rest of error checking to Array.Copy.
for (int_cosize i = 0; i < mSize; i++)
array[i + arrayIndex] = mItems[i];
}
public void EnsureCapacity(int min)
{
int allocSize = AllocSize;
if (allocSize < min)
{
int_cosize newCapacity = (int_cosize)(allocSize == 0 ? cDefaultCapacity : allocSize * 2);
// Allow the list to grow to maximum possible capacity (~2G elements) before encountering overflow.
// Note that this check works even when mItems.Length overflowed thanks to the (uint) cast
//if ((uint)newCapacity > Array.MaxArrayLength) newCapacity = Array.MaxArrayLength;
if (newCapacity < min) newCapacity = (int_cosize)min;
Capacity = newCapacity;
}
}
public void Reserve(int size)
{
EnsureCapacity(size);
}
public Enumerator GetEnumerator()
{
return Enumerator(this);
}
public int_cosize IndexOf(T item)
{
//return Array.IndexOf(mItems, item, 0, mSize);
for (int i = 0; i < mSize; i++)
if (mItems[i] == item)
return (int_cosize)i;
return -1;
}
public int_cosize IndexOf(T item, int index)
{
for (int i = index; i < mSize; i++)
if (mItems[i] == item)
return (int_cosize)i;
return -1;
}
public int_cosize IndexOf(T item, int index, int count)
{
for (int i = index; i < index + count; i++)
if (mItems[i] == item)
return (int_cosize)i;
return -1;
}
public void Insert(int index, T item)
{
if (mSize == AllocSize) EnsureCapacity(mSize + 1);
if (index < mSize)
{
Internal.MemCpy(mItems + index + 1, mItems + index, (mSize - index) * strideof(T), alignof(T));
}
mItems[index] = item;
mSize++;
#if VERSION_LIST
mVersion++;
#endif
}
public void RemoveAt(int index)
{
if (((int)Internal.UnsafeCastToPtr(this) & 0xFFFF) == 0x4BA0)
{
NOP!();
}
Debug.Assert((uint)index < (uint)mSize);
if (index < mSize - 1)
{
Internal.MemCpy(mItems + index, mItems + index + 1, (mSize - index - 1) * strideof(T), alignof(T));
}
mSize--;
#if VERSION_LIST
mVersion++;
#endif
}
public void RemoveRange(int index, int count)
{
Debug.Assert((uint)index + (uint)count <= (uint)mSize);
if (index + count < mSize - 1)
{
for (int i = index; i < mSize - count; i++)
mItems[i] = mItems[i + count];
}
mSize -= (.)count;
#if VERSION_LIST
mVersion++;
#endif
}
public void RemoveAtFast(int index)
{
Debug.Assert((uint32)index < (uint32)mSize);
mSize--;
if (mSize > 0)
mItems[index] = mItems[mSize];
#if VERSION_LIST
mVersion++;
#endif
}
public void Sort(Comparison<T> comp)
{
var sorter = Sorter<T, void>(mItems, null, mSize, comp);
sorter.Sort(0, mSize);
}
public T PopBack()
{
T backVal = mItems[mSize - 1];
mSize--;
return backVal;
}
public T PopFront()
{
T backVal = mItems[0];
RemoveAt(0);
return backVal;
}
public bool Remove(T item)
{
int_cosize index = IndexOf(item);
if (index >= 0)
{
RemoveAt(index);
return true;
}
return false;
}
public static operator Span<T>(List<T> list)
{
return Span<T>(list.mItems, list.mSize);
}
protected override void GCMarkMembers()
{
for (int i < mSize)
{
GC.Mark_Unbound(mItems[i]);
}
}
public struct Enumerator : IRefEnumerator<T>
{
private List<T> mList;
private int mIndex;
#if VERSION_LIST
private int32 mVersion;
#endif
private T* mCurrent;
internal this(List<T> list)
{
mList = list;
mIndex = 0;
#if VERSION_LIST
mVersion = list.mVersion;
#endif
mCurrent = null;
}
#if VERSION_LIST
void CheckVersion()
{
if (mVersion != mList.mVersion)
Runtime.FatalError(cVersionError);
}
#endif
public void Dispose()
{
}
public bool MoveNext() mut
{
List<T> localList = mList;
if ((uint(mIndex) < uint(localList.mSize)))
{
mCurrent = &localList.mItems[mIndex];
mIndex++;
return true;
}
return MoveNextRare();
}
private bool MoveNextRare() mut
{
#if VERSION_LIST
CheckVersion();
#endif
mIndex = mList.mSize + 1;
mCurrent = null;
return false;
}
public T Current
{
get
{
return *mCurrent;
}
}
public ref T CurrentRef
{
get
{
return ref *mCurrent;
}
}
public int Index
{
get
{
return mIndex - 1;
}
}
public int Count
{
get
{
return mList.Count;
}
}
public void Remove() mut
{
int curIdx = mIndex - 1;
mList.RemoveAt(curIdx);
#if VERSION_LIST
mVersion = mList.mVersion;
#endif
mIndex = curIdx;
}
public void RemoveFast() mut
{
int curIdx = mIndex - 1;
int lastIdx = mList.Count - 1;
if (curIdx < lastIdx)
mList[curIdx] = mList[lastIdx];
mList.RemoveAt(lastIdx);
#if VERSION_LIST
mVersion = mList.mVersion;
#endif
mIndex = curIdx;
}
public void Reset() mut
{
mIndex = 0;
mCurrent = null;
}
public Result<T> GetNext() mut
{
if (!MoveNext())
return .Err;
return Current;
}
public Result<T*> GetNextRef() mut
{
if (!MoveNext())
return .Err;
return &CurrentRef;
}
}
}
}

View file

@ -0,0 +1,302 @@
// This file contains portions of code released by Microsoft under the MIT license as part
// of an open-sourcing initiative in 2014 of the C# core libraries.
// The original source was submitted to https://github.com/Microsoft/referencesource
namespace System.Collections.Generic
{
struct Sorter<T, T2>
{
// This is the threshold where Introspective sort switches to Insertion sort.
// Empirically, 16 seems to speed up most cases without slowing down others, at least for integers.
// Large value types may benefit from a smaller number.
const int IntrosortSizeThreshold = 16;
private T* keys;
private T2* items;
private int mCount;
private Comparison<T> comparer;
internal this(T* keys, T2* items, int count, Comparison<T> comparer)
{
this.keys = keys;
this.items = items;
mCount = count;
this.comparer = comparer;
}
internal static int FloorLog2(int n)
{
int result = 0;
int val = n;
while (val >= 1)
{
result++;
val = val / 2;
}
return result;
}
private static int GetMedian(int low, int hi)
{
// Note both may be negative, if we are dealing with arrays w/ negative lower bounds.
//Contract.Requires(low <= hi);
//Contract.Assert( hi - low >= 0, "Length overflow!");
return low + ((hi - low) >> 1);
}
internal void SwapIfGreaterWithItems(int a, int b)
{
if (a != b)
{
if (comparer(keys[a], keys[b]) > 0)
{
T temp = keys[a];
keys[a] = keys[b];
keys[b] = temp;
if ((items != null) && (sizeof(T2) != 0))
{
T2 item = items[a];
items[a] = items[b];
items[b] = item;
}
}
}
}
private void Swap(int i, int j)
{
T t = keys[i];
keys[i] = keys[j];
keys[j] = t;
if (items != null)
{
T2 item = items[i];
items[i] = items[j];
items[j] = item;
}
}
internal void Sort(int left, int length)
{
IntrospectiveSort(left, length);
}
private void DepthLimitedQuickSort(int left, int right, int depthLimit)
{
// Can use the much faster jit helpers for array access.
repeat
{
if (depthLimit == 0)
{
Heapsort(left, right);
return;
}
int curLeft = left;
int curRight = right;
int curDepthLimit = depthLimit;
int i = curLeft;
int j = curRight;
// pre-sort the low, middle (pivot), and high values in place.
// this improves performance in the face of already sorted data, or
// data that is made up of multiple sorted runs appended together.
int middle = GetMedian(i, j);
SwapIfGreaterWithItems(i, middle); // swap the low with the mid point
SwapIfGreaterWithItems(i, j); // swap the low with the high
SwapIfGreaterWithItems(middle, j); // swap the middle with the high
T x = keys[middle];
repeat
{
while (comparer(keys[i], x) < 0) i++;
while (comparer(x, keys[j]) < 0) j--;
//Contract.Assert(i >= left && j <= right, "(i>=left && j<=right) Sort failed - Is your IComparer bogus?");
if (i > j) break;
if (i < j)
{
T key = keys[i];
keys[i] = keys[j];
keys[j] = key;
if (items != null)
{
T2 item = items[i];
items[i] = items[j];
items[j] = item;
}
}
i++;
j--;
} while (i <= j);
// The next iteration of the while loop is to "recursively" sort the larger half of the array and the
// following calls recrusively sort the smaller half. So we subtrack one from depthLimit here so
// both sorts see the new value.
curDepthLimit--;
if (j - curLeft <= curRight - i)
{
if (curLeft < j) DepthLimitedQuickSort(curLeft, j, curDepthLimit);
curLeft = i;
}
else
{
if (i < curRight) DepthLimitedQuickSort(i, curRight, curDepthLimit);
curRight = j;
}
} while (left < right);
}
private void IntrospectiveSort(int left, int length)
{
if (length < 2)
return;
IntroSort(left, length + left - 1, 2 * FloorLog2(mCount));
}
private void IntroSort(int lo, int hi, int depthLimit)
{
int curHi = hi;
int curDepthLimit = depthLimit;
while (curHi > lo)
{
int partitionSize = curHi - lo + 1;
if (partitionSize <= IntrosortSizeThreshold)
{
if (partitionSize == 1)
{
return;
}
if (partitionSize == 2)
{
SwapIfGreaterWithItems(lo, curHi);
return;
}
if (partitionSize == 3)
{
SwapIfGreaterWithItems(lo, curHi-1);
SwapIfGreaterWithItems(lo, curHi);
SwapIfGreaterWithItems(curHi-1, curHi);
return;
}
InsertionSort(lo, curHi);
return;
}
if (curDepthLimit == 0)
{
Heapsort(lo, curHi);
return;
}
curDepthLimit--;
int p = PickPivotAndPartition(lo, curHi);
IntroSort(p + 1, curHi, curDepthLimit);
curHi = p - 1;
}
}
private int PickPivotAndPartition(int lo, int hi)
{
// Compute median-of-three. But also partition them, since we've done the comparison.
int mid = lo + (hi - lo) / 2;
// Sort lo, mid and hi appropriately, then pick mid as the pivot.
SwapIfGreaterWithItems(lo, mid);
SwapIfGreaterWithItems(lo, hi);
SwapIfGreaterWithItems(mid, hi);
T pivot = keys[mid];
Swap(mid, hi - 1);
int left = lo, right = hi - 1; // We already partitioned lo and hi and put the pivot in hi - 1. And we pre-increment & decrement below.
while (left < right)
{
while (comparer(keys[++left], pivot) < 0) {}
while (comparer(pivot, keys[--right]) < 0) {}
if(left >= right)
break;
Swap(left, right);
}
// Put pivot in the right location.
Swap(left, (hi - 1));
return left;
}
private void Heapsort(int lo, int hi)
{
int n = hi - lo + 1;
for (int i = n / 2; i >= 1; i = i - 1)
{
DownHeap(i, n, lo);
}
for (int i = n; i > 1; i = i - 1)
{
Swap(lo, lo + i - 1);
DownHeap(1, i - 1, lo);
}
}
private void DownHeap(int i, int n, int lo)
{
int curI = i;
T d = keys[lo + curI - 1];
//T dt = (items != null) ? items[lo + i - 1] : null;
T2* dt = (items != null) ? &items[lo + curI - 1] : null;
int child;
while (curI <= n / 2)
{
child = 2 * curI;
if (child < n && comparer(keys[lo + child - 1], keys[lo + child]) < 0)
{
child++;
}
if (!(comparer(d, keys[lo + child - 1]) < 0))
break;
keys[lo + curI - 1] = keys[lo + child - 1];
if(items != null)
items[lo + curI - 1] = items[lo + child - 1];
curI = child;
}
keys[lo + curI - 1] = d;
if (items != null)
items[lo + curI - 1] = *dt;
}
private void InsertionSort(int lo, int hi)
{
int i, j;
T t;
T2* ti = null;
for (i = lo; i < hi; i++)
{
j = i;
t = keys[i + 1];
//ti = (items != null) ? items[i + 1] : null;
if (items != null)
ti = &items[i + 1];
while (j >= lo && comparer(t, keys[j]) < 0)
{
keys[j + 1] = keys[j];
if(items != null)
items[j + 1] = items[j];
j--;
}
keys[j + 1] = t;
if (items != null)
items[j + 1] = *ti;
}
}
}
}

View file

@ -0,0 +1,36 @@
using System;
using System.Runtime.InteropServices;
namespace System.Collections
{
interface IEnumerator
{
Object Current { get; }
bool MoveNext();
void Reset();
void Dispose();
}
interface IEnumerable
{
IEnumerator GetEnumerator();
}
}
namespace System.Collections.Generic
{
interface IEnumerator<T>
{
Result<T> GetNext() mut;
}
interface IRefEnumerator<T> : IEnumerator<T>
{
Result<T*> GetNextRef() mut;
}
concrete interface IEnumerable<T>
{
concrete IEnumerator<T> GetEnumerator();
}
}