Paradox Game Engine  v1.0.0 beta06
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Events Macros Pages
DesignExtensions.cs
Go to the documentation of this file.
1 // Copyright (c) 2014 Silicon Studio Corp. (http://siliconstudio.co.jp)
2 // This file is distributed under GPL v3. See LICENSE.md for details.
3 using System;
4 using System.Collections;
5 using System.Collections.Generic;
6 using System.Linq;
7 using System.Reflection;
8 
9 namespace SiliconStudio.Core.Extensions
10 {
11  public static class DesignExtensions
12  {
13  /// <summary>
14  /// Checks whether the IEnumerable represents a readonly data source.
15  /// </summary>
16  /// <param name="source">The IEnumerable to check.</param>
17  /// <returns>Returns true if the data source is readonly, false otherwise.</returns>
18  public static bool IsReadOnly(this IEnumerable source)
19  {
20  if (source == null)
21  throw new ArgumentNullException("source");
22 
23  var collection = source as ICollection<object>;
24  if (collection != null)
25  return collection.IsReadOnly;
26 
27  var list = source as IList;
28  if (list != null)
29  return list.IsReadOnly;
30 
31  return true;
32  }
33 
34  /// <summary>
35  /// Allow to directly iterate over an enumerator type.
36  /// </summary>
37  /// <typeparam name="T">Type of items provided by the enumerator.</typeparam>
38  /// <param name="enumerator">Enumerator instance to iterate on.</param>
39  /// <returns>Returns an enumerable that can be consume in a foreach statement.</returns>
40  public static IEnumerable<T> Enumerate<T>(this IEnumerator<T> enumerator)
41  {
42  while (enumerator.MoveNext())
43  yield return enumerator.Current;
44  }
45 
46  /// <summary>
47  /// Allow to directly iterate over an enumerator type.
48  /// </summary>
49  /// <typeparam name="T">Type of items provided by the enumerator.</typeparam>
50  /// <param name="enumerator">Enumerator instance to iterate on. (subtype is casted to T)</param>
51  /// <returns>Returns a typed enumerable that can be consume in a foreach statement.</returns>
52  public static IEnumerable<T> Enumerate<T>(this IEnumerator enumerator)
53  {
54  while (enumerator.MoveNext())
55  yield return (T)enumerator.Current;
56  }
57 
58  public static IEnumerable<Tuple<T1, T2>> Zip<T1, T2>(this IEnumerable<T1> enumerable1, IEnumerable<T2> enumerable2)
59  {
60  if (enumerable1 == null) throw new ArgumentNullException("enumerable1");
61  if (enumerable2 == null) throw new ArgumentNullException("enumerable2");
62 
63  using (IEnumerator<T1> enumerator1 = enumerable1.GetEnumerator())
64  {
65  using (IEnumerator<T2> enumerator2 = enumerable2.GetEnumerator())
66  {
67  bool enumMoved = true;
68  while (enumMoved)
69  {
70  enumMoved = enumerator1.MoveNext();
71  bool enum2Moved = enumerator2.MoveNext();
72  if (enumMoved != enum2Moved)
73  throw new InvalidOperationException("Enumerables do not have the same number of items.");
74 
75  if (enumMoved)
76  {
77  yield return Tuple.Create(enumerator1.Current, enumerator2.Current);
78  }
79  }
80  }
81  }
82  }
83 
84  /// <summary>
85  /// Iterates over all elements of source and their children recursively.
86  /// </summary>
87  /// <typeparam name="T"></typeparam>
88  /// <param name="source">The source.</param>
89  /// <param name="childrenSelector">The children selector.</param>
90  /// <returns></returns>
91  public static IEnumerable<T> SelectDeep<T>(this IEnumerable<T> source, Func<T, IEnumerable<T>> childrenSelector)
92  {
93  foreach (T item in source)
94  {
95  yield return item;
96 
97  foreach (T child in childrenSelector(item).SelectDeep(childrenSelector))
98  yield return child;
99  }
100  }
101 
102  public static IEnumerable<T> Distinct<T, TKey>(this IEnumerable<T> source, Func<T, TKey> selector)
103  {
104  return source.Distinct(new SelectorEqualityComparer<T, TKey>(selector));
105  }
106 
107  public static bool Equals<T>(IEnumerable<T> a1, IEnumerable<T> a2, IEqualityComparer<T> comparer = null)
108  {
109  if (ReferenceEquals(a1, a2))
110  return true;
111 
112  if (a1 == null || a2 == null)
113  return false;
114 
115  if (comparer == null)
116  comparer = EqualityComparer<T>.Default;
117 
118  var e1 = a1.GetEnumerator();
119  var e2 = a2.GetEnumerator();
120 
121  while (true)
122  {
123  bool move1 = e1.MoveNext();
124  bool move2 = e2.MoveNext();
125 
126  // End of enumeration, success!
127  if (!move1 && !move2)
128  break;
129 
130  // One of the IEnumerable is shorter than the other?
131  if (move1 ^ move2)
132  return false;
133 
134  if (!comparer.Equals(e1.Current, e2.Current))
135  return false;
136  }
137 
138  return true;
139  }
140 
141  public static bool SequenceEqual(this IEnumerable a1, IEnumerable a2)
142  {
143  if (ReferenceEquals(a1, a2))
144  return true;
145 
146  if (a1 == null || a2 == null)
147  return false;
148 
149  var e1 = a1.GetEnumerator();
150  var e2 = a2.GetEnumerator();
151 
152  while (true)
153  {
154  bool move1 = e1.MoveNext();
155  bool move2 = e2.MoveNext();
156 
157  // End of enumeration, success!
158  if (!move1 && !move2)
159  return true;
160 
161  // One of the IEnumerable is shorter than the other?
162  if (move1 ^ move2)
163  return false;
164 
165  // item from the first enum is non null and does not equal item from the second enum
166  if (e1.Current != null && !e1.Current.Equals(e2.Current))
167  return false;
168 
169  // item from the second enum is non null and does not equal item from the first enum
170  if (e2.Current != null && !e2.Current.Equals(e1.Current))
171  return false;
172  }
173  }
174 
175  public static bool AllEqual(this IEnumerable<object> values, out object value)
176  {
177  value = null;
178  object firstNotNull = values.FirstOrDefault(x => x != null);
179  // Either empty, or everything is null
180  if (firstNotNull == null)
181  return true;
182 
183  value = firstNotNull;
184 
185  return values.SkipWhile(x => x != firstNotNull).All(firstNotNull.Equals);
186  }
187 
188  /// <summary>
189  /// Returns the value corresponding to the given key. If the key is absent from the dictionary, it is added with the default value of the TValue type.
190  /// </summary>
191  /// <param name="dictionary">The dictionary.</param>
192  /// <param name="key">The key of the value we are looking for.</param>
193  /// <returns></returns>
194  public static TValue GetOrCreateValue<TKey, TValue>(this IDictionary<TKey, TValue> dictionary, TKey key) where TValue : new()
195  {
196  TValue value;
197  if (!dictionary.TryGetValue(key, out value))
198  {
199  value = new TValue();
200  dictionary.Add(key, value);
201  }
202  return value;
203  }
204 
205  public static int RemoveWhere<T>(this IList<T> list, Predicate<T> predicate)
206  {
207  int count = 0;
208  var array = list.ToArray();
209  for (var i = array.Length - 1; i >= 0; --i)
210  {
211  if (predicate(array[i]))
212  list.RemoveAt(i);
213 
214  ++count;
215  }
216  return count;
217  }
218 
219  public static int RemoveWhere<T>(this ICollection<T> collection, Predicate<T> predicate)
220  {
221  int count = 0;
222  foreach (var item in collection.ToArray().Where(x => predicate(x)))
223  {
224  collection.Remove(item);
225  ++count;
226  }
227  return count;
228  }
229 
230  class SelectorEqualityComparer<T, TKey> : IEqualityComparer<T>
231  {
232  Func<T, TKey> selector;
233 
234  public SelectorEqualityComparer(Func<T, TKey> selector)
235  {
236  this.selector = selector;
237  }
238 
239  public bool Equals(T x, T y)
240  {
241  var keyX = selector(x);
242  var keyY = selector(y);
243  if (!typeof(T).GetTypeInfo().IsValueType)
244  {
245  if (object.ReferenceEquals(keyX, null))
246  return object.ReferenceEquals(keyY, null);
247  }
248 
249  return selector(x).Equals(selector(y));
250  }
251 
252  public int GetHashCode(T obj)
253  {
254  var key = selector(obj);
255  if (!typeof(T).GetTypeInfo().IsValueType && object.ReferenceEquals(key, null))
256  return 0;
257  return key.GetHashCode();
258  }
259  }
260  }
261 }
_In_ size_t _In_ DXGI_FORMAT _In_ size_t _In_ float size_t y
Definition: DirectXTexP.h:191
_In_ size_t count
Definition: DirectXTexP.h:174
static bool SequenceEqual(this IEnumerable a1, IEnumerable a2)
static bool AllEqual(this IEnumerable< object > values, out object value)
static bool IsReadOnly(this IEnumerable source)
Checks whether the IEnumerable represents a readonly data source.