diff --git a/llvm/include/llvm/ADT/SmallVector.h b/llvm/include/llvm/ADT/SmallVector.h index 36b324355ee10..8ccbaf8652193 100644 --- a/llvm/include/llvm/ADT/SmallVector.h +++ b/llvm/include/llvm/ADT/SmallVector.h @@ -501,25 +501,22 @@ class SmallVectorTemplateBase : public SmallVectorTemplateCommon { /// Copy the range [I, E) onto the uninitialized memory /// starting with "Dest", constructing elements into it as needed. - template + template static void uninitialized_copy(It1 I, It1 E, It2 Dest) { - // Arbitrary iterator types; just use the basic implementation. - std::uninitialized_copy(I, E, Dest); - } - - /// Copy the range [I, E) onto the uninitialized memory - /// starting with "Dest", constructing elements into it as needed. - template - static void uninitialized_copy( - T1 *I, T1 *E, T2 *Dest, - std::enable_if_t, T2>::value> * = - nullptr) { - // Use memcpy for PODs iterated by pointers (which includes SmallVector - // iterators): std::uninitialized_copy optimizes to memmove, but we can - // use memcpy here. Note that I and E are iterators and thus might be - // invalid for memcpy if they are equal. - if (I != E) - std::memcpy(reinterpret_cast(Dest), I, (E - I) * sizeof(T)); + if constexpr (std::is_pointer_v && std::is_pointer_v && + std::is_same_v< + std::remove_const_t>, + std::remove_pointer_t>) { + // Use memcpy for PODs iterated by pointers (which includes SmallVector + // iterators): std::uninitialized_copy optimizes to memmove, but we can + // use memcpy here. Note that I and E are iterators and thus might be + // invalid for memcpy if they are equal. + if (I != E) + std::memcpy(reinterpret_cast(Dest), I, (E - I) * sizeof(T)); + } else { + // Arbitrary iterator types; just use the basic implementation. + std::uninitialized_copy(I, E, Dest); + } } /// Double the size of the allocated memory, guaranteeing space for at