1 // 2 // Copyright (c) 2010-2018 Antmicro 3 // Copyright (c) 2011-2015 Realtime Embedded 4 // 5 // This file is licensed under the MIT License. 6 // Full license text is available in 'licenses/MIT.txt'. 7 // 8 using System; 9 using System.Collections.Generic; 10 using System.Collections; 11 12 namespace Antmicro.Renode.Utilities.Collections 13 { 14 public sealed class AutoResizingList<T> : IList<T> 15 { AutoResizingList(int initialCapacity = 4)16 public AutoResizingList(int initialCapacity = 4) 17 { 18 this.initialCapacity = initialCapacity; 19 Clear(); 20 } 21 22 public int Count { get; private set; } 23 24 public bool IsReadOnly 25 { 26 get 27 { 28 return false; 29 } 30 } 31 32 public T this[int index] 33 { 34 get 35 { 36 ResizeTo(index + 1); 37 return data[index]; 38 } 39 set 40 { 41 ResizeTo(index + 1); 42 data[index] = value; 43 } 44 } 45 Add(T item)46 public void Add(T item) 47 { 48 ResizeTo(Count + 1); 49 data[Count - 1] = item; 50 } 51 Clear()52 public void Clear() 53 { 54 data = new T[initialCapacity]; 55 Count = 0; 56 } 57 Contains(T item)58 public bool Contains(T item) 59 { 60 return IndexOf(item) != -1; 61 } 62 CopyTo(T[] array, int index)63 public void CopyTo(T[] array, int index) 64 { 65 Array.Copy(data, array, Count); 66 } 67 IEnumerable.GetEnumerator()68 IEnumerator IEnumerable.GetEnumerator() 69 { 70 return GetEnumerator(); 71 } 72 GetEnumerator()73 public IEnumerator<T> GetEnumerator() 74 { 75 var count = Count; 76 for(var i = 0; i < count; i++) 77 { 78 yield return data[i]; 79 } 80 } 81 IndexOf(T item)82 public int IndexOf(T item) 83 { 84 var index = Array.IndexOf(data, item); 85 if(index >= Count) 86 { 87 return -1; 88 } 89 return index; 90 } 91 Insert(int index, T item)92 public void Insert(int index, T item) 93 { 94 if(index >= Count) 95 { 96 this[index] = item; 97 return; 98 } 99 ResizeTo(Count + 1); 100 for(var i = Count - 2; i >= index; i--) 101 { 102 data[i + 1] = data[i]; 103 } 104 data[index] = item; 105 } 106 Remove(T item)107 public bool Remove(T item) 108 { 109 var index = IndexOf(item); 110 if(index == -1) 111 { 112 return false; 113 } 114 RemoveAt(index); 115 return true; 116 } 117 RemoveAt(int index)118 public void RemoveAt(int index) 119 { 120 ResizeTo(Count - 1); 121 var count = Count; 122 for(var i = index; i < count; i++) 123 { 124 data[i] = data[i + 1]; 125 } 126 } 127 ResizeTo(int neededSize)128 private void ResizeTo(int neededSize) 129 { 130 if(neededSize < 0) 131 { 132 throw new ArgumentException("Index cannot be negative."); 133 } 134 Count = Math.Max(Count, neededSize); 135 if(data.Length >= neededSize) 136 { 137 return; 138 } 139 var newData = new T[data.Length*2]; 140 data.CopyTo(newData, 0); 141 data = newData; 142 } 143 144 private T[] data; 145 private readonly int initialCapacity; 146 } 147 } 148 149