1 #![cfg(feature = "alloc")] 2 3 use super::*; 4 5 use alloc::vec::{self, Vec}; 6 use tinyvec_macros::impl_mirrored; 7 8 #[cfg(feature = "serde")] 9 use core::marker::PhantomData; 10 #[cfg(feature = "serde")] 11 use serde::de::{Deserialize, Deserializer, SeqAccess, Visitor}; 12 #[cfg(feature = "serde")] 13 use serde::ser::{Serialize, SerializeSeq, Serializer}; 14 15 /// Helper to make a `TinyVec`. 16 /// 17 /// You specify the backing array type, and optionally give all the elements you 18 /// want to initially place into the array. 19 /// 20 /// ```rust 21 /// use tinyvec::*; 22 /// 23 /// // The backing array type can be specified in the macro call 24 /// let empty_tv = tiny_vec!([u8; 16]); 25 /// let some_ints = tiny_vec!([i32; 4] => 1, 2, 3); 26 /// let many_ints = tiny_vec!([i32; 4] => 1, 2, 3, 4, 5, 6, 7, 8, 9, 10); 27 /// 28 /// // Or left to inference 29 /// let empty_tv: TinyVec<[u8; 16]> = tiny_vec!(); 30 /// let some_ints: TinyVec<[i32; 4]> = tiny_vec!(1, 2, 3); 31 /// let many_ints: TinyVec<[i32; 4]> = tiny_vec!(1, 2, 3, 4, 5, 6, 7, 8, 9, 10); 32 /// ``` 33 #[macro_export] 34 #[cfg_attr(docs_rs, doc(cfg(feature = "alloc")))] 35 macro_rules! tiny_vec { 36 ($array_type:ty => $($elem:expr),* $(,)?) => { 37 { 38 // https://github.com/rust-lang/lang-team/issues/28 39 const INVOKED_ELEM_COUNT: usize = 0 $( + { let _ = stringify!($elem); 1 })*; 40 // If we have more `$elem` than the `CAPACITY` we will simply go directly 41 // to constructing on the heap. 42 match $crate::TinyVec::constructor_for_capacity(INVOKED_ELEM_COUNT) { 43 $crate::TinyVecConstructor::Inline(f) => { 44 f($crate::array_vec!($array_type => $($elem),*)) 45 } 46 $crate::TinyVecConstructor::Heap(f) => { 47 f(vec!($($elem),*)) 48 } 49 } 50 } 51 }; 52 ($array_type:ty) => { 53 $crate::TinyVec::<$array_type>::default() 54 }; 55 ($($elem:expr),*) => { 56 $crate::tiny_vec!(_ => $($elem),*) 57 }; 58 ($elem:expr; $n:expr) => { 59 $crate::TinyVec::from([$elem; $n]) 60 }; 61 () => { 62 $crate::tiny_vec!(_) 63 }; 64 } 65 66 #[doc(hidden)] // Internal implementation details of `tiny_vec!` 67 pub enum TinyVecConstructor<A: Array> { 68 Inline(fn(ArrayVec<A>) -> TinyVec<A>), 69 Heap(fn(Vec<A::Item>) -> TinyVec<A>), 70 } 71 72 /// A vector that starts inline, but can automatically move to the heap. 73 /// 74 /// * Requires the `alloc` feature 75 /// 76 /// A `TinyVec` is either an Inline([`ArrayVec`](crate::ArrayVec::<A>)) or 77 /// Heap([`Vec`](https://doc.rust-lang.org/alloc/vec/struct.Vec.html)). The 78 /// interface for the type as a whole is a bunch of methods that just match on 79 /// the enum variant and then call the same method on the inner vec. 80 /// 81 /// ## Construction 82 /// 83 /// Because it's an enum, you can construct a `TinyVec` simply by making an 84 /// `ArrayVec` or `Vec` and then putting it into the enum. 85 /// 86 /// There is also a macro 87 /// 88 /// ```rust 89 /// # use tinyvec::*; 90 /// let empty_tv = tiny_vec!([u8; 16]); 91 /// let some_ints = tiny_vec!([i32; 4] => 1, 2, 3); 92 /// ``` 93 #[derive(Clone)] 94 #[cfg_attr(docs_rs, doc(cfg(feature = "alloc")))] 95 pub enum TinyVec<A: Array> { 96 #[allow(missing_docs)] 97 Inline(ArrayVec<A>), 98 #[allow(missing_docs)] 99 Heap(Vec<A::Item>), 100 } 101 102 impl<A: Array> Default for TinyVec<A> { 103 #[inline] 104 #[must_use] default() -> Self105 fn default() -> Self { 106 TinyVec::Inline(ArrayVec::default()) 107 } 108 } 109 110 impl<A: Array> Deref for TinyVec<A> { 111 type Target = [A::Item]; 112 113 impl_mirrored! { 114 type Mirror = TinyVec; 115 #[inline(always)] 116 #[must_use] 117 fn deref(self: &Self) -> &Self::Target; 118 } 119 } 120 121 impl<A: Array> DerefMut for TinyVec<A> { 122 impl_mirrored! { 123 type Mirror = TinyVec; 124 #[inline(always)] 125 #[must_use] 126 fn deref_mut(self: &mut Self) -> &mut Self::Target; 127 } 128 } 129 130 impl<A: Array, I: SliceIndex<[A::Item]>> Index<I> for TinyVec<A> { 131 type Output = <I as SliceIndex<[A::Item]>>::Output; 132 #[inline(always)] 133 #[must_use] index(&self, index: I) -> &Self::Output134 fn index(&self, index: I) -> &Self::Output { 135 &self.deref()[index] 136 } 137 } 138 139 impl<A: Array, I: SliceIndex<[A::Item]>> IndexMut<I> for TinyVec<A> { 140 #[inline(always)] 141 #[must_use] index_mut(&mut self, index: I) -> &mut Self::Output142 fn index_mut(&mut self, index: I) -> &mut Self::Output { 143 &mut self.deref_mut()[index] 144 } 145 } 146 147 #[cfg(feature = "serde")] 148 #[cfg_attr(docs_rs, doc(cfg(feature = "serde")))] 149 impl<A: Array> Serialize for TinyVec<A> 150 where 151 A::Item: Serialize, 152 { 153 #[must_use] serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: Serializer,154 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> 155 where 156 S: Serializer, 157 { 158 let mut seq = serializer.serialize_seq(Some(self.len()))?; 159 for element in self.iter() { 160 seq.serialize_element(element)?; 161 } 162 seq.end() 163 } 164 } 165 166 #[cfg(feature = "serde")] 167 #[cfg_attr(docs_rs, doc(cfg(feature = "serde")))] 168 impl<'de, A: Array> Deserialize<'de> for TinyVec<A> 169 where 170 A::Item: Deserialize<'de>, 171 { deserialize<D>(deserializer: D) -> Result<Self, D::Error> where D: Deserializer<'de>,172 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> 173 where 174 D: Deserializer<'de>, 175 { 176 deserializer.deserialize_seq(TinyVecVisitor(PhantomData)) 177 } 178 } 179 180 impl<A: Array> TinyVec<A> { 181 /// Returns whether elements are on heap 182 #[inline(always)] 183 #[must_use] is_heap(&self) -> bool184 pub fn is_heap(&self) -> bool { 185 match self { 186 TinyVec::Heap(_) => true, 187 TinyVec::Inline(_) => false, 188 } 189 } 190 /// Returns whether elements are on stack 191 #[inline(always)] 192 #[must_use] is_inline(&self) -> bool193 pub fn is_inline(&self) -> bool { 194 !self.is_heap() 195 } 196 197 /// Shrinks the capacity of the vector as much as possible.\ 198 /// It is inlined if length is less than `A::CAPACITY`. 199 /// ```rust 200 /// use tinyvec::*; 201 /// let mut tv = tiny_vec!([i32; 2] => 1, 2, 3); 202 /// assert!(tv.is_heap()); 203 /// let _ = tv.pop(); 204 /// assert!(tv.is_heap()); 205 /// tv.shrink_to_fit(); 206 /// assert!(tv.is_inline()); 207 /// ``` shrink_to_fit(&mut self)208 pub fn shrink_to_fit(&mut self) { 209 let vec = match self { 210 TinyVec::Inline(_) => return, 211 TinyVec::Heap(h) => h, 212 }; 213 214 if vec.len() > A::CAPACITY { 215 return vec.shrink_to_fit(); 216 } 217 218 let moved_vec = core::mem::replace(vec, Vec::new()); 219 220 let mut av = ArrayVec::default(); 221 let mut rest = av.fill(moved_vec); 222 debug_assert!(rest.next().is_none()); 223 *self = TinyVec::Inline(av); 224 } 225 226 /// Moves the content of the TinyVec to the heap, if it's inline. 227 /// ```rust 228 /// use tinyvec::*; 229 /// let mut tv = tiny_vec!([i32; 4] => 1, 2, 3); 230 /// assert!(tv.is_inline()); 231 /// tv.move_to_the_heap(); 232 /// assert!(tv.is_heap()); 233 /// ``` 234 #[allow(clippy::missing_inline_in_public_items)] move_to_the_heap(&mut self)235 pub fn move_to_the_heap(&mut self) { 236 let arr = match self { 237 TinyVec::Heap(_) => return, 238 TinyVec::Inline(a) => a, 239 }; 240 241 let v = arr.drain_to_vec(); 242 *self = TinyVec::Heap(v); 243 } 244 245 /// If TinyVec is inline, moves the content of it to the heap. 246 /// Also reserves additional space. 247 /// ```rust 248 /// use tinyvec::*; 249 /// let mut tv = tiny_vec!([i32; 4] => 1, 2, 3); 250 /// assert!(tv.is_inline()); 251 /// tv.move_to_the_heap_and_reserve(32); 252 /// assert!(tv.is_heap()); 253 /// assert!(tv.capacity() >= 35); 254 /// ``` move_to_the_heap_and_reserve(&mut self, n: usize)255 pub fn move_to_the_heap_and_reserve(&mut self, n: usize) { 256 let arr = match self { 257 TinyVec::Heap(h) => return h.reserve(n), 258 TinyVec::Inline(a) => a, 259 }; 260 261 let v = arr.drain_to_vec_and_reserve(n); 262 *self = TinyVec::Heap(v); 263 } 264 265 /// Reserves additional space. 266 /// Moves to the heap if array can't hold `n` more items 267 /// ```rust 268 /// use tinyvec::*; 269 /// let mut tv = tiny_vec!([i32; 4] => 1, 2, 3, 4); 270 /// assert!(tv.is_inline()); 271 /// tv.reserve(1); 272 /// assert!(tv.is_heap()); 273 /// assert!(tv.capacity() >= 5); 274 /// ``` reserve(&mut self, n: usize)275 pub fn reserve(&mut self, n: usize) { 276 let arr = match self { 277 TinyVec::Heap(h) => return h.reserve(n), 278 TinyVec::Inline(a) => a, 279 }; 280 281 if n > arr.capacity() - arr.len() { 282 let v = arr.drain_to_vec_and_reserve(n); 283 *self = TinyVec::Heap(v); 284 } 285 286 /* In this place array has enough place, so no work is needed more */ 287 return; 288 } 289 290 /// Reserves additional space. 291 /// Moves to the heap if array can't hold `n` more items 292 /// 293 /// From [Vec::reserve_exact](https://doc.rust-lang.org/std/vec/struct.Vec.html#method.reserve_exact) 294 /// ```text 295 /// Note that the allocator may give the collection more space than it requests. 296 /// Therefore, capacity can not be relied upon to be precisely minimal. 297 /// Prefer `reserve` if future insertions are expected. 298 /// ``` 299 /// ```rust 300 /// use tinyvec::*; 301 /// let mut tv = tiny_vec!([i32; 4] => 1, 2, 3, 4); 302 /// assert!(tv.is_inline()); 303 /// tv.reserve_exact(1); 304 /// assert!(tv.is_heap()); 305 /// assert!(tv.capacity() >= 5); 306 /// ``` reserve_exact(&mut self, n: usize)307 pub fn reserve_exact(&mut self, n: usize) { 308 let arr = match self { 309 TinyVec::Heap(h) => return h.reserve_exact(n), 310 TinyVec::Inline(a) => a, 311 }; 312 313 if n > arr.capacity() - arr.len() { 314 let v = arr.drain_to_vec_and_reserve(n); 315 *self = TinyVec::Heap(v); 316 } 317 318 /* In this place array has enough place, so no work is needed more */ 319 return; 320 } 321 322 /// Makes a new TinyVec with _at least_ the given capacity. 323 /// 324 /// If the requested capacity is less than or equal to the array capacity you 325 /// get an inline vec. If it's greater than you get a heap vec. 326 /// ``` 327 /// # use tinyvec::*; 328 /// let t = TinyVec::<[u8; 10]>::with_capacity(5); 329 /// assert!(t.is_inline()); 330 /// assert!(t.capacity() >= 5); 331 /// 332 /// let t = TinyVec::<[u8; 10]>::with_capacity(20); 333 /// assert!(t.is_heap()); 334 /// assert!(t.capacity() >= 20); 335 /// ``` 336 #[inline] 337 #[must_use] with_capacity(cap: usize) -> Self338 pub fn with_capacity(cap: usize) -> Self { 339 if cap <= A::CAPACITY { 340 TinyVec::Inline(ArrayVec::default()) 341 } else { 342 TinyVec::Heap(Vec::with_capacity(cap)) 343 } 344 } 345 } 346 347 impl<A: Array> TinyVec<A> { 348 /// Move all values from `other` into this vec. 349 #[cfg(feature = "rustc_1_40")] 350 #[inline] append(&mut self, other: &mut Self)351 pub fn append(&mut self, other: &mut Self) { 352 self.reserve(other.len()); 353 354 /* Doing append should be faster, because it is effectively a memcpy */ 355 match (self, other) { 356 (TinyVec::Heap(sh), TinyVec::Heap(oh)) => sh.append(oh), 357 (TinyVec::Inline(a), TinyVec::Heap(h)) => a.extend(h.drain(..)), 358 (ref mut this, TinyVec::Inline(arr)) => this.extend(arr.drain(..)), 359 } 360 } 361 362 /// Move all values from `other` into this vec. 363 #[cfg(not(feature = "rustc_1_40"))] 364 #[inline] append(&mut self, other: &mut Self)365 pub fn append(&mut self, other: &mut Self) { 366 match other { 367 TinyVec::Inline(a) => self.extend(a.drain(..)), 368 TinyVec::Heap(h) => self.extend(h.drain(..)), 369 } 370 } 371 372 impl_mirrored! { 373 type Mirror = TinyVec; 374 375 /// Remove an element, swapping the end of the vec into its place. 376 /// 377 /// ## Panics 378 /// * If the index is out of bounds. 379 /// 380 /// ## Example 381 /// ```rust 382 /// use tinyvec::*; 383 /// let mut tv = tiny_vec!([&str; 4] => "foo", "bar", "quack", "zap"); 384 /// 385 /// assert_eq!(tv.swap_remove(1), "bar"); 386 /// assert_eq!(tv.as_slice(), &["foo", "zap", "quack"][..]); 387 /// 388 /// assert_eq!(tv.swap_remove(0), "foo"); 389 /// assert_eq!(tv.as_slice(), &["quack", "zap"][..]); 390 /// ``` 391 #[inline] 392 pub fn swap_remove(self: &mut Self, index: usize) -> A::Item; 393 394 /// Remove and return the last element of the vec, if there is one. 395 /// 396 /// ## Failure 397 /// * If the vec is empty you get `None`. 398 #[inline] 399 pub fn pop(self: &mut Self) -> Option<A::Item>; 400 401 /// Removes the item at `index`, shifting all others down by one index. 402 /// 403 /// Returns the removed element. 404 /// 405 /// ## Panics 406 /// 407 /// If the index is out of bounds. 408 /// 409 /// ## Example 410 /// 411 /// ```rust 412 /// use tinyvec::*; 413 /// let mut tv = tiny_vec!([i32; 4] => 1, 2, 3); 414 /// assert_eq!(tv.remove(1), 2); 415 /// assert_eq!(tv.as_slice(), &[1, 3][..]); 416 /// ``` 417 #[inline] 418 pub fn remove(self: &mut Self, index: usize) -> A::Item; 419 420 /// The length of the vec (in elements). 421 #[inline(always)] 422 #[must_use] 423 pub fn len(self: &Self) -> usize; 424 425 /// The capacity of the `TinyVec`. 426 /// 427 /// When not heap allocated this is fixed based on the array type. 428 /// Otherwise its the result of the underlying Vec::capacity. 429 #[inline(always)] 430 #[must_use] 431 pub fn capacity(self: &Self) -> usize; 432 433 /// Reduces the vec's length to the given value. 434 /// 435 /// If the vec is already shorter than the input, nothing happens. 436 #[inline] 437 pub fn truncate(self: &mut Self, new_len: usize); 438 439 /// A mutable pointer to the backing array. 440 /// 441 /// ## Safety 442 /// 443 /// This pointer has provenance over the _entire_ backing array/buffer. 444 #[inline(always)] 445 #[must_use] 446 pub fn as_mut_ptr(self: &mut Self) -> *mut A::Item; 447 448 /// A const pointer to the backing array. 449 /// 450 /// ## Safety 451 /// 452 /// This pointer has provenance over the _entire_ backing array/buffer. 453 #[inline(always)] 454 #[must_use] 455 pub fn as_ptr(self: &Self) -> *const A::Item; 456 } 457 458 /// Walk the vec and keep only the elements that pass the predicate given. 459 /// 460 /// ## Example 461 /// 462 /// ```rust 463 /// use tinyvec::*; 464 /// 465 /// let mut tv = tiny_vec!([i32; 10] => 1, 2, 3, 4); 466 /// tv.retain(|&x| x % 2 == 0); 467 /// assert_eq!(tv.as_slice(), &[2, 4][..]); 468 /// ``` 469 #[inline] retain<F: FnMut(&A::Item) -> bool>(self: &mut Self, acceptable: F)470 pub fn retain<F: FnMut(&A::Item) -> bool>(self: &mut Self, acceptable: F) { 471 match self { 472 TinyVec::Inline(i) => i.retain(acceptable), 473 TinyVec::Heap(h) => h.retain(acceptable), 474 } 475 } 476 477 /// Helper for getting the mut slice. 478 #[inline(always)] 479 #[must_use] as_mut_slice(self: &mut Self) -> &mut [A::Item]480 pub fn as_mut_slice(self: &mut Self) -> &mut [A::Item] { 481 self.deref_mut() 482 } 483 484 /// Helper for getting the shared slice. 485 #[inline(always)] 486 #[must_use] as_slice(self: &Self) -> &[A::Item]487 pub fn as_slice(self: &Self) -> &[A::Item] { 488 self.deref() 489 } 490 491 /// Removes all elements from the vec. 492 #[inline(always)] clear(&mut self)493 pub fn clear(&mut self) { 494 self.truncate(0) 495 } 496 497 /// De-duplicates the vec. 498 #[cfg(feature = "nightly_slice_partition_dedup")] 499 #[inline(always)] dedup(&mut self) where A::Item: PartialEq,500 pub fn dedup(&mut self) 501 where 502 A::Item: PartialEq, 503 { 504 self.dedup_by(|a, b| a == b) 505 } 506 507 /// De-duplicates the vec according to the predicate given. 508 #[cfg(feature = "nightly_slice_partition_dedup")] 509 #[inline(always)] dedup_by<F>(&mut self, same_bucket: F) where F: FnMut(&mut A::Item, &mut A::Item) -> bool,510 pub fn dedup_by<F>(&mut self, same_bucket: F) 511 where 512 F: FnMut(&mut A::Item, &mut A::Item) -> bool, 513 { 514 let len = { 515 let (dedup, _) = self.as_mut_slice().partition_dedup_by(same_bucket); 516 dedup.len() 517 }; 518 self.truncate(len); 519 } 520 521 /// De-duplicates the vec according to the key selector given. 522 #[cfg(feature = "nightly_slice_partition_dedup")] 523 #[inline(always)] dedup_by_key<F, K>(&mut self, mut key: F) where F: FnMut(&mut A::Item) -> K, K: PartialEq,524 pub fn dedup_by_key<F, K>(&mut self, mut key: F) 525 where 526 F: FnMut(&mut A::Item) -> K, 527 K: PartialEq, 528 { 529 self.dedup_by(|a, b| key(a) == key(b)) 530 } 531 532 /// Creates a draining iterator that removes the specified range in the vector 533 /// and yields the removed items. 534 /// 535 /// **Note: This method has significant performance issues compared to 536 /// matching on the TinyVec and then calling drain on the Inline or Heap value 537 /// inside. The draining iterator has to branch on every single access. It is 538 /// provided for simplicity and compatability only.** 539 /// 540 /// ## Panics 541 /// * If the start is greater than the end 542 /// * If the end is past the edge of the vec. 543 /// 544 /// ## Example 545 /// ```rust 546 /// use tinyvec::*; 547 /// let mut tv = tiny_vec!([i32; 4] => 1, 2, 3); 548 /// let tv2: TinyVec<[i32; 4]> = tv.drain(1..).collect(); 549 /// assert_eq!(tv.as_slice(), &[1][..]); 550 /// assert_eq!(tv2.as_slice(), &[2, 3][..]); 551 /// 552 /// tv.drain(..); 553 /// assert_eq!(tv.as_slice(), &[]); 554 /// ``` 555 #[inline] drain<R: RangeBounds<usize>>( &mut self, range: R, ) -> TinyVecDrain<'_, A>556 pub fn drain<R: RangeBounds<usize>>( 557 &mut self, range: R, 558 ) -> TinyVecDrain<'_, A> { 559 match self { 560 TinyVec::Inline(i) => TinyVecDrain::Inline(i.drain(range)), 561 TinyVec::Heap(h) => TinyVecDrain::Heap(h.drain(range)), 562 } 563 } 564 565 /// Clone each element of the slice into this vec. 566 /// ```rust 567 /// use tinyvec::*; 568 /// let mut tv = tiny_vec!([i32; 4] => 1, 2); 569 /// tv.extend_from_slice(&[3, 4]); 570 /// assert_eq!(tv.as_slice(), [1, 2, 3, 4]); 571 /// ``` 572 #[inline] extend_from_slice(&mut self, sli: &[A::Item]) where A::Item: Clone,573 pub fn extend_from_slice(&mut self, sli: &[A::Item]) 574 where 575 A::Item: Clone, 576 { 577 self.reserve(sli.len()); 578 match self { 579 TinyVec::Inline(a) => a.extend_from_slice(sli), 580 TinyVec::Heap(h) => h.extend_from_slice(sli), 581 } 582 } 583 584 /// Wraps up an array and uses the given length as the initial length. 585 /// 586 /// Note that the `From` impl for arrays assumes the full length is used. 587 /// 588 /// ## Panics 589 /// 590 /// The length must be less than or equal to the capacity of the array. 591 #[inline] 592 #[must_use] 593 #[allow(clippy::match_wild_err_arm)] from_array_len(data: A, len: usize) -> Self594 pub fn from_array_len(data: A, len: usize) -> Self { 595 match Self::try_from_array_len(data, len) { 596 Ok(out) => out, 597 Err(_) => { 598 panic!("TinyVec: length {} exceeds capacity {}!", len, A::CAPACITY) 599 } 600 } 601 } 602 603 /// This is an internal implementation detail of the `tiny_vec!` macro, and 604 /// using it other than from that macro is not supported by this crate's 605 /// SemVer guarantee. 606 #[inline(always)] 607 #[doc(hidden)] constructor_for_capacity(cap: usize) -> TinyVecConstructor<A>608 pub fn constructor_for_capacity(cap: usize) -> TinyVecConstructor<A> { 609 if cap <= A::CAPACITY { 610 TinyVecConstructor::Inline(TinyVec::Inline) 611 } else { 612 TinyVecConstructor::Heap(TinyVec::Heap) 613 } 614 } 615 616 /// Inserts an item at the position given, moving all following elements +1 617 /// index. 618 /// 619 /// ## Panics 620 /// * If `index` > `len` 621 /// 622 /// ## Example 623 /// ```rust 624 /// use tinyvec::*; 625 /// let mut tv = tiny_vec!([i32; 10] => 1, 2, 3); 626 /// tv.insert(1, 4); 627 /// assert_eq!(tv.as_slice(), &[1, 4, 2, 3]); 628 /// tv.insert(4, 5); 629 /// assert_eq!(tv.as_slice(), &[1, 4, 2, 3, 5]); 630 /// ``` 631 #[inline] insert(&mut self, index: usize, item: A::Item)632 pub fn insert(&mut self, index: usize, item: A::Item) { 633 assert!( 634 index <= self.len(), 635 "insertion index (is {}) should be <= len (is {})", 636 index, 637 self.len() 638 ); 639 640 let arr = match self { 641 TinyVec::Heap(v) => return v.insert(index, item), 642 TinyVec::Inline(a) => a, 643 }; 644 645 if let Some(x) = arr.try_insert(index, item) { 646 let mut v = Vec::with_capacity(arr.len() * 2); 647 let mut it = 648 arr.iter_mut().map(|r| core::mem::replace(r, Default::default())); 649 v.extend(it.by_ref().take(index)); 650 v.push(x); 651 v.extend(it); 652 *self = TinyVec::Heap(v); 653 } 654 } 655 656 /// If the vec is empty. 657 #[inline(always)] 658 #[must_use] is_empty(&self) -> bool659 pub fn is_empty(&self) -> bool { 660 self.len() == 0 661 } 662 663 /// Makes a new, empty vec. 664 #[inline(always)] 665 #[must_use] new() -> Self666 pub fn new() -> Self { 667 Self::default() 668 } 669 670 /// Place an element onto the end of the vec. 671 /// ## Panics 672 /// * If the length of the vec would overflow the capacity. 673 /// ```rust 674 /// use tinyvec::*; 675 /// let mut tv = tiny_vec!([i32; 10] => 1, 2, 3); 676 /// tv.push(4); 677 /// assert_eq!(tv.as_slice(), &[1, 2, 3, 4]); 678 /// ``` 679 #[inline] push(&mut self, val: A::Item)680 pub fn push(&mut self, val: A::Item) { 681 // The code path for moving the inline contents to the heap produces a lot 682 // of instructions, but we have a strong guarantee that this is a cold 683 // path. LLVM doesn't know this, inlines it, and this tends to cause a 684 // cascade of other bad inlining decisions because the body of push looks 685 // huge even though nearly every call executes the same few instructions. 686 // 687 // Moving the logic out of line with #[cold] causes the hot code to be 688 // inlined together, and we take the extra cost of a function call only 689 // in rare cases. 690 #[cold] 691 fn drain_to_heap_and_push<A: Array>( 692 arr: &mut ArrayVec<A>, val: A::Item, 693 ) -> TinyVec<A> { 694 /* Make the Vec twice the size to amortize the cost of draining */ 695 let mut v = arr.drain_to_vec_and_reserve(arr.len()); 696 v.push(val); 697 TinyVec::Heap(v) 698 } 699 700 match self { 701 TinyVec::Heap(v) => v.push(val), 702 TinyVec::Inline(arr) => { 703 if let Some(x) = arr.try_push(val) { 704 *self = drain_to_heap_and_push(arr, x); 705 } 706 } 707 } 708 } 709 710 /// Resize the vec to the new length. 711 /// 712 /// If it needs to be longer, it's filled with clones of the provided value. 713 /// If it needs to be shorter, it's truncated. 714 /// 715 /// ## Example 716 /// 717 /// ```rust 718 /// use tinyvec::*; 719 /// 720 /// let mut tv = tiny_vec!([&str; 10] => "hello"); 721 /// tv.resize(3, "world"); 722 /// assert_eq!(tv.as_slice(), &["hello", "world", "world"][..]); 723 /// 724 /// let mut tv = tiny_vec!([i32; 10] => 1, 2, 3, 4); 725 /// tv.resize(2, 0); 726 /// assert_eq!(tv.as_slice(), &[1, 2][..]); 727 /// ``` 728 #[inline] resize(&mut self, new_len: usize, new_val: A::Item) where A::Item: Clone,729 pub fn resize(&mut self, new_len: usize, new_val: A::Item) 730 where 731 A::Item: Clone, 732 { 733 self.resize_with(new_len, || new_val.clone()); 734 } 735 736 /// Resize the vec to the new length. 737 /// 738 /// If it needs to be longer, it's filled with repeated calls to the provided 739 /// function. If it needs to be shorter, it's truncated. 740 /// 741 /// ## Example 742 /// 743 /// ```rust 744 /// use tinyvec::*; 745 /// 746 /// let mut tv = tiny_vec!([i32; 3] => 1, 2, 3); 747 /// tv.resize_with(5, Default::default); 748 /// assert_eq!(tv.as_slice(), &[1, 2, 3, 0, 0][..]); 749 /// 750 /// let mut tv = tiny_vec!([i32; 2]); 751 /// let mut p = 1; 752 /// tv.resize_with(4, || { 753 /// p *= 2; 754 /// p 755 /// }); 756 /// assert_eq!(tv.as_slice(), &[2, 4, 8, 16][..]); 757 /// ``` 758 #[inline] resize_with<F: FnMut() -> A::Item>(&mut self, new_len: usize, f: F)759 pub fn resize_with<F: FnMut() -> A::Item>(&mut self, new_len: usize, f: F) { 760 match new_len.checked_sub(self.len()) { 761 None => return self.truncate(new_len), 762 Some(n) => self.reserve(n), 763 } 764 765 match self { 766 TinyVec::Inline(a) => a.resize_with(new_len, f), 767 TinyVec::Heap(v) => v.resize_with(new_len, f), 768 } 769 } 770 771 /// Splits the collection at the point given. 772 /// 773 /// * `[0, at)` stays in this vec 774 /// * `[at, len)` ends up in the new vec. 775 /// 776 /// ## Panics 777 /// * if at > len 778 /// 779 /// ## Example 780 /// 781 /// ```rust 782 /// use tinyvec::*; 783 /// let mut tv = tiny_vec!([i32; 4] => 1, 2, 3); 784 /// let tv2 = tv.split_off(1); 785 /// assert_eq!(tv.as_slice(), &[1][..]); 786 /// assert_eq!(tv2.as_slice(), &[2, 3][..]); 787 /// ``` 788 #[inline] split_off(&mut self, at: usize) -> Self789 pub fn split_off(&mut self, at: usize) -> Self { 790 match self { 791 TinyVec::Inline(a) => TinyVec::Inline(a.split_off(at)), 792 TinyVec::Heap(v) => TinyVec::Heap(v.split_off(at)), 793 } 794 } 795 796 /// Creates a splicing iterator that removes the specified range in the 797 /// vector, yields the removed items, and replaces them with elements from 798 /// the provided iterator. 799 /// 800 /// `splice` fuses the provided iterator, so elements after the first `None` 801 /// are ignored. 802 /// 803 /// ## Panics 804 /// * If the start is greater than the end. 805 /// * If the end is past the edge of the vec. 806 /// * If the provided iterator panics. 807 /// 808 /// ## Example 809 /// ```rust 810 /// use tinyvec::*; 811 /// let mut tv = tiny_vec!([i32; 4] => 1, 2, 3); 812 /// let tv2: TinyVec<[i32; 4]> = tv.splice(1.., 4..=6).collect(); 813 /// assert_eq!(tv.as_slice(), &[1, 4, 5, 6][..]); 814 /// assert_eq!(tv2.as_slice(), &[2, 3][..]); 815 /// 816 /// tv.splice(.., None); 817 /// assert_eq!(tv.as_slice(), &[]); 818 /// ``` 819 #[inline] splice<R, I>( &mut self, range: R, replacement: I, ) -> TinyVecSplice<'_, A, core::iter::Fuse<I::IntoIter>> where R: RangeBounds<usize>, I: IntoIterator<Item = A::Item>,820 pub fn splice<R, I>( 821 &mut self, range: R, replacement: I, 822 ) -> TinyVecSplice<'_, A, core::iter::Fuse<I::IntoIter>> 823 where 824 R: RangeBounds<usize>, 825 I: IntoIterator<Item = A::Item>, 826 { 827 use core::ops::Bound; 828 let start = match range.start_bound() { 829 Bound::Included(x) => *x, 830 Bound::Excluded(x) => x.saturating_add(1), 831 Bound::Unbounded => 0, 832 }; 833 let end = match range.end_bound() { 834 Bound::Included(x) => x.saturating_add(1), 835 Bound::Excluded(x) => *x, 836 Bound::Unbounded => self.len(), 837 }; 838 assert!( 839 start <= end, 840 "TinyVec::splice> Illegal range, {} to {}", 841 start, 842 end 843 ); 844 assert!( 845 end <= self.len(), 846 "TinyVec::splice> Range ends at {} but length is only {}!", 847 end, 848 self.len() 849 ); 850 851 TinyVecSplice { 852 removal_start: start, 853 removal_end: end, 854 parent: self, 855 replacement: replacement.into_iter().fuse(), 856 } 857 } 858 859 /// Wraps an array, using the given length as the starting length. 860 /// 861 /// If you want to use the whole length of the array, you can just use the 862 /// `From` impl. 863 /// 864 /// ## Failure 865 /// 866 /// If the given length is greater than the capacity of the array this will 867 /// error, and you'll get the array back in the `Err`. 868 #[inline] try_from_array_len(data: A, len: usize) -> Result<Self, A>869 pub fn try_from_array_len(data: A, len: usize) -> Result<Self, A> { 870 let arr = ArrayVec::try_from_array_len(data, len)?; 871 Ok(TinyVec::Inline(arr)) 872 } 873 } 874 875 /// Draining iterator for `TinyVecDrain` 876 /// 877 /// See [`TinyVecDrain::drain`](TinyVecDrain::<A>::drain) 878 #[cfg_attr(docs_rs, doc(cfg(feature = "alloc")))] 879 pub enum TinyVecDrain<'p, A: Array> { 880 #[allow(missing_docs)] 881 Inline(ArrayVecDrain<'p, A::Item>), 882 #[allow(missing_docs)] 883 Heap(vec::Drain<'p, A::Item>), 884 } 885 886 impl<'p, A: Array> Iterator for TinyVecDrain<'p, A> { 887 type Item = A::Item; 888 889 impl_mirrored! { 890 type Mirror = TinyVecDrain; 891 892 #[inline] 893 fn next(self: &mut Self) -> Option<Self::Item>; 894 #[inline] 895 fn nth(self: &mut Self, n: usize) -> Option<Self::Item>; 896 #[inline] 897 fn size_hint(self: &Self) -> (usize, Option<usize>); 898 #[inline] 899 fn last(self: Self) -> Option<Self::Item>; 900 #[inline] 901 fn count(self: Self) -> usize; 902 } 903 904 #[inline] for_each<F: FnMut(Self::Item)>(self, f: F)905 fn for_each<F: FnMut(Self::Item)>(self, f: F) { 906 match self { 907 TinyVecDrain::Inline(i) => i.for_each(f), 908 TinyVecDrain::Heap(h) => h.for_each(f), 909 } 910 } 911 } 912 913 impl<'p, A: Array> DoubleEndedIterator for TinyVecDrain<'p, A> { 914 impl_mirrored! { 915 type Mirror = TinyVecDrain; 916 917 #[inline] 918 fn next_back(self: &mut Self) -> Option<Self::Item>; 919 920 #[cfg(feature = "rustc_1_40")] 921 #[inline] 922 fn nth_back(self: &mut Self, n: usize) -> Option<Self::Item>; 923 } 924 } 925 926 /// Splicing iterator for `TinyVec` 927 /// See [`TinyVec::splice`](TinyVec::<A>::splice) 928 #[cfg_attr(docs_rs, doc(cfg(feature = "alloc")))] 929 pub struct TinyVecSplice<'p, A: Array, I: Iterator<Item = A::Item>> { 930 parent: &'p mut TinyVec<A>, 931 removal_start: usize, 932 removal_end: usize, 933 replacement: I, 934 } 935 936 impl<'p, A, I> Iterator for TinyVecSplice<'p, A, I> 937 where 938 A: Array, 939 I: Iterator<Item = A::Item>, 940 { 941 type Item = A::Item; 942 943 #[inline] next(&mut self) -> Option<A::Item>944 fn next(&mut self) -> Option<A::Item> { 945 if self.removal_start < self.removal_end { 946 match self.replacement.next() { 947 Some(replacement) => { 948 let removed = core::mem::replace( 949 &mut self.parent[self.removal_start], 950 replacement, 951 ); 952 self.removal_start += 1; 953 Some(removed) 954 } 955 None => { 956 let removed = self.parent.remove(self.removal_start); 957 self.removal_end -= 1; 958 Some(removed) 959 } 960 } 961 } else { 962 None 963 } 964 } 965 966 #[inline] size_hint(&self) -> (usize, Option<usize>)967 fn size_hint(&self) -> (usize, Option<usize>) { 968 let len = self.len(); 969 (len, Some(len)) 970 } 971 } 972 973 impl<'p, A, I> ExactSizeIterator for TinyVecSplice<'p, A, I> 974 where 975 A: Array, 976 I: Iterator<Item = A::Item>, 977 { 978 #[inline] len(&self) -> usize979 fn len(&self) -> usize { 980 self.removal_end - self.removal_start 981 } 982 } 983 984 impl<'p, A, I> FusedIterator for TinyVecSplice<'p, A, I> 985 where 986 A: Array, 987 I: Iterator<Item = A::Item>, 988 { 989 } 990 991 impl<'p, A, I> DoubleEndedIterator for TinyVecSplice<'p, A, I> 992 where 993 A: Array, 994 I: Iterator<Item = A::Item> + DoubleEndedIterator, 995 { 996 #[inline] next_back(&mut self) -> Option<A::Item>997 fn next_back(&mut self) -> Option<A::Item> { 998 if self.removal_start < self.removal_end { 999 match self.replacement.next_back() { 1000 Some(replacement) => { 1001 let removed = core::mem::replace( 1002 &mut self.parent[self.removal_end - 1], 1003 replacement, 1004 ); 1005 self.removal_end -= 1; 1006 Some(removed) 1007 } 1008 None => { 1009 let removed = self.parent.remove(self.removal_end - 1); 1010 self.removal_end -= 1; 1011 Some(removed) 1012 } 1013 } 1014 } else { 1015 None 1016 } 1017 } 1018 } 1019 1020 impl<'p, A: Array, I: Iterator<Item = A::Item>> Drop 1021 for TinyVecSplice<'p, A, I> 1022 { drop(&mut self)1023 fn drop(&mut self) { 1024 for _ in self.by_ref() {} 1025 1026 let (lower_bound, _) = self.replacement.size_hint(); 1027 self.parent.reserve(lower_bound); 1028 1029 for replacement in self.replacement.by_ref() { 1030 self.parent.insert(self.removal_end, replacement); 1031 self.removal_end += 1; 1032 } 1033 } 1034 } 1035 1036 impl<A: Array> AsMut<[A::Item]> for TinyVec<A> { 1037 #[inline(always)] 1038 #[must_use] as_mut(&mut self) -> &mut [A::Item]1039 fn as_mut(&mut self) -> &mut [A::Item] { 1040 &mut *self 1041 } 1042 } 1043 1044 impl<A: Array> AsRef<[A::Item]> for TinyVec<A> { 1045 #[inline(always)] 1046 #[must_use] as_ref(&self) -> &[A::Item]1047 fn as_ref(&self) -> &[A::Item] { 1048 &*self 1049 } 1050 } 1051 1052 impl<A: Array> Borrow<[A::Item]> for TinyVec<A> { 1053 #[inline(always)] 1054 #[must_use] borrow(&self) -> &[A::Item]1055 fn borrow(&self) -> &[A::Item] { 1056 &*self 1057 } 1058 } 1059 1060 impl<A: Array> BorrowMut<[A::Item]> for TinyVec<A> { 1061 #[inline(always)] 1062 #[must_use] borrow_mut(&mut self) -> &mut [A::Item]1063 fn borrow_mut(&mut self) -> &mut [A::Item] { 1064 &mut *self 1065 } 1066 } 1067 1068 impl<A: Array> Extend<A::Item> for TinyVec<A> { 1069 #[inline] extend<T: IntoIterator<Item = A::Item>>(&mut self, iter: T)1070 fn extend<T: IntoIterator<Item = A::Item>>(&mut self, iter: T) { 1071 let iter = iter.into_iter(); 1072 let (lower_bound, _) = iter.size_hint(); 1073 self.reserve(lower_bound); 1074 1075 let a = match self { 1076 TinyVec::Heap(h) => return h.extend(iter), 1077 TinyVec::Inline(a) => a, 1078 }; 1079 1080 let mut iter = a.fill(iter); 1081 let maybe = iter.next(); 1082 1083 let surely = match maybe { 1084 Some(x) => x, 1085 None => return, 1086 }; 1087 1088 let mut v = a.drain_to_vec_and_reserve(a.len()); 1089 v.push(surely); 1090 v.extend(iter); 1091 *self = TinyVec::Heap(v); 1092 } 1093 } 1094 1095 impl<A: Array> From<ArrayVec<A>> for TinyVec<A> { 1096 #[inline(always)] 1097 #[must_use] from(arr: ArrayVec<A>) -> Self1098 fn from(arr: ArrayVec<A>) -> Self { 1099 TinyVec::Inline(arr) 1100 } 1101 } 1102 1103 impl<A: Array> From<A> for TinyVec<A> { from(array: A) -> Self1104 fn from(array: A) -> Self { 1105 TinyVec::Inline(ArrayVec::from(array)) 1106 } 1107 } 1108 1109 impl<T, A> From<&'_ [T]> for TinyVec<A> 1110 where 1111 T: Clone + Default, 1112 A: Array<Item = T>, 1113 { 1114 #[inline] 1115 #[must_use] from(slice: &[T]) -> Self1116 fn from(slice: &[T]) -> Self { 1117 if slice.len() > A::CAPACITY { 1118 TinyVec::Heap(slice.into()) 1119 } else { 1120 let mut arr = ArrayVec::new(); 1121 // We do not use ArrayVec::extend_from_slice, because it looks like LLVM 1122 // fails to deduplicate all the length-checking logic between the 1123 // above if and the contents of that method, thus producing much 1124 // slower code. Unlike many of the other optimizations in this 1125 // crate, this one is worth keeping an eye on. I see no reason, for 1126 // any element type, that these should produce different code. But 1127 // they do. (rustc 1.51.0) 1128 arr.set_len(slice.len()); 1129 arr.as_mut_slice().clone_from_slice(slice); 1130 TinyVec::Inline(arr) 1131 } 1132 } 1133 } 1134 1135 impl<T, A> From<&'_ mut [T]> for TinyVec<A> 1136 where 1137 T: Clone + Default, 1138 A: Array<Item = T>, 1139 { 1140 #[inline] 1141 #[must_use] from(slice: &mut [T]) -> Self1142 fn from(slice: &mut [T]) -> Self { 1143 Self::from(&*slice) 1144 } 1145 } 1146 1147 impl<A: Array> FromIterator<A::Item> for TinyVec<A> { 1148 #[inline] 1149 #[must_use] from_iter<T: IntoIterator<Item = A::Item>>(iter: T) -> Self1150 fn from_iter<T: IntoIterator<Item = A::Item>>(iter: T) -> Self { 1151 let mut av = Self::default(); 1152 av.extend(iter); 1153 av 1154 } 1155 } 1156 1157 /// Iterator for consuming an `TinyVec` and returning owned elements. 1158 #[cfg_attr(docs_rs, doc(cfg(feature = "alloc")))] 1159 pub enum TinyVecIterator<A: Array> { 1160 #[allow(missing_docs)] 1161 Inline(ArrayVecIterator<A>), 1162 #[allow(missing_docs)] 1163 Heap(alloc::vec::IntoIter<A::Item>), 1164 } 1165 1166 impl<A: Array> TinyVecIterator<A> { 1167 impl_mirrored! { 1168 type Mirror = TinyVecIterator; 1169 /// Returns the remaining items of this iterator as a slice. 1170 #[inline] 1171 #[must_use] 1172 pub fn as_slice(self: &Self) -> &[A::Item]; 1173 } 1174 } 1175 1176 impl<A: Array> FusedIterator for TinyVecIterator<A> {} 1177 1178 impl<A: Array> Iterator for TinyVecIterator<A> { 1179 type Item = A::Item; 1180 1181 impl_mirrored! { 1182 type Mirror = TinyVecIterator; 1183 1184 #[inline] 1185 fn next(self: &mut Self) -> Option<Self::Item>; 1186 1187 #[inline(always)] 1188 #[must_use] 1189 fn size_hint(self: &Self) -> (usize, Option<usize>); 1190 1191 #[inline(always)] 1192 fn count(self: Self) -> usize; 1193 1194 #[inline] 1195 fn last(self: Self) -> Option<Self::Item>; 1196 1197 #[inline] 1198 fn nth(self: &mut Self, n: usize) -> Option<A::Item>; 1199 } 1200 } 1201 1202 impl<A: Array> Debug for TinyVecIterator<A> 1203 where 1204 A::Item: Debug, 1205 { 1206 #[allow(clippy::missing_inline_in_public_items)] fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result1207 fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result { 1208 f.debug_tuple("TinyVecIterator").field(&self.as_slice()).finish() 1209 } 1210 } 1211 1212 impl<A: Array> IntoIterator for TinyVec<A> { 1213 type Item = A::Item; 1214 type IntoIter = TinyVecIterator<A>; 1215 #[inline(always)] 1216 #[must_use] into_iter(self) -> Self::IntoIter1217 fn into_iter(self) -> Self::IntoIter { 1218 match self { 1219 TinyVec::Inline(a) => TinyVecIterator::Inline(a.into_iter()), 1220 TinyVec::Heap(v) => TinyVecIterator::Heap(v.into_iter()), 1221 } 1222 } 1223 } 1224 1225 impl<'a, A: Array> IntoIterator for &'a mut TinyVec<A> { 1226 type Item = &'a mut A::Item; 1227 type IntoIter = core::slice::IterMut<'a, A::Item>; 1228 #[inline(always)] 1229 #[must_use] into_iter(self) -> Self::IntoIter1230 fn into_iter(self) -> Self::IntoIter { 1231 self.iter_mut() 1232 } 1233 } 1234 1235 impl<'a, A: Array> IntoIterator for &'a TinyVec<A> { 1236 type Item = &'a A::Item; 1237 type IntoIter = core::slice::Iter<'a, A::Item>; 1238 #[inline(always)] 1239 #[must_use] into_iter(self) -> Self::IntoIter1240 fn into_iter(self) -> Self::IntoIter { 1241 self.iter() 1242 } 1243 } 1244 1245 impl<A: Array> PartialEq for TinyVec<A> 1246 where 1247 A::Item: PartialEq, 1248 { 1249 #[inline] 1250 #[must_use] eq(&self, other: &Self) -> bool1251 fn eq(&self, other: &Self) -> bool { 1252 self.as_slice().eq(other.as_slice()) 1253 } 1254 } 1255 impl<A: Array> Eq for TinyVec<A> where A::Item: Eq {} 1256 1257 impl<A: Array> PartialOrd for TinyVec<A> 1258 where 1259 A::Item: PartialOrd, 1260 { 1261 #[inline] 1262 #[must_use] partial_cmp(&self, other: &Self) -> Option<core::cmp::Ordering>1263 fn partial_cmp(&self, other: &Self) -> Option<core::cmp::Ordering> { 1264 self.as_slice().partial_cmp(other.as_slice()) 1265 } 1266 } 1267 impl<A: Array> Ord for TinyVec<A> 1268 where 1269 A::Item: Ord, 1270 { 1271 #[inline] 1272 #[must_use] cmp(&self, other: &Self) -> core::cmp::Ordering1273 fn cmp(&self, other: &Self) -> core::cmp::Ordering { 1274 self.as_slice().cmp(other.as_slice()) 1275 } 1276 } 1277 1278 impl<A: Array> PartialEq<&A> for TinyVec<A> 1279 where 1280 A::Item: PartialEq, 1281 { 1282 #[inline] 1283 #[must_use] eq(&self, other: &&A) -> bool1284 fn eq(&self, other: &&A) -> bool { 1285 self.as_slice().eq(other.as_slice()) 1286 } 1287 } 1288 1289 impl<A: Array> PartialEq<&[A::Item]> for TinyVec<A> 1290 where 1291 A::Item: PartialEq, 1292 { 1293 #[inline] 1294 #[must_use] eq(&self, other: &&[A::Item]) -> bool1295 fn eq(&self, other: &&[A::Item]) -> bool { 1296 self.as_slice().eq(*other) 1297 } 1298 } 1299 1300 impl<A: Array> Hash for TinyVec<A> 1301 where 1302 A::Item: Hash, 1303 { 1304 #[inline] hash<H: Hasher>(&self, state: &mut H)1305 fn hash<H: Hasher>(&self, state: &mut H) { 1306 self.as_slice().hash(state) 1307 } 1308 } 1309 1310 // // // // // // // // 1311 // Formatting impls 1312 // // // // // // // // 1313 1314 impl<A: Array> Binary for TinyVec<A> 1315 where 1316 A::Item: Binary, 1317 { 1318 #[allow(clippy::missing_inline_in_public_items)] fmt(&self, f: &mut Formatter) -> core::fmt::Result1319 fn fmt(&self, f: &mut Formatter) -> core::fmt::Result { 1320 write!(f, "[")?; 1321 for (i, elem) in self.iter().enumerate() { 1322 if i > 0 { 1323 write!(f, ", ")?; 1324 } 1325 Binary::fmt(elem, f)?; 1326 } 1327 write!(f, "]") 1328 } 1329 } 1330 1331 impl<A: Array> Debug for TinyVec<A> 1332 where 1333 A::Item: Debug, 1334 { 1335 #[allow(clippy::missing_inline_in_public_items)] fmt(&self, f: &mut Formatter) -> core::fmt::Result1336 fn fmt(&self, f: &mut Formatter) -> core::fmt::Result { 1337 write!(f, "[")?; 1338 for (i, elem) in self.iter().enumerate() { 1339 if i > 0 { 1340 write!(f, ", ")?; 1341 } 1342 Debug::fmt(elem, f)?; 1343 } 1344 write!(f, "]") 1345 } 1346 } 1347 1348 impl<A: Array> Display for TinyVec<A> 1349 where 1350 A::Item: Display, 1351 { 1352 #[allow(clippy::missing_inline_in_public_items)] fmt(&self, f: &mut Formatter) -> core::fmt::Result1353 fn fmt(&self, f: &mut Formatter) -> core::fmt::Result { 1354 write!(f, "[")?; 1355 for (i, elem) in self.iter().enumerate() { 1356 if i > 0 { 1357 write!(f, ", ")?; 1358 } 1359 Display::fmt(elem, f)?; 1360 } 1361 write!(f, "]") 1362 } 1363 } 1364 1365 impl<A: Array> LowerExp for TinyVec<A> 1366 where 1367 A::Item: LowerExp, 1368 { 1369 #[allow(clippy::missing_inline_in_public_items)] fmt(&self, f: &mut Formatter) -> core::fmt::Result1370 fn fmt(&self, f: &mut Formatter) -> core::fmt::Result { 1371 write!(f, "[")?; 1372 for (i, elem) in self.iter().enumerate() { 1373 if i > 0 { 1374 write!(f, ", ")?; 1375 } 1376 LowerExp::fmt(elem, f)?; 1377 } 1378 write!(f, "]") 1379 } 1380 } 1381 1382 impl<A: Array> LowerHex for TinyVec<A> 1383 where 1384 A::Item: LowerHex, 1385 { 1386 #[allow(clippy::missing_inline_in_public_items)] fmt(&self, f: &mut Formatter) -> core::fmt::Result1387 fn fmt(&self, f: &mut Formatter) -> core::fmt::Result { 1388 write!(f, "[")?; 1389 for (i, elem) in self.iter().enumerate() { 1390 if i > 0 { 1391 write!(f, ", ")?; 1392 } 1393 LowerHex::fmt(elem, f)?; 1394 } 1395 write!(f, "]") 1396 } 1397 } 1398 1399 impl<A: Array> Octal for TinyVec<A> 1400 where 1401 A::Item: Octal, 1402 { 1403 #[allow(clippy::missing_inline_in_public_items)] fmt(&self, f: &mut Formatter) -> core::fmt::Result1404 fn fmt(&self, f: &mut Formatter) -> core::fmt::Result { 1405 write!(f, "[")?; 1406 for (i, elem) in self.iter().enumerate() { 1407 if i > 0 { 1408 write!(f, ", ")?; 1409 } 1410 Octal::fmt(elem, f)?; 1411 } 1412 write!(f, "]") 1413 } 1414 } 1415 1416 impl<A: Array> Pointer for TinyVec<A> 1417 where 1418 A::Item: Pointer, 1419 { 1420 #[allow(clippy::missing_inline_in_public_items)] fmt(&self, f: &mut Formatter) -> core::fmt::Result1421 fn fmt(&self, f: &mut Formatter) -> core::fmt::Result { 1422 write!(f, "[")?; 1423 for (i, elem) in self.iter().enumerate() { 1424 if i > 0 { 1425 write!(f, ", ")?; 1426 } 1427 Pointer::fmt(elem, f)?; 1428 } 1429 write!(f, "]") 1430 } 1431 } 1432 1433 impl<A: Array> UpperExp for TinyVec<A> 1434 where 1435 A::Item: UpperExp, 1436 { 1437 #[allow(clippy::missing_inline_in_public_items)] fmt(&self, f: &mut Formatter) -> core::fmt::Result1438 fn fmt(&self, f: &mut Formatter) -> core::fmt::Result { 1439 write!(f, "[")?; 1440 for (i, elem) in self.iter().enumerate() { 1441 if i > 0 { 1442 write!(f, ", ")?; 1443 } 1444 UpperExp::fmt(elem, f)?; 1445 } 1446 write!(f, "]") 1447 } 1448 } 1449 1450 impl<A: Array> UpperHex for TinyVec<A> 1451 where 1452 A::Item: UpperHex, 1453 { 1454 #[allow(clippy::missing_inline_in_public_items)] fmt(&self, f: &mut Formatter) -> core::fmt::Result1455 fn fmt(&self, f: &mut Formatter) -> core::fmt::Result { 1456 write!(f, "[")?; 1457 for (i, elem) in self.iter().enumerate() { 1458 if i > 0 { 1459 write!(f, ", ")?; 1460 } 1461 UpperHex::fmt(elem, f)?; 1462 } 1463 write!(f, "]") 1464 } 1465 } 1466 1467 #[cfg(feature = "serde")] 1468 #[cfg_attr(docs_rs, doc(cfg(feature = "alloc")))] 1469 struct TinyVecVisitor<A: Array>(PhantomData<A>); 1470 1471 #[cfg(feature = "serde")] 1472 impl<'de, A: Array> Visitor<'de> for TinyVecVisitor<A> 1473 where 1474 A::Item: Deserialize<'de>, 1475 { 1476 type Value = TinyVec<A>; 1477 expecting( &self, formatter: &mut core::fmt::Formatter, ) -> core::fmt::Result1478 fn expecting( 1479 &self, formatter: &mut core::fmt::Formatter, 1480 ) -> core::fmt::Result { 1481 formatter.write_str("a sequence") 1482 } 1483 visit_seq<S>(self, mut seq: S) -> Result<Self::Value, S::Error> where S: SeqAccess<'de>,1484 fn visit_seq<S>(self, mut seq: S) -> Result<Self::Value, S::Error> 1485 where 1486 S: SeqAccess<'de>, 1487 { 1488 let mut new_tinyvec = match seq.size_hint() { 1489 Some(expected_size) => TinyVec::with_capacity(expected_size), 1490 None => Default::default(), 1491 }; 1492 1493 while let Some(value) = seq.next_element()? { 1494 new_tinyvec.push(value); 1495 } 1496 1497 Ok(new_tinyvec) 1498 } 1499 } 1500