PageRenderTime 30ms CodeModel.GetById 1ms RepoModel.GetById 1ms app.codeStats 0ms

/Microsoft.Scripting/Utils/ArrayUtils.cs

https://bitbucket.org/stefanrusek/xronos
C# | 317 lines | 239 code | 58 blank | 20 comment | 40 complexity | d117a3fb16d6905e06b5e80815f3d213 MD5 | raw file
  1. /* ****************************************************************************
  2. *
  3. * Copyright (c) Microsoft Corporation.
  4. *
  5. * This source code is subject to terms and conditions of the Microsoft Public License. A
  6. * copy of the license can be found in the License.html file at the root of this distribution. If
  7. * you cannot locate the Microsoft Public License, please send an email to
  8. * dlr@microsoft.com. By using this source code in any fashion, you are agreeing to be bound
  9. * by the terms of the Microsoft Public License.
  10. *
  11. * You must not remove this notice, or any other, from this software.
  12. *
  13. *
  14. * ***************************************************************************/
  15. #if CODEPLEX_40
  16. using System;
  17. #else
  18. using System; using Microsoft;
  19. #endif
  20. using System.Collections.Generic;
  21. using System.Diagnostics;
  22. using System.Text;
  23. namespace Microsoft.Scripting.Utils {
  24. public static class ArrayUtils {
  25. [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Security", "CA2105:ArrayFieldsShouldNotBeReadOnly")]
  26. public static readonly string[] EmptyStrings = new string[0];
  27. [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Security", "CA2105:ArrayFieldsShouldNotBeReadOnly")]
  28. public static readonly object[] EmptyObjects = new object[0];
  29. public static TOutput[] ConvertAll<TInput, TOutput>(TInput[] input, Converter<TInput, TOutput> conv) {
  30. #if SILVERLIGHT
  31. ContractUtils.RequiresNotNull(input, "input");
  32. ContractUtils.RequiresNotNull(conv, "conv");
  33. TOutput[] res = new TOutput[input.Length];
  34. for (int i = 0; i < input.Length; i++) {
  35. res[i] = conv(input[i]);
  36. }
  37. return res;
  38. #else
  39. return System.Array.ConvertAll<TInput, TOutput>(input, conv);
  40. #endif
  41. }
  42. public static T[] FindAll<T>(T[] array, Predicate<T> match) {
  43. #if SILVERLIGHT
  44. if (array == null) {
  45. throw new ArgumentNullException("array");
  46. }
  47. if (match == null) {
  48. throw new ArgumentNullException("match");
  49. }
  50. List<T> list = new List<T>();
  51. for (int i = 0; i < array.Length; i++) {
  52. if (match(array[i])) {
  53. list.Add(array[i]);
  54. }
  55. }
  56. return list.ToArray();
  57. #else
  58. return System.Array.FindAll(array, match);
  59. #endif
  60. }
  61. [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1814:PreferJaggedArraysOverMultidimensional", MessageId = "1#")] // TODO: fix
  62. public static void PrintTable(StringBuilder output, string[,] table) {
  63. ContractUtils.RequiresNotNull(output, "output");
  64. ContractUtils.RequiresNotNull(table, "table");
  65. int max_width = 0;
  66. for (int i = 0; i < table.GetLength(0); i++) {
  67. if (table[i, 0].Length > max_width) {
  68. max_width = table[i, 0].Length;
  69. }
  70. }
  71. for (int i = 0; i < table.GetLength(0); i++) {
  72. output.Append(" ");
  73. output.Append(table[i, 0]);
  74. for (int j = table[i, 0].Length; j < max_width + 1; j++) {
  75. output.Append(' ');
  76. }
  77. output.AppendLine(table[i, 1]);
  78. }
  79. }
  80. public static T[] Copy<T>(T[] array) {
  81. return (array.Length > 0) ? (T[])array.Clone() : array;
  82. }
  83. public static T[] MakeArray<T>(ICollection<T> list) {
  84. if (list.Count == 0) {
  85. return new T[0];
  86. }
  87. T[] res = new T[list.Count];
  88. list.CopyTo(res, 0);
  89. return res;
  90. }
  91. public static T[] MakeArray<T>(ICollection<T> elements, int reservedSlotsBefore, int reservedSlotsAfter) {
  92. if (reservedSlotsAfter < 0) throw new ArgumentOutOfRangeException("reservedSlotsAfter");
  93. if (reservedSlotsBefore < 0) throw new ArgumentOutOfRangeException("reservedSlotsBefore");
  94. if (elements == null) {
  95. return new T[reservedSlotsBefore + reservedSlotsAfter];
  96. }
  97. T[] result = new T[reservedSlotsBefore + elements.Count + reservedSlotsAfter];
  98. elements.CopyTo(result, reservedSlotsBefore);
  99. return result;
  100. }
  101. public static T[] RotateRight<T>(T[] array, int count) {
  102. ContractUtils.RequiresNotNull(array, "array");
  103. if ((count < 0) || (count > array.Length)) throw new ArgumentOutOfRangeException("count");
  104. T[] result = new T[array.Length];
  105. // The head of the array is shifted, and the tail will be rotated to the head of the resulting array
  106. int sizeOfShiftedArray = array.Length - count;
  107. Array.Copy(array, 0, result, count, sizeOfShiftedArray);
  108. Array.Copy(array, sizeOfShiftedArray, result, 0, count);
  109. return result;
  110. }
  111. public static T[] ShiftRight<T>(T[] array, int count) {
  112. ContractUtils.RequiresNotNull(array, "array");
  113. if (count < 0) throw new ArgumentOutOfRangeException("count");
  114. T[] result = new T[array.Length + count];
  115. System.Array.Copy(array, 0, result, count, array.Length);
  116. return result;
  117. }
  118. public static T[] ShiftLeft<T>(T[] array, int count) {
  119. ContractUtils.RequiresNotNull(array, "array");
  120. if (count < 0) throw new ArgumentOutOfRangeException("count");
  121. T[] result = new T[array.Length - count];
  122. System.Array.Copy(array, count, result, 0, result.Length);
  123. return result;
  124. }
  125. public static T[] Insert<T>(T item, IList<T> list) {
  126. T[] res = new T[list.Count + 1];
  127. res[0] = item;
  128. list.CopyTo(res, 1);
  129. return res;
  130. }
  131. public static T[] Insert<T>(T item1, T item2, IList<T> list) {
  132. T[] res = new T[list.Count + 2];
  133. res[0] = item1;
  134. res[1] = item2;
  135. list.CopyTo(res, 2);
  136. return res;
  137. }
  138. public static T[] Insert<T>(T item, T[] array) {
  139. T[] result = ShiftRight(array, 1);
  140. result[0] = item;
  141. return result;
  142. }
  143. public static T[] Insert<T>(T item1, T item2, T[] array) {
  144. T[] result = ShiftRight(array, 2);
  145. result[0] = item1;
  146. result[1] = item2;
  147. return result;
  148. }
  149. public static T[] Append<T>(T[] array, T item) {
  150. ContractUtils.RequiresNotNull(array, "array");
  151. System.Array.Resize<T>(ref array, array.Length + 1);
  152. array[array.Length - 1] = item;
  153. return array;
  154. }
  155. public static T[] AppendRange<T>(T[] array, IList<T> items) {
  156. return AppendRange<T>(array, items, 0);
  157. }
  158. public static T[] AppendRange<T>(T[] array, IList<T> items, int additionalItemCount) {
  159. ContractUtils.RequiresNotNull(array, "array");
  160. if (additionalItemCount < 0) throw new ArgumentOutOfRangeException("additionalItemCount");
  161. int j = array.Length;
  162. System.Array.Resize<T>(ref array, array.Length + items.Count + additionalItemCount);
  163. for (int i = 0; i < items.Count; i++, j++) {
  164. array[j] = items[i];
  165. }
  166. return array;
  167. }
  168. [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1814:PreferJaggedArraysOverMultidimensional")] // TODO: fix
  169. public static T[,] Concatenate<T>(T[,] array1, T[,] array2) {
  170. int columnsCount = array1.GetLength(1);
  171. Debug.Assert(array2.GetLength(1) == columnsCount);
  172. int row1Count = array1.GetLength(0);
  173. int row2Count = array2.GetLength(0);
  174. int totalRowsCount = row1Count + row2Count;
  175. T[,] result = new T[totalRowsCount, columnsCount];
  176. for (int i = 0; i < row1Count; i++) {
  177. for (int j = 0; j < columnsCount; j++) {
  178. result[i, j] = array1[i, j];
  179. }
  180. }
  181. for (int i = 0; i < row2Count; i++) {
  182. for (int j = 0; j < columnsCount; j++) {
  183. result[(i + row1Count), j] = array2[i, j];
  184. }
  185. }
  186. return result;
  187. }
  188. public static void SwapLastTwo<T>(T[] array) {
  189. Debug.Assert(array != null && array.Length >= 2);
  190. T temp = array[array.Length - 1];
  191. array[array.Length - 1] = array[array.Length - 2];
  192. array[array.Length - 2] = temp;
  193. }
  194. public static T[] RemoveFirst<T>(IList<T> list) {
  195. return ShiftLeft(MakeArray(list), 1);
  196. }
  197. public static T[] RemoveFirst<T>(T[] array) {
  198. return ShiftLeft(array, 1);
  199. }
  200. public static T[] RemoveLast<T>(T[] array) {
  201. ContractUtils.RequiresNotNull(array, "array");
  202. System.Array.Resize(ref array, array.Length - 1);
  203. return array;
  204. }
  205. public static T[] RemoveAt<T>(IList<T> list, int indexToRemove) {
  206. return RemoveAt(MakeArray(list), indexToRemove);
  207. }
  208. public static T[] RemoveAt<T>(T[] array, int indexToRemove) {
  209. ContractUtils.RequiresNotNull(array, "array");
  210. ContractUtils.Requires(indexToRemove >= 0 && indexToRemove < array.Length, "index");
  211. T[] result = new T[array.Length - 1];
  212. if (indexToRemove > 0) {
  213. Array.Copy(array, 0, result, 0, indexToRemove);
  214. }
  215. int remaining = array.Length - indexToRemove - 1;
  216. if (remaining > 0) {
  217. Array.Copy(array, array.Length - remaining, result, result.Length - remaining, remaining);
  218. }
  219. return result;
  220. }
  221. public static T[] InsertAt<T>(IList<T> list, int index, params T[] items) {
  222. return InsertAt(MakeArray(list), index, items);
  223. }
  224. public static T[] InsertAt<T>(T[] array, int index, params T[] items) {
  225. ContractUtils.RequiresNotNull(array, "array");
  226. ContractUtils.RequiresNotNull(items, "items");
  227. ContractUtils.Requires(index >= 0 && index <= array.Length, "index");
  228. if (items.Length == 0) {
  229. return Copy(array);
  230. }
  231. T[] result = new T[array.Length + items.Length];
  232. if (index > 0) {
  233. Array.Copy(array, 0, result, 0, index);
  234. }
  235. Array.Copy(items, 0, result, index, items.Length);
  236. int remaining = array.Length - index;
  237. if (remaining > 0) {
  238. Array.Copy(array, array.Length - remaining, result, result.Length - remaining, remaining);
  239. }
  240. return result;
  241. }
  242. /// <summary>
  243. /// Converts a generic ICollection of T into an array of T.
  244. ///
  245. /// If the collection is already an array of T the original collection is returned.
  246. /// </summary>
  247. public static T[] ToArray<T>(ICollection<T> list) {
  248. T[] res = list as T[];
  249. if (res == null) {
  250. res = new T[list.Count];
  251. int i = 0;
  252. foreach (T obj in list) {
  253. res[i++] = obj;
  254. }
  255. }
  256. return res;
  257. }
  258. }
  259. }