diff options
| author | Jeffrey Seyfried <jeffrey.seyfried@gmail.com> | 2016-06-26 02:18:04 +0000 |
|---|---|---|
| committer | Jeffrey Seyfried <jeffrey.seyfried@gmail.com> | 2016-06-26 02:18:43 +0000 |
| commit | 8eddf0280014972e051856dfe949054acf53c043 (patch) | |
| tree | 8d4523f2bd6a218c75b5a602fa30d5cd85d8184c /src/libsyntax/util | |
| parent | 8748cd92d06328af657934f6728183c10f92eefe (diff) | |
| parent | 5033eca65f1dd9585aafa9cddd9d4bfd71b820c1 (diff) | |
| download | rust-8eddf0280014972e051856dfe949054acf53c043.tar.gz rust-8eddf0280014972e051856dfe949054acf53c043.zip | |
Rollup merge of #34339 - jseyfried:thin_vec, r=petrochenkov,Manishearth
Generalize and abstract `ThinAttributes` to `ThinVec<Attribute>`.
Diffstat (limited to 'src/libsyntax/util')
| -rw-r--r-- | src/libsyntax/util/thin_vec.rs | 59 |
1 files changed, 59 insertions, 0 deletions
diff --git a/src/libsyntax/util/thin_vec.rs b/src/libsyntax/util/thin_vec.rs new file mode 100644 index 00000000000..546686b46b8 --- /dev/null +++ b/src/libsyntax/util/thin_vec.rs @@ -0,0 +1,59 @@ +// Copyright 2016 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +/// A vector type optimized for cases where this size is usually 0 (c.f. `SmallVector`). +/// The `Option<Box<..>>` wrapping allows us to represent a zero sized vector with `None`, +/// which uses only a single (null) pointer. +#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] +pub struct ThinVec<T>(Option<Box<Vec<T>>>); + +impl<T> ThinVec<T> { + pub fn new() -> Self { + ThinVec(None) + } +} + +impl<T> From<Vec<T>> for ThinVec<T> { + fn from(vec: Vec<T>) -> Self { + if vec.is_empty() { + ThinVec(None) + } else { + ThinVec(Some(Box::new(vec))) + } + } +} + +impl<T> Into<Vec<T>> for ThinVec<T> { + fn into(self) -> Vec<T> { + match self { + ThinVec(None) => Vec::new(), + ThinVec(Some(vec)) => *vec, + } + } +} + +impl<T> ::std::ops::Deref for ThinVec<T> { + type Target = [T]; + fn deref(&self) -> &[T] { + match *self { + ThinVec(None) => &[], + ThinVec(Some(ref vec)) => vec, + } + } +} + +impl<T> Extend<T> for ThinVec<T> { + fn extend<I: IntoIterator<Item = T>>(&mut self, iter: I) { + match *self { + ThinVec(Some(ref mut vec)) => vec.extend(iter), + ThinVec(None) => *self = iter.into_iter().collect::<Vec<_>>().into(), + } + } +} |
