wasSharp – Blame information for rev 43

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