使い方
Unityで使う用の一時的な処理で使うリストを作ってみました.
初期化時に下のコードの様にstackalloc T[maxsize]で確保したスパンを渡します.
初期サイズがmaxsizeでサイズを拡張しない,本家Listのような動きを再現しました.
ListedSpan<T> list = new ListedSpan<T>(stackalloc T[maxsize]);
コード
using System;
public ref struct ListedSpan<T>
{
private int count;
private Span<T> sparray;
public int BufferCapacity => sparray.Length;
public int Count => count;
/// <summary>
/// = new ListedSpan<T>(stackalloc T[maxcount]);と使う
/// </summary>
public ListedSpan(in Span<T> stackalloced)
{
sparray = stackalloced;
count = 0;
}
public Span<T> AsSpan() => sparray.Slice(0, count);
public bool ContainsIndex(int i) => 0 <= i && i < count;
public void Clear() => count = 0;
public void Add(in T add)
{
if (BufferCapacity < count + 1) throw new IndexOutOfRangeException("確保バッファを超過");
sparray[count++] = add;
}
public void RemoveRange(int start, int range)
{
if (!ContainsIndex(start)) throw new IndexOutOfRangeException("削除開始インデックスがリスト外");
if (!ContainsIndex(start + range - 1)) throw new IndexOutOfRangeException("削除開始インデックスから指定範囲を行くとはみ出ます");
count -= range;
int backCount = BufferCapacity - start - range;
Span<T> copyFrom = sparray.Slice(start + range, backCount);// 削除範囲含まない後ろの全部
Span<T> copyTo = sparray.Slice(start, backCount);// 削除開始を含む後ろ
copyFrom.CopyTo(copyTo);
}
public void Insert(int index,in T insert)
{
int add = 1;
int newCount = count + add;
if (!ContainsIndex(index)) throw new IndexOutOfRangeException();
if (BufferCapacity < newCount) throw new IndexOutOfRangeException();
count = newCount;
int backCount = BufferCapacity - index - add;
Span<T> copyFrom = sparray.Slice(index, backCount);
Span<T> copyTo = sparray.Slice(index + add, backCount);
copyFrom.CopyTo(copyTo);
sparray[index] = insert;
}
public void Insert(int index, in T t0, in T t1, in T t2)
{
int add = 3;
int newCount = count + add;
if (!ContainsIndex(index)) throw new IndexOutOfRangeException();
if (BufferCapacity < newCount) throw new IndexOutOfRangeException();
count = newCount;
int backCount = BufferCapacity - index - add;
Span<T> copyFrom = sparray.Slice(index, backCount);
Span<T> copyTo = sparray.Slice(index + add, backCount);
copyFrom.CopyTo(copyTo);
sparray[index++] = t0;
sparray[index++] = t1;
sparray[index] = t2;
}
}