https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108487
--- Comment #16 from GCC Commits <cvs-commit at gcc dot gnu.org> --- The releases/gcc-14 branch has been updated by Jonathan Wakely <r...@gcc.gnu.org>: https://gcc.gnu.org/g:5a830c6cd54d376ee23043381c6ed761559e1e08 commit r14-11483-g5a830c6cd54d376ee23043381c6ed761559e1e08 Author: Jonathan Wakely <jwak...@redhat.com> Date: Tue Mar 25 13:24:08 2025 +0000 libstdc++: Optimize std::vector construction from input iterators [PR108487] LWG 3291 make std::ranges::iota_view's iterator have input_iterator_tag as its iterator_category, even though it satisfies the C++20 std::forward_iterator concept. This means that the traditional std::vector::vector(InputIterator, InputIterator) constructor treats iota_view iterators as input iterators, because it only understands the C++17 iterator requirements, not the C++20 iterator concepts. This results in a loop that calls emplace_back for each individual element of the iota_view, requiring the vector to reallocate repeatedly as the values are inserted. This makes it unnecessarily slow to construct a vector from an iota_view. This change adds a new _M_range_initialize_n function for initializing a vector from a range (which doesn't have to be common) and a size. This new function can be used by vector(InputIterator, InputIterator) when std::ranges::distance can be used to get the size. It can also be used by the _M_range_initialize overload that gets the size for a Cpp17ForwardIterator pair using std::distance, and by the vector(initializer_list) constructor. With this new function constructing a std::vector from iota_view does a single allocation of the correct size and so doesn't need to reallocate in a loop. libstdc++-v3/ChangeLog: PR libstdc++/108487 * include/bits/stl_vector.h (vector(initializer_list)): Call _M_range_initialize_n instead of _M_range_initialize. (vector(InputIterator, InputIterator)): Use _M_range_initialize_n for C++20 sized sentinels and forward iterators. (vector::_M_range_initialize(FwIt, FwIt, forward_iterator_tag)): Use _M_range_initialize_n. (vector::_M_range_initialize_n): New function. * testsuite/23_containers/vector/cons/108487.cc: New test. gcc/testsuite/ChangeLog: * g++.dg/tree-ssa/initlist-opt1.C: Match _M_range_initialize_n instead of _M_range_initialize. * g++.dg/tree-ssa/initlist-opt2.C: Likewise. Reviewed-by: Tomasz KamiÅski <tkami...@redhat.com> (cherry picked from commit e200f53a5556516ec831e6b7a34aaa0f10a4ab0a)