From ae82dc2ec264ecf2c7fd0249b8f5783f3c466ed7 Mon Sep 17 00:00:00 2001 From: Dan Kaplun Date: Thu, 5 Apr 2018 22:42:36 -0400 Subject: [PATCH] Add smallvec! macro --- benches/bench.rs | 21 +++++++++++++++++++++ lib.rs | 49 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 70 insertions(+) diff --git a/benches/bench.rs b/benches/bench.rs index 3ca112a..9ffbb46 100644 --- a/benches/bench.rs +++ b/benches/bench.rs @@ -1,5 +1,6 @@ #![feature(test)] +#[macro_use] extern crate smallvec; extern crate test; @@ -109,3 +110,23 @@ fn bench_pushpop(b: &mut Bencher) { vec }); } + +#[bench] +fn bench_macro_from_elem(b: &mut Bencher) { + b.iter(|| { + let vec: SmallVec<[u64; 16]> = smallvec![42; 100]; + vec + }); +} + +#[bench] +fn bench_macro_from_list(b: &mut Bencher) { + b.iter(|| { + let vec: SmallVec<[u64; 16]> = smallvec![ + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 20, 24, 32, 36, 0x40, 0x80, + 0x100, 0x200, 0x400, 0x800, 0x1000, 0x2000, 0x4000, 0x8000, 0x10000, 0x20000, 0x40000, + 0x80000, 0x100000 + ]; + vec + }); +} diff --git a/lib.rs b/lib.rs index d2ba0ca..eaa157a 100644 --- a/lib.rs +++ b/lib.rs @@ -55,6 +55,55 @@ use std::marker::PhantomData; use SmallVecData::{Inline, Heap}; +/// Creates a [`SmallVec`] containing the arguments. +/// +/// `smallvec!` allows `SmallVec`s to be defined with the same syntax as array expressions. +/// There are two forms of this macro: +/// +/// - Create a [`SmallVec`] containing a given list of elements: +/// +/// ``` +/// # #[macro_use] extern crate smallvec; +/// # use smallvec::SmallVec; +/// # fn main() { +/// let v: SmallVec<[_; 128]> = smallvec![1, 2, 3]; +/// assert_eq!(v[0], 1); +/// assert_eq!(v[1], 2); +/// assert_eq!(v[2], 3); +/// # } +/// ``` +/// +/// - Create a [`SmallVec`] from a given element and size: +/// +/// ``` +/// # #[macro_use] extern crate smallvec; +/// # use smallvec::SmallVec; +/// # fn main() { +/// let v: SmallVec<[_; 0x8000]> = smallvec![1; 3]; +/// assert_eq!(v, SmallVec::from_buf([1, 1, 1])); +/// # } +/// ``` +/// +/// Note that unlike array expressions this syntax supports all elements +/// which implement [`Clone`] and the number of elements doesn't have to be +/// a constant. +/// +/// This will use `clone` to duplicate an expression, so one should be careful +/// using this with types having a nonstandard `Clone` implementation. For +/// example, `smallvec![Rc::new(1); 5]` will create a vector of five references +/// to the same boxed integer value, not five references pointing to independently +/// boxed integers. + +#[macro_export] +macro_rules! smallvec { + ($elem:expr; $n:expr) => ({ + SmallVec::from_elem($elem, $n) + }); + ($($x:expr),*) => ({ + SmallVec::from_slice(&[$($x),*]) + }); +} + /// Common operations implemented by both `Vec` and `SmallVec`. /// /// This can be used to write generic code that works with both `Vec` and `SmallVec`.