Skip to content

Commit 707093b

Browse files
author
bors-servo
authored
Auto merge of #90 - dbkaplun:smallvec!, r=mbrubeck
Add vec!-like smallvec! macro Hello, This implements a smallvec! macro for the smallvec package. It infers the underlying Array size and has similar syntax to `vec!`. For users wishing to incorporate smallvec into their projects, this macro eases the transition significantly. Thanks for considering. <!-- Reviewable:start --> --- This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/rust-smallvec/90) <!-- Reviewable:end -->
2 parents 4749fc2 + 3d1eb54 commit 707093b

File tree

2 files changed

+83
-0
lines changed

2 files changed

+83
-0
lines changed

benches/bench.rs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#![feature(test)]
22

3+
#[macro_use]
34
extern crate smallvec;
45
extern crate test;
56

@@ -109,3 +110,23 @@ fn bench_pushpop(b: &mut Bencher) {
109110
vec
110111
});
111112
}
113+
114+
#[bench]
115+
fn bench_macro_from_elem(b: &mut Bencher) {
116+
b.iter(|| {
117+
let vec: SmallVec<[u64; 16]> = smallvec![42; 100];
118+
vec
119+
});
120+
}
121+
122+
#[bench]
123+
fn bench_macro_from_list(b: &mut Bencher) {
124+
b.iter(|| {
125+
let vec: SmallVec<[u64; 16]> = smallvec![
126+
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 20, 24, 32, 36, 0x40, 0x80,
127+
0x100, 0x200, 0x400, 0x800, 0x1000, 0x2000, 0x4000, 0x8000, 0x10000, 0x20000, 0x40000,
128+
0x80000, 0x100000
129+
];
130+
vec
131+
});
132+
}

lib.rs

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,55 @@ use std::marker::PhantomData;
5555

5656
use SmallVecData::{Inline, Heap};
5757

58+
/// Creates a [`SmallVec`] containing the arguments.
59+
///
60+
/// `smallvec!` allows `SmallVec`s to be defined with the same syntax as array expressions.
61+
/// There are two forms of this macro:
62+
///
63+
/// - Create a [`SmallVec`] containing a given list of elements:
64+
///
65+
/// ```
66+
/// # #[macro_use] extern crate smallvec;
67+
/// # use smallvec::SmallVec;
68+
/// # fn main() {
69+
/// let v: SmallVec<[_; 128]> = smallvec![1, 2, 3];
70+
/// assert_eq!(v[0], 1);
71+
/// assert_eq!(v[1], 2);
72+
/// assert_eq!(v[2], 3);
73+
/// # }
74+
/// ```
75+
///
76+
/// - Create a [`SmallVec`] from a given element and size:
77+
///
78+
/// ```
79+
/// # #[macro_use] extern crate smallvec;
80+
/// # use smallvec::SmallVec;
81+
/// # fn main() {
82+
/// let v: SmallVec<[_; 0x8000]> = smallvec![1; 3];
83+
/// assert_eq!(v, SmallVec::from_buf([1, 1, 1]));
84+
/// # }
85+
/// ```
86+
///
87+
/// Note that unlike array expressions this syntax supports all elements
88+
/// which implement [`Clone`] and the number of elements doesn't have to be
89+
/// a constant.
90+
///
91+
/// This will use `clone` to duplicate an expression, so one should be careful
92+
/// using this with types having a nonstandard `Clone` implementation. For
93+
/// example, `smallvec![Rc::new(1); 5]` will create a vector of five references
94+
/// to the same boxed integer value, not five references pointing to independently
95+
/// boxed integers.
96+
97+
#[macro_export]
98+
macro_rules! smallvec {
99+
($elem:expr; $n:expr) => ({
100+
SmallVec::from_elem($elem, $n)
101+
});
102+
($($x:expr),*) => ({
103+
SmallVec::from_slice(&[$($x),*])
104+
});
105+
}
106+
58107
/// Common operations implemented by both `Vec` and `SmallVec`.
59108
///
60109
/// This can be used to write generic code that works with both `Vec` and `SmallVec`.
@@ -747,6 +796,19 @@ impl<A: Array> SmallVec<A> where A::Item: Clone {
747796
self.truncate(len);
748797
}
749798
}
799+
800+
/// Creates a `SmallVec` with `n` copies of `elem`.
801+
/// ```
802+
/// use smallvec::SmallVec;
803+
///
804+
/// let v = SmallVec::<[char; 128]>::from_elem('d', 2);
805+
/// assert_eq!(v, SmallVec::from_buf(['d', 'd']));
806+
/// ```
807+
pub fn from_elem(elem: A::Item, n: usize) -> Self {
808+
let mut v = SmallVec::with_capacity(n);
809+
v.insert_many(0, (0..n).map(|_| elem.clone()));
810+
v
811+
}
750812
}
751813

752814
impl<A: Array> ops::Deref for SmallVec<A> {

0 commit comments

Comments
 (0)