wasSharp – Blame information for rev 47

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>
69 /// Invokes pf in case the predicate p resolves or qf in case the predicate q resolves, or ef otherwise.
70 /// </summary>
71 /// <typeparam name="T">the type of items in the query</typeparam>
72 /// <param name="query">the selector query</param>
73 /// <param name="p">the condition for invoking pf</param>
74 /// <param name="pf">the action to invoke in case p resolves</param>
75 /// <param name="q">the condition for invoking qf</param>
76 /// <param name="qf">the action to invoke in case q resolves</param>
77 /// <param name="ef">the action to invoke otherwise</param>
78 public static void ForAll<T>(this ParallelQuery<T> query, Predicate<T> p, Action<T> pf, Predicate<T> q, Action<T> qf, Action<T> ef)
79 {
80 query.ForAll(o =>
81 {
82 if (p.Invoke(o))
83 {
84 pf.Invoke(o);
85 }
86 else if (q.Invoke(o))
87 {
88 qf.Invoke(o);
89 }
90 else
91 {
92 ef.Invoke(o);
93 }
94 });
95 }
96  
97 ///////////////////////////////////////////////////////////////////////////
98 // Copyright (C) 2017 Wizardry and Steamworks - License: GNU GPLv3 //
99 ///////////////////////////////////////////////////////////////////////////
100 /// <summary>
101 /// Invokes pf in case the predicate p resolves or qf in case the predicate q resolves.
102 /// </summary>
103 /// <typeparam name="T">the type of items in the query</typeparam>
104 /// <param name="query">the selector query</param>
105 /// <param name="p">the condition for invoking pf</param>
106 /// <param name="pf">the action to invoke in case p resolves</param>
107 /// <param name="q">the condition for invoking qf</param>
108 /// <param name="qf">the action to invoke in case q resolves</param>
109 public static void ForAll<T>(this ParallelQuery<T> query, Predicate<T> p, Action<T> pf, Predicate<T> q, Action<T> qf)
110 {
111 query.ForAll(o =>
112 {
113 if (p.Invoke(o))
114 {
115 pf.Invoke(o);
116 return;
117 }
118  
119 if (q.Invoke(o))
120 {
121 qf.Invoke(o);
122 return;
123 }
124 });
125 }
126  
127 ///////////////////////////////////////////////////////////////////////////
128 // Copyright (C) 2017 Wizardry and Steamworks - License: GNU GPLv3 //
129 ///////////////////////////////////////////////////////////////////////////
130 /// <summary>
131 /// Invokes pass if and only if predicate resovles or fail otherwise.
132 /// </summary>
133 /// <typeparam name="T">the type of items in the query</typeparam>
134 /// <param name="query">the selector query</param>
135 /// <param name="condition">the condition for invoking pf</param>
136 /// <param name="pass">the function to invoke in case the predicate resolves</param>
137 /// <param name="fail">the function to invoke otherwise</param>
138 public static void ForAll<T>(this ParallelQuery<T> query, Predicate<T> condition, Action<T> pass, Action<T> fail)
139 {
140 query.ForAll(o =>
141 {
142 switch (condition.Invoke(o))
143 {
144 case true:
145 pass.Invoke(o);
146 return;
147  
148 default:
149 fail.Invoke(o);
150 return;
151 }
152 });
153 }
154  
155 ///////////////////////////////////////////////////////////////////////////
156 // Copyright (C) 2017 Wizardry and Steamworks - License: GNU GPLv3 //
157 ///////////////////////////////////////////////////////////////////////////
158 /// <summary>
159 /// Invokes pass if and only if condition holds or fail otherwise.
160 /// </summary>
161 /// <typeparam name="T">the return type of the pass and fail functions</typeparam>
162 /// <param name="condition">the branch condition</param>
163 /// <param name="pass">function with no parameters and return type T in case condition passes</param>
164 /// <param name="fail">function with no parameters and return type T in case condition fails</param>
165 /// <returns>the result of pass in case condition holds or the result of fail otherwise</returns>
166 public static T IfElse<T>(this bool condition, Func<T> pass, Func<T> fail)
167 {
168 return condition ? pass.Invoke() : fail.Invoke();
169 }
170  
171 ///////////////////////////////////////////////////////////////////////////
172 // Copyright (C) 2017 Wizardry and Steamworks - License: GNU GPLv3 //
173 ///////////////////////////////////////////////////////////////////////////
174 /// <summary>
175 /// Invokes pass if and only if condition holds or fail otherwise.
176 /// </summary>
177 /// <typeparam name="U">the type of the argument to pass and fail</typeparam>
178 /// <typeparam name="V">the return type of pass and fail</typeparam>
179 /// <param name="condition">the branch condition</param>
180 /// <param name="pass">function that takes argument arg and returns type V in case condition holds</param>
181 /// <param name="fail">function that takes argument arg and returns type V in case condition fails</param>
182 /// <param name="arg">the argument passed to pass or fail functions</param>
183 /// <returns>the result of pass in case condition holds or the result of fail otherwise</returns>
184 public static V IfElse<U, V>(this bool condition, Func<U, V> pass, Func<U, V> fail, U arg = default(U))
185 {
186 return condition ? pass.Invoke(arg) : fail.Invoke(arg);
187 }
188  
189 ///////////////////////////////////////////////////////////////////////////
190 // Copyright (C) 2017 Wizardry and Steamworks - License: GNU GPLv3 //
191 ///////////////////////////////////////////////////////////////////////////
192 /// <summary>
193 /// Invokes pass if and only if condition holds or fail otherwise.
194 /// </summary>
195 /// <typeparam name="T">the type of the argument to pass and fail</typeparam>
196 /// <param name="condition">the branch condition</param>
197 /// <param name="pass">function that takes argument arg and returns nothing in case condition holds</param>
198 /// <param name="fail">function that takes argument arg and returns nothing in case condition fails</param>
199 /// <param name="arg">the optional argument passed to pass or fail functions</param>
200 public static void IfElse<T>(this bool condition, Action<T> pass, Action<T> fail, T arg = default(T))
201 {
202 switch (condition)
203 {
204 case true:
205 pass.Invoke(arg);
206 return;
207  
208 default:
209 fail.Invoke(arg);
210 return;
211 }
212 }
213  
214 ///////////////////////////////////////////////////////////////////////////
215 // Copyright (C) 2017 Wizardry and Steamworks - License: GNU GPLv3 //
216 ///////////////////////////////////////////////////////////////////////////
217 /// <summary>
218 /// Invokes pass if and only if condition holds or fail otherwise.
219 /// </summary>
220 /// <typeparam name="U">the type of the first argument to the pass or fail functions</typeparam>
221 /// <typeparam name="V">the type of the second argument to the pass or fail functions</typeparam>
222 /// <param name="condition">the branch condition</param>
223 /// <param name="pass">function that takes argument arg and returns nothing in case condition holds</param>
224 /// <param name="fail">function that takes argument arg and returns nothing in case condition fails</param>
225 /// <param name="arga">first optional argument passed to pass or fail functions</param>
226 /// <param name="argb">second optional argument passed to pass or fail functions</param>
227 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))
228 {
229 switch (condition)
230 {
231 case true:
232 pass.Invoke(arga, argb);
233 return;
234  
235 default:
236 fail.Invoke(arga, argb);
237 return;
238 }
239 }
240  
241 ///////////////////////////////////////////////////////////////////////////
11 office 242 // Copyright (C) 2016 Wizardry and Steamworks - License: GNU GPLv3 //
243 ///////////////////////////////////////////////////////////////////////////
244 /// <summary>
245 /// Returns true of an enumerable contains more than one element.
246 /// </summary>
247 /// <typeparam name="T">the type of the enumeration</typeparam>
248 /// <param name="e">the enumeration</param>
249 /// <returns>true if enumeration contains more than one element</returns>
250 /// <remarks>O(2) worst case</remarks>
251 public static bool Some<T>(this IEnumerable<T> e)
252 {
253 var i = 0;
254 using (var iter = e.GetEnumerator())
255 {
256 while (iter.MoveNext())
257 {
258 if (++i > 1)
259 return true;
260 }
261 return false;
262 }
263 }
264  
265 /// <summary>
29 office 266 /// Sequentially removes all the elements from the first sequence that are in the second sequence
267 /// or all the elements from the second sequence that are in the first sequence.
11 office 268 /// </summary>
269 /// <typeparam name="T">the type o the collection</typeparam>
270 /// <param name="o">the first sequence to remove from</param>
271 /// <param name="p">the second sequence to remove</param>
29 office 272 /// <returns>the first sequence excluding the second sequence or the second sequence excluding the first sequence</returns>
273 public static IEnumerable<T> SequenceExceptAny<T>(this IEnumerable<T> o, IEnumerable<T> p) where T : IEquatable<T>
11 office 274 {
275 var l = new List<T>(o);
276 var r = new List<T>(p);
277 return l.Count > r.Count
278 ? l.Zip(r, (x, y) => x.Equals(y) ? default(T) : y)
43 office 279 .Concat(l.Skip(r.Count))
11 office 280 .Where(q => q != null && !q.Equals(default(T)))
281 : r.Zip(l, (x, y) => x.Equals(y) ? default(T) : y)
43 office 282 .Concat(r.Skip(l.Count))
11 office 283 .Where(q => q != null && !q.Equals(default(T)));
284 }
29 office 285  
286 /// <summary>
287 /// Sequentially removes all the elements from the first sequence that are in the second sequence.
288 /// </summary>
289 /// <typeparam name="T">the type o the collection</typeparam>
290 /// <param name="o">the first sequence to remove from</param>
291 /// <param name="p">the second sequence to remove</param>
292 /// <returns>the first sequence excluding the second sequence</returns>
293 public static IEnumerable<T> SequenceExcept<T>(this IEnumerable<T> a, IEnumerable<T> b) where T : IEquatable<T>
294 {
43 office 295 using (var ea = a.GetEnumerator())
29 office 296 {
43 office 297 using (var eb = b.GetEnumerator())
298 {
299 while (ea.MoveNext())
300 {
301 if (eb.MoveNext() && ea.Current.Equals(eb.Current))
302 continue;
303 yield return ea.Current;
304 }
305 }
29 office 306 }
307 }
11 office 308 }
27 office 309 }