// // Ptr.cs - i'm not sure what this is for now but it looks interesting // // Author: // Michael Becker // // Copyright (c) 2011-2020 Mike Becker's Software // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program. If not, see . using System; using System.Diagnostics; namespace UniversalEditor { [DebuggerNonUserCode()] public struct Ptr { private T[] value; private int index; private int length; /// /// Gets the capacity of the underlying array. /// public int Capacity { get { return value.Length; } } /// /// Gets the size of the . /// public int Size { get { return length; } } public Ptr(T[] value, int index = -1) { this.value = value; this.length = value.Length; this.mvarAutoResize = false; if (index < -1 || index > value.Length - 1) throw new IndexOutOfRangeException(); this.index = index; } public static Ptr operator + (Ptr value, int addend) { return new Ptr(value.value, value.index + 1); } public static Ptr operator - (Ptr value, int addend) { return new Ptr(value.value, value.index - 1); } /// /// Increments the index, then sets the value stored at that position to the given value. /// /// The value to set. public void IncrementThenSetValue(T value) { this.Increment(); SetValue(value); } /// /// Decrements the index, then sets the value stored at that position to the given value. /// /// The value to set. public void DecrementThenSetValue(T value) { Decrement(); SetValue(value); } /// /// Sets the value at the current position to the given value, then increments the index. /// /// The value to set. public void SetValueThenIncrement(T value) { SetValue(value); Increment(); } /// /// Sets the value at the current position to the given value, then decrements the index. /// /// The value to set. public void SetValueThenDecrement(T value) { SetValue(value); Decrement(); } public void Increment() { this.index++; AutoResizeIfNeeded(this.index); } public void Decrement() { if (this.index - 1 < 0) throw new IndexOutOfRangeException(); this.index--; } /// /// Increments the index, then gets the value stored at that position. /// /// The value stored at the position after the index has been incremented. public T IncrementThenGetValue() { this.index++; T value = this.value[this.index]; return value; } /// /// Decrements the index, then gets the value stored at that position. /// /// The value stored at the position after the index has been decremented. public T DecrementThenGetValue() { this.index--; T value = this.value[this.index]; return value; } /// /// Gets the value stored at the current position, then increments the index. /// /// The value stored at the position before the index has been incremented. public T GetValueThenIncrement() { T value = this.value[this.index]; this.index++; return value; } /// /// Gets the value stored at the current position, then decrements the index. /// /// The value stored at the position before the index has been decremented. public T GetValueThenDecrement() { T value = this.value[this.index]; this.index--; return value; } /// /// Retrieves all elements of this as an array. /// /// An array of all items in this . public T[] ToArray() { return (T[])this.value.Clone(); } /// /// Sets the value at the specified index to the given value. /// /// The value to set. /// The index in the underlying array of the value to set, or -1 to set the current value. public void SetValue(T value, int index = -1) { if (index == -1) index = this.index; AutoResizeIfNeeded(index); if (index < 0 || index > this.value.Length - 1) throw new IndexOutOfRangeException(); this.value[index] = value; } /// /// Determines whether an auto-resize is needed. /// /// /// -1 if auto-resize is disabled, 0 if no resize was needed, or the number of elements added to the underlying array. private int AutoResizeIfNeeded(int index) { if (mvarAutoResize) return -1; if (index > this.length - 1 && mvarAutoResize) { if (this.length + 1 > this.value.Length - 1) { Array.Resize(ref this.value, this.value.Length * 2); this.length++; } } return 0; } /// /// Retrieves the value at the specified index. /// /// The index in the underlying array of the value to retrieve, or -1 to retrieve the current value. /// public T GetValue(int index = -1) { if (index == -1) index = this.index; return this.value[index]; } public T this[int index] { get { return this.value[index]; } set { this.value[index] = value; } } private bool mvarAutoResize; /// /// Determines if the underlying array will automatically resize when an attempt is made to address memory outside of the array boundaries. /// public bool AutoResize { get { return mvarAutoResize; } set { mvarAutoResize = value; } } } }