Assuming you fix the infinite loop at:
for(unsigned i = 0; i < totalSize - oldData.size(); ++i) oldData.push_back(0);
And write something like:
for(unsigned i = oldData.size(); i < totalSize; ++i) oldData.push_back(0);
or, even better:
oldData.resize(totalSize, 0);
Then std::move will move all the data from oldData to newData. Here is a quote from cppreference:
6) Move constructor. Constructs the container with the contents of other using move semantics. Allocator is obtained by move-construction from the allocator belonging to other. After the move, other is guaranteed to be empty().
7) Allocator-extended move constructor. Using alloc as the allocator for the new container, moving the contents from other; if alloc != other.get_allocator(), this results in an element-wise move. (in that case, other is not guaranteed to be empty after the move)
In your specific case, the vector has a default allocator, which means that only item (6) applies. However, if someone passes an allocator then things become more interesting.
Here is the rest of cppreference on the subject of complexity:
6) Constant.
7) Linear if alloc != other.get_allocator(), otherwise constant.
Again, in your case the complexity is O(1), but with allocators things get more interesting.
Conclusion: internal representation has to move a constant number of pointers in O(1), and not move the elements one-by-one. It is possible to implement vector with one pointer with capacity and size integers, or three pointers (begin, end, and the end of capacity). And for all these implementations, moving is a simple playing around with pointers.
However, if a non-default allocator is provided and the two vectors use a different allocator object, then the values have to be moved or copied one-by-one.
moveis fine, but think about your loop condition -oldData.size()keeps changing.std::vector::resizewill do exactly what you set out to do with thereserveand loop, only without a bug.