diff --git a/Underscore.Test/Collection/CreationTest.cs b/Underscore.Test/Collection/CreationTest.cs index 77364e6..d2179bb 100644 Binary files a/Underscore.Test/Collection/CreationTest.cs and b/Underscore.Test/Collection/CreationTest.cs differ diff --git a/Underscore.Test/Function/BooleanTest.cs b/Underscore.Test/Function/BooleanTest.cs new file mode 100644 index 0000000..6086acd --- /dev/null +++ b/Underscore.Test/Function/BooleanTest.cs @@ -0,0 +1,109 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using Underscore.Function; + +namespace Underscore.Test.Function +{ + [TestClass] + public class BooleanTest + { + [TestMethod] + public void FunctionNegate() + { + var testing = new BooleanComponent(); + var function = testing.Negate( () => true); + + Assert.IsFalse(function()); + + var fn2 = testing.Negate(new Func(s => s == "s")); + Assert.IsTrue(fn2("l")); + Assert.IsFalse(fn2("s")); + + } + + [TestMethod] + public void FunctionOrPositive() + { + bool[] wasCalled = {false, false, false, false}; + Func[] toCall = + { + (s,s2) => wasCalled[0] = s == "s1" && s2 == "s2", + (s,s2) => wasCalled[1] = s == "s1" && s2 == "s2", + (s,s2) => wasCalled[2] = s == "s1" && s2 == "s2", + (s,s2) => wasCalled[3] = s == "s1" && s2 == "s2" + }; + var testing = new BooleanComponent(); + var result = testing.Or(toCall); + Assert.IsTrue(result("s1","s2")); + Assert.IsTrue(wasCalled[0]); + Assert.IsFalse(wasCalled[1]); + Assert.IsFalse(wasCalled[2]); + Assert.IsFalse(wasCalled[3]); + + } + + + [TestMethod] + public void FunctionOrNegative() + { + bool[] wasCalled = { true, true, true, true}; + Func[] toCall = + { + (s,s2) => wasCalled[0] = s != "s1" && s2 != "s2", + (s,s2) => wasCalled[1] = s != "s1" && s2 != "s2", + (s,s2) => wasCalled[2] = s != "s1" && s2 != "s2", + (s,s2) => wasCalled[3] = s != "s1" && s2 != "s2" + }; + var testing = new BooleanComponent(); + var result = testing.Or(toCall); + Assert.IsFalse(result("s1", "s2")); + foreach (var b in wasCalled) + { + Assert.IsFalse(b); + } + } + + + + [TestMethod] + public void FunctionAndPositive() + { + bool[] wasCalled = { false, false, false, false }; + Func[] toCall = + { + (s,s2) => wasCalled[0] = s == "s1" && s2 == "s2", + (s,s2) => wasCalled[1] = s == "s1" && s2 == "s2", + (s,s2) => wasCalled[2] = s == "s1" && s2 == "s2", + (s,s2) => wasCalled[3] = s == "s1" && s2 == "s2" + }; + var testing = new BooleanComponent(); + var result = testing.And(toCall); + Assert.IsTrue(result("s1", "s2")); + foreach (var b in wasCalled) + { + Assert.IsTrue(b); + } + } + + + [TestMethod] + public void FunctionAndNegative() + { + bool[] wasCalled = { true, true, true, true }; + Func[] toCall = + { + (s,s2) => wasCalled[0] = s != "s1" && s2 != "s2", + (s,s2) => wasCalled[1] = s == "s1" && s2 == "s2", + (s,s2) => wasCalled[2] = s == "s1" && s2 == "s2", + (s,s2) => wasCalled[3] = s == "s1" && s2 == "s2" + }; + var testing = new BooleanComponent(); + var result = testing.And(toCall); + Assert.IsFalse(result("s1", "s2")); + Assert.IsFalse(wasCalled[0]); + + for(int i=1;i - + + False + @@ -69,6 +71,7 @@ + diff --git a/Underscore.cs.sln b/Underscore.cs.sln index be10bb0..f514ee3 100644 --- a/Underscore.cs.sln +++ b/Underscore.cs.sln @@ -1,12 +1,14 @@  Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 2013 -VisualStudioVersion = 12.0.30723.0 +# Visual Studio 14 +VisualStudioVersion = 14.0.23107.0 MinimumVisualStudioVersion = 10.0.40219.1 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Underscore.cs", "Underscore.cs\Underscore.cs.csproj", "{946C4F0D-101A-46DB-8C41-C102D0947E99}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Underscore.Test", "Underscore.Test\Underscore.Test.csproj", "{D8C013CF-12B1-4743-9044-D92903510970}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PreformanceTest", "PreformanceTest\PreformanceTest.csproj", "{B34E3068-1596-4F2D-B1BA-39074E0B2661}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -21,6 +23,10 @@ Global {D8C013CF-12B1-4743-9044-D92903510970}.Debug|Any CPU.Build.0 = Debug|Any CPU {D8C013CF-12B1-4743-9044-D92903510970}.Release|Any CPU.ActiveCfg = Release|Any CPU {D8C013CF-12B1-4743-9044-D92903510970}.Release|Any CPU.Build.0 = Release|Any CPU + {B34E3068-1596-4F2D-B1BA-39074E0B2661}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {B34E3068-1596-4F2D-B1BA-39074E0B2661}.Debug|Any CPU.Build.0 = Debug|Any CPU + {B34E3068-1596-4F2D-B1BA-39074E0B2661}.Release|Any CPU.ActiveCfg = Release|Any CPU + {B34E3068-1596-4F2D-B1BA-39074E0B2661}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/Underscore.cs/Collection/Contract/Creation.cs b/Underscore.cs/Collection/Contract/Creation.cs index 741fd05..120b4bb 100644 --- a/Underscore.cs/Collection/Contract/Creation.cs +++ b/Underscore.cs/Collection/Contract/Creation.cs @@ -11,6 +11,9 @@ public interface ICreationComponent /// Func> Snapshot( IEnumerable collection ); + IEnumerable Extend(IEnumerable collection, int length); + + IEnumerable Infinite(IEnumerable collection); } } diff --git a/Underscore.cs/Collection/Implementation/Creation.cs b/Underscore.cs/Collection/Implementation/Creation.cs index 5a21be4..3d04d57 100644 --- a/Underscore.cs/Collection/Implementation/Creation.cs +++ b/Underscore.cs/Collection/Implementation/Creation.cs @@ -19,5 +19,46 @@ public Func> Snapshot( IEnumerable collection ) return ( ) => new List( tsnap ); } + public IEnumerable Extend(IEnumerable collection, int length) + { + using (var enmr = collection.GetEnumerator()) + { + if(!enmr.MoveNext()) throw new ApplicationException("Cannot extend an empty collection"); + yield return enmr.Current; + + //make i = 1 instead of zero to account for the first return. + for (int i = 1; i < length; i++) + { + if (!enmr.MoveNext()) { enmr.Reset(); + enmr.MoveNext(); + } + + yield return enmr.Current; + + } + } + } + + public IEnumerable Infinite(IEnumerable collection) + { + using (var enmr = collection.GetEnumerator()) + { + if (!enmr.MoveNext()) throw new ApplicationException("Cannot extend an empty collection"); + yield return enmr.Current; + + //make i = 1 instead of zero to account for the first return. + while(true) + { + + if (!enmr.MoveNext()) { enmr.Reset(); + enmr.MoveNext(); + } + + yield return enmr.Current; + + } + } + } + } } diff --git a/Underscore.cs/Function/Contract/Boolean.cs b/Underscore.cs/Function/Contract/Boolean.cs new file mode 100644 index 0000000..452b2e7 --- /dev/null +++ b/Underscore.cs/Function/Contract/Boolean.cs @@ -0,0 +1,322 @@ +using System; + +// This code has been automatically generated +// if you want to make changes make them on +// the corresponding the text template file +// Boolean.tt +namespace Underscore.Function +{ + + public interface IBooleanComponent + { + + + /// + /// Negates the logic of the passed function + /// + Func Negate( Func fn); + + + /// + /// Negates the logic of the passed function + /// + Func Negate( Func fn); + + + /// + /// Negates the logic of the passed function + /// + Func Negate( Func fn); + + + /// + /// Negates the logic of the passed function + /// + Func Negate( Func fn); + + + /// + /// Negates the logic of the passed function + /// + Func Negate( Func fn); + + + /// + /// Negates the logic of the passed function + /// + Func Negate( Func fn); + + + /// + /// Negates the logic of the passed function + /// + Func Negate( Func fn); + + + /// + /// Negates the logic of the passed function + /// + Func Negate( Func fn); + + + /// + /// Negates the logic of the passed function + /// + Func Negate( Func fn); + + + /// + /// Negates the logic of the passed function + /// + Func Negate( Func fn); + + + /// + /// Negates the logic of the passed function + /// + Func Negate( Func fn); + + + /// + /// Negates the logic of the passed function + /// + Func Negate( Func fn); + + + /// + /// Negates the logic of the passed function + /// + Func Negate( Func fn); + + + /// + /// Negates the logic of the passed function + /// + Func Negate( Func fn); + + + /// + /// Negates the logic of the passed function + /// + Func Negate( Func fn); + + + /// + /// Negates the logic of the passed function + /// + Func Negate( Func fn); + + + /// + /// Negates the logic of the passed function + /// + Func Negate( Func fn); + + + /// + /// Creates an aggregate function that is a result of the passed functions being called and being 'or'ed together + /// + Func Or( params Func[] fns); + + + /// + /// Creates an aggregate function that is a result of the passed functions being called and being 'or'ed together + /// + Func Or( params Func[] fns); + + + /// + /// Creates an aggregate function that is a result of the passed functions being called and being 'or'ed together + /// + Func Or( params Func[] fns); + + + /// + /// Creates an aggregate function that is a result of the passed functions being called and being 'or'ed together + /// + Func Or( params Func[] fns); + + + /// + /// Creates an aggregate function that is a result of the passed functions being called and being 'or'ed together + /// + Func Or( params Func[] fns); + + + /// + /// Creates an aggregate function that is a result of the passed functions being called and being 'or'ed together + /// + Func Or( params Func[] fns); + + + /// + /// Creates an aggregate function that is a result of the passed functions being called and being 'or'ed together + /// + Func Or( params Func[] fns); + + + /// + /// Creates an aggregate function that is a result of the passed functions being called and being 'or'ed together + /// + Func Or( params Func[] fns); + + + /// + /// Creates an aggregate function that is a result of the passed functions being called and being 'or'ed together + /// + Func Or( params Func[] fns); + + + /// + /// Creates an aggregate function that is a result of the passed functions being called and being 'or'ed together + /// + Func Or( params Func[] fns); + + + /// + /// Creates an aggregate function that is a result of the passed functions being called and being 'or'ed together + /// + Func Or( params Func[] fns); + + + /// + /// Creates an aggregate function that is a result of the passed functions being called and being 'or'ed together + /// + Func Or( params Func[] fns); + + + /// + /// Creates an aggregate function that is a result of the passed functions being called and being 'or'ed together + /// + Func Or( params Func[] fns); + + + /// + /// Creates an aggregate function that is a result of the passed functions being called and being 'or'ed together + /// + Func Or( params Func[] fns); + + + /// + /// Creates an aggregate function that is a result of the passed functions being called and being 'or'ed together + /// + Func Or( params Func[] fns); + + + /// + /// Creates an aggregate function that is a result of the passed functions being called and being 'or'ed together + /// + Func Or( params Func[] fns); + + + /// + /// Creates an aggregate function that is a result of the passed functions being called and being 'or'ed together + /// + Func Or( params Func[] fns); + + + /// + /// Creates an aggregate function that is a result of the passed functions being called and being 'and'ed together + /// + Func And( params Func[] fns); + + + /// + /// Creates an aggregate function that is a result of the passed functions being called and being 'and'ed together + /// + Func And( params Func[] fns); + + + /// + /// Creates an aggregate function that is a result of the passed functions being called and being 'and'ed together + /// + Func And( params Func[] fns); + + + /// + /// Creates an aggregate function that is a result of the passed functions being called and being 'and'ed together + /// + Func And( params Func[] fns); + + + /// + /// Creates an aggregate function that is a result of the passed functions being called and being 'and'ed together + /// + Func And( params Func[] fns); + + + /// + /// Creates an aggregate function that is a result of the passed functions being called and being 'and'ed together + /// + Func And( params Func[] fns); + + + /// + /// Creates an aggregate function that is a result of the passed functions being called and being 'and'ed together + /// + Func And( params Func[] fns); + + + /// + /// Creates an aggregate function that is a result of the passed functions being called and being 'and'ed together + /// + Func And( params Func[] fns); + + + /// + /// Creates an aggregate function that is a result of the passed functions being called and being 'and'ed together + /// + Func And( params Func[] fns); + + + /// + /// Creates an aggregate function that is a result of the passed functions being called and being 'and'ed together + /// + Func And( params Func[] fns); + + + /// + /// Creates an aggregate function that is a result of the passed functions being called and being 'and'ed together + /// + Func And( params Func[] fns); + + + /// + /// Creates an aggregate function that is a result of the passed functions being called and being 'and'ed together + /// + Func And( params Func[] fns); + + + /// + /// Creates an aggregate function that is a result of the passed functions being called and being 'and'ed together + /// + Func And( params Func[] fns); + + + /// + /// Creates an aggregate function that is a result of the passed functions being called and being 'and'ed together + /// + Func And( params Func[] fns); + + + /// + /// Creates an aggregate function that is a result of the passed functions being called and being 'and'ed together + /// + Func And( params Func[] fns); + + + /// + /// Creates an aggregate function that is a result of the passed functions being called and being 'and'ed together + /// + Func And( params Func[] fns); + + + /// + /// Creates an aggregate function that is a result of the passed functions being called and being 'and'ed together + /// + Func And( params Func[] fns); + + + } + +} \ No newline at end of file diff --git a/Underscore.cs/Function/Contract/Boolean.tt b/Underscore.cs/Function/Contract/Boolean.tt new file mode 100644 index 0000000..5740943 --- /dev/null +++ b/Underscore.cs/Function/Contract/Boolean.tt @@ -0,0 +1,83 @@ +<#@ template debug="false" hostspecific="false" language="C#" #> +<#@ assembly name="System.Core" #> +<#@ import namespace="System.Collections.Generic" #> +<#@ import namespace="System.Linq" #> +<#@ output extension=".cs" #> +using System; + +// This code has been automatically generated +// if you want to make changes make them on +// the corresponding the text template file +// Boolean.tt +namespace Underscore.Function +{ + + public interface IBooleanComponent + { + +<# + + var typeArgs = Enumerable.Range(1, 16).Select(i => "T" + i).ToArray(); + + + for (int i = 1; i < 18; i++) + { + var currTypeArgs = typeArgs.Take(i-1).ToArray(); + var currTypeArgsString = string.Join(", ", currTypeArgs); + var fnRetType = string.Join(", ", currTypeArgs.Concat(new[]{"bool"})); + + if (!string.IsNullOrEmpty(currTypeArgsString)) + currTypeArgsString = "<" + currTypeArgsString + ">"; + + #> + + /// + /// Negates the logic of the passed function + /// + Func<<#=fnRetType#>> Negate<#=currTypeArgsString#>( Func<<#=fnRetType#>> fn); + + <# + } + + for (int i = 1; i < 18; i++) + { + var currTypeArgs = typeArgs.Take(i-1).ToArray(); + var currTypeArgsString = string.Join(", ", currTypeArgs); + var fnRetType = string.Join(", ", currTypeArgs.Concat(new[]{"bool"})); + + if (!string.IsNullOrEmpty(currTypeArgsString)) + currTypeArgsString = "<" + currTypeArgsString + ">"; + + #> + + /// + /// Creates an aggregate function that is a result of the passed functions being called and being 'or'ed together + /// + Func<<#=fnRetType#>> Or<#=currTypeArgsString#>( params Func<<#=fnRetType#>>[] fns); + + <# + } + + for (int i = 1; i < 18; i++) + { + var currTypeArgs = typeArgs.Take(i-1).ToArray(); + var currTypeArgsString = string.Join(", ", currTypeArgs); + var fnRetType = string.Join(", ", currTypeArgs.Concat(new[]{"bool"})); + + if (!string.IsNullOrEmpty(currTypeArgsString)) + currTypeArgsString = "<" + currTypeArgsString + ">"; + + #> + + /// + /// Creates an aggregate function that is a result of the passed functions being called and being 'and'ed together + /// + Func<<#=fnRetType#>> And<#=currTypeArgsString#>( params Func<<#=fnRetType#>>[] fns); + + <# + } +#> + + } + +} \ No newline at end of file diff --git a/Underscore.cs/Function/Implementation/Boolean.cs b/Underscore.cs/Function/Implementation/Boolean.cs new file mode 100644 index 0000000..492f04e --- /dev/null +++ b/Underscore.cs/Function/Implementation/Boolean.cs @@ -0,0 +1,476 @@ +using System; +using System.Linq; + +// This code has been automatically generated +// if you want to make changes make them on +// the corresponding the text template file +// Boolean.tt +namespace Underscore.Function +{ + + public class BooleanComponent : IBooleanComponent + { + + + /// + /// Negates the logic of the passed function + /// + public Func Negate( Func fn) + { + return ()=>!fn(); + } + + + /// + /// Negates the logic of the passed function + /// + public Func Negate( Func fn) + { + return (a)=>!fn(a); + } + + + /// + /// Negates the logic of the passed function + /// + public Func Negate( Func fn) + { + return (a,b)=>!fn(a,b); + } + + + /// + /// Negates the logic of the passed function + /// + public Func Negate( Func fn) + { + return (a,b,c)=>!fn(a,b,c); + } + + + /// + /// Negates the logic of the passed function + /// + public Func Negate( Func fn) + { + return (a,b,c,d)=>!fn(a,b,c,d); + } + + + /// + /// Negates the logic of the passed function + /// + public Func Negate( Func fn) + { + return (a,b,c,d,e)=>!fn(a,b,c,d,e); + } + + + /// + /// Negates the logic of the passed function + /// + public Func Negate( Func fn) + { + return (a,b,c,d,e,f)=>!fn(a,b,c,d,e,f); + } + + + /// + /// Negates the logic of the passed function + /// + public Func Negate( Func fn) + { + return (a,b,c,d,e,f,g)=>!fn(a,b,c,d,e,f,g); + } + + + /// + /// Negates the logic of the passed function + /// + public Func Negate( Func fn) + { + return (a,b,c,d,e,f,g,h)=>!fn(a,b,c,d,e,f,g,h); + } + + + /// + /// Negates the logic of the passed function + /// + public Func Negate( Func fn) + { + return (a,b,c,d,e,f,g,h,i)=>!fn(a,b,c,d,e,f,g,h,i); + } + + + /// + /// Negates the logic of the passed function + /// + public Func Negate( Func fn) + { + return (a,b,c,d,e,f,g,h,i,j)=>!fn(a,b,c,d,e,f,g,h,i,j); + } + + + /// + /// Negates the logic of the passed function + /// + public Func Negate( Func fn) + { + return (a,b,c,d,e,f,g,h,i,j,k)=>!fn(a,b,c,d,e,f,g,h,i,j,k); + } + + + /// + /// Negates the logic of the passed function + /// + public Func Negate( Func fn) + { + return (a,b,c,d,e,f,g,h,i,j,k,l)=>!fn(a,b,c,d,e,f,g,h,i,j,k,l); + } + + + /// + /// Negates the logic of the passed function + /// + public Func Negate( Func fn) + { + return (a,b,c,d,e,f,g,h,i,j,k,l,m)=>!fn(a,b,c,d,e,f,g,h,i,j,k,l,m); + } + + + /// + /// Negates the logic of the passed function + /// + public Func Negate( Func fn) + { + return (a,b,c,d,e,f,g,h,i,j,k,l,m,n)=>!fn(a,b,c,d,e,f,g,h,i,j,k,l,m,n); + } + + + /// + /// Negates the logic of the passed function + /// + public Func Negate( Func fn) + { + return (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o)=>!fn(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o); + } + + + /// + /// Negates the logic of the passed function + /// + public Func Negate( Func fn) + { + return (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p)=>!fn(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p); + } + + + /// + /// Creates an aggregate function that is a result of the passed functions being called and being 'or'ed together + /// + public Func Or( params Func[] fns) + { + return ()=>fns.Aggregate(false,(prev,current)=>prev || current()); + } + + + /// + /// Creates an aggregate function that is a result of the passed functions being called and being 'or'ed together + /// + public Func Or( params Func[] fns) + { + return (a)=>fns.Aggregate(false,(prev,current)=>prev || current(a)); + } + + + /// + /// Creates an aggregate function that is a result of the passed functions being called and being 'or'ed together + /// + public Func Or( params Func[] fns) + { + return (a,b)=>fns.Aggregate(false,(prev,current)=>prev || current(a,b)); + } + + + /// + /// Creates an aggregate function that is a result of the passed functions being called and being 'or'ed together + /// + public Func Or( params Func[] fns) + { + return (a,b,c)=>fns.Aggregate(false,(prev,current)=>prev || current(a,b,c)); + } + + + /// + /// Creates an aggregate function that is a result of the passed functions being called and being 'or'ed together + /// + public Func Or( params Func[] fns) + { + return (a,b,c,d)=>fns.Aggregate(false,(prev,current)=>prev || current(a,b,c,d)); + } + + + /// + /// Creates an aggregate function that is a result of the passed functions being called and being 'or'ed together + /// + public Func Or( params Func[] fns) + { + return (a,b,c,d,e)=>fns.Aggregate(false,(prev,current)=>prev || current(a,b,c,d,e)); + } + + + /// + /// Creates an aggregate function that is a result of the passed functions being called and being 'or'ed together + /// + public Func Or( params Func[] fns) + { + return (a,b,c,d,e,f)=>fns.Aggregate(false,(prev,current)=>prev || current(a,b,c,d,e,f)); + } + + + /// + /// Creates an aggregate function that is a result of the passed functions being called and being 'or'ed together + /// + public Func Or( params Func[] fns) + { + return (a,b,c,d,e,f,g)=>fns.Aggregate(false,(prev,current)=>prev || current(a,b,c,d,e,f,g)); + } + + + /// + /// Creates an aggregate function that is a result of the passed functions being called and being 'or'ed together + /// + public Func Or( params Func[] fns) + { + return (a,b,c,d,e,f,g,h)=>fns.Aggregate(false,(prev,current)=>prev || current(a,b,c,d,e,f,g,h)); + } + + + /// + /// Creates an aggregate function that is a result of the passed functions being called and being 'or'ed together + /// + public Func Or( params Func[] fns) + { + return (a,b,c,d,e,f,g,h,i)=>fns.Aggregate(false,(prev,current)=>prev || current(a,b,c,d,e,f,g,h,i)); + } + + + /// + /// Creates an aggregate function that is a result of the passed functions being called and being 'or'ed together + /// + public Func Or( params Func[] fns) + { + return (a,b,c,d,e,f,g,h,i,j)=>fns.Aggregate(false,(prev,current)=>prev || current(a,b,c,d,e,f,g,h,i,j)); + } + + + /// + /// Creates an aggregate function that is a result of the passed functions being called and being 'or'ed together + /// + public Func Or( params Func[] fns) + { + return (a,b,c,d,e,f,g,h,i,j,k)=>fns.Aggregate(false,(prev,current)=>prev || current(a,b,c,d,e,f,g,h,i,j,k)); + } + + + /// + /// Creates an aggregate function that is a result of the passed functions being called and being 'or'ed together + /// + public Func Or( params Func[] fns) + { + return (a,b,c,d,e,f,g,h,i,j,k,l)=>fns.Aggregate(false,(prev,current)=>prev || current(a,b,c,d,e,f,g,h,i,j,k,l)); + } + + + /// + /// Creates an aggregate function that is a result of the passed functions being called and being 'or'ed together + /// + public Func Or( params Func[] fns) + { + return (a,b,c,d,e,f,g,h,i,j,k,l,m)=>fns.Aggregate(false,(prev,current)=>prev || current(a,b,c,d,e,f,g,h,i,j,k,l,m)); + } + + + /// + /// Creates an aggregate function that is a result of the passed functions being called and being 'or'ed together + /// + public Func Or( params Func[] fns) + { + return (a,b,c,d,e,f,g,h,i,j,k,l,m,n)=>fns.Aggregate(false,(prev,current)=>prev || current(a,b,c,d,e,f,g,h,i,j,k,l,m,n)); + } + + + /// + /// Creates an aggregate function that is a result of the passed functions being called and being 'or'ed together + /// + public Func Or( params Func[] fns) + { + return (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o)=>fns.Aggregate(false,(prev,current)=>prev || current(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o)); + } + + + /// + /// Creates an aggregate function that is a result of the passed functions being called and being 'or'ed together + /// + public Func Or( params Func[] fns) + { + return (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p)=>fns.Aggregate(false,(prev,current)=>prev || current(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p)); + } + + + /// + /// Creates an aggregate function that is a result of the passed functions being called and being 'and'ed together + /// + public Func And( params Func[] fns) + { + return ()=>fns.Aggregate(true,(prev,current)=>prev && current()); + } + + + /// + /// Creates an aggregate function that is a result of the passed functions being called and being 'and'ed together + /// + public Func And( params Func[] fns) + { + return (a)=>fns.Aggregate(true,(prev,current)=>prev && current(a)); + } + + + /// + /// Creates an aggregate function that is a result of the passed functions being called and being 'and'ed together + /// + public Func And( params Func[] fns) + { + return (a,b)=>fns.Aggregate(true,(prev,current)=>prev && current(a,b)); + } + + + /// + /// Creates an aggregate function that is a result of the passed functions being called and being 'and'ed together + /// + public Func And( params Func[] fns) + { + return (a,b,c)=>fns.Aggregate(true,(prev,current)=>prev && current(a,b,c)); + } + + + /// + /// Creates an aggregate function that is a result of the passed functions being called and being 'and'ed together + /// + public Func And( params Func[] fns) + { + return (a,b,c,d)=>fns.Aggregate(true,(prev,current)=>prev && current(a,b,c,d)); + } + + + /// + /// Creates an aggregate function that is a result of the passed functions being called and being 'and'ed together + /// + public Func And( params Func[] fns) + { + return (a,b,c,d,e)=>fns.Aggregate(true,(prev,current)=>prev && current(a,b,c,d,e)); + } + + + /// + /// Creates an aggregate function that is a result of the passed functions being called and being 'and'ed together + /// + public Func And( params Func[] fns) + { + return (a,b,c,d,e,f)=>fns.Aggregate(true,(prev,current)=>prev && current(a,b,c,d,e,f)); + } + + + /// + /// Creates an aggregate function that is a result of the passed functions being called and being 'and'ed together + /// + public Func And( params Func[] fns) + { + return (a,b,c,d,e,f,g)=>fns.Aggregate(true,(prev,current)=>prev && current(a,b,c,d,e,f,g)); + } + + + /// + /// Creates an aggregate function that is a result of the passed functions being called and being 'and'ed together + /// + public Func And( params Func[] fns) + { + return (a,b,c,d,e,f,g,h)=>fns.Aggregate(true,(prev,current)=>prev && current(a,b,c,d,e,f,g,h)); + } + + + /// + /// Creates an aggregate function that is a result of the passed functions being called and being 'and'ed together + /// + public Func And( params Func[] fns) + { + return (a,b,c,d,e,f,g,h,i)=>fns.Aggregate(true,(prev,current)=>prev && current(a,b,c,d,e,f,g,h,i)); + } + + + /// + /// Creates an aggregate function that is a result of the passed functions being called and being 'and'ed together + /// + public Func And( params Func[] fns) + { + return (a,b,c,d,e,f,g,h,i,j)=>fns.Aggregate(true,(prev,current)=>prev && current(a,b,c,d,e,f,g,h,i,j)); + } + + + /// + /// Creates an aggregate function that is a result of the passed functions being called and being 'and'ed together + /// + public Func And( params Func[] fns) + { + return (a,b,c,d,e,f,g,h,i,j,k)=>fns.Aggregate(true,(prev,current)=>prev && current(a,b,c,d,e,f,g,h,i,j,k)); + } + + + /// + /// Creates an aggregate function that is a result of the passed functions being called and being 'and'ed together + /// + public Func And( params Func[] fns) + { + return (a,b,c,d,e,f,g,h,i,j,k,l)=>fns.Aggregate(true,(prev,current)=>prev && current(a,b,c,d,e,f,g,h,i,j,k,l)); + } + + + /// + /// Creates an aggregate function that is a result of the passed functions being called and being 'and'ed together + /// + public Func And( params Func[] fns) + { + return (a,b,c,d,e,f,g,h,i,j,k,l,m)=>fns.Aggregate(true,(prev,current)=>prev && current(a,b,c,d,e,f,g,h,i,j,k,l,m)); + } + + + /// + /// Creates an aggregate function that is a result of the passed functions being called and being 'and'ed together + /// + public Func And( params Func[] fns) + { + return (a,b,c,d,e,f,g,h,i,j,k,l,m,n)=>fns.Aggregate(true,(prev,current)=>prev && current(a,b,c,d,e,f,g,h,i,j,k,l,m,n)); + } + + + /// + /// Creates an aggregate function that is a result of the passed functions being called and being 'and'ed together + /// + public Func And( params Func[] fns) + { + return (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o)=>fns.Aggregate(true,(prev,current)=>prev && current(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o)); + } + + + /// + /// Creates an aggregate function that is a result of the passed functions being called and being 'and'ed together + /// + public Func And( params Func[] fns) + { + return (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p)=>fns.Aggregate(true,(prev,current)=>prev && current(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p)); + } + + + } + +} \ No newline at end of file diff --git a/Underscore.cs/Function/Implementation/Boolean.tt b/Underscore.cs/Function/Implementation/Boolean.tt new file mode 100644 index 0000000..01e8b86 --- /dev/null +++ b/Underscore.cs/Function/Implementation/Boolean.tt @@ -0,0 +1,96 @@ +<#@ template debug="false" hostspecific="false" language="C#" #> +<#@ assembly name="System.Core" #> +<#@ import namespace="System.Linq" #> +<#@ output extension=".cs" #> +using System; +using System.Linq; + +// This code has been automatically generated +// if you want to make changes make them on +// the corresponding the text template file +// Boolean.tt +namespace Underscore.Function +{ + + public class BooleanComponent : IBooleanComponent + { + +<# + + const string argNames = "abcdefghijklmnopqrstuvwxyz"; + var typeArgs = Enumerable.Range(1, 16).Select(i => "T" + i).ToArray(); + + + for (int i = 1; i < 18; i++) + { + var currTypeArgs = typeArgs.Take(i-1).ToArray(); + var currTypeArgsString = string.Join(", ", currTypeArgs); + var fnRetType = string.Join(", ", currTypeArgs.Concat(new[]{"bool"})); + var callStr = string.Join(",", argNames.Take(i-1).Select(a => a.ToString())); + if (!string.IsNullOrEmpty(currTypeArgsString)) currTypeArgsString = "<" + currTypeArgsString + ">"; + + #> + + /// + /// Negates the logic of the passed function + /// + public Func<<#=fnRetType#>> Negate<#=currTypeArgsString#>( Func<<#=fnRetType#>> fn) + { + return (<#=callStr#>)=>!fn(<#=callStr#>); + } + + <# + } + + + + + for (int i = 1; i < 18; i++) + { + var currTypeArgs = typeArgs.Take(i-1).ToArray(); + var currTypeArgsString = string.Join(", ", currTypeArgs); + var fnRetType = string.Join(", ", currTypeArgs.Concat(new[]{"bool"})); + var callStr = string.Join(",", argNames.Take(i-1).Select(a => a.ToString())); + if (!string.IsNullOrEmpty(currTypeArgsString)) currTypeArgsString = "<" + currTypeArgsString + ">"; + + #> + + /// + /// Creates an aggregate function that is a result of the passed functions being called and being 'or'ed together + /// + public Func<<#=fnRetType#>> Or<#=currTypeArgsString#>( params Func<<#=fnRetType#>>[] fns) + { + return (<#=callStr#>)=>fns.Aggregate(false,(prev,current)=>prev || current(<#=callStr#>)); + } + + <# + } + + + + + for (int i = 1; i < 18; i++) + { + var currTypeArgs = typeArgs.Take(i-1).ToArray(); + var currTypeArgsString = string.Join(", ", currTypeArgs); + var fnRetType = string.Join(", ", currTypeArgs.Concat(new[]{"bool"})); + var callStr = string.Join(",", argNames.Take(i-1).Select(a => a.ToString())); + if (!string.IsNullOrEmpty(currTypeArgsString)) currTypeArgsString = "<" + currTypeArgsString + ">"; + + #> + + /// + /// Creates an aggregate function that is a result of the passed functions being called and being 'and'ed together + /// + public Func<<#=fnRetType#>> And<#=currTypeArgsString#>( params Func<<#=fnRetType#>>[] fns) + { + return (<#=callStr#>)=>fns.Aggregate(true,(prev,current)=>prev && current(<#=callStr#>)); + } + + <# + } +#> + + } + +} \ No newline at end of file diff --git a/Underscore.cs/List/Contract/Manipulate.cs b/Underscore.cs/List/Contract/Manipulate.cs index 832aaf1..04a6280 100644 --- a/Underscore.cs/List/Contract/Manipulate.cs +++ b/Underscore.cs/List/Contract/Manipulate.cs @@ -40,5 +40,9 @@ public interface IManipulateComponent /// Generates a random sample of items from the passed list /// IList Sample( IList list, int size, bool unique ); + + IEnumerable Extend(IList list, int size); + + IEnumerable Infinite(IList list); } } diff --git a/Underscore.cs/List/Implementation/Manipulate.cs b/Underscore.cs/List/Implementation/Manipulate.cs index aa05c31..83bfb35 100644 --- a/Underscore.cs/List/Implementation/Manipulate.cs +++ b/Underscore.cs/List/Implementation/Manipulate.cs @@ -158,6 +158,20 @@ public IList Sample( IList list, int size, bool allUnique ) return retv; } + public IEnumerable Extend(IList list, int size) + { + for (int i = 0; i < size; i++) + yield return list[i%list.Count]; + } + + public IEnumerable Infinite(IList list) + { + for(int i=0;;i++) + { + yield return list[i%list.Count]; + } + } + protected virtual void Dispose(bool disposing) { if (disposing) diff --git a/Underscore.cs/Module/Collection.cs b/Underscore.cs/Module/Collection.cs index caa5dc8..39cfb96 100644 --- a/Underscore.cs/Module/Collection.cs +++ b/Underscore.cs/Module/Collection.cs @@ -26,7 +26,17 @@ public Func> Snapshot( IEnumerable collection ) { return _creator.Snapshot( collection ); } - + + public IEnumerable Extend(IEnumerable collection, int length) + { + return _creator.Extend(collection, length); + } + + public IEnumerable Infinite(IEnumerable collection) + { + return _creator.Infinite(collection); + } + public IEnumerable> Chunk( IEnumerable collection, int size ) { diff --git a/Underscore.cs/Module/Function.cs b/Underscore.cs/Module/Function.cs index 8c3abb4..519671a 100644 --- a/Underscore.cs/Module/Function.cs +++ b/Underscore.cs/Module/Function.cs @@ -13,7 +13,8 @@ public class Function : IComposeComponent, ISynchComponent, IConvertComponent, - ICacheComponent + ICacheComponent, + IBooleanComponent { private readonly IComposeComponent _compose; @@ -23,6 +24,7 @@ public class Function : private readonly IConvertComponent _convert; private readonly ISynchComponent _synch; private readonly ICacheComponent _cache; + private readonly IBooleanComponent _booleanComponent; public Function( IBindComponent bind, @@ -31,7 +33,8 @@ public Function( IComposeComponent compose, IConvertComponent convert, ISynchComponent synch, - ICacheComponent cache) + ICacheComponent cache, + IBooleanComponent boolComponent) { _bind = bind; _partial = partial; @@ -40,6 +43,7 @@ public Function( _synch = synch; _convert = convert; _cache = cache; + _booleanComponent = boolComponent; } @@ -2006,5 +2010,260 @@ public Func Negate(Func fn) + { + return _booleanComponent.Negate(fn); + } + + public Func Negate(Func fn) + { + return _booleanComponent.Negate(fn); + } + + public Func Negate(Func fn) + { + return _booleanComponent.Negate(fn); + } + + public Func Negate(Func fn) + { + return _booleanComponent.Negate(fn); + } + + public Func Negate(Func fn) + { + return _booleanComponent.Negate(fn); + } + + public Func Negate(Func fn) + { + return _booleanComponent.Negate(fn); + } + + public Func Negate(Func fn) + { + return _booleanComponent.Negate(fn); + } + + public Func Negate(Func fn) + { + return _booleanComponent.Negate(fn); + } + + public Func Negate(Func fn) + { + return _booleanComponent.Negate(fn); + } + + public Func Negate(Func fn) + { + return _booleanComponent.Negate(fn); + } + + public Func Negate(Func fn) + { + return _booleanComponent.Negate(fn); + } + + public Func Negate(Func fn) + { + return _booleanComponent.Negate(fn); + } + + public Func Negate(Func fn) + { + return _booleanComponent.Negate(fn); + } + + public Func Negate(Func fn) + { + return _booleanComponent.Negate(fn); + } + + public Func Negate(Func fn) + { + return _booleanComponent.Negate(fn); + } + + public Func Negate(Func fn) + { + return _booleanComponent.Negate(fn); + } + + public Func Negate(Func fn) + { + return _booleanComponent.Negate(fn); + } + + public Func Or(params Func[] fns) + { + return _booleanComponent.Or(fns); + } + + public Func Or(params Func[] fns) + { + return _booleanComponent.Or(fns); + } + + public Func Or(params Func[] fns) + { + return _booleanComponent.Or(fns); + } + + public Func Or(params Func[] fns) + { + return _booleanComponent.Or(fns); + } + + public Func Or(params Func[] fns) + { + return _booleanComponent.Or(fns); + } + + public Func Or(params Func[] fns) + { + return _booleanComponent.Or(fns); + } + + public Func Or(params Func[] fns) + { + return _booleanComponent.Or(fns); + } + + public Func Or(params Func[] fns) + { + return _booleanComponent.Or(fns); + } + + public Func Or(params Func[] fns) + { + return _booleanComponent.Or(fns); + } + + public Func Or(params Func[] fns) + { + return _booleanComponent.Or(fns); + } + + public Func Or(params Func[] fns) + { + return _booleanComponent.Or(fns); + } + + public Func Or(params Func[] fns) + { + return _booleanComponent.Or(fns); + } + + public Func Or(params Func[] fns) + { + return _booleanComponent.Or(fns); + } + + public Func Or(params Func[] fns) + { + return _booleanComponent.Or(fns); + } + + public Func Or(params Func[] fns) + { + return _booleanComponent.Or(fns); + } + + public Func Or(params Func[] fns) + { + return _booleanComponent.Or(fns); + } + + public Func Or(params Func[] fns) + { + return _booleanComponent.Or(fns); + } + + public Func And(params Func[] fns) + { + return _booleanComponent.And(fns); + } + + public Func And(params Func[] fns) + { + return _booleanComponent.And(fns); + } + + public Func And(params Func[] fns) + { + return _booleanComponent.And(fns); + } + + public Func And(params Func[] fns) + { + return _booleanComponent.And(fns); + } + + public Func And(params Func[] fns) + { + return _booleanComponent.And(fns); + } + + public Func And(params Func[] fns) + { + return _booleanComponent.And(fns); + } + + public Func And(params Func[] fns) + { + return _booleanComponent.And(fns); + } + + public Func And(params Func[] fns) + { + return _booleanComponent.And(fns); + } + + public Func And(params Func[] fns) + { + return _booleanComponent.And(fns); + } + + public Func And(params Func[] fns) + { + return _booleanComponent.And(fns); + } + + public Func And(params Func[] fns) + { + return _booleanComponent.And(fns); + } + + public Func And(params Func[] fns) + { + return _booleanComponent.And(fns); + } + + public Func And(params Func[] fns) + { + return _booleanComponent.And(fns); + } + + public Func And(params Func[] fns) + { + return _booleanComponent.And(fns); + } + + public Func And(params Func[] fns) + { + return _booleanComponent.And(fns); + } + + public Func And(params Func[] fns) + { + return _booleanComponent.And(fns); + } + + public Func And(params Func[] fns) + { + return _booleanComponent.And(fns); + } } } diff --git a/Underscore.cs/Module/List.cs b/Underscore.cs/Module/List.cs index aebdb98..9ae467c 100644 --- a/Underscore.cs/Module/List.cs +++ b/Underscore.cs/Module/List.cs @@ -71,6 +71,16 @@ public IList Sample( IList list, int size, bool unique ) return _manipulator.Sample( list, size, unique ); } + public IEnumerable Extend(IList list, int size) + { + return _manipulator.Extend(list, size); + } + + public IEnumerable Infinite(IList list) + { + return _manipulator.Infinite(list); + } + public IList Slice( IList list, int start, int end ) { return _partitioner.Slice( list, start, end ); diff --git a/Underscore.cs/Object/Reflection/Implementation/Property.cs b/Underscore.cs/Object/Reflection/Implementation/Property.cs index 5bfcf4e..6b906fa 100644 --- a/Underscore.cs/Object/Reflection/Implementation/Property.cs +++ b/Underscore.cs/Object/Reflection/Implementation/Property.cs @@ -11,6 +11,7 @@ public class PropertyComponent : IPropertyComponent private readonly Func> _getValidProperties; private readonly Func> _propertiesByType; private readonly Func> _getValidPropertiesWithBindingFlags; + private readonly Func _getProperty; private const BindingFlags defaultFlags = BindingFlags.Public | BindingFlags.Instance ; public PropertyComponent( ICacheComponent cacher ) @@ -29,6 +30,11 @@ public PropertyComponent( ICacheComponent cacher ) (tme, tprop, flags) => _getValidPropertiesWithBindingFlags(tme, flags).Where(a => a.PropertyType == tprop); + var tmpProp = _getProperty = (t, n, bf) => t.GetProperty(n,bf); + + _getProperty = cacher.Memoize(tmpProp); + + } @@ -52,7 +58,7 @@ public IEnumerable All( object target ) public IEnumerable All(Type type) { - return Enumerate(type).ToList(); + return Enumerate(type); } public IEnumerable All(object target, BindingFlags flags) @@ -72,9 +78,10 @@ public void SetValue(object target, string name, T value, bool caseSensitive, name = name.ToLower(); var possible = OfType(target, typeof (T), flags); - if (possible.Any()) + var propertyInfos = possible as PropertyInfo[] ?? possible.ToArray(); + if (propertyInfos.Any()) { - var assigning = possible.FirstOrDefault(a => (caseSensitive ? a.Name : a.Name.ToLower()) == name); + var assigning = propertyInfos.FirstOrDefault(a => (caseSensitive ? a.Name : a.Name.ToLower()) == name); if (assigning != null) assigning.SetValue(target, value); @@ -245,7 +252,7 @@ private PropertyInfo PropertyCaseInsensitive(object target, string name, Binding private PropertyInfo PropertyCaseSensitive(object target, string name, BindingFlags flags = defaultFlags) { - return All(target, flags).FirstOrDefault(a => a.Name == name); + return _getProperty(target.GetType(), name,flags); } diff --git a/Underscore.cs/Properties/AssemblyInfo.cs b/Underscore.cs/Properties/AssemblyInfo.cs index 0a05688..5eb00a8 100644 --- a/Underscore.cs/Properties/AssemblyInfo.cs +++ b/Underscore.cs/Properties/AssemblyInfo.cs @@ -7,5 +7,5 @@ [assembly: AssemblyCopyright("Copyright © 2014-2016 Chip Keyser")] [assembly: ComVisible(false)] [assembly: Guid("b96a9e7d-de48-4b0d-8397-d98a7a734880")] -[assembly: AssemblyVersion("0.1.3.12")] -[assembly: AssemblyFileVersion("0.1.3.12")] +[assembly: AssemblyVersion("0.1.3.13")] +[assembly: AssemblyFileVersion("0.1.3.13")] diff --git a/Underscore.cs/Setup/Function.cs b/Underscore.cs/Setup/Function.cs index 96020ce..92d41a2 100644 --- a/Underscore.cs/Setup/Function.cs +++ b/Underscore.cs/Setup/Function.cs @@ -16,6 +16,7 @@ public void Load(Kernel kernel ) kernel.Register(); kernel.Register(); kernel.Register(); + kernel.Register(); kernel.Register(); } } diff --git a/Underscore.cs/Underscore.cs.csproj b/Underscore.cs/Underscore.cs.csproj index bf281fb..aecf39f 100644 --- a/Underscore.cs/Underscore.cs.csproj +++ b/Underscore.cs/Underscore.cs.csproj @@ -65,6 +65,11 @@ + + Boolean.tt + True + True + @@ -73,6 +78,11 @@ + + True + True + Boolean.tt + @@ -130,6 +140,16 @@ + + + TextTemplatingFileGenerator + Boolean.cs + + + TextTemplatingFileGenerator + Boolean.cs + +