While researching ideas for a constexpr vector-like container, I ran into folly's small_vector container. I was reading through the implementation and was confused by this part of moveObjectsRightAndCreate
:
for (; in != first && out > lastConstructed;) {
// Out must be decremented before an exception can be thrown so that
// the rollback guard knows where to start.
--out;
new (out) T(std::move(*(--in)));
}
for (; in != first;) {
--out;
*out = std::move(*(--in));
}
for (; out > lastConstructed;) {
--out;
new (out) T(create());
}
for (; out != first;) {
--out;
*out = create();
}
My understanding is this: For parts of the array where memory was uninitialized, they use placement new with std::move
. For parts of the array where objects were previously moved from, they use move assignment.
It seems like the primary difference is whether the move constructor or move assignment is used, but I'm not really sure I understand the implications of these choices. Why not use placement new for both cases? Why not use move assignment for both cases? Since we know the size of the array, we will never call the destructor on uninitialized memory anyway, right?