PageRenderTime 35ms CodeModel.GetById 11ms RepoModel.GetById 1ms app.codeStats 0ms

/mcs/class/dlr/Runtime/Microsoft.Scripting.Core/Utils/CollectionExtensions.cs

https://github.com/massimiliano-mantione/mono
C# | 195 lines | 146 code | 25 blank | 24 comment | 20 complexity | 75b91938ea4f7f349875ae158f4e2ee7 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 CLR2
  16. using Microsoft.Scripting.Utils;
  17. #else
  18. using System.Diagnostics.Contracts;
  19. #endif
  20. using System.Collections.Generic;
  21. using System.Collections.ObjectModel;
  22. using System.Diagnostics;
  23. using System.Runtime.CompilerServices;
  24. namespace System.Dynamic.Utils {
  25. internal static class CollectionExtensions {
  26. /// <summary>
  27. /// Wraps the provided enumerable into a ReadOnlyCollection{T}
  28. ///
  29. /// Copies all of the data into a new array, so the data can't be
  30. /// changed after creation. The exception is if the enumerable is
  31. /// already a ReadOnlyCollection{T}, in which case we just return it.
  32. /// </summary>
  33. #if !CLR2
  34. [Pure]
  35. #endif
  36. internal static ReadOnlyCollection<T> ToReadOnly<T>(this IEnumerable<T> enumerable) {
  37. if (enumerable == null) {
  38. return EmptyReadOnlyCollection<T>.Instance;
  39. }
  40. var troc = enumerable as TrueReadOnlyCollection<T>;
  41. if (troc != null) {
  42. return troc;
  43. }
  44. var builder = enumerable as ReadOnlyCollectionBuilder<T>;
  45. if (builder != null) {
  46. return builder.ToReadOnlyCollection();
  47. }
  48. var collection = enumerable as ICollection<T>;
  49. if (collection != null) {
  50. int count = collection.Count;
  51. if (count == 0) {
  52. return EmptyReadOnlyCollection<T>.Instance;
  53. }
  54. T[] clone = new T[count];
  55. collection.CopyTo(clone, 0);
  56. return new TrueReadOnlyCollection<T>(clone);
  57. }
  58. // ToArray trims the excess space and speeds up access
  59. return new TrueReadOnlyCollection<T>(new List<T>(enumerable).ToArray());
  60. }
  61. // We could probably improve the hashing here
  62. internal static int ListHashCode<T>(this IEnumerable<T> list) {
  63. var cmp = EqualityComparer<T>.Default;
  64. int h = 6551;
  65. foreach (T t in list) {
  66. h ^= (h << 5) ^ cmp.GetHashCode(t);
  67. }
  68. return h;
  69. }
  70. #if !CLR2
  71. [Pure]
  72. #endif
  73. internal static bool ListEquals<T>(this ICollection<T> first, ICollection<T> second) {
  74. if (first.Count != second.Count) {
  75. return false;
  76. }
  77. var cmp = EqualityComparer<T>.Default;
  78. var f = first.GetEnumerator();
  79. var s = second.GetEnumerator();
  80. while (f.MoveNext()) {
  81. s.MoveNext();
  82. if (!cmp.Equals(f.Current, s.Current)) {
  83. return false;
  84. }
  85. }
  86. return true;
  87. }
  88. internal static IEnumerable<U> Select<T, U>(this IEnumerable<T> enumerable, Func<T, U> select) {
  89. foreach (T t in enumerable) {
  90. yield return select(t);
  91. }
  92. }
  93. // Name needs to be different so it doesn't conflict with Enumerable.Select
  94. internal static U[] Map<T, U>(this ICollection<T> collection, Func<T, U> select) {
  95. int count = collection.Count;
  96. U[] result = new U[count];
  97. count = 0;
  98. foreach (T t in collection) {
  99. result[count++] = select(t);
  100. }
  101. return result;
  102. }
  103. internal static IEnumerable<T> Where<T>(this IEnumerable<T> enumerable, Func<T, bool> where) {
  104. foreach (T t in enumerable) {
  105. if (where(t)) {
  106. yield return t;
  107. }
  108. }
  109. }
  110. internal static bool Any<T>(this IEnumerable<T> source, Func<T, bool> predicate) {
  111. foreach (T element in source) {
  112. if (predicate(element)) {
  113. return true;
  114. }
  115. }
  116. return false;
  117. }
  118. internal static bool All<T>(this IEnumerable<T> source, Func<T, bool> predicate) {
  119. foreach (T element in source) {
  120. if (!predicate(element)) {
  121. return false;
  122. }
  123. }
  124. return true;
  125. }
  126. internal static T[] RemoveFirst<T>(this T[] array) {
  127. T[] result = new T[array.Length - 1];
  128. Array.Copy(array, 1, result, 0, result.Length);
  129. return result;
  130. }
  131. internal static T[] RemoveLast<T>(this T[] array) {
  132. T[] result = new T[array.Length - 1];
  133. Array.Copy(array, 0, result, 0, result.Length);
  134. return result;
  135. }
  136. internal static T[] AddFirst<T>(this IList<T> list, T item) {
  137. T[] res = new T[list.Count + 1];
  138. res[0] = item;
  139. list.CopyTo(res, 1);
  140. return res;
  141. }
  142. internal static T[] AddLast<T>(this IList<T> list, T item) {
  143. T[] res = new T[list.Count + 1];
  144. list.CopyTo(res, 0);
  145. res[list.Count] = item;
  146. return res;
  147. }
  148. internal static T First<T>(this IEnumerable<T> source) {
  149. var list = source as IList<T>;
  150. if (list != null) {
  151. return list[0];
  152. }
  153. using (var e = source.GetEnumerator()) {
  154. if (e.MoveNext()) return e.Current;
  155. }
  156. throw new InvalidOperationException();
  157. }
  158. internal static T Last<T>(this IList<T> list) {
  159. return list[list.Count - 1];
  160. }
  161. internal static T[] Copy<T>(this T[] array) {
  162. T[] copy = new T[array.Length];
  163. Array.Copy(array, copy, array.Length);
  164. return copy;
  165. }
  166. }
  167. internal static class EmptyReadOnlyCollection<T> {
  168. internal static ReadOnlyCollection<T> Instance = new TrueReadOnlyCollection<T>(new T[0]);
  169. }
  170. }