@@ -180,9 +180,21 @@ class ASTVector {
180180  size_t  capacity () const  { return  this ->capacity_ptr () - Begin; }
181181
182182  // / append - Add the specified range to the end of the SmallVector.
183-   template <typename  in_iter>
183+   template   <typename  in_iter>
184184  void  append (const  ASTContext &C, in_iter in_start, in_iter in_end) {
185-     size_type NumInputs = std::distance (in_start, in_end);
185+     using  size_type =
186+         typename  std::remove_reference_t <decltype (*this )>::size_type;
187+     using  iterator_category =
188+         typename  std::iterator_traits<in_iter>::iterator_category;
189+ 
190+     size_t  NumInputs = 0 ;
191+     constexpr  bool  is_random_access =
192+         std::is_base_of_v<std::random_access_iterator_tag, iterator_category>;
193+ 
194+     if  constexpr  (is_random_access)
195+       NumInputs = static_cast <size_type>(in_end - in_start);
196+     else 
197+       NumInputs = static_cast <size_type>(std::distance (in_start, in_end));
186198
187199    if  (NumInputs == 0 )
188200      return ;
@@ -192,9 +204,11 @@ class ASTVector {
192204      this ->grow (C, this ->size ()+NumInputs);
193205
194206    //  Copy the new elements over.
195-     //  TODO: NEED To compile time dispatch on whether in_iter is a random access
196-     //  iterator to use the fast uninitialized_copy.
197-     std::uninitialized_copy (in_start, in_end, this ->end ());
207+     if  constexpr  (is_random_access)
208+       std::uninitialized_copy_n (in_start, NumInputs, this ->end ());
209+     else 
210+       std::uninitialized_copy (in_start, in_end, this ->end ());
211+ 
198212    this ->setEnd (this ->end () + NumInputs);
199213  }
200214
0 commit comments