about summary refs log tree commit diff
path: root/src/librustc_data_structures
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2018-08-14 15:09:37 +0000
committerbors <bors@rust-lang.org>2018-08-14 15:09:37 +0000
commit23f09bbed4ef12c5f9db198c22f50b608ea6c6d5 (patch)
tree547c1cea1a62ace01f8cef6c8120612596208083 /src/librustc_data_structures
parentf45f52532a394d2d607fc5693364ad820049376d (diff)
parente5e6375352636360add297c1f5a1f37ce71506e9 (diff)
downloadrust-23f09bbed4ef12c5f9db198c22f50b608ea6c6d5.tar.gz
rust-23f09bbed4ef12c5f9db198c22f50b608ea6c6d5.zip
Auto merge of #53085 - ljedrz:cleanup_syntax_structures, r=ljedrz
Move SmallVector and ThinVec out of libsyntax

- move `libsyntax::util::SmallVector` tests to `librustc_data_structures::small_vec`
- remove `libsyntax::util::SmallVector`
- move `libsyntax::util::thin_vec` to `librustc_data_structures::thin_vec`

Other than moving these data structures where they belong it allows modules using `SmallVector<T>` (`SmallVec<[T; 1]>`) to specify their own length (e.g. 8 or 32) independently from `libsyntax`.
Diffstat (limited to 'src/librustc_data_structures')
-rw-r--r--src/librustc_data_structures/lib.rs1
-rw-r--r--src/librustc_data_structures/small_vec.rs65
-rw-r--r--src/librustc_data_structures/thin_vec.rs59
3 files changed, 125 insertions, 0 deletions
diff --git a/src/librustc_data_structures/lib.rs b/src/librustc_data_structures/lib.rs
index 421229a8909..5699512326a 100644
--- a/src/librustc_data_structures/lib.rs
+++ b/src/librustc_data_structures/lib.rs
@@ -79,6 +79,7 @@ pub mod sorted_map;
 #[macro_use] pub mod stable_hasher;
 pub mod sync;
 pub mod tiny_list;
+pub mod thin_vec;
 pub mod transitive_relation;
 pub mod tuple_slice;
 pub use ena::unify;
diff --git a/src/librustc_data_structures/small_vec.rs b/src/librustc_data_structures/small_vec.rs
index e958fd7da61..6f101b20d88 100644
--- a/src/librustc_data_structures/small_vec.rs
+++ b/src/librustc_data_structures/small_vec.rs
@@ -29,6 +29,8 @@ use array_vec::Array;
 
 pub struct SmallVec<A: Array>(AccumulateVec<A>);
 
+pub type OneVector<T> = SmallVec<[T; 1]>;
+
 impl<A> Clone for SmallVec<A>
     where A: Array,
           A::Element: Clone {
@@ -227,6 +229,69 @@ mod tests {
 
     use super::*;
 
+    #[test]
+    fn test_len() {
+        let v: OneVector<isize> = OneVector::new();
+        assert_eq!(0, v.len());
+
+        assert_eq!(1, OneVector::one(1).len());
+        assert_eq!(5, OneVector::many(vec![1, 2, 3, 4, 5]).len());
+    }
+
+    #[test]
+    fn test_push_get() {
+        let mut v = OneVector::new();
+        v.push(1);
+        assert_eq!(1, v.len());
+        assert_eq!(1, v[0]);
+        v.push(2);
+        assert_eq!(2, v.len());
+        assert_eq!(2, v[1]);
+        v.push(3);
+        assert_eq!(3, v.len());
+        assert_eq!(3, v[2]);
+    }
+
+    #[test]
+    fn test_from_iter() {
+        let v: OneVector<isize> = (vec![1, 2, 3]).into_iter().collect();
+        assert_eq!(3, v.len());
+        assert_eq!(1, v[0]);
+        assert_eq!(2, v[1]);
+        assert_eq!(3, v[2]);
+    }
+
+    #[test]
+    fn test_move_iter() {
+        let v = OneVector::new();
+        let v: Vec<isize> = v.into_iter().collect();
+        assert_eq!(v, Vec::new());
+
+        let v = OneVector::one(1);
+        assert_eq!(v.into_iter().collect::<Vec<_>>(), [1]);
+
+        let v = OneVector::many(vec![1, 2, 3]);
+        assert_eq!(v.into_iter().collect::<Vec<_>>(), [1, 2, 3]);
+    }
+
+    #[test]
+    #[should_panic]
+    fn test_expect_one_zero() {
+        let _: isize = OneVector::new().expect_one("");
+    }
+
+    #[test]
+    #[should_panic]
+    fn test_expect_one_many() {
+        OneVector::many(vec![1, 2]).expect_one("");
+    }
+
+    #[test]
+    fn test_expect_one_one() {
+        assert_eq!(1, OneVector::one(1).expect_one(""));
+        assert_eq!(1, OneVector::many(vec![1]).expect_one(""));
+    }
+
     #[bench]
     fn fill_small_vec_1_10_with_cap(b: &mut Bencher) {
         b.iter(|| {
diff --git a/src/librustc_data_structures/thin_vec.rs b/src/librustc_data_structures/thin_vec.rs
new file mode 100644
index 00000000000..546686b46b8
--- /dev/null
+++ b/src/librustc_data_structures/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(),
+        }
+    }
+}