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