using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using Chernobyl.Collections.Generic;
namespace Chernobyl.Extensions
{
///
/// Extension methods for and related types.
///
public static class ActionExtensions
{
///
/// Returns a method that invokes with the
/// argument specified by .
///
/// The type of the argument expected by
/// .
/// The method to invoke on invocation of the returned
/// method.
/// The argument to pass to
/// on invocation of the returned method.
/// The method whose invocation invokes
/// with as its parameter.
public static Action Bind(this Action method, T1 arg1)
{
return () => method(arg1);
}
///
/// Returns a sequence of methods whose argument is bound to the values
/// in .
///
/// The argument type expected by .
/// The method to be invoked on invocation of the
/// returned methods.
/// The instances to be provided to
/// .
/// The methods whose invocation will invoke
/// with the as its parameters.
public static IEnumerable Bind(this Action method, IEnumerable arguments)
{
return arguments.Select(method.Bind);
}
///
/// Returns a method that invokes with the
/// argument specified by .
///
/// The type of the first argument expected by
/// .
/// The type of the second argument expected by
/// .
/// The method to invoke on invocation of the returned
/// method.
/// The argument to pass to
/// on invocation of the returned method.
///
/// The method whose invocation invokes
/// with as its parameter.
///
public static Action Bind(this Action method, T1 arg1)
{
return arg2 => method(arg1, arg2);
}
///
/// Returns a sequence of methods whose first argument is bound to the
/// values in .
///
/// The first argument type expected by .
/// The second argument type expected by .
/// The method to be invoked on invocation of the
/// returned methods.
/// The instances to be provided to
/// .
///
/// The methods whose invocation will invoke
/// with the as its parameters.
///
public static IEnumerable> Bind(this Action method, IEnumerable firstArguments)
{
return firstArguments.Select>(method.Bind);
}
///
/// Returns a method that invokes with the
/// argument specified by .
///
/// The type of the first argument expected by
/// .
/// The type of the second argument expected by
/// .
/// The type of the third argument expected by
/// .
/// The method to invoke on invocation of the returned
/// method.
/// The argument to pass to
/// on invocation of the returned method.
///
/// The method whose invocation invokes
/// with as its parameter.
///
public static Action Bind(this Action method, T1 arg1)
{
return (arg2, arg3) => method(arg1, arg2, arg3);
}
///
/// Returns a method that, when invoked, will invoked the provided
/// once for each of the
/// provided. The will form the first
/// parameter of the .
///
/// The first argument type expected by .
/// The second argument type expected by .
/// The third argument type expected by .
/// The method to be invoked on invocation of the
/// returned method.
/// The instances to be provided to
/// .
///
/// The method whose invocation will invoke
/// with the as its parameters.
///
public static IEnumerable> Bind(this Action method, IEnumerable firstArguments)
{
return firstArguments.Select>(method.Bind);
}
///
/// Creates a composite method that, when invoked, invokes other methods.
///
/// The methods to combine into a single composite
/// method.
/// The composite method.
public static Action Combine(this IEnumerable actions)
{
return () => actions.For(action => action());
}
///
/// Converts a single method taking many arguments to many methods each
/// taking one argument, such that, when the returned method are all
/// invoked, will be invoked with all of the
/// items passed to the returned methods.
///
/// The type taken by the methods.
/// The callback to be invoked once all of the
/// return methods have been invoked..
/// The number of items to collect before
/// is invoked.
/// The methods to invoke to invoke .
public static IEnumerable> AsMany(this Action> callback, int count)
{
var values = new T[count];
var valuesResolved = 0;
return values.Select>((o, index) => value =>
{
values[index] = value;
// Invoke the callback once all values have been resolved.
if (Interlocked.Increment(ref valuesResolved) == count)
{
callback(values);
valuesResolved = 0;
}
});
}
///
/// Converts many methods taking a single argument to one method taking
/// many arguments, such that, when the returned method is invoked, all
/// of the provided are invoked.
///
/// The type taken by the methods.
/// The methods to invoke when the returned method
/// is invoked.
/// The method to invoke when invoking .
public static Action> AsOne(this IEnumerable> methods)
{
return items => methods.Zip(items).For(pair => pair.First(pair.Second));
}
///
/// Converts a method taking one argument into a method that can take
/// many of the same argument type.
///
/// The type taken by the .
/// The method to convert.
/// The method to whose invocation invokes
/// once for each item.
public static Action> AsManyArgumented(this Action method)
{
return items => items.For(method);
}
///
/// Invokes the specified methods, passing in the provided method.
///
public static void Invoke(this IEnumerable actions)
{
actions.For(action => action());
}
///
/// Invokes the specified methods, passing in the provided method.
///
/// The type expected by the method.
/// The methods to invoke.
/// The parameter to pass to the methods.
public static void Invoke(this IEnumerable> actions, T param1)
{
actions.For(action => action(param1));
}
///
/// Returns a method that casts the parameter before passing it to the
/// method provided.
///
/// The type to cast the parameter to and pass to
/// the method provided.
/// The method to invoke after the cast.
/// The method that, when invoked, invokes
/// with its parameter casted.
public static Action