Add copy() specialization for host-to-host transfers

This adds a copy() specialization for host-to-host transfers
which simply forwards the call to std::copy().

This is useful in templated algorithms which may in certain
circumstances copy() between data ranges on the host.
Add result argument to reduce() algorithm

This adds an output iterator result argument to the reduce()
algorithm. Now, instead of returning the reduced result, the
result is written to an output iterator. This allows the value
to stay on the device and avoids a device-to-host copy in cases
where the result is not needed on the host (e.g. it is part of
a larger computation).

This is an API breaking change to users of reduce(). Affected code
should now declare a result variable and then pass a pointer to it
as the new result argument.