Thanks for your feedbacks. Very good idea about limiting the loop to what's needed.
I'll try to have a look because I need something similar to properly invalidate iterators on assignment in _GLIBCXX_DEBUG mode.
François On 9/22/26 12:56, Tomasz Kaminski wrote:
On Tue, Sep 22, 2026 at 12:21 PM Jonathan Wakely <[email protected]> wrote:On Mon, 21 Sept 2026 at 19:10, Tomasz Kaminski <[email protected]> wrote: > > Double loop allows us to check capacity (and throw) early and avoid insertions when > range is forward. And typical uses of std::inplace_vector will not be for huge sequences with many thousands of elements, so the cost of computing the distance first is bounded and should be reasonable. I don't think we should try to remove the double loop. What could be useful is not using ranges::distance or std::distance for non-sized sentinels, because what we could do is stop counting after finding that the range will not fit.We could use auto c = ranges::advance(it, n, end) for that and then check if c == n && it != end to throw. We will need separate loop for C++17 iterators.If the remaining capacity is 5 and we try to insert a range of 200 elements, we only need to count to 5 to determine that we haven't reached the sentinel and so it won't fit. Counting the other 195 elements is wasted work. > > On Mon, Sep 21, 2026 at 7:44 PM François Dumont <[email protected]> wrote: >> >> Hi >> >> I wonder what you think about this patch. >> >> Maybe this has already been discuss, sorry if so. >> >> If fine I'll try to isolate _S_distance in a testable helper. >> >> libstdc++: Do not loop several times on range given to >> std::inplace_vector::assign >> >> std::inplace_vector::assign first compute the distance between the >> input iterators >> before running the assignment loop. The distance is computed as >> long as the input >> range is a sized-sentinel or forward iterators. It means that when >> computing distance >> on a forward_list like in the added test the range will be loop >> through twice. >> >> As inplace_vector do not need reallocation to increase its capacity >> it seems more >> optimal to only get the distance if it can be done in O(1). >> Otherwise we just loop >> through the range and add elements using emplace_back. >> >> libstdc++-v3/ChangeLog: >> >> * include/std/inplace_vector (inplace_vector::_S_distance): >> Return a distance >> only if sized_sentinel_for or iterator is derived from >> random_access_iterator_tag. >> * >> testsuite/23_containers/inplace_vector/modifiers/assign_forward_list.cc: >> New test >> case. Only checking that the right thing is done but not >> that it is done with only >> one loop on the input range. >> >> Quickly tested with the added test case for now. >> >> François >>
