collect-mac 0.1.0

This crate provides the `collect!` macro, which can be used to easily construct arbitrary collections, including `Vec`, `String`, and `HashMap`. It also endeavours to construct the collection with a single allocation, where possible.

Crate collect_mac [] [src]

This crate provides the collect! macro, which can be used to easily construct arbitrary collections, including Vec, String, and HashMap. It also endeavours to construct the collection with a single allocation, where possible.

Example

// In the crate root module:
#[macro_use] extern crate collect_mac;

// Initialise an empty collection.
let a: Vec<i32> = collect![];
let b: HashMap<String, bool> = collect![];

// Initialise a sequence.
let c: String = collect!['a', 'b', 'c'];

// Initialise a sequence with a type constraint.
let d = collect![as HashSet<_>: 0, 1, 2];

// Initialise a map collection.
let e: BTreeMap<i32, &str> = collect![
    1 => "one",
    2 => "two",
    3 => "many",
    4 => "lots",
];

// Initialise a map with a type constraint.
let f: HashMap<_, u8> = collect![as HashMap<i32, _>: 42 => 0, -11 => 2];

Details

The macro supports any collection which implements both the Default and Extend traits. Specifically, it creates a new, empty collection using Default, then calls Extend once for each element.

Single-allocation construction is tested and guaranteed for the following standard containers:

In general, single-allocation construction is done by providing the number of elements through the Iterator::size_hint of the first call to Extend. The expectation is that the collection will, if possible, pre-allocate enough space for all the elements when it goes to insert the first.

As an example, here is a simplified version of the Extend implementation for Vec:

impl<T> Extend<T> for Vec<T> {
    #[inline]
    fn extend<I: IntoIterator<Item=T>>(&mut self, iterable: I) {
        let mut iterator = iterable.into_iter();
        while let Some(element) = iterator.next() {
            let len = self.len();
            if len == self.capacity() {
                let (lower, _) = iterator.size_hint();
                self.reserve(lower.saturating_add(1));
            }
            self.push(element);
        }
    }
}

Macros

collect!

This macro can be used to easily construct arbitrary collections, including Vec, String, and HashMap. It also endeavours to construct the collection with a single allocation, where possible.