wasSharp – Blame information for rev 52

Subversion Repositories:
Rev:
Rev Author Line No. Line
11 office 1 ///////////////////////////////////////////////////////////////////////////
2 // Copyright (C) Wizardry and Steamworks 2013 - License: GNU GPLv3 //
3 // Please see: http://www.gnu.org/licenses/gpl.html for legal details, //
4 // rights of fair usage, the disclaimer and warranty conditions. //
5 ///////////////////////////////////////////////////////////////////////////
6  
7 using System;
8 using System.Collections.Generic;
9 using System.Linq;
10  
11 namespace wasSharp.Linq
12 {
13 public static class Extensions
14 {
15 ///////////////////////////////////////////////////////////////////////////
32 office 16 // Copyright (C) 2017 Wizardry and Steamworks - License: GNU GPLv3 //
17 ///////////////////////////////////////////////////////////////////////////
18 /// <summary>
19 /// A functional implementation of a switch clause.
20 /// </summary>
21 /// <typeparam name="T">the type of items in the query</typeparam>
22 /// <param name="query">the selector query</param>
23 /// <param name="default">the function to execute when no case matches</param>
24 /// <param name="case">a list of predicates representing the switch cases,
25 /// where each predicate has to return True or False indicating whether
26 /// fallthrough should occur.
27 /// </param>
47 office 28 /// <remarks>when used, the default action must be explicitly specified
29 /// due to language restrictions
30 /// </remarks>
32 office 31 public static void Switch<T>(this IEnumerable<T> query,
32 // default
33 Action<T> @default,
34 // case
35 // case
36 // ...
37 params Predicate<T>[] @case)
38 {
39 if (@case.Length % 2 != 0)
40 throw new ArgumentException("Pairs of predicates expected.");
41  
46 office 42 var enumerable = query as IList<T> ?? query.ToList();
43 using (var iter = enumerable.GetEnumerator())
32 office 44 {
46 office 45 while (iter.MoveNext())
32 office 46 {
46 office 47 var match = false;
48 for (var i = 0; i < @case.Length; i += 2)
32 office 49 {
46 office 50 if (!@case[i].Invoke(iter.Current))
51 continue;
52  
53 if (@case[i + 1].Invoke(iter.Current))
54 return;
55  
56 match = true;
32 office 57 }
46 office 58  
59 if (!match)
60 @default.Invoke(iter.Current);
32 office 61 }
62 }
63 }
64  
65 ///////////////////////////////////////////////////////////////////////////
66 // Copyright (C) 2017 Wizardry and Steamworks - License: GNU GPLv3 //
67 ///////////////////////////////////////////////////////////////////////////
68 /// <summary>
49 office 69 /// A functional implementation of a switch clause.
70 /// </summary>
71 /// <typeparam name="T">the type of the item to query</typeparam>
72 /// <param name="query">the selector query</param>
73 /// <param name="default">the function to execute when no case matches</param>
74 /// <param name="case">a list of predicates representing the switch cases,
75 /// where each predicate has to return True or False indicating whether
76 /// fallthrough should occur.
77 /// </param>
78 /// <remarks>when used, the default action must be explicitly specified
79 /// due to language restrictions
80 /// </remarks>
81 public static void Switch<T>(this T query,
82 // default
83 Action<T> @default,
84 // case
85 // case
86 // ...
87 params Predicate<T>[] @case)
88 {
89 if (@case.Length % 2 != 0)
90 throw new ArgumentException("Pairs of predicates expected.");
91  
92 var match = false;
93 for (var i = 0; i < @case.Length; i += 2)
94 {
95 if (!@case[i].Invoke(query))
96 continue;
97  
98 if (@case[i + 1].Invoke(query))
99 return;
100  
101 match = true;
102 }
103  
104 if (!match)
105 @default.Invoke(query);
106  
107 }
108  
109 ///////////////////////////////////////////////////////////////////////////
110 // Copyright (C) 2017 Wizardry and Steamworks - License: GNU GPLv3 //
111 ///////////////////////////////////////////////////////////////////////////
112 /// <summary>
32 office 113 /// Invokes pf in case the predicate p resolves or qf in case the predicate q resolves, or ef otherwise.
114 /// </summary>
115 /// <typeparam name="T">the type of items in the query</typeparam>
116 /// <param name="query">the selector query</param>
117 /// <param name="p">the condition for invoking pf</param>
118 /// <param name="pf">the action to invoke in case p resolves</param>
119 /// <param name="q">the condition for invoking qf</param>
120 /// <param name="qf">the action to invoke in case q resolves</param>
121 /// <param name="ef">the action to invoke otherwise</param>
122 public static void ForAll<T>(this ParallelQuery<T> query, Predicate<T> p, Action<T> pf, Predicate<T> q, Action<T> qf, Action<T> ef)
123 {
124 query.ForAll(o =>
125 {
126 if (p.Invoke(o))
127 {
128 pf.Invoke(o);
129 }
130 else if (q.Invoke(o))
131 {
132 qf.Invoke(o);
133 }
134 else
135 {
136 ef.Invoke(o);
137 }
138 });
139 }
140  
141 ///////////////////////////////////////////////////////////////////////////
142 // Copyright (C) 2017 Wizardry and Steamworks - License: GNU GPLv3 //
143 ///////////////////////////////////////////////////////////////////////////
144 /// <summary>
145 /// Invokes pf in case the predicate p resolves or qf in case the predicate q resolves.
146 /// </summary>
147 /// <typeparam name="T">the type of items in the query</typeparam>
148 /// <param name="query">the selector query</param>
149 /// <param name="p">the condition for invoking pf</param>
150 /// <param name="pf">the action to invoke in case p resolves</param>
151 /// <param name="q">the condition for invoking qf</param>
152 /// <param name="qf">the action to invoke in case q resolves</param>
153 public static void ForAll<T>(this ParallelQuery<T> query, Predicate<T> p, Action<T> pf, Predicate<T> q, Action<T> qf)
154 {
155 query.ForAll(o =>
156 {
157 if (p.Invoke(o))
158 {
159 pf.Invoke(o);
160 return;
161 }
162  
163 if (q.Invoke(o))
164 {
165 qf.Invoke(o);
166 return;
167 }
168 });
169 }
170  
171 ///////////////////////////////////////////////////////////////////////////
172 // Copyright (C) 2017 Wizardry and Steamworks - License: GNU GPLv3 //
173 ///////////////////////////////////////////////////////////////////////////
174 /// <summary>
175 /// Invokes pass if and only if predicate resovles or fail otherwise.
176 /// </summary>
177 /// <typeparam name="T">the type of items in the query</typeparam>
178 /// <param name="query">the selector query</param>
179 /// <param name="condition">the condition for invoking pf</param>
180 /// <param name="pass">the function to invoke in case the predicate resolves</param>
181 /// <param name="fail">the function to invoke otherwise</param>
182 public static void ForAll<T>(this ParallelQuery<T> query, Predicate<T> condition, Action<T> pass, Action<T> fail)
183 {
184 query.ForAll(o =>
185 {
186 switch (condition.Invoke(o))
187 {
188 case true:
189 pass.Invoke(o);
190 return;
191  
192 default:
193 fail.Invoke(o);
194 return;
195 }
196 });
197 }
198  
199 ///////////////////////////////////////////////////////////////////////////
200 // Copyright (C) 2017 Wizardry and Steamworks - License: GNU GPLv3 //
201 ///////////////////////////////////////////////////////////////////////////
202 /// <summary>
203 /// Invokes pass if and only if condition holds or fail otherwise.
204 /// </summary>
205 /// <typeparam name="T">the return type of the pass and fail functions</typeparam>
206 /// <param name="condition">the branch condition</param>
207 /// <param name="pass">function with no parameters and return type T in case condition passes</param>
208 /// <param name="fail">function with no parameters and return type T in case condition fails</param>
209 /// <returns>the result of pass in case condition holds or the result of fail otherwise</returns>
210 public static T IfElse<T>(this bool condition, Func<T> pass, Func<T> fail)
211 {
212 return condition ? pass.Invoke() : fail.Invoke();
213 }
214  
215 ///////////////////////////////////////////////////////////////////////////
216 // Copyright (C) 2017 Wizardry and Steamworks - License: GNU GPLv3 //
217 ///////////////////////////////////////////////////////////////////////////
218 /// <summary>
219 /// Invokes pass if and only if condition holds or fail otherwise.
220 /// </summary>
221 /// <typeparam name="U">the type of the argument to pass and fail</typeparam>
222 /// <typeparam name="V">the return type of pass and fail</typeparam>
223 /// <param name="condition">the branch condition</param>
224 /// <param name="pass">function that takes argument arg and returns type V in case condition holds</param>
225 /// <param name="fail">function that takes argument arg and returns type V in case condition fails</param>
226 /// <param name="arg">the argument passed to pass or fail functions</param>
227 /// <returns>the result of pass in case condition holds or the result of fail otherwise</returns>
228 public static V IfElse<U, V>(this bool condition, Func<U, V> pass, Func<U, V> fail, U arg = default(U))
229 {
230 return condition ? pass.Invoke(arg) : fail.Invoke(arg);
231 }
232  
233 ///////////////////////////////////////////////////////////////////////////
234 // Copyright (C) 2017 Wizardry and Steamworks - License: GNU GPLv3 //
235 ///////////////////////////////////////////////////////////////////////////
236 /// <summary>
237 /// Invokes pass if and only if condition holds or fail otherwise.
238 /// </summary>
239 /// <typeparam name="T">the type of the argument to pass and fail</typeparam>
240 /// <param name="condition">the branch condition</param>
241 /// <param name="pass">function that takes argument arg and returns nothing in case condition holds</param>
242 /// <param name="fail">function that takes argument arg and returns nothing in case condition fails</param>
243 /// <param name="arg">the optional argument passed to pass or fail functions</param>
244 public static void IfElse<T>(this bool condition, Action<T> pass, Action<T> fail, T arg = default(T))
245 {
246 switch (condition)
247 {
248 case true:
249 pass.Invoke(arg);
250 return;
251  
252 default:
253 fail.Invoke(arg);
254 return;
255 }
256 }
257  
258 ///////////////////////////////////////////////////////////////////////////
259 // Copyright (C) 2017 Wizardry and Steamworks - License: GNU GPLv3 //
260 ///////////////////////////////////////////////////////////////////////////
261 /// <summary>
262 /// Invokes pass if and only if condition holds or fail otherwise.
263 /// </summary>
264 /// <typeparam name="U">the type of the first argument to the pass or fail functions</typeparam>
265 /// <typeparam name="V">the type of the second argument to the pass or fail functions</typeparam>
266 /// <param name="condition">the branch condition</param>
267 /// <param name="pass">function that takes argument arg and returns nothing in case condition holds</param>
268 /// <param name="fail">function that takes argument arg and returns nothing in case condition fails</param>
269 /// <param name="arga">first optional argument passed to pass or fail functions</param>
270 /// <param name="argb">second optional argument passed to pass or fail functions</param>
271 public static void IfElse<U, V>(this bool condition, Action<U, V> pass, Action<U, V> fail, U arga = default(U), V argb = default(V))
272 {
273 switch (condition)
274 {
275 case true:
276 pass.Invoke(arga, argb);
277 return;
278  
279 default:
280 fail.Invoke(arga, argb);
281 return;
282 }
283 }
284  
285 ///////////////////////////////////////////////////////////////////////////
11 office 286 // Copyright (C) 2016 Wizardry and Steamworks - License: GNU GPLv3 //
287 ///////////////////////////////////////////////////////////////////////////
288 /// <summary>
289 /// Returns true of an enumerable contains more than one element.
290 /// </summary>
291 /// <typeparam name="T">the type of the enumeration</typeparam>
292 /// <param name="e">the enumeration</param>
293 /// <returns>true if enumeration contains more than one element</returns>
294 /// <remarks>O(2) worst case</remarks>
295 public static bool Some<T>(this IEnumerable<T> e)
296 {
297 var i = 0;
298 using (var iter = e.GetEnumerator())
299 {
300 while (iter.MoveNext())
301 {
302 if (++i > 1)
303 return true;
304 }
305 return false;
306 }
307 }
308  
309 /// <summary>
29 office 310 /// Sequentially removes all the elements from the first sequence that are in the second sequence
311 /// or all the elements from the second sequence that are in the first sequence.
11 office 312 /// </summary>
313 /// <typeparam name="T">the type o the collection</typeparam>
314 /// <param name="o">the first sequence to remove from</param>
315 /// <param name="p">the second sequence to remove</param>
29 office 316 /// <returns>the first sequence excluding the second sequence or the second sequence excluding the first sequence</returns>
317 public static IEnumerable<T> SequenceExceptAny<T>(this IEnumerable<T> o, IEnumerable<T> p) where T : IEquatable<T>
11 office 318 {
319 var l = new List<T>(o);
320 var r = new List<T>(p);
321 return l.Count > r.Count
322 ? l.Zip(r, (x, y) => x.Equals(y) ? default(T) : y)
43 office 323 .Concat(l.Skip(r.Count))
11 office 324 .Where(q => q != null && !q.Equals(default(T)))
325 : r.Zip(l, (x, y) => x.Equals(y) ? default(T) : y)
43 office 326 .Concat(r.Skip(l.Count))
11 office 327 .Where(q => q != null && !q.Equals(default(T)));
328 }
29 office 329  
330 /// <summary>
331 /// Sequentially removes all the elements from the first sequence that are in the second sequence.
332 /// </summary>
333 /// <typeparam name="T">the type o the collection</typeparam>
334 /// <param name="o">the first sequence to remove from</param>
335 /// <param name="p">the second sequence to remove</param>
336 /// <returns>the first sequence excluding the second sequence</returns>
337 public static IEnumerable<T> SequenceExcept<T>(this IEnumerable<T> a, IEnumerable<T> b) where T : IEquatable<T>
338 {
43 office 339 using (var ea = a.GetEnumerator())
29 office 340 {
43 office 341 using (var eb = b.GetEnumerator())
342 {
343 while (ea.MoveNext())
344 {
345 if (eb.MoveNext() && ea.Current.Equals(eb.Current))
346 continue;
347 yield return ea.Current;
348 }
349 }
29 office 350 }
351 }
11 office 352 }
27 office 353 }