import std.stdio;
import std.conv;
import std.traits;
import std.regex;
import std.algorithm;
import std.array;
import std.typetuple;
import std.typecons;
template count(T...)
{
enum count = T.length;
}
template myCurry(alias fun, args...)
{
static if (__traits(compiles, (ParameterTypeTuple!fun).length))
{
static if (args.length > (ParameterTypeTuple!fun).length)
{
static assert(0, Format!("Tried to pass too many arguments - %s, max is %s.",
count!args, (ParameterTypeTuple!fun).length));
}
}
auto myCurry(T...)(T t)
{
return fun(args, t);
}
}
template bind(alias fun, staticArgs...)
{
struct bind
{
static ReturnType!fun opCall(T...)(T runArgs)
{
// explicit check that static arguments 0 and 2 are void
static if (is(staticArgs[0] == void) && is(staticArgs[2] == void))
{
fun(runArgs[0], staticArgs[1], runArgs[1], staticArgs[3]);
}
}
}
}
void foo(int a, int b, int c, int d)
{
writefln("%s %s %s %s", a, b, c, d);
}
alias bind!(foo, void, 2, void, 4) fooBind;
void main()
{
fooBind(1, 3);
}