using System; namespace ARMeilleure.Common { /// /// Represents a numeric counter. /// /// Type of the counter class Counter : IDisposable where T : unmanaged { private bool _disposed; private readonly int _index; private readonly EntryTable _countTable; /// /// Initializes a new instance of the class from the specified /// instance and index. /// /// instance /// Index in the private Counter(EntryTable countTable, int index) { _countTable = countTable; _index = index; } /// /// Gets a reference to the value of the counter. /// public ref T Value { get { if (_disposed) { throw new ObjectDisposedException(null); } return ref _countTable.GetValue(_index); } } /// /// Tries to create a instance from the specified instance. /// /// from which to create the /// instance if success; otherwise /// if success; otherwise /// is /// is unsupported public static bool TryCreate(EntryTable countTable, out Counter counter) { if (countTable == null) { throw new ArgumentNullException(nameof(countTable)); } if (typeof(T) != typeof(byte) && typeof(T) != typeof(sbyte) && typeof(T) != typeof(short) && typeof(T) != typeof(ushort) && typeof(T) != typeof(int) && typeof(T) != typeof(uint) && typeof(T) != typeof(long) && typeof(T) != typeof(ulong) && typeof(T) != typeof(nint) && typeof(T) != typeof(nuint) && typeof(T) != typeof(float) && typeof(T) != typeof(double)) { throw new ArgumentException("Counter does not support the specified type", nameof(countTable)); } if (countTable.TryAllocate(out int index)) { counter = new Counter(countTable, index); return true; } counter = null; return false; } /// /// Releases all resources used by the instance. /// public void Dispose() { if (!_disposed) { _countTable.Free(_index); _disposed = true; } } } }