1use super::*;
2
3use alloc::vec::{self, Vec};
4use core::convert::TryFrom;
5use tinyvec_macros::impl_mirrored;
6
7#[cfg(feature = "rustc_1_57")]
8use alloc::collections::TryReserveError;
9
10#[cfg(feature = "serde")]
11use core::marker::PhantomData;
12#[cfg(feature = "serde")]
13use serde_core::de::{Deserialize, Deserializer, SeqAccess, Visitor};
14#[cfg(feature = "serde")]
15use serde_core::ser::{Serialize, SerializeSeq, Serializer};
16
17#[macro_export]
36#[cfg_attr(docsrs, doc(cfg(feature = "alloc")))]
37macro_rules! tiny_vec {
38 ($array_type:ty => $($elem:expr),* $(,)?) => {
39 {
40 const INVOKED_ELEM_COUNT: usize = 0 $( + { let _ = stringify!($elem); 1 })*;
42 match $crate::TinyVec::constructor_for_capacity(INVOKED_ELEM_COUNT) {
45 $crate::TinyVecConstructor::Inline(f) => {
46 f($crate::array_vec!($array_type => $($elem),*))
47 }
48 $crate::TinyVecConstructor::Heap(f) => {
49 f(vec!($($elem),*))
50 }
51 }
52 }
53 };
54 ($array_type:ty) => {
55 $crate::TinyVec::<$array_type>::default()
56 };
57 ($($elem:expr),*) => {
58 $crate::tiny_vec!(_ => $($elem),*)
59 };
60 ($elem:expr; $n:expr) => {
61 $crate::TinyVec::from([$elem; $n])
62 };
63 () => {
64 $crate::tiny_vec!(_)
65 };
66}
67
68#[doc(hidden)] pub enum TinyVecConstructor<A: Array> {
70 Inline(fn(ArrayVec<A>) -> TinyVec<A>),
71 Heap(fn(Vec<A::Item>) -> TinyVec<A>),
72}
73
74#[cfg_attr(docsrs, doc(cfg(feature = "alloc")))]
96pub enum TinyVec<A: Array> {
97 #[allow(missing_docs)]
98 Inline(ArrayVec<A>),
99 #[allow(missing_docs)]
100 Heap(Vec<A::Item>),
101}
102
103impl<A> Clone for TinyVec<A>
104where
105 A: Array + Clone,
106 A::Item: Clone,
107{
108 #[inline]
109 fn clone(&self) -> Self {
110 match self {
111 TinyVec::Heap(v) => TinyVec::Heap(v.clone()),
112 TinyVec::Inline(v) => TinyVec::Inline(v.clone()),
113 }
114 }
115
116 #[inline]
117 fn clone_from(&mut self, o: &Self) {
118 if o.len() > self.len() {
119 self.reserve(o.len() - self.len());
120 } else {
121 self.truncate(o.len());
122 }
123 let (start, end) = o.split_at(self.len());
124 for (dst, src) in self.iter_mut().zip(start) {
125 dst.clone_from(src);
126 }
127 self.extend_from_slice(end);
128 }
129}
130
131impl<A: Array> Default for TinyVec<A> {
132 #[inline]
133 fn default() -> Self {
134 TinyVec::Inline(ArrayVec::default())
135 }
136}
137
138impl<A: Array> Deref for TinyVec<A> {
139 type Target = [A::Item];
140
141 impl_mirrored! {
142 type Mirror = TinyVec;
143 #[inline(always)]
144 #[must_use]
145 fn deref(self: &Self) -> &Self::Target;
146 }
147}
148
149impl<A: Array> DerefMut for TinyVec<A> {
150 impl_mirrored! {
151 type Mirror = TinyVec;
152 #[inline(always)]
153 #[must_use]
154 fn deref_mut(self: &mut Self) -> &mut Self::Target;
155 }
156}
157
158impl<A: Array, I: SliceIndex<[A::Item]>> Index<I> for TinyVec<A> {
159 type Output = <I as SliceIndex<[A::Item]>>::Output;
160 #[inline(always)]
161 fn index(&self, index: I) -> &Self::Output {
162 &self.deref()[index]
163 }
164}
165
166impl<A: Array, I: SliceIndex<[A::Item]>> IndexMut<I> for TinyVec<A> {
167 #[inline(always)]
168 fn index_mut(&mut self, index: I) -> &mut Self::Output {
169 &mut self.deref_mut()[index]
170 }
171}
172
173#[cfg(feature = "std")]
174#[cfg_attr(docs_rs, doc(cfg(feature = "std")))]
175impl<A: Array<Item = u8>> std::io::Write for TinyVec<A> {
176 #[inline(always)]
177 fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
178 self.extend_from_slice(buf);
179 Ok(buf.len())
180 }
181
182 #[inline(always)]
183 fn flush(&mut self) -> std::io::Result<()> {
184 Ok(())
185 }
186}
187
188#[cfg(feature = "serde")]
189#[cfg_attr(docs_rs, doc(cfg(feature = "serde")))]
190impl<A: Array> Serialize for TinyVec<A>
191where
192 A::Item: Serialize,
193{
194 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
195 where
196 S: Serializer,
197 {
198 let mut seq = serializer.serialize_seq(Some(self.len()))?;
199 for element in self.iter() {
200 seq.serialize_element(element)?;
201 }
202 seq.end()
203 }
204}
205
206#[cfg(feature = "serde")]
207#[cfg_attr(docs_rs, doc(cfg(feature = "serde")))]
208impl<'de, A: Array> Deserialize<'de> for TinyVec<A>
209where
210 A::Item: Deserialize<'de>,
211{
212 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
213 where
214 D: Deserializer<'de>,
215 {
216 deserializer.deserialize_seq(TinyVecVisitor(PhantomData))
217 }
218}
219
220#[cfg(feature = "borsh")]
221#[cfg_attr(docs_rs, doc(cfg(feature = "borsh")))]
222impl<A: Array> borsh::BorshSerialize for TinyVec<A>
223where
224 <A as Array>::Item: borsh::BorshSerialize,
225{
226 fn serialize<W: borsh::io::Write>(
227 &self, writer: &mut W,
228 ) -> borsh::io::Result<()> {
229 <usize as borsh::BorshSerialize>::serialize(&self.len(), writer)?;
230 for elem in self.iter() {
231 <<A as Array>::Item as borsh::BorshSerialize>::serialize(elem, writer)?;
232 }
233 Ok(())
234 }
235}
236
237#[cfg(any(feature = "borsh", feature = "bin-proto", feature = "serde"))]
244fn cautious_capacity<T>(len: usize) -> usize {
245 const MAX_PREALLOC_BYTES: usize = 4096;
248 let item_size = core::mem::size_of::<T>();
249 if item_size == 0 {
250 len
251 } else {
252 core::cmp::min(len, MAX_PREALLOC_BYTES / item_size)
253 }
254}
255
256#[cfg(feature = "borsh")]
257#[cfg_attr(docs_rs, doc(cfg(feature = "borsh")))]
258impl<A: Array> borsh::BorshDeserialize for TinyVec<A>
259where
260 <A as Array>::Item: borsh::BorshDeserialize,
261{
262 fn deserialize_reader<R: borsh::io::Read>(
263 reader: &mut R,
264 ) -> borsh::io::Result<Self> {
265 let len = <usize as borsh::BorshDeserialize>::deserialize_reader(reader)?;
266 let mut new_tinyvec =
267 Self::with_capacity(cautious_capacity::<A::Item>(len));
268
269 for _ in 0..len {
270 new_tinyvec.push(
271 <<A as Array>::Item as borsh::BorshDeserialize>::deserialize_reader(
272 reader,
273 )?,
274 )
275 }
276
277 Ok(new_tinyvec)
278 }
279}
280
281#[cfg(feature = "arbitrary")]
282#[cfg_attr(docs_rs, doc(cfg(feature = "arbitrary")))]
283impl<'a, A> arbitrary::Arbitrary<'a> for TinyVec<A>
284where
285 A: Array,
286 A::Item: arbitrary::Arbitrary<'a>,
287{
288 fn arbitrary(u: &mut arbitrary::Unstructured<'a>) -> arbitrary::Result<Self> {
289 let v = Vec::arbitrary(u)?;
290 let mut tv = TinyVec::Heap(v);
291 tv.shrink_to_fit();
292 Ok(tv)
293 }
294}
295
296#[cfg(feature = "bin-proto")]
297#[cfg_attr(docs_rs, doc(cfg(feature = "bin-proto")))]
298impl<Ctx, A> bin_proto::BitEncode<Ctx, bin_proto::Untagged> for TinyVec<A>
299where
300 A: Array,
301 <A as Array>::Item: bin_proto::BitEncode<Ctx>,
302{
303 fn encode<W, E>(
304 &self, write: &mut W, ctx: &mut Ctx, tag: bin_proto::Untagged,
305 ) -> bin_proto::Result<()>
306 where
307 W: bin_proto::BitWrite,
308 E: bin_proto::Endianness,
309 {
310 <[<A as Array>::Item] as bin_proto::BitEncode<_, _>>::encode::<_, E>(
311 self.as_slice(),
312 write,
313 ctx,
314 tag,
315 )
316 }
317}
318
319#[cfg(feature = "bin-proto")]
320#[cfg_attr(docs_rs, doc(cfg(feature = "bin-proto")))]
321impl<Tag, Ctx, A> bin_proto::BitDecode<Ctx, bin_proto::Tag<Tag>> for TinyVec<A>
322where
323 A: Array,
324 <A as Array>::Item: bin_proto::BitDecode<Ctx>,
325 Tag: ::core::convert::TryInto<usize>,
326{
327 fn decode<R, E>(
328 read: &mut R, ctx: &mut Ctx, tag: bin_proto::Tag<Tag>,
329 ) -> bin_proto::Result<Self>
330 where
331 R: bin_proto::BitRead,
332 E: bin_proto::Endianness,
333 {
334 let item_count =
335 tag.0.try_into().map_err(|_| bin_proto::Error::TagConvert)?;
336 let mut values =
337 Self::with_capacity(cautious_capacity::<A::Item>(item_count));
338 for _ in 0..item_count {
339 values.push(bin_proto::BitDecode::<_, _>::decode::<_, E>(read, ctx, ())?);
340 }
341 Ok(values)
342 }
343}
344
345#[cfg(feature = "bin-proto")]
346#[cfg_attr(docs_rs, doc(cfg(feature = "bin-proto")))]
347impl<Ctx, A> bin_proto::BitDecode<Ctx, bin_proto::Untagged> for TinyVec<A>
348where
349 A: Array,
350 <A as Array>::Item: bin_proto::BitDecode<Ctx>,
351{
352 fn decode<R, E>(
353 read: &mut R, ctx: &mut Ctx, _tag: bin_proto::Untagged,
354 ) -> bin_proto::Result<Self>
355 where
356 R: bin_proto::BitRead,
357 E: bin_proto::Endianness,
358 {
359 bin_proto::util::decode_items_to_eof::<_, E, _, _>(read, ctx).collect()
360 }
361}
362
363#[cfg(feature = "schemars")]
364#[cfg_attr(docs_rs, doc(cfg(feature = "schemars")))]
365impl<A> schemars::JsonSchema for TinyVec<A>
366where
367 A: Array,
368 <A as Array>::Item: schemars::JsonSchema,
369{
370 fn schema_name() -> alloc::borrow::Cow<'static, str> {
371 alloc::format!(
372 "Array_up_to_size_{}_of_{}",
373 A::CAPACITY,
374 <A as Array>::Item::schema_name()
375 )
376 .into()
377 }
378
379 fn json_schema(
380 generator: &mut schemars::SchemaGenerator,
381 ) -> schemars::Schema {
382 schemars::json_schema!({
383 "type": "array",
384 "items": generator.subschema_for::<<A as Array>::Item>(),
385 "maxItems": A::CAPACITY
386 })
387 }
388}
389
390impl<A: Array> TinyVec<A> {
391 #[inline(always)]
393 #[must_use]
394 pub fn is_heap(&self) -> bool {
395 match self {
396 TinyVec::Heap(_) => true,
397 TinyVec::Inline(_) => false,
398 }
399 }
400 #[inline(always)]
402 #[must_use]
403 pub fn is_inline(&self) -> bool {
404 !self.is_heap()
405 }
406
407 #[inline]
419 pub fn shrink_to_fit(&mut self) {
420 let vec = match self {
421 TinyVec::Inline(_) => return,
422 TinyVec::Heap(h) => h,
423 };
424
425 if vec.len() > A::CAPACITY {
426 return vec.shrink_to_fit();
427 }
428
429 let moved_vec = core::mem::take(vec);
430
431 let mut av = ArrayVec::default();
432 let mut rest = av.fill(moved_vec);
433 debug_assert!(rest.next().is_none());
434 *self = TinyVec::Inline(av);
435 }
436
437 #[allow(clippy::missing_inline_in_public_items)]
446 pub fn move_to_the_heap(&mut self) {
447 let arr = match self {
448 TinyVec::Heap(_) => return,
449 TinyVec::Inline(a) => a,
450 };
451
452 let v = arr.drain_to_vec();
453 *self = TinyVec::Heap(v);
454 }
455
456 #[inline]
471 #[cfg(feature = "rustc_1_57")]
472 pub fn try_move_to_the_heap(&mut self) -> Result<(), TryReserveError> {
473 let arr = match self {
474 TinyVec::Heap(_) => return Ok(()),
475 TinyVec::Inline(a) => a,
476 };
477
478 let v = arr.try_drain_to_vec()?;
479 *self = TinyVec::Heap(v);
480 return Ok(());
481 }
482
483 #[inline]
494 pub fn move_to_the_heap_and_reserve(&mut self, n: usize) {
495 let arr = match self {
496 TinyVec::Heap(h) => return h.reserve(n),
497 TinyVec::Inline(a) => a,
498 };
499
500 let v = arr.drain_to_vec_and_reserve(n);
501 *self = TinyVec::Heap(v);
502 }
503
504 #[inline]
520 #[cfg(feature = "rustc_1_57")]
521 pub fn try_move_to_the_heap_and_reserve(
522 &mut self, n: usize,
523 ) -> Result<(), TryReserveError> {
524 let arr = match self {
525 TinyVec::Heap(h) => return h.try_reserve(n),
526 TinyVec::Inline(a) => a,
527 };
528
529 let v = arr.try_drain_to_vec_and_reserve(n)?;
530 *self = TinyVec::Heap(v);
531 return Ok(());
532 }
533
534 #[inline]
545 pub fn reserve(&mut self, n: usize) {
546 let arr = match self {
547 TinyVec::Heap(h) => return h.reserve(n),
548 TinyVec::Inline(a) => a,
549 };
550
551 if n > arr.capacity() - arr.len() {
552 let v = arr.drain_to_vec_and_reserve(n);
553 *self = TinyVec::Heap(v);
554 }
555
556 return;
558 }
559
560 #[inline]
576 #[cfg(feature = "rustc_1_57")]
577 pub fn try_reserve(&mut self, n: usize) -> Result<(), TryReserveError> {
578 let arr = match self {
579 TinyVec::Heap(h) => return h.try_reserve(n),
580 TinyVec::Inline(a) => a,
581 };
582
583 if n > arr.capacity() - arr.len() {
584 let v = arr.try_drain_to_vec_and_reserve(n)?;
585 *self = TinyVec::Heap(v);
586 }
587
588 return Ok(());
590 }
591
592 #[inline]
610 pub fn reserve_exact(&mut self, n: usize) {
611 let arr = match self {
612 TinyVec::Heap(h) => return h.reserve_exact(n),
613 TinyVec::Inline(a) => a,
614 };
615
616 if n > arr.capacity() - arr.len() {
617 let v = arr.drain_to_vec_and_reserve(n);
618 *self = TinyVec::Heap(v);
619 }
620
621 return;
623 }
624
625 #[inline]
647 #[cfg(feature = "rustc_1_57")]
648 pub fn try_reserve_exact(&mut self, n: usize) -> Result<(), TryReserveError> {
649 let arr = match self {
650 TinyVec::Heap(h) => return h.try_reserve_exact(n),
651 TinyVec::Inline(a) => a,
652 };
653
654 if n > arr.capacity() - arr.len() {
655 let v = arr.try_drain_to_vec_and_reserve(n)?;
656 *self = TinyVec::Heap(v);
657 }
658
659 return Ok(());
661 }
662
663 #[inline]
678 #[must_use]
679 pub fn with_capacity(cap: usize) -> Self {
680 if cap <= A::CAPACITY {
681 TinyVec::Inline(ArrayVec::default())
682 } else {
683 TinyVec::Heap(Vec::with_capacity(cap))
684 }
685 }
686
687 #[inline]
713 #[must_use]
714 pub fn into_boxed_slice(self) -> alloc::boxed::Box<[A::Item]> {
715 self.into_vec().into_boxed_slice()
716 }
717
718 #[inline]
741 #[must_use]
742 pub fn into_vec(self) -> Vec<A::Item> {
743 self.into()
744 }
745}
746
747impl<A: Array> TinyVec<A> {
748 #[inline]
750 pub fn append(&mut self, other: &mut Self) {
751 self.reserve(other.len());
752
753 match (self, other) {
755 (TinyVec::Heap(sh), TinyVec::Heap(oh)) => sh.append(oh),
756 (TinyVec::Inline(a), TinyVec::Heap(h)) => a.extend(h.drain(..)),
757 (ref mut this, TinyVec::Inline(arr)) => this.extend(arr.drain(..)),
758 }
759 }
760
761 impl_mirrored! {
762 type Mirror = TinyVec;
763
764 #[inline]
781 pub fn swap_remove(self: &mut Self, index: usize) -> A::Item;
782
783 #[inline]
788 pub fn pop(self: &mut Self) -> Option<A::Item>;
789
790 #[inline]
807 pub fn remove(self: &mut Self, index: usize) -> A::Item;
808
809 #[inline(always)]
811 #[must_use]
812 pub fn len(self: &Self) -> usize;
813
814 #[inline(always)]
819 #[must_use]
820 pub fn capacity(self: &Self) -> usize;
821
822 #[inline]
826 pub fn truncate(self: &mut Self, new_len: usize);
827
828 #[inline(always)]
834 #[must_use]
835 pub fn as_mut_ptr(self: &mut Self) -> *mut A::Item;
836
837 #[inline(always)]
843 #[must_use]
844 pub fn as_ptr(self: &Self) -> *const A::Item;
845 }
846
847 #[inline]
859 pub fn retain<F: FnMut(&A::Item) -> bool>(&mut self, acceptable: F) {
860 match self {
861 TinyVec::Inline(i) => i.retain(acceptable),
862 TinyVec::Heap(h) => h.retain(acceptable),
863 }
864 }
865
866 #[inline]
879 #[cfg(feature = "rustc_1_61")]
880 pub fn retain_mut<F: FnMut(&mut A::Item) -> bool>(&mut self, acceptable: F) {
881 match self {
882 TinyVec::Inline(i) => i.retain_mut(acceptable),
883 TinyVec::Heap(h) => h.retain_mut(acceptable),
884 }
885 }
886
887 #[inline(always)]
889 #[must_use]
890 pub fn as_mut_slice(&mut self) -> &mut [A::Item] {
891 self.deref_mut()
892 }
893
894 #[inline(always)]
896 #[must_use]
897 pub fn as_slice(&self) -> &[A::Item] {
898 self.deref()
899 }
900
901 #[inline(always)]
903 pub fn clear(&mut self) {
904 self.truncate(0)
905 }
906
907 #[cfg(feature = "nightly_slice_partition_dedup")]
909 #[inline(always)]
910 pub fn dedup(&mut self)
911 where
912 A::Item: PartialEq,
913 {
914 self.dedup_by(|a, b| a == b)
915 }
916
917 #[cfg(feature = "nightly_slice_partition_dedup")]
919 #[inline(always)]
920 pub fn dedup_by<F>(&mut self, same_bucket: F)
921 where
922 F: FnMut(&mut A::Item, &mut A::Item) -> bool,
923 {
924 let len = {
925 let (dedup, _) = self.as_mut_slice().partition_dedup_by(same_bucket);
926 dedup.len()
927 };
928 self.truncate(len);
929 }
930
931 #[cfg(feature = "nightly_slice_partition_dedup")]
933 #[inline(always)]
934 pub fn dedup_by_key<F, K>(&mut self, mut key: F)
935 where
936 F: FnMut(&mut A::Item) -> K,
937 K: PartialEq,
938 {
939 self.dedup_by(|a, b| key(a) == key(b))
940 }
941
942 #[inline]
966 pub fn drain<R: RangeBounds<usize>>(
967 &mut self, range: R,
968 ) -> TinyVecDrain<'_, A> {
969 match self {
970 TinyVec::Inline(i) => TinyVecDrain::Inline(i.drain(range)),
971 TinyVec::Heap(h) => TinyVecDrain::Heap(h.drain(range)),
972 }
973 }
974
975 #[inline]
983 pub fn extend_from_slice(&mut self, sli: &[A::Item])
984 where
985 A::Item: Clone,
986 {
987 self.reserve(sli.len());
988 match self {
989 TinyVec::Inline(a) => a.extend_from_slice(sli),
990 TinyVec::Heap(h) => h.extend_from_slice(sli),
991 }
992 }
993
994 #[inline]
1002 #[must_use]
1003 #[allow(clippy::match_wild_err_arm)]
1004 pub fn from_array_len(data: A, len: usize) -> Self {
1005 match Self::try_from_array_len(data, len) {
1006 Ok(out) => out,
1007 Err(_) => {
1008 panic!("TinyVec: length {} exceeds capacity {}!", len, A::CAPACITY)
1009 }
1010 }
1011 }
1012
1013 #[inline(always)]
1017 #[doc(hidden)]
1018 pub fn constructor_for_capacity(cap: usize) -> TinyVecConstructor<A> {
1019 if cap <= A::CAPACITY {
1020 TinyVecConstructor::Inline(TinyVec::Inline)
1021 } else {
1022 TinyVecConstructor::Heap(TinyVec::Heap)
1023 }
1024 }
1025
1026 #[inline]
1042 pub fn insert(&mut self, index: usize, item: A::Item) {
1043 assert!(
1044 index <= self.len(),
1045 "insertion index (is {}) should be <= len (is {})",
1046 index,
1047 self.len()
1048 );
1049
1050 let arr = match self {
1051 TinyVec::Heap(v) => return v.insert(index, item),
1052 TinyVec::Inline(a) => a,
1053 };
1054
1055 if let Some(x) = arr.try_insert(index, item) {
1056 let mut v = Vec::with_capacity(arr.len() * 2);
1057 let mut it = arr.iter_mut().map(core::mem::take);
1058 v.extend(it.by_ref().take(index));
1059 v.push(x);
1060 v.extend(it);
1061 *self = TinyVec::Heap(v);
1062 }
1063 }
1064
1065 #[inline(always)]
1067 #[must_use]
1068 pub fn is_empty(&self) -> bool {
1069 self.len() == 0
1070 }
1071
1072 #[inline(always)]
1074 #[must_use]
1075 pub fn new() -> Self {
1076 Self::default()
1077 }
1078
1079 #[inline]
1081 pub fn push(&mut self, val: A::Item) {
1082 #[cold]
1092 fn drain_to_heap_and_push<A: Array>(
1093 arr: &mut ArrayVec<A>, val: A::Item,
1094 ) -> TinyVec<A> {
1095 let mut v = arr.drain_to_vec_and_reserve(arr.len());
1097 v.push(val);
1098 TinyVec::Heap(v)
1099 }
1100
1101 match self {
1102 TinyVec::Heap(v) => v.push(val),
1103 TinyVec::Inline(arr) => {
1104 if let Some(x) = arr.try_push(val) {
1105 *self = drain_to_heap_and_push(arr, x);
1106 }
1107 }
1108 }
1109 }
1110
1111 #[inline]
1130 pub fn resize(&mut self, new_len: usize, new_val: A::Item)
1131 where
1132 A::Item: Clone,
1133 {
1134 self.resize_with(new_len, || new_val.clone());
1135 }
1136
1137 #[inline]
1160 pub fn resize_with<F: FnMut() -> A::Item>(&mut self, new_len: usize, f: F) {
1161 match new_len.checked_sub(self.len()) {
1162 None => return self.truncate(new_len),
1163 Some(n) => self.reserve(n),
1164 }
1165
1166 match self {
1167 TinyVec::Inline(a) => a.resize_with(new_len, f),
1168 TinyVec::Heap(v) => v.resize_with(new_len, f),
1169 }
1170 }
1171
1172 #[inline]
1190 pub fn split_off(&mut self, at: usize) -> Self {
1191 match self {
1192 TinyVec::Inline(a) => TinyVec::Inline(a.split_off(at)),
1193 TinyVec::Heap(v) => TinyVec::Heap(v.split_off(at)),
1194 }
1195 }
1196
1197 #[inline]
1221 pub fn splice<R, I>(
1222 &mut self, range: R, replacement: I,
1223 ) -> TinyVecSplice<'_, A, core::iter::Fuse<I::IntoIter>>
1224 where
1225 R: RangeBounds<usize>,
1226 I: IntoIterator<Item = A::Item>,
1227 {
1228 use core::ops::Bound;
1229 let start = match range.start_bound() {
1230 Bound::Included(x) => *x,
1231 Bound::Excluded(x) => x.saturating_add(1),
1232 Bound::Unbounded => 0,
1233 };
1234 let end = match range.end_bound() {
1235 Bound::Included(x) => x.saturating_add(1),
1236 Bound::Excluded(x) => *x,
1237 Bound::Unbounded => self.len(),
1238 };
1239 assert!(
1240 start <= end,
1241 "TinyVec::splice> Illegal range, {} to {}",
1242 start,
1243 end
1244 );
1245 assert!(
1246 end <= self.len(),
1247 "TinyVec::splice> Range ends at {} but length is only {}!",
1248 end,
1249 self.len()
1250 );
1251
1252 TinyVecSplice {
1253 removal_start: start,
1254 removal_end: end,
1255 parent: self,
1256 replacement: replacement.into_iter().fuse(),
1257 }
1258 }
1259
1260 #[inline]
1270 pub fn try_from_array_len(data: A, len: usize) -> Result<Self, A> {
1271 let arr = ArrayVec::try_from_array_len(data, len)?;
1272 Ok(TinyVec::Inline(arr))
1273 }
1274}
1275
1276#[cfg_attr(docsrs, doc(cfg(feature = "alloc")))]
1280pub enum TinyVecDrain<'p, A: Array> {
1281 #[allow(missing_docs)]
1282 Inline(ArrayVecDrain<'p, A::Item>),
1283 #[allow(missing_docs)]
1284 Heap(vec::Drain<'p, A::Item>),
1285}
1286
1287impl<'p, A: Array> Iterator for TinyVecDrain<'p, A> {
1288 type Item = A::Item;
1289
1290 impl_mirrored! {
1291 type Mirror = TinyVecDrain;
1292
1293 #[inline]
1294 fn next(self: &mut Self) -> Option<Self::Item>;
1295 #[inline]
1296 fn nth(self: &mut Self, n: usize) -> Option<Self::Item>;
1297 #[inline]
1298 fn size_hint(self: &Self) -> (usize, Option<usize>);
1299 #[inline]
1300 fn last(self: Self) -> Option<Self::Item>;
1301 #[inline]
1302 fn count(self: Self) -> usize;
1303 }
1304
1305 #[inline]
1306 fn for_each<F: FnMut(Self::Item)>(self, f: F) {
1307 match self {
1308 TinyVecDrain::Inline(i) => i.for_each(f),
1309 TinyVecDrain::Heap(h) => h.for_each(f),
1310 }
1311 }
1312}
1313
1314impl<'p, A: Array> DoubleEndedIterator for TinyVecDrain<'p, A> {
1315 impl_mirrored! {
1316 type Mirror = TinyVecDrain;
1317
1318 #[inline]
1319 fn next_back(self: &mut Self) -> Option<Self::Item>;
1320
1321 #[inline]
1322 fn nth_back(self: &mut Self, n: usize) -> Option<Self::Item>;
1323 }
1324}
1325
1326#[cfg_attr(docsrs, doc(cfg(feature = "alloc")))]
1329pub struct TinyVecSplice<'p, A: Array, I: Iterator<Item = A::Item>> {
1330 parent: &'p mut TinyVec<A>,
1331 removal_start: usize,
1332 removal_end: usize,
1333 replacement: I,
1334}
1335
1336impl<'p, A, I> Iterator for TinyVecSplice<'p, A, I>
1337where
1338 A: Array,
1339 I: Iterator<Item = A::Item>,
1340{
1341 type Item = A::Item;
1342
1343 #[inline]
1344 fn next(&mut self) -> Option<A::Item> {
1345 if self.removal_start < self.removal_end {
1346 match self.replacement.next() {
1347 Some(replacement) => {
1348 let removed = core::mem::replace(
1349 &mut self.parent[self.removal_start],
1350 replacement,
1351 );
1352 self.removal_start += 1;
1353 Some(removed)
1354 }
1355 None => {
1356 let removed = self.parent.remove(self.removal_start);
1357 self.removal_end -= 1;
1358 Some(removed)
1359 }
1360 }
1361 } else {
1362 None
1363 }
1364 }
1365
1366 #[inline]
1367 fn size_hint(&self) -> (usize, Option<usize>) {
1368 let len = self.len();
1369 (len, Some(len))
1370 }
1371}
1372
1373impl<'p, A, I> ExactSizeIterator for TinyVecSplice<'p, A, I>
1374where
1375 A: Array,
1376 I: Iterator<Item = A::Item>,
1377{
1378 #[inline]
1379 fn len(&self) -> usize {
1380 self.removal_end - self.removal_start
1381 }
1382}
1383
1384impl<'p, A, I> FusedIterator for TinyVecSplice<'p, A, I>
1385where
1386 A: Array,
1387 I: Iterator<Item = A::Item>,
1388{
1389}
1390
1391impl<'p, A, I> DoubleEndedIterator for TinyVecSplice<'p, A, I>
1392where
1393 A: Array,
1394 I: Iterator<Item = A::Item> + DoubleEndedIterator,
1395{
1396 #[inline]
1397 fn next_back(&mut self) -> Option<A::Item> {
1398 if self.removal_start < self.removal_end {
1399 match self.replacement.next_back() {
1400 Some(replacement) => {
1401 let removed = core::mem::replace(
1402 &mut self.parent[self.removal_end - 1],
1403 replacement,
1404 );
1405 self.removal_end -= 1;
1406 Some(removed)
1407 }
1408 None => {
1409 let removed = self.parent.remove(self.removal_end - 1);
1410 self.removal_end -= 1;
1411 Some(removed)
1412 }
1413 }
1414 } else {
1415 None
1416 }
1417 }
1418}
1419
1420impl<'p, A: Array, I: Iterator<Item = A::Item>> Drop
1421 for TinyVecSplice<'p, A, I>
1422{
1423 #[inline]
1424 fn drop(&mut self) {
1425 for _ in self.by_ref() {}
1426
1427 let (lower_bound, _) = self.replacement.size_hint();
1428 self.parent.reserve(lower_bound);
1429
1430 for replacement in self.replacement.by_ref() {
1431 self.parent.insert(self.removal_end, replacement);
1432 self.removal_end += 1;
1433 }
1434 }
1435}
1436
1437impl<A: Array> AsMut<[A::Item]> for TinyVec<A> {
1438 #[inline(always)]
1439 fn as_mut(&mut self) -> &mut [A::Item] {
1440 &mut *self
1441 }
1442}
1443
1444impl<A: Array> AsRef<[A::Item]> for TinyVec<A> {
1445 #[inline(always)]
1446 fn as_ref(&self) -> &[A::Item] {
1447 &*self
1448 }
1449}
1450
1451impl<A: Array> Borrow<[A::Item]> for TinyVec<A> {
1452 #[inline(always)]
1453 fn borrow(&self) -> &[A::Item] {
1454 &*self
1455 }
1456}
1457
1458impl<A: Array> BorrowMut<[A::Item]> for TinyVec<A> {
1459 #[inline(always)]
1460 fn borrow_mut(&mut self) -> &mut [A::Item] {
1461 &mut *self
1462 }
1463}
1464
1465impl<A: Array> Extend<A::Item> for TinyVec<A> {
1466 #[inline]
1467 fn extend<T: IntoIterator<Item = A::Item>>(&mut self, iter: T) {
1468 let iter = iter.into_iter();
1469 let (lower_bound, _) = iter.size_hint();
1470 self.reserve(lower_bound);
1471
1472 let a = match self {
1473 TinyVec::Heap(h) => return h.extend(iter),
1474 TinyVec::Inline(a) => a,
1475 };
1476
1477 let mut iter = a.fill(iter);
1478 let maybe = iter.next();
1479
1480 let surely = match maybe {
1481 Some(x) => x,
1482 None => return,
1483 };
1484
1485 let mut v = a.drain_to_vec_and_reserve(a.len());
1486 v.push(surely);
1487 v.extend(iter);
1488 *self = TinyVec::Heap(v);
1489 }
1490}
1491
1492impl<A: Array> From<ArrayVec<A>> for TinyVec<A> {
1493 #[inline(always)]
1494 fn from(arr: ArrayVec<A>) -> Self {
1495 TinyVec::Inline(arr)
1496 }
1497}
1498
1499impl<A: Array> From<A> for TinyVec<A> {
1500 #[inline]
1501 fn from(array: A) -> Self {
1502 TinyVec::Inline(ArrayVec::from(array))
1503 }
1504}
1505
1506impl<T, A> From<&'_ [T]> for TinyVec<A>
1507where
1508 T: Clone + Default,
1509 A: Array<Item = T>,
1510{
1511 #[inline]
1512 fn from(slice: &[T]) -> Self {
1513 if let Ok(arr) = ArrayVec::try_from(slice) {
1514 TinyVec::Inline(arr)
1515 } else {
1516 TinyVec::Heap(slice.into())
1517 }
1518 }
1519}
1520
1521impl<T, A> From<&'_ mut [T]> for TinyVec<A>
1522where
1523 T: Clone + Default,
1524 A: Array<Item = T>,
1525{
1526 #[inline]
1527 fn from(slice: &mut [T]) -> Self {
1528 Self::from(&*slice)
1529 }
1530}
1531
1532impl<A: Array> FromIterator<A::Item> for TinyVec<A> {
1533 #[inline]
1534 fn from_iter<T: IntoIterator<Item = A::Item>>(iter: T) -> Self {
1535 let mut av = Self::default();
1536 av.extend(iter);
1537 av
1538 }
1539}
1540
1541impl<A: Array> Into<Vec<A::Item>> for TinyVec<A> {
1542 #[inline]
1587 fn into(self) -> Vec<A::Item> {
1588 match self {
1589 Self::Heap(inner) => inner,
1590 Self::Inline(mut inner) => inner.drain_to_vec(),
1591 }
1592 }
1593}
1594
1595#[cfg_attr(docsrs, doc(cfg(feature = "alloc")))]
1597pub enum TinyVecIterator<A: Array> {
1598 #[allow(missing_docs)]
1599 Inline(ArrayVecIterator<A>),
1600 #[allow(missing_docs)]
1601 Heap(alloc::vec::IntoIter<A::Item>),
1602}
1603
1604impl<A: Array> TinyVecIterator<A> {
1605 impl_mirrored! {
1606 type Mirror = TinyVecIterator;
1607 #[inline]
1609 #[must_use]
1610 pub fn as_slice(self: &Self) -> &[A::Item];
1611 }
1612}
1613
1614impl<A: Array> FusedIterator for TinyVecIterator<A> {}
1615
1616impl<A: Array> Iterator for TinyVecIterator<A> {
1617 type Item = A::Item;
1618
1619 impl_mirrored! {
1620 type Mirror = TinyVecIterator;
1621
1622 #[inline]
1623 fn next(self: &mut Self) -> Option<Self::Item>;
1624
1625 #[inline(always)]
1626 #[must_use]
1627 fn size_hint(self: &Self) -> (usize, Option<usize>);
1628
1629 #[inline(always)]
1630 fn count(self: Self) -> usize;
1631
1632 #[inline]
1633 fn last(self: Self) -> Option<Self::Item>;
1634
1635 #[inline]
1636 fn nth(self: &mut Self, n: usize) -> Option<A::Item>;
1637 }
1638}
1639
1640impl<A: Array> DoubleEndedIterator for TinyVecIterator<A> {
1641 impl_mirrored! {
1642 type Mirror = TinyVecIterator;
1643
1644 #[inline]
1645 fn next_back(self: &mut Self) -> Option<Self::Item>;
1646
1647 #[inline]
1648 fn nth_back(self: &mut Self, n: usize) -> Option<Self::Item>;
1649 }
1650}
1651
1652impl<A: Array> ExactSizeIterator for TinyVecIterator<A> {
1653 impl_mirrored! {
1654 type Mirror = TinyVecIterator;
1655 #[inline]
1656 fn len(self: &Self) -> usize;
1657 }
1658}
1659
1660impl<A: Array> Debug for TinyVecIterator<A>
1661where
1662 A::Item: Debug,
1663{
1664 #[allow(clippy::missing_inline_in_public_items)]
1665 fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
1666 f.debug_tuple("TinyVecIterator").field(&self.as_slice()).finish()
1667 }
1668}
1669
1670#[cfg(feature = "defmt")]
1671#[cfg_attr(docs_rs, doc(cfg(feature = "defmt")))]
1672impl<A: Array> defmt::Format for TinyVecIterator<A>
1673where
1674 A::Item: defmt::Format,
1675{
1676 fn format(&self, fmt: defmt::Formatter<'_>) {
1677 defmt::write!(fmt, "TinyVecIterator({:?})", self.as_slice())
1678 }
1679}
1680
1681impl<A: Array> IntoIterator for TinyVec<A> {
1682 type Item = A::Item;
1683 type IntoIter = TinyVecIterator<A>;
1684 #[inline(always)]
1685 fn into_iter(self) -> Self::IntoIter {
1686 match self {
1687 TinyVec::Inline(a) => TinyVecIterator::Inline(a.into_iter()),
1688 TinyVec::Heap(v) => TinyVecIterator::Heap(v.into_iter()),
1689 }
1690 }
1691}
1692
1693impl<'a, A: Array> IntoIterator for &'a mut TinyVec<A> {
1694 type Item = &'a mut A::Item;
1695 type IntoIter = core::slice::IterMut<'a, A::Item>;
1696 #[inline(always)]
1697 fn into_iter(self) -> Self::IntoIter {
1698 self.iter_mut()
1699 }
1700}
1701
1702impl<'a, A: Array> IntoIterator for &'a TinyVec<A> {
1703 type Item = &'a A::Item;
1704 type IntoIter = core::slice::Iter<'a, A::Item>;
1705 #[inline(always)]
1706 fn into_iter(self) -> Self::IntoIter {
1707 self.iter()
1708 }
1709}
1710
1711impl<A: Array> PartialEq for TinyVec<A>
1712where
1713 A::Item: PartialEq,
1714{
1715 #[inline]
1716 fn eq(&self, other: &Self) -> bool {
1717 self.as_slice().eq(other.as_slice())
1718 }
1719}
1720impl<A: Array> Eq for TinyVec<A> where A::Item: Eq {}
1721
1722impl<A: Array> PartialOrd for TinyVec<A>
1723where
1724 A::Item: PartialOrd,
1725{
1726 #[inline]
1727 fn partial_cmp(&self, other: &Self) -> Option<core::cmp::Ordering> {
1728 self.as_slice().partial_cmp(other.as_slice())
1729 }
1730}
1731impl<A: Array> Ord for TinyVec<A>
1732where
1733 A::Item: Ord,
1734{
1735 #[inline]
1736 fn cmp(&self, other: &Self) -> core::cmp::Ordering {
1737 self.as_slice().cmp(other.as_slice())
1738 }
1739}
1740
1741impl<A: Array> PartialEq<&A> for TinyVec<A>
1742where
1743 A::Item: PartialEq,
1744{
1745 #[inline]
1746 fn eq(&self, other: &&A) -> bool {
1747 self.as_slice().eq(other.as_slice())
1748 }
1749}
1750
1751impl<A: Array> PartialEq<&[A::Item]> for TinyVec<A>
1752where
1753 A::Item: PartialEq,
1754{
1755 #[inline]
1756 fn eq(&self, other: &&[A::Item]) -> bool {
1757 self.as_slice().eq(*other)
1758 }
1759}
1760
1761impl<A: Array> Hash for TinyVec<A>
1762where
1763 A::Item: Hash,
1764{
1765 #[inline]
1766 fn hash<H: Hasher>(&self, state: &mut H) {
1767 self.as_slice().hash(state)
1768 }
1769}
1770
1771impl<A: Array> Binary for TinyVec<A>
1776where
1777 A::Item: Binary,
1778{
1779 #[allow(clippy::missing_inline_in_public_items)]
1780 fn fmt(&self, f: &mut Formatter) -> core::fmt::Result {
1781 write!(f, "[")?;
1782 if f.alternate() {
1783 write!(f, "\n ")?;
1784 }
1785 for (i, elem) in self.iter().enumerate() {
1786 if i > 0 {
1787 write!(f, ",{}", if f.alternate() { "\n " } else { " " })?;
1788 }
1789 Binary::fmt(elem, f)?;
1790 }
1791 if f.alternate() {
1792 write!(f, ",\n")?;
1793 }
1794 write!(f, "]")
1795 }
1796}
1797
1798impl<A: Array> Debug for TinyVec<A>
1799where
1800 A::Item: Debug,
1801{
1802 #[allow(clippy::missing_inline_in_public_items)]
1803 fn fmt(&self, f: &mut Formatter) -> core::fmt::Result {
1804 <[A::Item] as Debug>::fmt(self.as_slice(), f)
1805 }
1806}
1807
1808#[cfg(feature = "defmt")]
1809#[cfg_attr(docs_rs, doc(cfg(feature = "defmt")))]
1810impl<A: Array> defmt::Format for TinyVec<A>
1811where
1812 A::Item: defmt::Format,
1813{
1814 fn format(&self, fmt: defmt::Formatter<'_>) {
1815 defmt::Format::format(self.as_slice(), fmt)
1816 }
1817}
1818
1819impl<A: Array> Display for TinyVec<A>
1820where
1821 A::Item: Display,
1822{
1823 #[allow(clippy::missing_inline_in_public_items)]
1824 fn fmt(&self, f: &mut Formatter) -> core::fmt::Result {
1825 write!(f, "[")?;
1826 if f.alternate() {
1827 write!(f, "\n ")?;
1828 }
1829 for (i, elem) in self.iter().enumerate() {
1830 if i > 0 {
1831 write!(f, ",{}", if f.alternate() { "\n " } else { " " })?;
1832 }
1833 Display::fmt(elem, f)?;
1834 }
1835 if f.alternate() {
1836 write!(f, ",\n")?;
1837 }
1838 write!(f, "]")
1839 }
1840}
1841
1842impl<A: Array> LowerExp for TinyVec<A>
1843where
1844 A::Item: LowerExp,
1845{
1846 #[allow(clippy::missing_inline_in_public_items)]
1847 fn fmt(&self, f: &mut Formatter) -> core::fmt::Result {
1848 write!(f, "[")?;
1849 if f.alternate() {
1850 write!(f, "\n ")?;
1851 }
1852 for (i, elem) in self.iter().enumerate() {
1853 if i > 0 {
1854 write!(f, ",{}", if f.alternate() { "\n " } else { " " })?;
1855 }
1856 LowerExp::fmt(elem, f)?;
1857 }
1858 if f.alternate() {
1859 write!(f, ",\n")?;
1860 }
1861 write!(f, "]")
1862 }
1863}
1864
1865impl<A: Array> LowerHex for TinyVec<A>
1866where
1867 A::Item: LowerHex,
1868{
1869 #[allow(clippy::missing_inline_in_public_items)]
1870 fn fmt(&self, f: &mut Formatter) -> core::fmt::Result {
1871 write!(f, "[")?;
1872 if f.alternate() {
1873 write!(f, "\n ")?;
1874 }
1875 for (i, elem) in self.iter().enumerate() {
1876 if i > 0 {
1877 write!(f, ",{}", if f.alternate() { "\n " } else { " " })?;
1878 }
1879 LowerHex::fmt(elem, f)?;
1880 }
1881 if f.alternate() {
1882 write!(f, ",\n")?;
1883 }
1884 write!(f, "]")
1885 }
1886}
1887
1888impl<A: Array> Octal for TinyVec<A>
1889where
1890 A::Item: Octal,
1891{
1892 #[allow(clippy::missing_inline_in_public_items)]
1893 fn fmt(&self, f: &mut Formatter) -> core::fmt::Result {
1894 write!(f, "[")?;
1895 if f.alternate() {
1896 write!(f, "\n ")?;
1897 }
1898 for (i, elem) in self.iter().enumerate() {
1899 if i > 0 {
1900 write!(f, ",{}", if f.alternate() { "\n " } else { " " })?;
1901 }
1902 Octal::fmt(elem, f)?;
1903 }
1904 if f.alternate() {
1905 write!(f, ",\n")?;
1906 }
1907 write!(f, "]")
1908 }
1909}
1910
1911impl<A: Array> Pointer for TinyVec<A>
1912where
1913 A::Item: Pointer,
1914{
1915 #[allow(clippy::missing_inline_in_public_items)]
1916 fn fmt(&self, f: &mut Formatter) -> core::fmt::Result {
1917 write!(f, "[")?;
1918 if f.alternate() {
1919 write!(f, "\n ")?;
1920 }
1921 for (i, elem) in self.iter().enumerate() {
1922 if i > 0 {
1923 write!(f, ",{}", if f.alternate() { "\n " } else { " " })?;
1924 }
1925 Pointer::fmt(elem, f)?;
1926 }
1927 if f.alternate() {
1928 write!(f, ",\n")?;
1929 }
1930 write!(f, "]")
1931 }
1932}
1933
1934impl<A: Array> UpperExp for TinyVec<A>
1935where
1936 A::Item: UpperExp,
1937{
1938 #[allow(clippy::missing_inline_in_public_items)]
1939 fn fmt(&self, f: &mut Formatter) -> core::fmt::Result {
1940 write!(f, "[")?;
1941 if f.alternate() {
1942 write!(f, "\n ")?;
1943 }
1944 for (i, elem) in self.iter().enumerate() {
1945 if i > 0 {
1946 write!(f, ",{}", if f.alternate() { "\n " } else { " " })?;
1947 }
1948 UpperExp::fmt(elem, f)?;
1949 }
1950 if f.alternate() {
1951 write!(f, ",\n")?;
1952 }
1953 write!(f, "]")
1954 }
1955}
1956
1957impl<A: Array> UpperHex for TinyVec<A>
1958where
1959 A::Item: UpperHex,
1960{
1961 #[allow(clippy::missing_inline_in_public_items)]
1962 fn fmt(&self, f: &mut Formatter) -> core::fmt::Result {
1963 write!(f, "[")?;
1964 if f.alternate() {
1965 write!(f, "\n ")?;
1966 }
1967 for (i, elem) in self.iter().enumerate() {
1968 if i > 0 {
1969 write!(f, ",{}", if f.alternate() { "\n " } else { " " })?;
1970 }
1971 UpperHex::fmt(elem, f)?;
1972 }
1973 if f.alternate() {
1974 write!(f, ",\n")?;
1975 }
1976 write!(f, "]")
1977 }
1978}
1979
1980#[cfg(feature = "serde")]
1981#[cfg_attr(docs_rs, doc(cfg(feature = "alloc")))]
1982struct TinyVecVisitor<A: Array>(PhantomData<A>);
1983
1984#[cfg(feature = "serde")]
1985impl<'de, A: Array> Visitor<'de> for TinyVecVisitor<A>
1986where
1987 A::Item: Deserialize<'de>,
1988{
1989 type Value = TinyVec<A>;
1990
1991 fn expecting(
1992 &self, formatter: &mut core::fmt::Formatter,
1993 ) -> core::fmt::Result {
1994 formatter.write_str("a sequence")
1995 }
1996
1997 fn visit_seq<S>(self, mut seq: S) -> Result<Self::Value, S::Error>
1998 where
1999 S: SeqAccess<'de>,
2000 {
2001 let mut new_tinyvec = match seq.size_hint() {
2002 Some(expected_size) => {
2003 TinyVec::with_capacity(cautious_capacity::<A::Item>(expected_size))
2004 }
2005 None => Default::default(),
2006 };
2007
2008 while let Some(value) = seq.next_element()? {
2009 new_tinyvec.push(value);
2010 }
2011
2012 Ok(new_tinyvec)
2013 }
2014}