Skip to content

Vec::push_in_capacity ? #84649

Closed
Closed
@leonardo-m

Description

@leonardo-m

This enhancement suggestion looks a bit silly to me, but I think it's worth asking for an opinion in this bug tracker.

I think this is a reasonable usage pattern of Vec::spare_capacity_mut and Vec::set_len. I've used it with a larger SomeData to avoid both an useless initialization and the use of Vec::push that in those cases is slightly slower, the disadvantage is that this code contains unsafe{} and it's a bit fiddly:

#![feature(vec_spare_capacity, maybe_uninit_extra)]
fn cond(i: usize) -> bool { i % 2 == 0 }
struct SomeData(usize); // Something larger.
fn main() {
    const N: usize = 1_000_000;
    let mut data = Vec::with_capacity(N);
    let mut data_len = 0;
    let data_uninit = data.spare_capacity_mut();

    for i in 0 .. N {
        if cond(i) {
            data_uninit[data_len].write(SomeData(i));
            data_len += 1;
        }
    }
    unsafe {
        data.set_len(data_len);
    }
}

An API that removes the unsafety could be:

#![feature(vec_push_in_capacity)]
fn cond(i: usize) -> bool { i % 2 == 0 }
struct SomeData(usize); // Something larger.
fn main() {
    const N: usize = 1_000_000;
    let mut data = Vec::with_capacity(N);

    for i in 0 .. N {
        if cond(i) {
            data.push_in_capacity(SomeData(i));
        }
    }
}

Vec::push_in_capacity is similar to Vec::push, but it doesn't include any growing strategy (and doesn't include such growing/realloc code in the binary), so it just uses the capacity. If the capacity isn't enough it panics (just like the first code panics if the capacity is finished at data_uninit[data_len]).

Metadata

Metadata

Assignees

No one assigned

    Labels

    C-feature-requestCategory: A feature request, i.e: not implemented / a PR.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions