D-Programming-Language/phobos — pull request #1141 by monarchdodra (2013-02-15 16:05:31+00:00)
Title: Improve XnaryFun argument passign

From the conversation here:
http://forum.dlang.org/thread/qhlsrpqajuwstvlspimf@forum.dlang.org

Basically, using binaryFun!"a < b" made extra and un-necassary copies to just call binaryFun, before it actually calls the internal `return(fun)`. This is problematic if the object passed by value has a postblit (as even if the postblit is cheap, calling it is *completly* unnecessary). This is especially apparent given how *massively* XnaryFun is used, I think it is very important to make it run as fast as possible, with no compromises.

The designed was improved to provide both pass by ref, and pass by value*.

The changes where thoroughly benched: Small built-in types (eg int) take absolutely no penalty from the new pass by ref. As for objects with a postblit (even trivially simple: increment a global counter) take a great performance boost: algorithm.sort ran about 50% faster for the type `struct S{int i; this(this){++k;}}`.

== The pulls ==

The first pull is just a fix for CTFE: in CTFE, it is illegal to pass by mutable ref a non-mutable. Having *naryFun take by ref revealed the bug.

The second pull is a quick and easy change to take by auto ref. Benches showed results that are maybe faster, never slower. win-win. Since the argument "byRef" is now useless, is deprecated the signature that uses "byRef"

== Debatable pull ==

The last pull request is more controversial: it makes Xnary functions *not* accept pass by value, if fun does not accept by value either. For example:

```D
void foo(ref int){}

int main()
{
unaryFun!"foo(a)"(5);
}
```
This code, arguably, should be illegal, since foo does not provide pass by value. Under those circumstances, unaryFun should not take by value either. It currently does, but I made it so it doesn't.

This is debatable. I think it is correct, but it can break code. I can keep or remove it.