D minMax function implementation
Is this an efficient implementation?


Yup. It calls map exactly once per item, and otherwise does nothing but the regular range calls. A specialized implementation could be more efficient in some cases (but probably only if using vector instructions), as could a parallel implementation, but neither of these have the genericity that your code does.


  Is it readable?


Absolutely, it's some of the most readable code I've seen. The content of the loop is somewhat dense. You could perhaps make it less dense like this:

    auto front = tuple!("elem", "map")(r.front, map(r.front));
    auto min = front;
    auto max = front;

    r.popFront;
    foreach (e; r) {
        front = tuple(e, map(e));
        if(front.map &gt; max.map) max = front;
        if(front.map &lt; min.map) min = front;
    }
    return tuple!("min", "max")(min.elem, max.elem);


Apart from that, I got nuthin'.


  Any general feedback is appreciated.


As hinted at in the section above, instead of while (!empty), you might want to use foreach. This reduces your code by one line (r.popFront()), and makes it clearer that you're going to iterate over every element of the range. It shouldn't change the performance of the code in any way.

You should put an if (is(typeof(unaryFun!pred))) constraint on the template, so the user of the function gets an error message on the line where he or she tries to instantiate it with arr.minMax!"invalid string".

Also, the name pred is wrong - a predicate is a boolean-valued function, like equal, same color or contains bees. I'd call it Fn or Fun.

As a minor nit, I'd also change the name of map, probably to fn or fun (note the difference in capitalization). This because I kept conflating your map with std.algorithm.map. The concept is correct, but essentially the name is already taken.

All in all, very good - my only comments are essentially nitpicks.