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.
11 use self::SmallVectorRepr
::*;
12 use self::IntoIterRepr
::*;
14 use std
::iter
::{IntoIterator, FromIterator}
;
21 /// A vector type optimized for cases where the size is almost always 0 or 1
22 pub struct SmallVector
<T
> {
23 repr
: SmallVectorRepr
<T
>,
26 enum SmallVectorRepr
<T
> {
32 impl<T
> FromIterator
<T
> for SmallVector
<T
> {
33 fn from_iter
<I
: IntoIterator
<Item
=T
>>(iter
: I
) -> SmallVector
<T
> {
34 let mut v
= SmallVector
::zero();
40 impl<T
> Extend
<T
> for SmallVector
<T
> {
41 fn extend
<I
: IntoIterator
<Item
=T
>>(&mut self, iter
: I
) {
48 impl<T
> SmallVector
<T
> {
49 pub fn zero() -> SmallVector
<T
> {
50 SmallVector { repr: Zero }
53 pub fn one(v
: T
) -> SmallVector
<T
> {
54 SmallVector { repr: One(v) }
57 pub fn many(vs
: Vec
<T
>) -> SmallVector
<T
> {
58 SmallVector { repr: Many(vs) }
61 pub fn as_slice
<'a
>(&'a
self) -> &'a
[T
] {
64 let result
: &[T
] = &[];
68 unsafe { slice::from_raw_parts(v, 1) }
74 pub fn pop(&mut self) -> Option
<T
> {
78 let one
= mem
::replace(&mut self.repr
, Zero
);
84 Many(ref mut vs
) => vs
.pop(),
88 pub fn push(&mut self, v
: T
) {
90 Zero
=> self.repr
= One(v
),
92 let one
= mem
::replace(&mut self.repr
, Zero
);
94 One(v1
) => mem
::replace(&mut self.repr
, Many(vec
!(v1
, v
))),
98 Many(ref mut vs
) => vs
.push(v
)
102 pub fn push_all(&mut self, other
: SmallVector
<T
>) {
103 for v
in other
.into_iter() {
108 pub fn get
<'a
>(&'a
self, idx
: usize) -> &'a T
{
110 One(ref v
) if idx
== 0 => v
,
111 Many(ref vs
) => &vs
[idx
],
112 _
=> panic
!("out of bounds access")
116 pub fn expect_one(self, err
: &'
static str) -> T
{
121 v
.into_iter().next().unwrap()
130 /// Deprecated: use `into_iter`.
131 #[unstable(feature = "rustc_private", issue = "0")]
132 #[deprecated(since = "1.0.0", reason = "use into_iter")]
133 pub fn move_iter(self) -> IntoIter
<T
> {
137 pub fn into_iter(self) -> IntoIter
<T
> {
138 let repr
= match self.repr
{
139 Zero
=> ZeroIterator
,
140 One(v
) => OneIterator(v
),
141 Many(vs
) => ManyIterator(vs
.into_iter())
143 IntoIter { repr: repr }
146 pub fn len(&self) -> usize {
150 Many(ref vals
) => vals
.len()
154 pub fn is_empty(&self) -> bool { self.len() == 0 }
157 pub struct IntoIter
<T
> {
158 repr
: IntoIterRepr
<T
>,
161 enum IntoIterRepr
<T
> {
164 ManyIterator(vec
::IntoIter
<T
>),
167 impl<T
> Iterator
for IntoIter
<T
> {
170 fn next(&mut self) -> Option
<T
> {
172 ZeroIterator
=> None
,
174 let mut replacement
= ZeroIterator
;
175 mem
::swap(&mut self.repr
, &mut replacement
);
177 OneIterator(v
) => Some(v
),
181 ManyIterator(ref mut inner
) => inner
.next()
185 fn size_hint(&self) -> (usize, Option
<usize>) {
187 ZeroIterator
=> (0, Some(0)),
188 OneIterator(..) => (1, Some(1)),
189 ManyIterator(ref inner
) => inner
.size_hint()
194 impl<T
> MoveMap
<T
> for SmallVector
<T
> {
195 fn move_map
<F
>(self, mut f
: F
) -> SmallVector
<T
> where F
: FnMut(T
) -> T
{
196 let repr
= match self.repr
{
199 Many(vs
) => Many(vs
.move_map(f
))
201 SmallVector { repr: repr }
211 let v
: SmallVector
<isize> = SmallVector
::zero();
212 assert_eq
!(0, v
.len());
214 assert_eq
!(1, SmallVector
::one(1).len());
215 assert_eq
!(5, SmallVector
::many(vec
![1, 2, 3, 4, 5]).len());
220 let mut v
= SmallVector
::zero();
222 assert_eq
!(1, v
.len());
223 assert_eq
!(&1, v
.get(0));
225 assert_eq
!(2, v
.len());
226 assert_eq
!(&2, v
.get(1));
228 assert_eq
!(3, v
.len());
229 assert_eq
!(&3, v
.get(2));
233 fn test_from_iter() {
234 let v
: SmallVector
<isize> = (vec
![1, 2, 3]).into_iter().collect();
235 assert_eq
!(3, v
.len());
236 assert_eq
!(&1, v
.get(0));
237 assert_eq
!(&2, v
.get(1));
238 assert_eq
!(&3, v
.get(2));
242 fn test_move_iter() {
243 let v
= SmallVector
::zero();
244 let v
: Vec
<isize> = v
.into_iter().collect();
245 assert_eq
!(v
, Vec
::new());
247 let v
= SmallVector
::one(1);
248 assert_eq
!(v
.into_iter().collect
::<Vec
<_
>>(), [1]);
250 let v
= SmallVector
::many(vec
![1, 2, 3]);
251 assert_eq
!(v
.into_iter().collect
::<Vec
<_
>>(), [1, 2, 3]);
256 fn test_expect_one_zero() {
257 let _
: isize = SmallVector
::zero().expect_one("");
262 fn test_expect_one_many() {
263 SmallVector
::many(vec
!(1, 2)).expect_one("");
267 fn test_expect_one_one() {
268 assert_eq
!(1, SmallVector
::one(1).expect_one(""));
269 assert_eq
!(1, SmallVector
::many(vec
!(1)).expect_one(""));