You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Implement an inline-only growable (bounded) 'vector' #863
This issue was labelled with: A-collections, A-libs in the Rust repository
Something like [T, .. n] but with a length field (and the correct destructor), so it's valid to store anywhere from 0 upto nTs in it. This can have Ts dynamically pushed and popped, but attempting to push more than n would be an error. I.e.
(The error could either be fail! or a Result<(), ...> return value.)
This is useful for data structures like 2-4-trees, B-trees etc., where they have internal nodes that store a sequence of keys with variable, but bounded, length. At the moment the only safe way to encode this is either a heap allocation (Vec) or with [Option<T>, .. n] where the "length" is modeled by storing [Some(x_1), Some(x_2), ..., Some(x_length), None, ..., None] (this leads to a lot of unwrap and unnecessary branches).
#197 is related, to make the destructors work right. For full generality we would need integer type params, but we can certainly have an internal abstraction of this form in collections (for use in btree etc.) with the lengths required hard-coded, and generalise/publish it later.
I think this could be done in a parameterized way even without integer generics if we use the array type as a parameter. I have a proof-of-concept implementation which seems to work although I'm not completely sure how much I can assume about the low-level representation of [T; n] values.
wow @tdudziak you had the same ideas as I, even down to the name! I've published crates.io/arrayvec by now, and I found some interesting quirks along the way. It turns out Option is not a good idea with uninitialized memory, see testcase here and solution (I think) with this enum here.
Yours is very nice because it doesn't use any array trait at all. That's probably superior.
It's worth looking at Gecko's nsAutoTArray: https://hg.mozilla.org/mozilla-central/file/d3228c82badd/xpcom/glue/nsTArray.h#l2296
It has inline storage and reallocates on the heap if the inline capacity is reached. This is extremely useful to be fast those 90% of the time where you know your array will have less than N elements and still works like a regular vector the rest of the time. I am not keen on the idea that the inline growable vector should error when the number of elements exceeds its capacity.
smallvec seems to be more of an optimized version of Vec for usages with predominately small size. Imo, this RFC aims for bounded vector that can be layout on stack without any dynamic allocation, at least when the item type is stack based too.
For the return type of push, I have a feeling it may be mostly used in static guaranteed case, where unwrap() every time could be a hassle. If we do use it in a dynamic way, we can always check the size before push. Looks to me panic! is better.
Looking forward for an implementation of this in std.
arrayvec is mentioned in this thread already. It's a bounded capacity vector. Capacity generics are limited by the current state of rust (no integer generic parameters).
Activity
tdudziak commentedon May 8, 2015
I think this could be done in a parameterized way even without integer generics if we use the array type as a parameter. I have a proof-of-concept implementation which seems to work although I'm not completely sure how much I can assume about the low-level representation of
[T; n]values.bluss commentedon May 27, 2015
wow @tdudziak you had the same ideas as I, even down to the name! I've published crates.io/arrayvec by now, and I found some interesting quirks along the way. It turns out Option is not a good idea with uninitialized memory, see testcase here and solution (I think) with this enum here.
Yours is very nice because it doesn't use any array trait at all. That's probably superior.
nical commentedon Jul 27, 2015
It's worth looking at Gecko's nsAutoTArray: https://hg.mozilla.org/mozilla-central/file/d3228c82badd/xpcom/glue/nsTArray.h#l2296
It has inline storage and reallocates on the heap if the inline capacity is reached. This is extremely useful to be fast those 90% of the time where you know your array will have less than N elements and still works like a regular vector the rest of the time. I am not keen on the idea that the inline growable vector should error when the number of elements exceeds its capacity.
bluss commentedon Jul 27, 2015
@nical, that's servo's smallvec
ticki commentedon Feb 15, 2016
Any plans for getting this into the standard library?
jonas-schievink commentedon Feb 15, 2016
@ticki I hope not until we have proper type-level numerals
ticki commentedon Feb 15, 2016
Right, that's why I said plans. Having a non-generic one would be a mess.
WiSaGaN commentedon Feb 19, 2016
smallvecseems to be more of an optimized version ofVecfor usages with predominately small size. Imo, this RFC aims for bounded vector that can be layout on stack without any dynamic allocation, at least when the item type is stack based too.For the return type of
push, I have a feeling it may be mostly used in static guaranteed case, whereunwrap()every time could be a hassle. If we do use it in a dynamic way, we can always check the size beforepush. Looks to mepanic!is better.Looking forward for an implementation of this in
std.ticki commentedon Feb 19, 2016
@WiSaGaN This is not what we are discussing. We are discussing a vector with an arbitrary size, but only heap allocated when a certain length is met.
WiSaGaN commentedon Feb 19, 2016
@ticki I am not sure that's the case. OP's post explicitly mentioned "bounded".
bluss commentedon Feb 19, 2016
arrayvec is mentioned in this thread already. It's a bounded capacity vector. Capacity generics are limited by the current state of rust (no integer generic parameters).
Centril commentedon Oct 7, 2018
Closing this in favor of
arrayvecfor the time being; const generics are being worked on, rust-lang/rust#44580.