wasSharp – Diff between revs 53 and 55

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