Permalink
Fetching contributors…
Cannot retrieve contributors at this time
129 lines (107 sloc) 5.81 KB
<#@ template debug="false" hostspecific="false" language="C#" #>
<#@ assembly name="System.Core" #>
<#@ import namespace="System.Collections.Generic" #>
<#@ import namespace="System.Linq" #>
<#@ import namespace="System.Text" #>
<#@ output extension=".generated.cs" #>
<#@ include file="..\..\General.ttinclude" #>// The MIT License
//
// Copyright (c) 2012 Jordan E. Terrell
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
using System;
using System.Collections.Generic;
using iSynaptic.Commons.Collections.Generic;
namespace iSynaptic.Commons
{
public static partial class FuncExtensions
{
<# foreach(var i in Enumerable.Range(1, 7))
{
string typeArgs = Delimit(Enumerable.Range(1, i), ", ", x => "T" + x.ToString());
string args = Delimit(Enumerable.Range(1, i), ", ", x => "t" + x.ToString());
string reverseTypeArgs = Delimit(Enumerable.Range(1, i).Reverse(), ", ", x => "T" + x.ToString());
string reverseArgs = Delimit(Enumerable.Range(1, i).Reverse(), ", ", x => "t" + x.ToString());
string curriedTypeArgs = Delimit(Enumerable.Range(1, i).Skip(1), ", ", x => "T" + x.ToString());
string curriedArgs = Delimit(Enumerable.Range(1, i).Skip(1), ", ", x => "t" + x.ToString());
#>
public static Func<<#= typeArgs #>, TResult> Synchronize<<#= typeArgs #>, TResult>(this Func<<#= typeArgs #>, TResult> @this)
{
return @this.Synchronize((<#= args #>) => true);
}
public static Func<<#= typeArgs #>, TResult> Synchronize<<#= typeArgs #>, TResult>(this Func<<#= typeArgs #>, TResult> @this, Func<<#= typeArgs #>, bool> needsSynchronizationPredicate)
{
Guard.NotNull(@this, "@this");
Guard.NotNull(needsSynchronizationPredicate, "needsSynchronizationPredicate");
return Synchronize(@this, needsSynchronizationPredicate, new object());
}
public static Func<<#= typeArgs #>, TResult> Synchronize<<#= typeArgs #>, TResult>(this Func<<#= typeArgs #>, TResult> @this, Func<<#= typeArgs #>, bool> needsSynchronizationPredicate, object gate)
{
Guard.NotNull(@this, "@this");
Guard.NotNull(needsSynchronizationPredicate, "needsSynchronizationPredicate");
Guard.NotNull(gate, "gate");
return (<#= args #>) =>
{
if(needsSynchronizationPredicate(<#= args #>))
{
lock (gate)
{
return @this(<#= args #>);
}
}
return @this(<#= args #>);
};
}
<# } #>
<# foreach(var i in Enumerable.Range(1, 7))
{
string fullTypeArgs = Delimit(Enumerable.Range(1, i), ", ", x => "T" + x.ToString());
string fullArgs = Delimit(Enumerable.Range(1, i), ", ", x => "t" + x.ToString());
string nestedTupleType = "";
string nestedTupleCreate = "";
string nestedArgs = "";
foreach(var batch in Batch(Enumerable.Range(1, i), 7).Reverse())
{
string typePrefix = "Tuple<" + Delimit(batch, ", ", x => "T" + x.ToString());
string createPrefix = "new Tuple<" + Delimit(batch, ", ", x => "T" + x.ToString());
string argCreatePrefix = ">(" + Delimit(batch, ", ", x => "t" + x.ToString());
string argsList = "x" + string.Join("", Enumerable.Repeat(".Rest", batch.Index)) + Delimit(batch.Select(x => ((x - 1) % 7) + 1), ", x" + string.Join("", Enumerable.Repeat(".Rest", batch.Index)), x => ".Item" + x.ToString());
if(string.IsNullOrWhiteSpace(nestedTupleType))
{
nestedTupleType = typePrefix + ">";
nestedTupleCreate = createPrefix + argCreatePrefix + ")";
nestedArgs = argsList;
}
else
{
nestedTupleCreate = createPrefix + ", " + nestedTupleType + argCreatePrefix + ", " + nestedTupleCreate + ")";
nestedTupleType = typePrefix + ", " + nestedTupleType + ">";
nestedArgs = argsList + ", " + nestedArgs;
}
}
#>
public static Func<<#= fullTypeArgs #>, TResult> Memoize<<#= fullTypeArgs #>, TResult>(this Func<<#= fullTypeArgs #>, TResult> @this)
{
Guard.NotNull(@this, "@this");
var dictionary = new LazySelectionDictionary<<#= nestedTupleType #>, TResult>(x => @this(<#= nestedArgs #>).ToMaybe());
return (<#= fullArgs #>) => dictionary[<#= nestedTupleCreate #>];
}
<# } #>
}
}