I would expect an idiomatic implementation to drastically go down in lines of code... while compile times probably will go up.
I would expect an idiomatic implementation to drastically go down in lines of code... while compile times probably will go up.
Can you give an example of where something in the project could be, say, 20 lines of code instead of 30? https://github.com/quick-lint/cpp-vs-rust/tree/master/rust
It's also idiomatic for push to return nothing and for pop to return the item (if any - and not crash if not empty!). Similarly back should return an Option instead of crashing on empty (and is called last in Rust). for_each is also unidiomatic - it's much more useful to provide an iterator over the collection.
Here's an example implementation in ~60LOC instead of ~200: https://play.rust-lang.org/?version=nightly&mode=debug&editi...
btw the author is looking to improve the Rust version and is accepting contributions in that repo if you wanna improve the experiment
That said, the pop implementation seems faulty in that it does not appear to deallocate empty chunks. Does Rust have any non-obvious magic here?
[1]: https://doc.rust-lang.org/std/vec/struct.Vec.html#guarantees
No, the only magic here is my utter lack of testing for throwaway HN code :) A corrected implementation would be:
pub fn pop(&mut self) -> Option<T> {
let last = self.chunks.last_mut()?;
let ret = last.pop()?;
if last.is_empty() {
self.chunks.pop();
}
Some(ret)
}
This is only correct if we maintain the invariant that we do not keep any empty chunks around, but the rest of the implementation does not violate this.