Report a bug
If you spot a problem with this page, click here to create a Github issue.
Improve this page
Quickly fork, edit online, and submit a pull request for this page. Requires a signed-in GitHub account. This works well for small changes. If you'd like to make larger changes you may want to consider using a local clone.

mir.functional

Functions that manipulate other functions. This module provides functions for compile time function composition. These functions are helpful when constructing predicates for the algorithms in mir.ndslice.

Functions

Function Name Description
naryFun Create a unary, binary or N-nary function from a string. Most often used when defining algorithms on ranges and slices.
pipe Join a couple of functions into one that executes the original functions one after the other, using one function's result for the next function's argument.
not Creates a function that negates another.
reverseArgs Predicate that reverses the order of its arguments.
forward Forwards function arguments with saving ref-ness.
refTuple Removes Ref shell.
unref Creates a RefTuple structure.
_ref Creates a Ref structure.
struct Ref(T) if (!isRef!T);
Simple wrapper that holds a pointer. It is used for as workaround to return multiple auto ref values.
@trusted this(ref T value);
T* __ptr;
@property ref T __value();
Ref!T _ref(T)(ref T value);
Creates Ref wrapper.
struct RefTuple(T...);
Simplified tuple structure. Some fields may be type of Ref. Ref stores a pointer to a values.
template Unref(V : Ref!T, T)

template Unref(V : RefTuple!T, T...)

template Unref(V)
Removes Ref shell.
RefTuple!Args refTuple(Args...)(auto ref Args args);
Returns:
a RefTuple structure.
If an argument is accessable by reference, then its pointer is stored instead.
Use refTuple in combintation with unref to make a completely value tuple.
ref T unref(V : Ref!T, T)(V value);

Unref!(RefTuple!T) unref(V : RefTuple!T, T...)(V value);

V unref(V)(V value);
Removes Ref shell.
template adjoin(fun...) if (fun.length && fun.length <= 26)
Takes multiple functions and adjoins them together. The result is a RefTuple with one element per passed-in function. Upon invocation, the returned tuple is the adjoined results of all functions.

Note: In the special case where only a single function is provided (F.length == 1), adjoin simply aliases to the single passed function (F[0]).

Examples:
static bool f1(int a) { return a != 0; }
static int f2(int a) { return a / 2; }
auto x = adjoin!(f1, f2)(5);
assert(is(typeof(x) == RefTuple!(bool, int)));
assert(x.a == true && x.b == 2);
auto adjoin(Args...)(auto ref Args args);
template naryFun(alias fun)
Transforms a string representing an expression into a binary function. The string must use symbol names a, b, ..., z as the parameters. If fun is not a string, naryFun aliases itself away to fun.
Examples:
// Strings are compiled into functions:
alias isEven = naryFun!("(a & 1) == 0");
assert(isEven(2) && !isEven(1));
Examples:
alias less = naryFun!("a < b");
assert(less(1, 2) && !less(2, 1));
alias greater = naryFun!("a > b");
assert(!greater("1", "2") && greater("2", "1"));
Examples:
naryFun accepts up to 26 arguments.
assert(naryFun!("a * b + c")(2, 3, 4) == 10);
Examples:
naryFun can return by reference.
int a;
assert(&naryFun!("a")(a) == &a);
Examples:
args paramter tuple
assert(naryFun!("args[0] + args[1]")(2, 3) == 5);
ref auto naryFun(Args...)(auto ref Args args)
if (args.length <= 26);
Specialization for string lambdas
template reverseArgs(alias fun)
N-ary predicate that reverses the order of arguments, e.g., given pred(a, b, c), returns pred(c, b, a).
Examples:
int abc(int a, int b, int c) { return a * b + c; }
alias cba = reverseArgs!abc;
assert(abc(91, 17, 32) == cba(32, 17, 91));
ref auto reverseArgs(Args...)(auto ref Args args)
if (is(typeof(fun(Reverse!args))));
template not(alias pred)
Negates predicate pred.
Examples:
import std.algorithm.searching : find;
import std.uni : isWhite;
string a = "   Hello, world!";
assert(find!(not!isWhite)(a) == "Hello, world!");
bool not(T...)(auto ref T args);
template pipe(fun...)
Composes passed-in functions fun[0], fun[1], ... returning a function f(x) that in turn returns ...(fun[1](fun[0](x))).... Each function can be a regular functions, a delegate, a lambda, or a string.
Examples:
assert(pipe!("a + b", a => a * 10)(2, 3) == 50);
Examples:
pipe can return by reference.
int a;
assert(&pipe!("a", "a")(a) == &a);
Examples:
Template bloat reduction
enum  a = "a * 2";
alias b = e => e + 2;

alias p0 = pipe!(pipe!(a, b), pipe!(b, a));
alias p1 = pipe!(a, b, b, a);

static assert(__traits(isSame, p0, p1));
ref auto pipe(Args...)(auto ref Args args);
template forward(args...)
Forwards function arguments with saving ref-ness.
Examples:
class C
{
    static int foo(int n) { return 1; }
    static int foo(ref int n) { return 2; }
}
int bar()(auto ref int x) { return C.foo(forward!x); }

assert(bar(1) == 1);
int i;
assert(bar(i) == 2);
Examples:
void foo(int n, ref string s) { s = null; foreach (i; 0..n) s ~= "Hello"; }

// forwards all arguments which are bound to parameter tuple
void bar(Args...)(auto ref Args args) { return foo(forward!args); }

// forwards all arguments with swapping order
void baz(Args...)(auto ref Args args) { return foo(forward!args[$/2..$], forward!args[0..$/2]); }

string s;
bar(1, s);
assert(s == "Hello");
baz(s, 2);
assert(s == "HelloHello");