Skip to content

Instantly share code, notes, and snippets.

@JimBobSquarePants
Created February 13, 2018 13:57
Show Gist options
  • Save JimBobSquarePants/5f391ad0a9f617f6f76ad7c5e129255a to your computer and use it in GitHub Desktop.
Save JimBobSquarePants/5f391ad0a9f617f6f76ad7c5e129255a to your computer and use it in GitHub Desktop.
Attempt at a fast dense array.
/// <summary>
/// Represents a dense array of NxN dimensions.
/// </summary>
/// <typeparam name="T">The type of elements in the array.</typeparam>
public struct MatrixNxN<T>
{
/// <summary>
/// The 1D representation of the 2D array.
/// </summary>
public readonly T[] Data;
/// <summary>
/// Gets the width of the 2D array.
/// </summary>
public readonly int Width;
/// <summary>
/// Gets the height of the 2D array.
/// </summary>
public readonly int Height;
/// <summary>
/// Initializes a new instance of the <see cref="MatrixNxN{T}" /> struct.
/// </summary>
/// <param name="width">The width.</param>
/// <param name="height">The height.</param>
public MatrixNxN(int width, int height)
{
this.Height = height;
this.Width = width;
this.Data = new T[this.Width * this.Height];
}
/// <summary>
/// Initializes a new instance of the <see cref="MatrixNxN{T}"/> struct.
/// </summary>
/// <param name="data">The 2D array to provide access to.</param>
public MatrixNxN(T[,] data)
{
this.Height = data.GetLength(0);
this.Width = data.GetLength(1);
this.Data = new T[this.Width * this.Height];
for (int y = 0; y < this.Height; y++)
{
for (int x = 0; x < this.Width; x++)
{
this.Data[(y * this.Width) + x] = data[y, x];
}
}
}
/// <summary>
/// Gets or sets the item at the specified position.
/// </summary>
/// <param name="row">The row-coordinate of the item. Must be greater than or equal to zero and less than the height of the array.</param>
/// <param name="column">The column-coordinate of the item. Must be greater than or equal to zero and less than the width of the array.</param>
/// <returns>The <see typeparam="T"/> at the specified position.</returns>
public T this[int row, int column]
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get
{
this.CheckCoordinates(row, column);
return this.Data[(row * this.Width) + column];
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
set
{
this.CheckCoordinates(row, column);
this.Data[(row * this.Width) + column] = value;
}
}
/// <summary>
/// Performs an implicit conversion from a 2D array to a <see cref="MatrixNxN{T}" />.
/// </summary>
/// <param name="data">The source array.</param>
/// <returns>
/// The <see cref="MatrixNxN{T}"/> representation on the source data.
/// </returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static implicit operator MatrixNxN<T>(T[,] data)
{
return new MatrixNxN<T>(data);
}
/// <summary>
/// Checks the coordinates to ensure they are within bounds.
/// </summary>
/// <param name="row">The y-coordinate of the item. Must be greater than zero and smaller than the height of the array.</param>
/// <param name="column">The x-coordinate of the item. Must be greater than zero and smaller than the width of the array.</param>
/// <exception cref="ArgumentOutOfRangeException">
/// Thrown if the coordinates are not within the bounds of the array.
/// </exception>
[Conditional("DEBUG")]
private void CheckCoordinates(int row, int column)
{
if (row < 0 || row >= this.Height)
{
throw new ArgumentOutOfRangeException(nameof(row), row, $"{row} is outwith the array bounds.");
}
if (column < 0 || column >= this.Width)
{
throw new ArgumentOutOfRangeException(nameof(column), column, $"{column} is outwith the array bounds.");
}
}
/// <summary>
/// Checks the coordinates to ensure they are within bounds.
/// </summary>
/// <param name="row">The y-coordinate of the item. Must be greater than zero and smaller than the height of the array.</param>
/// <exception cref="ArgumentOutOfRangeException">
/// Thrown if the coordinates are not within the bounds of the image.
/// </exception>
[Conditional("DEBUG")]
private void CheckCoordinates(int row)
{
if (row < 0 || row >= this.Height)
{
throw new ArgumentOutOfRangeException(nameof(row), row, $"{row} is outwith the array bounds.");
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment