Instead of using reverse_iterator, share the optimization between the 4 algorithms. The key observation here that memmove applies to both copy and move identically, and to their _backward versions very similarly. All algorithms now follow the same pattern along the lines of:
if constexpr (can_memmove<InIter, OutIter>) { memmove(first, last, out); } else { naive_implementation(first, last, out); }
A follow-up will delete unconstrained_reverse_iterator.
This patch removes duplication and divergence between std::copy, std::move and std::move_backward. It also improves testing:
- the test for whether the optimization is used only applied to std::copy and, more importantly, was essentially a no-op because it would still pass if the optimization was not used;
- there were no tests to make sure the optimization is not used when the effect would be visible.
Could you clang-format all the changes?