wasSharp – Blame information for rev 46

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