Coverage Report

Created: 2025-07-11 07:04

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