1 // Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
15 /// A vector type optimized for cases where the size is almost always 0 or 1
16 pub enum SmallVector<T> {
22 impl<T> Container for SmallVector<T> {
23 fn len(&self) -> uint {
27 Many(ref vals) => vals.len()
32 impl<T> FromIterator<T> for SmallVector<T> {
33 fn from_iterator<I: Iterator<T>>(iter: &mut I) -> SmallVector<T> {
42 impl<T> SmallVector<T> {
43 pub fn zero() -> SmallVector<T> {
47 pub fn one(v: T) -> SmallVector<T> {
51 pub fn many(vs: Vec<T> ) -> SmallVector<T> {
55 pub fn push(&mut self, v: T) {
57 Zero => *self = One(v),
59 let one = mem::replace(self, Zero);
61 One(v1) => mem::replace(self, Many(vec!(v1, v))),
65 Many(ref mut vs) => vs.push(v)
69 pub fn push_all(&mut self, other: SmallVector<T>) {
70 for v in other.move_iter() {
75 pub fn get<'a>(&'a self, idx: uint) -> &'a T {
77 One(ref v) if idx == 0 => v,
78 Many(ref vs) => vs.get(idx),
79 _ => fail!("out of bounds access")
83 pub fn expect_one(self, err: &'static str) -> T {
88 v.move_iter().next().unwrap()
97 pub fn move_iter(self) -> MoveItems<T> {
100 One(v) => OneIterator(v),
101 Many(vs) => ManyIterator(vs.move_iter())
106 pub enum MoveItems<T> {
109 priv ManyIterator(vec_ng::MoveItems<T>),
112 impl<T> Iterator<T> for MoveItems<T> {
113 fn next(&mut self) -> Option<T> {
115 ZeroIterator => None,
117 let mut replacement = ZeroIterator;
118 mem::swap(self, &mut replacement);
120 OneIterator(v) => Some(v),
124 ManyIterator(ref mut inner) => inner.next()
128 fn size_hint(&self) -> (uint, Option<uint>) {
130 ZeroIterator => (0, Some(0)),
131 OneIterator(..) => (1, Some(1)),
132 ManyIterator(ref inner) => inner.size_hint()
141 use std::vec_ng::Vec;
145 let v: SmallVector<int> = SmallVector::zero();
146 assert_eq!(0, v.len());
148 assert_eq!(1, SmallVector::one(1).len());
149 assert_eq!(5, SmallVector::many(vec!(1, 2, 3, 4, 5)).len());
154 let mut v = SmallVector::zero();
156 assert_eq!(1, v.len());
157 assert_eq!(&1, v.get(0));
159 assert_eq!(2, v.len());
160 assert_eq!(&2, v.get(1));
162 assert_eq!(3, v.len());
163 assert_eq!(&3, v.get(2));
167 fn test_from_iterator() {
168 let v: SmallVector<int> = (vec!(1, 2, 3)).move_iter().collect();
169 assert_eq!(3, v.len());
170 assert_eq!(&1, v.get(0));
171 assert_eq!(&2, v.get(1));
172 assert_eq!(&3, v.get(2));
176 fn test_move_iter() {
177 let v = SmallVector::zero();
178 let v: Vec<int> = v.move_iter().collect();
179 assert_eq!(Vec::new(), v);
181 let v = SmallVector::one(1);
182 assert_eq!(vec!(1), v.move_iter().collect());
184 let v = SmallVector::many(vec!(1, 2, 3));
185 assert_eq!(vec!(1, 2, 3), v.move_iter().collect());
190 fn test_expect_one_zero() {
191 let _: int = SmallVector::zero().expect_one("");
196 fn test_expect_one_many() {
197 SmallVector::many(vec!(1, 2)).expect_one("");
201 fn test_expect_one_one() {
202 assert_eq!(1, SmallVector::one(1).expect_one(""));
203 assert_eq!(1, SmallVector::many(vec!(1)).expect_one(""));