Represents a loose abstraction of an arraylist, wheres the buffer array is available for public access.
//The MIT License (MIT) //http://bornagain.codeplex.com/license using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace BornAgain.Engine.Core { /// <summary> /// Represents a loose abstraction of an arraylist, where /// the buffer array is available for public access. /// </summary> /// <typeparam name="T">The type of element.</typeparam> public class ArrayCollection<T> : IDisposable { public T this[int index] { get { return _array[index]; } } private T[] _array; /// <summary> /// Gets the array. /// </summary> public T[] Array { get { return _array; } } private int _currentCount; /// <summary> /// Gets the current amount of items in the array. /// </summary> public int CurrentCount { get { return _currentCount; } } /// <summary> /// Gets the total amount of items the array can /// currently hold. /// </summary> public int CurrentCapacity { get { return _array.Length; } } private bool _isFixed; /// <summary> /// Whether or not the array collection is fixed in length. /// </summary> public bool IsFixed { get { return _isFixed; } set { _isFixed = value; } } /// <summary> /// Creates a new instance of the <see cref="ArrayCollection"/> /// class with the specified starting capacity. /// </summary> /// <param name="count">The starting capacity.</param> public ArrayCollection(int count, bool isFixed) { if (count < 10) count = 10; _array = new T[count]; _isFixed = isFixed; } /// <summary> /// Creates a new instance of the <see cref="ArrayCollection"/> /// class with the specified starting capacity. The collection is /// fixed. /// </summary> /// <param name="count">The starting capacity.</param> public ArrayCollection(int count) : this(count, true) { } /// <summary> /// Adds an item to the array collection. /// </summary> /// <param name="value">The item to add.</param> public int Add(T value) { if (_currentCount == CurrentCapacity) { if (_isFixed) return -1; else Grow(); } _array[_currentCount] = value; return _currentCount++; } /// <summary> /// Clears the array collection. /// </summary> public void Clear() { _currentCount = 0; } /// <summary> /// Sets the array collection. /// </summary> /// <param name="offset">The position to start copying into.</param> /// <param name="value">The array to copy from.</param> /// <param name="start">The start index within <see cref="value"/>.</param> /// <param name="count">The amount of items to copy.</param> public void Set(int offset, T[] value, int start, int count) { // Preconditions. if (value == null) throw new ArgumentNullException("value"); if (start + count > value.Length) throw new ArgumentOutOfRangeException("start + count"); if (offset < 0) throw new ArgumentOutOfRangeException("offset"); // Ensure size. if (CurrentCapacity < offset + count) Resize(offset + count); // Set the current item. _currentCount = offset; // Add the item. for (int i = start; i < start + count; i++) { Add(value[i]); } } /// <summary> /// Resizes the array. /// </summary> /// <param name="count"></param> private void Resize(int count) { System.Array.Resize<T>(ref _array, count); } /// <summary> /// Grows the array by 10%. /// </summary> private void Grow() { Resize((int)(CurrentCapacity * 1.1f)); } #region Dispose /// <summary> /// Whether or not this object has been disposed. /// </summary> private bool _isDisposed; /// <summary> /// Finalizer. /// </summary> ~ArrayCollection() { Dispose(false); } /// <summary> /// Called when the object is being disposed. /// </summary> /// <param name="disposing">True if being called from <see cref="IDisposable.Dispose"/>, /// false if being called from the finalizer.</param> private void Dispose(bool disposing) { if (_isDisposed) return; _isDisposed = true; _array = new T[0]; } void IDisposable.Dispose() { Dispose(true); GC.SuppressFinalize(this); } #endregion } }