Example #1
0
        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);
        }
Example #2
0
        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);
        }
Example #3
0
        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);
        }
Example #4
0
 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);
     }
 }
Example #5
0
        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++;
            }
        }
Example #6
0
        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);
        }
Example #7
0
        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);
        }
Example #8
0
 public RleItem(RleItem <V> other)
 {
     Value      = other.Value;
     StartIndex = other.StartIndex;
     EndIndex   = other.EndIndex;
 }