1 module skia.List; 2 3 import skia.Common; 4 import skia.Exceptions; 5 6 import std.range; 7 import std.algorithm; 8 import std.container.array; 9 10 /** 11 * see_also: 12 * https://docs.microsoft.com/en-us/dotnet/api/system.collections.generic.list-1?view=net-5.0 13 */ 14 15 class List(T) : IList!T { 16 17 private Array!(T) _array; 18 19 this() { } 20 21 this(int capacity) { 22 _array.reserve(capacity); 23 } 24 25 this(Array!T array) { 26 this._array = array; 27 } 28 29 this(T[] list) { 30 this._array = list.array; 31 } 32 33 T front() { 34 return _array.front; 35 } 36 37 T moveFront() { 38 // return _array.moveFront(); 39 // TODO: Tasks pending completion -@Administrator at 2021-04-08T10:25:50+08:00 40 // 41 throw new NotImplementedException(); 42 } 43 44 void popFront() { 45 _array.removeBack; 46 } 47 48 bool IsReadOnly() 49 { 50 return false; 51 } 52 53 int Count() { 54 return cast(int)_array.length; 55 } 56 57 bool empty() { 58 return _array.empty(); 59 } 60 61 int opApply(scope int delegate(T) dg) { 62 assert(dg !is null); 63 64 int r = 0; 65 foreach (T item; _array) { 66 r = dg(item); 67 if (r != 0) { 68 break; 69 } 70 } 71 return r; 72 } 73 74 int opApply(scope int delegate(size_t, T) dg) { 75 assert(dg !is null); 76 77 int r = 0; 78 for (int i = 0; i < _array.length; i++) { 79 r = dg(i, _array[i]); 80 if (r != 0) { 81 break; 82 } 83 } 84 return r; 85 86 } 87 88 T opIndex(int index) 89 { 90 return _array[index]; 91 } 92 93 T opIndexAssign(T value, int index) 94 { 95 _array[index] = value; 96 return value; 97 } 98 99 void Add(T item) { 100 _array.insertBack(item); 101 } 102 103 void Insert(int index, T item) { 104 _array.insertBefore(_array[index .. index + 1], item); 105 } 106 107 void Clear() { 108 _array.clear(); 109 } 110 111 bool Contains(T o) { 112 return _array[].canFind(o); 113 } 114 115 bool Exists(T o) { 116 return _array[].canFind(o); 117 } 118 119 void CopyTo(T[] array, int arrayIndex = 0) 120 { 121 assert(arrayIndex >= 0 && arrayIndex <= _array.length); 122 123 if (array.length + arrayIndex < _array.length) 124 { 125 // _array = _array[0..arrayIndex] ~ array ~ _array[(array.length + arrayIndex)..$]; 126 for(size_t i = 0; i < array.length; i++) { 127 _array[arrayIndex + i + 1] = array[i]; 128 } 129 } 130 else 131 { 132 // _array = _array[0..arrayIndex] ~ array; 133 _array.removeBack(_array.length - arrayIndex - 1); 134 _array ~= Array!T(array); 135 } 136 } 137 138 int IndexOf(T o) { 139 for (size_t i = 0; i < _array.length; i++) { 140 static if (is(T == class)) { 141 if (_array[i] is o) 142 return cast(int) i; 143 } else { 144 if (_array[i] == o) 145 return cast(int) i; 146 } 147 } 148 149 return -1; 150 } 151 152 int LastIndexOf(T item) { 153 for (size_t i = _array.length - 1; i >= 0; i--) { 154 if (_array[i] == item) 155 return cast(int) i; 156 } 157 158 return -1; 159 } 160 161 bool Remove(T item) { 162 int index = IndexOf(item); 163 if (index < 0) 164 return false; 165 _array.linearRemove(_array[index .. index + 1]); 166 return true; 167 } 168 169 T RemoveAt(int index) { 170 T oldValue = _array[index]; 171 _array.linearRemove(_array[index .. index + 1]); 172 return oldValue; 173 } 174 175 T FirstOrDefault(scope bool delegate(T) dg) { 176 if (dg is null) { 177 return _array.front(); 178 } 179 foreach (T item; _array) { 180 if (dg(item)) { 181 return item; 182 } 183 } 184 return T.init; 185 } 186 187 List!T Where(scope bool delegate(T) dg) { 188 assert(dg !is null); 189 190 List!(T) meets = new List!(T)(); 191 auto subArray = _array[].filter!(dg).array; 192 foreach (T item; subArray) { 193 meets.Add(item); 194 } 195 return meets; 196 } 197 198 T[] ToList() { 199 return _array.array; 200 } 201 } 202