about summary refs log tree commit diff
path: root/src/libsyntax/util
diff options
context:
space:
mode:
authorJeffrey Seyfried <jeffrey.seyfried@gmail.com>2016-06-26 02:18:04 +0000
committerJeffrey Seyfried <jeffrey.seyfried@gmail.com>2016-06-26 02:18:43 +0000
commit8eddf0280014972e051856dfe949054acf53c043 (patch)
tree8d4523f2bd6a218c75b5a602fa30d5cd85d8184c /src/libsyntax/util
parent8748cd92d06328af657934f6728183c10f92eefe (diff)
parent5033eca65f1dd9585aafa9cddd9d4bfd71b820c1 (diff)
downloadrust-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.rs59
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(),
+        }
+    }
+}