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
}
}
Related examples in the same category