diff --git a/clang/include/clang/AST/ASTVector.h b/clang/include/clang/AST/ASTVector.h index d5a04767ca133..ca30ec343492a 100644 --- a/clang/include/clang/AST/ASTVector.h +++ b/clang/include/clang/AST/ASTVector.h @@ -180,9 +180,21 @@ class ASTVector { size_t capacity() const { return this->capacity_ptr() - Begin; } /// append - Add the specified range to the end of the SmallVector. - template + template void append(const ASTContext &C, in_iter in_start, in_iter in_end) { - size_type NumInputs = std::distance(in_start, in_end); + using size_type = + typename std::remove_reference_t::size_type; + using iterator_category = + typename std::iterator_traits::iterator_category; + + size_t NumInputs = 0; + constexpr bool is_random_access = + std::is_base_of_v; + + if constexpr (is_random_access) + NumInputs = static_cast(in_end - in_start); + else + NumInputs = static_cast(std::distance(in_start, in_end)); if (NumInputs == 0) return; @@ -192,9 +204,11 @@ class ASTVector { this->grow(C, this->size()+NumInputs); // Copy the new elements over. - // TODO: NEED To compile time dispatch on whether in_iter is a random access - // iterator to use the fast uninitialized_copy. - std::uninitialized_copy(in_start, in_end, this->end()); + if constexpr (is_random_access) + std::uninitialized_copy_n(in_start, NumInputs, this->end()); + else + std::uninitialized_copy(in_start, in_end, this->end()); + this->setEnd(this->end() + NumInputs); }