/////////////////////////////////////////////////////////////////////////// // Copyright (C) Wizardry and Steamworks 2013 - License: GNU GPLv3 // // Please see: http://www.gnu.org/licenses/gpl.html for legal details, // // rights of fair usage, the disclaimer and warranty conditions. // /////////////////////////////////////////////////////////////////////////// using System; using System.Collections.Generic; using System.Linq; namespace wasSharp.Lambda { public static class Extensions { /////////////////////////////////////////////////////////////////////////// // Copyright (C) 2017 Wizardry and Steamworks - License: GNU GPLv3 // /////////////////////////////////////////////////////////////////////////// /// /// A functional implementation of a switch clause. /// /// the type of items in the query /// the selector query /// the function to execute when no case matches /// a list of predicates representing the switch cases, /// where each predicate has to return True or False indicating whether /// fallthrough should occur. /// /// when used, the default action must be explicitly specified /// due to language restrictions /// public static void Switch(this IEnumerable query, // default Action @default, // case // case // ... params Predicate[] @case) { if (@case.Length % 2 != 0) throw new ArgumentException("Pairs of predicates expected."); var enumerable = query as IList ?? query.ToList(); using (var iter = enumerable.GetEnumerator()) { while (iter.MoveNext()) { var match = false; for (var i = 0; i < @case.Length; i += 2) { if (!@case[i].Invoke(iter.Current)) continue; if (@case[i + 1].Invoke(iter.Current)) return; match = true; } if (!match) @default.Invoke(iter.Current); } } } /////////////////////////////////////////////////////////////////////////// // Copyright (C) 2017 Wizardry and Steamworks - License: GNU GPLv3 // /////////////////////////////////////////////////////////////////////////// /// /// A functional implementation of a switch clause. /// /// the type of the item to query /// the selector query /// the function to execute when no case matches /// a list of predicates representing the switch cases, /// where each predicate has to return True or False indicating whether /// fallthrough should occur. /// /// when used, the default action must be explicitly specified /// due to language restrictions /// public static void Switch(this T query, // default Action @default, // case // case // ... params Predicate[] @case) { if (@case.Length % 2 != 0) throw new ArgumentException("Pairs of predicates expected."); var match = false; for (var i = 0; i < @case.Length; i += 2) { if (!@case[i].Invoke(query)) continue; if (@case[i + 1].Invoke(query)) return; match = true; } if (!match) @default.Invoke(query); } /////////////////////////////////////////////////////////////////////////// // Copyright (C) 2017 Wizardry and Steamworks - License: GNU GPLv3 // /////////////////////////////////////////////////////////////////////////// /// /// Invokes pf in case the predicate p resolves or qf in case the predicate q resolves, or ef otherwise. /// /// the type of items in the query /// the selector query /// the condition for invoking pf /// the action to invoke in case p resolves /// the condition for invoking qf /// the action to invoke in case q resolves /// the action to invoke otherwise public static void ForAll(this ParallelQuery query, Predicate p, Action pf, Predicate q, Action qf, Action ef) { query.ForAll(o => { if (p.Invoke(o)) { pf.Invoke(o); } else if (q.Invoke(o)) { qf.Invoke(o); } else { ef.Invoke(o); } }); } /////////////////////////////////////////////////////////////////////////// // Copyright (C) 2017 Wizardry and Steamworks - License: GNU GPLv3 // /////////////////////////////////////////////////////////////////////////// /// /// Invokes pf in case the predicate p resolves or qf in case the predicate q resolves. /// /// the type of items in the query /// the selector query /// the condition for invoking pf /// the action to invoke in case p resolves /// the condition for invoking qf /// the action to invoke in case q resolves public static void ForAll(this ParallelQuery query, Predicate p, Action pf, Predicate q, Action qf) { query.ForAll(o => { if (p.Invoke(o)) { pf.Invoke(o); return; } if (q.Invoke(o)) { qf.Invoke(o); return; } }); } /////////////////////////////////////////////////////////////////////////// // Copyright (C) 2017 Wizardry and Steamworks - License: GNU GPLv3 // /////////////////////////////////////////////////////////////////////////// /// /// Invokes pass if and only if predicate resovles or fail otherwise. /// /// the type of items in the query /// the selector query /// the condition for invoking pf /// the function to invoke in case the predicate resolves /// the function to invoke otherwise public static void ForAll(this ParallelQuery query, Predicate condition, Action pass, Action fail) { query.ForAll(o => { switch (condition.Invoke(o)) { case true: pass.Invoke(o); return; default: fail.Invoke(o); return; } }); } /////////////////////////////////////////////////////////////////////////// // Copyright (C) 2017 Wizardry and Steamworks - License: GNU GPLv3 // /////////////////////////////////////////////////////////////////////////// /// /// Invokes pass if and only if condition holds or fail otherwise. /// /// the return type of the pass and fail functions /// the branch condition /// function with no parameters and return type T in case condition passes /// function with no parameters and return type T in case condition fails /// the result of pass in case condition holds or the result of fail otherwise public static V IfElse(this T arg, Func condition, Func pass, Func fail) { return condition.Invoke(arg) ? pass.Invoke(arg) : fail.Invoke(arg); } /////////////////////////////////////////////////////////////////////////// // Copyright (C) 2017 Wizardry and Steamworks - License: GNU GPLv3 // /////////////////////////////////////////////////////////////////////////// /// /// Invokes pass if and only if condition holds or fail otherwise. /// /// the return type of the pass and fail functions /// the branch condition /// function with no parameters and return type T in case condition passes /// function with no parameters and return type T in case condition fails /// the result of pass in case condition holds or the result of fail otherwise public static T IfElse(this bool condition, Func pass, Func fail) { return condition ? pass.Invoke() : fail.Invoke(); } /////////////////////////////////////////////////////////////////////////// // Copyright (C) 2017 Wizardry and Steamworks - License: GNU GPLv3 // /////////////////////////////////////////////////////////////////////////// /// /// Invokes pass if and only if condition holds or fail otherwise. /// /// the type of the argument to pass and fail /// the return type of pass and fail /// the branch condition /// function that takes argument arg and returns type V in case condition holds /// function that takes argument arg and returns type V in case condition fails /// the argument passed to pass or fail functions /// the result of pass in case condition holds or the result of fail otherwise public static V IfElse(this bool condition, Func pass, Func fail, U arg = default(U)) { return condition ? pass.Invoke(arg) : fail.Invoke(arg); } /////////////////////////////////////////////////////////////////////////// // Copyright (C) 2017 Wizardry and Steamworks - License: GNU GPLv3 // /////////////////////////////////////////////////////////////////////////// /// /// Invokes pass if and only if condition holds or fail otherwise. /// /// the type of the argument to pass and fail /// the branch condition /// function that takes argument arg and returns nothing in case condition holds /// function that takes argument arg and returns nothing in case condition fails /// the optional argument passed to pass or fail functions public static void IfElse(this bool condition, Action pass, Action fail, T arg = default(T)) { switch (condition) { case true: pass.Invoke(arg); return; default: fail.Invoke(arg); return; } } /////////////////////////////////////////////////////////////////////////// // Copyright (C) 2017 Wizardry and Steamworks - License: GNU GPLv3 // /////////////////////////////////////////////////////////////////////////// /// /// Invokes pass if and only if condition holds or fail otherwise. /// /// the type of the first argument to the pass or fail functions /// the type of the second argument to the pass or fail functions /// the branch condition /// function that takes argument arg and returns nothing in case condition holds /// function that takes argument arg and returns nothing in case condition fails /// first optional argument passed to pass or fail functions /// second optional argument passed to pass or fail functions public static void IfElse(this bool condition, Action pass, Action fail, U arga = default(U), V argb = default(V)) { switch (condition) { case true: pass.Invoke(arga, argb); return; default: fail.Invoke(arga, argb); return; } } /////////////////////////////////////////////////////////////////////////// // Copyright (C) 2016 Wizardry and Steamworks - License: GNU GPLv3 // /////////////////////////////////////////////////////////////////////////// /// /// Returns true of an enumerable contains more than one element. /// /// the type of the enumeration /// the enumeration /// true if enumeration contains more than one element /// O(2) worst case public static bool Some(this IEnumerable e) { var i = 0; using (var iter = e.GetEnumerator()) { while (iter.MoveNext()) { if (++i > 1) return true; } return false; } } } }