7
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

c#でヒープに乗らないリストっぽいものを作ってみた

Last updated at Posted at 2025-03-26

使い方

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;
    }
}
7
4
5

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?