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