Put fix 3

Third attempt at fixing put. I think this could be the good one.

This new version is capable of transcoding any character/string of any width, to any character/string of any width. It does this (if I may say so), rather efficiently too.

This basically "fixes" the totality of `std.format`, which sometimes needs to put a dchar in the output stream, made simple code such as `formattedWrite((const(char[]) s){}, "%s", "string");` fail to compile. Now, we can even do things like `formattedWrite((const(char[]) s){}, "%s", "string"d);` (notice the `"d`). Yay!

Added some optimizations for array to array copy too.

For what this does, I also think the "flow" is as simple as we can get it to be. I tripple checked all the code paths, and I made sure using -cov that *all* roads are taken and validated.

As a *helper* feature, I defined `doPut`, which is "put without any features", and it's corresponding trait `isNativeOutputRange`. This is used strictly internally, and is not made public to the user.