about summary refs log tree commit diff
path: root/src/libsyntax/util
diff options
context:
space:
mode:
Diffstat (limited to 'src/libsyntax/util')
-rw-r--r--src/libsyntax/util/small_vector.rs36
1 files changed, 36 insertions, 0 deletions
diff --git a/src/libsyntax/util/small_vector.rs b/src/libsyntax/util/small_vector.rs
index 1649934f4b1..c4b096d656f 100644
--- a/src/libsyntax/util/small_vector.rs
+++ b/src/libsyntax/util/small_vector.rs
@@ -69,6 +69,42 @@ impl<T> SmallVector<T> {
         }
     }
 
+    pub fn pop(&mut self) -> Option<T> {
+        match self.repr {
+            Zero => None,
+            One(..) => {
+                let one = mem::replace(&mut self.repr, Zero);
+                match one {
+                    One(v1) => Some(v1),
+                    _ => unreachable!()
+                }
+            }
+            Many(..) => {
+                let mut many = mem::replace(&mut self.repr, Zero);
+                let item =
+                    match many {
+                        Many(ref mut vs) if vs.len() == 1 => {
+                            // self.repr is already Zero
+                            vs.pop()
+                        },
+                        Many(ref mut vs) if vs.len() == 2 => {
+                            let item = vs.pop();
+                            mem::replace(&mut self.repr, One(vs.pop().unwrap()));
+                            item
+                        },
+                        Many(ref mut vs) if vs.len() > 2 => {
+                            let item = vs.pop();
+                            let rest = mem::replace(vs, vec!());
+                            mem::replace(&mut self.repr, Many(rest));
+                            item
+                        },
+                        _ => unreachable!()
+                    };
+                item
+            }
+        }
+    }
+
     pub fn push(&mut self, v: T) {
         match self.repr {
             Zero => self.repr = One(v),