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