Changing ByCodepoint's "save" signature

1) Because if it returns a ref, then it isn't actually saving anything...
2) Changed the "const" qualifier to inout: Using "const" means the return type is always "const ByCodepoint", which isn't a valid range (a const range can't be popped)

The change is mostly moot, since it would appear ByCodepoint's save or forwardness is never used anyways. But that doesn't mean it shouldn't be correct.
fix issue 9160 multiSort constraint bug
Corrected constraints for std.algorithm.endsWith

Previously endsWith constraints only required input ranges, but the algorithm uses `back` and `popBack` within, so clearly a bidirectional range is needed.
Merge pull request #1012 from Poita/endsWithConstraints

Corrected constraints for std.algorithm.endsWith
Merge pull request #1011 from blackwhale/fix-multisort

fix issue 9160 multiSort constraint regression
Refactored endsWith to use retro + startsWith.

What's the point of having all these powerful, generic, abstract functions if we're just going to copy and paste code? :-)

This change has several benefits:

* It is far more elegant.
* Changes (optimisations) to startsWith automatically carry across to endsWith.
* We get extra testing for startsWith and retro for free.
Rewrite joiner to not assume persistence of .front.
Add unittest for new joiner.
Completely get rid of UTF-8 to workaround OSX/64 bug.
Replace joiner unittest with one that doesn't suffer from issue 9131.
Revert "Fix `std.range.takeExactly` trait to reject slices without length."

This reverts commit 6a0b6c4deebe48d0e2650598bdf58ffa93cb66b5.
Adjustments to take and takeExactly.

takeExactly now returns the same type as take where possible, and
neither take nor takeExactly check hasSlicing for infinite ranges (since
infinite ranges will soon be required to use them for slicing, and that
creates a circular dependency among those 3 templates
Some whitespace cleanup.
Adustments to hasSlicing.

Now, it enforces that opSlice returns a range which can be assigned to
the original range type (so that it can be assigned to the original
range as long as the original range isn't const) as long as it's finite,
and it enforces that opSlice's result is the result of take when the
range is infinite.
Fix to Map caused by changes to hasSlicing.

import std.algorithm;
import std.range;

void main()
{
    auto N2 = sequence!"n"(cast(size_t)1).map!"a";
}

ceased to compile, because Map's opSlice won't work anymore over
infinite ranges, because the result can't be reassigned to the original.
Add some requirements for opDollar to hasSlicing.

Ideally, opDollar would be outright required for any range with slicing,
but unless/until it's changed so that length automatically aliases to
opDollar when opDollar isn't defined (issue# 7177), that's probably not
a reasonable requirement to make.
Further strengthen hasSlicing.

The extra requirements are not currently enabled because of bug# 8847,
but they're now there, and they're listed as their in the documentation
so that no one will think that they're not supposed to apply.
Strengthened isRandomAccess with regards to $.

It now requires that indexing with $ result in the same type as front if
r[$] works, and if that works, and the range isn't infinite, r[$ - 1]
must be the same type as front. Ideally, we'd require that r[$] work
regardless, but without enhancement #7177 being implemented, that would
likely break too much code, as opDollar was only recently fixed and
probably isn't used much.
Removed incorrect @property attributes in std.range.

They were removed previously but reintroduced due to a bad rebase, so
I'm removing them again here.
Merge pull request #987 from quickfur/new_joiner

Fix issue 8085