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