Optimization for put/doPut templates that use outputRanges that should be pass by value

The original put/doPut functions pass in the OutputRange by ref, i.e.

```D
package void doPut(R, E)(ref R r, auto ref E e)
void put(R, E)(ref R r, E e)
```

However, some types do not need to be passed by reference such as pointers, dynamic arrays, classes, delegates...

To better optimize these output ranges I added overloads for the put/doPut functions that pass the OutputRange by value instead of by reference (See code).

Now that each overload handles a different set of types, some of the logic can be removed from each function, but I just duplicated the logic twice to minimize the potential amount of turmoil (I don't want to mess anything up).  If anyone knows "for sure" what logic can be removed I'm willing to do that, but, most of the logic is compile time so the only gain will be slightly faster compile times (not necessarily smaller/leaner functions).  Also feel free to make any modifications to my code:)
I know this wasn't your doing, but can you fix nativaly? I'm assuming it should be natively?