1 unstable release
Uses old Rust 2015
0.1.0 | Nov 13, 2015 |
---|
#1832 in Data structures
575 downloads per month
Used in 18 crates
(10 directly)
8KB
83 lines
collect!
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.
lib.rs
:
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);
}
}
}