1 #![cfg(feature = "alloc")] 2 3 use super::*; 4 5 use alloc::vec::Vec; 6 7 /// Helper to make a `TinyVec`. 8 /// 9 /// You specify the backing array type, and optionally give all the elements you 10 /// want to initially place into the array. 11 /// 12 /// As an unfortunate restriction, the backing array type must support `Default` 13 /// for it to work with this macro. 14 /// 15 /// ```rust 16 /// use tinyvec::*; 17 /// 18 /// // The backing array type can be specified in the macro call 19 /// let empty_tv = tiny_vec!([u8; 16]); 20 /// let some_ints = tiny_vec!([i32; 4], 1, 2, 3); 21 /// let many_ints = tiny_vec!([i32; 4], 1, 2, 3, 4, 5, 6, 7, 8, 9, 10); 22 /// 23 /// // Or left to inference 24 /// let empty_tv: TinyVec<[u8; 16]> = tiny_vec!(); 25 /// let some_ints: TinyVec<[i32; 4]> = tiny_vec!(1, 2, 3); 26 /// let many_ints: TinyVec<[i32; 4]> = tiny_vec!(1, 2, 3, 4, 5, 6, 7, 8, 9, 10); 27 /// ``` 28 #[macro_export] 29 macro_rules! tiny_vec { 30 ($array_type:ty) => { 31 { 32 let mut tv: $crate::TinyVec<$array_type> = Default::default(); 33 tv 34 } 35 }; 36 ($array_type:ty, $($elem:expr),* $(,)?) => { 37 { 38 // Note(Lokathor): This goofy looking thing will count the number of 39 // `$elem` entries we were given. We can't spit out the "+1"s on their 40 // own, we need to use `$elem` in the repetition-expansion somehow. 41 // However, we also can't assume it's `Copy` data, so we must use `$elem` 42 // only once "for real" in the expansion as a whole. To achieve this, we 43 // can `stringify!` each element in an inner block, then have the block 44 // return a 1. The stringification is a compile time thing, it won't 45 // actually move any values. 46 const INVOKED_ELEM_COUNT: usize = 0 $( + { let _ = stringify!($elem); 1 })*; 47 // If we have more `$elem` than the `CAPACITY` we will simply go directly 48 // to constructing on the heap. 49 let av: $crate::TinyVec<$array_type> = $crate::TinyVec::from_either_with_capacity( 50 INVOKED_ELEM_COUNT, 51 #[inline(always)] || $crate::array_vec!($array_type, $($elem),*), 52 #[inline(always)] || vec!($($elem),*)); 53 av 54 } 55 }; 56 () => { 57 tiny_vec!(_) 58 }; 59 ($($elem:expr),*) => { 60 tiny_vec!(_, $($elem),*) 61 }; 62 } 63 64 /// A vector that starts inline, but can automatically move to the heap. 65 /// 66 /// * Requires the `alloc` feature 67 /// 68 /// A `TinyVec` is either an Inline([`ArrayVec`](crate::ArrayVec::<A>)) or 69 /// Heap([`Vec`](https://doc.rust-lang.org/alloc/vec/struct.Vec.html)). The 70 /// interface for the type as a whole is a bunch of methods that just match on 71 /// the enum variant and then call the same method on the inner vec. 72 /// 73 /// ## Construction 74 /// 75 /// Because it's an enum, you can construct a `TinyVec` simply by making an 76 /// `ArrayVec` or `Vec` and then putting it into the enum. 77 /// 78 /// There is also a macro 79 /// 80 /// ```rust 81 /// # use tinyvec::*; 82 /// let empty_tv = tiny_vec!([u8; 16]); 83 /// let some_ints = tiny_vec!([i32; 4], 1, 2, 3); 84 /// ``` 85 #[derive(Clone)] 86 pub enum TinyVec<A: Array> { 87 #[allow(missing_docs)] 88 Inline(ArrayVec<A>), 89 #[allow(missing_docs)] 90 Heap(Vec<A::Item>), 91 } 92 impl<A: Array + Default> Default for TinyVec<A> { 93 #[inline] 94 #[must_use] default() -> Self95 fn default() -> Self { 96 TinyVec::Inline(ArrayVec::default()) 97 } 98 } 99 100 impl<A: Array> Deref for TinyVec<A> { 101 type Target = [A::Item]; 102 #[inline(always)] 103 #[must_use] deref(&self) -> &Self::Target104 fn deref(&self) -> &Self::Target { 105 match self { 106 TinyVec::Inline(a) => a.deref(), 107 TinyVec::Heap(v) => v.deref(), 108 } 109 } 110 } 111 112 impl<A: Array> DerefMut for TinyVec<A> { 113 #[inline(always)] 114 #[must_use] deref_mut(&mut self) -> &mut Self::Target115 fn deref_mut(&mut self) -> &mut Self::Target { 116 match self { 117 TinyVec::Inline(a) => a.deref_mut(), 118 TinyVec::Heap(v) => v.deref_mut(), 119 } 120 } 121 } 122 123 impl<A: Array, I: SliceIndex<[A::Item]>> Index<I> for TinyVec<A> { 124 type Output = <I as SliceIndex<[A::Item]>>::Output; 125 #[inline(always)] 126 #[must_use] index(&self, index: I) -> &Self::Output127 fn index(&self, index: I) -> &Self::Output { 128 &self.deref()[index] 129 } 130 } 131 132 impl<A: Array, I: SliceIndex<[A::Item]>> IndexMut<I> for TinyVec<A> { 133 #[inline(always)] 134 #[must_use] index_mut(&mut self, index: I) -> &mut Self::Output135 fn index_mut(&mut self, index: I) -> &mut Self::Output { 136 &mut self.deref_mut()[index] 137 } 138 } 139 140 impl<A: Array> TinyVec<A> { 141 /// Moves the content of the TinyVec to the heap, if it's inline. 142 #[allow(clippy::missing_inline_in_public_items)] move_to_the_heap(&mut self)143 pub fn move_to_the_heap(&mut self) { 144 match self { 145 TinyVec::Inline(ref mut arr) => { 146 let mut v = Vec::with_capacity(A::CAPACITY * 2); 147 for item in arr.drain(..) { 148 v.push(item); 149 } 150 replace(self, TinyVec::Heap(v)); 151 } 152 TinyVec::Heap(_) => (), 153 } 154 } 155 } 156 157 impl<A: Array> TinyVec<A> { 158 /// Move all values from `other` into this vec. 159 #[inline] append(&mut self, other: &mut Self)160 pub fn append(&mut self, other: &mut Self) { 161 for item in other.drain(..) { 162 self.push(item) 163 } 164 } 165 166 /// A mutable pointer to the backing array. 167 /// 168 /// ## Safety 169 /// 170 /// This pointer has provenance over the _entire_ backing array/buffer. 171 #[inline(always)] 172 #[must_use] as_mut_ptr(&mut self) -> *mut A::Item173 pub fn as_mut_ptr(&mut self) -> *mut A::Item { 174 match self { 175 TinyVec::Inline(a) => a.as_mut_ptr(), 176 TinyVec::Heap(v) => v.as_mut_ptr(), 177 } 178 } 179 180 /// Helper for getting the mut slice. 181 #[inline(always)] 182 #[must_use] as_mut_slice(&mut self) -> &mut [A::Item]183 pub fn as_mut_slice(&mut self) -> &mut [A::Item] { 184 self.deref_mut() 185 } 186 187 /// A const pointer to the backing array. 188 /// 189 /// ## Safety 190 /// 191 /// This pointer has provenance over the _entire_ backing array/buffer. 192 #[inline(always)] 193 #[must_use] as_ptr(&self) -> *const A::Item194 pub fn as_ptr(&self) -> *const A::Item { 195 match self { 196 TinyVec::Inline(a) => a.as_ptr(), 197 TinyVec::Heap(v) => v.as_ptr(), 198 } 199 } 200 201 /// Helper for getting the shared slice. 202 #[inline(always)] 203 #[must_use] as_slice(&self) -> &[A::Item]204 pub fn as_slice(&self) -> &[A::Item] { 205 self.deref() 206 } 207 208 /// The capacity of the `TinyVec`. 209 /// 210 /// When not heap allocated this is fixed based on the array type. 211 /// Otherwise its the result of the underlying Vec::capacity. 212 #[inline(always)] 213 #[must_use] capacity(&self) -> usize214 pub fn capacity(&self) -> usize { 215 match self { 216 TinyVec::Inline(_) => A::CAPACITY, 217 TinyVec::Heap(v) => v.capacity(), 218 } 219 } 220 221 /// Removes all elements from the vec. 222 #[inline(always)] clear(&mut self)223 pub fn clear(&mut self) { 224 self.truncate(0) 225 } 226 227 /// De-duplicates the vec. 228 #[cfg(feature = "nightly_slice_partition_dedup")] 229 #[inline(always)] dedup(&mut self) where A::Item: PartialEq,230 pub fn dedup(&mut self) 231 where 232 A::Item: PartialEq, 233 { 234 self.dedup_by(|a, b| a == b) 235 } 236 237 /// De-duplicates the vec according to the predicate given. 238 #[cfg(feature = "nightly_slice_partition_dedup")] 239 #[inline(always)] dedup_by<F>(&mut self, same_bucket: F) where F: FnMut(&mut A::Item, &mut A::Item) -> bool,240 pub fn dedup_by<F>(&mut self, same_bucket: F) 241 where 242 F: FnMut(&mut A::Item, &mut A::Item) -> bool, 243 { 244 let len = { 245 let (dedup, _) = self.as_mut_slice().partition_dedup_by(same_bucket); 246 dedup.len() 247 }; 248 self.truncate(len); 249 } 250 251 /// De-duplicates the vec according to the key selector given. 252 #[cfg(feature = "nightly_slice_partition_dedup")] 253 #[inline(always)] dedup_by_key<F, K>(&mut self, mut key: F) where F: FnMut(&mut A::Item) -> K, K: PartialEq,254 pub fn dedup_by_key<F, K>(&mut self, mut key: F) 255 where 256 F: FnMut(&mut A::Item) -> K, 257 K: PartialEq, 258 { 259 self.dedup_by(|a, b| key(a) == key(b)) 260 } 261 262 /// Creates a draining iterator that removes the specified range in the vector 263 /// and yields the removed items. 264 /// 265 /// ## Panics 266 /// * If the start is greater than the end 267 /// * If the end is past the edge of the vec. 268 /// 269 /// ## Example 270 /// ```rust 271 /// use tinyvec::*; 272 /// let mut tv = tiny_vec!([i32; 4], 1, 2, 3); 273 /// let tv2: TinyVec<[i32; 4]> = tv.drain(1..).collect(); 274 /// assert_eq!(tv.as_slice(), &[1][..]); 275 /// assert_eq!(tv2.as_slice(), &[2, 3][..]); 276 /// 277 /// tv.drain(..); 278 /// assert_eq!(tv.as_slice(), &[]); 279 /// ``` 280 #[inline] drain<R: RangeBounds<usize>>( &mut self, range: R, ) -> TinyVecDrain<'_, A>281 pub fn drain<R: RangeBounds<usize>>( 282 &mut self, 283 range: R, 284 ) -> TinyVecDrain<'_, A> { 285 use core::ops::Bound; 286 let start = match range.start_bound() { 287 Bound::Included(x) => *x, 288 Bound::Excluded(x) => x + 1, 289 Bound::Unbounded => 0, 290 }; 291 let end = match range.end_bound() { 292 Bound::Included(x) => x + 1, 293 Bound::Excluded(x) => *x, 294 Bound::Unbounded => self.len(), 295 }; 296 assert!( 297 start <= end, 298 "TinyVec::drain> Illegal range, {} to {}", 299 start, 300 end 301 ); 302 assert!( 303 end <= self.len(), 304 "TinyVec::drain> Range ends at {} but length is only {}!", 305 end, 306 self.len() 307 ); 308 TinyVecDrain { 309 parent: self, 310 target_index: start, 311 target_count: end - start, 312 } 313 } 314 315 /// Clone each element of the slice into this vec. 316 #[inline] extend_from_slice(&mut self, sli: &[A::Item]) where A::Item: Clone,317 pub fn extend_from_slice(&mut self, sli: &[A::Item]) 318 where 319 A::Item: Clone, 320 { 321 for i in sli { 322 self.push(i.clone()) 323 } 324 } 325 326 /// Wraps up an array and uses the given length as the initial length. 327 /// 328 /// Note that the `From` impl for arrays assumes the full length is used. 329 /// 330 /// ## Panics 331 /// 332 /// The length must be less than or equal to the capacity of the array. 333 #[inline] 334 #[must_use] 335 #[allow(clippy::match_wild_err_arm)] from_array_len(data: A, len: usize) -> Self336 pub fn from_array_len(data: A, len: usize) -> Self { 337 match Self::try_from_array_len(data, len) { 338 Ok(out) => out, 339 Err(_) => { 340 panic!("TinyVec: length {} exceeds capacity {}!", len, A::CAPACITY) 341 } 342 } 343 } 344 345 #[inline(always)] 346 #[doc(hidden)] // Internal implementation details of `tiny_vec!` from_either_with_capacity( cap: usize, make_array: impl FnOnce() -> ArrayVec<A>, make_vec: impl FnOnce() -> Vec<A::Item>, ) -> Self347 pub fn from_either_with_capacity( 348 cap: usize, 349 make_array: impl FnOnce() -> ArrayVec<A>, 350 make_vec: impl FnOnce() -> Vec<A::Item>, 351 ) -> Self { 352 if cap <= A::CAPACITY { 353 TinyVec::Inline(make_array()) 354 } else { 355 TinyVec::Heap(make_vec()) 356 } 357 } 358 359 /// Inserts an item at the position given, moving all following elements +1 360 /// index. 361 /// 362 /// ## Panics 363 /// * If `index` > `len` 364 /// 365 /// ## Example 366 /// ```rust 367 /// use tinyvec::*; 368 /// let mut tv = tiny_vec!([i32; 10], 1, 2, 3); 369 /// tv.insert(1, 4); 370 /// assert_eq!(tv.as_slice(), &[1, 4, 2, 3]); 371 /// tv.insert(4, 5); 372 /// assert_eq!(tv.as_slice(), &[1, 4, 2, 3, 5]); 373 /// ``` 374 #[inline] insert(&mut self, index: usize, item: A::Item)375 pub fn insert(&mut self, index: usize, item: A::Item) { 376 match self { 377 TinyVec::Inline(a) => { 378 if a.len() == A::CAPACITY { 379 self.move_to_the_heap(); 380 self.insert(index, item) 381 } else { 382 a.insert(index, item); 383 } 384 } 385 TinyVec::Heap(v) => v.insert(index, item), 386 } 387 } 388 389 /// If the vec is empty. 390 #[inline(always)] 391 #[must_use] is_empty(&self) -> bool392 pub fn is_empty(&self) -> bool { 393 self.len() == 0 394 } 395 396 /// The length of the vec (in elements). 397 #[inline(always)] 398 #[must_use] len(&self) -> usize399 pub fn len(&self) -> usize { 400 match self { 401 TinyVec::Inline(a) => a.len(), 402 TinyVec::Heap(v) => v.len(), 403 } 404 } 405 406 /// Makes a new, empty vec. 407 #[inline(always)] 408 #[must_use] new() -> Self where A: Default,409 pub fn new() -> Self 410 where 411 A: Default, 412 { 413 Self::default() 414 } 415 416 /// Remove and return the last element of the vec, if there is one. 417 /// 418 /// ## Failure 419 /// * If the vec is empty you get `None`. 420 #[inline] pop(&mut self) -> Option<A::Item>421 pub fn pop(&mut self) -> Option<A::Item> { 422 match self { 423 TinyVec::Inline(a) => a.pop(), 424 TinyVec::Heap(v) => v.pop(), 425 } 426 } 427 428 /// Place an element onto the end of the vec. 429 /// ## Panics 430 /// * If the length of the vec would overflow the capacity. 431 #[inline(always)] push(&mut self, val: A::Item)432 pub fn push(&mut self, val: A::Item) { 433 match self { 434 TinyVec::Inline(a) => { 435 if a.len() == A::CAPACITY { 436 self.move_to_the_heap(); 437 self.push(val) 438 } else { 439 a.push(val); 440 } 441 } 442 TinyVec::Heap(v) => v.push(val), 443 } 444 } 445 446 /// Removes the item at `index`, shifting all others down by one index. 447 /// 448 /// Returns the removed element. 449 /// 450 /// ## Panics 451 /// 452 /// If the index is out of bounds. 453 /// 454 /// ## Example 455 /// 456 /// ```rust 457 /// use tinyvec::*; 458 /// let mut tv = tiny_vec!([i32; 4], 1, 2, 3); 459 /// assert_eq!(tv.remove(1), 2); 460 /// assert_eq!(tv.as_slice(), &[1, 3][..]); 461 /// ``` 462 #[inline] remove(&mut self, index: usize) -> A::Item463 pub fn remove(&mut self, index: usize) -> A::Item { 464 match self { 465 TinyVec::Inline(a) => a.remove(index), 466 TinyVec::Heap(v) => v.remove(index), 467 } 468 } 469 470 /// Resize the vec to the new length. 471 /// 472 /// If it needs to be longer, it's filled with clones of the provided value. 473 /// If it needs to be shorter, it's truncated. 474 /// 475 /// ## Example 476 /// 477 /// ```rust 478 /// use tinyvec::*; 479 /// 480 /// let mut tv = tiny_vec!([&str; 10], "hello"); 481 /// tv.resize(3, "world"); 482 /// assert_eq!(tv.as_slice(), &["hello", "world", "world"][..]); 483 /// 484 /// let mut tv = tiny_vec!([i32; 10], 1, 2, 3, 4); 485 /// tv.resize(2, 0); 486 /// assert_eq!(tv.as_slice(), &[1, 2][..]); 487 /// ``` 488 #[inline] resize(&mut self, new_len: usize, new_val: A::Item) where A::Item: Clone,489 pub fn resize(&mut self, new_len: usize, new_val: A::Item) 490 where 491 A::Item: Clone, 492 { 493 match self { 494 TinyVec::Inline(a) => { 495 if new_len > A::CAPACITY { 496 self.move_to_the_heap(); 497 self.resize(new_len, new_val); 498 } else { 499 a.resize(new_len, new_val); 500 } 501 } 502 TinyVec::Heap(v) => v.resize(new_len, new_val), 503 } 504 } 505 506 /// Resize the vec to the new length. 507 /// 508 /// If it needs to be longer, it's filled with repeated calls to the provided 509 /// function. If it needs to be shorter, it's truncated. 510 /// 511 /// ## Example 512 /// 513 /// ```rust 514 /// use tinyvec::*; 515 /// 516 /// let mut tv = tiny_vec!([i32; 10], 1, 2, 3); 517 /// tv.resize_with(5, Default::default); 518 /// assert_eq!(tv.as_slice(), &[1, 2, 3, 0, 0][..]); 519 /// 520 /// let mut tv = tiny_vec!([i32; 10]); 521 /// let mut p = 1; 522 /// tv.resize_with(4, || { 523 /// p *= 2; 524 /// p 525 /// }); 526 /// assert_eq!(tv.as_slice(), &[2, 4, 8, 16][..]); 527 /// ``` 528 #[inline] resize_with<F: FnMut() -> A::Item>(&mut self, new_len: usize, f: F)529 pub fn resize_with<F: FnMut() -> A::Item>(&mut self, new_len: usize, f: F) { 530 match self { 531 TinyVec::Inline(a) => a.resize_with(new_len, f), 532 TinyVec::Heap(v) => v.resize_with(new_len, f), 533 } 534 } 535 536 /// Walk the vec and keep only the elements that pass the predicate given. 537 /// 538 /// ## Example 539 /// 540 /// ```rust 541 /// use tinyvec::*; 542 /// 543 /// let mut tv = tiny_vec!([i32; 10], 1, 2, 3, 4); 544 /// tv.retain(|&x| x % 2 == 0); 545 /// assert_eq!(tv.as_slice(), &[2, 4][..]); 546 /// ``` 547 #[inline] retain<F: FnMut(&A::Item) -> bool>(&mut self, acceptable: F)548 pub fn retain<F: FnMut(&A::Item) -> bool>(&mut self, acceptable: F) { 549 match self { 550 TinyVec::Inline(a) => a.retain(acceptable), 551 TinyVec::Heap(v) => v.retain(acceptable), 552 } 553 } 554 555 /// Splits the collection at the point given. 556 /// 557 /// * `[0, at)` stays in this vec 558 /// * `[at, len)` ends up in the new vec. 559 /// 560 /// ## Panics 561 /// * if at > len 562 /// 563 /// ## Example 564 /// 565 /// ```rust 566 /// use tinyvec::*; 567 /// let mut tv = tiny_vec!([i32; 4], 1, 2, 3); 568 /// let tv2 = tv.split_off(1); 569 /// assert_eq!(tv.as_slice(), &[1][..]); 570 /// assert_eq!(tv2.as_slice(), &[2, 3][..]); 571 /// ``` 572 #[inline] split_off(&mut self, at: usize) -> Self where A: Default,573 pub fn split_off(&mut self, at: usize) -> Self 574 where 575 A: Default, 576 { 577 match self { 578 TinyVec::Inline(a) => TinyVec::Inline(a.split_off(at)), 579 TinyVec::Heap(v) => TinyVec::Heap(v.split_off(at)), 580 } 581 } 582 583 /// Remove an element, swapping the end of the vec into its place. 584 /// 585 /// ## Panics 586 /// * If the index is out of bounds. 587 /// 588 /// ## Example 589 /// ```rust 590 /// use tinyvec::*; 591 /// let mut tv = tiny_vec!([&str; 4], "foo", "bar", "quack", "zap"); 592 /// 593 /// assert_eq!(tv.swap_remove(1), "bar"); 594 /// assert_eq!(tv.as_slice(), &["foo", "zap", "quack"][..]); 595 /// 596 /// assert_eq!(tv.swap_remove(0), "foo"); 597 /// assert_eq!(tv.as_slice(), &["quack", "zap"][..]); 598 /// ``` 599 #[inline] swap_remove(&mut self, index: usize) -> A::Item600 pub fn swap_remove(&mut self, index: usize) -> A::Item { 601 match self { 602 TinyVec::Inline(a) => a.swap_remove(index), 603 TinyVec::Heap(v) => v.swap_remove(index), 604 } 605 } 606 607 /// Reduces the vec's length to the given value. 608 /// 609 /// If the vec is already shorter than the input, nothing happens. 610 #[inline] truncate(&mut self, new_len: usize)611 pub fn truncate(&mut self, new_len: usize) { 612 match self { 613 TinyVec::Inline(a) => a.truncate(new_len), 614 TinyVec::Heap(v) => v.truncate(new_len), 615 } 616 } 617 618 /// Wraps an array, using the given length as the starting length. 619 /// 620 /// If you want to use the whole length of the array, you can just use the 621 /// `From` impl. 622 /// 623 /// ## Failure 624 /// 625 /// If the given length is greater than the capacity of the array this will 626 /// error, and you'll get the array back in the `Err`. 627 #[inline] try_from_array_len(data: A, len: usize) -> Result<Self, A>628 pub fn try_from_array_len(data: A, len: usize) -> Result<Self, A> { 629 let arr = ArrayVec::try_from_array_len(data, len)?; 630 Ok(TinyVec::Inline(arr)) 631 } 632 } 633 634 /// Draining iterator for `TinyVecDrain` 635 /// 636 /// See [`TinyVecDrain::drain`](TinyVecDrain::<A>::drain) 637 pub struct TinyVecDrain<'p, A: Array> { 638 parent: &'p mut TinyVec<A>, 639 target_index: usize, 640 target_count: usize, 641 } 642 impl<'p, A: Array> FusedIterator for TinyVecDrain<'p, A> { } 643 impl<'p, A: Array> Iterator for TinyVecDrain<'p, A> { 644 type Item = A::Item; 645 #[inline] next(&mut self) -> Option<Self::Item>646 fn next(&mut self) -> Option<Self::Item> { 647 if self.target_count > 0 { 648 let out = self.parent.remove(self.target_index); 649 self.target_count -= 1; 650 Some(out) 651 } else { 652 None 653 } 654 } 655 } 656 impl<'p, A: Array> Drop for TinyVecDrain<'p, A> { 657 #[inline] drop(&mut self)658 fn drop(&mut self) { 659 for _ in self {} 660 } 661 } 662 663 impl<A: Array> AsMut<[A::Item]> for TinyVec<A> { 664 #[inline(always)] 665 #[must_use] as_mut(&mut self) -> &mut [A::Item]666 fn as_mut(&mut self) -> &mut [A::Item] { 667 &mut *self 668 } 669 } 670 671 impl<A: Array> AsRef<[A::Item]> for TinyVec<A> { 672 #[inline(always)] 673 #[must_use] as_ref(&self) -> &[A::Item]674 fn as_ref(&self) -> &[A::Item] { 675 &*self 676 } 677 } 678 679 impl<A: Array> Borrow<[A::Item]> for TinyVec<A> { 680 #[inline(always)] 681 #[must_use] borrow(&self) -> &[A::Item]682 fn borrow(&self) -> &[A::Item] { 683 &*self 684 } 685 } 686 687 impl<A: Array> BorrowMut<[A::Item]> for TinyVec<A> { 688 #[inline(always)] 689 #[must_use] borrow_mut(&mut self) -> &mut [A::Item]690 fn borrow_mut(&mut self) -> &mut [A::Item] { 691 &mut *self 692 } 693 } 694 695 impl<A: Array> Extend<A::Item> for TinyVec<A> { 696 #[inline] extend<T: IntoIterator<Item = A::Item>>(&mut self, iter: T)697 fn extend<T: IntoIterator<Item = A::Item>>(&mut self, iter: T) { 698 for t in iter { 699 self.push(t) 700 } 701 } 702 } 703 704 impl<A: Array> From<ArrayVec<A>> for TinyVec<A> { 705 #[inline(always)] 706 #[must_use] from(arr: ArrayVec<A>) -> Self707 fn from(arr: ArrayVec<A>) -> Self { 708 TinyVec::Inline(arr) 709 } 710 } 711 712 impl<A: Array> From<A> for TinyVec<A> { from(array: A) -> Self713 fn from(array: A) -> Self { 714 TinyVec::Inline(ArrayVec::from(array)) 715 } 716 } 717 718 impl<T, A> From<&'_ [T]> for TinyVec<A> 719 where 720 T: Clone + Default, 721 A: Array<Item = T> + Default, 722 { 723 #[inline] 724 #[must_use] from(slice: &[T]) -> Self725 fn from(slice: &[T]) -> Self { 726 if slice.len() > A::CAPACITY { 727 TinyVec::Heap(slice.into()) 728 } else { 729 let mut arr = ArrayVec::new(); 730 arr.extend_from_slice(slice); 731 732 TinyVec::Inline(arr) 733 } 734 } 735 } 736 737 impl<T, A> From<&'_ mut [T]> for TinyVec<A> 738 where 739 T: Clone + Default, 740 A: Array<Item = T> + Default, 741 { 742 #[inline] 743 #[must_use] from(slice: &mut [T]) -> Self744 fn from(slice: &mut [T]) -> Self { 745 Self::from(&*slice) 746 } 747 } 748 749 impl<A: Array + Default> FromIterator<A::Item> for TinyVec<A> { 750 #[inline] 751 #[must_use] from_iter<T: IntoIterator<Item = A::Item>>(iter: T) -> Self752 fn from_iter<T: IntoIterator<Item = A::Item>>(iter: T) -> Self { 753 let mut av = Self::default(); 754 for i in iter { 755 av.push(i) 756 } 757 av 758 } 759 } 760 761 /// Iterator for consuming an `TinyVec` and returning owned elements. 762 pub enum TinyVecIterator<A: Array> { 763 #[allow(missing_docs)] 764 Inline(ArrayVecIterator<A>), 765 #[allow(missing_docs)] 766 Heap(alloc::vec::IntoIter<A::Item>), 767 } 768 769 impl<A: Array> TinyVecIterator<A> { 770 /// Returns the remaining items of this iterator as a slice. 771 #[inline] 772 #[must_use] as_slice(&self) -> &[A::Item]773 pub fn as_slice(&self) -> &[A::Item] { 774 match self { 775 TinyVecIterator::Inline(a) => a.as_slice(), 776 TinyVecIterator::Heap(v) => v.as_slice(), 777 } 778 } 779 } 780 impl<A: Array> FusedIterator for TinyVecIterator<A> { } 781 impl<A: Array> Iterator for TinyVecIterator<A> { 782 type Item = A::Item; 783 #[inline] next(&mut self) -> Option<Self::Item>784 fn next(&mut self) -> Option<Self::Item> { 785 match self { 786 TinyVecIterator::Inline(a) => a.next(), 787 TinyVecIterator::Heap(v) => v.next(), 788 } 789 } 790 #[inline(always)] 791 #[must_use] size_hint(&self) -> (usize, Option<usize>)792 fn size_hint(&self) -> (usize, Option<usize>) { 793 match self { 794 TinyVecIterator::Inline(a) => a.size_hint(), 795 TinyVecIterator::Heap(v) => v.size_hint(), 796 } 797 } 798 #[inline(always)] count(self) -> usize799 fn count(self) -> usize { 800 match self { 801 TinyVecIterator::Inline(a) => a.count(), 802 TinyVecIterator::Heap(v) => v.count(), 803 } 804 } 805 #[inline] last(self) -> Option<Self::Item>806 fn last(self) -> Option<Self::Item> { 807 match self { 808 TinyVecIterator::Inline(a) => a.last(), 809 TinyVecIterator::Heap(v) => v.last(), 810 } 811 } 812 #[inline] nth(&mut self, n: usize) -> Option<A::Item>813 fn nth(&mut self, n: usize) -> Option<A::Item> { 814 match self { 815 TinyVecIterator::Inline(a) => a.nth(n), 816 TinyVecIterator::Heap(v) => v.nth(n), 817 } 818 } 819 } 820 821 impl<A: Array> Debug for TinyVecIterator<A> where A::Item: Debug { 822 #[allow(clippy::missing_inline_in_public_items)] fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result823 fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result { 824 f.debug_tuple("TinyVecIterator").field(&self.as_slice()).finish() 825 } 826 } 827 828 impl<A: Array> IntoIterator for TinyVec<A> { 829 type Item = A::Item; 830 type IntoIter = TinyVecIterator<A>; 831 #[inline(always)] 832 #[must_use] into_iter(self) -> Self::IntoIter833 fn into_iter(self) -> Self::IntoIter { 834 match self { 835 TinyVec::Inline(a) => TinyVecIterator::Inline(a.into_iter()), 836 TinyVec::Heap(v) => TinyVecIterator::Heap(v.into_iter()), 837 } 838 } 839 } 840 841 impl<'a, A: Array> IntoIterator for &'a mut TinyVec<A> { 842 type Item = &'a mut A::Item; 843 type IntoIter = alloc::slice::IterMut<'a, A::Item>; 844 #[inline(always)] 845 #[must_use] into_iter(self) -> Self::IntoIter846 fn into_iter(self) -> Self::IntoIter { 847 self.iter_mut() 848 } 849 } 850 851 impl<'a, A: Array> IntoIterator for &'a TinyVec<A> { 852 type Item = &'a A::Item; 853 type IntoIter = alloc::slice::Iter<'a, A::Item>; 854 #[inline(always)] 855 #[must_use] into_iter(self) -> Self::IntoIter856 fn into_iter(self) -> Self::IntoIter { 857 self.iter() 858 } 859 } 860 861 impl<A: Array> PartialEq for TinyVec<A> 862 where 863 A::Item: PartialEq, 864 { 865 #[inline] 866 #[must_use] eq(&self, other: &Self) -> bool867 fn eq(&self, other: &Self) -> bool { 868 self.as_slice().eq(other.as_slice()) 869 } 870 } 871 impl<A: Array> Eq for TinyVec<A> where A::Item: Eq {} 872 873 impl<A: Array> PartialOrd for TinyVec<A> 874 where 875 A::Item: PartialOrd, 876 { 877 #[inline] 878 #[must_use] partial_cmp(&self, other: &Self) -> Option<core::cmp::Ordering>879 fn partial_cmp(&self, other: &Self) -> Option<core::cmp::Ordering> { 880 self.as_slice().partial_cmp(other.as_slice()) 881 } 882 } 883 impl<A: Array> Ord for TinyVec<A> 884 where 885 A::Item: Ord, 886 { 887 #[inline] 888 #[must_use] cmp(&self, other: &Self) -> core::cmp::Ordering889 fn cmp(&self, other: &Self) -> core::cmp::Ordering { 890 self.as_slice().cmp(other.as_slice()) 891 } 892 } 893 894 impl<A: Array> PartialEq<&A> for TinyVec<A> 895 where 896 A::Item: PartialEq, 897 { 898 #[inline] 899 #[must_use] eq(&self, other: &&A) -> bool900 fn eq(&self, other: &&A) -> bool { 901 self.as_slice().eq(other.as_slice()) 902 } 903 } 904 905 impl<A: Array> PartialEq<&[A::Item]> for TinyVec<A> 906 where 907 A::Item: PartialEq, 908 { 909 #[inline] 910 #[must_use] eq(&self, other: &&[A::Item]) -> bool911 fn eq(&self, other: &&[A::Item]) -> bool { 912 self.as_slice().eq(*other) 913 } 914 } 915 916 impl<A: Array> Hash for TinyVec<A> 917 where 918 A::Item: Hash, 919 { 920 #[inline] hash<H: Hasher>(&self, state: &mut H)921 fn hash<H: Hasher>(&self, state: &mut H) { 922 self.as_slice().hash(state) 923 } 924 } 925 926 // // // // // // // // 927 // Formatting impls 928 // // // // // // // // 929 930 impl<A: Array> Binary for TinyVec<A> 931 where 932 A::Item: Binary, 933 { 934 #[allow(clippy::missing_inline_in_public_items)] fmt(&self, f: &mut Formatter) -> core::fmt::Result935 fn fmt(&self, f: &mut Formatter) -> core::fmt::Result { 936 write!(f, "[")?; 937 for (i, elem) in self.iter().enumerate() { 938 if i > 0 { 939 write!(f, ", ")?; 940 } 941 Binary::fmt(elem, f)?; 942 } 943 write!(f, "]") 944 } 945 } 946 947 impl<A: Array> Debug for TinyVec<A> 948 where 949 A::Item: Debug, 950 { 951 #[allow(clippy::missing_inline_in_public_items)] fmt(&self, f: &mut Formatter) -> core::fmt::Result952 fn fmt(&self, f: &mut Formatter) -> core::fmt::Result { 953 write!(f, "[")?; 954 for (i, elem) in self.iter().enumerate() { 955 if i > 0 { 956 write!(f, ", ")?; 957 } 958 Debug::fmt(elem, f)?; 959 } 960 write!(f, "]") 961 } 962 } 963 964 impl<A: Array> Display for TinyVec<A> 965 where 966 A::Item: Display, 967 { 968 #[allow(clippy::missing_inline_in_public_items)] fmt(&self, f: &mut Formatter) -> core::fmt::Result969 fn fmt(&self, f: &mut Formatter) -> core::fmt::Result { 970 write!(f, "[")?; 971 for (i, elem) in self.iter().enumerate() { 972 if i > 0 { 973 write!(f, ", ")?; 974 } 975 Display::fmt(elem, f)?; 976 } 977 write!(f, "]") 978 } 979 } 980 981 impl<A: Array> LowerExp for TinyVec<A> 982 where 983 A::Item: LowerExp, 984 { 985 #[allow(clippy::missing_inline_in_public_items)] fmt(&self, f: &mut Formatter) -> core::fmt::Result986 fn fmt(&self, f: &mut Formatter) -> core::fmt::Result { 987 write!(f, "[")?; 988 for (i, elem) in self.iter().enumerate() { 989 if i > 0 { 990 write!(f, ", ")?; 991 } 992 LowerExp::fmt(elem, f)?; 993 } 994 write!(f, "]") 995 } 996 } 997 998 impl<A: Array> LowerHex for TinyVec<A> 999 where 1000 A::Item: LowerHex, 1001 { 1002 #[allow(clippy::missing_inline_in_public_items)] fmt(&self, f: &mut Formatter) -> core::fmt::Result1003 fn fmt(&self, f: &mut Formatter) -> core::fmt::Result { 1004 write!(f, "[")?; 1005 for (i, elem) in self.iter().enumerate() { 1006 if i > 0 { 1007 write!(f, ", ")?; 1008 } 1009 LowerHex::fmt(elem, f)?; 1010 } 1011 write!(f, "]") 1012 } 1013 } 1014 1015 impl<A: Array> Octal for TinyVec<A> 1016 where 1017 A::Item: Octal, 1018 { 1019 #[allow(clippy::missing_inline_in_public_items)] fmt(&self, f: &mut Formatter) -> core::fmt::Result1020 fn fmt(&self, f: &mut Formatter) -> core::fmt::Result { 1021 write!(f, "[")?; 1022 for (i, elem) in self.iter().enumerate() { 1023 if i > 0 { 1024 write!(f, ", ")?; 1025 } 1026 Octal::fmt(elem, f)?; 1027 } 1028 write!(f, "]") 1029 } 1030 } 1031 1032 impl<A: Array> Pointer for TinyVec<A> 1033 where 1034 A::Item: Pointer, 1035 { 1036 #[allow(clippy::missing_inline_in_public_items)] fmt(&self, f: &mut Formatter) -> core::fmt::Result1037 fn fmt(&self, f: &mut Formatter) -> core::fmt::Result { 1038 write!(f, "[")?; 1039 for (i, elem) in self.iter().enumerate() { 1040 if i > 0 { 1041 write!(f, ", ")?; 1042 } 1043 Pointer::fmt(elem, f)?; 1044 } 1045 write!(f, "]") 1046 } 1047 } 1048 1049 impl<A: Array> UpperExp for TinyVec<A> 1050 where 1051 A::Item: UpperExp, 1052 { 1053 #[allow(clippy::missing_inline_in_public_items)] fmt(&self, f: &mut Formatter) -> core::fmt::Result1054 fn fmt(&self, f: &mut Formatter) -> core::fmt::Result { 1055 write!(f, "[")?; 1056 for (i, elem) in self.iter().enumerate() { 1057 if i > 0 { 1058 write!(f, ", ")?; 1059 } 1060 UpperExp::fmt(elem, f)?; 1061 } 1062 write!(f, "]") 1063 } 1064 } 1065 1066 impl<A: Array> UpperHex for TinyVec<A> 1067 where 1068 A::Item: UpperHex, 1069 { 1070 #[allow(clippy::missing_inline_in_public_items)] fmt(&self, f: &mut Formatter) -> core::fmt::Result1071 fn fmt(&self, f: &mut Formatter) -> core::fmt::Result { 1072 write!(f, "[")?; 1073 for (i, elem) in self.iter().enumerate() { 1074 if i > 0 { 1075 write!(f, ", ")?; 1076 } 1077 UpperHex::fmt(elem, f)?; 1078 } 1079 write!(f, "]") 1080 } 1081 } 1082