📷 A modern, cross-platform, 2D Graphics library for .NET
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

120 lines
3.7 KiB

// Copyright (c) Six Labors and contributors.
// Licensed under the Apache License, Version 2.0.
using System;
using SixLabors.ImageSharp.Memory;
namespace SixLabors.ImageSharp.Tests.Memory.DiscontiguousBuffers
{
public struct MemoryGroupIndex : IEquatable<MemoryGroupIndex>
{
public override bool Equals(object obj) => obj is MemoryGroupIndex other && this.Equals(other);
public override int GetHashCode() => HashCode.Combine(this.BufferLength, this.BufferIndex, this.ElementIndex);
public int BufferLength { get; }
public int BufferIndex { get; }
public int ElementIndex { get; }
public MemoryGroupIndex(int bufferLength, int bufferIndex, int elementIndex)
{
this.BufferLength = bufferLength;
this.BufferIndex = bufferIndex;
this.ElementIndex = elementIndex;
}
public static MemoryGroupIndex operator +(MemoryGroupIndex idx, int val)
{
int nextElementIndex = idx.ElementIndex + val;
return new MemoryGroupIndex(
idx.BufferLength,
idx.BufferIndex + (nextElementIndex / idx.BufferLength),
nextElementIndex % idx.BufferLength);
}
public bool Equals(MemoryGroupIndex other)
{
if (this.BufferLength != other.BufferLength)
{
throw new InvalidOperationException();
}
return this.BufferIndex == other.BufferIndex && this.ElementIndex == other.ElementIndex;
}
public static bool operator ==(MemoryGroupIndex a, MemoryGroupIndex b) => a.Equals(b);
public static bool operator !=(MemoryGroupIndex a, MemoryGroupIndex b) => !a.Equals(b);
public static bool operator <(MemoryGroupIndex a, MemoryGroupIndex b)
{
if (a.BufferLength != b.BufferLength)
{
throw new InvalidOperationException();
}
if (a.BufferIndex < b.BufferIndex)
{
return true;
}
if (a.BufferIndex == b.BufferIndex)
{
return a.ElementIndex < b.ElementIndex;
}
return false;
}
public static bool operator >(MemoryGroupIndex a, MemoryGroupIndex b)
{
if (a.BufferLength != b.BufferLength)
{
throw new InvalidOperationException();
}
if (a.BufferIndex > b.BufferIndex)
{
return true;
}
if (a.BufferIndex == b.BufferIndex)
{
return a.ElementIndex > b.ElementIndex;
}
return false;
}
}
internal static class MemoryGroupIndexExtensions
{
public static T GetElementAt<T>(this IMemoryGroup<T> group, MemoryGroupIndex idx)
where T : struct
{
return group[idx.BufferIndex].Span[idx.ElementIndex];
}
public static void SetElementAt<T>(this IMemoryGroup<T> group, MemoryGroupIndex idx, T value)
where T : struct
{
group[idx.BufferIndex].Span[idx.ElementIndex] = value;
}
public static MemoryGroupIndex MinIndex<T>(this IMemoryGroup<T> group)
where T : struct
{
return new MemoryGroupIndex(group.BufferLength, 0, 0);
}
public static MemoryGroupIndex MaxIndex<T>(this IMemoryGroup<T> group)
where T : struct
{
return group.Count == 0
? new MemoryGroupIndex(group.BufferLength, 0, 0)
: new MemoryGroupIndex(group.BufferLength, group.Count - 1, group[group.Count - 1].Length);
}
}
}