@@ -502,25 +502,22 @@ class SmallVectorTemplateBase<T, true> : public SmallVectorTemplateCommon<T> {
502502
503503 // / Copy the range [I, E) onto the uninitialized memory
504504 // / starting with "Dest", constructing elements into it as needed.
505- template <typename It1, typename It2>
505+ template <typename It1, typename It2>
506506 static void uninitialized_copy (It1 I, It1 E, It2 Dest) {
507- // Arbitrary iterator types; just use the basic implementation.
508- std::uninitialized_copy (I, E, Dest);
509- }
510-
511- // / Copy the range [I, E) onto the uninitialized memory
512- // / starting with "Dest", constructing elements into it as needed.
513- template <typename T1, typename T2>
514- static void uninitialized_copy (
515- T1 *I, T1 *E, T2 *Dest,
516- std::enable_if_t <std::is_same<std::remove_const_t <T1>, T2>::value> * =
517- nullptr ) {
518- // Use memcpy for PODs iterated by pointers (which includes SmallVector
519- // iterators): std::uninitialized_copy optimizes to memmove, but we can
520- // use memcpy here. Note that I and E are iterators and thus might be
521- // invalid for memcpy if they are equal.
522- if (I != E)
523- std::memcpy (reinterpret_cast <void *>(Dest), I, (E - I) * sizeof (T));
507+ if constexpr (std::is_pointer_v<It1> && std::is_pointer_v<It2> &&
508+ std::is_same_v<
509+ std::remove_const_t <std::remove_pointer_t <It1>>,
510+ std::remove_pointer_t <It2>>) {
511+ // Use memcpy for PODs iterated by pointers (which includes SmallVector
512+ // iterators): std::uninitialized_copy optimizes to memmove, but we can
513+ // use memcpy here. Note that I and E are iterators and thus might be
514+ // invalid for memcpy if they are equal.
515+ if (I != E)
516+ std::memcpy (reinterpret_cast <void *>(Dest), I, (E - I) * sizeof (T));
517+ } else {
518+ // Arbitrary iterator types; just use the basic implementation.
519+ std::uninitialized_copy (I, E, Dest);
520+ }
524521 }
525522
526523 // / Double the size of the allocated memory, guaranteeing space for at
0 commit comments