Stop allowing use of SmallVectorBase::set_size() outside of the
SmallVector implementation, which sets the size without calling
constructors or destructors. Most callers should probably just use
resize(). Or, if the new size is guaranteed to be <= size() then
the new-ish truncate() works too (and optimizes better).
Some callers want to avoid initializing memory before copying in values.
Before this commit, this depended on reserve() and set_size():
auto Size = V.size(); V.reserve(V.size() + NumNew); // Reserve for the expected size. NumNew = initialize(V.end(), ...); // Get number added. V.set_size(V.size() + NumNew); // Set size to match.
Such code should be updated to use resize_for_overwrite() and
truncate():
auto Size = V.size(); V.resize_for_overwrite(Size + NumNew); // Resize to expected size. NumNew = initialize(V.begin() + Size, ...)); // Get number added. V.truncate(Size + NumNew); // Truncate to match.
The new pattern is safe even for non-trivial types, since
resize_for_overwrite() calls constructors and truncate() calls
destructors. For trivial types, it should optimize the same way as the
old pattern.
Downstream code adopting this new pattern to adapt to the disappearance
of set_size() should carefully audit uses of V between the resize
and the truncate:
- Change V.size() => Size.
- Change V.capacity() => V.size() (mostly).
- Change V.end() => V.begin() + Size.
- If V is an out-parameter, early returns need a V.truncate() or V.clear(). A scope exit is recommended.
I think maybe this can be removed entirely - all the call sites use "this->set_size", so I think they'd find that in the base class?