Code/Extensions/IListExtensions.cs
namespace Nodebox.Extensions;

public static class IListExtensions {
    extension<T>(IList<T> list) {
        public void Resize(int size) {
            Resize(list, size, (_) => default);
        }

        public void Resize(int size, Func<int, T> generator, Action<int, T> destructor = null) {
            ArgumentNullException.ThrowIfNull(list);
            ArgumentOutOfRangeException.ThrowIfNegative(size);

            if (list.Count == size) {
                return;
            }

            if (size > list.Count) {
                if (list is List<T> genericList) {
                    genericList.AddRange(Enumerable.Range(0, size - list.Count).Select(generator));
                } else {
                    while (list.Count < size) {
                        list.Add(generator(list.Count));
                    }
                }
            } else {
                if (list is List<T> genericList) {
                    if (destructor != null) {
                        foreach (var i in Enumerable.Range(size, list.Count - size)) {
                            destructor(i, genericList[i]);
                        }
                    }
                    genericList.RemoveRange(size, list.Count - size);
                } else {
                    while (list.Count > size) {
                        destructor(list.Count - 1, list[list.Count - 1]);
                        list.RemoveAt(list.Count - 1);
                    }
                }
            }
        }
    }
}