1#![cfg(feature = "alloc")]
2
3use super::*;
4
5use alloc::vec::{self, Vec};
6use core::convert::TryFrom;
7use tinyvec_macros::impl_mirrored;
8
9#[cfg(feature = "rustc_1_57")]
10use alloc::collections::TryReserveError;
11
12#[cfg(feature = "serde")]
13use core::marker::PhantomData;
14#[cfg(feature = "serde")]
15use serde::de::{Deserialize, Deserializer, SeqAccess, Visitor};
16#[cfg(feature = "serde")]
17use 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")))]
39macro_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!`
71pub 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")))]
98pub enum TinyVec<A: Array> {
99 #[allow(missing_docs)]
100 Inline(ArrayVec<A>),
101 #[allow(missing_docs)]
102 Heap(Vec<A::Item>),
103}
104
105impl<A> Clone for TinyVec<A>
106where
107 A: Array + Clone,
108 A::Item: Clone,
109{
110 #[inline]
111 fn clone(&self) -> Self {
112 match self {
113 TinyVec::Heap(v: &Vec<::Item>) => TinyVec::Heap(v.clone()),
114 TinyVec::Inline(v: &ArrayVec) => TinyVec::Inline(v.clone()),
115 }
116 }
117
118 #[inline]
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(new_len:o.len());
124 }
125 let (start: &[::Item], end: &[::Item]) = o.split_at(self.len());
126 for (dst: &mut ::Item, src: &::Item) in self.iter_mut().zip(start) {
127 dst.clone_from(source:src);
128 }
129 self.extend_from_slice(sli:end);
130 }
131}
132
133impl<A: Array> Default for TinyVec<A> {
134 #[inline]
135 #[must_use]
136 fn default() -> Self {
137 TinyVec::Inline(ArrayVec::default())
138 }
139}
140
141impl<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
152impl<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
161impl<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]
165 fn index(&self, index: I) -> &Self::Output {
166 &self.deref()[index]
167 }
168}
169
170impl<A: Array, I: SliceIndex<[A::Item]>> IndexMut<I> for TinyVec<A> {
171 #[inline(always)]
172 #[must_use]
173 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")))]
180impl<A: Array<Item = u8>> std::io::Write for TinyVec<A> {
181 #[inline(always)]
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)]
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")))]
195impl<A: Array> Serialize for TinyVec<A>
196where
197 A::Item: Serialize,
198{
199 #[must_use]
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")))]
214impl<'de, A: Array> Deserialize<'de> for TinyVec<A>
215where
216 A::Item: Deserialize<'de>,
217{
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")))]
228impl<'a, A> arbitrary::Arbitrary<'a> for TinyVec<A>
229where
230 A: Array,
231 A::Item: arbitrary::Arbitrary<'a>,
232{
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
241impl<A: Array> TinyVec<A> {
242 /// Returns whether elements are on heap
243 #[inline(always)]
244 #[must_use]
245 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]
254 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 /// ```
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)]
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")]
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 /// ```
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")]
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 /// ```
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")]
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 /// ```
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")]
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]
522 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
531impl<A: Array> TinyVec<A> {
532 /// Move all values from `other` into this vec.
533 #[cfg(feature = "rustc_1_40")]
534 #[inline]
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]
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]
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]
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]
671 pub fn as_slice(self: &Self) -> &[A::Item] {
672 self.deref()
673 }
674
675 /// Removes all elements from the vec.
676 #[inline(always)]
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)]
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)]
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)]
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]
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]
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)]
778 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)]
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]
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]
843 pub fn is_empty(&self) -> bool {
844 self.len() == 0
845 }
846
847 /// Makes a new, empty vec.
848 #[inline(always)]
849 #[must_use]
850 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]
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]
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]
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]
973 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]
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]
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")))]
1063pub 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
1070impl<'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]
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
1097impl<'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")))]
1113pub 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
1120impl<'p, A, I> Iterator for TinyVecSplice<'p, A, I>
1121where
1122 A: Array,
1123 I: Iterator<Item = A::Item>,
1124{
1125 type Item = A::Item;
1126
1127 #[inline]
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]
1151 fn size_hint(&self) -> (usize, Option<usize>) {
1152 let len = self.len();
1153 (len, Some(len))
1154 }
1155}
1156
1157impl<'p, A, I> ExactSizeIterator for TinyVecSplice<'p, A, I>
1158where
1159 A: Array,
1160 I: Iterator<Item = A::Item>,
1161{
1162 #[inline]
1163 fn len(&self) -> usize {
1164 self.removal_end - self.removal_start
1165 }
1166}
1167
1168impl<'p, A, I> FusedIterator for TinyVecSplice<'p, A, I>
1169where
1170 A: Array,
1171 I: Iterator<Item = A::Item>,
1172{
1173}
1174
1175impl<'p, A, I> DoubleEndedIterator for TinyVecSplice<'p, A, I>
1176where
1177 A: Array,
1178 I: Iterator<Item = A::Item> + DoubleEndedIterator,
1179{
1180 #[inline]
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: ::Item) => {
1185 let removed: ::Item = core::mem::replace(
1186 &mut self.parent[self.removal_end - 1],
1187 src:replacement,
1188 );
1189 self.removal_end -= 1;
1190 Some(removed)
1191 }
1192 None => {
1193 let removed: ::Item = 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
1204impl<'p, A: Array, I: Iterator<Item = A::Item>> Drop
1205 for TinyVecSplice<'p, A, I>
1206{
1207 fn drop(&mut self) {
1208 for _ in self.by_ref() {}
1209
1210 let (lower_bound: usize, _) = self.replacement.size_hint();
1211 self.parent.reserve(lower_bound);
1212
1213 for replacement: ::Item in self.replacement.by_ref() {
1214 self.parent.insert(self.removal_end, item:replacement);
1215 self.removal_end += 1;
1216 }
1217 }
1218}
1219
1220impl<A: Array> AsMut<[A::Item]> for TinyVec<A> {
1221 #[inline(always)]
1222 #[must_use]
1223 fn as_mut(&mut self) -> &mut [A::Item] {
1224 &mut *self
1225 }
1226}
1227
1228impl<A: Array> AsRef<[A::Item]> for TinyVec<A> {
1229 #[inline(always)]
1230 #[must_use]
1231 fn as_ref(&self) -> &[A::Item] {
1232 &*self
1233 }
1234}
1235
1236impl<A: Array> Borrow<[A::Item]> for TinyVec<A> {
1237 #[inline(always)]
1238 #[must_use]
1239 fn borrow(&self) -> &[A::Item] {
1240 &*self
1241 }
1242}
1243
1244impl<A: Array> BorrowMut<[A::Item]> for TinyVec<A> {
1245 #[inline(always)]
1246 #[must_use]
1247 fn borrow_mut(&mut self) -> &mut [A::Item] {
1248 &mut *self
1249 }
1250}
1251
1252impl<A: Array> Extend<A::Item> for TinyVec<A> {
1253 #[inline]
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
1279impl<A: Array> From<ArrayVec<A>> for TinyVec<A> {
1280 #[inline(always)]
1281 #[must_use]
1282 fn from(arr: ArrayVec<A>) -> Self {
1283 TinyVec::Inline(arr)
1284 }
1285}
1286
1287impl<A: Array> From<A> for TinyVec<A> {
1288 fn from(array: A) -> Self {
1289 TinyVec::Inline(ArrayVec::from(array))
1290 }
1291}
1292
1293impl<T, A> From<&'_ [T]> for TinyVec<A>
1294where
1295 T: Clone + Default,
1296 A: Array<Item = T>,
1297{
1298 #[inline]
1299 #[must_use]
1300 fn from(slice: &[T]) -> Self {
1301 if let Ok(arr: ArrayVec) = ArrayVec::try_from(slice) {
1302 TinyVec::Inline(arr)
1303 } else {
1304 TinyVec::Heap(slice.into())
1305 }
1306 }
1307}
1308
1309impl<T, A> From<&'_ mut [T]> for TinyVec<A>
1310where
1311 T: Clone + Default,
1312 A: Array<Item = T>,
1313{
1314 #[inline]
1315 #[must_use]
1316 fn from(slice: &mut [T]) -> Self {
1317 Self::from(&*slice)
1318 }
1319}
1320
1321impl<A: Array> FromIterator<A::Item> for TinyVec<A> {
1322 #[inline]
1323 #[must_use]
1324 fn from_iter<T: IntoIterator<Item = A::Item>>(iter: T) -> Self {
1325 let mut av: TinyVec = 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")))]
1333pub 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
1340impl<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
1350impl<A: Array> FusedIterator for TinyVecIterator<A> {}
1351
1352impl<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
1376impl<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
1389impl<A: Array> Debug for TinyVecIterator<A>
1390where
1391 A::Item: Debug,
1392{
1393 #[allow(clippy::missing_inline_in_public_items)]
1394 fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
1395 f.debug_tuple(name:"TinyVecIterator").field(&self.as_slice()).finish()
1396 }
1397}
1398
1399impl<A: Array> IntoIterator for TinyVec<A> {
1400 type Item = A::Item;
1401 type IntoIter = TinyVecIterator<A>;
1402 #[inline(always)]
1403 #[must_use]
1404 fn into_iter(self) -> Self::IntoIter {
1405 match self {
1406 TinyVec::Inline(a: ArrayVec) => TinyVecIterator::Inline(a.into_iter()),
1407 TinyVec::Heap(v: Vec<::Item>) => TinyVecIterator::Heap(v.into_iter()),
1408 }
1409 }
1410}
1411
1412impl<'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]
1417 fn into_iter(self) -> Self::IntoIter {
1418 self.iter_mut()
1419 }
1420}
1421
1422impl<'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]
1427 fn into_iter(self) -> Self::IntoIter {
1428 self.iter()
1429 }
1430}
1431
1432impl<A: Array> PartialEq for TinyVec<A>
1433where
1434 A::Item: PartialEq,
1435{
1436 #[inline]
1437 #[must_use]
1438 fn eq(&self, other: &Self) -> bool {
1439 self.as_slice().eq(other.as_slice())
1440 }
1441}
1442impl<A: Array> Eq for TinyVec<A> where A::Item: Eq {}
1443
1444impl<A: Array> PartialOrd for TinyVec<A>
1445where
1446 A::Item: PartialOrd,
1447{
1448 #[inline]
1449 #[must_use]
1450 fn partial_cmp(&self, other: &Self) -> Option<core::cmp::Ordering> {
1451 self.as_slice().partial_cmp(other.as_slice())
1452 }
1453}
1454impl<A: Array> Ord for TinyVec<A>
1455where
1456 A::Item: Ord,
1457{
1458 #[inline]
1459 #[must_use]
1460 fn cmp(&self, other: &Self) -> core::cmp::Ordering {
1461 self.as_slice().cmp(other.as_slice())
1462 }
1463}
1464
1465impl<A: Array> PartialEq<&A> for TinyVec<A>
1466where
1467 A::Item: PartialEq,
1468{
1469 #[inline]
1470 #[must_use]
1471 fn eq(&self, other: &&A) -> bool {
1472 self.as_slice().eq(other.as_slice())
1473 }
1474}
1475
1476impl<A: Array> PartialEq<&[A::Item]> for TinyVec<A>
1477where
1478 A::Item: PartialEq,
1479{
1480 #[inline]
1481 #[must_use]
1482 fn eq(&self, other: &&[A::Item]) -> bool {
1483 self.as_slice().eq(*other)
1484 }
1485}
1486
1487impl<A: Array> Hash for TinyVec<A>
1488where
1489 A::Item: Hash,
1490{
1491 #[inline]
1492 fn hash<H: Hasher>(&self, state: &mut H) {
1493 self.as_slice().hash(state)
1494 }
1495}
1496
1497// // // // // // // //
1498// Formatting impls
1499// // // // // // // //
1500
1501impl<A: Array> Binary for TinyVec<A>
1502where
1503 A::Item: Binary,
1504{
1505 #[allow(clippy::missing_inline_in_public_items)]
1506 fn fmt(&self, f: &mut Formatter) -> core::fmt::Result {
1507 write!(f, "[")?;
1508 if f.alternate() {
1509 write!(f, "\n ")?;
1510 }
1511 for (i: usize, elem: &::Item) in self.iter().enumerate() {
1512 if i > 0 {
1513 write!(f, ",{}", if f.alternate() { "\n " } else { " " })?;
1514 }
1515 Binary::fmt(self:elem, f)?;
1516 }
1517 if f.alternate() {
1518 write!(f, ",\n")?;
1519 }
1520 write!(f, "]")
1521 }
1522}
1523
1524impl<A: Array> Debug for TinyVec<A>
1525where
1526 A::Item: Debug,
1527{
1528 #[allow(clippy::missing_inline_in_public_items)]
1529 fn fmt(&self, f: &mut Formatter) -> core::fmt::Result {
1530 write!(f, "[")?;
1531 if f.alternate() {
1532 write!(f, "\n ")?;
1533 }
1534 for (i: usize, elem: &::Item) in self.iter().enumerate() {
1535 if i > 0 {
1536 write!(f, ",{}", if f.alternate() { "\n " } else { " " })?;
1537 }
1538 Debug::fmt(self:elem, f)?;
1539 }
1540 if f.alternate() {
1541 write!(f, ",\n")?;
1542 }
1543 write!(f, "]")
1544 }
1545}
1546
1547impl<A: Array> Display for TinyVec<A>
1548where
1549 A::Item: Display,
1550{
1551 #[allow(clippy::missing_inline_in_public_items)]
1552 fn fmt(&self, f: &mut Formatter) -> core::fmt::Result {
1553 write!(f, "[")?;
1554 if f.alternate() {
1555 write!(f, "\n ")?;
1556 }
1557 for (i: usize, elem: &::Item) in self.iter().enumerate() {
1558 if i > 0 {
1559 write!(f, ",{}", if f.alternate() { "\n " } else { " " })?;
1560 }
1561 Display::fmt(self:elem, f)?;
1562 }
1563 if f.alternate() {
1564 write!(f, ",\n")?;
1565 }
1566 write!(f, "]")
1567 }
1568}
1569
1570impl<A: Array> LowerExp for TinyVec<A>
1571where
1572 A::Item: LowerExp,
1573{
1574 #[allow(clippy::missing_inline_in_public_items)]
1575 fn fmt(&self, f: &mut Formatter) -> core::fmt::Result {
1576 write!(f, "[")?;
1577 if f.alternate() {
1578 write!(f, "\n ")?;
1579 }
1580 for (i: usize, elem: &::Item) in self.iter().enumerate() {
1581 if i > 0 {
1582 write!(f, ",{}", if f.alternate() { "\n " } else { " " })?;
1583 }
1584 LowerExp::fmt(self:elem, f)?;
1585 }
1586 if f.alternate() {
1587 write!(f, ",\n")?;
1588 }
1589 write!(f, "]")
1590 }
1591}
1592
1593impl<A: Array> LowerHex for TinyVec<A>
1594where
1595 A::Item: LowerHex,
1596{
1597 #[allow(clippy::missing_inline_in_public_items)]
1598 fn fmt(&self, f: &mut Formatter) -> core::fmt::Result {
1599 write!(f, "[")?;
1600 if f.alternate() {
1601 write!(f, "\n ")?;
1602 }
1603 for (i: usize, elem: &::Item) in self.iter().enumerate() {
1604 if i > 0 {
1605 write!(f, ",{}", if f.alternate() { "\n " } else { " " })?;
1606 }
1607 LowerHex::fmt(self:elem, f)?;
1608 }
1609 if f.alternate() {
1610 write!(f, ",\n")?;
1611 }
1612 write!(f, "]")
1613 }
1614}
1615
1616impl<A: Array> Octal for TinyVec<A>
1617where
1618 A::Item: Octal,
1619{
1620 #[allow(clippy::missing_inline_in_public_items)]
1621 fn fmt(&self, f: &mut Formatter) -> core::fmt::Result {
1622 write!(f, "[")?;
1623 if f.alternate() {
1624 write!(f, "\n ")?;
1625 }
1626 for (i: usize, elem: &::Item) in self.iter().enumerate() {
1627 if i > 0 {
1628 write!(f, ",{}", if f.alternate() { "\n " } else { " " })?;
1629 }
1630 Octal::fmt(self:elem, f)?;
1631 }
1632 if f.alternate() {
1633 write!(f, ",\n")?;
1634 }
1635 write!(f, "]")
1636 }
1637}
1638
1639impl<A: Array> Pointer for TinyVec<A>
1640where
1641 A::Item: Pointer,
1642{
1643 #[allow(clippy::missing_inline_in_public_items)]
1644 fn fmt(&self, f: &mut Formatter) -> core::fmt::Result {
1645 write!(f, "[")?;
1646 if f.alternate() {
1647 write!(f, "\n ")?;
1648 }
1649 for (i: usize, elem: &::Item) in self.iter().enumerate() {
1650 if i > 0 {
1651 write!(f, ",{}", if f.alternate() { "\n " } else { " " })?;
1652 }
1653 Pointer::fmt(self:elem, f)?;
1654 }
1655 if f.alternate() {
1656 write!(f, ",\n")?;
1657 }
1658 write!(f, "]")
1659 }
1660}
1661
1662impl<A: Array> UpperExp for TinyVec<A>
1663where
1664 A::Item: UpperExp,
1665{
1666 #[allow(clippy::missing_inline_in_public_items)]
1667 fn fmt(&self, f: &mut Formatter) -> core::fmt::Result {
1668 write!(f, "[")?;
1669 if f.alternate() {
1670 write!(f, "\n ")?;
1671 }
1672 for (i: usize, elem: &::Item) in self.iter().enumerate() {
1673 if i > 0 {
1674 write!(f, ",{}", if f.alternate() { "\n " } else { " " })?;
1675 }
1676 UpperExp::fmt(self:elem, f)?;
1677 }
1678 if f.alternate() {
1679 write!(f, ",\n")?;
1680 }
1681 write!(f, "]")
1682 }
1683}
1684
1685impl<A: Array> UpperHex for TinyVec<A>
1686where
1687 A::Item: UpperHex,
1688{
1689 #[allow(clippy::missing_inline_in_public_items)]
1690 fn fmt(&self, f: &mut Formatter) -> core::fmt::Result {
1691 write!(f, "[")?;
1692 if f.alternate() {
1693 write!(f, "\n ")?;
1694 }
1695 for (i: usize, elem: &::Item) in self.iter().enumerate() {
1696 if i > 0 {
1697 write!(f, ",{}", if f.alternate() { "\n " } else { " " })?;
1698 }
1699 UpperHex::fmt(self: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")))]
1710struct TinyVecVisitor<A: Array>(PhantomData<A>);
1711
1712#[cfg(feature = "serde")]
1713impl<'de, A: Array> Visitor<'de> for TinyVecVisitor<A>
1714where
1715 A::Item: Deserialize<'de>,
1716{
1717 type Value = TinyVec<A>;
1718
1719 fn expecting(
1720 &self, formatter: &mut core::fmt::Formatter,
1721 ) -> core::fmt::Result {
1722 formatter.write_str("a sequence")
1723 }
1724
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