1 | use crate::{smallvec, SmallVec}; |
2 | |
3 | use std::iter::FromIterator; |
4 | |
5 | use alloc::borrow::ToOwned; |
6 | use alloc::boxed::Box; |
7 | use alloc::rc::Rc; |
8 | use alloc::{vec, vec::Vec}; |
9 | |
10 | #[test] |
11 | pub fn test_zero() { |
12 | let mut v = SmallVec::<[_; 0]>::new(); |
13 | assert!(!v.spilled()); |
14 | v.push(0usize); |
15 | assert!(v.spilled()); |
16 | assert_eq!(&*v, &[0]); |
17 | } |
18 | |
19 | // We heap allocate all these strings so that double frees will show up under valgrind. |
20 | |
21 | #[test] |
22 | pub fn test_inline() { |
23 | let mut v = SmallVec::<[_; 16]>::new(); |
24 | v.push("hello" .to_owned()); |
25 | v.push("there" .to_owned()); |
26 | assert_eq!(&*v, &["hello" .to_owned(), "there" .to_owned(),][..]); |
27 | } |
28 | |
29 | #[test] |
30 | pub fn test_spill() { |
31 | let mut v = SmallVec::<[_; 2]>::new(); |
32 | v.push("hello" .to_owned()); |
33 | assert_eq!(v[0], "hello" ); |
34 | v.push("there" .to_owned()); |
35 | v.push("burma" .to_owned()); |
36 | assert_eq!(v[0], "hello" ); |
37 | v.push("shave" .to_owned()); |
38 | assert_eq!( |
39 | &*v, |
40 | &[ |
41 | "hello" .to_owned(), |
42 | "there" .to_owned(), |
43 | "burma" .to_owned(), |
44 | "shave" .to_owned(), |
45 | ][..] |
46 | ); |
47 | } |
48 | |
49 | #[test] |
50 | pub fn test_double_spill() { |
51 | let mut v = SmallVec::<[_; 2]>::new(); |
52 | v.push("hello" .to_owned()); |
53 | v.push("there" .to_owned()); |
54 | v.push("burma" .to_owned()); |
55 | v.push("shave" .to_owned()); |
56 | v.push("hello" .to_owned()); |
57 | v.push("there" .to_owned()); |
58 | v.push("burma" .to_owned()); |
59 | v.push("shave" .to_owned()); |
60 | assert_eq!( |
61 | &*v, |
62 | &[ |
63 | "hello" .to_owned(), |
64 | "there" .to_owned(), |
65 | "burma" .to_owned(), |
66 | "shave" .to_owned(), |
67 | "hello" .to_owned(), |
68 | "there" .to_owned(), |
69 | "burma" .to_owned(), |
70 | "shave" .to_owned(), |
71 | ][..] |
72 | ); |
73 | } |
74 | |
75 | // https://github.com/servo/rust-smallvec/issues/4 |
76 | #[test] |
77 | fn issue_4() { |
78 | SmallVec::<[Box<u32>; 2]>::new(); |
79 | } |
80 | |
81 | // https://github.com/servo/rust-smallvec/issues/5 |
82 | #[test] |
83 | fn issue_5() { |
84 | assert!(Some(SmallVec::<[&u32; 2]>::new()).is_some()); |
85 | } |
86 | |
87 | #[test] |
88 | fn test_with_capacity() { |
89 | let v: SmallVec<[u8; 3]> = SmallVec::with_capacity(1); |
90 | assert!(v.is_empty()); |
91 | assert!(!v.spilled()); |
92 | assert_eq!(v.capacity(), 3); |
93 | |
94 | let v: SmallVec<[u8; 3]> = SmallVec::with_capacity(10); |
95 | assert!(v.is_empty()); |
96 | assert!(v.spilled()); |
97 | assert_eq!(v.capacity(), 10); |
98 | } |
99 | |
100 | #[test] |
101 | fn drain() { |
102 | let mut v: SmallVec<[u8; 2]> = SmallVec::new(); |
103 | v.push(3); |
104 | assert_eq!(v.drain(..).collect::<Vec<_>>(), &[3]); |
105 | |
106 | // spilling the vec |
107 | v.push(3); |
108 | v.push(4); |
109 | v.push(5); |
110 | let old_capacity = v.capacity(); |
111 | assert_eq!(v.drain(1..).collect::<Vec<_>>(), &[4, 5]); |
112 | // drain should not change the capacity |
113 | assert_eq!(v.capacity(), old_capacity); |
114 | |
115 | // Exercise the tail-shifting code when in the inline state |
116 | // This has the potential to produce UB due to aliasing |
117 | let mut v: SmallVec<[u8; 2]> = SmallVec::new(); |
118 | v.push(1); |
119 | v.push(2); |
120 | assert_eq!(v.drain(..1).collect::<Vec<_>>(), &[1]); |
121 | } |
122 | |
123 | #[test] |
124 | fn drain_rev() { |
125 | let mut v: SmallVec<[u8; 2]> = SmallVec::new(); |
126 | v.push(3); |
127 | assert_eq!(v.drain(..).rev().collect::<Vec<_>>(), &[3]); |
128 | |
129 | // spilling the vec |
130 | v.push(3); |
131 | v.push(4); |
132 | v.push(5); |
133 | assert_eq!(v.drain(..).rev().collect::<Vec<_>>(), &[5, 4, 3]); |
134 | } |
135 | |
136 | #[test] |
137 | fn drain_forget() { |
138 | let mut v: SmallVec<[u8; 1]> = smallvec![0, 1, 2, 3, 4, 5, 6, 7]; |
139 | std::mem::forget(v.drain(2..5)); |
140 | assert_eq!(v.len(), 2); |
141 | } |
142 | |
143 | #[test] |
144 | fn into_iter() { |
145 | let mut v: SmallVec<[u8; 2]> = SmallVec::new(); |
146 | v.push(3); |
147 | assert_eq!(v.into_iter().collect::<Vec<_>>(), &[3]); |
148 | |
149 | // spilling the vec |
150 | let mut v: SmallVec<[u8; 2]> = SmallVec::new(); |
151 | v.push(3); |
152 | v.push(4); |
153 | v.push(5); |
154 | assert_eq!(v.into_iter().collect::<Vec<_>>(), &[3, 4, 5]); |
155 | } |
156 | |
157 | #[test] |
158 | fn into_iter_rev() { |
159 | let mut v: SmallVec<[u8; 2]> = SmallVec::new(); |
160 | v.push(3); |
161 | assert_eq!(v.into_iter().rev().collect::<Vec<_>>(), &[3]); |
162 | |
163 | // spilling the vec |
164 | let mut v: SmallVec<[u8; 2]> = SmallVec::new(); |
165 | v.push(3); |
166 | v.push(4); |
167 | v.push(5); |
168 | assert_eq!(v.into_iter().rev().collect::<Vec<_>>(), &[5, 4, 3]); |
169 | } |
170 | |
171 | #[test] |
172 | fn into_iter_drop() { |
173 | use std::cell::Cell; |
174 | |
175 | struct DropCounter<'a>(&'a Cell<i32>); |
176 | |
177 | impl<'a> Drop for DropCounter<'a> { |
178 | fn drop(&mut self) { |
179 | self.0.set(self.0.get() + 1); |
180 | } |
181 | } |
182 | |
183 | { |
184 | let cell = Cell::new(0); |
185 | let mut v: SmallVec<[DropCounter<'_>; 2]> = SmallVec::new(); |
186 | v.push(DropCounter(&cell)); |
187 | v.into_iter(); |
188 | assert_eq!(cell.get(), 1); |
189 | } |
190 | |
191 | { |
192 | let cell = Cell::new(0); |
193 | let mut v: SmallVec<[DropCounter<'_>; 2]> = SmallVec::new(); |
194 | v.push(DropCounter(&cell)); |
195 | v.push(DropCounter(&cell)); |
196 | assert!(v.into_iter().next().is_some()); |
197 | assert_eq!(cell.get(), 2); |
198 | } |
199 | |
200 | { |
201 | let cell = Cell::new(0); |
202 | let mut v: SmallVec<[DropCounter<'_>; 2]> = SmallVec::new(); |
203 | v.push(DropCounter(&cell)); |
204 | v.push(DropCounter(&cell)); |
205 | v.push(DropCounter(&cell)); |
206 | assert!(v.into_iter().next().is_some()); |
207 | assert_eq!(cell.get(), 3); |
208 | } |
209 | { |
210 | let cell = Cell::new(0); |
211 | let mut v: SmallVec<[DropCounter<'_>; 2]> = SmallVec::new(); |
212 | v.push(DropCounter(&cell)); |
213 | v.push(DropCounter(&cell)); |
214 | v.push(DropCounter(&cell)); |
215 | { |
216 | let mut it = v.into_iter(); |
217 | assert!(it.next().is_some()); |
218 | assert!(it.next_back().is_some()); |
219 | } |
220 | assert_eq!(cell.get(), 3); |
221 | } |
222 | } |
223 | |
224 | #[test] |
225 | fn test_capacity() { |
226 | let mut v: SmallVec<[u8; 2]> = SmallVec::new(); |
227 | v.reserve(1); |
228 | assert_eq!(v.capacity(), 2); |
229 | assert!(!v.spilled()); |
230 | |
231 | v.reserve_exact(0x100); |
232 | assert!(v.capacity() >= 0x100); |
233 | |
234 | v.push(0); |
235 | v.push(1); |
236 | v.push(2); |
237 | v.push(3); |
238 | |
239 | v.shrink_to_fit(); |
240 | assert!(v.capacity() < 0x100); |
241 | } |
242 | |
243 | #[test] |
244 | fn test_truncate() { |
245 | let mut v: SmallVec<[Box<u8>; 8]> = SmallVec::new(); |
246 | |
247 | for x in 0..8 { |
248 | v.push(Box::new(x)); |
249 | } |
250 | v.truncate(4); |
251 | |
252 | assert_eq!(v.len(), 4); |
253 | assert!(!v.spilled()); |
254 | |
255 | assert_eq!(*v.swap_remove(1), 1); |
256 | assert_eq!(*v.remove(1), 3); |
257 | v.insert(1, Box::new(3)); |
258 | |
259 | assert_eq!(&v.iter().map(|v| **v).collect::<Vec<_>>(), &[0, 3, 2]); |
260 | } |
261 | |
262 | #[test] |
263 | fn test_insert_many() { |
264 | let mut v: SmallVec<[u8; 8]> = SmallVec::new(); |
265 | for x in 0..4 { |
266 | v.push(x); |
267 | } |
268 | assert_eq!(v.len(), 4); |
269 | v.insert_many(1, [5, 6].iter().cloned()); |
270 | assert_eq!( |
271 | &v.iter().map(|v| *v).collect::<Vec<_>>(), |
272 | &[0, 5, 6, 1, 2, 3] |
273 | ); |
274 | } |
275 | |
276 | struct MockHintIter<T: Iterator> { |
277 | x: T, |
278 | hint: usize, |
279 | } |
280 | impl<T: Iterator> Iterator for MockHintIter<T> { |
281 | type Item = T::Item; |
282 | fn next(&mut self) -> Option<Self::Item> { |
283 | self.x.next() |
284 | } |
285 | fn size_hint(&self) -> (usize, Option<usize>) { |
286 | (self.hint, None) |
287 | } |
288 | } |
289 | |
290 | #[test] |
291 | fn test_insert_many_short_hint() { |
292 | let mut v: SmallVec<[u8; 8]> = SmallVec::new(); |
293 | for x in 0..4 { |
294 | v.push(x); |
295 | } |
296 | assert_eq!(v.len(), 4); |
297 | v.insert_many( |
298 | 1, |
299 | MockHintIter { |
300 | x: [5, 6].iter().cloned(), |
301 | hint: 5, |
302 | }, |
303 | ); |
304 | assert_eq!( |
305 | &v.iter().map(|v| *v).collect::<Vec<_>>(), |
306 | &[0, 5, 6, 1, 2, 3] |
307 | ); |
308 | } |
309 | |
310 | #[test] |
311 | fn test_insert_many_long_hint() { |
312 | let mut v: SmallVec<[u8; 8]> = SmallVec::new(); |
313 | for x in 0..4 { |
314 | v.push(x); |
315 | } |
316 | assert_eq!(v.len(), 4); |
317 | v.insert_many( |
318 | 1, |
319 | MockHintIter { |
320 | x: [5, 6].iter().cloned(), |
321 | hint: 1, |
322 | }, |
323 | ); |
324 | assert_eq!( |
325 | &v.iter().map(|v| *v).collect::<Vec<_>>(), |
326 | &[0, 5, 6, 1, 2, 3] |
327 | ); |
328 | } |
329 | |
330 | // https://github.com/servo/rust-smallvec/issues/96 |
331 | mod insert_many_panic { |
332 | use crate::{smallvec, SmallVec}; |
333 | use alloc::boxed::Box; |
334 | |
335 | struct PanicOnDoubleDrop { |
336 | dropped: Box<bool>, |
337 | } |
338 | |
339 | impl PanicOnDoubleDrop { |
340 | fn new() -> Self { |
341 | Self { |
342 | dropped: Box::new(false), |
343 | } |
344 | } |
345 | } |
346 | |
347 | impl Drop for PanicOnDoubleDrop { |
348 | fn drop(&mut self) { |
349 | assert!(!*self.dropped, "already dropped" ); |
350 | *self.dropped = true; |
351 | } |
352 | } |
353 | |
354 | /// Claims to yield `hint` items, but actually yields `count`, then panics. |
355 | struct BadIter { |
356 | hint: usize, |
357 | count: usize, |
358 | } |
359 | |
360 | impl Iterator for BadIter { |
361 | type Item = PanicOnDoubleDrop; |
362 | fn size_hint(&self) -> (usize, Option<usize>) { |
363 | (self.hint, None) |
364 | } |
365 | fn next(&mut self) -> Option<Self::Item> { |
366 | if self.count == 0 { |
367 | panic!() |
368 | } |
369 | self.count -= 1; |
370 | Some(PanicOnDoubleDrop::new()) |
371 | } |
372 | } |
373 | |
374 | #[test] |
375 | fn panic_early_at_start() { |
376 | let mut vec: SmallVec<[PanicOnDoubleDrop; 0]> = |
377 | smallvec![PanicOnDoubleDrop::new(), PanicOnDoubleDrop::new(),]; |
378 | let result = ::std::panic::catch_unwind(move || { |
379 | vec.insert_many(0, BadIter { hint: 1, count: 0 }); |
380 | }); |
381 | assert!(result.is_err()); |
382 | } |
383 | |
384 | #[test] |
385 | fn panic_early_in_middle() { |
386 | let mut vec: SmallVec<[PanicOnDoubleDrop; 0]> = |
387 | smallvec![PanicOnDoubleDrop::new(), PanicOnDoubleDrop::new(),]; |
388 | let result = ::std::panic::catch_unwind(move || { |
389 | vec.insert_many(1, BadIter { hint: 4, count: 2 }); |
390 | }); |
391 | assert!(result.is_err()); |
392 | } |
393 | |
394 | #[test] |
395 | fn panic_early_at_end() { |
396 | let mut vec: SmallVec<[PanicOnDoubleDrop; 0]> = |
397 | smallvec![PanicOnDoubleDrop::new(), PanicOnDoubleDrop::new(),]; |
398 | let result = ::std::panic::catch_unwind(move || { |
399 | vec.insert_many(2, BadIter { hint: 3, count: 1 }); |
400 | }); |
401 | assert!(result.is_err()); |
402 | } |
403 | |
404 | #[test] |
405 | fn panic_late_at_start() { |
406 | let mut vec: SmallVec<[PanicOnDoubleDrop; 0]> = |
407 | smallvec![PanicOnDoubleDrop::new(), PanicOnDoubleDrop::new(),]; |
408 | let result = ::std::panic::catch_unwind(move || { |
409 | vec.insert_many(0, BadIter { hint: 3, count: 5 }); |
410 | }); |
411 | assert!(result.is_err()); |
412 | } |
413 | |
414 | #[test] |
415 | fn panic_late_at_end() { |
416 | let mut vec: SmallVec<[PanicOnDoubleDrop; 0]> = |
417 | smallvec![PanicOnDoubleDrop::new(), PanicOnDoubleDrop::new(),]; |
418 | let result = ::std::panic::catch_unwind(move || { |
419 | vec.insert_many(2, BadIter { hint: 3, count: 5 }); |
420 | }); |
421 | assert!(result.is_err()); |
422 | } |
423 | } |
424 | |
425 | #[test] |
426 | #[should_panic ] |
427 | fn test_invalid_grow() { |
428 | let mut v: SmallVec<[u8; 8]> = SmallVec::new(); |
429 | v.extend(0..8); |
430 | v.grow(5); |
431 | } |
432 | |
433 | #[test] |
434 | #[should_panic ] |
435 | fn drain_overflow() { |
436 | let mut v: SmallVec<[u8; 8]> = smallvec![0]; |
437 | v.drain(..=std::usize::MAX); |
438 | } |
439 | |
440 | #[test] |
441 | fn test_insert_from_slice() { |
442 | let mut v: SmallVec<[u8; 8]> = SmallVec::new(); |
443 | for x in 0..4 { |
444 | v.push(x); |
445 | } |
446 | assert_eq!(v.len(), 4); |
447 | v.insert_from_slice(1, &[5, 6]); |
448 | assert_eq!( |
449 | &v.iter().map(|v| *v).collect::<Vec<_>>(), |
450 | &[0, 5, 6, 1, 2, 3] |
451 | ); |
452 | } |
453 | |
454 | #[test] |
455 | fn test_extend_from_slice() { |
456 | let mut v: SmallVec<[u8; 8]> = SmallVec::new(); |
457 | for x in 0..4 { |
458 | v.push(x); |
459 | } |
460 | assert_eq!(v.len(), 4); |
461 | v.extend_from_slice(&[5, 6]); |
462 | assert_eq!( |
463 | &v.iter().map(|v| *v).collect::<Vec<_>>(), |
464 | &[0, 1, 2, 3, 5, 6] |
465 | ); |
466 | } |
467 | |
468 | #[test] |
469 | #[should_panic ] |
470 | fn test_drop_panic_smallvec() { |
471 | // This test should only panic once, and not double panic, |
472 | // which would mean a double drop |
473 | struct DropPanic; |
474 | |
475 | impl Drop for DropPanic { |
476 | fn drop(&mut self) { |
477 | panic!("drop" ); |
478 | } |
479 | } |
480 | |
481 | let mut v = SmallVec::<[_; 1]>::new(); |
482 | v.push(DropPanic); |
483 | } |
484 | |
485 | #[test] |
486 | fn test_eq() { |
487 | let mut a: SmallVec<[u32; 2]> = SmallVec::new(); |
488 | let mut b: SmallVec<[u32; 2]> = SmallVec::new(); |
489 | let mut c: SmallVec<[u32; 2]> = SmallVec::new(); |
490 | // a = [1, 2] |
491 | a.push(1); |
492 | a.push(2); |
493 | // b = [1, 2] |
494 | b.push(1); |
495 | b.push(2); |
496 | // c = [3, 4] |
497 | c.push(3); |
498 | c.push(4); |
499 | |
500 | assert!(a == b); |
501 | assert!(a != c); |
502 | } |
503 | |
504 | #[test] |
505 | fn test_ord() { |
506 | let mut a: SmallVec<[u32; 2]> = SmallVec::new(); |
507 | let mut b: SmallVec<[u32; 2]> = SmallVec::new(); |
508 | let mut c: SmallVec<[u32; 2]> = SmallVec::new(); |
509 | // a = [1] |
510 | a.push(1); |
511 | // b = [1, 1] |
512 | b.push(1); |
513 | b.push(1); |
514 | // c = [1, 2] |
515 | c.push(1); |
516 | c.push(2); |
517 | |
518 | assert!(a < b); |
519 | assert!(b > a); |
520 | assert!(b < c); |
521 | assert!(c > b); |
522 | } |
523 | |
524 | #[test] |
525 | fn test_hash() { |
526 | use std::collections::hash_map::DefaultHasher; |
527 | use std::hash::Hash; |
528 | |
529 | { |
530 | let mut a: SmallVec<[u32; 2]> = SmallVec::new(); |
531 | let b = [1, 2]; |
532 | a.extend(b.iter().cloned()); |
533 | let mut hasher = DefaultHasher::new(); |
534 | assert_eq!(a.hash(&mut hasher), b.hash(&mut hasher)); |
535 | } |
536 | { |
537 | let mut a: SmallVec<[u32; 2]> = SmallVec::new(); |
538 | let b = [1, 2, 11, 12]; |
539 | a.extend(b.iter().cloned()); |
540 | let mut hasher = DefaultHasher::new(); |
541 | assert_eq!(a.hash(&mut hasher), b.hash(&mut hasher)); |
542 | } |
543 | } |
544 | |
545 | #[test] |
546 | fn test_as_ref() { |
547 | let mut a: SmallVec<[u32; 2]> = SmallVec::new(); |
548 | a.push(1); |
549 | assert_eq!(a.as_ref(), [1]); |
550 | a.push(2); |
551 | assert_eq!(a.as_ref(), [1, 2]); |
552 | a.push(3); |
553 | assert_eq!(a.as_ref(), [1, 2, 3]); |
554 | } |
555 | |
556 | #[test] |
557 | fn test_as_mut() { |
558 | let mut a: SmallVec<[u32; 2]> = SmallVec::new(); |
559 | a.push(1); |
560 | assert_eq!(a.as_mut(), [1]); |
561 | a.push(2); |
562 | assert_eq!(a.as_mut(), [1, 2]); |
563 | a.push(3); |
564 | assert_eq!(a.as_mut(), [1, 2, 3]); |
565 | a.as_mut()[1] = 4; |
566 | assert_eq!(a.as_mut(), [1, 4, 3]); |
567 | } |
568 | |
569 | #[test] |
570 | fn test_borrow() { |
571 | use std::borrow::Borrow; |
572 | |
573 | let mut a: SmallVec<[u32; 2]> = SmallVec::new(); |
574 | a.push(1); |
575 | assert_eq!(a.borrow(), [1]); |
576 | a.push(2); |
577 | assert_eq!(a.borrow(), [1, 2]); |
578 | a.push(3); |
579 | assert_eq!(a.borrow(), [1, 2, 3]); |
580 | } |
581 | |
582 | #[test] |
583 | fn test_borrow_mut() { |
584 | use std::borrow::BorrowMut; |
585 | |
586 | let mut a: SmallVec<[u32; 2]> = SmallVec::new(); |
587 | a.push(1); |
588 | assert_eq!(a.borrow_mut(), [1]); |
589 | a.push(2); |
590 | assert_eq!(a.borrow_mut(), [1, 2]); |
591 | a.push(3); |
592 | assert_eq!(a.borrow_mut(), [1, 2, 3]); |
593 | BorrowMut::<[u32]>::borrow_mut(&mut a)[1] = 4; |
594 | assert_eq!(a.borrow_mut(), [1, 4, 3]); |
595 | } |
596 | |
597 | #[test] |
598 | fn test_from() { |
599 | assert_eq!(&SmallVec::<[u32; 2]>::from(&[1][..])[..], [1]); |
600 | assert_eq!(&SmallVec::<[u32; 2]>::from(&[1, 2, 3][..])[..], [1, 2, 3]); |
601 | |
602 | let vec = vec![]; |
603 | let small_vec: SmallVec<[u8; 3]> = SmallVec::from(vec); |
604 | assert_eq!(&*small_vec, &[]); |
605 | drop(small_vec); |
606 | |
607 | let vec = vec![1, 2, 3, 4, 5]; |
608 | let small_vec: SmallVec<[u8; 3]> = SmallVec::from(vec); |
609 | assert_eq!(&*small_vec, &[1, 2, 3, 4, 5]); |
610 | drop(small_vec); |
611 | |
612 | let vec = vec![1, 2, 3, 4, 5]; |
613 | let small_vec: SmallVec<[u8; 1]> = SmallVec::from(vec); |
614 | assert_eq!(&*small_vec, &[1, 2, 3, 4, 5]); |
615 | drop(small_vec); |
616 | |
617 | let array = [1]; |
618 | let small_vec: SmallVec<[u8; 1]> = SmallVec::from(array); |
619 | assert_eq!(&*small_vec, &[1]); |
620 | drop(small_vec); |
621 | |
622 | let array = [99; 128]; |
623 | let small_vec: SmallVec<[u8; 128]> = SmallVec::from(array); |
624 | assert_eq!(&*small_vec, vec![99u8; 128].as_slice()); |
625 | drop(small_vec); |
626 | } |
627 | |
628 | #[test] |
629 | fn test_from_slice() { |
630 | assert_eq!(&SmallVec::<[u32; 2]>::from_slice(&[1][..])[..], [1]); |
631 | assert_eq!( |
632 | &SmallVec::<[u32; 2]>::from_slice(&[1, 2, 3][..])[..], |
633 | [1, 2, 3] |
634 | ); |
635 | } |
636 | |
637 | #[test] |
638 | fn test_exact_size_iterator() { |
639 | let mut vec = SmallVec::<[u32; 2]>::from(&[1, 2, 3][..]); |
640 | assert_eq!(vec.clone().into_iter().len(), 3); |
641 | assert_eq!(vec.drain(..2).len(), 2); |
642 | assert_eq!(vec.into_iter().len(), 1); |
643 | } |
644 | |
645 | #[test] |
646 | fn test_into_iter_as_slice() { |
647 | let vec = SmallVec::<[u32; 2]>::from(&[1, 2, 3][..]); |
648 | let mut iter = vec.clone().into_iter(); |
649 | assert_eq!(iter.as_slice(), &[1, 2, 3]); |
650 | assert_eq!(iter.as_mut_slice(), &[1, 2, 3]); |
651 | iter.next(); |
652 | assert_eq!(iter.as_slice(), &[2, 3]); |
653 | assert_eq!(iter.as_mut_slice(), &[2, 3]); |
654 | iter.next_back(); |
655 | assert_eq!(iter.as_slice(), &[2]); |
656 | assert_eq!(iter.as_mut_slice(), &[2]); |
657 | } |
658 | |
659 | #[test] |
660 | fn test_into_iter_clone() { |
661 | // Test that the cloned iterator yields identical elements and that it owns its own copy |
662 | // (i.e. no use after move errors). |
663 | let mut iter = SmallVec::<[u8; 2]>::from_iter(0..3).into_iter(); |
664 | let mut clone_iter = iter.clone(); |
665 | while let Some(x) = iter.next() { |
666 | assert_eq!(x, clone_iter.next().unwrap()); |
667 | } |
668 | assert_eq!(clone_iter.next(), None); |
669 | } |
670 | |
671 | #[test] |
672 | fn test_into_iter_clone_partially_consumed_iterator() { |
673 | // Test that the cloned iterator only contains the remaining elements of the original iterator. |
674 | let mut iter = SmallVec::<[u8; 2]>::from_iter(0..3).into_iter().skip(1); |
675 | let mut clone_iter = iter.clone(); |
676 | while let Some(x) = iter.next() { |
677 | assert_eq!(x, clone_iter.next().unwrap()); |
678 | } |
679 | assert_eq!(clone_iter.next(), None); |
680 | } |
681 | |
682 | #[test] |
683 | fn test_into_iter_clone_empty_smallvec() { |
684 | let mut iter = SmallVec::<[u8; 2]>::new().into_iter(); |
685 | let mut clone_iter = iter.clone(); |
686 | assert_eq!(iter.next(), None); |
687 | assert_eq!(clone_iter.next(), None); |
688 | } |
689 | |
690 | #[test] |
691 | fn shrink_to_fit_unspill() { |
692 | let mut vec = SmallVec::<[u8; 2]>::from_iter(0..3); |
693 | vec.pop(); |
694 | assert!(vec.spilled()); |
695 | vec.shrink_to_fit(); |
696 | assert!(!vec.spilled(), "shrink_to_fit will un-spill if possible" ); |
697 | } |
698 | |
699 | #[test] |
700 | fn test_into_vec() { |
701 | let vec = SmallVec::<[u8; 2]>::from_iter(0..2); |
702 | assert_eq!(vec.into_vec(), vec![0, 1]); |
703 | |
704 | let vec = SmallVec::<[u8; 2]>::from_iter(0..3); |
705 | assert_eq!(vec.into_vec(), vec![0, 1, 2]); |
706 | } |
707 | |
708 | #[test] |
709 | fn test_into_inner() { |
710 | let vec = SmallVec::<[u8; 2]>::from_iter(0..2); |
711 | assert_eq!(vec.into_inner(), Ok([0, 1])); |
712 | |
713 | let vec = SmallVec::<[u8; 2]>::from_iter(0..1); |
714 | assert_eq!(vec.clone().into_inner(), Err(vec)); |
715 | |
716 | let vec = SmallVec::<[u8; 2]>::from_iter(0..3); |
717 | assert_eq!(vec.clone().into_inner(), Err(vec)); |
718 | } |
719 | |
720 | #[test] |
721 | fn test_from_vec() { |
722 | let vec = vec![]; |
723 | let small_vec: SmallVec<[u8; 3]> = SmallVec::from_vec(vec); |
724 | assert_eq!(&*small_vec, &[]); |
725 | drop(small_vec); |
726 | |
727 | let vec = vec![]; |
728 | let small_vec: SmallVec<[u8; 1]> = SmallVec::from_vec(vec); |
729 | assert_eq!(&*small_vec, &[]); |
730 | drop(small_vec); |
731 | |
732 | let vec = vec![1]; |
733 | let small_vec: SmallVec<[u8; 3]> = SmallVec::from_vec(vec); |
734 | assert_eq!(&*small_vec, &[1]); |
735 | drop(small_vec); |
736 | |
737 | let vec = vec![1, 2, 3]; |
738 | let small_vec: SmallVec<[u8; 3]> = SmallVec::from_vec(vec); |
739 | assert_eq!(&*small_vec, &[1, 2, 3]); |
740 | drop(small_vec); |
741 | |
742 | let vec = vec![1, 2, 3, 4, 5]; |
743 | let small_vec: SmallVec<[u8; 3]> = SmallVec::from_vec(vec); |
744 | assert_eq!(&*small_vec, &[1, 2, 3, 4, 5]); |
745 | drop(small_vec); |
746 | |
747 | let vec = vec![1, 2, 3, 4, 5]; |
748 | let small_vec: SmallVec<[u8; 1]> = SmallVec::from_vec(vec); |
749 | assert_eq!(&*small_vec, &[1, 2, 3, 4, 5]); |
750 | drop(small_vec); |
751 | } |
752 | |
753 | #[test] |
754 | fn test_retain() { |
755 | // Test inline data storate |
756 | let mut sv: SmallVec<[i32; 5]> = SmallVec::from_slice(&[1, 2, 3, 3, 4]); |
757 | sv.retain(|&mut i| i != 3); |
758 | assert_eq!(sv.pop(), Some(4)); |
759 | assert_eq!(sv.pop(), Some(2)); |
760 | assert_eq!(sv.pop(), Some(1)); |
761 | assert_eq!(sv.pop(), None); |
762 | |
763 | // Test spilled data storage |
764 | let mut sv: SmallVec<[i32; 3]> = SmallVec::from_slice(&[1, 2, 3, 3, 4]); |
765 | sv.retain(|&mut i| i != 3); |
766 | assert_eq!(sv.pop(), Some(4)); |
767 | assert_eq!(sv.pop(), Some(2)); |
768 | assert_eq!(sv.pop(), Some(1)); |
769 | assert_eq!(sv.pop(), None); |
770 | |
771 | // Test that drop implementations are called for inline. |
772 | let one = Rc::new(1); |
773 | let mut sv: SmallVec<[Rc<i32>; 3]> = SmallVec::new(); |
774 | sv.push(Rc::clone(&one)); |
775 | assert_eq!(Rc::strong_count(&one), 2); |
776 | sv.retain(|_| false); |
777 | assert_eq!(Rc::strong_count(&one), 1); |
778 | |
779 | // Test that drop implementations are called for spilled data. |
780 | let mut sv: SmallVec<[Rc<i32>; 1]> = SmallVec::new(); |
781 | sv.push(Rc::clone(&one)); |
782 | sv.push(Rc::new(2)); |
783 | assert_eq!(Rc::strong_count(&one), 2); |
784 | sv.retain(|_| false); |
785 | assert_eq!(Rc::strong_count(&one), 1); |
786 | } |
787 | |
788 | #[test] |
789 | fn test_dedup() { |
790 | let mut dupes: SmallVec<[i32; 5]> = SmallVec::from_slice(&[1, 1, 2, 3, 3]); |
791 | dupes.dedup(); |
792 | assert_eq!(&*dupes, &[1, 2, 3]); |
793 | |
794 | let mut empty: SmallVec<[i32; 5]> = SmallVec::new(); |
795 | empty.dedup(); |
796 | assert!(empty.is_empty()); |
797 | |
798 | let mut all_ones: SmallVec<[i32; 5]> = SmallVec::from_slice(&[1, 1, 1, 1, 1]); |
799 | all_ones.dedup(); |
800 | assert_eq!(all_ones.len(), 1); |
801 | |
802 | let mut no_dupes: SmallVec<[i32; 5]> = SmallVec::from_slice(&[1, 2, 3, 4, 5]); |
803 | no_dupes.dedup(); |
804 | assert_eq!(no_dupes.len(), 5); |
805 | } |
806 | |
807 | #[test] |
808 | fn test_resize() { |
809 | let mut v: SmallVec<[i32; 8]> = SmallVec::new(); |
810 | v.push(1); |
811 | v.resize(5, 0); |
812 | assert_eq!(v[..], [1, 0, 0, 0, 0][..]); |
813 | |
814 | v.resize(2, -1); |
815 | assert_eq!(v[..], [1, 0][..]); |
816 | } |
817 | |
818 | #[cfg (feature = "write" )] |
819 | #[test] |
820 | fn test_write() { |
821 | use std::io::Write; |
822 | |
823 | let data = [1, 2, 3, 4, 5]; |
824 | |
825 | let mut small_vec: SmallVec<[u8; 2]> = SmallVec::new(); |
826 | let len = small_vec.write(&data[..]).unwrap(); |
827 | assert_eq!(len, 5); |
828 | assert_eq!(small_vec.as_ref(), data.as_ref()); |
829 | |
830 | let mut small_vec: SmallVec<[u8; 2]> = SmallVec::new(); |
831 | small_vec.write_all(&data[..]).unwrap(); |
832 | assert_eq!(small_vec.as_ref(), data.as_ref()); |
833 | } |
834 | |
835 | #[cfg (feature = "serde" )] |
836 | #[test] |
837 | fn test_serde() { |
838 | use bincode::{config, deserialize}; |
839 | let mut small_vec: SmallVec<[i32; 2]> = SmallVec::new(); |
840 | small_vec.push(1); |
841 | let encoded = config().limit(100).serialize(&small_vec).unwrap(); |
842 | let decoded: SmallVec<[i32; 2]> = deserialize(&encoded).unwrap(); |
843 | assert_eq!(small_vec, decoded); |
844 | small_vec.push(2); |
845 | // Spill the vec |
846 | small_vec.push(3); |
847 | small_vec.push(4); |
848 | // Check again after spilling. |
849 | let encoded = config().limit(100).serialize(&small_vec).unwrap(); |
850 | let decoded: SmallVec<[i32; 2]> = deserialize(&encoded).unwrap(); |
851 | assert_eq!(small_vec, decoded); |
852 | } |
853 | |
854 | #[test] |
855 | fn grow_to_shrink() { |
856 | let mut v: SmallVec<[u8; 2]> = SmallVec::new(); |
857 | v.push(1); |
858 | v.push(2); |
859 | v.push(3); |
860 | assert!(v.spilled()); |
861 | v.clear(); |
862 | // Shrink to inline. |
863 | v.grow(2); |
864 | assert!(!v.spilled()); |
865 | assert_eq!(v.capacity(), 2); |
866 | assert_eq!(v.len(), 0); |
867 | v.push(4); |
868 | assert_eq!(v[..], [4]); |
869 | } |
870 | |
871 | #[test] |
872 | fn resumable_extend() { |
873 | let s = "a b c" ; |
874 | // This iterator yields: (Some('a'), None, Some('b'), None, Some('c')), None |
875 | let it = s |
876 | .chars() |
877 | .scan(0, |_, ch| if ch.is_whitespace() { None } else { Some(ch) }); |
878 | let mut v: SmallVec<[char; 4]> = SmallVec::new(); |
879 | v.extend(it); |
880 | assert_eq!(v[..], ['a' ]); |
881 | } |
882 | |
883 | // #139 |
884 | #[test] |
885 | fn uninhabited() { |
886 | enum Void {} |
887 | let _sv = SmallVec::<[Void; 8]>::new(); |
888 | } |
889 | |
890 | #[test] |
891 | fn grow_spilled_same_size() { |
892 | let mut v: SmallVec<[u8; 2]> = SmallVec::new(); |
893 | v.push(0); |
894 | v.push(1); |
895 | v.push(2); |
896 | assert!(v.spilled()); |
897 | assert_eq!(v.capacity(), 4); |
898 | // grow with the same capacity |
899 | v.grow(4); |
900 | assert_eq!(v.capacity(), 4); |
901 | assert_eq!(v[..], [0, 1, 2]); |
902 | } |
903 | |
904 | #[cfg (feature = "const_generics" )] |
905 | #[test] |
906 | fn const_generics() { |
907 | let _v = SmallVec::<[i32; 987]>::default(); |
908 | } |
909 | |
910 | #[cfg (feature = "const_new" )] |
911 | #[test] |
912 | fn const_new() { |
913 | let v = const_new_inner(); |
914 | assert_eq!(v.capacity(), 4); |
915 | assert_eq!(v.len(), 0); |
916 | let v = const_new_inline_sized(); |
917 | assert_eq!(v.capacity(), 4); |
918 | assert_eq!(v.len(), 4); |
919 | assert_eq!(v[0], 1); |
920 | let v = const_new_inline_args(); |
921 | assert_eq!(v.capacity(), 2); |
922 | assert_eq!(v.len(), 2); |
923 | assert_eq!(v[0], 1); |
924 | assert_eq!(v[1], 4); |
925 | } |
926 | #[cfg (feature = "const_new" )] |
927 | const fn const_new_inner() -> SmallVec<[i32; 4]> { |
928 | SmallVec::<[i32; 4]>::new_const() |
929 | } |
930 | #[cfg (feature = "const_new" )] |
931 | const fn const_new_inline_sized() -> SmallVec<[i32; 4]> { |
932 | crate::smallvec_inline![1; 4] |
933 | } |
934 | #[cfg (feature = "const_new" )] |
935 | const fn const_new_inline_args() -> SmallVec<[i32; 2]> { |
936 | crate::smallvec_inline![1, 4] |
937 | } |
938 | |
939 | #[test] |
940 | fn empty_macro() { |
941 | let _v: SmallVec<[u8; 1]> = smallvec![]; |
942 | } |
943 | |
944 | #[test] |
945 | fn zero_size_items() { |
946 | SmallVec::<[(); 0]>::new().push(()); |
947 | } |
948 | |
949 | #[test] |
950 | fn test_insert_many_overflow() { |
951 | let mut v: SmallVec<[u8; 1]> = SmallVec::new(); |
952 | v.push(123); |
953 | |
954 | // Prepare an iterator with small lower bound |
955 | let iter = (0u8..5).filter(|n| n % 2 == 0); |
956 | assert_eq!(iter.size_hint().0, 0); |
957 | |
958 | v.insert_many(0, iter); |
959 | assert_eq!(&*v, &[0, 2, 4, 123]); |
960 | } |
961 | |
962 | #[test] |
963 | fn test_clone_from() { |
964 | let mut a: SmallVec<[u8; 2]> = SmallVec::new(); |
965 | a.push(1); |
966 | a.push(2); |
967 | a.push(3); |
968 | |
969 | let mut b: SmallVec<[u8; 2]> = SmallVec::new(); |
970 | b.push(10); |
971 | |
972 | let mut c: SmallVec<[u8; 2]> = SmallVec::new(); |
973 | c.push(20); |
974 | c.push(21); |
975 | c.push(22); |
976 | |
977 | a.clone_from(&b); |
978 | assert_eq!(&*a, &[10]); |
979 | |
980 | b.clone_from(&c); |
981 | assert_eq!(&*b, &[20, 21, 22]); |
982 | } |
983 | |
984 | #[test] |
985 | fn test_size() { |
986 | use core::mem::size_of; |
987 | assert_eq!(24, size_of::<SmallVec<[u8; 8]>>()); |
988 | } |
989 | |
990 | #[cfg (feature = "drain_filter" )] |
991 | #[test] |
992 | fn drain_filter() { |
993 | let mut a: SmallVec<[u8; 2]> = smallvec![1u8, 2, 3, 4, 5, 6, 7, 8]; |
994 | |
995 | let b: SmallVec<[u8; 2]> = a.drain_filter(|x| *x % 3 == 0).collect(); |
996 | |
997 | assert_eq!(a, SmallVec::<[u8; 2]>::from_slice(&[1u8, 2, 4, 5, 7, 8])); |
998 | assert_eq!(b, SmallVec::<[u8; 2]>::from_slice(&[3u8, 6])); |
999 | } |
1000 | |
1001 | #[cfg (feature = "drain_keep_rest" )] |
1002 | #[test] |
1003 | fn drain_keep_rest() { |
1004 | let mut a: SmallVec<[i32; 3]> = smallvec![1i32, 2, 3, 4, 5, 6, 7, 8]; |
1005 | let mut df = a.drain_filter(|x| *x % 2 == 0); |
1006 | |
1007 | assert_eq!(df.next().unwrap(), 2); |
1008 | assert_eq!(df.next().unwrap(), 4); |
1009 | |
1010 | df.keep_rest(); |
1011 | |
1012 | assert_eq!(a, SmallVec::<[i32; 3]>::from_slice(&[1i32, 3, 5, 6, 7, 8])); |
1013 | } |
1014 | |