You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
320 lines
7.7 KiB
320 lines
7.7 KiB
using System; |
|
using System.Collections; |
|
using System.Collections.Generic; |
|
|
|
namespace AX.AudioSystem |
|
{ |
|
/// <summary> |
|
/// 构造一个暴露内部数组的 List。 |
|
/// </summary> |
|
internal class BetterList<T> |
|
{ |
|
private const int DefaultCapacity = 4; |
|
private const int MaxArrayLength = 0x7fefffff; |
|
|
|
private static readonly T[] emptyArray = new T[0]; |
|
|
|
private T[] items; |
|
private int size; |
|
|
|
public BetterList() |
|
{ |
|
items = emptyArray; |
|
} |
|
|
|
public BetterList(int capacity) |
|
{ |
|
if (capacity < 0) |
|
throw new ArgumentOutOfRangeException("capacity"); |
|
|
|
if (capacity == 0) |
|
items = emptyArray; |
|
else |
|
items = new T[capacity]; |
|
} |
|
|
|
public int Capacity |
|
{ |
|
get |
|
{ |
|
return items.Length; |
|
} |
|
set |
|
{ |
|
if (value < size) |
|
throw new ArgumentOutOfRangeException("capacity"); |
|
|
|
if (value != items.Length) |
|
{ |
|
if (value > 0) |
|
{ |
|
T[] newItems = new T[value]; |
|
|
|
if (size > 0) |
|
Array.Copy(items, 0, newItems, 0, size); |
|
|
|
items = newItems; |
|
} |
|
else |
|
items = emptyArray; |
|
} |
|
} |
|
} |
|
|
|
public int Count |
|
{ |
|
get { return size; } |
|
} |
|
|
|
public T this[int index] |
|
{ |
|
get |
|
{ |
|
if ((uint)index >= (uint)size) |
|
throw new ArgumentOutOfRangeException(); |
|
|
|
return items[index]; |
|
} |
|
|
|
set |
|
{ |
|
if ((uint)index >= (uint)size) |
|
throw new ArgumentOutOfRangeException(); |
|
|
|
items[index] = value; |
|
} |
|
} |
|
|
|
public void Add(T item) |
|
{ |
|
if (size == items.Length) |
|
EnsureCapacity(size + 1); |
|
|
|
items[size++] = item; |
|
} |
|
|
|
public void AddRange(IEnumerable<T> enumerable) |
|
{ |
|
if (enumerable == null) |
|
throw new ArgumentNullException("enumerable"); |
|
|
|
ICollection<T> collection = enumerable as ICollection<T>; |
|
|
|
if (collection != null) |
|
{ |
|
int count = collection.Count; |
|
|
|
if (count > 0) |
|
{ |
|
EnsureCapacity(size + count); |
|
|
|
collection.CopyTo(items, size); |
|
|
|
size += count; |
|
} |
|
} |
|
else |
|
{ |
|
foreach (var item in enumerable) |
|
Add(item); |
|
} |
|
} |
|
|
|
public void AddRange(T[] data, int offset, int count) |
|
{ |
|
if (data == null) |
|
throw new ArgumentNullException("data"); |
|
|
|
if (offset < 0) |
|
throw new ArgumentOutOfRangeException("offset"); |
|
|
|
if(count < 0) |
|
throw new ArgumentOutOfRangeException("count"); |
|
|
|
if (data.Length - offset < count) |
|
throw new ArgumentOutOfRangeException("data, offset, count"); |
|
|
|
if(count > 0) |
|
{ |
|
EnsureCapacity(size + count); |
|
|
|
Array.Copy(data, offset, items, size, count); |
|
|
|
size += count; |
|
} |
|
} |
|
|
|
public void AddRange(T[] data) |
|
{ |
|
AddRange(data, 0, data.Length); |
|
} |
|
|
|
public void Clear() |
|
{ |
|
if (size > 0) |
|
{ |
|
Array.Clear(items, 0, size); |
|
size = 0; |
|
} |
|
} |
|
|
|
public bool Contains(T item) |
|
{ |
|
if ((Object)item == null) |
|
{ |
|
for (int i = 0; i < size; i++) |
|
if ((Object)items[i] == null) |
|
return true; |
|
|
|
return false; |
|
} |
|
else |
|
{ |
|
EqualityComparer<T> comparer = EqualityComparer<T>.Default; |
|
|
|
for (int i = 0; i < size; i++) |
|
{ |
|
if (comparer.Equals(items[i], item)) |
|
return true; |
|
} |
|
|
|
return false; |
|
} |
|
} |
|
|
|
public void CopyTo(T[] array) |
|
{ |
|
CopyTo(array, 0); |
|
} |
|
|
|
public void CopyTo(int index, T[] array, int arrayIndex, int count) |
|
{ |
|
if (size - index < count) |
|
throw new ArgumentException(); |
|
|
|
Array.Copy(items, index, array, arrayIndex, count); |
|
} |
|
|
|
public void CopyTo(T[] array, int arrayIndex) |
|
{ |
|
Array.Copy(items, 0, array, arrayIndex, size); |
|
} |
|
|
|
|
|
private void EnsureCapacity(int min) |
|
{ |
|
if (items.Length < min) |
|
{ |
|
int newCapacity = items.Length == 0 ? DefaultCapacity : items.Length * 2; |
|
|
|
if ((uint)newCapacity > MaxArrayLength) |
|
newCapacity = MaxArrayLength; |
|
|
|
if (newCapacity < min) |
|
newCapacity = min; |
|
|
|
Capacity = newCapacity; |
|
} |
|
} |
|
|
|
|
|
public int IndexOf(T item) |
|
{ |
|
return Array.IndexOf(items, item, 0, size); |
|
} |
|
|
|
public int IndexOf(T item, int index) |
|
{ |
|
if (index > size) |
|
throw new ArgumentOutOfRangeException("index"); |
|
|
|
return Array.IndexOf(items, item, index, size - index); |
|
} |
|
|
|
public int IndexOf(T item, int index, int count) |
|
{ |
|
if (index > size) |
|
throw new ArgumentOutOfRangeException("index"); |
|
|
|
if (count < 0 || index > size - count) |
|
throw new ArgumentOutOfRangeException("count"); |
|
|
|
return Array.IndexOf(items, item, index, count); |
|
} |
|
|
|
public bool Remove(T item) |
|
{ |
|
int index = IndexOf(item); |
|
|
|
if (index >= 0) |
|
{ |
|
RemoveAt(index); |
|
return true; |
|
} |
|
|
|
return false; |
|
} |
|
|
|
public void RemoveAt(int index) |
|
{ |
|
if ((uint)index >= (uint)size) |
|
throw new ArgumentOutOfRangeException(); |
|
|
|
size--; |
|
|
|
if (index < size) |
|
{ |
|
Array.Copy(items, index + 1, items, index, size - index); |
|
} |
|
|
|
items[size] = default(T); |
|
} |
|
|
|
public void RemoveRange(int index, int count) |
|
{ |
|
if (index < 0) |
|
throw new ArgumentOutOfRangeException("index"); |
|
|
|
if (count < 0) |
|
throw new ArgumentOutOfRangeException("count"); |
|
|
|
if (size - index < count) |
|
throw new ArgumentOutOfRangeException(); |
|
|
|
if (count > 0) |
|
{ |
|
size -= count; |
|
|
|
if (index < size) |
|
Array.Copy(items, index + count, items, index, size - index); |
|
|
|
Array.Clear(items, size, count); |
|
} |
|
} |
|
|
|
public T[] ToArray() |
|
{ |
|
var array = new T[size]; |
|
|
|
CopyTo(array); |
|
|
|
return array; |
|
} |
|
|
|
/// <summary> |
|
/// 获得原始的数组。特别注意:不要对此数组进行操作。 |
|
/// </summary> |
|
public T[] GetBuffer() |
|
{ |
|
return items; |
|
} |
|
|
|
public void TrimExcess() |
|
{ |
|
int threshold = (int)(((double)items.Length) * 0.9); |
|
|
|
if (size < threshold) |
|
Capacity = size; |
|
} |
|
} |
|
} |