Avoid un-necessary decode in startsWith/endsWith

As requested in #2503.

Perhaps it's overkill?
If we are going to go into that territory, then we might as well declare that the `startsWith` variant that accepts a single character is only valid with narrow strings if the needle is a `dchar`, because `char` and `wchar` do not represent Unicode code points.

However, that's just not useful. So instead, if the second argument to `startsWith` is a code unit, then I think it should compare code units.

`"é".startsWith(cast(char)'é')` should be false, because a `char` is an UTF-8 code unit, and the UTF-8 sequence "é" does not start with it.

> Because it's a range of codepoints. `"é".front == "é"[0]` produces false, so so should startsWith. 

By the above  logic this comparison is also invalid, since we're comparing code points with code units. But `.front` is (more or less) explicit decoding.