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