int InsertIndexRange(int index, int count) { int itemIndex = GetItemIndex(index); RleItem <T> item = items[itemIndex]; if (item.StartIndex < index) { itemIndex++; items.Insert(itemIndex, new RleItem <T>(item.Value, index, item.EndIndex)); item.EndIndex = index - 1; } for (int i = items.Count - 1; i >= itemIndex; i--) { item = items[i]; if (item.StartIndex + count >= length) { items.RemoveAt(i); } else { item.StartIndex = item.StartIndex + count; item.EndIndex = Math.Min(item.EndIndex + count, length - 1); } } return(itemIndex); }
int CutIndexRange(int startIndex, int endIndex) { int firstItemIndex = GetItemIndex(startIndex); int lastItemIndex = GetItemIndex(endIndex); if (firstItemIndex == lastItemIndex) { return(CutIndexRangeFromItem(firstItemIndex, startIndex, endIndex)); } RleItem <T> item = items[firstItemIndex]; if (item.StartIndex < startIndex) { item.EndIndex = startIndex - 1; firstItemIndex++; } item = items[lastItemIndex]; if (item.EndIndex > endIndex) { item.StartIndex = endIndex + 1; lastItemIndex--; } int count = lastItemIndex - firstItemIndex + 1; if (count > 0) { items.RemoveRange(firstItemIndex, count); } return(firstItemIndex); }
int CutIndexRangeFromItem(int itemIndex, int startIndex, int endIndex) { RleItem <T> item = items[itemIndex]; if (item.StartIndex == startIndex) { if (item.EndIndex == endIndex) { items.RemoveAt(itemIndex); } else { item.StartIndex = endIndex + 1; } } else { itemIndex++; if (item.EndIndex > endIndex) { items.Insert(itemIndex, new RleItem <T>(item.Value, endIndex + 1, item.EndIndex)); } item.EndIndex = startIndex - 1; } return(itemIndex); }
public T this[int index] { get { CheckIndex(index); RleItem <T> item = GetItem(index); if (ImmutableValues || (Object)item.Value == null) { return(item.Value); } ICloneable cloneable = item.Value as ICloneable; if (cloneable == null) { ICloneable <T> typedCloneable = item.Value as ICloneable <T>; if (typedCloneable == null) { throw new InvalidOperationException("Unable to clone value. ICloneable or ICloneable<T> not implemented."); } return(typedCloneable.Clone()); } return((T)cloneable.Clone()); } set { CheckIndex(index); SetValue(index, value); } }
protected virtual void SetValue(int index, T value) { int itemIndex = GetItemIndex(index); RleItem <T> item = items[itemIndex]; if (AreEqual(value, item.Value)) { return; } if (item.StartIndex == item.EndIndex) { item.Value = value; if (TryMergeWithPrevious(itemIndex)) { TryMergeWithNext(itemIndex - 1); } else { TryMergeWithNext(itemIndex); } } else if (index == item.StartIndex) { item.StartIndex++; items.Insert(itemIndex, new RleItem <T>(value, index, index)); TryMergeWithPrevious(itemIndex); } else if (index == item.EndIndex) { item.EndIndex--; items.Insert(itemIndex + 1, new RleItem <T>(value, index, index)); mruItemIndex++; TryMergeWithNext(itemIndex + 1); } else { itemIndex++; items.Insert(itemIndex, new RleItem <T>(item.Value, index + 1, item.EndIndex)); items.Insert(itemIndex, new RleItem <T>(value, index, index)); item.EndIndex = index - 1; mruItemIndex++; } }
public IRleCollection <T> GetRange(int startIndex, int endIndex) { CheckRangeIndexes(startIndex, endIndex); RleCollection <T> result = new RleCollection <T>(endIndex - startIndex + 1); result.ImmutableValues = this.ImmutableValues; int itemIndex = GetItemIndex(startIndex); RleItem <T> sourceItem = items[itemIndex]; while (sourceItem != null && sourceItem.StartIndex <= endIndex) { RleItem <T> item = new RleItem <T>(sourceItem.Value, Math.Max(sourceItem.StartIndex, startIndex) - startIndex, Math.Min(sourceItem.EndIndex, endIndex) - startIndex); result.items.Add(item); itemIndex++; sourceItem = itemIndex < items.Count ? items[itemIndex] : null; } return(result); }
public void Remove(int index, int count) { CheckIndexAndCount(index, count); T lastValue = GetItem(length - 1).Value; int itemIndex = CutIndexRange(index, index + count - 1); if (itemIndex == items.Count) { items.Insert(itemIndex, new RleItem <T>(lastValue, index, length - 1)); } else { for (int i = itemIndex; i < items.Count; i++) { RleItem <T> item = items[i]; item.StartIndex -= count; item.EndIndex -= count; } items[items.Count - 1].EndIndex = length - 1; } TryMergeWithPrevious(itemIndex); }
public RleItem(RleItem <V> other) { Value = other.Value; StartIndex = other.StartIndex; EndIndex = other.EndIndex; }